diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index 4d03e93b0..f6af41125 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -118,7 +118,10 @@ - + + + + diff --git a/src/com/magento/idea/magento2plugin/actions/generation/OverrideFileInThemeAction.java b/src/com/magento/idea/magento2plugin/actions/generation/OverrideFileInThemeAction.java new file mode 100644 index 000000000..ff7323d45 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/OverrideFileInThemeAction.java @@ -0,0 +1,105 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.magento.idea.magento2plugin.magento.packages.ComponentType; +import com.magento.idea.magento2plugin.magento.packages.Package; +import com.magento.idea.magento2plugin.project.Settings; +import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil; +import javax.swing.Icon; +import org.jetbrains.annotations.NotNull; + +public abstract class OverrideFileInThemeAction extends AnAction { + + protected PsiFile psiFile; + + /** + * Override file in theme action constructor. + * + * @param actionName String + * @param actionDescription String + * @param module Icon + */ + public OverrideFileInThemeAction( + final String actionName, + final String actionDescription, + final Icon module + ) { + super(actionName, actionDescription, module); + } + + /** + * Action entry point. + * + * @param event AnActionEvent + */ + @Override + public void update(final @NotNull AnActionEvent event) { + setStatus(event, false); + final Project project = event.getData(PlatformDataKeys.PROJECT); + final PsiFile targetFile = event.getData(PlatformDataKeys.PSI_FILE); + + if (project == null || targetFile == null) { + return; + } + + if (Settings.isEnabled(project) && isOverrideAllowed(targetFile, project)) { + setStatus(event, true); + psiFile = targetFile; + } + } + + /** + * Implement this method to specify if override allowed for particular file types. + * + * @param file PsiFile + * @param project Project + * + * @return boolean + */ + protected abstract boolean isOverrideAllowed( + final @NotNull PsiFile file, + final @NotNull Project project + ); + + /** + * Check if file has a path specific to the Magento 2 module or theme. + * + * @param file PsiFile + * @param project Project + * + * @return boolean + */ + protected boolean isFileInModuleOrTheme( + final @NotNull PsiFile file, + final @NotNull Project project + ) { + final GetMagentoModuleUtil.MagentoModuleData moduleData = + GetMagentoModuleUtil.getByContext(file.getContainingDirectory(), project); + + if (moduleData == null) { + return false; + } + final VirtualFile virtualFile = file.getVirtualFile(); + + if (moduleData.getType().equals(ComponentType.module)) { + return virtualFile.getPath().contains("/" + Package.moduleViewDir + "/"); + } else { + return moduleData.getType().equals(ComponentType.theme); + } + } + + private void setStatus(final AnActionEvent event, final boolean status) { + event.getPresentation().setVisible(status); + event.getPresentation().setEnabled(status); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/OverrideInThemeAction.java b/src/com/magento/idea/magento2plugin/actions/generation/OverrideInThemeAction.java deleted file mode 100644 index 85a77e67a..000000000 --- a/src/com/magento/idea/magento2plugin/actions/generation/OverrideInThemeAction.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -package com.magento.idea.magento2plugin.actions.generation; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.project.DumbAwareAction; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import com.magento.idea.magento2plugin.MagentoIcons; -import com.magento.idea.magento2plugin.actions.generation.dialog.OverrideInThemeDialog; -import com.magento.idea.magento2plugin.magento.packages.ComponentType; -import com.magento.idea.magento2plugin.magento.packages.Package; -import com.magento.idea.magento2plugin.project.Settings; -import com.magento.idea.magento2plugin.util.magento.GetComponentNameByDirectoryUtil; -import com.magento.idea.magento2plugin.util.magento.GetComponentTypeByNameUtil; -import org.jetbrains.annotations.NotNull; - -public class OverrideInThemeAction extends DumbAwareAction { - - public static final String ACTION_NAME = "Override this template in a project theme"; - public static final String ACTION_DESCRIPTION = "Override in project theme"; - private PsiFile psiFile; - - public OverrideInThemeAction() { - super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE); - } - - /** - * Action entry point. - * - * @param event AnActionEvent - */ - @Override - public void update(final @NotNull AnActionEvent event) { - boolean status = false; - final Project project = event.getData(PlatformDataKeys.PROJECT); - psiFile = event.getData(PlatformDataKeys.PSI_FILE); - - if (Settings.isEnabled(project)) { - try { - status = isOverrideAllowed( - psiFile.getVirtualFile(), - project - ); - } catch (NullPointerException e) { //NOPMD - // Ignore - } - } - - this.setStatus(event, status); - } - - private boolean isOverrideAllowed(final VirtualFile file, final Project project) { - if (file.isDirectory()) { - return false; - } - - boolean isAllowed = false; - - final String componentType = GetComponentTypeByNameUtil.execute( - GetComponentNameByDirectoryUtil.execute(psiFile.getContainingDirectory(), project) - ); - - if (componentType.equals(ComponentType.module.toString())) { - isAllowed = file.getPath().contains(Package.moduleViewDir); - } else if (componentType.equals(ComponentType.theme.toString())) { - isAllowed = true; - } - - return isAllowed; - } - - private void setStatus(final AnActionEvent event, final boolean status) { - event.getPresentation().setVisible(status); - event.getPresentation().setEnabled(status); - } - - @Override - public void actionPerformed(final @NotNull AnActionEvent event) { - OverrideInThemeDialog.open(event.getProject(), this.psiFile); - } - - @Override - public boolean isDumbAware() { - return false; - } -} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/OverrideLayoutInThemeAction.java b/src/com/magento/idea/magento2plugin/actions/generation/OverrideLayoutInThemeAction.java new file mode 100644 index 000000000..e37abacaf --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/OverrideLayoutInThemeAction.java @@ -0,0 +1,59 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlFile; +import com.magento.idea.magento2plugin.MagentoIcons; +import com.magento.idea.magento2plugin.actions.generation.dialog.OverrideLayoutInThemeDialog; +import com.magento.idea.magento2plugin.magento.files.LayoutXml; +import org.jetbrains.annotations.NotNull; + +public class OverrideLayoutInThemeAction extends OverrideFileInThemeAction { + + public static final String ACTION_NAME = "Override this layout in a project theme"; + public static final String ACTION_DESCRIPTION = "Override layout in project theme"; + + public OverrideLayoutInThemeAction() { + super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE); + } + + @Override + public void actionPerformed(final @NotNull AnActionEvent event) { + final Project project = event.getProject(); + + if (project == null || psiFile == null) { + return; + } + OverrideLayoutInThemeDialog.open(project, psiFile); + } + + @Override + protected boolean isOverrideAllowed( + final @NotNull PsiFile file, + final @NotNull Project project + ) { + final VirtualFile virtualFile = file.getVirtualFile(); + + if (virtualFile == null || virtualFile.isDirectory()) { + return false; + } + + if (!(file instanceof XmlFile)) { + return false; + } + + if (!LayoutXml.PARENT_DIR.equals(file.getContainingDirectory().getName()) + && !LayoutXml.PAGE_LAYOUT_DIR.equals(file.getContainingDirectory().getName())) { + return false; + } + + return isFileInModuleOrTheme(file, project); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/OverrideTemplateInThemeAction.java b/src/com/magento/idea/magento2plugin/actions/generation/OverrideTemplateInThemeAction.java new file mode 100644 index 000000000..325ac90ca --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/OverrideTemplateInThemeAction.java @@ -0,0 +1,57 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.magento.idea.magento2plugin.MagentoIcons; +import com.magento.idea.magento2plugin.actions.CopyMagentoPath; +import com.magento.idea.magento2plugin.actions.generation.dialog.OverrideTemplateInThemeDialog; +import org.jetbrains.annotations.NotNull; + +public class OverrideTemplateInThemeAction extends OverrideFileInThemeAction { + + public static final String ACTION_NAME = "Override this file in a project theme"; + public static final String ACTION_TEMPLATE_DESCRIPTION = "Override template in project theme"; + public static final String ACTION_STYLES_DESCRIPTION = "Override styles in project theme"; + public static final String LESS_FILE_EXTENSION = "less"; + + public OverrideTemplateInThemeAction() { + super(ACTION_NAME, ACTION_TEMPLATE_DESCRIPTION, MagentoIcons.MODULE); + } + + @Override + public void actionPerformed(final @NotNull AnActionEvent event) { + final Project project = event.getProject(); + + if (project == null || psiFile == null) { + return; + } + OverrideTemplateInThemeDialog.open(project, psiFile); + } + + @Override + protected boolean isOverrideAllowed( + final @NotNull PsiFile file, + final @NotNull Project project + ) { + final VirtualFile virtualFile = file.getVirtualFile(); + + if (virtualFile == null || virtualFile.isDirectory()) { + return false; + } + final String fileExtension = virtualFile.getExtension(); + + if (!CopyMagentoPath.PHTML_EXTENSION.equals(fileExtension) + && !LESS_FILE_EXTENSION.equals(fileExtension)) { + return false; + } + + return isFileInModuleOrTheme(file, project); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideInTheme.form b/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideLayoutInTheme.form similarity index 99% rename from src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideInTheme.form rename to src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideLayoutInTheme.form index 392e93cac..6f7e2862f 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideInTheme.form +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideLayoutInTheme.form @@ -1,5 +1,5 @@ - + diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideInThemeDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideLayoutInThemeDialog.java similarity index 65% rename from src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideInThemeDialog.java rename to src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideLayoutInThemeDialog.java index 01d11059c..727f1363d 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideInThemeDialog.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideLayoutInThemeDialog.java @@ -6,14 +6,18 @@ package com.magento.idea.magento2plugin.actions.generation.dialog; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; -import com.magento.idea.magento2plugin.actions.generation.OverrideInThemeAction; +import com.magento.idea.magento2plugin.actions.generation.OverrideLayoutInThemeAction; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule; -import com.magento.idea.magento2plugin.actions.generation.generator.OverrideInThemeGenerator; +import com.magento.idea.magento2plugin.actions.generation.generator.OverrideLayoutInThemeGenerator; import com.magento.idea.magento2plugin.indexes.ModuleIndex; import com.magento.idea.magento2plugin.magento.packages.Areas; +import com.magento.idea.magento2plugin.magento.packages.ComponentType; +import com.magento.idea.magento2plugin.magento.packages.Package; +import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; @@ -28,15 +32,16 @@ import javax.swing.KeyStroke; import org.jetbrains.annotations.NotNull; -public class OverrideInThemeDialog extends AbstractDialog { - @NotNull - private final Project project; +public class OverrideLayoutInThemeDialog extends AbstractDialog { + + private static final String THEME_NAME = "target theme"; + + private final @NotNull Project project; private final PsiFile psiFile; private JPanel contentPane; private JButton buttonOK; private JButton buttonCancel; private JLabel selectTheme; //NOPMD - private static final String THEME_NAME = "target theme"; @FieldValidation(rule = RuleRegistry.NOT_EMPTY, message = {NotEmptyRule.MESSAGE, THEME_NAME}) @@ -50,7 +55,10 @@ public class OverrideInThemeDialog extends AbstractDialog { * @param project Project * @param psiFile PsiFile */ - public OverrideInThemeDialog(final @NotNull Project project, final PsiFile psiFile) { + public OverrideLayoutInThemeDialog( + final @NotNull Project project, + final @NotNull PsiFile psiFile + ) { super(); this.project = project; @@ -58,7 +66,7 @@ public OverrideInThemeDialog(final @NotNull Project project, final PsiFile psiFi setContentPane(contentPane); setModal(true); - setTitle(OverrideInThemeAction.ACTION_DESCRIPTION); + setTitle(OverrideLayoutInThemeAction.ACTION_DESCRIPTION); getRootPane().setDefaultButton(buttonOK); fillThemeOptions(); @@ -85,58 +93,74 @@ public void windowClosing(final WindowEvent event) { addComponentListener(new FocusOnAFieldListener(() -> theme.requestFocusInWindow())); } - private void onOverride() { - this.radioButtonOverride.setSelected(true); - this.radioButtonExtend.setSelected(false); - } - - private void onExtend() { - this.radioButtonOverride.setSelected(false); - this.radioButtonExtend.setSelected(true); + /** + * Open popup. + * + * @param project Project + * @param psiFile PsiFile + */ + public static void open(final @NotNull Project project, final @NotNull PsiFile psiFile) { + final OverrideLayoutInThemeDialog dialog = + new OverrideLayoutInThemeDialog(project, psiFile); + dialog.pack(); + dialog.centerDialog(dialog); + dialog.setVisible(true); } private void onOK() { if (validateFormFields()) { - final OverrideInThemeGenerator overrideInThemeGenerator = - new OverrideInThemeGenerator(project); + final OverrideLayoutInThemeGenerator overrideLayoutInThemeGenerator = + new OverrideLayoutInThemeGenerator(project); - overrideInThemeGenerator.execute(psiFile, this.getTheme(), this.isOverride()); + overrideLayoutInThemeGenerator.execute(psiFile, getTheme(), isOverride()); + exit(); } - exit(); } - public String getTheme() { + private String getTheme() { return this.theme.getSelectedItem().toString(); } - /** - * Is Override. - * - * @return boolean - */ - public boolean isOverride() { + private boolean isOverride() { return this.radioButtonOverride.isSelected(); } - /** - * Open popup. - * - * @param project Project - * @param psiFile PsiFile - */ - public static void open(final @NotNull Project project, final PsiFile psiFile) { - final OverrideInThemeDialog dialog = new OverrideInThemeDialog(project, psiFile); - dialog.pack(); - dialog.centerDialog(dialog); - dialog.setVisible(true); + private void onOverride() { + this.radioButtonOverride.setSelected(true); + this.radioButtonExtend.setSelected(false); + } + + private void onExtend() { + this.radioButtonOverride.setSelected(false); + this.radioButtonExtend.setSelected(true); } private void fillThemeOptions() { - final String area = psiFile.getVirtualFile().getPath().split("view/")[1].split("/")[0]; + final GetMagentoModuleUtil.MagentoModuleData moduleData = + GetMagentoModuleUtil.getByContext(psiFile.getContainingDirectory(), project); + + if (moduleData == null) { + return; + } + String area = ""; // NOPMD; + + if (moduleData.getType().equals(ComponentType.module)) { + final PsiDirectory viewDir = moduleData.getViewDir(); + + if (viewDir == null) { + return; + } + final String filePath = psiFile.getVirtualFile().getPath(); + final String relativePath = filePath.replace(viewDir.getVirtualFile().getPath(), ""); + area = relativePath.split(Package.V_FILE_SEPARATOR)[1]; + } else { + area = moduleData.getName().split(Package.V_FILE_SEPARATOR)[0]; + } final List themeNames = new ModuleIndex(project).getEditableThemeNames(); for (final String themeName : themeNames) { - if (Areas.base.toString().equals(area) || themeName.split("/")[0].equals(area)) { + if (Areas.base.toString().equals(area) + || themeName.split(Package.V_FILE_SEPARATOR)[0].equals(area)) { theme.addItem(themeName); } } diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideTemplateInThemeDialog.form b/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideTemplateInThemeDialog.form new file mode 100644 index 000000000..598e8eb48 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideTemplateInThemeDialog.form @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideTemplateInThemeDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideTemplateInThemeDialog.java new file mode 100644 index 000000000..31920f0e4 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideTemplateInThemeDialog.java @@ -0,0 +1,154 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.magento.idea.magento2plugin.actions.CopyMagentoPath; +import com.magento.idea.magento2plugin.actions.generation.OverrideTemplateInThemeAction; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule; +import com.magento.idea.magento2plugin.actions.generation.generator.OverrideTemplateInThemeGenerator; +import com.magento.idea.magento2plugin.indexes.ModuleIndex; +import com.magento.idea.magento2plugin.magento.packages.Areas; +import com.magento.idea.magento2plugin.magento.packages.ComponentType; +import com.magento.idea.magento2plugin.magento.packages.Package; +import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.List; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import org.jetbrains.annotations.NotNull; + +public class OverrideTemplateInThemeDialog extends AbstractDialog { + + private static final String THEME_NAME = "target theme"; + + private final @NotNull Project project; + private final PsiFile psiFile; + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + private JLabel selectTheme; //NOPMD + + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, THEME_NAME}) + private JComboBox theme; + + /** + * Constructor. + * + * @param project Project + * @param psiFile PsiFile + */ + public OverrideTemplateInThemeDialog( + final @NotNull Project project, + final @NotNull PsiFile psiFile + ) { + super(); + + this.project = project; + this.psiFile = psiFile; + + setContentPane(contentPane); + setModal(true); + + if (CopyMagentoPath.PHTML_EXTENSION.equals(psiFile.getVirtualFile().getExtension())) { + setTitle(OverrideTemplateInThemeAction.ACTION_TEMPLATE_DESCRIPTION); + } else { + setTitle(OverrideTemplateInThemeAction.ACTION_STYLES_DESCRIPTION); + } + getRootPane().setDefaultButton(buttonOK); + fillThemeOptions(); + + buttonOK.addActionListener((final ActionEvent event) -> onOK()); + buttonCancel.addActionListener((final ActionEvent event) -> onCancel()); + + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(final WindowEvent event) { + onCancel(); + } + }); + + contentPane.registerKeyboardAction( + (final ActionEvent event) -> onCancel(), + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + + addComponentListener(new FocusOnAFieldListener(() -> theme.requestFocusInWindow())); + } + + /** + * Open popup. + * + * @param project Project + * @param psiFile PsiFile + */ + public static void open(final @NotNull Project project, final @NotNull PsiFile psiFile) { + final OverrideTemplateInThemeDialog dialog = + new OverrideTemplateInThemeDialog(project, psiFile); + dialog.pack(); + dialog.centerDialog(dialog); + dialog.setVisible(true); + } + + private void onOK() { + if (validateFormFields()) { + final OverrideTemplateInThemeGenerator overrideInThemeGenerator = + new OverrideTemplateInThemeGenerator(project); + + overrideInThemeGenerator.execute(psiFile, this.getTheme()); + exit(); + } + } + + private String getTheme() { + return this.theme.getSelectedItem().toString(); + } + + private void fillThemeOptions() { + final GetMagentoModuleUtil.MagentoModuleData moduleData = + GetMagentoModuleUtil.getByContext(psiFile.getContainingDirectory(), project); + + if (moduleData == null) { + return; + } + String area = ""; // NOPMD + + if (moduleData.getType().equals(ComponentType.module)) { + final PsiDirectory viewDir = moduleData.getViewDir(); + + if (viewDir == null) { + return; + } + final String filePath = psiFile.getVirtualFile().getPath(); + final String relativePath = filePath.replace(viewDir.getVirtualFile().getPath(), ""); + area = relativePath.split(Package.V_FILE_SEPARATOR)[1]; + } else { + area = moduleData.getName().split(Package.V_FILE_SEPARATOR)[0]; + } + final List themeNames = new ModuleIndex(project).getEditableThemeNames(); + + for (final String themeName : themeNames) { + if (Areas.base.toString().equals(area) + || themeName.split(Package.V_FILE_SEPARATOR)[0].equals(area)) { + theme.addItem(themeName); + } + } + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideInThemeGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideInThemeGenerator.java index 94f092bb2..b13e93030 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideInThemeGenerator.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideInThemeGenerator.java @@ -5,107 +5,73 @@ package com.magento.idea.magento2plugin.actions.generation.generator; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; -import com.maddyhome.idea.copyright.actions.UpdateCopyrightProcessor; import com.magento.idea.magento2plugin.actions.generation.generator.util.DirectoryGenerator; import com.magento.idea.magento2plugin.bundles.ValidatorBundle; -import com.magento.idea.magento2plugin.indexes.ModuleIndex; import com.magento.idea.magento2plugin.magento.packages.Areas; -import com.magento.idea.magento2plugin.magento.packages.ComponentType; import com.magento.idea.magento2plugin.util.RegExUtil; -import com.magento.idea.magento2plugin.util.magento.GetComponentNameByDirectoryUtil; -import com.magento.idea.magento2plugin.util.magento.GetComponentTypeByNameUtil; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; -public class OverrideInThemeGenerator { - private final ValidatorBundle validatorBundle; +@SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod") +public abstract class OverrideInThemeGenerator { - private final Project project; + protected final Project project; + protected final ValidatorBundle validatorBundle; + /** + * OverrideInThemeGenerator constructor. + * + * @param project Project + */ public OverrideInThemeGenerator(final Project project) { this.project = project; this.validatorBundle = new ValidatorBundle(); } /** - * Action entry point. + * Get target directory. * - * @param baseFile PsiFile - * @param themeName String - * @param isOverride boolean + * @param directory PsiDirectory + * @param pathComponents List[String] + * + * @return PsiDirectory */ - public void execute(final PsiFile baseFile, final String themeName, final boolean isOverride) { - final String componentType = GetComponentTypeByNameUtil.execute( - GetComponentNameByDirectoryUtil - .execute(baseFile.getContainingDirectory(), project)); - - List pathComponents; - if (componentType.equals(ComponentType.module.toString())) { - pathComponents = getModulePathComponents( - baseFile, - GetComponentNameByDirectoryUtil.execute( - baseFile.getContainingDirectory(), - project - ) - ); - if (isOverride) { - pathComponents.add("override"); - pathComponents.add("base"); - } - } else if (componentType.equals(ComponentType.theme.toString())) { - pathComponents = getThemePathComponents(baseFile); - } else { - return; - } - - final ModuleIndex moduleIndex = new ModuleIndex(project); - PsiDirectory directory = moduleIndex.getModuleDirectoryByModuleName(themeName); - - if (directory == null) { - return; - } - directory = getTargetDirectory(directory, pathComponents); + protected PsiDirectory getTargetDirectory( + final PsiDirectory directory, + final List pathComponents + ) { + PsiDirectory result = directory; + PsiDirectory tempDirectory = directory; + final DirectoryGenerator generator = DirectoryGenerator.getInstance(); - if (directory.findFile(baseFile.getName()) != null) { - JBPopupFactory.getInstance() - .createMessage( - validatorBundle.message("validator.file.alreadyExists", baseFile.getName()) - ) - .showCenteredInCurrentWindow(project); - directory.findFile(baseFile.getName()).navigate(true); - return; + for (final String directoryName : pathComponents) { + result = generator.findOrCreateSubdirectory(tempDirectory, directoryName); + tempDirectory = result; } - final PsiDirectory finalDirectory = directory; - ApplicationManager.getApplication().runWriteAction(() -> { - finalDirectory.copyFileFrom(baseFile.getName(), baseFile); - }); - - final PsiFile newFile = directory.findFile(baseFile.getName()); - assert newFile != null; - final Module module = ModuleUtilCore.findModuleForPsiElement(newFile); - final UpdateCopyrightProcessor processor = new UpdateCopyrightProcessor( - project, - module, - newFile - ); - processor.run(); - - newFile.navigate(true); + return result; } - private List getModulePathComponents(final PsiFile file, final String componentName) { + /** + * Gt module path components. + * + * @param file PsiFile + * @param componentName String + * + * @return List[String] + */ + protected List getModulePathComponents( + final PsiFile file, + final String componentName + ) { final List pathComponents = new ArrayList<>(); PsiDirectory parent = file.getParent(); + while (!parent.getName().equals(Areas.frontend.toString()) && !parent.getName().equals(Areas.adminhtml.toString()) && !parent.getName().equals(Areas.base.toString()) @@ -119,7 +85,14 @@ private List getModulePathComponents(final PsiFile file, final String co return pathComponents; } - private List getThemePathComponents(final PsiFile file) { + /** + * Get theme path components. + * + * @param file PsiFile + * + * @return String[] + */ + protected List getThemePathComponents(final PsiFile file) { final List pathComponents = new ArrayList<>(); final Pattern pattern = Pattern.compile(RegExUtil.Magento.MODULE_NAME); @@ -133,18 +106,4 @@ private List getThemePathComponents(final PsiFile file) { return pathComponents; } - - private PsiDirectory getTargetDirectory( - PsiDirectory directory, //NOPMD - final List pathComponents - ) { - PsiDirectory result = directory; - final DirectoryGenerator generator = DirectoryGenerator.getInstance(); - - for (final String directoryName : pathComponents) { - result = generator.findOrCreateSubdirectory(directory, directoryName); - } - - return result; - } } diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideLayoutInThemeGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideLayoutInThemeGenerator.java new file mode 100644 index 000000000..9654c88f9 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideLayoutInThemeGenerator.java @@ -0,0 +1,118 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.maddyhome.idea.copyright.actions.UpdateCopyrightProcessor; +import com.magento.idea.magento2plugin.indexes.ModuleIndex; +import com.magento.idea.magento2plugin.magento.packages.ComponentType; +import com.magento.idea.magento2plugin.magento.packages.Package; +import com.magento.idea.magento2plugin.util.magento.GetComponentNameByDirectoryUtil; +import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil; +import java.util.List; + +public class OverrideLayoutInThemeGenerator extends OverrideInThemeGenerator { + + /** + * OverrideLayoutInThemeGenerator constructor. + * + * @param project Project + */ + public OverrideLayoutInThemeGenerator(final Project project) { + super(project); + } + + /** + * Action entry point. + * + * @param baseFile PsiFile + * @param themeName String + * @param isOverride boolean + */ + public void execute( + final PsiFile baseFile, + final String themeName, + final boolean isOverride + ) { + final GetMagentoModuleUtil.MagentoModuleData moduleData = + GetMagentoModuleUtil.getByContext(baseFile.getContainingDirectory(), project); + + if (moduleData == null) { + return; + } + List pathComponents; + + if (moduleData.getType().equals(ComponentType.module)) { + pathComponents = getModulePathComponents( + baseFile, + GetComponentNameByDirectoryUtil.execute( + baseFile.getContainingDirectory(), + project + ) + ); + if (isOverride) { + pathComponents.add("override"); + pathComponents.add("base"); + } + } else if (moduleData.getType().equals(ComponentType.theme)) { + pathComponents = getThemePathComponents(baseFile); + + if (isOverride) { + pathComponents.add("override"); + pathComponents.add("theme"); + final String[] parentThemeName = + moduleData.getName().split(Package.V_FILE_SEPARATOR); + pathComponents.add(parentThemeName[1]); + pathComponents.add(parentThemeName[2]); + } + } else { + return; + } + + final ModuleIndex moduleIndex = new ModuleIndex(project); + PsiDirectory directory = moduleIndex.getModuleDirectoryByModuleName(themeName); + + if (directory == null) { + return; + } + directory = getTargetDirectory(directory, pathComponents); + + if (directory.findFile(baseFile.getName()) != null) { + JBPopupFactory.getInstance() + .createMessage( + validatorBundle.message( + "validator.file.alreadyExists", + baseFile.getName()) + ) + .showCenteredInCurrentWindow(project); + directory.findFile(baseFile.getName()).navigate(true); + return; + } + + final PsiDirectory finalDirectory = directory; + ApplicationManager.getApplication().runWriteAction(() -> { + finalDirectory.copyFileFrom(baseFile.getName(), baseFile); + }); + + final PsiFile newFile = directory.findFile(baseFile.getName()); + assert newFile != null; + final Module module = ModuleUtilCore.findModuleForPsiElement(newFile); + final UpdateCopyrightProcessor processor = new UpdateCopyrightProcessor( + project, + module, + newFile + ); + processor.run(); + + newFile.navigate(true); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideTemplateInThemeGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideTemplateInThemeGenerator.java new file mode 100644 index 000000000..f2e76d0ca --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/OverrideTemplateInThemeGenerator.java @@ -0,0 +1,98 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.maddyhome.idea.copyright.actions.UpdateCopyrightProcessor; +import com.magento.idea.magento2plugin.indexes.ModuleIndex; +import com.magento.idea.magento2plugin.magento.packages.ComponentType; +import com.magento.idea.magento2plugin.util.magento.GetComponentNameByDirectoryUtil; +import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil; +import java.util.List; + +public class OverrideTemplateInThemeGenerator extends OverrideInThemeGenerator { + + /** + * OverrideTemplateInThemeGenerator constructor. + * + * @param project Project + */ + public OverrideTemplateInThemeGenerator(final Project project) { + super(project); + } + + /** + * Action entry point. + * + * @param baseFile PsiFile + * @param themeName String + */ + public void execute(final PsiFile baseFile, final String themeName) { + + final GetMagentoModuleUtil.MagentoModuleData moduleData = + GetMagentoModuleUtil.getByContext(baseFile.getContainingDirectory(), project); + + if (moduleData == null) { + return; + } + + List pathComponents; + if (moduleData.getType().equals(ComponentType.module)) { + pathComponents = getModulePathComponents( + baseFile, + GetComponentNameByDirectoryUtil.execute( + baseFile.getContainingDirectory(), + project + ) + ); + } else if (moduleData.getType().equals(ComponentType.theme)) { + pathComponents = getThemePathComponents(baseFile); + } else { + return; + } + + final ModuleIndex moduleIndex = new ModuleIndex(project); + PsiDirectory directory = moduleIndex.getModuleDirectoryByModuleName(themeName); + + if (directory == null) { + return; + } + directory = getTargetDirectory(directory, pathComponents); + + if (directory.findFile(baseFile.getName()) != null) { + JBPopupFactory.getInstance() + .createMessage( + validatorBundle.message("validator.file.alreadyExists", baseFile.getName()) + ) + .showCenteredInCurrentWindow(project); + directory.findFile(baseFile.getName()).navigate(true); + return; + } + + final PsiDirectory finalDirectory = directory; + ApplicationManager.getApplication().runWriteAction(() -> { + finalDirectory.copyFileFrom(baseFile.getName(), baseFile); + }); + + final PsiFile newFile = directory.findFile(baseFile.getName()); + assert newFile != null; + final Module module = ModuleUtilCore.findModuleForPsiElement(newFile); + final UpdateCopyrightProcessor processor = new UpdateCopyrightProcessor( + project, + module, + newFile + ); + processor.run(); + + newFile.navigate(true); + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/files/LayoutXml.java b/src/com/magento/idea/magento2plugin/magento/files/LayoutXml.java index cfe0910a8..df887fd87 100644 --- a/src/com/magento/idea/magento2plugin/magento/files/LayoutXml.java +++ b/src/com/magento/idea/magento2plugin/magento/files/LayoutXml.java @@ -22,6 +22,7 @@ public class LayoutXml implements ModuleFileInterface { public static final String XML_ATTRIBUTE_TEMPLATE = "template"; public static final String ARGUMENTS_TEMPLATE = "Magento Module Class Arguments In Xml"; public static final String PARENT_DIR = "layout"; + public static final String PAGE_LAYOUT_DIR = "page_layout"; public static final String NAME_ATTRIBUTE = "name"; public static final String CONTENT_CONTAINER_NAME = "content"; diff --git a/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java b/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java index 503844a89..f1218c26b 100644 --- a/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java +++ b/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java @@ -10,6 +10,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.SlowOperations; import com.jetbrains.php.lang.psi.elements.ClassConstantReference; import com.jetbrains.php.lang.psi.elements.MethodReference; import com.jetbrains.php.lang.psi.elements.StringLiteralExpression; @@ -108,7 +109,10 @@ private static PsiFile getModuleRegistrationFile( private static String parseParameterValue(final PsiElement valueHolder) { if (valueHolder instanceof ClassConstantReference) { - final PsiElement resolved = ((ClassConstantReference) valueHolder).resolve(); + final ClassConstantReference constantReference = (ClassConstantReference) valueHolder; + final PsiElement resolved = SlowOperations.allowSlowOperations( + constantReference::resolve + ); if (!(resolved instanceof ClassConstImpl)) { return null;