This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 228448
Collapse All | Expand All

(-)a/core.multiview/apichanges.xml (+14 lines)
Lines 110-115 Link Here
110
    <!-- ACTUAL CHANGES BEGIN HERE: -->
110
    <!-- ACTUAL CHANGES BEGIN HERE: -->
111
111
112
  <changes>
112
  <changes>
113
    <change id="Multiview.Spliting">
114
        <summary>MultiView TopComponent spliting</summary>
115
        <version major="1" minor="35"/>
116
        <date day="17" month="4" year="2013"/>
117
        <author login="theofanis"/>
118
        <compatibility addition="yes" semantic="incompatible"/>
119
        <description>
120
	    Should a MultiViewElement allow spliting? Some applications
121
	    may need that, some don't. There is a
122
	    <a href="architecture-summary.html#branding-MultiViewElement.Spliting.Enabled">
123
		branding API</a> to control such behavior now.
124
        </description>
125
        <issue number="228448"/>
126
    </change>
113
    <change id="validate.icon">
127
    <change id="validate.icon">
114
        <api name="multiview_spi"/>
128
        <api name="multiview_spi"/>
115
        <summary>Validate icons</summary>
129
        <summary>Validate icons</summary>
(-)a/core.multiview/arch.xml (-1 / +8 lines)
Lines 904-910 Link Here
904
        </question>
904
        </question>
905
-->
905
-->
906
<answer id="resources-read">
906
<answer id="resources-read">
907
No.
907
    <p>
908
	<api category="devel" group="branding" name="MultiViewElement.Spliting.Enabled" type="export">
909
	    By default a MultiViewElement allows the containing TopComponent to split it.
910
	    Some systems may however find this not of any use. Then they should brand the
911
	    <code>MultiViewElement.Spliting.Enabled</code> to <code>false</code>. NetBeans IDE
912
	    by default does allow spliting.
913
	</api>
914
    </p>
908
</answer>
915
</answer>
909
916
910
<!-- Copy this above the </api-answers> tag! -->
917
<!-- Copy this above the </api-answers> tag! -->
(-)a/core.multiview/manifest.mf (-1 / +1 lines)
Lines 1-6 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.core.multiview/1
2
OpenIDE-Module: org.netbeans.core.multiview/1
3
OpenIDE-Module-Specification-Version: 1.34
3
OpenIDE-Module-Specification-Version: 1.35
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/core/multiview/resources/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/core/multiview/resources/Bundle.properties
5
OpenIDE-Module-Layer: org/netbeans/core/multiview/resources/mf-layer.xml
5
OpenIDE-Module-Layer: org/netbeans/core/multiview/resources/mf-layer.xml
6
AutoUpdate-Essential-Module: true
6
AutoUpdate-Essential-Module: true
(-)a/core.multiview/src/org/netbeans/core/multiview/ContextAwareDescription.java (-1 / +2 lines)
Lines 51-55 Link Here
51
 */
51
 */
52
@MimeLocation(subfolderName="MultiView")
52
@MimeLocation(subfolderName="MultiView")
53
public interface ContextAwareDescription extends MultiViewDescription {
53
public interface ContextAwareDescription extends MultiViewDescription {
54
    public ContextAwareDescription createContextAwareDescription(Lookup context);
54
    public ContextAwareDescription createContextAwareDescription(Lookup context, boolean isSplitDescription);
55
    public boolean isSplitDescription();
55
}
56
}
(-)a/core.multiview/src/org/netbeans/core/multiview/EditorsAction.java (-2 / +4 lines)
Lines 142-149 Link Here
142
                        if (thisPers.getDisplayName().equals(handler.getSelectedPerspective().getDisplayName())) {
142
                        if (thisPers.getDisplayName().equals(handler.getSelectedPerspective().getDisplayName())) {
143
                            item.setSelected(true);
143
                            item.setSelected(true);
144
                        }
144
                        }
145
                        group.add(item);
145
			if (!((ContextAwareDescription) Accessor.DEFAULT.extractDescription(thisPers)).isSplitDescription()) {
146
                        add(item);
146
			    group.add(item);
147
			    add(item);
148
			}
147
                    }
149
                    }
148
                } else { // handler == null
150
                } else { // handler == null
149
                    //No reason to enable action on any TC because now it was enabled even for Welcome page
151
                    //No reason to enable action on any TC because now it was enabled even for Welcome page
(-)a/core.multiview/src/org/netbeans/core/multiview/MultiViewCloneableTopComponent.java (-3 / +42 lines)
Lines 106-112 Link Here
106
    
106
    
107
    private void setDeserializedMultiViewDescriptions(MultiViewDescription[] descriptions, 
107
    private void setDeserializedMultiViewDescriptions(MultiViewDescription[] descriptions, 
108
                                                      MultiViewDescription defaultDesc, Map existingElements) {
108
                                                      MultiViewDescription defaultDesc, Map existingElements) {
109
        peer.setDeserializedMultiViewDescriptions(descriptions, defaultDesc, existingElements);
109
        peer.setDeserializedMultiViewDescriptions(-1, descriptions, defaultDesc, null, existingElements);
110
    }
110
    }
111
    
111
    
112
    MultiViewModel getModel() {
112
    MultiViewModel getModel() {
Lines 173-181 Link Here
173
        Action[] superActions = super.getActions();
173
        Action[] superActions = super.getActions();
174
        Action[] acts = peer.peerGetActions(superActions);
174
        Action[] acts = peer.peerGetActions(superActions);
175
        
175
        
176
        Action[] myActions = new Action[acts.length + 2];
176
        Action[] myActions = new Action[acts.length + 3];
177
        System.arraycopy(acts, 0, myActions, 0, acts.length);
177
        System.arraycopy(acts, 0, myActions, 0, acts.length);
178
        myActions[acts.length + 1] = new EditorsAction();
178
        myActions[acts.length + 1] = new EditorsAction();
179
        myActions[acts.length + 2] = new SplitAction(true);
179
        return myActions;
180
        return myActions;
180
    }
181
    }
181
    
182
    
Lines 198-208 Link Here
198
    @Override
199
    @Override
199
    protected CloneableTopComponent createClonedObject() {
200
    protected CloneableTopComponent createClonedObject() {
200
        MultiViewCloneableTopComponent tc = new MultiViewCloneableTopComponent();
201
        MultiViewCloneableTopComponent tc = new MultiViewCloneableTopComponent();
201
        tc.setMultiViewDescriptions(peer.model.getDescriptions(), peer.model.getActiveDescription());;
202
	tc.setMultiViewDescriptions(peer.model.getDescriptions(), getActiveDescription());
202
        tc.setCloseOperationHandler(peer.closeHandler);
203
        tc.setCloseOperationHandler(peer.closeHandler);
203
        tc.peer.copyMimeContext(peer);
204
        tc.peer.copyMimeContext(peer);
205
	if(getSplitOrientation() != -1) {
206
	    tc.splitComponent(getSplitOrientation());
207
	    tc.updateName();
208
	}
204
        return tc;
209
        return tc;
205
    }
210
    }
211
212
    private MultiViewDescription getActiveDescription() {
213
	int splitOrientation = getSplitOrientation();
214
	MultiViewDescription activeDescription = peer.model.getActiveDescription();
215
	if (splitOrientation != -1) {
216
	    boolean isSplitDescription = false;
217
	    if (activeDescription instanceof ContextAwareDescription) {
218
		isSplitDescription = ((ContextAwareDescription) activeDescription).isSplitDescription();
219
	    }
220
	    if (isSplitDescription) {
221
		for (MultiViewDescription descr : peer.model.getDescriptions()) {
222
		    if (descr.getDisplayName().equals(activeDescription.getDisplayName())) {
223
			activeDescription = descr;
224
			break;
225
		    }
226
		}
227
	    }
228
	}
229
	return activeDescription;
230
    }
231
232
    public TopComponent splitComponent(int orientation) {
233
	peer.peerSplitComponent(orientation);
234
	return this;
235
    }
236
237
    public TopComponent clearSplit() {
238
	peer.peerClearSplit();
239
	return this;
240
    }
241
242
    public int getSplitOrientation() {
243
	return peer.getSplitOrientation();
244
    }
206
    
245
    
207
    /** Serialize this top component.
246
    /** Serialize this top component.
208
    * Subclasses wishing to store state must call the super method, then write to the stream.
247
    * Subclasses wishing to store state must call the super method, then write to the stream.
(-)a/core.multiview/src/org/netbeans/core/multiview/MultiViewModel.java (+9 lines)
Lines 73-78 Link Here
73
//    private Map nestedPerspectiveComponents; //key=description, value mull or perspectiveComponent
73
//    private Map nestedPerspectiveComponents; //key=description, value mull or perspectiveComponent
74
    private MultiViewDescription[] descriptions;
74
    private MultiViewDescription[] descriptions;
75
    private ButtonGroup group;
75
    private ButtonGroup group;
76
    private ButtonGroup groupSplit;
76
    private Collection<MultiViewElement> shownElements;
77
    private Collection<MultiViewElement> shownElements;
77
    private ArrayList<ElementSelectionListener> listeners;
78
    private ArrayList<ElementSelectionListener> listeners;
78
    private ActionRequestObserverFactory observerFactory;
79
    private ActionRequestObserverFactory observerFactory;
Lines 108-113 Link Here
108
        }
109
        }
109
        currentEditor = (defaultDescr == null || !nestedElements.containsKey(defaultDescr) ? descriptions[0] : defaultDescr);
110
        currentEditor = (defaultDescr == null || !nestedElements.containsKey(defaultDescr) ? descriptions[0] : defaultDescr);
110
        group = new BtnGroup();
111
        group = new BtnGroup();
112
	groupSplit = new BtnGroup();
111
    }
113
    }
112
    
114
    
113
    
115
    
Lines 196-201 Link Here
196
        return group;
198
        return group;
197
    }
199
    }
198
    
200
    
201
    /**
202
     * The button group where the togglebuttons for the split descriptions are put into.
203
     */
204
    ButtonGroup getButtonGroupSplit() {
205
        return groupSplit;
206
    }
207
    
199
    MultiViewElement getElementForDescription(MultiViewDescription description) {
208
    MultiViewElement getElementForDescription(MultiViewDescription description) {
200
        return getElementForDescription(description, true);
209
        return getElementForDescription(description, true);
201
    }
210
    }
(-)a/core.multiview/src/org/netbeans/core/multiview/MultiViewPeer.java (-16 / +120 lines)
Lines 71-76 Link Here
71
import javax.swing.InputMap;
71
import javax.swing.InputMap;
72
import javax.swing.JComponent;
72
import javax.swing.JComponent;
73
import javax.swing.JEditorPane;
73
import javax.swing.JEditorPane;
74
import javax.swing.JSplitPane;
74
import javax.swing.KeyStroke;
75
import javax.swing.KeyStroke;
75
import javax.swing.event.ChangeEvent;
76
import javax.swing.event.ChangeEvent;
76
import javax.swing.event.ChangeListener;
77
import javax.swing.event.ChangeListener;
Lines 130-135 Link Here
130
    private final PreferenceChangeListener editorSettingsListener = new PreferenceChangeListenerImpl();
131
    private final PreferenceChangeListener editorSettingsListener = new PreferenceChangeListenerImpl();
131
    private final PropertyChangeListener propListener;
132
    private final PropertyChangeListener propListener;
132
    private DelegateUndoRedo delegateUndoRedo;
133
    private DelegateUndoRedo delegateUndoRedo;
134
    private int splitOrientation = -1;
133
    
135
    
134
    MultiViewPeer(TopComponent pr, ActionRequestObserverFactory fact) {
136
    MultiViewPeer(TopComponent pr, ActionRequestObserverFactory fact) {
135
        selListener = new SelectionListener();
137
        selListener = new SelectionListener();
Lines 152-158 Link Here
152
        List<MultiViewDescription> arr = new ArrayList<MultiViewDescription>();
154
        List<MultiViewDescription> arr = new ArrayList<MultiViewDescription>();
153
        final Lookup lkp = MimeLookup.getLookup(mimeType);
155
        final Lookup lkp = MimeLookup.getLookup(mimeType);
154
        for (ContextAwareDescription d : lkp.lookupAll(ContextAwareDescription.class)) {
156
        for (ContextAwareDescription d : lkp.lookupAll(ContextAwareDescription.class)) {
155
            d = d.createContextAwareDescription(context.getLookup());
157
            d = d.createContextAwareDescription(context.getLookup(), false);
158
            arr.add(d);
159
            d = d.createContextAwareDescription(context.getLookup(), true);
156
            arr.add(d);
160
            arr.add(d);
157
        }
161
        }
158
        if (arr.isEmpty()) {
162
        if (arr.isEmpty()) {
Lines 187-200 Link Here
187
        closeHandler = handler;
191
        closeHandler = handler;
188
    }
192
    }
189
    
193
    
190
    void setDeserializedMultiViewDescriptions(MultiViewDescription[] descriptions, 
194
    void setDeserializedMultiViewDescriptions(int splitOrientation, MultiViewDescription[] descriptions,
191
                                                      MultiViewDescription defaultDesc, Map<MultiViewDescription, MultiViewElement> existingElements) {
195
       MultiViewDescription defaultDesc, MultiViewDescription defaultDescSplit, Map<MultiViewDescription, MultiViewElement> existingElements) {
192
        if (model != null) {
196
        if (model != null) {
193
            model.removeElementSelectionListener(selListener);
197
            model.removeElementSelectionListener(selListener);
194
        }
198
        }
199
	// if Design view was active before closing, set default to Source view
200
	defaultDesc = defaultDesc.getDisplayName().startsWith("&Design") ? descriptions[0] : defaultDesc; //NOI18N
201
	defaultDescSplit = defaultDescSplit.getDisplayName().startsWith("&Design") ? descriptions[1] : defaultDescSplit; //NOI18N
195
        model = new MultiViewModel(descriptions, defaultDesc, factory, existingElements);
202
        model = new MultiViewModel(descriptions, defaultDesc, factory, existingElements);
196
        model.addElementSelectionListener(selListener);
203
        model.addElementSelectionListener(selListener);
197
        tabs.setModel(model);
204
	tabs.setModel(model);
205
	this.splitOrientation = splitOrientation;
206
	if(splitOrientation != -1) {
207
	    tabs.peerSplitComponent(splitOrientation, this, defaultDesc, defaultDescSplit);
208
	}
198
    }
209
    }
199
    
210
    
200
    /**
211
    /**
Lines 257-262 Link Here
257
                }
268
                }
258
            });
269
            });
259
        }
270
        }
271
	if(peer instanceof MultiViewTopComponent || peer instanceof MultiViewCloneableTopComponent) {
272
            delegatingMap.put("splitWindowHorizantally", new javax.swing.AbstractAction() { // NOI18N
273
                @Override
274
                public void actionPerformed(ActionEvent evt) {
275
		    TopComponent split;
276
		    if(peer instanceof MultiViewTopComponent || peer instanceof MultiViewCloneableTopComponent) {
277
			split = ((MultiViewTopComponent) peer).splitComponent(JSplitPane.HORIZONTAL_SPLIT);
278
		    } else {
279
			split = ((MultiViewCloneableTopComponent) peer).splitComponent(JSplitPane.HORIZONTAL_SPLIT);
280
		    }
281
		    split.open();
282
		    split.requestActive();
283
                }
284
            });
285
            delegatingMap.put("splitWindowVertically", new javax.swing.AbstractAction() { // NOI18N
286
                @Override
287
                public void actionPerformed(ActionEvent evt) {
288
		    TopComponent split;
289
		    if(peer instanceof MultiViewTopComponent || peer instanceof MultiViewCloneableTopComponent) {
290
			split = ((MultiViewTopComponent) peer).splitComponent(JSplitPane.VERTICAL_SPLIT);
291
		    } else {
292
			split = ((MultiViewCloneableTopComponent) peer).splitComponent(JSplitPane.VERTICAL_SPLIT);
293
		    }
294
		    split.open();
295
		    split.requestActive();
296
                }
297
            });
298
            delegatingMap.put("clearSplit", new javax.swing.AbstractAction() { // NOI18N
299
		@Override
300
                public void actionPerformed(ActionEvent evt) {
301
		    TopComponent original;
302
		    if(peer instanceof MultiViewTopComponent || peer instanceof MultiViewCloneableTopComponent) {
303
			original = ((MultiViewTopComponent) peer).clearSplit();
304
		    } else {
305
			original = ((MultiViewCloneableTopComponent) peer).clearSplit();
306
		    }
307
		    original.open();
308
		    original.requestActive();
309
                }
310
            });
311
        }
260
        delegatingMap.put("closeWindow", new javax.swing.AbstractAction() { // NOI18N
312
        delegatingMap.put("closeWindow", new javax.swing.AbstractAction() { // NOI18N
261
           public void actionPerformed(ActionEvent evt) {
313
           public void actionPerformed(ActionEvent evt) {
262
               peer.close();
314
               peer.close();
Lines 283-289 Link Here
283
        JComponent jc = el.getToolbarRepresentation();
335
        JComponent jc = el.getToolbarRepresentation();
284
        assert jc != null : "MultiViewElement " + el.getClass() + " returns null as toolbar component."; //NOI18N
336
        assert jc != null : "MultiViewElement " + el.getClass() + " returns null as toolbar component."; //NOI18N
285
        jc.setOpaque(false);
337
        jc.setOpaque(false);
286
        tabs.setInnerToolBar(jc);
338
        tabs.setInnerToolBar(jc, ((ContextAwareDescription)model.getActiveDescription()).isSplitDescription());
287
        tabs.setToolbarBarVisible(isToolbarVisible());
339
        tabs.setToolbarBarVisible(isToolbarVisible());
288
        if (editorSettingsPreferences != null) {
340
        if (editorSettingsPreferences != null) {
289
            editorSettingsPreferences.addPreferenceChangeListener(editorSettingsListener);
341
            editorSettingsPreferences.addPreferenceChangeListener(editorSettingsListener);
Lines 315-320 Link Here
315
        showCurrentElement(true);
367
        showCurrentElement(true);
316
        tabs.setToolbarBarVisible(isToolbarVisible());
368
        tabs.setToolbarBarVisible(isToolbarVisible());
317
    }
369
    }
370
371
    void peerSplitComponent(int orientation) {
372
	splitOrientation = orientation;
373
	tabs.peerSplitComponent(orientation, this, null, null);
374
    }
375
376
    void peerClearSplit() {
377
	tabs.peerClearSplit();
378
	showCurrentElement();
379
	model.fireActivateCurrent();
380
	splitOrientation = -1;
381
    }
382
383
    int getSplitOrientation() {
384
	return splitOrientation;
385
    }
318
    
386
    
319
    boolean requestFocusInWindow() {
387
    boolean requestFocusInWindow() {
320
        // somehow this may be called when model is null
388
        // somehow this may be called when model is null
Lines 335-340 Link Here
335
     * hides the old element when switching elements.
403
     * hides the old element when switching elements.
336
     */
404
     */
337
    void hideElement(MultiViewDescription desc) {
405
    void hideElement(MultiViewDescription desc) {
406
	if (desc != null && splitOrientation != -1) {
407
	    MultiViewDescription topDesc = tabs.getTopComponentDescription();
408
	    MultiViewDescription bottomDesc = tabs.getBottomComponentDescription();
409
	    if (tabs.isHiddenTriggeredByMultiViewButton()
410
		    && (!topDesc.getDisplayName().equals(desc.getDisplayName())
411
		    || !bottomDesc.getDisplayName().equals(desc.getDisplayName()))) {
412
		MultiViewElement el = model.getElementForDescription(desc);
413
		el.componentHidden();
414
	    }
415
	    return;
416
	}
338
        if (desc != null) {
417
        if (desc != null) {
339
            MultiViewElement el = model.getElementForDescription(desc);
418
            MultiViewElement el = model.getElementForDescription(desc);
340
            el.componentHidden();
419
            el.componentHidden();
Lines 354-364 Link Here
354
        MultiViewElement el = model.getActiveElement();
433
        MultiViewElement el = model.getActiveElement();
355
        MultiViewDescription desc = model.getActiveDescription();
434
        MultiViewDescription desc = model.getActiveDescription();
356
435
357
        // TODO display name is not a good unique id..
436
	// TODO display name is not a good unique id..
358
        // also consider a usecase where multiple elements point to a single visual component.
437
	// also consider a usecase where multiple elements point to a single visual component.
359
        //. eg. property sheet uses same component and only changes model.
438
	//. eg. property sheet uses same component and only changes model.
360
        // in this case we probably should not remove and add the component from awt hierarchy
439
	// in this case we probably should not remove and add the component from awt hierarchy
361
        tabs.switchToCard(el, desc.getDisplayName());
440
	boolean isSplitDescription = false;
441
	if(desc instanceof ContextAwareDescription) {
442
	    isSplitDescription = ((ContextAwareDescription)desc).isSplitDescription();
443
	}
444
        tabs.switchToCard(el, desc.getDisplayName(), isSplitDescription);
362
        Image icon = desc.getIcon();
445
        Image icon = desc.getIcon();
363
        if( null == icon ) {
446
        if( null == icon ) {
364
            //#204072
447
            //#204072
Lines 389-395 Link Here
389
            assignLookup(el);
472
            assignLookup(el);
390
            
473
            
391
            if (peer.isVisible()) {
474
            if (peer.isVisible()) {
392
                tabs.setInnerToolBar(el.getToolbarRepresentation());
475
                tabs.setInnerToolBar(el.getToolbarRepresentation(), isSplitDescription);
393
                tabs.setToolbarBarVisible(isToolbarVisible());
476
                tabs.setToolbarBarVisible(isToolbarVisible());
394
            }
477
            }
395
            
478
            
Lines 508-515 Link Here
508
            fromMime = false;
591
            fromMime = false;
509
        }
592
        }
510
        MultiViewDescription[] descs = model.getDescriptions();
593
        MultiViewDescription[] descs = model.getDescriptions();
511
        MultiViewDescription curr = model.getActiveDescription();
594
	MultiViewDescription curr = tabs.getTopComponentDescription();
595
	MultiViewDescription currSplit = tabs.getBottomComponentDescription();
512
        int currIndex = 0;
596
        int currIndex = 0;
597
        int currIndexSplit = 0;
598
513
        for (int i = 0; i < descs.length; i++) {
599
        for (int i = 0; i < descs.length; i++) {
514
            if (!fromMime) {
600
            if (!fromMime) {
515
                out.writeObject(descs[i]);
601
                out.writeObject(descs[i]);
Lines 526-533 Link Here
526
            if (descs[i] == curr) {
612
            if (descs[i] == curr) {
527
                currIndex = i;
613
                currIndex = i;
528
            }
614
            }
615
	    if (descs[i] == currSplit) {
616
                currIndexSplit = i;
617
            }
529
        }
618
        }
530
        out.writeObject(new Integer(currIndex));
619
        out.writeObject(new Integer(currIndex));
620
        out.writeObject(new Integer(currIndexSplit));
621
	out.writeObject(new Integer(splitOrientation));
531
        
622
        
532
    }
623
    }
533
624
Lines 539-547 Link Here
539
        ArrayList<MultiViewDescription> descList = new ArrayList<MultiViewDescription>();
630
        ArrayList<MultiViewDescription> descList = new ArrayList<MultiViewDescription>();
540
        HashMap<MultiViewDescription, MultiViewElement> map = new HashMap<MultiViewDescription, MultiViewElement>();
631
        HashMap<MultiViewDescription, MultiViewElement> map = new HashMap<MultiViewDescription, MultiViewElement>();
541
        int current = 0;
632
        int current = 0;
633
        int currentSplit = 0;
634
        int splitOrient = -1;
542
        CloseOperationHandler close = null;
635
        CloseOperationHandler close = null;
543
        try {
636
        try {
544
            int counting = 0;
637
            int counting = 0;
638
	    int intCounting = 0;
545
            MultiViewDescription lastDescription = null;
639
            MultiViewDescription lastDescription = null;
546
            while (true) {
640
            while (true) {
547
                Object obj = in.readObject();
641
                Object obj = in.readObject();
Lines 576-583 Link Here
576
                }
670
                }
577
                else if (obj instanceof Integer)  {
671
                else if (obj instanceof Integer)  {
578
                    Integer integ = (Integer)obj;
672
                    Integer integ = (Integer)obj;
579
                    current = integ.intValue();
673
		    if(intCounting == 0) {
580
                    break;
674
			intCounting++;
675
			current = integ.intValue();
676
		    } else if (intCounting == 1) {
677
			intCounting++;
678
			currentSplit = integ.intValue();
679
		    } else if (intCounting == 2) {
680
			splitOrient = integ.intValue();
681
			break;
682
		    }
581
                } 
683
                } 
582
                if (obj instanceof CloseOperationHandler) {
684
                if (obj instanceof CloseOperationHandler) {
583
                    close = (CloseOperationHandler)obj;
685
                    close = (CloseOperationHandler)obj;
Lines 597-606 Link Here
597
                descs = descList.toArray(descs);
699
                descs = descList.toArray(descs);
598
                //the integer with current element was not read yet, fallback to zero.
700
                //the integer with current element was not read yet, fallback to zero.
599
                MultiViewDescription currDesc = descs[0];
701
                MultiViewDescription currDesc = descs[0];
702
                MultiViewDescription currDescSplit = descs[1];
600
703
601
                //when error, ignore any deserialized elements..
704
                //when error, ignore any deserialized elements..
602
                map.clear();
705
                map.clear();
603
                setDeserializedMultiViewDescriptions(descs, currDesc, map);
706
                setDeserializedMultiViewDescriptions(1, descs, currDesc, currDescSplit, map);
604
            }
707
            }
605
            
708
            
606
            throw exc;
709
            throw exc;
Lines 616-622 Link Here
616
        MultiViewDescription[] descs = new MultiViewDescription[descList.size()];
719
        MultiViewDescription[] descs = new MultiViewDescription[descList.size()];
617
        descs = descList.toArray(descs);
720
        descs = descList.toArray(descs);
618
        MultiViewDescription currDesc = descs[current];
721
        MultiViewDescription currDesc = descs[current];
619
        setDeserializedMultiViewDescriptions(descs, currDesc, map);
722
        MultiViewDescription currDescSplit = descs[currentSplit];
723
        setDeserializedMultiViewDescriptions(splitOrient, descs, currDesc, currDescSplit, map);
620
    }    
724
    }    
621
725
622
    private Action[] getDefaultTCActions() {
726
    private Action[] getDefaultTCActions() {
(-)a/core.multiview/src/org/netbeans/core/multiview/MultiViewTopComponent.java (-4 / +23 lines)
Lines 101-107 Link Here
101
    
101
    
102
    private void setDeserializedMultiViewDescriptions(MultiViewDescription[] descriptions, 
102
    private void setDeserializedMultiViewDescriptions(MultiViewDescription[] descriptions, 
103
                                                      MultiViewDescription defaultDesc, Map existingElements) {
103
                                                      MultiViewDescription defaultDesc, Map existingElements) {
104
        peer.setDeserializedMultiViewDescriptions(descriptions, defaultDesc, existingElements);
104
        peer.setDeserializedMultiViewDescriptions(-1, descriptions, defaultDesc, null, existingElements);
105
    }
105
    }
106
    
106
    
107
    MultiViewModel getModel() {
107
    MultiViewModel getModel() {
Lines 161-169 Link Here
161
        //TEMP don't delegate to element's actions..
161
        //TEMP don't delegate to element's actions..
162
        Action[] superActions = superActions4Tests == null ? super.getActions() : superActions4Tests;
162
        Action[] superActions = superActions4Tests == null ? super.getActions() : superActions4Tests;
163
        Action[] acts = peer.peerGetActions(superActions);
163
        Action[] acts = peer.peerGetActions(superActions);
164
        Action[] myActions = new Action[acts.length + 2];
164
        Action[] myActions = new Action[acts.length + 3];
165
        System.arraycopy(acts, 0, myActions, 0, acts.length);
165
        System.arraycopy(acts, 0, myActions, 0, acts.length);
166
        myActions[acts.length + 1] = new EditorsAction();
166
        myActions[acts.length + 1] = new EditorsAction();
167
        myActions[acts.length + 2] = new SplitAction(true);
167
        return myActions;
168
        return myActions;
168
    }
169
    }
169
    
170
    
Lines 292-307 Link Here
292
        SubComponent[] res = new SubComponent[perspectives.length];
293
        SubComponent[] res = new SubComponent[perspectives.length];
293
        for( int i=0; i<perspectives.length; i++ ) {
294
        for( int i=0; i<perspectives.length; i++ ) {
294
            final MultiViewPerspective mvp = perspectives[i];
295
            final MultiViewPerspective mvp = perspectives[i];
295
            res[i] = new SubComponent( Actions.cutAmpersand(mvp.getDisplayName()), new ActionListener() {
296
	    MultiViewDescription descr = Accessor.DEFAULT.extractDescription(mvp);
297
	    Lookup lookup = descr == null ? peer.getLookup() :
298
		    model.getElementForDescription(descr, false) == null ? peer.getLookup() : model.getElementForDescription(descr, false).getLookup();
299
	    boolean showing = peer.tabs.isShowing(descr);
300
            res[i] = new SubComponent( Actions.cutAmpersand(mvp.getDisplayName()), null, new ActionListener() {
296
301
297
                @Override
302
                @Override
298
                public void actionPerformed( ActionEvent e ) {
303
                public void actionPerformed( ActionEvent e ) {
299
                    peer.getMultiViewHandlerDelegate().requestActive( mvp );
304
                    peer.getMultiViewHandlerDelegate().requestActive( mvp );
300
                }
305
                }
301
            }, mvp == model.getSelectedPerspective() );
306
            }, mvp == model.getSelectedPerspective(), lookup, showing );
302
        }
307
        }
303
        return res;
308
        return res;
304
    }
309
    }
310
311
    public TopComponent splitComponent(int orientation) {
312
	peer.peerSplitComponent(orientation);
313
	return this;
314
    }
315
316
    public TopComponent clearSplit() {
317
	peer.peerClearSplit();
318
	return this;
319
    }
320
321
    public int getSplitOrientation() {
322
	return peer.getSplitOrientation();
323
    }
305
    
324
    
306
//    public Lookup getLookup() {
325
//    public Lookup getLookup() {
307
//        return peer.getLookup(super.getLookup());
326
//        return peer.getLookup(super.getLookup());
(-)a/core.multiview/src/org/netbeans/core/multiview/SplitAction.java (+243 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.core.multiview;
43
44
import java.awt.event.ActionEvent;
45
import java.util.Map;
46
import javax.swing.AbstractAction;
47
import javax.swing.Action;
48
import javax.swing.JComponent;
49
import javax.swing.JMenu;
50
import javax.swing.JMenuItem;
51
import javax.swing.JSplitPane;
52
import javax.swing.SwingUtilities;
53
import org.openide.awt.DynamicMenuContent;
54
import org.openide.awt.Mnemonics;
55
import org.openide.util.NbBundle;
56
import org.openide.util.NbBundle.Messages;
57
import org.openide.util.actions.Presenter;
58
import org.openide.windows.TopComponent;
59
import org.openide.windows.WindowManager;
60
61
/**
62
 * Action to show in main menu to split document.
63
 *
64
 * @author Th. Oikonomou
65
 */
66
@Messages({"CTL_SplitDocumentAction=&Split Document", "CTL_SplitAction=&Split", "MultiViewElement.Spliting.Enabled=true"})
67
public class SplitAction extends AbstractAction implements Presenter.Menu, Presenter.Popup {
68
69
    boolean useSplitName = false;
70
71
    public SplitAction() {
72
	super(Bundle.CTL_SplitDocumentAction());
73
    }
74
75
    public SplitAction(boolean useSplitName) {
76
	super(Bundle.CTL_SplitDocumentAction());
77
	this.useSplitName = useSplitName;
78
    }
79
80
    static Action createSplitAction(Map map) {
81
	if(!isSplitingEnabled()) {
82
	    return null;
83
	}
84
	Object nameObj = map.get("displayName"); //NOI18N
85
	if (nameObj == null) {
86
	    return null;
87
	}
88
	return new SplitAction(nameObj.toString().equals(Bundle.CTL_SplitAction()));
89
    }
90
91
    @Override
92
    public void actionPerformed(ActionEvent ev) {
93
	assert false;
94
    }
95
96
    @Override
97
    public JMenuItem getMenuPresenter() {
98
	return getSplitMenuItem();
99
    }
100
101
    @Override
102
    public JMenuItem getPopupPresenter() {
103
	return getSplitMenuItem();
104
    }
105
    
106
    private JMenuItem getSplitMenuItem() {
107
	if(!isSplitingEnabled()) {
108
	    return null;
109
	}
110
	JMenu menu = new SplitAction.UpdatingMenu();
111
	String label = useSplitName ? Bundle.CTL_SplitAction() : Bundle.CTL_SplitDocumentAction();
112
	Mnemonics.setLocalizedText(menu, label);
113
	return menu;
114
    }
115
116
    private static boolean isSplitingEnabled() {
117
	boolean splitingEnabled = "true".equals(Bundle.MultiViewElement_Spliting_Enabled()); // NOI18N
118
	return splitingEnabled;
119
    }
120
121
    private static final class UpdatingMenu extends JMenu implements DynamicMenuContent {
122
123
	@Override
124
	public JComponent[] synchMenuPresenters(JComponent[] items) {
125
	    return getMenuPresenters();
126
	}
127
128
	@Override
129
	public JComponent[] getMenuPresenters() {
130
	    assert SwingUtilities.isEventDispatchThread() : "Must be called from AWT";
131
	    removeAll();
132
	    final TopComponent tc = WindowManager.getDefault().getRegistry().getActivated();
133
	    if (tc != null) {
134
		setEnabled(true);
135
		if (tc instanceof MultiViewTopComponent || tc instanceof MultiViewCloneableTopComponent) {
136
		    JMenuItem item = new JMenuItem(new SplitDocumentAction(tc, JSplitPane.VERTICAL_SPLIT));
137
		    Mnemonics.setLocalizedText(item, item.getText());
138
		    add(item);
139
		    item = new JMenuItem(new SplitDocumentAction(tc, JSplitPane.HORIZONTAL_SPLIT));
140
		    Mnemonics.setLocalizedText(item, item.getText());
141
		    add(item);
142
		    item = new JMenuItem(new ClearSplitAction(tc));
143
		    Mnemonics.setLocalizedText(item, item.getText());
144
		    add(item);
145
		} else { // tc is not splitable
146
		    //No reason to enable action on any TC because now it was enabled even for Welcome page
147
		    setEnabled(false);
148
		    /*JRadioButtonMenuItem but = new JRadioButtonMenuItem();
149
		     Mnemonics.setLocalizedText(but, NbBundle.getMessage(EditorsAction.class, "EditorsAction.source"));
150
		     but.setSelected(true);
151
		     add(but);*/
152
		}
153
	    } else { // tc == null
154
		setEnabled(false);
155
	    }
156
	    return new JComponent[]{this};
157
	}
158
    }
159
160
    @NbBundle.Messages({"LBL_SplitDocumentActionVertical=&Vertically",
161
	"LBL_SplitDocumentActionHorizontal=&Horizontally",
162
	"LBL_ValueSplitVertical=splitVertically",
163
	"LBL_ValueSplitHorizontal=splitHorizontally"})
164
    private static class SplitDocumentAction extends AbstractAction {
165
166
	private final TopComponent tc;
167
	private final int orientation;
168
169
	public SplitDocumentAction(TopComponent tc, int orientation) {
170
	    this.tc = tc;
171
	    this.orientation = orientation;
172
	    putValue(Action.NAME, orientation == JSplitPane.VERTICAL_SPLIT ? Bundle.LBL_SplitDocumentActionVertical() : Bundle.LBL_SplitDocumentActionHorizontal());
173
	    //hack to insert extra actions into JDev's popup menu
174
	    putValue("_nb_action_id_", orientation == JSplitPane.VERTICAL_SPLIT ? Bundle.LBL_ValueSplitVertical() : Bundle.LBL_ValueSplitHorizontal()); //NOI18N
175
	    if (tc instanceof MultiViewTopComponent) {
176
		setEnabled(((MultiViewTopComponent) tc).getSplitOrientation() == -1
177
			|| ((MultiViewTopComponent) tc).getSplitOrientation() != orientation);
178
	    } else if (tc instanceof MultiViewCloneableTopComponent) {
179
		setEnabled(((MultiViewCloneableTopComponent) tc).getSplitOrientation() == -1
180
			|| ((MultiViewCloneableTopComponent) tc).getSplitOrientation() != orientation);
181
	    } else {
182
		setEnabled(false);
183
	    }
184
	}
185
186
	@Override
187
	public void actionPerformed(ActionEvent evt) {
188
	    splitWindow(tc, orientation);
189
	}
190
    }
191
192
    @NbBundle.Messages({"LBL_ClearSplitAction=&Clear",
193
	"LBL_ValueClearSplit=clearSplit"})
194
    private static class ClearSplitAction extends AbstractAction {
195
196
	private final TopComponent tc;
197
198
	public ClearSplitAction(TopComponent tc) {
199
	    this.tc = tc;
200
	    putValue(Action.NAME, Bundle.LBL_ClearSplitAction());
201
	    //hack to insert extra actions into JDev's popup menu
202
	    putValue("_nb_action_id_", Bundle.LBL_ValueClearSplit()); //NOI18N
203
	    if (tc instanceof MultiViewTopComponent) {
204
		setEnabled(((MultiViewTopComponent) tc).getSplitOrientation() != -1);
205
	    } else if (tc instanceof MultiViewCloneableTopComponent) {
206
		setEnabled(((MultiViewCloneableTopComponent) tc).getSplitOrientation() != -1);
207
	    } else {
208
		setEnabled(false);
209
	    }
210
	}
211
212
	@Override
213
	public void actionPerformed(ActionEvent evt) {
214
	    clearSplit(tc);
215
	}
216
    }
217
218
    static void splitWindow(TopComponent tc, int orientation) {
219
	if (tc instanceof MultiViewTopComponent || tc instanceof MultiViewCloneableTopComponent) {
220
	    TopComponent split;
221
	    if (tc instanceof MultiViewTopComponent) {
222
		split = ((MultiViewTopComponent) tc).splitComponent(orientation);
223
	    } else {
224
		split = ((MultiViewCloneableTopComponent) tc).splitComponent(orientation);
225
	    }
226
	    split.open();
227
	    split.requestActive();
228
	}
229
    }
230
231
    static void clearSplit(TopComponent tc) {
232
	if (tc instanceof MultiViewTopComponent || tc instanceof MultiViewCloneableTopComponent) {
233
	    TopComponent original;
234
	    if (tc instanceof MultiViewTopComponent) {
235
		original = ((MultiViewTopComponent) tc).clearSplit();
236
	    } else {
237
		original = ((MultiViewCloneableTopComponent) tc).clearSplit();
238
	    }
239
	    original.open();
240
	    original.requestActive();
241
	}
242
    }
243
}
(-)a/core.multiview/src/org/netbeans/core/multiview/TabsComponent.java (-17 / +452 lines)
Lines 46-51 Link Here
46
46
47
import java.awt.*;
47
import java.awt.*;
48
import java.awt.event.*;
48
import java.awt.event.*;
49
import java.beans.PropertyChangeEvent;
50
import java.beans.PropertyChangeListener;
49
import java.util.Enumeration;
51
import java.util.Enumeration;
50
import java.util.HashSet;
52
import java.util.HashSet;
51
import java.util.Set;
53
import java.util.Set;
Lines 72-81 Link Here
72
    MultiViewModel model;
74
    MultiViewModel model;
73
    private MouseListener buttonMouseListener = null;
75
    private MouseListener buttonMouseListener = null;
74
    private JComponent toolbarPanel;
76
    private JComponent toolbarPanel;
77
    private JComponent toolbarPanelSplit;
75
    JPanel componentPanel; /** package private for tests */
78
    JPanel componentPanel; /** package private for tests */
79
    JPanel componentPanelSplit; /** package private for tests */
76
    private CardLayout cardLayout;
80
    private CardLayout cardLayout;
81
    private CardLayout cardLayoutSplit;
77
    private Set<MultiViewElement> alreadyAddedElements;
82
    private Set<MultiViewElement> alreadyAddedElements;
83
    private Set<MultiViewElement> alreadyAddedElementsSplit;
78
    private JToolBar bar;
84
    private JToolBar bar;
85
    private JToolBar barSplit;
86
87
    private JSplitPane splitPane;
88
    private AWTEventListener awtEventListener;
89
    private boolean isTopLeft = true;
90
    private JPanel topLeftComponent;
91
    private JPanel bottomRightComponent;
92
    private Dimension barMinSize;
93
    private Dimension panelMinSizep;
94
    private MultiViewDescription[] topBottomDescriptions = null;
95
    private PropertyChangeListener splitterPropertyChangeListener;
96
    private boolean removeSplit = false;
97
    private MultiViewPeer mvPeer;
98
    private boolean hiddenTriggeredByMultiViewButton = false;
79
    
99
    
80
    private static final boolean AQUA = "Aqua".equals(UIManager.getLookAndFeel().getID()); //NOI18N
100
    private static final boolean AQUA = "Aqua".equals(UIManager.getLookAndFeel().getID()); //NOI18N
81
101
Lines 124-140 Link Here
124
        int prefHeight = -1;
144
        int prefHeight = -1;
125
        int prefWidth = -1;
145
        int prefWidth = -1;
126
        for (int i = 0; i < descs.length; i++) {
146
        for (int i = 0; i < descs.length; i++) {
127
            JToggleButton button = createButton(descs[i]);
147
	    boolean shouldCreateToggleButton = true;
128
            model.getButtonGroup().add(button);
148
	    if(descs[i] instanceof ContextAwareDescription) {
129
            GridBagConstraints cons = new GridBagConstraints();
149
		shouldCreateToggleButton = !((ContextAwareDescription)descs[i]).isSplitDescription();
130
            cons.anchor = GridBagConstraints.WEST;
150
	    }
131
            prefHeight = Math.max(button.getPreferredSize().height, prefHeight);
151
	    if (shouldCreateToggleButton) {
132
            bar.add(button, cons);
152
		JToggleButton button = createButton(descs[i]);
133
            prefWidth = Math.max(button.getPreferredSize().width, prefWidth);
153
		model.getButtonGroup().add(button);
134
            if (descs[i] == model.getActiveDescription()) {
154
		GridBagConstraints cons = new GridBagConstraints();
135
                active = button;
155
		cons.anchor = GridBagConstraints.WEST;
136
                
156
		prefHeight = Math.max(button.getPreferredSize().height, prefHeight);
137
            }
157
		bar.add(button, cons);
158
		prefWidth = Math.max(button.getPreferredSize().width, prefWidth);
159
		if (descs[i] == model.getActiveDescription()) {
160
		    active = button;
161
		}
162
	    }
138
        }
163
        }
139
        Enumeration en = model.getButtonGroup().getElements();
164
        Enumeration en = model.getButtonGroup().getElements();
140
        while (en.hasMoreElements()) {
165
        while (en.hasMoreElements()) {
Lines 158-164 Link Here
158
    }
183
    }
159
184
160
    
185
    
161
    void switchToCard(MultiViewElement elem, String id) {
186
    MultiViewDescription getTopComponentDescription() {
187
	return topBottomDescriptions == null ? model.getActiveDescription() : topBottomDescriptions[0];
188
    }
189
190
    MultiViewDescription getBottomComponentDescription() {
191
	return topBottomDescriptions == null ? model.getActiveDescription() : topBottomDescriptions[1];
192
    }
193
194
    void peerClearSplit() {
195
	MultiViewDescription activeDescription = topBottomDescriptions[0];
196
	Toolkit.getDefaultToolkit().removeAWTEventListener(getAWTEventListener());
197
	splitPane.removePropertyChangeListener(splitterPropertyChangeListener);
198
	removeAll();
199
	splitPane = null;
200
	topBottomDescriptions = null;
201
	isTopLeft = true;
202
	topLeftComponent = null;
203
	bottomRightComponent = null;
204
	alreadyAddedElementsSplit = null;
205
	awtEventListener = null;
206
	barSplit = null;
207
	cardLayoutSplit = null;
208
	componentPanelSplit = null;
209
	toolbarPanelSplit = null;
210
	splitterPropertyChangeListener = null;
211
	mvPeer = null;
212
	
213
	add(bar, BorderLayout.NORTH);
214
        add(componentPanel, BorderLayout.CENTER);
215
	model.setActiveDescription(activeDescription);
216
    }
217
218
    private void setupSplit() {
219
	topLeftComponent = new JPanel(new BorderLayout());
220
	barMinSize = bar.getMinimumSize();
221
	panelMinSizep = componentPanel.getMinimumSize();
222
	topLeftComponent.add(bar, BorderLayout.NORTH);
223
        topLeftComponent.add(componentPanel, BorderLayout.CENTER);
224
225
	bottomRightComponent = new JPanel();
226
	barSplit = new JToolBar();
227
        Border b = (Border)UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
228
        barSplit.setBorder(b);
229
        barSplit.setFloatable(false);
230
        barSplit.setFocusable(true);
231
        if( "Windows".equals( UIManager.getLookAndFeel().getID())
232
                && !isXPTheme()) {
233
            barSplit.setRollover(true);
234
        } else if( AQUA ) {
235
            barSplit.setBackground(UIManager.getColor("NbExplorerView.background"));
236
        }
237
238
        bottomRightComponent.setLayout(new BorderLayout());
239
        bottomRightComponent.add(barSplit, BorderLayout.NORTH);
240
        startTogglingSplit();
241
        setToolbarBarVisibleSplit(bar.isVisible());
242
243
        componentPanelSplit = new JPanel();
244
        cardLayoutSplit = new CardLayout();
245
        componentPanelSplit.setLayout(cardLayoutSplit);
246
        bottomRightComponent.add(componentPanelSplit, BorderLayout.CENTER);
247
        alreadyAddedElementsSplit = new HashSet<MultiViewElement>();
248
249
        MultiViewDescription[] descs = model.getDescriptions();
250
        MultiViewDescription def = model.getActiveDescription();
251
        GridBagLayout grid = new GridBagLayout();
252
        barSplit.setLayout(grid);
253
	JToggleButton activeSplit = null;
254
        int prefHeight = -1;
255
        int prefWidth = -1;
256
        for (int i = 0; i < descs.length; i++) {
257
	    if (descs[i] instanceof ContextAwareDescription && ((ContextAwareDescription)descs[i]).isSplitDescription()) {
258
		JToggleButton button = createButton(descs[i]);
259
		model.getButtonGroupSplit().add(button);
260
		GridBagConstraints cons = new GridBagConstraints();
261
		cons.anchor = GridBagConstraints.WEST;
262
		prefHeight = Math.max(button.getPreferredSize().height, prefHeight);
263
		barSplit.add(button, cons);
264
		prefWidth = Math.max(button.getPreferredSize().width, prefWidth);
265
		if (descs[i].getDisplayName().startsWith(def.getDisplayName())) {
266
		    activeSplit = button;
267
		}
268
	    }
269
        }
270
        Enumeration en = model.getButtonGroupSplit().getElements();
271
        while (en.hasMoreElements()) {
272
            JToggleButton but = (JToggleButton)en.nextElement();
273
            Insets ins = but.getBorder().getBorderInsets(but);
274
            but.setPreferredSize(new Dimension(prefWidth + 10, prefHeight));
275
            but.setMinimumSize(new Dimension(prefWidth + 10, prefHeight));
276
277
        }
278
        if (activeSplit != null) {
279
            activeSplit.setSelected(true);
280
        }
281
282
        toolbarPanelSplit = getEmptyInnerToolBar();
283
        GridBagConstraints cons = new GridBagConstraints();
284
        cons.anchor = GridBagConstraints.EAST;
285
        cons.fill = GridBagConstraints.BOTH;
286
        cons.gridwidth = GridBagConstraints.REMAINDER;
287
        cons.weightx = 1;
288
289
        barSplit.add(toolbarPanelSplit, cons);
290
    }
291
292
    void peerSplitComponent(int orientation, MultiViewPeer mvPeer, MultiViewDescription defaultDesc, MultiViewDescription defaultDescClone) {
293
	MultiViewDescription[] descriptions = model.getDescriptions();
294
	this.mvPeer = mvPeer;
295
296
	MultiViewDescription activeDescription = model.getActiveDescription();
297
	if (splitPane == null) {
298
	    splitPane = new JSplitPane();
299
	    topBottomDescriptions = new MultiViewDescription[2];
300
	    if (defaultDesc != null && defaultDescClone != null) {// called during deserialization
301
		topBottomDescriptions[0] = defaultDesc;
302
		topBottomDescriptions[1] = defaultDescClone;
303
	    } else {
304
		int activeDescIndex = 0;
305
		for (int i = 0; i < descriptions.length; i++) {
306
		    MultiViewDescription multiViewDescription = descriptions[i];
307
		    if (multiViewDescription.getDisplayName().equals(activeDescription.getDisplayName())) {
308
			activeDescIndex = i;
309
			break;
310
		    }
311
		}
312
		topBottomDescriptions[0] = descriptions[activeDescIndex];
313
		topBottomDescriptions[1] = descriptions[activeDescIndex + 1];
314
	    }
315
	    
316
	    setupSplit();
317
	    splitPane.setOneTouchExpandable(true);
318
	    splitPane.setContinuousLayout(true);
319
	    splitPane.setResizeWeight(0.5);
320
321
	    removeAll();
322
	    Toolkit.getDefaultToolkit().addAWTEventListener(getAWTEventListener(), MouseEvent.MOUSE_EVENT_MASK | MouseEvent.MOUSE_MOTION_EVENT_MASK);
323
	    add(splitPane, BorderLayout.CENTER);
324
325
326
	    MultiViewDescription bottomDescription = topBottomDescriptions[1];
327
	    isTopLeft = false;
328
	    model.setActiveDescription(bottomDescription);
329
	    if (defaultDesc != null && defaultDescClone != null) {// called during deserialization
330
		selecteAppropriateButton();
331
	    }
332
333
	    MultiViewDescription topDescription = topBottomDescriptions[0];
334
	    isTopLeft = true;
335
	    model.setActiveDescription(topDescription);
336
	    if (defaultDesc != null && defaultDescClone != null) {// called during deserialization
337
		selecteAppropriateButton();
338
	    }
339
	} else {
340
	    topLeftComponent = (JPanel) splitPane.getTopComponent();
341
	    bottomRightComponent = (JPanel) splitPane.getBottomComponent();
342
	}
343
	if(orientation != splitPane.getOrientation()) {
344
	    splitPane.removePropertyChangeListener(splitterPropertyChangeListener);
345
	    splitterPropertyChangeListener = null;
346
	}
347
	splitPane.setOrientation(orientation);
348
	splitPane.setTopComponent(topLeftComponent);
349
	splitPane.setBottomComponent(bottomRightComponent);
350
	splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, getSplitterPropertyChangeListener(orientation));
351
	topLeftComponent.setMinimumSize(new Dimension(0, 0));
352
	bottomRightComponent.setMinimumSize(new Dimension(0, 0));
353
    }
354
355
    private void selecteAppropriateButton() {
356
	Enumeration en = model.getButtonGroupSplit().getElements();
357
	while (en.hasMoreElements()) {
358
	    JToggleButton but = (JToggleButton) en.nextElement();
359
	    MultiViewDescription buttonsDescription = ((TabsButtonModel) but.getModel()).getButtonsDescription();
360
	    if (buttonsDescription == (isTopLeft ? topBottomDescriptions[0] : topBottomDescriptions[1])) {
361
		but.setSelected(true);
362
	    }
363
	}
364
    }
365
366
    private PropertyChangeListener getSplitterPropertyChangeListener(final int orientation) {
367
	if (splitterPropertyChangeListener == null) {
368
	    splitterPropertyChangeListener = new PropertyChangeListener() {
369
		@Override
370
		public void propertyChange(PropertyChangeEvent pce) {
371
		    if (splitPane != null) {
372
			int current = Integer.parseInt(pce.getNewValue().toString());
373
			int dividerSize = splitPane.getDividerSize();
374
			int splitSize;
375
			int topMinSize;
376
			int bottomMinSize;
377
			if (orientation == JSplitPane.VERTICAL_SPLIT) {
378
			    splitSize = splitPane.getHeight();
379
			    topMinSize = (int) topLeftComponent.getMinimumSize().getHeight();
380
			    bottomMinSize = (int) bottomRightComponent.getMinimumSize().getHeight();
381
			} else {
382
			    splitSize = splitPane.getWidth();
383
			    topMinSize = (int) topLeftComponent.getMinimumSize().getWidth();
384
			    bottomMinSize = (int) bottomRightComponent.getMinimumSize().getWidth();
385
			}
386
			int min = topMinSize;
387
			int max = splitSize - bottomMinSize - dividerSize;
388
			if (current <= min || current >= max) {
389
			    removeSplit = true;
390
			} else {
391
			    removeSplit = false;
392
			}
393
		    }
394
		}
395
	    };
396
	}
397
	return splitterPropertyChangeListener;
398
    }
399
400
401
    @NbBundle.Messages({"LBL_ClearAllSplitsDialogMessage=Do you really want to clear the split?",
402
	"LBL_ClearAllSplitsDialogTitle=Clear Split"})
403
    private AWTEventListener getAWTEventListener() {
404
	if (awtEventListener == null) {
405
	    awtEventListener = new AWTEventListener() {
406
                @Override
407
                public void eventDispatched(AWTEvent event) {
408
                    MouseEvent e = (MouseEvent) event;
409
		    if (splitPane != null && e.getID() == MouseEvent.MOUSE_PRESSED) {
410
			MultiViewDescription activeDescription = null;
411
			Point locationOnScreen = e.getLocationOnScreen();
412
			SwingUtilities.convertPointFromScreen(locationOnScreen, splitPane);
413
			Component component = e.getComponent();
414
			while(component != null && component != splitPane) {
415
			    component = component.getParent();
416
			}
417
			if (component == splitPane && splitPane.getTopComponent().getBounds().contains(locationOnScreen)) {
418
			    isTopLeft = true;
419
			    activeDescription = topBottomDescriptions[0];
420
			} else if (component == splitPane && splitPane.getBottomComponent().getBounds().contains(locationOnScreen)) {
421
			    isTopLeft = false;
422
			    activeDescription = topBottomDescriptions[1];
423
			}
424
			if (activeDescription != null) {
425
			    if (!model.getActiveDescription().equals(activeDescription) ||
426
				    ((ContextAwareDescription)model.getActiveDescription()).isSplitDescription() != ((ContextAwareDescription)activeDescription).isSplitDescription()) {
427
				model.setActiveDescription(activeDescription);
428
			    }
429
			}
430
		    } else if (splitPane != null && e.getID() == MouseEvent.MOUSE_RELEASED) {
431
			if (removeSplit) {
432
			    if (e.getClickCount() != 0) {
433
				return;
434
			    }
435
			    if (mvPeer != null) {
436
				mvPeer.peerClearSplit();
437
				bar.setMinimumSize(barMinSize);
438
				componentPanel.setMinimumSize(panelMinSizep);
439
			    }
440
			    removeSplit = false;
441
			}
442
		    }
443
                }
444
            };
445
        }
446
        return awtEventListener;
447
    }
448
449
    private void changeSplitOrientation(int orientation) {
450
	splitPane.removePropertyChangeListener(splitterPropertyChangeListener);
451
	splitterPropertyChangeListener = null;
452
	splitPane.setOrientation(orientation);
453
	splitPane.setDividerLocation(0.5);
454
	splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, getSplitterPropertyChangeListener(orientation));
455
    }
456
457
    boolean isHiddenTriggeredByMultiViewButton() {
458
	return hiddenTriggeredByMultiViewButton;
459
    }
460
461
    boolean isShowing(MultiViewDescription descr) {
462
	if(descr == null) {
463
	    return false;
464
	}
465
	if(splitPane == null) {
466
	    return model.getActiveDescription() == descr;
467
	}
468
	return isTopLeft ? topBottomDescriptions[1] == descr : topBottomDescriptions[0] == descr;
469
    }
470
471
    void switchToCard(MultiViewElement elem, String id, boolean isSplitElement) {
472
	if (isSplitElement) {
473
	    switchToCardSplit(elem, id);
474
	    return;
475
	}
162
        if (! alreadyAddedElements.contains(elem)) {
476
        if (! alreadyAddedElements.contains(elem)) {
163
            componentPanel.add(elem.getVisualRepresentation(), id);
477
            componentPanel.add(elem.getVisualRepresentation(), id);
164
            alreadyAddedElements.add(elem);
478
            alreadyAddedElements.add(elem);
Lines 166-171 Link Here
166
        cardLayout.show(componentPanel, id);
480
        cardLayout.show(componentPanel, id);
167
    }
481
    }
168
482
483
    private void switchToCardSplit(MultiViewElement elem, String id) {
484
	if (!alreadyAddedElementsSplit.contains(elem)) {
485
	    componentPanelSplit.add(elem.getVisualRepresentation(), id);
486
	    alreadyAddedElementsSplit.add(elem);
487
	}
488
	cardLayoutSplit.show(componentPanelSplit, id);
489
    }
490
169
    /** Part of 130919 fix - don't hold visual representations after close */
491
    /** Part of 130919 fix - don't hold visual representations after close */
170
    void peerComponentClosed() {
492
    void peerComponentClosed() {
171
        if (componentPanel != null) {
493
        if (componentPanel != null) {
Lines 174-192 Link Here
174
        if (alreadyAddedElements != null) {
496
        if (alreadyAddedElements != null) {
175
            alreadyAddedElements.clear();
497
            alreadyAddedElements.clear();
176
        }
498
        }
499
        if (componentPanelSplit != null) {
500
            componentPanelSplit.removeAll();
501
        }
502
        if (alreadyAddedElementsSplit != null) {
503
            alreadyAddedElementsSplit.clear();
504
        }
177
    }
505
    }
178
    
506
    
179
    void changeActiveManually(MultiViewDescription desc) {
507
    void changeActiveManually(MultiViewDescription desc) {
180
        Enumeration en = model.getButtonGroup().getElements();
508
        Enumeration en = model.getButtonGroup().getElements();
509
	MultiViewDescription activeDescription = model.getActiveDescription();
510
	if (activeDescription instanceof ContextAwareDescription && ((ContextAwareDescription) activeDescription).isSplitDescription()) {
511
	    en = model.getButtonGroupSplit().getElements();
512
	}
181
        while (en.hasMoreElements()) {
513
        while (en.hasMoreElements()) {
182
            JToggleButton obj = (JToggleButton)en.nextElement();
514
            JToggleButton obj = (JToggleButton)en.nextElement();
183
            
515
            
184
            if (obj.getModel() instanceof TabsComponent.TabsButtonModel) {
516
            if (obj.getModel() instanceof TabsComponent.TabsButtonModel) {
185
                TabsButtonModel btnmodel = (TabsButtonModel)obj.getModel();
517
                TabsButtonModel btnmodel = (TabsButtonModel)obj.getModel();
186
                if (btnmodel.getButtonsDescription().equals(desc)) {
518
                if (btnmodel.getButtonsDescription().getDisplayName().equals(desc.getDisplayName())) {
187
                    obj.setSelected(true);
519
		    if (splitPane != null) {
188
                    MultiViewElement elem = model.getElementForDescription(desc);
520
			TabsComponent.this.hiddenTriggeredByMultiViewButton = true;
189
                    elem.getVisualRepresentation().requestFocus();
521
			if (((ContextAwareDescription) activeDescription).isSplitDescription()) {
522
			    model.getButtonGroupSplit().setSelected(obj.getModel(), true);
523
			    TabsComponent.this.isTopLeft = false;
524
			    TabsComponent.this.topBottomDescriptions[1] = btnmodel.getButtonsDescription();
525
			} else {
526
			    model.getButtonGroup().setSelected(obj.getModel(), true);
527
			    TabsComponent.this.isTopLeft = true;
528
			    TabsComponent.this.topBottomDescriptions[0] = btnmodel.getButtonsDescription();
529
			}
530
			model.fireActivateCurrent();
531
			TabsComponent.this.hiddenTriggeredByMultiViewButton = false;
532
		    } else {
533
			obj.setSelected(true);
534
			MultiViewElement elem = model.getElementForDescription(desc);
535
			elem.getVisualRepresentation().requestFocus();
536
		    }
190
                    break;
537
                    break;
191
                }
538
                }
192
            }
539
            }
Lines 195-200 Link Here
195
542
196
    void changeVisibleManually(MultiViewDescription desc) {
543
    void changeVisibleManually(MultiViewDescription desc) {
197
        Enumeration en = model.getButtonGroup().getElements();
544
        Enumeration en = model.getButtonGroup().getElements();
545
	MultiViewDescription activeDescription = model.getActiveDescription();
546
	if (activeDescription instanceof ContextAwareDescription && ((ContextAwareDescription) activeDescription).isSplitDescription()) {
547
	    en = model.getButtonGroupSplit().getElements();
548
	    desc = model.getActiveDescription();
549
	}
198
        while (en.hasMoreElements()) {
550
        while (en.hasMoreElements()) {
199
            JToggleButton obj = (JToggleButton)en.nextElement();
551
            JToggleButton obj = (JToggleButton)en.nextElement();
200
            
552
            
Lines 232-238 Link Here
232
        return button;
584
        return button;
233
    }
585
    }
234
586
235
    void setInnerToolBar(JComponent innerbar) {
587
    void setInnerToolBar(JComponent innerbar, boolean isSplitElement) {
588
	if (isSplitElement) {
589
	    setInnerToolBarSplit(innerbar);
590
	    return;
591
	}
236
        synchronized (getTreeLock()) {
592
        synchronized (getTreeLock()) {
237
            if (toolbarPanel != null) {
593
            if (toolbarPanel != null) {
238
                bar.remove(toolbarPanel);
594
                bar.remove(toolbarPanel);
Lines 264-269 Link Here
264
            bar.repaint();
620
            bar.repaint();
265
        }
621
        }
266
    }
622
    }
623
624
    private void setInnerToolBarSplit(JComponent innerbar) {
625
        synchronized (getTreeLock()) {
626
            if (toolbarPanelSplit != null) {
627
                barSplit.remove(toolbarPanelSplit);
628
            }
629
            if (innerbar == null) {
630
                innerbar = getEmptyInnerToolBar();
631
            }
632
            innerbar.putClientProperty(TOOLBAR_MARKER, "X"); //NOI18N
633
            // need to set it to null, because CloneableEditor set's the border for the editor bar part only..
634
            if (!AQUA) {
635
                innerbar.setBorder(null);
636
            } else {
637
                innerbar.setBorder (BorderFactory.createEmptyBorder(2, 0, 2, 0));
638
            }
639
            toolbarPanelSplit = innerbar;
640
            GridBagConstraints cons = new GridBagConstraints();
641
            cons.anchor = GridBagConstraints.EAST;
642
            cons.fill = GridBagConstraints.BOTH;
643
            cons.gridwidth = GridBagConstraints.REMAINDER;
644
            cons.weightx = 1;
645
            toolbarPanelSplit.setMinimumSize(new Dimension(10, 10));
646
//            cons.gridwidth = GridBagConstraints.REMAINDER;
647
648
            barSplit.add(toolbarPanelSplit, cons);
649
650
            // rootcycle is the tabscomponent..
651
//            toolbarPanel.setFocusCycleRoot(false);
652
            barSplit.revalidate();
653
            barSplit.repaint();
654
        }
655
    }
267
    
656
    
268
    void setToolbarBarVisible(boolean visible) {
657
    void setToolbarBarVisible(boolean visible) {
269
        if (toolbarVisible == visible) {
658
        if (toolbarVisible == visible) {
Lines 272-277 Link Here
272
        toolbarVisible = visible;
661
        toolbarVisible = visible;
273
        bar.setVisible(visible);
662
        bar.setVisible(visible);
274
    }
663
    }
664
665
    void setToolbarBarVisibleSplit(boolean visible) {
666
        if (toolbarVisible == visible) {
667
            return;
668
        }
669
        toolbarVisible = visible;
670
        barSplit.setVisible(visible);
671
    }
275
    
672
    
276
    
673
    
277
    
674
    
Lines 338-343 Link Here
338
        input.put(stroke, "TogglesGoDown");//NOI18N
735
        input.put(stroke, "TogglesGoDown");//NOI18N
339
    }
736
    }
340
737
738
    void startTogglingSplit() {
739
        ActionMap map = barSplit.getActionMap();
740
        Action act = new TogglesGoEastAction();
741
        // JToolbar action name
742
        map.put("navigateRight", act);//NOI18N
743
        InputMap input = barSplit.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
744
745
        act = new TogglesGoWestAction();
746
        // JToolbar action name
747
        map.put("navigateLeft", act);//NOI18N
748
749
        act = new TogglesGoDownAction();
750
        map.put("TogglesGoDown", act);//NOI18N
751
        // JToolbar action name
752
        map.put("navigateUp", act);//NOI18N
753
        KeyStroke stroke = KeyStroke.getKeyStroke("ESCAPE"); //NOI18N
754
        input.put(stroke, "TogglesGoDown");//NOI18N
755
    }
756
341
    
757
    
342
    private class TogglesGoWestAction extends AbstractAction {
758
    private class TogglesGoWestAction extends AbstractAction {
343
        
759
        
Lines 421-426 Link Here
421
            AbstractButton b = (AbstractButton)e.getComponent();
837
            AbstractButton b = (AbstractButton)e.getComponent();
422
            MultiViewModel model = TabsComponent.this.model;
838
            MultiViewModel model = TabsComponent.this.model;
423
            if (model != null) {
839
            if (model != null) {
840
		if (TabsComponent.this.splitPane != null) {
841
		    ButtonModel buttonModel = b.getModel();
842
		    if (buttonModel instanceof TabsButtonModel) {
843
			MultiViewDescription buttonsDescription = ((TabsButtonModel) buttonModel).getButtonsDescription();
844
			TabsComponent.this.hiddenTriggeredByMultiViewButton = true;
845
			if(((ContextAwareDescription)buttonsDescription).isSplitDescription()) {
846
			    model.getButtonGroupSplit().setSelected(b.getModel(), true);
847
			    TabsComponent.this.isTopLeft = false;
848
			    TabsComponent.this.topBottomDescriptions[1] = buttonsDescription;
849
			} else {
850
			    model.getButtonGroup().setSelected(b.getModel(), true);
851
			    TabsComponent.this.isTopLeft = true;
852
			    TabsComponent.this.topBottomDescriptions[0] = buttonsDescription;
853
			}
854
			model.fireActivateCurrent();
855
			TabsComponent.this.hiddenTriggeredByMultiViewButton = false;
856
		    }
857
		    return;
858
		}
424
                model.getButtonGroup().setSelected(b.getModel(), true);
859
                model.getButtonGroup().setSelected(b.getModel(), true);
425
                model.fireActivateCurrent();
860
                model.fireActivateCurrent();
426
            }
861
            }
(-)a/core.multiview/src/org/netbeans/core/multiview/resources/mf-layer.xml (-1 / +17 lines)
Lines 43-49 Link Here
43
Version 2 license, then the option applies only if the new code is
43
Version 2 license, then the option applies only if the new code is
44
made subject to such option by the copyright holder.
44
made subject to such option by the copyright holder.
45
-->
45
-->
46
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
46
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
47
<filesystem>
47
<filesystem>
48
    <folder name="Menu">
48
    <folder name="Menu">
49
        <folder name="View">
49
        <folder name="View">
Lines 51-57 Link Here
51
                <attr name="position" intvalue="100"/>
51
                <attr name="position" intvalue="100"/>
52
                <attr name="misplaced.action.allowed" boolvalue="true"/>
52
                <attr name="misplaced.action.allowed" boolvalue="true"/>
53
            </file>
53
            </file>
54
            <file name="org-netbeans-core-multiview-SplitAction.instance">
55
                <!--org.netbeans.core.multiview.SplitAction-->
56
                <attr bundlevalue="org.netbeans.core.multiview.Bundle#CTL_SplitAction" name="displayName"/>
57
                <attr name="instanceCreate" methodvalue="org.netbeans.core.multiview.SplitAction.createSplitAction"/>
58
                <attr intvalue="150" name="position"/>
59
            </file>
60
        </folder>
61
        <folder name="Window">
62
            <folder name="ConfigureWindow">
63
		<file name="org-netbeans-core-multiview-SplitAction.instance">
64
		    <!--org.netbeans.core.multiview.SplitAction-->
65
		    <attr bundlevalue="org.netbeans.core.multiview.Bundle#CTL_SplitDocumentAction" name="displayName"/>
66
		    <attr name="instanceCreate" methodvalue="org.netbeans.core.multiview.SplitAction.createSplitAction"/>
67
                    <attr intvalue="950" name="position"/>
68
		</file>
54
            </folder>
69
            </folder>
70
        </folder>
55
    </folder>
71
    </folder>
56
    <!--    folder name="Actions">
72
    <!--    folder name="Actions">
57
        <folder name="Window">
73
        <folder name="Window">
(-)a/core.multiview/src/org/netbeans/core/spi/multiview/MultiViewFactory.java (-5 / +12 lines)
Lines 202-208 Link Here
202
    }
202
    }
203
    
203
    
204
    static MultiViewDescription createMultiViewDescription(Map map) {
204
    static MultiViewDescription createMultiViewDescription(Map map) {
205
        return new MapMVD(map, null);
205
        return new MapMVD(map, null, false);
206
    }
206
    }
207
    
207
    
208
    private static final class Blank implements MultiViewElement, Serializable {
208
    private static final class Blank implements MultiViewElement, Serializable {
Lines 368-376 Link Here
368
    MultiViewDescription, ContextAwareDescription , SourceCheckDescription {
368
    MultiViewDescription, ContextAwareDescription , SourceCheckDescription {
369
        private final Map map;
369
        private final Map map;
370
        private final Lookup context;
370
        private final Lookup context;
371
        public MapMVD(Map map, Lookup context) {
371
	private boolean isSplitDescription;
372
        public MapMVD(Map map, Lookup context, boolean isSplitDescription) {
372
            this.map = map;
373
            this.map = map;
373
            this.context = context;
374
            this.context = context;
375
	    this.isSplitDescription = isSplitDescription;
374
        }
376
        }
375
        
377
        
376
        private <T> T get(String attr, Class<T> type) {
378
        private <T> T get(String attr, Class<T> type) {
Lines 461-473 Link Here
461
        }
463
        }
462
464
463
        @Override
465
        @Override
464
        public ContextAwareDescription createContextAwareDescription(Lookup context) {
466
	public ContextAwareDescription createContextAwareDescription(Lookup context, boolean isSplitDescription) {
465
            return new MapMVD(map, context);
467
	    return new MapMVD(map, context, isSplitDescription);
466
        }
468
	}
467
469
468
        @Override
470
        @Override
469
        public boolean isSourceView() {
471
        public boolean isSourceView() {
470
            return Boolean.TRUE.equals(map.get("sourceview")); // NOI18N
472
            return Boolean.TRUE.equals(map.get("sourceview")); // NOI18N
471
        }
473
        }
474
475
	@Override
476
	public boolean isSplitDescription() {
477
	    return isSplitDescription;
478
	}
472
    }
479
    }
473
}
480
}
(-)a/core.multiview/test/unit/src/org/netbeans/core/multiview/AbstractMultiViewTopComponentTestCase.java (-3 / +4 lines)
Lines 159-167 Link Here
159
        TopComponent result = TopComponent.getRegistry().getActivated();
159
        TopComponent result = TopComponent.getRegistry().getActivated();
160
        Action[] acts = result.getActions();
160
        Action[] acts = result.getActions();
161
        assertNotNull(acts);
161
        assertNotNull(acts);
162
        assertEquals("Three actions: " + Arrays.toString(acts), 3, acts.length);
162
        assertEquals("Four actions: " + Arrays.toString(acts), 4, acts.length);
163
        assertEquals("Second is null", null, acts[1]);
163
        assertEquals("Second is null", null, acts[1]);
164
        assertTrue("Last one instance of tab switching",  acts[2] instanceof EditorsAction);
164
        assertTrue("Second from last one instance of tab switching",  acts[2] instanceof EditorsAction);
165
        assertTrue("Last one instance of spliting",  acts[3] instanceof SplitAction);
165
        Object name = acts[0].getValue(Action.NAME);
166
        Object name = acts[0].getValue(Action.NAME);
166
        assertEquals("act2", name);
167
        assertEquals("act2", name);
167
        
168
        
Lines 171-177 Link Here
171
        hand.requestActive(Accessor.DEFAULT.createPerspective(desc1));
172
        hand.requestActive(Accessor.DEFAULT.createPerspective(desc1));
172
        acts = result.getActions();
173
        acts = result.getActions();
173
        assertNotNull(acts);
174
        assertNotNull(acts);
174
        assertEquals(3, acts.length);
175
        assertEquals(4, acts.length);
175
        name = acts[0].getValue(Action.NAME);
176
        name = acts[0].getValue(Action.NAME);
176
        assertEquals("act1", name);
177
        assertEquals("act1", name);
177
        
178
        
(-)a/core.multiview/test/unit/src/org/netbeans/core/multiview/MultiViewProcessorTest.java (-4 / +57 lines)
Lines 62-67 Link Here
62
import javax.swing.Action;
62
import javax.swing.Action;
63
import javax.swing.JComponent;
63
import javax.swing.JComponent;
64
import javax.swing.JPanel;
64
import javax.swing.JPanel;
65
import javax.swing.JSplitPane;
65
import junit.framework.Test;
66
import junit.framework.Test;
66
import junit.framework.TestSuite;
67
import junit.framework.TestSuite;
67
import org.netbeans.api.editor.mimelookup.MimeLookup;
68
import org.netbeans.api.editor.mimelookup.MimeLookup;
Lines 128-135 Link Here
128
        MultiViewHandler handler = MultiViews.findMultiViewHandler(mvc);
129
        MultiViewHandler handler = MultiViews.findMultiViewHandler(mvc);
129
        assertNotNull("Handler found", handler);
130
        assertNotNull("Handler found", handler);
130
        MultiViewPerspective[] arr = handler.getPerspectives();
131
        MultiViewPerspective[] arr = handler.getPerspectives();
131
        assertEquals("One perspetive found", 1, arr.length);
132
        assertEquals("Two perspetives found", 2, arr.length);
132
        assertEquals("Figaro", arr[0].getDisplayName());
133
        assertEquals("Figaro", arr[0].getDisplayName());
134
        assertEquals("Figaro", arr[1].getDisplayName());
135
	MultiViewDescription description = Accessor.DEFAULT.extractDescription(arr[0]);
136
	assertTrue(description instanceof ContextAwareDescription);
137
        assertFalse("First one is not for split", ((ContextAwareDescription)description).isSplitDescription());
138
	description = Accessor.DEFAULT.extractDescription(arr[1]);
139
	assertTrue(description instanceof ContextAwareDescription);
140
        assertTrue("Second one is for split", ((ContextAwareDescription)description).isSplitDescription());
133
141
134
        CloseH.retValue = true;
142
        CloseH.retValue = true;
135
        MVE.closeState = MultiViewFactory.createUnsafeCloseState("warn", null, null);
143
        MVE.closeState = MultiViewFactory.createUnsafeCloseState("warn", null, null);
Lines 202-209 Link Here
202
        MultiViewHandler handler = MultiViews.findMultiViewHandler(mvc);
210
        MultiViewHandler handler = MultiViews.findMultiViewHandler(mvc);
203
        assertNotNull("Handler found", handler);
211
        assertNotNull("Handler found", handler);
204
        MultiViewPerspective[] arr = handler.getPerspectives();
212
        MultiViewPerspective[] arr = handler.getPerspectives();
205
        assertEquals("One perspetive found", 1, arr.length);
213
        assertEquals("Two perspetives found", 2, arr.length);
206
        assertEquals("Contextual", arr[0].getDisplayName());
214
        assertEquals("Contextual", arr[0].getDisplayName());
215
	assertEquals("Contextual", arr[1].getDisplayName());
216
	MultiViewDescription description = Accessor.DEFAULT.extractDescription(arr[0]);
217
	assertTrue(description instanceof ContextAwareDescription);
218
        assertFalse("First one is not for split", ((ContextAwareDescription)description).isSplitDescription());
219
	description = Accessor.DEFAULT.extractDescription(arr[1]);
220
	assertTrue(description instanceof ContextAwareDescription);
221
        assertTrue("Second one is for split", ((ContextAwareDescription)description).isSplitDescription());
207
222
208
        assertPersistence("Always", TopComponent.PERSISTENCE_ALWAYS, mvc);
223
        assertPersistence("Always", TopComponent.PERSISTENCE_ALWAYS, mvc);
209
        
224
        
Lines 215-220 Link Here
215
        assertNull("No integer now", mvc.getLookup().lookup(Integer.class));
230
        assertNull("No integer now", mvc.getLookup().lookup(Integer.class));
216
        ic.add(1);
231
        ic.add(1);
217
        assertEquals("1 now", Integer.valueOf(1), mvc.getLookup().lookup(Integer.class));
232
        assertEquals("1 now", Integer.valueOf(1), mvc.getLookup().lookup(Integer.class));
233
234
	((MultiViewCloneableTopComponent)mvc).splitComponent(JSplitPane.HORIZONTAL_SPLIT);
235
	handler.requestActive(arr[0]);
236
	ic.remove(1);
237
        assertNull("No integer now", mvc.getLookup().lookup(Integer.class));
238
        ic.add(2);
239
        assertEquals("2 now", Integer.valueOf(2), mvc.getLookup().lookup(Integer.class));
218
    }
240
    }
219
    
241
    
220
    
242
    
Lines 370-377 Link Here
370
        assertNull("No icon yet", tc.getIcon());
392
        assertNull("No icon yet", tc.getIcon());
371
        MultiViewHandler handler = MultiViews.findMultiViewHandler(tc);
393
        MultiViewHandler handler = MultiViews.findMultiViewHandler(tc);
372
        final MultiViewPerspective[] two = handler.getPerspectives();
394
        final MultiViewPerspective[] two = handler.getPerspectives();
373
        assertEquals("One element only" + Arrays.asList(two), 1, handler.getPerspectives().length);
395
        assertEquals("Two elements only" + Arrays.asList(two), 2, handler.getPerspectives().length);
374
        assertEquals("First one is source", "source", two[0].preferredID());
396
        assertEquals("First one is source", "source", two[0].preferredID());
397
	MultiViewDescription description = Accessor.DEFAULT.extractDescription(two[0]);
398
	assertTrue(description instanceof ContextAwareDescription);
399
        assertFalse("First one is not for split", ((ContextAwareDescription)description).isSplitDescription());
400
        assertEquals("Second one is source", "source", two[1].preferredID());
401
	description = Accessor.DEFAULT.extractDescription(two[1]);
402
	assertTrue(description instanceof ContextAwareDescription);
403
        assertTrue("Second one is for split", ((ContextAwareDescription)description).isSplitDescription());
375
        handler.requestVisible(two[0]);
404
        handler.requestVisible(two[0]);
376
        
405
        
377
        
406
        
Lines 393-398 Link Here
393
        ic.remove(img);
422
        ic.remove(img);
394
        assertEquals("Second change in listener", 2, listener.cnt);
423
        assertEquals("Second change in listener", 2, listener.cnt);
395
        assertNull("No icon again", tc.getIcon());
424
        assertNull("No icon again", tc.getIcon());
425
426
	((MultiViewCloneableTopComponent)tc).splitComponent(JSplitPane.HORIZONTAL_SPLIT);
427
	handler.requestVisible(two[1]);
428
        ic.add(img);
429
        assertEquals("Third change in listener", 3, listener.cnt);
430
        assertEquals("Image changed", img, tc.getIcon());
431
432
	ic.remove(img);
433
        assertEquals("Forth change in listener", 4, listener.cnt);
434
        assertNull("No icon again", tc.getIcon());
396
    }
435
    }
397
436
398
    public void testMultiViewsContextCreate() {
437
    public void testMultiViewsContextCreate() {
Lines 404-411 Link Here
404
        MultiViewHandler handler = MultiViews.findMultiViewHandler(mvc);
443
        MultiViewHandler handler = MultiViews.findMultiViewHandler(mvc);
405
        assertNotNull("Handler found", handler);
444
        assertNotNull("Handler found", handler);
406
        MultiViewPerspective[] arr = handler.getPerspectives();
445
        MultiViewPerspective[] arr = handler.getPerspectives();
407
        assertEquals("One perspetive found", 1, arr.length);
446
        assertEquals("Two perspetives found", 2, arr.length);
408
        assertEquals("Contextual", arr[0].getDisplayName());
447
        assertEquals("Contextual", arr[0].getDisplayName());
448
	assertEquals("Contextual", arr[1].getDisplayName());
449
	MultiViewDescription description = Accessor.DEFAULT.extractDescription(arr[0]);
450
	assertTrue(description instanceof ContextAwareDescription);
451
        assertFalse("First one is not for split", ((ContextAwareDescription)description).isSplitDescription());
452
	description = Accessor.DEFAULT.extractDescription(arr[1]);
453
	assertTrue(description instanceof ContextAwareDescription);
454
        assertTrue("Second one is for split", ((ContextAwareDescription)description).isSplitDescription());
409
        
455
        
410
        mvc.open();
456
        mvc.open();
411
        mvc.requestActive();
457
        mvc.requestActive();
Lines 415-420 Link Here
415
        assertNull("No integer now", mvc.getLookup().lookup(Integer.class));
461
        assertNull("No integer now", mvc.getLookup().lookup(Integer.class));
416
        ic.add(1);
462
        ic.add(1);
417
        assertEquals("1 now", Integer.valueOf(1), mvc.getLookup().lookup(Integer.class));
463
        assertEquals("1 now", Integer.valueOf(1), mvc.getLookup().lookup(Integer.class));
464
	
465
	((MultiViewTopComponent)mvc).splitComponent(JSplitPane.HORIZONTAL_SPLIT);
466
	ic.remove(1);
467
	handler.requestActive(arr[1]);
468
        assertNull("No integer now", mvc.getLookup().lookup(Integer.class));
469
        ic.add(2);
470
        assertEquals("2 now", Integer.valueOf(2), mvc.getLookup().lookup(Integer.class));
418
    }
471
    }
419
472
420
    @MimeRegistration(mimeType="text/figaro", service=CloseOperationHandler.class)
473
    @MimeRegistration(mimeType="text/figaro", service=CloseOperationHandler.class)
(-)a/core.multiview/test/unit/src/org/netbeans/core/multiview/ToolbarVisibleTest.java (-5 / +5 lines)
Lines 110-116 Link Here
110
    }
110
    }
111
    
111
    
112
    public void testToolbarIsControlledByEditorSettings() throws Exception {
112
    public void testToolbarIsControlledByEditorSettings() throws Exception {
113
        doToolbarCheck(1);
113
        doToolbarCheck(2);
114
        
114
        
115
    }
115
    }
116
    public void testToolbarIsControlledByEditorSettingsWhenNonEditorSelected() throws Exception {
116
    public void testToolbarIsControlledByEditorSettingsWhenNonEditorSelected() throws Exception {
Lines 126-138 Link Here
126
        
126
        
127
        MultiViewHandler handle = MultiViews.findMultiViewHandler(tc);
127
        MultiViewHandler handle = MultiViews.findMultiViewHandler(tc);
128
        final MultiViewPerspective[] perspectives = handle.getPerspectives();
128
        final MultiViewPerspective[] perspectives = handle.getPerspectives();
129
        assertEquals("Two perspectives", 2, perspectives.length);
129
        assertEquals("Four perspectives", 4, perspectives.length);
130
        handle.requestVisible(perspectives[1]);
130
        handle.requestVisible(perspectives[2]);
131
        
131
        
132
        assertEquals("two toolbars exist", 2, MVE.allToolbars.size());
132
        assertEquals("two toolbars exist", 2, MVE.allToolbars.size());
133
        
133
        
134
        for (int i = 0; i < 2; i++) {
134
        for (int i = 0; i < 2; i++) {
135
            handle.requestVisible(perspectives[i]);
135
            handle.requestVisible(perspectives[i == 0 ? i : i + 1]);
136
            assertVisible("Toolbar is showing(" + i +")", MVE.allToolbars.get(i));
136
            assertVisible("Toolbar is showing(" + i +")", MVE.allToolbars.get(i));
137
        }
137
        }
138
        
138
        
Lines 144-150 Link Here
144
        waiter.waitThree();
144
        waiter.waitThree();
145
        
145
        
146
        for (int i = 0; i < 2; i++) {
146
        for (int i = 0; i < 2; i++) {
147
            handle.requestVisible(perspectives[i]);
147
            handle.requestVisible(perspectives[i == 0 ? i : i + 1]);
148
            assertFalse("No Toolbar is showing anymore", MVE.allToolbars.get(i).isShowing());
148
            assertFalse("No Toolbar is showing anymore", MVE.allToolbars.get(i).isShowing());
149
        }
149
        }
150
    }
150
    }
(-)a/core.multiview/test/unit/src/org/netbeans/core/spi/multiview/text/MultiViewEditorElementTest.java (-1 / +2 lines)
Lines 140-147 Link Here
140
        assertNull("No icon yet", tc.getIcon());
140
        assertNull("No icon yet", tc.getIcon());
141
        MultiViewHandler handler = MultiViews.findMultiViewHandler(tc);
141
        MultiViewHandler handler = MultiViews.findMultiViewHandler(tc);
142
        final MultiViewPerspective[] one = handler.getPerspectives();
142
        final MultiViewPerspective[] one = handler.getPerspectives();
143
        assertEquals("One element only" + Arrays.asList(one), 1, handler.getPerspectives().length);
143
        assertEquals("Two elements only" + Arrays.asList(one), 2, handler.getPerspectives().length);
144
        assertEquals("First one is source", "source", one[0].preferredID());
144
        assertEquals("First one is source", "source", one[0].preferredID());
145
        assertEquals("Second one is also source", "source", one[1].preferredID());
145
        handler.requestVisible(one[0]);
146
        handler.requestVisible(one[0]);
146
        
147
        
147
        List<Lookup.Provider> arr = new ArrayList<Provider>();
148
        List<Lookup.Provider> arr = new ArrayList<Provider>();
(-)a/openide.windows/apichanges.xml (+14 lines)
Lines 50-55 Link Here
50
<apidef name="winsys">Window System API</apidef>
50
<apidef name="winsys">Window System API</apidef>
51
</apidefs>
51
</apidefs>
52
<changes>
52
<changes>
53
<change id="topcomponent.SubComponent_lookup_and_showing">
54
    <api name="winsys"/>
55
    <summary>Added methods getLookup() and isShowing() in TopComponent.SubComponent.</summary>
56
    <version major="6" minor="63"/>
57
    <date day="17" month="4" year="2013"/>
58
    <author login="theofanis"/>
59
    <compatibility addition="yes" source="compatible" semantic="compatible" deprecation="no" deletion="no" modification="no"/>
60
    <description>
61
        <p>The new methods can be used in conjunction with split multiview window, where e.g. the pallette
62
	    needs to know which two of the available subcomponents are showing and query their lookup.</p>
63
    </description>
64
    <class package="org.openide.windows" name="TopComponent"/>
65
    <issue number="228448"/>
66
</change>
53
<change id="stop_request_attention">
67
<change id="stop_request_attention">
54
    <api name="winsys"/>
68
    <api name="winsys"/>
55
    <summary>Allow TopComponent's header to be permanently highlighted to draw user's attention.
69
    <summary>Allow TopComponent's header to be permanently highlighted to draw user's attention.
(-)a/openide.windows/manifest.mf (-1 / +1 lines)
Lines 1-6 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.openide.windows
2
OpenIDE-Module: org.openide.windows
3
OpenIDE-Module-Specification-Version: 6.62
3
OpenIDE-Module-Specification-Version: 6.63
4
OpenIDE-Module-Localizing-Bundle: org/openide/windows/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/openide/windows/Bundle.properties
5
AutoUpdate-Essential-Module: true
5
AutoUpdate-Essential-Module: true
6
6
(-)a/openide.windows/src/org/openide/windows/TopComponent.java (+34 lines)
Lines 1589-1594 Link Here
1589
        private final String description;
1589
        private final String description;
1590
        private final boolean active;
1590
        private final boolean active;
1591
        private final ActionListener activator;
1591
        private final ActionListener activator;
1592
        private final Lookup lookup;
1593
        private final boolean showing;
1592
1594
1593
        /**
1595
        /**
1594
         * C'tor
1596
         * C'tor
Lines 1612-1623 Link Here
1612
         * e.g. multiview sub-tab is selected.
1614
         * e.g. multiview sub-tab is selected.
1613
         */
1615
         */
1614
        public SubComponent( String displayName, String description, ActionListener activator, boolean active ) {
1616
        public SubComponent( String displayName, String description, ActionListener activator, boolean active ) {
1617
            this(displayName, description, activator, active, null, false);
1618
        }
1619
1620
	/**
1621
         * C'tor
1622
         * @param displayName Subcomponent's display name.
1623
         * @param description Short description to show in a tooltip.
1624
         * @param activator ActionListener to invoke when the sub-component needs
1625
         * to be actived.
1626
         * @param active True if the given sub-component is currently active,
1627
         * e.g. multiview sub-tab is selected.
1628
         * @param lookup the lookup of the given sub-component
1629
         * @param showing True if the given sub-component is currently showing,
1630
         * e.g. multiview sub-tab is selected or part of a split.
1631
         */
1632
        public SubComponent( String displayName, String description, ActionListener activator, boolean active, Lookup lookup, boolean showing ) {
1615
            this.displayName = displayName;
1633
            this.displayName = displayName;
1616
            this.description = description;
1634
            this.description = description;
1617
            this.active = active;
1635
            this.active = active;
1618
            this.activator = activator;
1636
            this.activator = activator;
1637
            this.lookup = lookup;
1638
	    this.showing = showing;
1619
        }
1639
        }
1620
1640
1641
	/**
1642
         * @return the lookup of the given sub-component, could be null
1643
         */
1644
        public Lookup getLookup() {
1645
	    return lookup;
1646
	}
1647
1648
	/**
1649
         * @return True if this sub-component is the active/selected one or part of a split.
1650
         */
1651
        public boolean isShowing() {
1652
	    return showing;
1653
	}
1654
1621
        /**
1655
        /**
1622
         * @return True if this sub-component is the active/selected one.
1656
         * @return True if this sub-component is the active/selected one.
1623
         */
1657
         */
(-)a/spi.palette/src/org/netbeans/spi/palette/PaletteSwitch.java (+13 lines)
Lines 185-190 Link Here
185
            return null;
185
            return null;
186
        
186
        
187
        PaletteController pc = (PaletteController)tc.getLookup().lookup( PaletteController.class );
187
        PaletteController pc = (PaletteController)tc.getLookup().lookup( PaletteController.class );
188
	if (pc == null && isOpened) {
189
	    TopComponent.SubComponent[] subComponents = tc.getSubComponents();
190
	    for (int i = 0; i < subComponents.length; i++) {
191
		TopComponent.SubComponent subComponent = subComponents[i];
192
		Lookup subComponentLookup = subComponent.getLookup();
193
		if (subComponentLookup != null) {
194
		    pc = (PaletteController) subComponentLookup.lookup(PaletteController.class);
195
		    if (pc != null && (subComponent.isActive() || subComponent.isShowing())) {
196
			break;
197
		    }
198
		}
199
	    }
200
	}
188
        if( null == pc && isOpened ) {
201
        if( null == pc && isOpened ) {
189
            //check if there's any palette assigned to TopComponent's mime type
202
            //check if there's any palette assigned to TopComponent's mime type
190
            Node[] activeNodes = tc.getActivatedNodes();
203
            Node[] activeNodes = tc.getActivatedNodes();

Return to bug 228448