Search in sources :

Example 1 with ConfiguredThemeEditorStyle

use of com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle in project android by JetBrains.

the class ThemeEditorTable method getPopupMenuAtCell.

private JPopupMenu getPopupMenuAtCell(final int row, final int column) {
    if (row < 0 || column < 0) {
        return null;
    }
    TableModel rawModel = getModel();
    if (!(rawModel instanceof AttributesTableModel)) {
        return null;
    }
    final AttributesTableModel model = (AttributesTableModel) rawModel;
    AttributesTableModel.RowContents contents = model.getRowContents(this.convertRowIndexToModel(row));
    if (contents instanceof AttributesTableModel.AttributeContents) {
        final AttributesTableModel.AttributeContents attribute = (AttributesTableModel.AttributeContents) contents;
        final EditedStyleItem item = attribute.getValue();
        if (item == null) {
            return null;
        }
        final JBPopupMenu popupMenu = new JBPopupMenu();
        if (attribute.getCellClass(1) == ConfiguredThemeEditorStyle.class) {
            popupMenu.add(new AbstractAction(GO_TO_DECLARATION) {

                @Override
                public void actionPerformed(ActionEvent e) {
                    myGoToListener.goTo(item);
                }
            });
        } else {
            final ResourceResolver resolver = myContext.getResourceResolver();
            assert resolver != null;
            final Project project = myContext.getProject();
            final ResourceValue resourceValue = resolver.resolveResValue(item.getSelectedValue());
            final File file = new File(resourceValue.getValue());
            final VirtualFileManager manager = VirtualFileManager.getInstance();
            final VirtualFile virtualFile = file.exists() ? manager.findFileByUrl("file://" + file.getAbsolutePath()) : null;
            if (virtualFile != null) {
                popupMenu.add(new AbstractAction(GO_TO_DECLARATION) {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        final OpenFileDescriptor descriptor = new OpenFileDescriptor(project, virtualFile);
                        FileEditorManager.getInstance(project).openEditor(descriptor, true);
                    }
                });
            }
        }
        myJavadocAction.setCurrentItem(item);
        popupMenu.add(myJavadocAction);
        final ConfiguredThemeEditorStyle selectedStyle = model.getSelectedStyle();
        if (!selectedStyle.isReadOnly() && selectedStyle.hasItem(item)) {
            popupMenu.add(new AbstractAction("Reset value") {

                @Override
                public void actionPerformed(ActionEvent e) {
                    selectedStyle.removeAttribute(item.getQualifiedName());
                    model.fireTableCellUpdated(attribute.getRowIndex(), 0);
                }
            });
        }
        return popupMenu;
    } else if (contents instanceof AttributesTableModel.ParentAttribute) {
        final ConfiguredThemeEditorStyle parentStyle = model.getSelectedStyle().getParent();
        if (parentStyle == null) {
            return null;
        }
        final JBPopupMenu menu = new JBPopupMenu();
        menu.add(new AbstractAction(GO_TO_DECLARATION) {

            @Override
            public void actionPerformed(ActionEvent e) {
                myGoToListener.goToParent();
            }
        });
        return menu;
    }
    return null;
}
Also used : AttributesTableModel(com.android.tools.idea.editors.theme.attributes.AttributesTableModel) VirtualFile(com.intellij.openapi.vfs.VirtualFile) VirtualFileManager(com.intellij.openapi.vfs.VirtualFileManager) ActionEvent(java.awt.event.ActionEvent) JBPopupMenu(com.intellij.openapi.ui.JBPopupMenu) EditedStyleItem(com.android.tools.idea.editors.theme.datamodels.EditedStyleItem) ConfiguredThemeEditorStyle(com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle) Project(com.intellij.openapi.project.Project) ResourceResolver(com.android.ide.common.resources.ResourceResolver) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) OpenFileDescriptor(com.intellij.openapi.fileEditor.OpenFileDescriptor) VirtualFile(com.intellij.openapi.vfs.VirtualFile) File(java.io.File) TableModel(javax.swing.table.TableModel) AttributesTableModel(com.android.tools.idea.editors.theme.attributes.AttributesTableModel)

Example 2 with ConfiguredThemeEditorStyle

use of com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle in project android by JetBrains.

the class DelegatingCellRenderer method getTableCellRendererComponent.

@Override
public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
    EditedStyleItem item = (value instanceof EditedStyleItem) ? (EditedStyleItem) value : null;
    final Component returnedComponent = myDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    ConfiguredThemeEditorStyle selectedStyle = ((AttributesTableModel) table.getModel()).getSelectedStyle();
    // Displays in bold attributes that are overriding their inherited value
    returnedComponent.setFont(selectedStyle.hasItem(item) ? returnedComponent.getFont().deriveFont(Font.BOLD) : returnedComponent.getFont().deriveFont(Font.PLAIN));
    returnedComponent.setForeground((item != null && !item.isPublicAttribute()) ? JBColor.LIGHT_GRAY : table.getForeground());
    return returnedComponent;
}
Also used : AttributesTableModel(com.android.tools.idea.editors.theme.attributes.AttributesTableModel) EditedStyleItem(com.android.tools.idea.editors.theme.datamodels.EditedStyleItem) ConfiguredThemeEditorStyle(com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle)

Example 3 with ConfiguredThemeEditorStyle

use of com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle in project android by JetBrains.

the class DelegatingCellEditor method getTableCellEditorComponent.

@Override
public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected, final int row, final int column) {
    final Object stringValue;
    final CellSpanModel model = (CellSpanModel) table.getModel();
    boolean boldFont = false;
    if (value instanceof EditedStyleItem) {
        final EditedStyleItem item = (EditedStyleItem) value;
        stringValue = ThemeEditorUtils.extractRealValue(item, model.getCellClass(row, column));
        ConfiguredThemeEditorStyle selectedStyle = ((AttributesTableModel) table.getModel()).getSelectedStyle();
        // Displays in bold attributes that are overriding their inherited value
        boldFont = selectedStyle.hasItem(item);
    } else {
        // Not an EditedStyleItem for theme name and theme parent.
        stringValue = value;
    }
    final Component returnedComponent = myDelegate.getTableCellEditorComponent(table, myConvertValueToString ? stringValue : value, isSelected, row, column);
    returnedComponent.setFont(boldFont ? returnedComponent.getFont().deriveFont(Font.BOLD) : returnedComponent.getFont().deriveFont(Font.PLAIN));
    return returnedComponent;
}
Also used : AttributesTableModel(com.android.tools.idea.editors.theme.attributes.AttributesTableModel) CellSpanModel(spantable.CellSpanModel) EventObject(java.util.EventObject) EditedStyleItem(com.android.tools.idea.editors.theme.datamodels.EditedStyleItem) ConfiguredThemeEditorStyle(com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle)

Example 4 with ConfiguredThemeEditorStyle

use of com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle in project android by JetBrains.

the class ParentRendererEditor method updateVariantsCombo.

private void updateVariantsCombo() {
    if (myItem == null) {
        myVariantsComboBox.setVisible(false);
        return;
    }
    myVariantsComboBox.setVisible(true);
    Collection<ConfiguredElement<String>> allParents = myItem.getParentNames();
    final String currentVariantColor = ColorUtil.toHex(ThemeEditorConstants.CURRENT_VARIANT_COLOR);
    final String notSelectedVariantColor = ColorUtil.toHex(ThemeEditorConstants.NOT_SELECTED_VARIANT_COLOR);
    final ArrayList<VariantsComboItem> variants = Lists.newArrayListWithCapacity(allParents.size());
    ConfiguredThemeEditorStyle currentParent = myItem.getParent(myContext.getThemeResolver());
    ConfiguredElement<String> selectedElement = null;
    if (currentParent != null) {
        //noinspection unchecked
        selectedElement = (ConfiguredElement<String>) currentParent.getConfiguration().getFullConfig().findMatchingConfigurable(ImmutableList.copyOf(allParents));
    }
    if (selectedElement == null) {
        selectedElement = allParents.iterator().next();
    }
    for (ConfiguredElement<String> configuredParent : allParents) {
        FolderConfiguration restrictedConfig = RestrictedConfiguration.restrict(configuredParent, allParents);
        String parentName = configuredParent.getElement();
        if (restrictedConfig == null) {
            // This type is not visible
            LOG.warn(String.format("For style '%1$s': Folder configuration '%2$s' can never be selected. There are no qualifiers combination that would allow selecting it.", parentName, configuredParent.getConfiguration()));
            continue;
        }
        if (configuredParent.getConfiguration().equals(selectedElement.getConfiguration())) {
            // This is the selected parent
            variants.add(0, new VariantsComboItem(String.format(ThemeEditorConstants.CURRENT_VARIANT_TEMPLATE, currentVariantColor, configuredParent.getConfiguration().toShortDisplayString()), restrictedConfig, configuredParent.getConfiguration()));
        } else {
            variants.add(new VariantsComboItem(String.format(ThemeEditorConstants.NOT_SELECTED_VARIANT_TEMPLATE, notSelectedVariantColor, configuredParent.getConfiguration().toShortDisplayString(), " - " + parentName), restrictedConfig, configuredParent.getConfiguration()));
        }
    }
    myVariantsComboBox.setModel(new CollectionComboBoxModel<VariantsComboItem>(variants, variants.get(0)));
}
Also used : ConfiguredElement(com.android.tools.idea.editors.theme.datamodels.ConfiguredElement) VariantsComboItem(com.android.tools.idea.editors.theme.attributes.variants.VariantsComboItem) FolderConfiguration(com.android.ide.common.resources.configuration.FolderConfiguration) ConfiguredThemeEditorStyle(com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle)

Example 5 with ConfiguredThemeEditorStyle

use of com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle in project android by JetBrains.

the class ThemeEditorComponent method createNewThemeWithAttributeValue.

/**
   * Sets a new value to the passed attribute. It will also trigger the reload if a change happened.
   * @param rv The attribute to set, including the current value.
   * @param strValue The new value.
   */
private void createNewThemeWithAttributeValue(@NotNull final EditedStyleItem rv, @NotNull final String strValue) {
    if (strValue.equals(rv.getValue())) {
        // No modification required.
        return;
    }
    ConfiguredThemeEditorStyle selectedStyle = getUsedStyle();
    if (selectedStyle == null) {
        LOG.error("No style/theme selected.");
        return;
    }
    // The current style is R/O so we need to propagate this change a new style.
    boolean isSubStyleSelected = isSubStyleSelected();
    String message = String.format("<html>The %1$s '<code>%2$s</code>' is Read-Only.<br/>A new %1$s will be created to modify '<code>%3$s</code>'.<br/></html>", isSubStyleSelected ? "style" : "theme", selectedStyle.getQualifiedName(), rv.getName());
    final ItemResourceValue originalValue = rv.getSelectedValue();
    ParentRendererEditor.ThemeParentChangedListener themeListener = new ParentRendererEditor.ThemeParentChangedListener() {

        private ConfiguredThemeEditorStyle myModifiedTheme;

        @Override
        public void themeChanged(@NotNull String name) {
            if (myModifiedTheme != null) {
                myModifiedTheme.getStyleResourceValue().addItem(originalValue);
            }
            myModifiedTheme = myThemeEditorContext.getThemeResolver().getTheme(name);
            assert myModifiedTheme != null;
            ItemResourceValue newSelectedValue = new ItemResourceValue(originalValue.getName(), originalValue.isFrameworkAttr(), strValue, false, null);
            myModifiedTheme.getStyleResourceValue().addItem(newSelectedValue);
            myPreviewThemeName = null;
            refreshPreviewPanel(name);
        }

        @Override
        public void reset() {
            myModifiedTheme.getStyleResourceValue().addItem(originalValue);
            reload(myThemeName);
        }
    };
    final String newStyleName = ThemeEditorUtils.showCreateNewStyleDialog(selectedStyle, myThemeEditorContext, !isSubStyleSelected, false, message, isSubStyleSelected ? null : themeListener);
    if (!isSubStyleSelected) {
        themeListener.reset();
    }
    if (newStyleName == null) {
        return;
    }
    // Need invokeLater to wait for the theme resolver to be aware of the newly created style through the resource change listener
    ApplicationManager.getApplication().invokeLater(new Runnable() {

        @Override
        public void run() {
            myThemeEditorContext.updateThemeResolver();
            ConfiguredThemeEditorStyle newStyle = myThemeEditorContext.getThemeResolver().getTheme(newStyleName);
            assert newStyle != null;
            newStyle.setValue(rv.getQualifiedName(), strValue);
        }
    });
    if (!isSubStyleSelected) {
        // We changed a theme, so we are done.
        // We don't need to call reload, because myResourceChangeListener will take care of it
        myThemeName = newStyleName;
        mySubStyleName = null;
        return;
    }
    ConfiguredThemeEditorStyle selectedTheme = getSelectedTheme();
    if (selectedTheme == null) {
        LOG.error("No theme selected.");
        return;
    }
    // Decide what property we need to modify.
    // If the modified style was pointed by a theme attribute, we need to use that theme attribute value
    // as property. Otherwise, just update the original property name with the new style.
    final String sourcePropertyName = mySubStyleSourceAttribute.isAttr() ? mySubStyleSourceAttribute.getAttrPropertyName() : mySubStyleSourceAttribute.getQualifiedName();
    // We've modified a sub-style so we need to modify the attribute that was originally pointing to this.
    if (selectedTheme.isReadOnly()) {
        // The theme pointing to the new style is r/o so create a new theme and then write the value.
        message = String.format("<html>The style '%1$s' which references to '%2$s' is also Read-Only.<br/>" + "A new theme will be created to point to the modified style '%3$s'.<br/></html>", selectedTheme.getQualifiedName(), rv.getName(), newStyleName);
        final String newThemeName = ThemeEditorUtils.showCreateNewStyleDialog(selectedTheme, myThemeEditorContext, true, false, message, themeListener);
        themeListener.reset();
        if (newThemeName != null) {
            // We don't need to call reload, because myResourceChangeListener will take care of it
            myThemeName = newThemeName;
            mySubStyleName = newStyleName;
            // Need invokeLater to wait for the theme resolver to be aware of the newly created theme through the resource change listener
            ApplicationManager.getApplication().invokeLater(new Runnable() {

                @Override
                public void run() {
                    myThemeEditorContext.updateThemeResolver();
                    ConfiguredThemeEditorStyle newTheme = myThemeEditorContext.getThemeResolver().getTheme(newThemeName);
                    assert newTheme != null;
                    newTheme.setValue(sourcePropertyName, newStyleName);
                }
            });
        }
    } else {
        selectedTheme.setValue(sourcePropertyName, newStyleName);
        // We don't need to call reload, because myResourceChangeListener will take care of it
        mySubStyleName = newStyleName;
    }
}
Also used : ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) ParentRendererEditor(com.android.tools.idea.editors.theme.attributes.editors.ParentRendererEditor) NotNull(org.jetbrains.annotations.NotNull) ConfiguredThemeEditorStyle(com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle)

Aggregations

ConfiguredThemeEditorStyle (com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle)41 Configuration (com.android.tools.idea.configurations.Configuration)21 VirtualFile (com.intellij.openapi.vfs.VirtualFile)19 FolderConfiguration (com.android.ide.common.resources.configuration.FolderConfiguration)13 ItemResourceValue (com.android.ide.common.rendering.api.ItemResourceValue)9 EditedStyleItem (com.android.tools.idea.editors.theme.datamodels.EditedStyleItem)9 ConfigurationManager (com.android.tools.idea.configurations.ConfigurationManager)8 NotNull (org.jetbrains.annotations.NotNull)6 ResourceResolver (com.android.ide.common.resources.ResourceResolver)5 AttributesTableModel (com.android.tools.idea.editors.theme.attributes.AttributesTableModel)4 ResourceValue (com.android.ide.common.rendering.api.ResourceValue)2 ParentThemesListModel (com.android.tools.idea.editors.theme.ParentThemesListModel)2 ConfiguredElement (com.android.tools.idea.editors.theme.datamodels.ConfiguredElement)2 PsiElement (com.intellij.psi.PsiElement)2 TableModel (javax.swing.table.TableModel)2 Nullable (org.jetbrains.annotations.Nullable)2 ResourceType (com.android.resources.ResourceType)1 IAndroidTarget (com.android.sdklib.IAndroidTarget)1 ThemeResolver (com.android.tools.idea.editors.theme.ThemeResolver)1 AttributesModelColorPaletteModel (com.android.tools.idea.editors.theme.attributes.AttributesModelColorPaletteModel)1