diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fb02a1e6..f6e5ee206 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0). ## 5.1.0 +### Added + +- Possibility to add second code source directory [#1297](https://github.com/magento/magento2-phpstorm-plugin/pull/1297) + ## 5.0.1 ### Fixed diff --git a/src/com/magento/idea/magento2plugin/indexes/ModuleIndex.java b/src/com/magento/idea/magento2plugin/indexes/ModuleIndex.java index f71d648c5..4e29d9ba6 100644 --- a/src/com/magento/idea/magento2plugin/indexes/ModuleIndex.java +++ b/src/com/magento/idea/magento2plugin/indexes/ModuleIndex.java @@ -16,6 +16,7 @@ import com.intellij.util.indexing.FileBasedIndex; import com.jetbrains.php.lang.PhpFileType; import com.magento.idea.magento2plugin.magento.packages.Package; +import com.magento.idea.magento2plugin.project.Settings; import com.magento.idea.magento2plugin.project.util.GetProjectBasePath; import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex; import com.magento.idea.magento2plugin.util.RegExUtil; @@ -41,7 +42,7 @@ public ModuleIndex(final Project project) { } public List getEditableModuleNames() { - return getModuleNames(Package.vendor, true); + return getModuleNames("/" + Package.vendor + "/|/tests/|/test/", true); } public List getEditableThemeNames() { @@ -83,7 +84,6 @@ private List getNames( .getInstance(); final List allModulesList = new ArrayList<>(); final Collection allModules = index.getAllKeys(ModuleNameIndex.KEY, project); - final Pattern compiled = Pattern.compile(filterPattern); for (final String moduleName : allModules) { if (!moduleName.matches(pattern)) { continue; @@ -98,21 +98,43 @@ private List getNames( continue; } final VirtualFile virtualFile = files.iterator().next(); - if (withinProject && !VfsUtilCore - .isAncestor(GetProjectBasePath.execute(project), virtualFile, false)) { + if (!isValid(filterPattern, withinProject, virtualFile)) { continue; } - final Matcher matcher = compiled.matcher(virtualFile.getPath()); - if (matcher.find()) { - continue; - } allModulesList.add(moduleName); } Collections.sort(allModulesList); return allModulesList; } + private boolean isValid(String filterPattern, boolean withinProject, VirtualFile virtualFile) { + if (!withinProject) { + return true; + } + + VirtualFile baseFile = GetProjectBasePath.execute(project); + if (baseFile == null) { + return false; + } + + final String path = virtualFile.getPath(); + final String additionalSourceDir = Settings.getAdditionalCodeSourceDirectory(project); + if (additionalSourceDir != null + && !additionalSourceDir.isEmpty() + && path.startsWith(additionalSourceDir)) { + return true; + } + + if (!VfsUtilCore.isAncestor(baseFile, virtualFile, false)) { + return false; + }; + + final Pattern compiled = Pattern.compile(filterPattern); + final Matcher matcher = compiled.matcher(virtualFile.getPath()); + return !matcher.find(); + } + /** * Returns PSI directory of the certain module. * diff --git a/src/com/magento/idea/magento2plugin/project/Settings.java b/src/com/magento/idea/magento2plugin/project/Settings.java index 5f33a19b9..40080fb76 100644 --- a/src/com/magento/idea/magento2plugin/project/Settings.java +++ b/src/com/magento/idea/magento2plugin/project/Settings.java @@ -31,6 +31,7 @@ public class Settings implements PersistentStateComponent { public boolean pluginEnabled; public static String defaultLicense = "Proprietary"; public String magentoPath; + public String additionalCodeSourceDirectory; public boolean mftfSupportEnabled; public boolean myDoNotAskContentConfigAgain; public String magentoVersion; @@ -42,6 +43,7 @@ public Settings.State getState() { return new Settings.State( this.pluginEnabled, this.magentoPath, + this.additionalCodeSourceDirectory, defaultLicense, this.mftfSupportEnabled, this.myDoNotAskContentConfigAgain, @@ -65,6 +67,7 @@ public void setState(final State state) { public void loadState(final @NotNull Settings.State state) { this.pluginEnabled = state.isPluginEnabled(); this.magentoPath = state.getMagentoPath(); + this.additionalCodeSourceDirectory = state.getAdditionalCodeSourceDirectory(); this.defaultLicense = state.getDefaultLicenseName(); this.mftfSupportEnabled = state.isMftfSupportEnabled(); this.myDoNotAskContentConfigAgain = state.isDoNotAskContentConfigAgain(); @@ -122,12 +125,18 @@ public static String getMagentoPath(final @NotNull Project project) { return getInstance(project).magentoPath; } + @Nullable + public static String getAdditionalCodeSourceDirectory(final @NotNull Project project) { + return getInstance(project).additionalCodeSourceDirectory; + } + @SuppressWarnings({"PMD.DataClass"}) @Tag public static class State { public boolean pluginEnabled; public String defaultLicenseName; public String magentoPath; + public String additionalCodeSourceDirectory; public boolean mftfSupportEnabled; public boolean myDoNotAskContentConfigAgain; public String magentoVersion; @@ -150,6 +159,7 @@ public State() {//NOPMD public State( final boolean pluginEnabled, final String magentoPath, + final String additionalCodeSourceDirectory, final String defaultLicenseName, final boolean mftfSupportEnabled, final boolean myDoNotAskContentConfigAgain, @@ -158,6 +168,7 @@ public State( ) { this.pluginEnabled = pluginEnabled; this.magentoPath = magentoPath; + this.additionalCodeSourceDirectory = additionalCodeSourceDirectory; this.defaultLicenseName = defaultLicenseName; this.mftfSupportEnabled = mftfSupportEnabled; this.myDoNotAskContentConfigAgain = myDoNotAskContentConfigAgain; @@ -183,6 +194,15 @@ public void setMagentoPath(final String magentoPath) { this.magentoPath = magentoPath; } + public String getAdditionalCodeSourceDirectory() { + return this.additionalCodeSourceDirectory; + } + + @Tag("additionalCodeSourceDirectory") + public void setAdditionalCodeSourceDirectory(final String additionalCodeSourceDirectory) { + this.additionalCodeSourceDirectory = additionalCodeSourceDirectory; + } + public String getMagentoVersion() { return this.magentoVersion; } @@ -253,6 +273,9 @@ public boolean equals(final Object objectToCompare) { if (this.magentoPath != null) { return this.magentoPath.equals(state.magentoPath); } + if (this.additionalCodeSourceDirectory != null) { + return this.additionalCodeSourceDirectory.equals(state.additionalCodeSourceDirectory); + } if (this.defaultLicenseName != null) { return this.defaultLicenseName.equals(state.defaultLicenseName); } else { @@ -269,6 +292,7 @@ public boolean equals(final Object objectToCompare) { public int hashCode() { int result = this.isPluginEnabled() ? 1 : 0; result = 31 * result + (this.magentoPath != null ? this.magentoPath.hashCode() : 0); + result = 31 * result + (this.additionalCodeSourceDirectory != null ? this.additionalCodeSourceDirectory.hashCode() : 0); result = 31 * result + (this.isMftfSupportEnabled() ? 1 : 0); result = 31 * result + (this.isDoNotAskContentConfigAgain() ? 1 : 0); result = 31 * result + ( diff --git a/src/com/magento/idea/magento2plugin/project/SettingsForm.form b/src/com/magento/idea/magento2plugin/project/SettingsForm.form index 58fc6561b..eca79fe13 100644 --- a/src/com/magento/idea/magento2plugin/project/SettingsForm.form +++ b/src/com/magento/idea/magento2plugin/project/SettingsForm.form @@ -3,7 +3,7 @@ - + @@ -16,6 +16,8 @@ + + @@ -101,6 +103,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/com/magento/idea/magento2plugin/project/SettingsForm.java b/src/com/magento/idea/magento2plugin/project/SettingsForm.java index 55f747bf6..66defc8ba 100644 --- a/src/com/magento/idea/magento2plugin/project/SettingsForm.java +++ b/src/com/magento/idea/magento2plugin/project/SettingsForm.java @@ -23,12 +23,7 @@ import com.magento.idea.magento2plugin.util.magento.MagentoVersionUtil; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextField; +import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.jetbrains.annotations.Nls; @@ -55,6 +50,8 @@ public class SettingsForm implements PhpFrameworkConfigurable { private final SettingsFormValidator validator = new SettingsFormValidator(this); private JLabel magentoVersionLabel;//NOPMD private JLabel magentoPathLabel;//NOPMD + private JLabel additionalCodeSourceDirectoryLabel;//NOPMD + private TextFieldWithBrowseButton additionalCodeSourceDirectory; public SettingsForm(@NotNull final Project project) { this.project = project; @@ -95,9 +92,11 @@ public void mouseClicked(final MouseEvent event) { moduleDefaultLicenseName.setText(getSettings().defaultLicense); mftfSupportEnabled.setSelected(getSettings().mftfSupportEnabled); magentoPath.getTextField().setText(getSettings().magentoPath); + additionalCodeSourceDirectory.getTextField().setText(getSettings().additionalCodeSourceDirectory); resolveMagentoVersion(); addPathListener(); + addAdditionalCodeSourceListener(); addMagentoVersionListener(); updateMagentoVersion(); @@ -130,9 +129,10 @@ public boolean isModified() { final boolean mftfSupportChanged = mftfSupportEnabled.isSelected() != getSettings().mftfSupportEnabled; final boolean magentoPathChanged = isMagentoPathChanged(); + final boolean additionalCodeSourceDirectoryChanged = isAdditionalCodeSourceDirectoryChanged(); return statusChanged || licenseChanged || mftfSupportChanged - || magentoPathChanged || versionChanged; + || magentoPathChanged || versionChanged || additionalCodeSourceDirectoryChanged; } private void resolveMagentoVersion() { @@ -145,6 +145,11 @@ private boolean isMagentoPathChanged() { return !magentoPath.getTextField().getText().equals(getSettings().magentoPath); } + private boolean isAdditionalCodeSourceDirectoryChanged() { + return !additionalCodeSourceDirectory.getTextField() + .getText().equals(getSettings().additionalCodeSourceDirectory); + } + @Override public void apply() throws ConfigurationException { this.validator.validate(); @@ -162,6 +167,7 @@ private void saveSettings() { getSettings().defaultLicense = moduleDefaultLicenseName.getText(); getSettings().mftfSupportEnabled = mftfSupportEnabled.isSelected(); getSettings().magentoPath = getMagentoPath(); + getSettings().additionalCodeSourceDirectory = getAdditionalCodeSourceDirectory(); buttonReindex.setEnabled(getSettings().pluginEnabled); regenerateUrnMapButton.setEnabled(getSettings().pluginEnabled); } @@ -176,6 +182,11 @@ public String getMagentoPath() { return magentoPath.getTextField().getText().trim(); } + @NotNull + public String getAdditionalCodeSourceDirectory() { + return additionalCodeSourceDirectory.getTextField().getText().trim(); + } + @Override public void reset() { pluginEnabled.setSelected(getSettings().pluginEnabled); @@ -220,6 +231,36 @@ protected VirtualFile getInitialFile() { this.magentoPath.addActionListener(browseFolderListener); } + private void addAdditionalCodeSourceListener() { + final FileChooserDescriptor descriptor = + FileChooserDescriptorFactory.createSingleFolderDescriptor(); + final ComponentWithBrowseButton.BrowseFolderActionListener browseFolderListener + = new ComponentWithBrowseButton.BrowseFolderActionListener( + "Source Directory", + "Choose Additional Code Source directory", + this.additionalCodeSourceDirectory, + project, + descriptor, + TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT + ) { + @Nullable + @Override + protected VirtualFile getInitialFile() { + + final String text = getComponentText(); + if (text.length() == 0) { + final VirtualFile file = GetProjectBasePath.execute(project); + if (file != null) { + return file; + } + } + + return super.getInitialFile(); + } + }; + this.additionalCodeSourceDirectory.addActionListener(browseFolderListener); + } + private void addMagentoVersionListener() { final DocumentListener onPathChange = new DocumentListener() { @Override diff --git a/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java b/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java index 3c4541f34..68c359375 100644 --- a/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java +++ b/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java @@ -18,6 +18,7 @@ import com.magento.idea.magento2plugin.magento.files.RegistrationPhp; 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.RegExUtil; import java.util.Collection; import java.util.regex.Matcher; @@ -94,12 +95,7 @@ public static MagentoModuleData getByContext( * @return boolean */ public static boolean isEditableModule(final @NotNull MagentoModuleData moduleData) { - final Pattern pattern = Pattern.compile(RegExUtil.Magento.CUSTOM_VENDOR_NAME); - final Matcher matcher = pattern.matcher( - moduleData.getModuleDir().getVirtualFile().getPath() - ); - - return matcher.find(); + return isDirectoryInEditableModule(moduleData.getModuleDir()); } /** @@ -110,6 +106,12 @@ public static boolean isEditableModule(final @NotNull MagentoModuleData moduleDa * @return boolean */ public static boolean isDirectoryInEditableModule(final @NotNull PsiDirectory directory) { + final String path = directory.getVirtualFile().getPath(); + final String additionalSourceDir = Settings.getAdditionalCodeSourceDirectory(directory.getProject()); + if (additionalSourceDir != null && !additionalSourceDir.isEmpty() && path.startsWith(additionalSourceDir)) { + return true; + } + final Pattern pattern = Pattern.compile(RegExUtil.Magento.CUSTOM_VENDOR_NAME); final Matcher matcher = pattern.matcher(directory.getVirtualFile().getPath());