2 * Copyright 2000-2016 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.
17 package com.intellij.profile.codeInspection.ui;
19 import com.intellij.codeHighlighting.HighlightDisplayLevel;
20 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
21 import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
22 import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
23 import com.intellij.codeInsight.hint.HintUtil;
24 import com.intellij.codeInspection.InspectionProfile;
25 import com.intellij.codeInspection.InspectionsBundle;
26 import com.intellij.codeInspection.ModifiableModel;
27 import com.intellij.codeInspection.ex.*;
28 import com.intellij.icons.AllIcons;
29 import com.intellij.ide.CommonActionsManager;
30 import com.intellij.ide.DefaultTreeExpander;
31 import com.intellij.ide.TreeExpander;
32 import com.intellij.ide.ui.search.SearchUtil;
33 import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
34 import com.intellij.lang.annotation.HighlightSeverity;
35 import com.intellij.openapi.Disposable;
36 import com.intellij.openapi.actionSystem.*;
37 import com.intellij.openapi.application.ApplicationManager;
38 import com.intellij.openapi.diagnostic.Logger;
39 import com.intellij.openapi.editor.colors.TextAttributesKey;
40 import com.intellij.openapi.editor.markup.TextAttributes;
41 import com.intellij.openapi.options.ConfigurationException;
42 import com.intellij.openapi.project.DumbAwareAction;
43 import com.intellij.openapi.project.Project;
44 import com.intellij.openapi.util.Comparing;
45 import com.intellij.openapi.util.Disposer;
46 import com.intellij.openapi.util.JDOMUtil;
47 import com.intellij.openapi.util.text.StringUtil;
48 import com.intellij.profile.ProfileManager;
49 import com.intellij.profile.codeInspection.InspectionProfileManager;
50 import com.intellij.profile.codeInspection.ProjectInspectionProfileManager;
51 import com.intellij.profile.codeInspection.SeverityProvider;
52 import com.intellij.profile.codeInspection.ui.filter.InspectionFilterAction;
53 import com.intellij.profile.codeInspection.ui.filter.InspectionsFilter;
54 import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionConfigTreeNode;
55 import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeComparator;
56 import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeRenderer;
57 import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeTable;
58 import com.intellij.profile.codeInspection.ui.table.ScopesAndSeveritiesTable;
59 import com.intellij.psi.search.scope.packageSet.NamedScope;
60 import com.intellij.ui.*;
61 import com.intellij.ui.components.JBLabel;
62 import com.intellij.util.Alarm;
63 import com.intellij.util.containers.ContainerUtil;
64 import com.intellij.util.containers.Convertor;
65 import com.intellij.util.containers.Queue;
66 import com.intellij.util.ui.JBInsets;
67 import com.intellij.util.ui.JBUI;
68 import com.intellij.util.ui.UIUtil;
69 import com.intellij.util.ui.tree.TreeUtil;
70 import gnu.trove.THashMap;
71 import gnu.trove.THashSet;
72 import org.jdom.Element;
73 import org.jetbrains.annotations.NonNls;
74 import org.jetbrains.annotations.NotNull;
75 import org.jetbrains.annotations.Nullable;
77 import javax.swing.FocusManager;
79 import javax.swing.event.TreeExpansionEvent;
80 import javax.swing.event.TreeExpansionListener;
81 import javax.swing.event.TreeSelectionEvent;
82 import javax.swing.event.TreeSelectionListener;
83 import javax.swing.tree.DefaultTreeModel;
84 import javax.swing.tree.TreeNode;
85 import javax.swing.tree.TreePath;
87 import java.beans.PropertyChangeEvent;
88 import java.beans.PropertyChangeListener;
89 import java.io.IOException;
90 import java.io.StringReader;
92 import java.util.List;
94 public class SingleInspectionProfilePanel extends JPanel {
95 private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.InspectionToolsPanel");
96 @NonNls private static final String INSPECTION_FILTER_HISTORY = "INSPECTION_FILTER_HISTORY";
97 private static final String UNDER_CONSTRUCTION = InspectionsBundle.message("inspection.tool.description.under.construction.text");
98 @NonNls private static final String EMPTY_HTML = "<html><body></body></html>";
100 private static final float DIVIDER_PROPORTION_DEFAULT = 0.5f;
102 private final Map<HighlightDisplayKey, ToolDescriptors> myInitialToolDescriptors = new THashMap<>();
103 private final InspectionConfigTreeNode myRoot =
104 new InspectionConfigTreeNode.Group(InspectionsBundle.message("inspection.root.node.title"));
105 private final Alarm myAlarm = new Alarm();
106 private final ProjectInspectionProfileManager myProjectProfileManager;
107 private InspectionProfileImpl myProfile;
108 private JEditorPane myBrowser;
109 private JPanel myOptionsPanel;
110 private JPanel myInspectionProfilePanel = null;
111 private FilterComponent myProfileFilter;
112 private final InspectionsFilter myInspectionsFilter = new InspectionsFilter() {
114 protected void filterChanged() {
115 filterTree(myProfileFilter.getFilter());
118 private boolean myModified = false;
119 private InspectionsConfigTreeTable myTreeTable;
120 private TreeExpander myTreeExpander;
121 private boolean myIsInRestore = false;
123 private String[] myInitialScopesOrder;
124 private Disposable myDisposable = new Disposable() {
126 public void dispose() {}
129 public SingleInspectionProfilePanel(@NotNull ProjectInspectionProfileManager projectProfileManager,
130 @NotNull ModifiableModel profile) {
131 super(new BorderLayout());
132 myProjectProfileManager = projectProfileManager;
133 myProfile = (InspectionProfileImpl)profile;
136 public Map<HighlightDisplayKey, ToolDescriptors> getInitialToolDescriptors() {
137 return myInitialToolDescriptors;
140 private static VisibleTreeState getExpandedNodes(InspectionProfileImpl profile) {
141 if (profile.isProjectLevel()) {
142 return ProjectInspectionProfilesVisibleTreeState.getInstance(((ProjectInspectionProfileManager)profile.getProfileManager()).getProject()).getVisibleTreeState(profile);
145 return AppInspectionProfilesVisibleTreeState.getInstance().getVisibleTreeState(profile);
149 private static InspectionConfigTreeNode findGroupNodeByPath(@NotNull String[] path, int idx, @NotNull InspectionConfigTreeNode node) {
150 if (path.length == idx) {
154 final String currentKey = path[idx];
155 for (int i = 0; i < node.getChildCount(); i++) {
156 final InspectionConfigTreeNode currentNode = (InspectionConfigTreeNode)node.getChildAt(i);
157 if (Comparing.equal(currentNode.getGroupName(), currentKey)) {
158 return findGroupNodeByPath(path, ++idx, currentNode);
166 private static InspectionConfigTreeNode findNodeByKey(String name, InspectionConfigTreeNode root) {
167 for (int i = 0; i < root.getChildCount(); i++) {
168 final InspectionConfigTreeNode child = (InspectionConfigTreeNode)root.getChildAt(i);
169 final Descriptor descriptor = child.getDefaultDescriptor();
170 if (descriptor != null) {
171 if (descriptor.getKey().toString().equals(name)) {
176 final InspectionConfigTreeNode node = findNodeByKey(name, child);
177 if (node != null) return node;
183 public static String renderSeverity(HighlightSeverity severity) {
184 if (HighlightSeverity.INFORMATION.equals(severity)) return "No highlighting, only fix"; //todo severity presentation
185 return StringUtil.capitalizeWords(severity.getName().toLowerCase(Locale.US), true);
188 private static void updateUpHierarchy(final InspectionConfigTreeNode parent) {
189 if (parent != null) {
191 updateUpHierarchy((InspectionConfigTreeNode)parent.getParent());
195 private static boolean isDescriptorAccepted(Descriptor descriptor,
196 @NonNls String filter,
197 final boolean forceInclude,
198 final List<Set<String>> keySetList, final Set<String> quoted) {
199 filter = filter.toLowerCase();
200 if (StringUtil.containsIgnoreCase(descriptor.getText(), filter)) {
203 final String[] groupPath = descriptor.getGroup();
204 for (String group : groupPath) {
205 if (StringUtil.containsIgnoreCase(group, filter)) {
209 for (String stripped : quoted) {
210 if (StringUtil.containsIgnoreCase(descriptor.getText(),stripped)) {
213 for (String group : groupPath) {
214 if (StringUtil.containsIgnoreCase(group,stripped)) {
218 final String description = descriptor.getToolWrapper().loadDescription();
219 if (description != null && StringUtil.containsIgnoreCase(description.toLowerCase(Locale.US), stripped)) {
220 if (!forceInclude) return true;
221 } else if (forceInclude) return false;
223 for (Set<String> keySet : keySetList) {
224 if (keySet.contains(descriptor.getKey().toString())) {
238 private static void setConfigPanel(final JPanel configPanelAnchor, final ScopeToolState state) {
239 configPanelAnchor.removeAll();
240 final JComponent additionalConfigPanel = state.getAdditionalConfigPanel();
241 if (additionalConfigPanel != null) {
242 // assume that the panel does not need scrolling if it already contains a scrollable content
243 if (UIUtil.hasScrollPane(additionalConfigPanel)) {
244 configPanelAnchor.add(additionalConfigPanel);
247 configPanelAnchor.add(ScrollPaneFactory.createScrollPane(additionalConfigPanel, SideBorder.NONE));
250 UIUtil.setEnabled(configPanelAnchor, state.isEnabled(), true);
253 private static InspectionConfigTreeNode getGroupNode(InspectionConfigTreeNode root, String[] groupPath) {
254 InspectionConfigTreeNode currentRoot = root;
255 for (final String group : groupPath) {
256 currentRoot = getGroupNode(currentRoot, group);
261 private static InspectionConfigTreeNode getGroupNode(InspectionConfigTreeNode root, String group) {
262 final int childCount = root.getChildCount();
263 for (int i = 0; i < childCount; i++) {
264 InspectionConfigTreeNode child = (InspectionConfigTreeNode)root.getChildAt(i);
265 if (group.equals(child.getUserObject())) {
269 InspectionConfigTreeNode child = new InspectionConfigTreeNode.Group(group);
274 private static void copyUsedSeveritiesIfUndefined(final ModifiableModel selectedProfile, final ProfileManager profileManager) {
275 final SeverityRegistrar registrar = ((SeverityProvider)profileManager).getSeverityRegistrar();
276 final Set<HighlightSeverity> severities = ((InspectionProfileImpl)selectedProfile).getUsedSeverities();
277 for (Iterator<HighlightSeverity> iterator = severities.iterator(); iterator.hasNext();) {
278 HighlightSeverity severity = iterator.next();
279 if (registrar.isSeverityValid(severity.getName())) {
284 if (!severities.isEmpty()) {
285 final SeverityRegistrar oppositeRegister = ((SeverityProvider)selectedProfile.getProfileManager()).getSeverityRegistrar();
286 for (HighlightSeverity severity : severities) {
287 final TextAttributesKey attributesKey = TextAttributesKey.find(severity.getName());
288 final TextAttributes textAttributes = oppositeRegister.getTextAttributesBySeverity(severity);
289 if (textAttributes == null) {
292 HighlightInfoType.HighlightInfoTypeImpl info = new HighlightInfoType.HighlightInfoTypeImpl(severity, attributesKey);
293 registrar.registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info),
294 textAttributes.getErrorStripeColor());
299 private void initUI() {
300 myInspectionProfilePanel = createInspectionProfileSettingsPanel();
301 add(myInspectionProfilePanel, BorderLayout.CENTER);
302 UserActivityWatcher userActivityWatcher = new UserActivityWatcher();
303 userActivityWatcher.addUserActivityListener(new UserActivityListener() {
305 public void stateChanged() {
306 //invoke after all other listeners
307 ApplicationManager.getApplication().invokeLater(() -> {
308 if (myProfile == null) return; //panel was disposed
309 updateProperSettingsForSelection();
310 wereToolSettingsModified();
314 userActivityWatcher.register(myOptionsPanel);
315 updateSelectedProfileState();
319 private void updateSelectedProfileState() {
320 if (myProfile == null) return;
326 public void updateSelection() {
327 if (myTreeTable != null) {
328 final TreePath selectionPath = myTreeTable.getTree().getSelectionPath();
329 if (selectionPath != null) {
330 TreeUtil.selectNode(myTreeTable.getTree(), (TreeNode) selectionPath.getLastPathComponent());
331 final int rowForPath = myTreeTable.getTree().getRowForPath(selectionPath);
332 TableUtil.selectRows(myTreeTable, new int[]{rowForPath});
338 private void loadDescriptorsConfigs(boolean onlyModified) {
339 for (ToolDescriptors toolDescriptors : myInitialToolDescriptors.values()) {
340 loadDescriptorConfig(toolDescriptors.getDefaultDescriptor(), onlyModified);
341 for (Descriptor descriptor : toolDescriptors.getNonDefaultDescriptors()) {
342 loadDescriptorConfig(descriptor, onlyModified);
347 private void loadDescriptorConfig(Descriptor descriptor, boolean ifModifier) {
348 if (!ifModifier || myProfile.isProperSetting(descriptor.getKey().toString())) {
349 descriptor.loadConfig();
353 private void wereToolSettingsModified() {
354 for (final ToolDescriptors toolDescriptor : myInitialToolDescriptors.values()) {
355 Descriptor desc = toolDescriptor.getDefaultDescriptor();
356 if (wereToolSettingsModified(desc, true)) return;
357 List<Descriptor> descriptors = toolDescriptor.getNonDefaultDescriptors();
358 for (Descriptor descriptor : descriptors) {
359 if (wereToolSettingsModified(descriptor, false)) return;
365 private boolean wereToolSettingsModified(Descriptor descriptor, boolean isDefault) {
366 if (!myProfile.isToolEnabled(descriptor.getKey(), descriptor.getScope(), myProjectProfileManager.getProject())) {
369 Element oldConfig = descriptor.getConfig();
370 if (oldConfig == null) return false;
372 ScopeToolState state = null;
374 state = myProfile.getToolDefaultState(descriptor.getKey().toString(), myProjectProfileManager.getProject());
376 for (ScopeToolState candidate : myProfile.getNonDefaultTools(descriptor.getKey().toString(), myProjectProfileManager.getProject())) {
377 final String scope = descriptor.getScopeName();
378 if (Comparing.equal(candidate.getScopeName(), scope)) {
389 Element newConfig = Descriptor.createConfigElement(state.getTool());
390 if (!JDOMUtil.areElementsEqual(oldConfig, newConfig)) {
391 myAlarm.cancelAllRequests();
392 myAlarm.addRequest(() -> myTreeTable.repaint(), 300);
399 private void updateProperSettingsForSelection() {
400 final TreePath selectionPath = myTreeTable.getTree().getSelectionPath();
401 if (selectionPath != null) {
402 InspectionConfigTreeNode node = (InspectionConfigTreeNode)selectionPath.getLastPathComponent();
403 final Descriptor descriptor = node.getDefaultDescriptor();
404 if (descriptor != null) {
405 final boolean properSetting = myProfile.isProperSetting(descriptor.getKey().toString());
406 if (node.isProperSetting() != properSetting) {
407 myAlarm.cancelAllRequests();
408 myAlarm.addRequest(() -> myTreeTable.repaint(), 300);
410 updateUpHierarchy((InspectionConfigTreeNode)node.getParent());
416 private void initToolStates() {
417 final InspectionProfileImpl profile = myProfile;
418 if (profile == null) return;
419 myInitialToolDescriptors.clear();
420 final Project project = myProjectProfileManager.getProject();
421 for (final ScopeToolState state : profile.getDefaultStates(myProjectProfileManager.getProject())) {
422 if (!accept(state.getTool())) continue;
423 final ToolDescriptors descriptors = ToolDescriptors.fromScopeToolState(state, profile, project);
424 myInitialToolDescriptors.put(descriptors.getDefaultDescriptor().getKey(), descriptors);
426 myInitialScopesOrder = myProfile.getScopesOrder();
429 protected boolean accept(InspectionToolWrapper entry) {
430 return entry.getDefaultLevel() != HighlightDisplayLevel.NON_SWITCHABLE_ERROR;
433 private void postProcessModification() {
434 wereToolSettingsModified();
436 for (ScopeToolState state : myProfile.getAllTools(myProjectProfileManager.getProject())) {
437 state.resetConfigPanel();
439 fillTreeData(myProfileFilter.getFilter(), true);
441 updateOptionsAndDescriptionPanel(myTreeTable.getTree().getSelectionPaths());
444 public void setFilter(String filter) {
445 myProfileFilter.setFilter(filter);
448 private void filterTree(@Nullable String filter) {
449 if (myTreeTable != null) {
450 getExpandedNodes(myProfile).saveVisibleState(myTreeTable.getTree());
451 fillTreeData(filter, true);
454 if (myTreeTable.getTree().getSelectionPath() == null) {
455 TreeUtil.selectFirstNode(myTreeTable.getTree());
460 private void filterTree() {
461 filterTree(myProfileFilter != null ? myProfileFilter.getFilter() : null);
464 private void reloadModel() {
466 myIsInRestore = true;
467 ((DefaultTreeModel)myTreeTable.getTree().getModel()).reload();
470 myIsInRestore = false;
475 private void restoreTreeState() {
478 myIsInRestore = true;
479 getExpandedNodes(myProfile).restoreVisibleState(myTreeTable.getTree());
482 myIsInRestore = false;
486 private ActionToolbar createTreeToolbarPanel() {
487 final CommonActionsManager actionManager = CommonActionsManager.getInstance();
489 DefaultActionGroup actions = new DefaultActionGroup();
491 actions.add(new InspectionFilterAction(myProfile, myInspectionsFilter, myProjectProfileManager.getProject(), myProfileFilter));
492 actions.addSeparator();
494 actions.add(actionManager.createExpandAllAction(myTreeExpander, myTreeTable));
495 actions.add(actionManager.createCollapseAllAction(myTreeExpander, myTreeTable));
496 actions.add(new DumbAwareAction("Reset to Empty", "Reset to empty", AllIcons.Actions.Reset_to_empty){
499 public void update(@NotNull AnActionEvent e) {
500 e.getPresentation().setEnabled(myProfile != null && myProfile.isExecutable(myProjectProfileManager.getProject()));
504 public void actionPerformed(@NotNull AnActionEvent e) {
505 myProfile.resetToEmpty(e.getProject());
506 loadDescriptorsConfigs(false);
507 postProcessModification();
511 actions.add(new AdvancedSettingsAction(myProjectProfileManager.getProject(), myRoot) {
513 protected InspectionProfileImpl getInspectionProfile() {
518 protected void postProcessModification() {
519 loadDescriptorsConfigs(true);
520 SingleInspectionProfilePanel.this.postProcessModification();
525 final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actions, true);
526 actionToolbar.setTargetComponent(this);
527 return actionToolbar;
530 private void repaintTableData() {
531 if (myTreeTable != null) {
532 getExpandedNodes(myProfile).saveVisibleState(myTreeTable.getTree());
538 public void selectInspectionTool(String name) {
539 selectNode(findNodeByKey(name, myRoot));
542 public void selectInspectionGroup(String[] path) {
543 final InspectionConfigTreeNode node = findGroupNodeByPath(path, 0, myRoot);
546 myTreeTable.getTree().expandPath(new TreePath(node.getPath()));
550 private void selectNode(InspectionConfigTreeNode node) {
552 TreeUtil.selectNode(myTreeTable.getTree(), node);
553 final int rowForPath = myTreeTable.getTree().getRowForPath(new TreePath(node.getPath()));
554 TableUtil.selectRows(myTreeTable, new int[]{rowForPath});
559 private void scrollToCenter() {
560 ListSelectionModel selectionModel = myTreeTable.getSelectionModel();
561 int maxSelectionIndex = selectionModel.getMaxSelectionIndex();
562 final int maxColumnSelectionIndex = Math.max(0, myTreeTable.getColumnModel().getSelectionModel().getMinSelectionIndex());
563 Rectangle maxCellRect = myTreeTable.getCellRect(maxSelectionIndex, maxColumnSelectionIndex, false);
565 final Point selectPoint = maxCellRect.getLocation();
566 final int allHeight = myTreeTable.getVisibleRect().height;
567 myTreeTable.scrollRectToVisible(new Rectangle(new Point(0, Math.max(0, selectPoint.y - allHeight / 2)), new Dimension(0, allHeight)));
570 private JScrollPane initTreeScrollPane() {
571 fillTreeData(null, true);
573 final InspectionsConfigTreeRenderer renderer = new InspectionsConfigTreeRenderer(){
575 protected String getFilter() {
576 return myProfileFilter != null ? myProfileFilter.getFilter() : null;
579 myTreeTable = InspectionsConfigTreeTable.create(new InspectionsConfigTreeTable.InspectionsConfigTreeTableSettings(myRoot, myProjectProfileManager.getProject()) {
581 protected void onChanged(final InspectionConfigTreeNode node) {
582 updateUpHierarchy((InspectionConfigTreeNode)node.getParent());
586 public void updateRightPanel() {
587 updateOptionsAndDescriptionPanel();
591 public InspectionProfileImpl getInspectionProfile() {
595 myTreeTable.setTreeCellRenderer(renderer);
596 myTreeTable.setRootVisible(false);
597 UIUtil.setLineStyleAngled(myTreeTable.getTree());
598 TreeUtil.installActions(myTreeTable.getTree());
601 myTreeTable.getTree().addTreeSelectionListener(new TreeSelectionListener() {
603 public void valueChanged(TreeSelectionEvent e) {
604 if (myTreeTable.getTree().getSelectionPaths() != null) {
605 updateOptionsAndDescriptionPanel(myTreeTable.getTree().getSelectionPaths());
608 initOptionsAndDescriptionPanel();
611 if (!myIsInRestore) {
612 InspectionProfileImpl selected = myProfile;
613 if (selected != null) {
614 InspectionProfileImpl baseProfile = (InspectionProfileImpl)selected.getParentProfile();
615 if (baseProfile != null) {
616 getExpandedNodes(baseProfile).setSelectionPaths(myTreeTable.getTree().getSelectionPaths());
618 getExpandedNodes(selected).setSelectionPaths(myTreeTable.getTree().getSelectionPaths());
626 myTreeTable.addMouseListener(new PopupHandler() {
628 public void invokePopup(Component comp, int x, int y) {
629 final int[] selectionRows = myTreeTable.getTree().getSelectionRows();
630 if (selectionRows != null &&
631 myTreeTable.getTree().getPathForLocation(x, y) != null &&
632 Arrays.binarySearch(selectionRows, myTreeTable.getTree().getRowForLocation(x, y)) > -1) {
633 compoundPopup().show(comp, x, y);
639 new TreeSpeedSearch(myTreeTable.getTree(), new Convertor<TreePath, String>() {
641 public String convert(TreePath o) {
642 final InspectionConfigTreeNode node = (InspectionConfigTreeNode)o.getLastPathComponent();
643 final Descriptor descriptor = node.getDefaultDescriptor();
644 return InspectionsConfigTreeComparator.getDisplayTextToSort(descriptor != null ? descriptor.getText() : node.getGroupName());
649 final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTreeTable);
650 myTreeTable.getTree().setShowsRootHandles(true);
651 scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
652 scrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.BOTTOM + SideBorder.LEFT + SideBorder.TOP));
653 TreeUtil.collapseAll(myTreeTable.getTree(), 1);
655 myTreeTable.getTree().addTreeExpansionListener(new TreeExpansionListener() {
659 public void treeCollapsed(TreeExpansionEvent event) {
660 InspectionProfileImpl selected = myProfile;
661 final InspectionProfileImpl parentProfile = (InspectionProfileImpl)selected.getParentProfile();
662 if (parentProfile != null) {
663 getExpandedNodes(parentProfile).saveVisibleState(myTreeTable.getTree());
665 getExpandedNodes(selected).saveVisibleState(myTreeTable.getTree());
669 public void treeExpanded(TreeExpansionEvent event) {
670 InspectionProfileImpl selected = myProfile;
671 if (selected != null) {
672 final InspectionConfigTreeNode node = (InspectionConfigTreeNode)event.getPath().getLastPathComponent();
673 final InspectionProfileImpl parentProfile = (InspectionProfileImpl)selected.getParentProfile();
674 if (parentProfile != null) {
675 getExpandedNodes(parentProfile).expandNode(node);
677 getExpandedNodes(selected).expandNode(node);
682 myTreeExpander = new DefaultTreeExpander(myTreeTable.getTree()) {
684 public boolean canExpand() {
685 return myTreeTable.isShowing();
689 public boolean canCollapse() {
690 return myTreeTable.isShowing();
693 myProfileFilter = new MyFilterComponent();
698 private JPopupMenu compoundPopup() {
699 final DefaultActionGroup group = new DefaultActionGroup();
700 final SeverityRegistrar severityRegistrar = ((SeverityProvider)myProfile.getProfileManager()).getOwnSeverityRegistrar();
701 for (HighlightSeverity severity : LevelChooserAction.getSeverities(severityRegistrar, includeDoNotShow())) {
702 final HighlightDisplayLevel level = HighlightDisplayLevel.find(severity);
703 group.add(new AnAction(renderSeverity(severity), renderSeverity(severity), level.getIcon()) {
705 public void actionPerformed(@NotNull AnActionEvent e) {
706 setNewHighlightingLevel(level);
710 public boolean isDumbAware() {
715 group.add(Separator.getInstance());
716 ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group);
717 return menu.getComponent();
720 private boolean includeDoNotShow() {
721 final TreePath[] paths = myTreeTable.getTree().getSelectionPaths();
722 if (paths == null) return true;
723 return includeDoNotShow(InspectionsAggregationUtil.getInspectionsNodes(paths));
726 private boolean includeDoNotShow(List<InspectionConfigTreeNode> nodes) {
727 final Project project = myProjectProfileManager.getProject();
728 return !nodes.stream()
729 .filter(node -> myProfile.getToolDefaultState(node.getKey().toString(), project).getTool() instanceof GlobalInspectionToolWrapper)
734 private void fillTreeData(@Nullable String filter, boolean forceInclude) {
735 if (myProfile == null) return;
736 myRoot.removeAllChildren();
738 List<Set<String>> keySetList = new ArrayList<>();
739 final Set<String> quoted = new HashSet<>();
740 if (filter != null && !filter.isEmpty()) {
741 keySetList.addAll(SearchUtil.findKeys(filter, quoted));
743 Project project = myProjectProfileManager.getProject();
744 final boolean emptyFilter = myInspectionsFilter.isEmptyFilter();
745 for (ToolDescriptors toolDescriptors : myInitialToolDescriptors.values()) {
746 final Descriptor descriptor = toolDescriptors.getDefaultDescriptor();
747 if (filter != null && !filter.isEmpty() && !isDescriptorAccepted(descriptor, filter, forceInclude, keySetList, quoted)) {
750 final InspectionConfigTreeNode node = new InspectionConfigTreeNode.Tool(toolDescriptors.getDefaultDescriptor().getKey(), this);
751 if (!emptyFilter && !myInspectionsFilter.matches(
752 myProfile.getTools(toolDescriptors.getDefaultDescriptor().getKey().toString(), project), node)) {
755 getGroupNode(myRoot, toolDescriptors.getDefaultDescriptor().getGroup()).add(node);
758 if (filter != null && forceInclude && myRoot.getChildCount() == 0) {
759 final Set<String> filters = SearchableOptionsRegistrar.getInstance().getProcessedWords(filter);
760 if (filters.size() > 1 || !quoted.isEmpty()) {
761 fillTreeData(filter, false);
764 TreeUtil.sort(myRoot, new InspectionsConfigTreeComparator());
767 // TODO 134099: see IntentionDescriptionPanel#readHTML
768 public static boolean readHTML(JEditorPane browser, String text) {
770 browser.read(new StringReader(text), null);
773 catch (IOException ignored) {
778 // TODO 134099: see IntentionDescriptionPanel#setHTML
779 public static String toHTML(JEditorPane browser, String text, boolean miniFontSize) {
780 final HintHint hintHint = new HintHint(browser, new Point(0, 0));
781 hintHint.setFont(miniFontSize ? UIUtil.getLabelFont(UIUtil.FontSize.SMALL) : UIUtil.getLabelFont());
782 return HintUtil.prepareHintText(text, hintHint);
785 private void updateOptionsAndDescriptionPanel(final TreePath... paths) {
786 if (myProfile == null || paths == null || paths.length == 0) {
789 final TreePath path = paths[0];
790 if (path == null) return;
791 final List<InspectionConfigTreeNode> nodes = InspectionsAggregationUtil.getInspectionsNodes(paths);
792 if (!nodes.isEmpty()) {
793 final InspectionConfigTreeNode singleNode = paths.length == 1 && ((InspectionConfigTreeNode)paths[0].getLastPathComponent()).getDefaultDescriptor() != null
794 ? ContainerUtil.getFirstItem(nodes) : null;
795 if (singleNode != null) {
796 final Descriptor descriptor = singleNode.getDefaultDescriptor();
797 LOG.assertTrue(descriptor != null);
798 if (descriptor.loadDescription() != null) {
799 // need this in order to correctly load plugin-supplied descriptions
800 final Descriptor defaultDescriptor = singleNode.getDefaultDescriptor();
801 final String description = defaultDescriptor.loadDescription();
803 if (!readHTML(myBrowser, SearchUtil.markup(toHTML(myBrowser, description, false), myProfileFilter.getFilter()))) {
804 readHTML(myBrowser, toHTML(myBrowser, "<b>" + UNDER_CONSTRUCTION + "</b>", false));
807 catch (Throwable t) {
808 LOG.error("Failed to load description for: " +
809 defaultDescriptor.getToolWrapper().getTool().getClass() +
816 readHTML(myBrowser, toHTML(myBrowser, "Can't find inspection description.", false));
820 readHTML(myBrowser, toHTML(myBrowser, "Multiple inspections are selected. You can edit them as a single inspection.", false));
823 myOptionsPanel.removeAll();
824 final Project project = myProjectProfileManager.getProject();
825 final JPanel severityPanel = new JPanel(new GridBagLayout());
826 final JPanel configPanelAnchor = new JPanel(new GridLayout());
828 final Set<String> scopesNames = new THashSet<>();
829 for (final InspectionConfigTreeNode node : nodes) {
830 final List<ScopeToolState> nonDefaultTools = myProfile.getNonDefaultTools(node.getDefaultDescriptor().getKey().toString(), project);
831 for (final ScopeToolState tool : nonDefaultTools) {
832 scopesNames.add(tool.getScopeName());
836 final double severityPanelWeightY;
837 if (scopesNames.isEmpty()) {
839 final LevelChooserAction severityLevelChooser =
840 new LevelChooserAction(((SeverityProvider)myProfile.getProfileManager()).getOwnSeverityRegistrar(),
841 includeDoNotShow(nodes)) {
843 protected void onChosen(final HighlightSeverity severity) {
844 final HighlightDisplayLevel level = HighlightDisplayLevel.find(severity);
845 for (final InspectionConfigTreeNode node : nodes) {
846 final HighlightDisplayKey key = node.getDefaultDescriptor().getKey();
847 final NamedScope scope = node.getDefaultDescriptor().getScope();
848 final boolean toUpdate = myProfile.getErrorLevel(key, scope, project) != level;
849 myProfile.setErrorLevel(key, level, null, project);
850 if (toUpdate) node.dropCache();
852 myTreeTable.updateUI();
855 final HighlightSeverity severity =
856 ScopesAndSeveritiesTable.getSeverity(ContainerUtil.map(nodes, node -> node.getDefaultDescriptor().getState()));
857 severityLevelChooser.setChosen(severity);
859 final ScopesChooser scopesChooser = new ScopesChooser(ContainerUtil.map(nodes, node -> node.getDefaultDescriptor()), myProfile, project, null) {
861 protected void onScopesOrderChanged() {
862 myTreeTable.updateUI();
863 updateOptionsAndDescriptionPanel();
867 protected void onScopeAdded() {
868 myTreeTable.updateUI();
869 updateOptionsAndDescriptionPanel();
873 severityPanel.add(new JLabel(InspectionsBundle.message("inspection.severity")),
874 new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL,
875 JBUI.insets(10, 0), 0, 0));
876 final JComponent severityLevelChooserComponent = severityLevelChooser.createCustomComponent(severityLevelChooser.getTemplatePresentation());
877 severityPanel.add(severityLevelChooserComponent,
878 new GridBagConstraints(1, 0, 1, 1, 0, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH,
879 JBUI.insets(10, 0), 0, 0));
880 final JComponent scopesChooserComponent = scopesChooser.createCustomComponent(scopesChooser.getTemplatePresentation());
881 severityPanel.add(scopesChooserComponent,
882 new GridBagConstraints(2, 0, 1, 1, 0, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH,
883 JBUI.insets(10, 0), 0, 0));
884 final JLabel label = new JLabel("", SwingConstants.RIGHT);
885 severityPanel.add(label,
886 new GridBagConstraints(3, 0, 1, 1, 1, 0,
887 GridBagConstraints.EAST,
888 GridBagConstraints.BOTH,
889 JBUI.insets(2, 0), 0, 0));
890 severityPanelWeightY = 0.0;
891 if (singleNode != null) {
892 setConfigPanel(configPanelAnchor, myProfile.getToolDefaultState(singleNode.getDefaultDescriptor().getKey().toString(),
897 if (singleNode != null) {
898 for (final Descriptor descriptor : singleNode.getDescriptors().getNonDefaultDescriptors()) {
899 descriptor.loadConfig();
902 final JTable scopesAndScopesAndSeveritiesTable =
903 new ScopesAndSeveritiesTable(new ScopesAndSeveritiesTable.TableSettings(nodes, myProfile, project) {
905 protected void onScopeChosen(@NotNull final ScopeToolState state) {
906 setConfigPanel(configPanelAnchor, state);
907 configPanelAnchor.revalidate();
908 configPanelAnchor.repaint();
912 protected void onSettingsChanged() {
917 protected void onScopeAdded() {
922 protected void onScopesOrderChanged() {
927 protected void onScopeRemoved(final int scopesCount) {
928 update(scopesCount == 1);
931 private void update(final boolean updateOptionsAndDescriptionPanel) {
932 Queue<InspectionConfigTreeNode> q = new Queue<>(nodes.size());
933 for (InspectionConfigTreeNode node : nodes) {
936 while (!q.isEmpty()) {
937 final InspectionConfigTreeNode inspectionConfigTreeNode = q.pullFirst();
938 inspectionConfigTreeNode.dropCache();
939 final TreeNode parent = inspectionConfigTreeNode.getParent();
940 if (parent != null && parent.getParent() != null) {
941 q.addLast((InspectionConfigTreeNode)parent);
945 myTreeTable.updateUI();
946 if (updateOptionsAndDescriptionPanel) {
947 updateOptionsAndDescriptionPanel();
952 final ToolbarDecorator wrappedTable = ToolbarDecorator.createDecorator(scopesAndScopesAndSeveritiesTable).disableUpDownActions().setRemoveActionUpdater(
953 new AnActionButtonUpdater() {
955 public boolean isEnabled(AnActionEvent e) {
956 final int selectedRow = scopesAndScopesAndSeveritiesTable.getSelectedRow();
957 final int rowCount = scopesAndScopesAndSeveritiesTable.getRowCount();
958 return rowCount - 1 != selectedRow;
961 final JPanel panel = wrappedTable.createPanel();
962 panel.setMinimumSize(new Dimension(getMinimumSize().width, 3 * scopesAndScopesAndSeveritiesTable.getRowHeight()));
963 severityPanel.add(new JBLabel("Severity by Scope"),
964 new GridBagConstraints(0, 0, 1, 1, 1.0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
965 JBUI.insets(5, 0, 2, 10), 0, 0));
966 severityPanel.add(panel, new GridBagConstraints(0, 1, 1, 1, 0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
967 JBUI.insets(0, 0, 0, 0), 0, 0));
968 severityPanelWeightY = 0.3;
970 myOptionsPanel.add(severityPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, severityPanelWeightY, GridBagConstraints.WEST, GridBagConstraints.BOTH,
971 JBUI.insets(0, 2, 0, 0), 0, 0));
972 if (configPanelAnchor.getComponentCount() != 0) {
973 configPanelAnchor.setBorder(IdeBorderFactory.createTitledBorder("Options", false, new JBInsets(7, 0, 0, 0)));
975 GuiUtils.enableChildren(myOptionsPanel, isThoughOneNodeEnabled(nodes));
976 if (configPanelAnchor.getComponentCount() != 0 || scopesNames.isEmpty()) {
977 myOptionsPanel.add(configPanelAnchor, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
978 JBUI.insets(0, 2, 0, 0), 0, 0));
980 myOptionsPanel.revalidate();
983 initOptionsAndDescriptionPanel();
985 myOptionsPanel.repaint();
988 private boolean isThoughOneNodeEnabled(final List<InspectionConfigTreeNode> nodes) {
989 final Project project = myProjectProfileManager.getProject();
990 for (final InspectionConfigTreeNode node : nodes) {
991 final String toolId = node.getDefaultDescriptor().getKey().toString();
992 if (myProfile.getTools(toolId, project).isEnabled()) {
999 private void updateOptionsAndDescriptionPanel() {
1000 final TreePath[] paths = myTreeTable.getTree().getSelectionPaths();
1001 if (paths != null) {
1002 updateOptionsAndDescriptionPanel(paths);
1004 initOptionsAndDescriptionPanel();
1008 private void initOptionsAndDescriptionPanel() {
1009 myOptionsPanel.removeAll();
1010 readHTML(myBrowser, EMPTY_HTML);
1011 myOptionsPanel.validate();
1012 myOptionsPanel.repaint();
1015 private boolean setSelectedProfileModified(boolean modified) {
1016 myProfile.setModified(modified);
1020 public ModifiableModel getProfile() {
1024 private void setProfile(final ModifiableModel modifiableModel) {
1025 if (myProfile == modifiableModel) return;
1026 myProfile = (InspectionProfileImpl)modifiableModel;
1031 public Dimension getPreferredSize() {
1032 return new Dimension(700, 500);
1035 public void disposeUI() {
1036 if (myInspectionProfilePanel == null) {
1039 myAlarm.cancelAllRequests();
1040 myProfileFilter.dispose();
1041 if (myProfile != null) {
1042 for (ScopeToolState state : myProfile.getAllTools(myProjectProfileManager.getProject())) {
1043 state.resetConfigPanel();
1047 Disposer.dispose(myDisposable);
1048 myDisposable = null;
1051 private JPanel createInspectionProfileSettingsPanel() {
1053 myBrowser = new JEditorPane(UIUtil.HTML_MIME, EMPTY_HTML);
1054 myBrowser.setEditable(false);
1055 myBrowser.setBorder(IdeBorderFactory.createEmptyBorder(5, 5, 5, 5));
1056 myBrowser.addHyperlinkListener(BrowserHyperlinkListener.INSTANCE);
1059 fillTreeData(myProfileFilter != null ? myProfileFilter.getFilter() : null, true);
1061 JPanel descriptionPanel = new JPanel(new BorderLayout());
1062 descriptionPanel.setBorder(IdeBorderFactory.createTitledBorder(InspectionsBundle.message("inspection.description.title"), false,
1063 new JBInsets(2, 2, 0, 0)));
1064 descriptionPanel.add(ScrollPaneFactory.createScrollPane(myBrowser), BorderLayout.CENTER);
1066 JBSplitter rightSplitter =
1067 new JBSplitter(true, "SingleInspectionProfilePanel.HORIZONTAL_DIVIDER_PROPORTION", DIVIDER_PROPORTION_DEFAULT);
1068 rightSplitter.setFirstComponent(descriptionPanel);
1070 myOptionsPanel = new JPanel(new GridBagLayout());
1071 initOptionsAndDescriptionPanel();
1072 rightSplitter.setSecondComponent(myOptionsPanel);
1073 rightSplitter.setHonorComponentsMinimumSize(true);
1075 final JScrollPane tree = initTreeScrollPane();
1077 final JPanel northPanel = new JPanel(new GridBagLayout());
1078 northPanel.setBorder(IdeBorderFactory.createEmptyBorder(2, 0, 2, 0));
1079 myProfileFilter.setPreferredSize(new Dimension(20, myProfileFilter.getPreferredSize().height));
1080 northPanel.add(myProfileFilter, new GridBagConstraints(0, 0, 1, 1, 0.5, 1, GridBagConstraints.BASELINE_TRAILING, GridBagConstraints.HORIZONTAL,
1081 JBUI.emptyInsets(), 0, 0));
1082 northPanel.add(createTreeToolbarPanel().getComponent(), new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.BASELINE_LEADING, GridBagConstraints.HORIZONTAL,
1083 JBUI.emptyInsets(), 0, 0));
1085 JBSplitter mainSplitter = new OnePixelSplitter(false, DIVIDER_PROPORTION_DEFAULT, 0.01f, 0.99f);
1086 mainSplitter.setSplitterProportionKey("SingleInspectionProfilePanel.VERTICAL_DIVIDER_PROPORTION");
1087 mainSplitter.setFirstComponent(tree);
1088 mainSplitter.setSecondComponent(rightSplitter);
1089 mainSplitter.setHonorComponentsMinimumSize(false);
1091 final JPanel panel = new JPanel(new BorderLayout());
1092 panel.add(northPanel, BorderLayout.NORTH);
1093 panel.add(mainSplitter, BorderLayout.CENTER);
1097 public boolean isModified() {
1098 if (myModified) return true;
1099 if (myProfile.isChanged()) return true;
1100 if (myProfile.getParentProfile().isProjectLevel() != myProfile.isProjectLevel()) return true;
1101 if (!Comparing.strEqual(myProfile.getParentProfile().getName(), myProfile.getName())) return true;
1102 if (!Comparing.equal(myInitialScopesOrder, myProfile.getScopesOrder())) return true;
1103 return descriptorsAreChanged();
1106 public void reset() {
1108 setProfile(myProfile);
1110 final String filter = myProfileFilter.getFilter();
1111 myProfileFilter.reset();
1112 myProfileFilter.setSelectedItem(filter);
1113 myProfile.setName(myProfile.getParentProfile().getName());
1114 myProfile.setProjectLevel(myProfile.getParentProfile().isProjectLevel());
1117 public void apply() throws ConfigurationException {
1118 final boolean modified = isModified();
1122 final ModifiableModel selectedProfile = getProfile();
1124 ProfileManager profileManager = selectedProfile.isProjectLevel() ? myProjectProfileManager : InspectionProfileManager.getInstance();
1125 InspectionProfile parentProfile = selectedProfile.getParentProfile();
1127 if (parentProfile.getProfileManager().getProfile(parentProfile.getName(), false) == parentProfile) {
1128 parentProfile.getProfileManager().deleteProfile(parentProfile.getName());
1130 if (selectedProfile.getProfileManager() != profileManager) {
1131 copyUsedSeveritiesIfUndefined(selectedProfile, profileManager);
1132 selectedProfile.setProfileManager(profileManager);
1134 selectedProfile.getProfileManager().updateProfile(selectedProfile);
1137 selectedProfile.commit();
1138 myProfile = (InspectionProfileImpl)parentProfile.getModifiableModel();
1139 setSelectedProfileModified(false);
1143 updateOptionsAndDescriptionPanel();
1146 private boolean descriptorsAreChanged() {
1147 for (ToolDescriptors toolDescriptors : myInitialToolDescriptors.values()) {
1148 Descriptor desc = toolDescriptors.getDefaultDescriptor();
1149 Project project = myProjectProfileManager.getProject();
1150 if (myProfile.isToolEnabled(desc.getKey(), null, project) != desc.isEnabled()){
1153 if (myProfile.getErrorLevel(desc.getKey(), desc.getScope(), project) != desc.getLevel()) {
1156 final List<Descriptor> descriptors = toolDescriptors.getNonDefaultDescriptors();
1157 for (Descriptor descriptor : descriptors) {
1158 if (myProfile.isToolEnabled(descriptor.getKey(), descriptor.getScope(), project) != descriptor.isEnabled()) {
1161 if (myProfile.getErrorLevel(descriptor.getKey(), descriptor.getScope(), project) != descriptor.getLevel()) {
1166 final List<ScopeToolState> tools = myProfile.getNonDefaultTools(desc.getKey().toString(), project);
1167 if (tools.size() != descriptors.size()) {
1170 for (int i = 0; i < tools.size(); i++) {
1171 final ScopeToolState pair = tools.get(i);
1172 if (!Comparing.equal(pair.getScope(project), descriptors.get(i).getScope())) {
1183 public void setVisible(boolean aFlag) {
1184 if (aFlag && myInspectionProfilePanel == null) {
1187 super.setVisible(aFlag);
1190 private void setNewHighlightingLevel(@NotNull HighlightDisplayLevel level) {
1191 final int[] rows = myTreeTable.getTree().getSelectionRows();
1192 final boolean showOptionsAndDescriptorPanels = rows != null && rows.length == 1;
1193 for (int i = 0; rows != null && i < rows.length; i++) {
1194 final InspectionConfigTreeNode node = (InspectionConfigTreeNode)myTreeTable.getTree().getPathForRow(rows[i]).getLastPathComponent();
1195 final InspectionConfigTreeNode parent = (InspectionConfigTreeNode)node.getParent();
1196 final Object userObject = node.getUserObject();
1197 if (userObject instanceof ToolDescriptors && (node.getScopeName() != null || node.isLeaf())) {
1198 updateErrorLevel(node, showOptionsAndDescriptorPanels, level);
1199 updateUpHierarchy(parent);
1202 updateErrorLevelUpInHierarchy(level, showOptionsAndDescriptorPanels, node);
1203 updateUpHierarchy(parent);
1207 updateOptionsAndDescriptionPanel(myTreeTable.getTree().getSelectionPaths());
1210 initOptionsAndDescriptionPanel();
1215 private void updateErrorLevelUpInHierarchy(@NotNull HighlightDisplayLevel level,
1216 boolean showOptionsAndDescriptorPanels,
1217 InspectionConfigTreeNode node) {
1219 for (int j = 0; j < node.getChildCount(); j++) {
1220 final InspectionConfigTreeNode child = (InspectionConfigTreeNode)node.getChildAt(j);
1221 final Object userObject = child.getUserObject();
1222 if (userObject instanceof ToolDescriptors && (child.getScopeName() != null || child.isLeaf())) {
1223 updateErrorLevel(child, showOptionsAndDescriptorPanels, level);
1226 updateErrorLevelUpInHierarchy(level, showOptionsAndDescriptorPanels, child);
1231 private void updateErrorLevel(final InspectionConfigTreeNode child,
1232 final boolean showOptionsAndDescriptorPanels,
1233 @NotNull HighlightDisplayLevel level) {
1234 final HighlightDisplayKey key = child.getDefaultDescriptor().getKey();
1235 myProfile.setErrorLevel(key, level, null, myProjectProfileManager.getProject());
1237 if (showOptionsAndDescriptorPanels) {
1238 updateOptionsAndDescriptionPanel(new TreePath(child.getPath()));
1242 public JComponent getPreferredFocusedComponent() {
1246 private class MyFilterComponent extends FilterComponent {
1247 private MyFilterComponent() {
1248 super(INSPECTION_FILTER_HISTORY, 10);
1252 public void filter() {
1253 filterTree(getFilter());
1257 protected void onlineFilter() {
1258 if (myProfile == null) return;
1259 final String filter = getFilter();
1260 getExpandedNodes(myProfile).saveVisibleState(myTreeTable.getTree());
1261 fillTreeData(filter, true);
1263 if (filter == null || filter.isEmpty()) {
1266 TreeUtil.expandAll(myTreeTable.getTree());