From e344d4a42f6424fba47f01f41d974ade0f3bfa62 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 10 Sep 2010 16:19:38 +0400 Subject: [PATCH] classpath panel refactored --- .../ui/configuration/ClasspathEditor.java | 7 +- .../classpath/AddItemPopupAction.java | 88 ++ .../ChooseModuleLibrariesDialog.java | 94 +++ .../classpath/ChooseNamedLibraryAction.java | 113 +++ .../ClasspathElementChooserDialog.java | 29 + .../classpath/ClasspathPanel.java | 37 + .../classpath/ClasspathPanelAction.java | 39 + .../ClasspathPanelImpl.java} | 781 ++++-------------- .../classpath/ClasspathTableItem.java | 95 +++ .../classpath/ClasspathTableModel.java | 151 ++++ .../classpath/CreateModuleLibraryDialog.java | 88 ++ .../classpath/InvalidJdkItem.java | 25 + 12 files changed, 901 insertions(+), 646 deletions(-) create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddItemPopupAction.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChooseModuleLibrariesDialog.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChooseNamedLibraryAction.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathElementChooserDialog.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanel.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelAction.java rename java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/{ClasspathPanel.java => classpath/ClasspathPanelImpl.java} (50%) create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathTableItem.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathTableModel.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/CreateModuleLibraryDialog.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/InvalidJdkItem.java diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java index 8fcd543b41ae..ef7f326b509e 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java @@ -26,6 +26,7 @@ import com.intellij.openapi.roots.ModuleRootListener; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.impl.storage.ClasspathStorage; import com.intellij.openapi.roots.impl.storage.ClasspathStorageProvider; +import com.intellij.openapi.roots.ui.configuration.classpath.ClasspathPanelImpl; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; import com.intellij.ui.OrderPanelListener; @@ -46,7 +47,7 @@ public class ClasspathEditor extends ModuleElementsEditor implements ModuleRootL public static final String NAME = ProjectBundle.message("modules.classpath.title"); public static final Icon ICON = IconLoader.getIcon("/modules/classpath.png"); - private ClasspathPanel myPanel; + private ClasspathPanelImpl myPanel; private ClasspathFormatPanel myClasspathFormatPanel; @@ -60,7 +61,7 @@ public class ClasspathEditor extends ModuleElementsEditor implements ModuleRootL } public boolean isModified() { - return super.isModified() || ( myClasspathFormatPanel != null && myClasspathFormatPanel.isModified()); + return super.isModified() || (myClasspathFormatPanel != null && myClasspathFormatPanel.isModified()); } public String getHelpTopic() { @@ -96,7 +97,7 @@ public class ClasspathEditor extends ModuleElementsEditor implements ModuleRootL } public JComponent createComponentImpl() { - myPanel = new ClasspathPanel(getState()); + myPanel = new ClasspathPanelImpl(getState()); myPanel.addListener(new OrderPanelListener() { public void entryMoved() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddItemPopupAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddItemPopupAction.java new file mode 100644 index 000000000000..179a66d7d59f --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddItemPopupAction.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +import com.intellij.openapi.util.Disposer; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; + +/** +* @author nik +*/ +abstract class AddItemPopupAction extends ClasspathPanelAction { + private final String myTitle; + private final Icon myIcon; + private final int myIndex; + + public AddItemPopupAction(ClasspathPanel classpathPanel, int index, String title, Icon icon) { + super(classpathPanel); + myTitle = title; + myIcon = icon; + myIndex = index; + } + + public String getTitle() { + return myTitle; + } + + public Icon getIcon() { + return myIcon; + } + + public int getIndex() { + return myIndex; + } + + @Override + public void run() { + final ClasspathElementChooserDialog dialog = createChooserDialog(); + if (dialog == null) { + return; + } + try { + dialog.doChoose(); + if (!dialog.isOK()) { + return; + } + final List chosen = dialog.getChosenElements(); + if (chosen.isEmpty()) { + return; + } + List toAdd = new ArrayList(); + for (ItemType item : chosen) { + final ClasspathTableItem tableItem = createTableItem(item); + if (tableItem != null) { + toAdd.add(tableItem); + } + } + myClasspathPanel.addItems(toAdd); + } + finally { + if (dialog instanceof ChooseNamedLibraryAction.MyChooserDialog) { + Disposer.dispose(dialog); + } + } + } + + @Nullable + protected abstract ClasspathTableItem createTableItem(final ItemType item); + + @Nullable + protected abstract ClasspathElementChooserDialog createChooserDialog(); +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChooseModuleLibrariesDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChooseModuleLibrariesDialog.java new file mode 100644 index 000000000000..e4b7970fc954 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChooseModuleLibrariesDialog.java @@ -0,0 +1,94 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryFileChooser; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.awt.List; +import java.util.*; + +/** +* @author nik +*/ +class ChooseModuleLibrariesDialog extends LibraryFileChooser implements ClasspathElementChooserDialog { + private Pair myLastChosen; + private final LibraryTable myLibraryTable; + @Nullable private final VirtualFile myFileToSelect; + + public ChooseModuleLibrariesDialog(Component parent, final LibraryTable libraryTable, final VirtualFile fileToSelect) { + super(createFileChooserDescriptor(parent), parent, false, null); + myLibraryTable = libraryTable; + myFileToSelect = fileToSelect; + } + + private static FileChooserDescriptor createFileChooserDescriptor(Component parent) { + final FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, true, false, false, true); + final Module contextModule = LangDataKeys.MODULE_CONTEXT.getData(DataManager.getInstance().getDataContext(parent)); + descriptor.putUserData(LangDataKeys.MODULE_CONTEXT, contextModule); + return descriptor; + } + + public java.util.List getChosenElements() { + if (myLastChosen == null) { + return Collections.emptyList(); + } + final VirtualFile[] files = filterAlreadyAdded(myLastChosen.getSecond()); + if (files.length == 0) { + return Collections.emptyList(); + } + final LibraryTable.ModifiableModel modifiableModel = myLibraryTable.getModifiableModel(); + final java.util.List addedLibraries = new ArrayList(files.length); + for (VirtualFile file : files) { + final Library library = modifiableModel.createLibrary(null); + final Library.ModifiableModel libModel = library.getModifiableModel(); + libModel.addRoot(file, OrderRootType.CLASSES); + libModel.commit(); + addedLibraries.add(library); + } + return addedLibraries; + } + + private VirtualFile[] filterAlreadyAdded(final VirtualFile[] files) { + if (files == null || files.length == 0) { + return VirtualFile.EMPTY_ARRAY; + } + final Set chosenFilesSet = new HashSet(Arrays.asList(files)); + final Set alreadyAdded = new HashSet(); + final Library[] libraries = myLibraryTable.getLibraries(); + for (Library library : libraries) { + ContainerUtil.addAll(alreadyAdded, library.getFiles(OrderRootType.CLASSES)); + } + chosenFilesSet.removeAll(alreadyAdded); + return VfsUtil.toVirtualFileArray(chosenFilesSet); + } + + public void doChoose() { + myLastChosen = chooseNameAndFiles(myFileToSelect); + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChooseNamedLibraryAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChooseNamedLibraryAction.java new file mode 100644 index 000000000000..78aa9bc6e593 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChooseNamedLibraryAction.java @@ -0,0 +1,113 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +import com.intellij.openapi.project.ProjectBundle; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.impl.libraries.LibraryImpl; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryTableEditor; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Disposer; +import com.intellij.util.Icons; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** +* @author nik +*/ +class ChooseNamedLibraryAction extends AddItemPopupAction { + private final LibraryTableModifiableModelProvider myLibraryTableModelProvider; + + public ChooseNamedLibraryAction(ClasspathPanel classpathPanel, + final int index, + final String title, + final LibraryTableModifiableModelProvider libraryTable) { + super(classpathPanel, index, title, Icons.LIBRARY_ICON); + myLibraryTableModelProvider = libraryTable; + } + + @Nullable + protected ClasspathTableItem createTableItem(final Library item) { + // clear invalid order entry corresponding to added library if any + final ModifiableRootModel rootModel = myClasspathPanel.getRootModel(); + final OrderEntry[] orderEntries = rootModel.getOrderEntries(); + for (OrderEntry orderEntry : orderEntries) { + if (orderEntry instanceof LibraryOrderEntry) { + if (item.getName().equals(((LibraryOrderEntry)orderEntry).getLibraryName())) { + if (orderEntry.isValid()) { + Messages.showErrorDialog(ProjectBundle.message("classpath.message.library.already.added",item.getName()), + ProjectBundle.message("classpath.title.adding.dependency")); + return null; + } else { + rootModel.removeOrderEntry(orderEntry); + } + } + } + } + return ClasspathTableItem.createLibItem(rootModel.addLibraryEntry(item)); + } + + protected ClasspathElementChooserDialog createChooserDialog() { + return new MyChooserDialog(); + } + + private Collection getAlreadyAddedLibraries() { + final OrderEntry[] orderEntries = myClasspathPanel.getRootModel().getOrderEntries(); + final Set result = new HashSet(orderEntries.length); + for (OrderEntry orderEntry : orderEntries) { + if (orderEntry instanceof LibraryOrderEntry && orderEntry.isValid()) { + final LibraryImpl library = (LibraryImpl)((LibraryOrderEntry)orderEntry).getLibrary(); + if (library != null) { + result.add(library.getSource()); + } + } + } + return result; + } + + class MyChooserDialog implements ClasspathElementChooserDialog { + private final LibraryTableEditor myEditor; + private Library[] myLibraries; + + MyChooserDialog(){ + myEditor = LibraryTableEditor.editLibraryTable(myLibraryTableModelProvider, myClasspathPanel.getProject()); + Disposer.register(this, myEditor); + } + + public List getChosenElements() { + final List chosen = new ArrayList(Arrays.asList(myLibraries)); + chosen.removeAll(getAlreadyAddedLibraries()); + return chosen; + } + + public void doChoose() { + final Iterator iter = myLibraryTableModelProvider.getModifiableModel().getLibraryIterator(); + myLibraries = myEditor.openDialog(myClasspathPanel.getComponent(), iter.hasNext()? Collections.singleton((Library)iter.next()) : Collections.emptyList(), false); + } + + public boolean isOK() { + return myLibraries != null; + } + + public void dispose() { + } + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathElementChooserDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathElementChooserDialog.java new file mode 100644 index 000000000000..56befffab2f7 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathElementChooserDialog.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +import com.intellij.openapi.Disposable; + +import java.util.List; + +/** +* @author nik +*/ +interface ClasspathElementChooserDialog extends Disposable { + List getChosenElements(); + void doChoose(); + boolean isOK(); +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanel.java new file mode 100644 index 000000000000..93303e504f51 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanel.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModifiableRootModel; + +import javax.swing.*; +import java.util.List; + +/** + * @author nik + */ +public interface ClasspathPanel { + void runClasspathPanelAction(Runnable action); + + void addItems(List toAdd); + + ModifiableRootModel getRootModel(); + + Project getProject(); + + JComponent getComponent(); +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelAction.java new file mode 100644 index 000000000000..32b2b41cbe69 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelAction.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author nik + */ +abstract class ClasspathPanelAction implements ActionListener, Runnable { + protected final ClasspathPanel myClasspathPanel; + + protected ClasspathPanelAction(ClasspathPanel classpathPanel) { + myClasspathPanel = classpathPanel; + } + + @Override + public void actionPerformed(ActionEvent e) { + execute(); + } + + public final void execute() { + myClasspathPanel.runClasspathPanelAction(this); + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java similarity index 50% rename from java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java rename to java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java index 754be25a271a..a64350a8ffb3 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java @@ -13,27 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.roots.ui.configuration; +package com.intellij.openapi.roots.ui.configuration.classpath; -import com.intellij.ide.DataManager; -import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.StdModuleTypes; +import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; -import com.intellij.openapi.roots.impl.libraries.LibraryImpl; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryTablePresentation; +import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider; +import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.dependencyAnalysis.AnalyzeDependenciesDialog; import com.intellij.openapi.roots.ui.configuration.libraryEditor.ChooseModulesDialog; -import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryFileChooser; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryTableEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.FindUsagesInProjectStructureActionBase; import com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable; @@ -49,26 +49,18 @@ import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.*; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.EventDispatcher; import com.intellij.util.Icons; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.ui.ItemRemovable; import com.intellij.util.ui.Table; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.Border; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import java.awt.*; @@ -76,22 +68,21 @@ import java.awt.event.*; import java.util.*; import java.util.List; -public class ClasspathPanel extends JPanel { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.ClasspathPanel"); +public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.classpath.ClasspathPanel"); private final Table myEntryTable; - private final MyTableModel myModel; + private final ClasspathTableModel myModel; private final EventDispatcher myListeners = EventDispatcher.create(OrderPanelListener.class); - private PopupAction[] myPopupActions = null; - private Icon[] myIcons = null; + private List> myPopupActions = null; private JButton myEditButton; private final ModuleConfigurationState myState; - protected ClasspathPanel(ModuleConfigurationState state) { + public ClasspathPanelImpl(ModuleConfigurationState state) { super(new BorderLayout()); myState = state; - myModel = new MyTableModel(state); + myModel = new ClasspathTableModel(state); myEntryTable = new Table(myModel); myEntryTable.setShowGrid(false); myEntryTable.setDragEnabled(false); @@ -99,7 +90,7 @@ public class ClasspathPanel extends JPanel { myEntryTable.setShowVerticalLines(false); myEntryTable.setIntercellSpacing(new Dimension(0, 0)); - myEntryTable.setDefaultRenderer(TableItem.class, new TableItemRenderer()); + myEntryTable.setDefaultRenderer(ClasspathTableItem.class, new TableItemRenderer()); myEntryTable.setDefaultRenderer(Boolean.class, new ExportFlagRenderer(myEntryTable.getDefaultRenderer(Boolean.class))); JComboBox scopeEditor = new JComboBox(new EnumComboBoxModel(DependencyScope.class)); @@ -126,7 +117,7 @@ public class ClasspathPanel extends JPanel { } public String getElementText(Object element) { - return getCellAppearance((TableItem)element, false).getText(); + return getCellAppearance((ClasspathTableItem)element, false).getText(); } public void selectElement(Object element, String selectedText) { @@ -143,8 +134,8 @@ public class ClasspathPanel extends JPanel { }; - setFixedColumnWidth(MyTableModel.EXPORT_COLUMN, MyTableModel.EXPORT_COLUMN_NAME); - setFixedColumnWidth(MyTableModel.SCOPE_COLUMN, DependencyScope.COMPILE.toString() + " "); // leave space for combobox border + setFixedColumnWidth(ClasspathTableModel.EXPORT_COLUMN, ClasspathTableModel.EXPORT_COLUMN_NAME); + setFixedColumnWidth(ClasspathTableModel.SCOPE_COLUMN, DependencyScope.COMPILE.toString() + " "); // leave space for combobox border myEntryTable.registerKeyboardAction( new ActionListener() { @@ -152,7 +143,7 @@ public class ClasspathPanel extends JPanel { final int[] selectedRows = myEntryTable.getSelectedRows(); boolean currentlyMarked = true; for (final int selectedRow : selectedRows) { - final TableItem item = myModel.getItemAt(myEntryTable.convertRowIndexToModel(selectedRow)); + final ClasspathTableItem item = myModel.getItemAt(myEntryTable.convertRowIndexToModel(selectedRow)); if (selectedRow < 0 || !item.isExportable()) { return; } @@ -277,7 +268,7 @@ public class ClasspathPanel extends JPanel { for (final int selectedRow : selectedRows) { minRow = Math.min(minRow, selectedRow); maxRow = Math.max(maxRow, selectedRow); - final TableItem item = myModel.getItemAt(selectedRow); + final ClasspathTableItem item = myModel.getItemAt(selectedRow); if (!item.isRemovable()) { removeButtonEnabled = false; } @@ -285,25 +276,28 @@ public class ClasspathPanel extends JPanel { upButton.setEnabled(minRow > 0 && minRow < myEntryTable.getRowCount()); downButton.setEnabled(maxRow >= 0 && maxRow < myEntryTable.getRowCount() - 1); removeButton.setEnabled(removeButtonEnabled); - TableItem selectedItem = selectedRows.length == 1 ? myModel.getItemAt(selectedRows[0]) : null; - myEditButton.setEnabled(selectedItem instanceof LibItem && selectedItem.isEditable()); + ClasspathTableItem selectedItem = selectedRows.length == 1 ? myModel.getItemAt(selectedRows[0]) : null; + myEditButton.setEnabled(selectedItem != null && selectedItem.isEditable()); } }); - upButton.addActionListener(new ButtonAction() { - protected void executeImpl() { + upButton.addActionListener(new ClasspathPanelAction(this) { + @Override + public void run() { moveSelectedRows(-1); } }); - downButton.addActionListener(new ButtonAction() { - protected void executeImpl() { + downButton.addActionListener(new ClasspathPanelAction(this) { + @Override + public void run() { moveSelectedRows(+1); } }); - if( isAnalyzeShown) { - analyzeButton.addActionListener(new ButtonAction() { + + if(isAnalyzeShown) { + analyzeButton.addActionListener(new ClasspathPanelAction(this) { @Override - protected void executeImpl() { + public void run() { AnalyzeDependenciesDialog.show(getRootModel().getModule()); } }); @@ -314,17 +308,20 @@ public class ClasspathPanel extends JPanel { addKeyboardShortcut(myEntryTable, upButton, KeyEvent.VK_UP, KeyEvent.CTRL_DOWN_MASK); addKeyboardShortcut(myEntryTable, downButton, KeyEvent.VK_DOWN, KeyEvent.CTRL_DOWN_MASK); - addButton.addActionListener(new ButtonAction() { - protected void executeImpl() { + addButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { initPopupActions(); - final JBPopup popup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep(null, myPopupActions, myIcons) { + final JBPopup popup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep>(null, myPopupActions) { + @Override + public Icon getIconFor(AddItemPopupAction aValue) { + return aValue.getIcon(); + } + public boolean isMnemonicsNavigationEnabled() { return true; } - public boolean isSelectable(PopupAction value) { - return value.isSelectable(); - } - public PopupStep onChosen(final PopupAction selectedValue, final boolean finalChoice) { + public PopupStep onChosen(final AddItemPopupAction selectedValue, final boolean finalChoice) { return doFinalStep(new Runnable() { public void run() { selectedValue.execute(); @@ -332,7 +329,7 @@ public class ClasspathPanel extends JPanel { }); } @NotNull - public String getTextFor(PopupAction value) { + public String getTextFor(AddItemPopupAction value) { return "&" + value.getIndex() + " " + value.getTitle(); } }); @@ -340,14 +337,15 @@ public class ClasspathPanel extends JPanel { } }); - removeButton.addActionListener(new ButtonAction() { - protected void executeImpl() { + removeButton.addActionListener(new ClasspathPanelAction(this) { + @Override + public void run() { final List removedRows = TableUtil.removeSelectedItems(myEntryTable); if (removedRows.isEmpty()) { return; } for (final Object removedRow : removedRows) { - final TableItem item = (TableItem)((Object[])removedRow)[MyTableModel.ITEM_COLUMN]; + final ClasspathTableItem item = (ClasspathTableItem)((Object[])removedRow)[ClasspathTableModel.ITEM_COLUMN]; final OrderEntry orderEntry = item.getEntry(); if (orderEntry == null) { continue; @@ -366,15 +364,11 @@ public class ClasspathPanel extends JPanel { myEditButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final int row = myEntryTable.getSelectedRow(); - final TableItem item = myModel.getItemAt(row); - if (!(item instanceof LibItem)) { - return; - } - final LibraryOrderEntry libraryOrderEntry = ((LibItem)item).getEntry(); - if (libraryOrderEntry == null) { - return; - } - final Library library = libraryOrderEntry.getLibrary(); + final ClasspathTableItem item = myModel.getItemAt(row); + final OrderEntry entry = item.getEntry(); + if (!(entry instanceof LibraryOrderEntry)) return; + + final Library library = ((LibraryOrderEntry)entry).getLibrary(); if (library == null) { return; } @@ -405,7 +399,7 @@ public class ClasspathPanel extends JPanel { } final LibraryTableEditor editor = LibraryTableEditor.editLibrary(provider, library, myState.getProject()); editor.addFileChooserContext(LangDataKeys.MODULE_CONTEXT, getRootModel().getModule()); - editor.openDialog(ClasspathPanel.this, Collections.singletonList(library), true); + editor.openDialog(ClasspathPanelImpl.this, Collections.singletonList(library), true); myEntryTable.repaint(); ModuleStructureConfigurable.getInstance(myState.getProject()).getTree().repaint(); } @@ -427,128 +421,65 @@ public class ClasspathPanel extends JPanel { ); } - private ModifiableRootModel getRootModel() { + @Override + public void runClasspathPanelAction(Runnable action) { + try { + disableModelUpdate(); + action.run(); + } + finally { + enableModelUpdate(); + myEntryTable.requestFocus(); + } + } + + @Override + public void addItems(List toAdd) { + for (ClasspathTableItem item : toAdd) { + myModel.addItem(item); + } + myModel.fireTableDataChanged(); + final ListSelectionModel selectionModel = myEntryTable.getSelectionModel(); + selectionModel.setSelectionInterval(myModel.getRowCount() - toAdd.size(), myModel.getRowCount() - 1); + TableUtil.scrollSelectionToVisible(myEntryTable); + + final StructureConfigurableContext context = ModuleStructureConfigurable.getInstance(myState.getProject()).getContext(); + context.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(context, getRootModel().getModule())); + } + + @Override + public ModifiableRootModel getRootModel() { return myState.getRootModel(); } + @Override + public Project getProject() { + return myState.getProject(); + } + + @Override + public JComponent getComponent() { + return this; + } + public void rootsChanged() { forceInitFromModel(); } - private abstract class ButtonAction implements ActionListener { - public final void actionPerformed(ActionEvent e) { - execute(); - } - - public final void execute() { - try { - disableModelUpdate(); - executeImpl(); - } - finally { - enableModelUpdate(); - myEntryTable.requestFocus(); - } - } - - protected abstract void executeImpl(); - } - - private class PopupAction extends ButtonAction{ - private final String myTitle; - private final Icon myIcon; - private final int myIndex; - - protected PopupAction(String title, Icon icon, final int index) { - myTitle = title; - myIcon = icon; - myIndex = index; - } - - public String getTitle() { - return myTitle; - } - - public Icon getIcon() { - return myIcon; - } - - public int getIndex() { - return myIndex; - } - - public boolean isSelectable() { - return true; - } - - protected void executeImpl() { - } - } - - private abstract class ChooseAndAddAction extends PopupAction{ - public ChooseAndAddAction(int index, String title, Icon icon) { - super(title, icon, index); - } - - protected final void executeImpl() { - final ChooserDialog dialog = createChooserDialog(); - if (dialog == null) { - return; - } - try { - dialog.doChoose(); - if (!dialog.isOK()) { - return; - } - final List chosen = dialog.getChosenElements(); - if (chosen.isEmpty()) { - return; - } - final ModuleStructureConfigurable rootConfigurable = ModuleStructureConfigurable.getInstance(myState.getProject()); - //int insertionIndex = myEntryTable.getSelectedRow(); - for (ItemType item : chosen) { - //myModel.addItemAt(createTableItem(item), insertionIndex++); - final TableItem tableItem = createTableItem(item); - if ( tableItem != null ) { - myModel.addItem(tableItem); - } - } - myModel.fireTableDataChanged(); - final ListSelectionModel selectionModel = myEntryTable.getSelectionModel(); - //selectionModel.setSelectionInterval(insertionIndex - chosen.size(), insertionIndex - 1); - selectionModel.setSelectionInterval(myModel.getRowCount() - chosen.size(), myModel.getRowCount() - 1); - TableUtil.scrollSelectionToVisible(myEntryTable); - - final StructureConfigurableContext context = rootConfigurable.getContext(); - context.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(context, getRootModel().getModule())); - } - finally { - if (dialog instanceof ChooseNamedLibraryAction.MyChooserDialog) { - Disposer.dispose(dialog); - } - } - } - - @Nullable - protected abstract TableItem createTableItem(final ItemType item); - - @Nullable - protected abstract ChooserDialog createChooserDialog(); - } - private void initPopupActions() { if (myPopupActions == null) { final StructureConfigurableContext context = ProjectStructureConfigurable.getInstance(myState.getProject()).getContext(); int actionIndex = 1; - final List actions = new ArrayList(Arrays.asList( - new ChooseAndAddAction(actionIndex++, ProjectBundle.message("classpath.add.simple.module.library.action"), Icons.JAR_ICON) { - protected TableItem createTableItem(final Library item) { + final List> actions = new ArrayList>(); + actions.add( + new AddItemPopupAction(this, actionIndex++, ProjectBundle.message("classpath.add.simple.module.library.action"), Icons.JAR_ICON) { + protected ClasspathTableItem createTableItem(final Library item) { final OrderEntry[] entries = getRootModel().getOrderEntries(); for (OrderEntry entry : entries) { if (entry instanceof LibraryOrderEntry) { final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)entry; if (item.equals(libraryOrderEntry.getLibrary())) { - return new LibItem(libraryOrderEntry); + return ClasspathTableItem.createLibItem(libraryOrderEntry); } } } @@ -556,18 +487,19 @@ public class ClasspathPanel extends JPanel { return null; } - protected ChooserDialog createChooserDialog() { - return new ChooseModuleLibrariesDialog(ClasspathPanel.this, getRootModel().getModuleLibraryTable(), null); + protected ClasspathElementChooserDialog createChooserDialog() { + return new ChooseModuleLibrariesDialog(ClasspathPanelImpl.this, getRootModel().getModuleLibraryTable(), null); } - }, - new ChooseAndAddAction(actionIndex++, ProjectBundle.message("classpath.add.module.library.action"), Icons.JAR_ICON) { - protected TableItem createTableItem(final Library item) { + }); + actions.add( + new AddItemPopupAction(this, actionIndex++, ProjectBundle.message("classpath.add.module.library.action"), Icons.JAR_ICON) { + protected ClasspathTableItem createTableItem(final Library item) { final OrderEntry[] entries = getRootModel().getOrderEntries(); for (OrderEntry entry : entries) { if (entry instanceof LibraryOrderEntry) { final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)entry; if (item.equals(libraryOrderEntry.getLibrary())) { - return new LibItem(libraryOrderEntry); + return ClasspathTableItem.createLibItem(libraryOrderEntry); } } } @@ -575,39 +507,36 @@ public class ClasspathPanel extends JPanel { return null; } - protected ChooserDialog createChooserDialog() { - return new CreateModuleLibraryDialog(ClasspathPanel.this, getRootModel().getModuleLibraryTable()); + protected ClasspathElementChooserDialog createChooserDialog() { + return new CreateModuleLibraryDialog(ClasspathPanelImpl.this, getRootModel().getModuleLibraryTable()); } - }, - new ChooseNamedLibraryAction(actionIndex++, ProjectBundle.message("classpath.add.project.library.action"), context.getProjectLibrariesProvider(true)), - new ChooseNamedLibraryAction(actionIndex++, ProjectBundle.message("classpath.add.global.library.action"), context.getGlobalLibrariesProvider(true)))); + }); + actions.add(new ChooseNamedLibraryAction(this, actionIndex++, ProjectBundle.message("classpath.add.project.library.action"), + context.getProjectLibrariesProvider(true))); + actions.add(new ChooseNamedLibraryAction(this, actionIndex++, ProjectBundle.message("classpath.add.global.library.action"), + context.getGlobalLibrariesProvider(true))); for (final LibraryTableModifiableModelProvider provider : context.getCustomLibrariesProviders(true)) { - actions.add(new ChooseNamedLibraryAction(actionIndex++, provider.getLibraryTablePresentation().getDisplayName(false) + "...", provider)); + actions.add(new ChooseNamedLibraryAction(this, actionIndex++, provider.getLibraryTablePresentation().getDisplayName(false) + "...", provider)); } - actions.add(new ChooseAndAddAction(actionIndex, ProjectBundle.message("classpath.add.module.dependency.action"), + actions.add(new AddItemPopupAction(this, actionIndex, ProjectBundle.message("classpath.add.module.dependency.action"), StdModuleTypes.JAVA.getNodeIcon(false)) { - protected TableItem createTableItem(final Module item) { - return new ModuleItem(getRootModel().addModuleOrderEntry(item)); + protected ClasspathTableItem createTableItem(final Module item) { + return ClasspathTableItem.createItem(getRootModel().addModuleOrderEntry(item)); } - protected ChooserDialog createChooserDialog() { + protected ClasspathElementChooserDialog createChooserDialog() { final List chooseItems = getDependencyModules(); if (chooseItems.isEmpty()) { - Messages.showMessageDialog(ClasspathPanel.this, ProjectBundle.message("message.no.module.dependency.candidates"), getTitle(), Messages.getInformationIcon()); + Messages.showMessageDialog(ClasspathPanelImpl.this, ProjectBundle.message("message.no.module.dependency.candidates"), getTitle(), Messages.getInformationIcon()); return null; } return new ChooseModulesToAddDialog(chooseItems, ProjectBundle.message("classpath.chooser.title.add.module.dependency")); } } - ); + ); - myPopupActions = actions.toArray(new PopupAction[actions.size()]); - - myIcons = new Icon[myPopupActions.length]; - for (int idx = 0; idx < myPopupActions.length; idx++) { - myIcons[idx] = myPopupActions[idx].getIcon(); - } + myPopupActions = actions; } } @@ -665,7 +594,7 @@ public class ClasspathPanel extends JPanel { private int moveRow(final int row, final int increment) { int newIndex = Math.abs(row + increment) % myModel.getRowCount(); - final TableItem item = myModel.removeDataRow(row); + final ClasspathTableItem item = myModel.removeDataRow(row); myModel.addItemAt(item, newIndex); return newIndex; } @@ -693,7 +622,7 @@ public class ClasspathPanel extends JPanel { } } - void forceInitFromModel() { + public void forceInitFromModel() { final int[] selection = myEntryTable.getSelectedRows(); myModel.clear(); myModel.init(); @@ -725,241 +654,8 @@ public class ClasspathPanel extends JPanel { } - private abstract static class TableItem { - @Nullable protected final T myEntry; - - protected TableItem(@Nullable T entry) { - myEntry = entry; - } - - public final boolean isExportable() { - return myEntry instanceof ExportableOrderEntry; - } - - public final boolean isExported() { - return isExportable() && ((ExportableOrderEntry)getEntry()).isExported(); - } - - public final void setExported(boolean isExported) { - if (isExportable()) { - ((ExportableOrderEntry)getEntry()).setExported(isExported); - } - } - - @Nullable - public final DependencyScope getScope() { - return myEntry instanceof ExportableOrderEntry ? ((ExportableOrderEntry) myEntry).getScope() : null; - } - - public final void setScope(DependencyScope scope) { - if (myEntry instanceof ExportableOrderEntry) { - ((ExportableOrderEntry) myEntry).setScope(scope); - } - } - - public final T getEntry() { - return myEntry; - } - - public abstract boolean isRemovable(); - public abstract boolean isEditable(); - } - - private static class LibItem extends TableItem { - public LibItem(LibraryOrderEntry entry) { - super(entry); - } - - public boolean isRemovable() { - return true; - } - - public boolean isEditable() { - final LibraryOrderEntry orderEntry = getEntry(); - return orderEntry != null && orderEntry.isValid(); - } - } - - private static class ModuleItem extends TableItem { - public ModuleItem(final ModuleOrderEntry entry) { - super(entry); - } - - public boolean isRemovable() { - return true; - } - - public boolean isEditable() { - return true; - } - } - - private static class JdkItem extends TableItem { - public JdkItem(final JdkOrderEntry entry) { - super(entry); - } - - public boolean isRemovable() { - return false; - } - - public boolean isEditable() { - return true; - } - } - - private static class SelfModuleItem extends TableItem { - public SelfModuleItem(final ModuleSourceOrderEntry entry) { - super(entry); - } - - public boolean isRemovable() { - return false; - } - - public boolean isEditable() { - return false; - } - } - - private static class MyTableModel extends AbstractTableModel implements ItemRemovable { - private static final String EXPORT_COLUMN_NAME = ProjectBundle.message("modules.order.export.export.column"); - private static final String SCOPE_COLUMN_NAME = ProjectBundle.message("modules.order.export.scope.column"); - public static final int EXPORT_COLUMN = 0; - public static final int ITEM_COLUMN = 1; - public static final int SCOPE_COLUMN = 2; - private final List myItems = new ArrayList(); - private final ModuleConfigurationState myState; - - public MyTableModel(final ModuleConfigurationState state) { - myState = state; - init(); - } - - private ModifiableRootModel getModel() { - return myState.getRootModel(); - } - - public void init() { - final OrderEntry[] orderEntries = getModel().getOrderEntries(); - boolean hasJdkOrderEntry = false; - for (final OrderEntry orderEntry : orderEntries) { - if (orderEntry instanceof JdkOrderEntry) { - hasJdkOrderEntry = true; - } - addOrderEntry(orderEntry); - } - if (!hasJdkOrderEntry) { - addItemAt(new JdkItem(null), 0); - } - } - - private void addOrderEntry(OrderEntry orderEntry) { - if (orderEntry instanceof JdkOrderEntry) { - addItem(new JdkItem((JdkOrderEntry)orderEntry)); - } - else if (orderEntry instanceof LibraryOrderEntry) { - addItem(new LibItem((LibraryOrderEntry)orderEntry)); - } - else if (orderEntry instanceof ModuleOrderEntry) { - addItem(new ModuleItem((ModuleOrderEntry)orderEntry)); - } - else if (orderEntry instanceof ModuleSourceOrderEntry) { - addItem(new SelfModuleItem((ModuleSourceOrderEntry)orderEntry)); - } - } - - public TableItem getItemAt(int row) { - return myItems.get(row); - } - - public void addItem(TableItem item) { - myItems.add(item); - } - - public void addItemAt(TableItem item, int row) { - myItems.add(row, item); - } - - public TableItem removeDataRow(int row) { - return myItems.remove(row); - } - - public void removeRow(int row) { - removeDataRow(row); - } - - public void clear() { - myItems.clear(); - } - - public int getRowCount() { - return myItems.size(); - } - - public Object getValueAt(int rowIndex, int columnIndex) { - final TableItem item = myItems.get(rowIndex); - if (columnIndex == EXPORT_COLUMN) { - return item.isExported(); - } - if (columnIndex == SCOPE_COLUMN) { - return item.getScope(); - } - if (columnIndex == ITEM_COLUMN) { - return item; - } - LOG.error("Incorrect column index: " + columnIndex); - return null; - } - - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - final TableItem item = myItems.get(rowIndex); - if (columnIndex == EXPORT_COLUMN) { - item.setExported(((Boolean)aValue).booleanValue()); - } - else if (columnIndex == SCOPE_COLUMN && aValue instanceof DependencyScope) { - item.setScope((DependencyScope) aValue); - } - } - - public String getColumnName(int column) { - if (column == EXPORT_COLUMN) { - return EXPORT_COLUMN_NAME; - } - if (column == SCOPE_COLUMN) { - return SCOPE_COLUMN_NAME; - } - return ""; - } - - public Class getColumnClass(int column) { - if (column == EXPORT_COLUMN) { - return Boolean.class; - } - if (column == SCOPE_COLUMN) { - return DependencyScope.class; - } - if (column == ITEM_COLUMN) { - return TableItem.class; - } - return super.getColumnClass(column); - } - - public int getColumnCount() { - return 3; - } - - public boolean isCellEditable(int row, int column) { - if (column == EXPORT_COLUMN || column == SCOPE_COLUMN) { - final TableItem item = myItems.get(row); - return item != null && item.isExportable(); - } - return false; - } - } - - private static CellAppearance getCellAppearance(final TableItem item, final boolean selected) { - if (item instanceof JdkItem && item.getEntry() == null) { + private static CellAppearance getCellAppearance(final ClasspathTableItem item, final boolean selected) { + if (item instanceof InvalidJdkItem) { return OrderEntryCellAppearanceUtils.forJdk(null, false, selected); } else { @@ -974,8 +670,8 @@ public class ClasspathPanel extends JPanel { setPaintFocusBorder(false); setFocusBorderAroundIcon(true); setBorder(NO_FOCUS_BORDER); - if (value instanceof TableItem) { - getCellAppearance((TableItem)value, selected).customize(this); + if (value instanceof ClasspathTableItem) { + getCellAppearance((ClasspathTableItem)value, selected).customize(this); } } } @@ -998,15 +694,9 @@ public class ClasspathPanel extends JPanel { } } - private interface ChooserDialog extends Disposable { - List getChosenElements(); - void doChoose(); - boolean isOK(); - } - - private class ChooseModulesToAddDialog extends ChooseModulesDialog implements ChooserDialog{ + private class ChooseModulesToAddDialog extends ChooseModulesDialog implements ClasspathElementChooserDialog { public ChooseModulesToAddDialog(final List items, final String title) { - super(ClasspathPanel.this, items, title); + super(ClasspathPanelImpl.this, items, title); } public void doChoose() { @@ -1017,193 +707,6 @@ public class ClasspathPanel extends JPanel { super.dispose(); } } - private static class CreateModuleLibraryDialog implements ChooserDialog { - private boolean myIsOk; - private final ClasspathPanel myParent; - private final LibraryTable myLibraryTable; - private Library myChosenLibrary; - - public CreateModuleLibraryDialog(ClasspathPanel parent, final LibraryTable libraryTable) { - myParent = parent; - myLibraryTable = libraryTable; - } - - public List getChosenElements() { - return myChosenLibrary == null? Collections.emptyList() : Collections.singletonList(myChosenLibrary); - } - - public void doChoose() { - final LibraryTable.ModifiableModel libraryModifiableModel = myLibraryTable.getModifiableModel(); - final LibraryTableModifiableModelProvider provider = new LibraryTableModifiableModelProvider() { - public LibraryTable.ModifiableModel getModifiableModel() { - return libraryModifiableModel; - } - - public String getTableLevel() { - return myLibraryTable.getTableLevel(); - } - - public LibraryTablePresentation getLibraryTablePresentation() { - return myLibraryTable.getPresentation(); - } - - public boolean isLibraryTableEditable() { - return false; - } - }; - final Library library = myLibraryTable.createLibrary(); - final LibraryTableEditor editor = LibraryTableEditor.editLibrary(provider, library, myParent.myState.getProject()); - final Module contextModule = DataKeys.MODULE_CONTEXT.getData(DataManager.getInstance().getDataContext(myParent)); - editor.addFileChooserContext(LangDataKeys.MODULE_CONTEXT, contextModule); - myIsOk = editor.openDialog(myParent, Collections.singletonList(library), true) != null; - if (myIsOk) { - myChosenLibrary = library; - } - else { - myChosenLibrary = null; - libraryModifiableModel.removeLibrary(library); - } - } - - public boolean isOK() { - return myIsOk; - } - - public void dispose() { - } - } - - private static class ChooseModuleLibrariesDialog extends LibraryFileChooser implements ChooserDialog { - private Pair myLastChosen; - private final LibraryTable myLibraryTable; - @Nullable private final VirtualFile myFileToSelect; - - public ChooseModuleLibrariesDialog(Component parent, final LibraryTable libraryTable, final VirtualFile fileToSelect) { - super(createFileChooserDescriptor(parent), parent, false, null); - myLibraryTable = libraryTable; - myFileToSelect = fileToSelect; - } - - private static FileChooserDescriptor createFileChooserDescriptor(Component parent) { - final FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, true, false, false, true); - final Module contextModule = LangDataKeys.MODULE_CONTEXT.getData(DataManager.getInstance().getDataContext(parent)); - descriptor.putUserData(LangDataKeys.MODULE_CONTEXT, contextModule); - return descriptor; - } - - public List getChosenElements() { - if (myLastChosen == null) { - return Collections.emptyList(); - } - final VirtualFile[] files = filterAlreadyAdded(myLastChosen.getSecond()); - if (files.length == 0) { - return Collections.emptyList(); - } - final LibraryTable.ModifiableModel modifiableModel = myLibraryTable.getModifiableModel(); - final List addedLibraries = new ArrayList(files.length); - for (VirtualFile file : files) { - final Library library = modifiableModel.createLibrary(null); - final Library.ModifiableModel libModel = library.getModifiableModel(); - libModel.addRoot(file, OrderRootType.CLASSES); - libModel.commit(); - addedLibraries.add(library); - } - return addedLibraries; - } - - private VirtualFile[] filterAlreadyAdded(final VirtualFile[] files) { - if (files == null || files.length == 0) { - return VirtualFile.EMPTY_ARRAY; - } - final Set chosenFilesSet = new HashSet(Arrays.asList(files)); - final Set alreadyAdded = new HashSet(); - final Library[] libraries = myLibraryTable.getLibraries(); - for (Library library : libraries) { - ContainerUtil.addAll(alreadyAdded, library.getFiles(OrderRootType.CLASSES)); - } - chosenFilesSet.removeAll(alreadyAdded); - return VfsUtil.toVirtualFileArray(chosenFilesSet); - } - - public void doChoose() { - myLastChosen = chooseNameAndFiles(myFileToSelect); - } - } - - private class ChooseNamedLibraryAction extends ChooseAndAddAction { - private final LibraryTableModifiableModelProvider myLibraryTableModelProvider; - - public ChooseNamedLibraryAction(final int index, final String title, final LibraryTableModifiableModelProvider libraryTable) { - super(index, title, Icons.LIBRARY_ICON); - myLibraryTableModelProvider = libraryTable; - } - - @Nullable - protected TableItem createTableItem(final Library item) { - // clear invalid order entry corresponding to added library if any - final OrderEntry[] orderEntries = getRootModel().getOrderEntries(); - for (OrderEntry orderEntry : orderEntries) { - if (orderEntry instanceof LibraryOrderEntry ) { - if (item.getName().equals(((LibraryOrderEntry)orderEntry).getLibraryName())) { - if ( orderEntry.isValid() ) { - Messages.showErrorDialog(ProjectBundle.message("classpath.message.library.already.added",item.getName()), - ProjectBundle.message("classpath.title.adding.dependency")); - return null; - } else { - getRootModel().removeOrderEntry(orderEntry); - } - } - } - } - return new LibItem(getRootModel().addLibraryEntry(item)); - } - - protected ChooserDialog createChooserDialog() { - return new MyChooserDialog(); - } - - private Collection getAlreadyAddedLibraries() { - final OrderEntry[] orderEntries = getRootModel().getOrderEntries(); - final Set result = new HashSet(orderEntries.length); - for (OrderEntry orderEntry : orderEntries) { - if (orderEntry instanceof LibraryOrderEntry && orderEntry.isValid()) { - final LibraryImpl library = (LibraryImpl)((LibraryOrderEntry)orderEntry).getLibrary(); - if (library != null) { - result.add(library.getSource()); - } - } - } - return result; - } - - private class MyChooserDialog implements ChooserDialog { - private final LibraryTableEditor myEditor; - private Library[] myLibraries; - - MyChooserDialog(){ - myEditor = LibraryTableEditor.editLibraryTable(myLibraryTableModelProvider, myState.getProject()); - Disposer.register(this, myEditor); - } - - public List getChosenElements() { - final List chosen = new ArrayList(Arrays.asList(myLibraries)); - chosen.removeAll(getAlreadyAddedLibraries()); - return chosen; - } - - public void doChoose() { - final Iterator iter = myLibraryTableModelProvider.getModifiableModel().getLibraryIterator(); - myLibraries = myEditor.openDialog(ClasspathPanel.this, iter.hasNext()? Collections.singleton((Library)iter.next()) : Collections.emptyList(), false); - } - - public boolean isOK() { - return myLibraries != null; - } - - public void dispose() { - } - } - } private class MyFindUsagesAction extends FindUsagesInProjectStructureActionBase { private MyFindUsagesAction() { @@ -1217,32 +720,24 @@ public class ClasspathPanel extends JPanel { protected ProjectStructureElement getSelectedElement() { int row = myEntryTable.getSelectedRow(); if (0 <= row && row < myModel.getRowCount()) { - TableItem item = myModel.getItemAt(row); - if (item instanceof LibItem) { - LibraryOrderEntry orderEntry = ((LibItem)item).getEntry(); - if (orderEntry != null) { - final Library library = orderEntry.getLibrary(); - if (library != null) { - return new LibraryProjectStructureElement(getContext(), library); - } + ClasspathTableItem item = myModel.getItemAt(row); + final OrderEntry entry = item.getEntry(); + if (entry instanceof LibraryOrderEntry) { + final Library library = ((LibraryOrderEntry)entry).getLibrary(); + if (library != null) { + return new LibraryProjectStructureElement(getContext(), library); } } - else if (item instanceof ModuleItem) { - ModuleOrderEntry orderEntry = ((ModuleItem)item).getEntry(); - if (orderEntry != null) { - final Module module = orderEntry.getModule(); - if (module != null) { - return new ModuleProjectStructureElement(getContext(), module); - } + else if (entry instanceof ModuleOrderEntry) { + final Module module = ((ModuleOrderEntry)entry).getModule(); + if (module != null) { + return new ModuleProjectStructureElement(getContext(), module); } } - else if (item instanceof JdkItem) { - JdkOrderEntry orderEntry = ((JdkItem)item).getEntry(); - if (orderEntry != null) { - final Sdk jdk = orderEntry.getJdk(); - if (jdk != null) { - return new SdkProjectStructureElement(getContext(), jdk); - } + else if (entry instanceof JdkOrderEntry) { + final Sdk jdk = ((JdkOrderEntry)entry).getJdk(); + if (jdk != null) { + return new SdkProjectStructureElement(getContext(), jdk); } } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathTableItem.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathTableItem.java new file mode 100644 index 000000000000..3b6689d3383a --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathTableItem.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +import com.intellij.openapi.roots.*; +import org.jetbrains.annotations.Nullable; + +/** +* @author nik +*/ +class ClasspathTableItem { + @Nullable protected final OrderEntry myEntry; + private final boolean myRemovable; + + @Nullable + public static ClasspathTableItem createItem(OrderEntry orderEntry) { + if (orderEntry instanceof JdkOrderEntry) { + return new ClasspathTableItem(orderEntry, false); + } + else if (orderEntry instanceof LibraryOrderEntry) { + return createLibItem((LibraryOrderEntry)orderEntry); + } + else if (orderEntry instanceof ModuleOrderEntry) { + return new ClasspathTableItem(orderEntry, true); + } + else if (orderEntry instanceof ModuleSourceOrderEntry) { + return new ClasspathTableItem(orderEntry, false); + } + return null; + } + + public static ClasspathTableItem createLibItem(LibraryOrderEntry orderEntry) { + return new ClasspathTableItem(orderEntry, true) { + public boolean isEditable() { + return myEntry != null && myEntry.isValid(); + } + }; + } + + protected ClasspathTableItem(@Nullable OrderEntry entry, boolean removable) { + myEntry = entry; + myRemovable = removable; + } + + public final boolean isExportable() { + return myEntry instanceof ExportableOrderEntry; + } + + public final boolean isExported() { + return myEntry instanceof ExportableOrderEntry && ((ExportableOrderEntry)myEntry).isExported(); + } + + public final void setExported(boolean isExported) { + if (myEntry instanceof ExportableOrderEntry) { + ((ExportableOrderEntry)myEntry).setExported(isExported); + } + } + + @Nullable + public final DependencyScope getScope() { + return myEntry instanceof ExportableOrderEntry ? ((ExportableOrderEntry) myEntry).getScope() : null; + } + + public final void setScope(DependencyScope scope) { + if (myEntry instanceof ExportableOrderEntry) { + ((ExportableOrderEntry) myEntry).setScope(scope); + } + } + + @Nullable + public final OrderEntry getEntry() { + return myEntry; + } + + public boolean isRemovable() { + return myRemovable; + } + + public boolean isEditable() { + return false; + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathTableModel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathTableModel.java new file mode 100644 index 000000000000..554b319af505 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathTableModel.java @@ -0,0 +1,151 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.ProjectBundle; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState; +import com.intellij.util.ui.ItemRemovable; + +import javax.swing.table.AbstractTableModel; +import java.util.ArrayList; +import java.util.List; + +/** +* @author nik +*/ +class ClasspathTableModel extends AbstractTableModel implements ItemRemovable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.classpath.ClasspathTableModel"); + public static final String EXPORT_COLUMN_NAME = ProjectBundle.message("modules.order.export.export.column"); + private static final String SCOPE_COLUMN_NAME = ProjectBundle.message("modules.order.export.scope.column"); + public static final int EXPORT_COLUMN = 0; + public static final int ITEM_COLUMN = 1; + public static final int SCOPE_COLUMN = 2; + private final List myItems = new ArrayList(); + private final ModuleConfigurationState myState; + + public ClasspathTableModel(final ModuleConfigurationState state) { + myState = state; + init(); + } + + private ModifiableRootModel getModel() { + return myState.getRootModel(); + } + + public void init() { + final OrderEntry[] orderEntries = getModel().getOrderEntries(); + boolean hasJdkOrderEntry = false; + for (final OrderEntry orderEntry : orderEntries) { + if (orderEntry instanceof JdkOrderEntry) { + hasJdkOrderEntry = true; + } + addItem(ClasspathTableItem.createItem(orderEntry)); + } + if (!hasJdkOrderEntry) { + addItemAt(new InvalidJdkItem(), 0); + } + } + + public ClasspathTableItem getItemAt(int row) { + return myItems.get(row); + } + + public void addItem(ClasspathTableItem item) { + myItems.add(item); + } + + public void addItemAt(ClasspathTableItem item, int row) { + myItems.add(row, item); + } + + public ClasspathTableItem removeDataRow(int row) { + return myItems.remove(row); + } + + public void removeRow(int row) { + removeDataRow(row); + } + + public void clear() { + myItems.clear(); + } + + public int getRowCount() { + return myItems.size(); + } + + public Object getValueAt(int rowIndex, int columnIndex) { + final ClasspathTableItem item = myItems.get(rowIndex); + if (columnIndex == EXPORT_COLUMN) { + return item.isExported(); + } + if (columnIndex == SCOPE_COLUMN) { + return item.getScope(); + } + if (columnIndex == ITEM_COLUMN) { + return item; + } + LOG.error("Incorrect column index: " + columnIndex); + return null; + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + final ClasspathTableItem item = myItems.get(rowIndex); + if (columnIndex == EXPORT_COLUMN) { + item.setExported(((Boolean)aValue).booleanValue()); + } + else if (columnIndex == SCOPE_COLUMN && aValue instanceof DependencyScope) { + item.setScope((DependencyScope) aValue); + } + } + + public String getColumnName(int column) { + if (column == EXPORT_COLUMN) { + return EXPORT_COLUMN_NAME; + } + if (column == SCOPE_COLUMN) { + return SCOPE_COLUMN_NAME; + } + return ""; + } + + public Class getColumnClass(int column) { + if (column == EXPORT_COLUMN) { + return Boolean.class; + } + if (column == SCOPE_COLUMN) { + return DependencyScope.class; + } + if (column == ITEM_COLUMN) { + return ClasspathTableItem.class; + } + return super.getColumnClass(column); + } + + public int getColumnCount() { + return 3; + } + + public boolean isCellEditable(int row, int column) { + if (column == EXPORT_COLUMN || column == SCOPE_COLUMN) { + final ClasspathTableItem item = myItems.get(row); + return item != null && item.isExportable(); + } + return false; + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/CreateModuleLibraryDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/CreateModuleLibraryDialog.java new file mode 100644 index 000000000000..5640df01ffe8 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/CreateModuleLibraryDialog.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataKeys; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablePresentation; +import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryTableEditor; + +import java.util.Collections; +import java.util.List; + +/** +* @author nik +*/ +class CreateModuleLibraryDialog implements ClasspathElementChooserDialog { + private boolean myIsOk; + private final ClasspathPanel myClasspathPanel; + private final LibraryTable myLibraryTable; + private Library myChosenLibrary; + + public CreateModuleLibraryDialog(ClasspathPanel classpathPanel, final LibraryTable libraryTable) { + myClasspathPanel = classpathPanel; + myLibraryTable = libraryTable; + } + + public List getChosenElements() { + return myChosenLibrary == null? Collections.emptyList() : Collections.singletonList(myChosenLibrary); + } + + public void doChoose() { + final LibraryTable.ModifiableModel libraryModifiableModel = myLibraryTable.getModifiableModel(); + final LibraryTableModifiableModelProvider provider = new LibraryTableModifiableModelProvider() { + public LibraryTable.ModifiableModel getModifiableModel() { + return libraryModifiableModel; + } + + public String getTableLevel() { + return myLibraryTable.getTableLevel(); + } + + public LibraryTablePresentation getLibraryTablePresentation() { + return myLibraryTable.getPresentation(); + } + + public boolean isLibraryTableEditable() { + return false; + } + }; + final Library library = myLibraryTable.createLibrary(); + final LibraryTableEditor editor = LibraryTableEditor.editLibrary(provider, library, myClasspathPanel.getProject()); + final Module contextModule = DataKeys.MODULE_CONTEXT.getData(DataManager.getInstance().getDataContext(myClasspathPanel.getComponent())); + editor.addFileChooserContext(LangDataKeys.MODULE_CONTEXT, contextModule); + myIsOk = editor.openDialog(myClasspathPanel.getComponent(), Collections.singletonList(library), true) != null; + if (myIsOk) { + myChosenLibrary = library; + } + else { + myChosenLibrary = null; + libraryModifiableModel.removeLibrary(library); + } + } + + public boolean isOK() { + return myIsOk; + } + + public void dispose() { + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/InvalidJdkItem.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/InvalidJdkItem.java new file mode 100644 index 000000000000..b9da44577a5c --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/InvalidJdkItem.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.classpath; + +/** + * @author nik + */ +public class InvalidJdkItem extends ClasspathTableItem { + public InvalidJdkItem() { + super(null, false); + } +}