2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.ide
.palette
.impl
;
18 import com
.intellij
.ide
.palette
.PaletteGroup
;
19 import com
.intellij
.ide
.palette
.PaletteItem
;
20 import com
.intellij
.ide
.palette
.PaletteItemProvider
;
21 import com
.intellij
.openapi
.actionSystem
.*;
22 import com
.intellij
.openapi
.extensions
.Extensions
;
23 import com
.intellij
.openapi
.fileEditor
.FileEditorManager
;
24 import com
.intellij
.openapi
.project
.Project
;
25 import com
.intellij
.openapi
.vfs
.VirtualFile
;
26 import com
.intellij
.ui
.PopupHandler
;
27 import com
.intellij
.util
.ArrayUtil
;
28 import com
.intellij
.util
.containers
.HashSet
;
29 import org
.jetbrains
.annotations
.NonNls
;
30 import org
.jetbrains
.annotations
.Nullable
;
33 import javax
.swing
.event
.ListSelectionEvent
;
34 import javax
.swing
.event
.ListSelectionListener
;
36 import java
.awt
.event
.KeyEvent
;
37 import java
.beans
.PropertyChangeEvent
;
38 import java
.beans
.PropertyChangeListener
;
44 public class PaletteWindow
extends JPanel
implements DataProvider
{
45 private final Project myProject
;
46 private final ArrayList
<PaletteGroupHeader
> myGroupHeaders
= new ArrayList
<PaletteGroupHeader
>();
47 private final PaletteItemProvider
[] myProviders
;
48 private final PaletteWindow
.MyPropertyChangeListener myPropertyChangeListener
= new MyPropertyChangeListener();
49 private final Set
<PaletteGroup
> myGroups
= new HashSet
<PaletteGroup
>();
50 private final JTabbedPane myTabbedPane
= new JTabbedPane();
51 private final JScrollPane myScrollPane
= new JScrollPane();
52 private final MyListSelectionListener myListSelectionListener
= new MyListSelectionListener();
53 private PaletteGroupHeader myLastFocusedGroup
;
55 @NonNls private static final String ourHelpID
= "guiDesigner.uiTour.palette";
57 public PaletteWindow(Project project
) {
59 myProviders
= Extensions
.getExtensions(PaletteItemProvider
.EP_NAME
, project
);
60 for(PaletteItemProvider provider
: myProviders
) {
61 provider
.addListener(myPropertyChangeListener
);
64 setLayout(new GridLayout(1, 1));
65 myScrollPane
.addMouseListener(new MyScrollPanePopupHandler());
66 KeyStroke escStroke
= KeyStroke
.getKeyStroke(KeyEvent
.VK_ESCAPE
, 0);
67 new ClearActiveItemAction().registerCustomShortcutSet(new CustomShortcutSet(escStroke
), myScrollPane
);
71 public void refreshPalette() {
75 public void refreshPalette(@Nullable VirtualFile selectedFile
) {
76 for(PaletteGroupHeader groupHeader
: myGroupHeaders
) {
77 groupHeader
.getComponentList().removeListSelectionListener(myListSelectionListener
);
79 String
[] oldTabNames
= collectTabNames(myGroups
);
80 myTabbedPane
.removeAll();
81 myGroupHeaders
.clear();
84 final ArrayList
<PaletteGroup
> currentGroups
= collectCurrentGroups(selectedFile
);
85 String
[] tabNames
= collectTabNames(currentGroups
);
86 if (tabNames
.length
== 1) {
87 if (oldTabNames
.length
!= 1) {
92 PaletteContentWindow contentWindow
= new PaletteContentWindow();
93 myScrollPane
.getViewport().setView(contentWindow
);
95 for(PaletteGroup group
: currentGroups
) {
96 addGroupToControl(group
, contentWindow
);
99 final JComponent view
= (JComponent
)myScrollPane
.getViewport().getView();
102 for(Component component
: view
.getComponents()) {
103 ((JComponent
) component
).revalidate();
108 if (oldTabNames
.length
<= 1) {
109 remove(myScrollPane
);
112 for(String tabName
: tabNames
) {
113 PaletteContentWindow contentWindow
= new PaletteContentWindow();
114 JScrollPane scrollPane
= new JScrollPane(contentWindow
);
115 scrollPane
.addMouseListener(new MyScrollPanePopupHandler());
116 myTabbedPane
.add(tabName
, scrollPane
);
117 for(PaletteGroup group
: currentGroups
) {
118 if (group
.getTabName().equals(tabName
)) {
119 addGroupToControl(group
, contentWindow
);
123 myTabbedPane
.revalidate();
127 private void addGroupToControl(PaletteGroup group
, JComponent control
) {
128 PaletteGroupHeader groupHeader
= new PaletteGroupHeader(this, group
);
129 myGroupHeaders
.add(groupHeader
);
131 control
.add(groupHeader
);
132 PaletteComponentList componentList
= new PaletteComponentList(myProject
, group
);
133 control
.add(componentList
);
134 groupHeader
.setComponentList(componentList
);
135 componentList
.addListSelectionListener(myListSelectionListener
);
138 private static String
[] collectTabNames(final Collection
<PaletteGroup
> groups
) {
139 Set
<String
> result
= new TreeSet
<String
>();
140 for(PaletteGroup group
: groups
) {
141 result
.add(group
.getTabName());
143 return ArrayUtil
.toStringArray(result
);
146 private ArrayList
<PaletteGroup
> collectCurrentGroups(@Nullable VirtualFile selectedFile
) {
147 ArrayList
<PaletteGroup
> result
= new ArrayList
<PaletteGroup
>();
148 if (selectedFile
== null) {
149 VirtualFile
[] editedFiles
= FileEditorManager
.getInstance(myProject
).getSelectedFiles();
150 if (editedFiles
.length
> 0) {
151 selectedFile
= editedFiles
[0];
154 if (selectedFile
!= null) {
155 for(PaletteItemProvider provider
: myProviders
) {
156 PaletteGroup
[] groups
= provider
.getActiveGroups(selectedFile
);
157 Collections
.addAll(result
, groups
);
163 public void refreshPaletteIfChanged(VirtualFile selectedFile
) {
164 Set
<PaletteGroup
> currentGroups
= new HashSet
<PaletteGroup
>(collectCurrentGroups(selectedFile
));
165 if (!currentGroups
.equals(myGroups
)) {
166 refreshPalette(selectedFile
);
170 public int getActiveGroupCount() {
171 return myGroups
.size();
174 public void clearActiveItem() {
175 if (getActiveItem() == null) return;
176 for(PaletteGroupHeader group
: myGroupHeaders
) {
177 group
.getComponentList().clearSelection();
179 ListSelectionEvent event
= new ListSelectionEvent(this, -1, -1, false);
180 PaletteManager
.getInstance(myProject
).notifySelectionChanged(event
);
183 @Nullable public PaletteItem
getActiveItem() {
184 for(PaletteGroupHeader groupHeader
: myGroupHeaders
) {
185 if (groupHeader
.isSelected() && groupHeader
.getComponentList().getSelectedValue() != null) {
186 return (PaletteItem
) groupHeader
.getComponentList().getSelectedValue();
192 @Nullable public Object
getData(String dataId
) {
193 if (dataId
.equals(DataConstants
.HELP_ID
)) {
196 if (dataId
.equals(DataConstants
.PROJECT
)) {
199 PaletteItem item
= getActiveItem();
201 Object data
= item
.getData(myProject
, dataId
);
202 if (data
!= null) return data
;
204 for(PaletteGroupHeader groupHeader
: myGroupHeaders
) {
205 if ((groupHeader
.isSelected() && groupHeader
.getComponentList().getSelectedValue() != null) || groupHeader
== myLastFocusedGroup
) {
206 return groupHeader
.getGroup().getData(myProject
, dataId
);
209 final int tabCount
= collectTabNames(myGroups
).length
;
211 JScrollPane activeScrollPane
;
213 activeScrollPane
= myScrollPane
;
216 activeScrollPane
= (JScrollPane
) myTabbedPane
.getSelectedComponent();
218 PaletteContentWindow activeContentWindow
= (PaletteContentWindow
) activeScrollPane
.getViewport().getView();
219 PaletteGroupHeader groupHeader
= activeContentWindow
.getLastGroupHeader();
220 if (groupHeader
!= null) {
221 return groupHeader
.getGroup().getData(myProject
, dataId
);
227 public Project
getProject() {
231 void setLastFocusedGroup(final PaletteGroupHeader focusedGroup
) {
232 myLastFocusedGroup
= focusedGroup
;
233 for(PaletteGroupHeader group
: myGroupHeaders
) {
234 group
.getComponentList().clearSelection();
238 private class MyListSelectionListener
implements ListSelectionListener
{
239 public void valueChanged(ListSelectionEvent e
) {
240 PaletteComponentList sourceList
= (PaletteComponentList
) e
.getSource();
241 for(int i
=e
.getFirstIndex(); i
<= e
.getLastIndex(); i
++) {
242 if (sourceList
.isSelectedIndex(i
)) {
243 // selection is being added
244 for(PaletteGroupHeader group
: myGroupHeaders
) {
245 if (group
.getComponentList() != sourceList
) {
246 group
.getComponentList().clearSelection();
252 PaletteManager
.getInstance(myProject
).notifySelectionChanged(e
);
256 private class MyPropertyChangeListener
implements PropertyChangeListener
{
257 public void propertyChange(PropertyChangeEvent evt
) {
262 private static class MyScrollPanePopupHandler
extends PopupHandler
{
263 public void invokePopup(Component comp
, int x
, int y
) {
264 JScrollPane scrollPane
= (JScrollPane
) comp
;
265 PaletteContentWindow contentWindow
= (PaletteContentWindow
) scrollPane
.getViewport().getView();
266 if (contentWindow
!= null) {
267 PaletteGroupHeader groupHeader
= contentWindow
.getLastGroupHeader();
268 if (groupHeader
!= null) {
269 groupHeader
.showGroupPopupMenu(comp
, x
, y
);
275 private class ClearActiveItemAction
extends AnAction
{
276 public void actionPerformed(AnActionEvent e
) {