# This patch file was generated by NetBeans IDE # Following Index: paths are relative to: D:\hg\core-main # This patch can be applied using context Tools: Patch action on respective folder. # It uses platform neutral UTF-8 encoding and \n newlines. # Above lines and this line are ignored by the patching process. Index: core.windows/manifest.mf --- core.windows/manifest.mf Base (BASE) +++ core.windows/manifest.mf Locally Modified (Based On LOCAL) @@ -6,5 +6,5 @@ OpenIDE-Module-Recommends: org.netbeans.core.windows.nativeaccess.NativeWindowSystem AutoUpdate-Show-In-Client: false AutoUpdate-Essential-Module: true -OpenIDE-Module-Specification-Version: 2.53 +OpenIDE-Module-Specification-Version: 2.54 Index: core.windows/nbproject/project.xml --- core.windows/nbproject/project.xml Base (BASE) +++ core.windows/nbproject/project.xml Locally Modified (Based On LOCAL) @@ -85,7 +85,7 @@ - 1.34 + 1.38 @@ -173,7 +173,7 @@ - 6.57 + 6.58 Index: core.windows/src/org/netbeans/core/windows/Central.java --- core.windows/src/org/netbeans/core/windows/Central.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/Central.java Locally Modified (Based On LOCAL) @@ -113,6 +113,20 @@ new ViewRequest(modeName, View.TOPCOMPONENT_CANCEL_REQUEST_ATTENTION, tc, tc)); } + /** + * Turns tab highlight on/off + * @param mode + * @param tc + * @param highlight + * @since 2.54 + */ + public void topComponentAttentionHighlight (ModeImpl mode, TopComponent tc, boolean highlight) { + String modeName = getModeName(mode); + viewRequestor.scheduleRequest ( + new ViewRequest(modeName, highlight ? View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_ON + : View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_OFF, tc, tc)); + } + ///////////////////// // Mutators >> /** Sets visible or invisible window system and requests view accordingly. */ Index: core.windows/src/org/netbeans/core/windows/view/DefaultView.java --- core.windows/src/org/netbeans/core/windows/view/DefaultView.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/DefaultView.java Locally Modified (Based On LOCAL) @@ -482,6 +482,25 @@ Logger.getLogger(DefaultView.class.getName()).fine( "Could not find mode " + viewEvent.getSource()); } + } else if (changeType == View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_ON + || changeType == View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_OFF) { + if (DEBUG) { + debugLog("Top component attention highlight"); //NOI18N + } + ModeView modeView = hierarchy.getModeViewForAccessor(wsa.findModeAccessor((String)viewEvent.getSource())); // XXX + if (modeView != null) { + TopComponent tc = (TopComponent) viewEvent.getNewValue(); + if (tc == null) { + throw new NullPointerException ("Top component is null for attention cancellation request"); //NOI18N + } + //make sure the TC is still opened in the given mode container + if( modeView.getTopComponents().contains( tc ) ) { + modeView.setAttentionHighlight(tc, changeType == View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_ON); + } + } else { + Logger.getLogger(DefaultView.class.getName()).fine( + "Could not find mode " + viewEvent.getSource()); + } } else if (changeType == View.TOPCOMPONENT_SHOW_BUSY || changeType == View.TOPCOMPONENT_HIDE_BUSY ) { if (DEBUG) { debugLog("Top component show/hide busy"); //NOI18N Index: core.windows/src/org/netbeans/core/windows/view/ModeContainer.java --- core.windows/src/org/netbeans/core/windows/view/ModeContainer.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ModeContainer.java Locally Modified (Based On LOCAL) @@ -90,6 +90,14 @@ public void cancelRequestAttention(TopComponent tc); + /** + * + * @param tc + * @param highlight + * @since 2.54 + */ + public void setAttentionHighlight(TopComponent tc, boolean highlight); + public void makeBusy(TopComponent tc, boolean busy); } Index: core.windows/src/org/netbeans/core/windows/view/ModeView.java --- core.windows/src/org/netbeans/core/windows/view/ModeView.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ModeView.java Locally Modified (Based On LOCAL) @@ -188,6 +188,10 @@ container.cancelRequestAttention(tc); } + public void setAttentionHighlight (TopComponent tc, boolean highlight) { + container.setAttentionHighlight(tc, highlight); + } + public void makeBusy(TopComponent tc, boolean busy) { container.makeBusy(tc, busy); } Index: core.windows/src/org/netbeans/core/windows/view/ui/DefaultSeparateContainer.java --- core.windows/src/org/netbeans/core/windows/view/ui/DefaultSeparateContainer.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ui/DefaultSeparateContainer.java Locally Modified (Based On LOCAL) @@ -115,6 +115,10 @@ //not implemented } + public void setAttentionHighlight(TopComponent tc, boolean highlight) { + tabbedHandler.setAttentionHighlight( tc, highlight ); + } + @Override public void makeBusy(TopComponent tc, boolean busy) { tabbedHandler.makeBusy( tc, busy ); Index: core.windows/src/org/netbeans/core/windows/view/ui/DefaultSplitContainer.java --- core.windows/src/org/netbeans/core/windows/view/ui/DefaultSplitContainer.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ui/DefaultSplitContainer.java Locally Modified (Based On LOCAL) @@ -96,6 +96,11 @@ } @Override + public void setAttentionHighlight (TopComponent tc, boolean highlight) { + tabbedHandler.setAttentionHighlight(tc, highlight); + } + + @Override public void makeBusy(TopComponent tc, boolean busy) { tabbedHandler.makeBusy( tc, busy ); } Index: core.windows/src/org/netbeans/core/windows/view/ui/slides/SlideBarContainer.java --- core.windows/src/org/netbeans/core/windows/view/ui/slides/SlideBarContainer.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ui/slides/SlideBarContainer.java Locally Modified (Based On LOCAL) @@ -108,6 +108,11 @@ } @Override + public void setAttentionHighlight( TopComponent tc, boolean highlight ) { + tabbedHandler.setAttentionHighlight (tc, highlight); + } + + @Override public void makeBusy(TopComponent tc, boolean busy) { tabbedHandler.makeBusy( tc, busy ); } Index: core.windows/src/org/netbeans/core/windows/view/ui/TabbedHandler.java --- core.windows/src/org/netbeans/core/windows/view/ui/TabbedHandler.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ui/TabbedHandler.java Locally Modified (Based On LOCAL) @@ -144,6 +144,10 @@ tabbed.cancelRequestAttention(tc); } + public void setAttentionHighlight (TopComponent tc, boolean highlight) { + tabbed.setAttentionHighlight(tc, highlight); + } + public void makeBusy( TopComponent tc, boolean busy ) { tabbed.makeBusy( tc, busy ); } Index: core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/AbstractTabbedImpl.java --- core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/AbstractTabbedImpl.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/AbstractTabbedImpl.java Locally Modified (Based On LOCAL) @@ -120,7 +120,27 @@ protected abstract void cancelRequestAttention( int tabIndex ); + @Override + public final void setAttentionHighlight( TopComponent tc, boolean highlight ) { + int idx = indexOf( tc ); + if( idx >= 0 ) { + setAttentionHighlight( idx, highlight ); + } else { + throw new IllegalArgumentException( "TopComponent " + tc + + " is not a child of this container" ); //NOI18N + } + } + + /** + * + * @param tabIndex + * @param highlight + * @since 2.54 + */ + protected abstract void setAttentionHighlight( int tabIndex, boolean highlight ); + + @Override public final void insertComponent( String name, javax.swing.Icon icon, Component comp, String toolTip, int position ) { TabData td = new TabData( comp, icon, name, toolTip ); Index: core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/JTabbedPaneAdapter.java --- core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/JTabbedPaneAdapter.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/JTabbedPaneAdapter.java Locally Modified (Based On LOCAL) @@ -189,6 +189,11 @@ } @Override + protected void setAttentionHighlight( int tabIndex, boolean highlight ) { + JTabbedPaneAdapter.this.setAttentionHighlight( tabIndex, highlight ); + } + + @Override protected int dropIndexOfPoint( Point location ) { return JTabbedPaneAdapter.this.dropIndexOfPoint( location ); } Index: core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/TabbedAdapter.java --- core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/TabbedAdapter.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/TabbedAdapter.java Locally Modified (Based On LOCAL) @@ -299,6 +299,11 @@ } @Override + protected void setAttentionHighlight( int tabIndex, boolean highlight ) { + TabbedAdapter.this.setAttentionHighlight( tabIndex, highlight ); + } + + @Override protected int dropIndexOfPoint( Point location ) { return TabbedAdapter.this.dropIndexOfPoint( location ); } Index: core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/tabbedpane/NBTabbedPane.java --- core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/tabbedpane/NBTabbedPane.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ui/tabcontrol/tabbedpane/NBTabbedPane.java Locally Modified (Based On LOCAL) @@ -268,6 +268,16 @@ stopBlinking(); } + /** + * + * @param tabIndex + * @param highlight + * @since 2.54 + */ + public final void setAttentionHighlight( int tabIndex, boolean highlight ) { + //TODO implement + } + public final void setActive( boolean active ) { if( active != this.active ) { this.active = active; Index: core.windows/src/org/netbeans/core/windows/view/View.java --- core.windows/src/org/netbeans/core/windows/view/View.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/View.java Locally Modified (Based On LOCAL) @@ -107,7 +107,15 @@ public int TOPCOMPONENT_REQUEST_ATTENTION = 63; public int TOPCOMPONENT_CANCEL_REQUEST_ATTENTION = 64; - public int CHANGE_MAXIMIZE_TOPCOMPONENT_SLIDE_IN = 65; + /** + * @since 2.54 + */ + public int TOPCOMPONENT_ATTENTION_HIGHLIGHT_ON = 65; + /** + * @since 2.54 + */ + public int TOPCOMPONENT_ATTENTION_HIGHLIGHT_OFF = 66; + public int CHANGE_MAXIMIZE_TOPCOMPONENT_SLIDE_IN = 67; //toggle TopComponent busy public int TOPCOMPONENT_SHOW_BUSY = 70; Index: core.windows/src/org/netbeans/core/windows/view/ViewEvent.java --- core.windows/src/org/netbeans/core/windows/view/ViewEvent.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/view/ViewEvent.java Locally Modified (Based On LOCAL) @@ -129,6 +129,8 @@ case View.CHANGE_VISIBILITY_CHANGED : typeStr = "CHANGE_VISIBILITY_CHANGED"; break; //NOI18N case View.TOPCOMPONENT_REQUEST_ATTENTION : typeStr = "TOPCOMPONENT_REQUEST_ATTENTION"; break; //NOI18N case View.TOPCOMPONENT_CANCEL_REQUEST_ATTENTION : typeStr = "TOPCOMPONENT_CANCEL_REQUEST_ATTENTION"; break; //NOI18N + case View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_OFF : typeStr = "TOPCOMPONENT_ATTENTION_HIGHLIGHT_OFF"; break; //NOI18N + case View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_ON : typeStr = "TOPCOMPONENT_ATTENTION_HIGHLIGHT_ON"; break; //NOI18N case View.TOPCOMPONENT_SHOW_BUSY : typeStr = "TOPCOMPONENT_SHOW_BUSY"; break; //NOI18N case View.TOPCOMPONENT_HIDE_BUSY : typeStr = "TOPCOMPONENT_HIDE_BUSY"; break; //NOI18N } Index: core.windows/src/org/netbeans/core/windows/ViewRequest.java --- core.windows/src/org/netbeans/core/windows/ViewRequest.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/ViewRequest.java Locally Modified (Based On LOCAL) @@ -152,6 +152,12 @@ case View.TOPCOMPONENT_CANCEL_REQUEST_ATTENTION : tp = "TOPCOMPONENT_CANCEL_REQUEST_ATTENTION"; //NOI18N break; + case View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_ON : + tp = "TOPCOMPONENT_ATTENTION_HIGHLIGHT_ON"; //NOI18N + break; + case View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_OFF : + tp = "TOPCOMPONENT_ATTENTION_HIGHLIGHT_OFF"; //NOI18N + break; default : tp = "UNKNOWN"; break; Index: core.windows/src/org/netbeans/core/windows/ViewRequestor.java --- core.windows/src/org/netbeans/core/windows/ViewRequestor.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/ViewRequestor.java Locally Modified (Based On LOCAL) @@ -156,7 +156,9 @@ || type == View.CHANGE_DND_PERFORMED || type == View.CHANGE_UI_UPDATE || type == View.TOPCOMPONENT_CANCEL_REQUEST_ATTENTION - || type == View.TOPCOMPONENT_REQUEST_ATTENTION; + || type == View.TOPCOMPONENT_REQUEST_ATTENTION + || type == View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_OFF + || type == View.TOPCOMPONENT_ATTENTION_HIGHLIGHT_ON; synchronized(requests) { Object oldValue = null; Index: core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java --- core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java Base (BASE) +++ core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java Locally Modified (Based On LOCAL) @@ -159,6 +159,13 @@ central.topComponentCancelRequestAttention(mode, tc); } + @Override + public void topComponentAttentionHighlight(TopComponent tc, boolean highlight) { + ModeImpl mode = (ModeImpl) findMode(tc); + + central.topComponentAttentionHighlight(mode, tc, highlight); + } + ///////////////////////// // API impelementation >> ///////////////////////// Index: o.n.swing.tabcontrol/apichanges.xml --- o.n.swing.tabcontrol/apichanges.xml Base (BASE) +++ o.n.swing.tabcontrol/apichanges.xml Locally Modified (Based On LOCAL) @@ -109,6 +109,27 @@ + + + Allow a tab to be permanently highlighted until user activates it. + + + + + + There's a new method void setSwitcherItems(SwitcherTableItems[],int) in + SwitcherTable class which allows to change the content of document switcher + popup. + + + + + + + + + + Allow changes in SwitcherTable content. Index: o.n.swing.tabcontrol/manifest.mf --- o.n.swing.tabcontrol/manifest.mf Base (BASE) +++ o.n.swing.tabcontrol/manifest.mf Locally Modified (Based On LOCAL) @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module-Localizing-Bundle: org/netbeans/swing/tabcontrol/Bundle.properties OpenIDE-Module: org.netbeans.swing.tabcontrol -OpenIDE-Module-Specification-Version: 1.37 +OpenIDE-Module-Specification-Version: 1.38 AutoUpdate-Essential-Module: true Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/customtabs/Tabbed.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/customtabs/Tabbed.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/customtabs/Tabbed.java Locally Modified (Based On LOCAL) @@ -73,6 +73,14 @@ public abstract void cancelRequestAttention(TopComponent tc); + /** + * Turn tab highlight on/off + * @param tab + * @since 1.38 + */ + public void setAttentionHighlight(TopComponent tc, boolean highlight) { + } + public abstract void addTopComponent(String name, Icon icon, TopComponent tc, String toolTip); public abstract void insertComponent(String name, Icon icon, Component comp, String toolTip, int position); Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AbstractTabCellRenderer.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AbstractTabCellRenderer.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AbstractTabCellRenderer.java Locally Modified (Based On LOCAL) @@ -241,10 +241,20 @@ } protected final boolean isAttention() { - return (state & TabState.ATTENTION) != 0; + return (state & TabState.ATTENTION) != 0 + || (state & TabState.HIGHLIGHT) != 0; } /** + * + * @return True if the tab should be highlighted, false otherwise. + * @since 1.38 + */ + protected final boolean isHighlight() { + return (state & TabState.HIGHLIGHT) != 0; + } + + /** * Convenience getter to determine if the current state indicates * that the renderer is currently configured appears to the left of * the selected tab. Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AbstractViewTabDisplayerUI.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AbstractViewTabDisplayerUI.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AbstractViewTabDisplayerUI.java Locally Modified (Based On LOCAL) @@ -664,10 +664,23 @@ protected boolean isAttention (int tab) { if( tab < 0 ) return false; - return (tabState.getState(tab) & TabState.ATTENTION) != 0; + return (tabState.getState(tab) & TabState.ATTENTION) != 0 + || (tabState.getState(tab) & TabState.HIGHLIGHT) != 0; } + /** + * + * @param tab + * @return True to highlight the given tab, false otherwise. + * @since 1.38 + */ + protected boolean isHighlight (int tab) { + if( tab < 0 ) + return false; + return (tabState.getState(tab) & TabState.HIGHLIGHT) != 0; + } + @Override protected void requestAttention (int tab) { tabState.addAlarmTab(tab); @@ -678,6 +691,15 @@ tabState.removeAlarmTab(tab); } + @Override + protected void setAttentionHighlight (int tab, boolean highlight) { + if( highlight ) { + tabState.addHighlightTab(tab); + } else { + tabState.removeHighlightTab(tab); + } + } + final boolean isUseStretchingTabs() { if( Boolean.getBoolean("winsys.stretching_view_tabs") ) //NOI18N return true; Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/BasicTabDisplayerUI.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/BasicTabDisplayerUI.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/BasicTabDisplayerUI.java Locally Modified (Based On LOCAL) @@ -528,6 +528,14 @@ tabState.removeAlarmTab(tab); } + @Override + protected final void setAttentionHighlight (int tab, boolean highlight) { + if( highlight ) { + tabState.addHighlightTab(tab); + } else { + tabState.removeHighlightTab(tab); + } + } @Override protected void modelChanged() { @@ -537,7 +545,7 @@ //sync int idx = selectionModel.getSelectedIndex(); tabState.setSelected(idx); - tabState.pruneAlarmTabs(displayer.getModel().size()); + tabState.pruneTabs(displayer.getModel().size()); super.modelChanged(); } Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/DefaultTabbedContainerUI.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/DefaultTabbedContainerUI.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/DefaultTabbedContainerUI.java Locally Modified (Based On LOCAL) @@ -701,6 +701,11 @@ tabDisplayer.cancelRequestAttention(tab); } + @Override + protected void setAttentionHighlight (int tab, boolean highlight) { + tabDisplayer.setAttentionHighlight(tab, highlight); + } + public void setShowCloseButton (boolean val) { tabDisplayer.setShowCloseButton(val); } Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/TabState.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/TabState.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/TabState.java Locally Modified (Based On LOCAL) @@ -210,11 +210,17 @@ * @since 1.34 */ public static final int BUSY = 2*32768; + /** + * Indicates that the tab should be highlighted to draw user's attention. + * @since 1.38 + */ + public static final int HIGHLIGHT = 2*BUSY; + /** * Indicates the last constant defined - renderers that wish to add their * own bitmasks should use multiples of this number */ - public static int STATE_LAST = BUSY; + public static int STATE_LAST = HIGHLIGHT; private int pressedIndex = -1; @@ -297,6 +303,9 @@ if (isAlarmTab(tab)) { result |= ATTENTION; } + if (isHighlightTab( tab)) { + result |= HIGHLIGHT; + } return result; } @@ -402,6 +411,7 @@ selectedIndex = i; curr = i; removeAlarmTab(i); + removeHighlightTab(i); possibleChange(prev, curr, SELECTED); return prev; } @@ -431,6 +441,7 @@ active = b; possibleChange(prev, b, ACTIVE); removeAlarmTab(selectedIndex); + removeHighlightTab(selectedIndex); return prev; } @@ -457,6 +468,24 @@ } } + private final HashSet highlightTabs = new HashSet(6); + + private boolean isHighlightTab(int tab) { + return highlightTabs.contains( tab ) && !alarmTabs.contains( tab ); + } + + /** + * Highlight the given tab. + * @param highlightTab + * @since 1.38 + */ + public final void addHighlightTab(int highlightTab) { + boolean added = highlightTabs.add(highlightTab); + if (added) { + repaintTab (highlightTab); + } + } + /** Remove a tab to the list of those which should "flash" or otherwise give * some notification to the user to get their attention */ public final void removeAlarmTab (int alarmTab) { @@ -475,6 +504,18 @@ } } + /** + * Turn tab highlight off. + * @param highlightTab + * @since 1.38 + */ + public final void removeHighlightTab(int highlightTab) { + boolean removed = highlightTabs.remove( highlightTab ); + if( removed ) { + repaintTab( highlightTab ); + } + } + private Timer alarmTimer = null; private boolean attentionToggle = false; private void startAlarmTimer() { @@ -519,11 +560,15 @@ } boolean hasAlarmTabs() { - return alarmTabs != null && !alarmTabs.isEmpty(); + return !alarmTabs.isEmpty(); } - void pruneAlarmTabs(int max) { - if (!hasAlarmTabs()) { + boolean hasHighlightTabs() { + return !highlightTabs.isEmpty(); + } + + void pruneTabs(int max) { + if (!(hasAlarmTabs() || hasHighlightTabs())) { return; } for (Iterator i=alarmTabs.iterator(); i.hasNext();) { @@ -531,6 +576,11 @@ i.remove(); } } + for (Iterator i=highlightTabs.iterator(); i.hasNext();) { + if (((Integer) i.next()).intValue() >= max) { + i.remove(); + } + } if (alarmTabs.isEmpty()) { stopAlarmTimer(); } @@ -545,9 +595,9 @@ //Handling of insertions/deletions where we'll need to update the //list of blinking tabs here. void intervalAdded (ListDataEvent evt) { - if (!hasAlarmTabs()) return; int start = evt.getIndex0(); int end = evt.getIndex1(); + if (hasAlarmTabs()) { int[] alarms = (int[]) Utilities.toPrimitiveArray((Integer[]) alarmTabs.toArray(new Integer[0])); boolean changed = false; for (int i=0; i < alarms.length; i++) { @@ -563,9 +613,26 @@ } } } + if( hasHighlightTabs() ) { + int[] highlights = (int[]) Utilities.toPrimitiveArray((Integer[]) highlightTabs.toArray(new Integer[0])); + boolean changed = false; + for (int i=0; i < highlights.length; i++) { + if (highlights[i] >= start) { + highlights[i] += (end - start) + 1; + changed = true; + } + } + if (changed) { + highlightTabs.clear(); + for (int i=0; i < highlights.length; i++) { + addHighlightTab(highlights[i]); + } + } + } + } void intervalRemoved (ListDataEvent evt) { - if (!hasAlarmTabs()) return; + if (hasAlarmTabs()) { int start = evt.getIndex0(); int end = evt.getIndex1(); @@ -625,9 +692,39 @@ } } } + if( hasAlarmTabs() ) { + int start = evt.getIndex0(); + int end = evt.getIndex1(); + int[] highlights = (int[]) Utilities.toPrimitiveArray((Integer[]) highlightTabs.toArray(new Integer[0])); + Arrays.sort(highlights); + + boolean changed = false; + for (int i=0; i < highlights.length; i++) { + if (highlights[i] >= start && highlights[i] <= end) { + highlights[i] = -1; + changed = true; + } + } + for (int i=0; i < highlights.length; i++) { + if (highlights[i] > end) { + highlights[i] -= (end - start) + 1; + changed = true; + } + } + if (changed) { + highlightTabs.clear(); + for (int i=0; i < highlights.length; i++) { + if (highlights[i] != -1) { + addHighlightTab(highlights[i]); + } + } + } + } + } + void indicesAdded (ComplexListDataEvent e) { - if (!hasAlarmTabs()) return; + if (hasAlarmTabs()) { int[] alarms = (int[]) Utilities.toPrimitiveArray((Integer[]) alarmTabs.toArray(new Integer[0])); java.util.Arrays.sort(alarms); @@ -652,20 +749,42 @@ } } } + if( hasHighlightTabs() ) { + int[] highlights = (int[]) Utilities.toPrimitiveArray((Integer[]) highlightTabs.toArray(new Integer[0])); + java.util.Arrays.sort(highlights); + int[] indices = e.getIndices(); + java.util.Arrays.sort(indices); + + boolean changed = false; + for (int i=0; i < indices.length; i++) { + for (int j=0; j < highlights.length; j++) { + if (highlights[j] >= indices[i]) { + highlights[j]++; + changed = true; + } + } + } + if (changed) { + highlightTabs.clear(); + for (int i=0; i < highlights.length; i++) { + if (highlights[i] != -1) { + addHighlightTab(highlights[i]); + } + } + } + } + } + void indicesRemoved (ComplexListDataEvent e) { - if (!hasAlarmTabs()) return; + if (hasAlarmTabs()) { int[] indices = e.getIndices(); java.util.Arrays.sort(indices); int[] alarms = (int[]) Utilities.toPrimitiveArray((Integer[]) alarmTabs.toArray(new Integer[0])); java.util.Arrays.sort(alarms); - if (alarms[alarms.length -1] < indices[0]) { - //Some tab removed after the last blinking tab, don't care - return; - } - + if (alarms[alarms.length -1] >= indices[0]) { boolean changed = false; for (int i=0; i < alarms.length; i++) { //First weed out all deleted alarm tabs @@ -700,12 +819,56 @@ stopAlarmTimer(); } } + } else { + //Some tab removed after the last blinking tab, don't care + } + } + if( hasHighlightTabs() ) { + int[] indices = e.getIndices(); + java.util.Arrays.sort(indices); + + int[] highlights = (int[]) Utilities.toPrimitiveArray((Integer[]) highlightTabs.toArray(new Integer[0])); + java.util.Arrays.sort(highlights); + + if (highlights[highlights.length -1] >= indices[0]) { + + boolean changed = false; + for (int i=0; i < highlights.length; i++) { + //First weed out all deleted alarm tabs + for (int j=0; j < indices.length; j++) { + if (highlights[i] == indices[j]) { + highlights[i] = -1; + changed = true; + } + } + } + for (int i=0; i < highlights.length; i++) { + //Now decrement those that remain that are affected + int alarm = highlights[i]; + for (int j=0; j < indices.length; j++) { + if (alarm > indices[j]) { + highlights[i]--; + changed = true; + } + } + } + + if (changed) { + highlightTabs.clear(); + for (int i=0; i < highlights.length; i++) { + if (highlights[i] >= 0) { + addHighlightTab(highlights[i]); + } + } + } + } + } repaintAllTabs(); } void indicesChanged (ComplexListDataEvent e) { - if (!hasAlarmTabs()) return; + if (hasAlarmTabs()) { if (e instanceof VeryComplexListDataEvent) { //it always will be VeryComplexListDataEvent ve = (VeryComplexListDataEvent) e; @@ -738,8 +901,37 @@ } } } + if( hasHighlightTabs() ) { + if (e instanceof VeryComplexListDataEvent) { //it always will be + VeryComplexListDataEvent ve = (VeryComplexListDataEvent) e; + ArrayDiff dif = ((VeryComplexListDataEvent) e).getDiff(); + List old = Arrays.asList(dif.getOldData()); + List nue = Arrays.asList(dif.getNewData()); + + int[] highlights = (int[]) Utilities.toPrimitiveArray((Integer[]) highlightTabs.toArray(new Integer[0])); + + boolean changed = false; + for (int i=0; i < highlights.length; i++) { + Object o = old.get(highlights[i]); + int idx = nue.indexOf(o); + changed |= idx != highlights[i]; + highlights[i] = nue.indexOf(o); + } + if (changed) { + highlightTabs.clear(); + for (int i=0; i < highlights.length; i++) { + if (highlights[i] >= 0) { + addHighlightTab(highlights[i]); + } + } + } + } + } + } + + void contentsChanged(ListDataEvent evt) { if (!hasAlarmTabs()) return; //Do nothing, just means some text or icons changed @@ -896,6 +1088,7 @@ } break; case ATTENTION: + case HIGHLIGHT: go = true; } if (go) { Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabbedContainer.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabbedContainer.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabbedContainer.java Locally Modified (Based On LOCAL) @@ -621,6 +621,15 @@ } /** + * Turn tab highlight on/off + * @param tab + * @since 1.38 + */ + public final void setAttentionHighlight (int tab, boolean highlight) { + getUI().setAttentionHighlight(tab, highlight); + } + + /** * Cause the specified tab to blink or otherwisse suggest that the user should * click it. */ @@ -641,6 +650,18 @@ } /** + * + * @param data + * @since 1.38 + */ + public final void setAttentionHighlight (TabData data, boolean highlight) { + int idx = getModel().indexOf(data); + if (idx != -1) { + setAttentionHighlight(idx, highlight); + } + } + + /** * Determine if this component thinks it is "active", which * affects how the tabs are painted - typically used to indicate that * keyboard focus is somewhere within the component Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabbedContainerUI.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabbedContainerUI.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabbedContainerUI.java Locally Modified (Based On LOCAL) @@ -214,4 +214,13 @@ protected abstract void cancelRequestAttention (int tab); + /** + * Turn tab highlight on/off + * @param tab + * @since 1.38 + */ + protected void setAttentionHighlight (int tab, boolean highlight) { + } + +} Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabDisplayer.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabDisplayer.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabDisplayer.java Locally Modified (Based On LOCAL) @@ -443,6 +443,15 @@ getUI().cancelRequestAttention (tab); } + /** + * Turn tab highlight on/off + * @param tab + * @since 1.38 + */ + public final void setAttentionHighlight (int tab, boolean highlight) { + getUI().setAttentionHighlight (tab, highlight); + } + public final boolean requestAttention (TabData data) { int idx = getModel().indexOf(data); boolean result = idx >= 0; Index: o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabDisplayerUI.java --- o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabDisplayerUI.java Base (BASE) +++ o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/TabDisplayerUI.java Locally Modified (Based On LOCAL) @@ -273,6 +273,14 @@ protected abstract void cancelRequestAttention (int tab); /** + * Turn tab highlight on/off + * @param tab + * @since 1.38 + */ + protected void setAttentionHighlight (int tab, boolean highlight) { + } + + /** * @since 1.9 * @return An icon for various buttons displayed in tab control (close/pin/scroll left/right etc), see TabControlButton class. */ Index: openide.windows/apichanges.xml --- openide.windows/apichanges.xml Base (BASE) +++ openide.windows/apichanges.xml Locally Modified (Based On LOCAL) @@ -50,6 +50,24 @@ Window System API + + + Allow TopComponent's header to be permanently highlighted to draw user's attention. + + + + + + +

New method setAttentionHighlight(boolean) in TopComponent class + can be used to permanently highlight TopComponent's tab until user + activates it. +

+
+ + + +
New API to check/modify the floating and minimize state of a TopComponent. Index: openide.windows/manifest.mf --- openide.windows/manifest.mf Base (BASE) +++ openide.windows/manifest.mf Locally Modified (Based On LOCAL) @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.windows -OpenIDE-Module-Specification-Version: 6.57 +OpenIDE-Module-Specification-Version: 6.58 OpenIDE-Module-Localizing-Bundle: org/openide/windows/Bundle.properties AutoUpdate-Essential-Module: true Index: openide.windows/src/org/openide/windows/TopComponent.java --- openide.windows/src/org/openide/windows/TopComponent.java Base (BASE) +++ openide.windows/src/org/openide/windows/TopComponent.java Locally Modified (Based On LOCAL) @@ -945,6 +945,21 @@ ); } + /** + * Permanently highlights this TopComponent's tab until user activates it. + * @param highlight True to highlight the tab, false to switch the highlight off. + * @since 6.58 + * @see #requestAttention(boolean) + */ + public final void setAttentionHighlight( final boolean highlight ) { + Mutex.EVENT.readAccess( new Runnable() { + @Override + public void run() { + WindowManager.getDefault().topComponentAttentionHighlight( TopComponent.this, highlight ); + } + }); + } + /** Set the name of this top component. * The default implementation just notifies the window manager. * @param name the new display name Index: openide.windows/src/org/openide/windows/WindowManager.java --- openide.windows/src/org/openide/windows/WindowManager.java Base (BASE) +++ openide.windows/src/org/openide/windows/WindowManager.java Locally Modified (Based On LOCAL) @@ -534,6 +534,15 @@ protected void topComponentCancelRequestAttention(TopComponent tc) { } + /** + * Highlights the tab of the given TopComponent until user activates it. + * @param tc + * @param highlight True to highlight the tab, false to switch the highlight off. + * @since 6.58 + */ + protected void topComponentAttentionHighlight(TopComponent tc, boolean highlight) { + } + /** Returns unique ID for specified TopComponent. * @param tc TopComponent the component for which is ID returned * @return unique TopComponent ID