11/*******************************************************************************
2- * Copyright (c) 2011, 2018 Wind River Systems, Inc. and others. All rights reserved.
2+ * Copyright (c) 2011, 2025 Wind River Systems, Inc. and others. All rights reserved.
33 * This program and the accompanying materials are made available under the terms
44 * of the Eclipse Public License 2.0 which accompanies this distribution, and is
55 * available at https://www.eclipse.org/legal/epl-2.0/
99 * Contributors:
1010 * Wind River Systems - initial API and implementation
1111 * Max Weninger (Wind River) - [361363] [TERMINALS] Implement "Pin&Clone" for the "Terminals" view
12+ * Alexander Fedorov (ArSysOp) - further evolution
1213 *******************************************************************************/
1314package org .eclipse .terminal .view .ui .internal ;
1415
1516import java .util .ArrayList ;
1617import java .util .Arrays ;
17- import java .util .HashMap ;
1818import java .util .List ;
1919import java .util .Map ;
2020import java .util .Objects ;
3333import org .eclipse .terminal .view .core .ITerminalsConnectorConstants ;
3434import org .eclipse .terminal .view .ui .IPreferenceKeys ;
3535import org .eclipse .terminal .view .ui .ITerminalsView ;
36- import org .eclipse .terminal .view .ui .IUIConstants ;
3736import org .eclipse .terminal .view .ui .internal .tabs .TabFolderManager ;
3837import org .eclipse .terminal .view .ui .internal .view .TerminalsView ;
3938import org .eclipse .terminal .view .ui .launcher .ITerminalConsoleViewManager ;
39+ import org .eclipse .terminal .view .ui .launcher .TerminalViewId ;
4040import org .eclipse .ui .IPartListener2 ;
4141import org .eclipse .ui .IPartService ;
4242import org .eclipse .ui .IPerspectiveDescriptor ;
@@ -181,7 +181,7 @@ private final IWorkbenchPage getActiveWorkbenchPage() {
181181 }
182182
183183 @ Override
184- public Optional <ITerminalsView > findConsoleView (String id , String secondaryId ) {
184+ public Optional <ITerminalsView > findConsoleView (TerminalViewId tvid ) {
185185 Assert .isNotNull (Display .findDisplay (Thread .currentThread ()));
186186
187187 ITerminalsView view = null ;
@@ -190,7 +190,7 @@ public Optional<ITerminalsView> findConsoleView(String id, String secondaryId) {
190190 IWorkbenchPage page = getActiveWorkbenchPage ();
191191 if (page != null ) {
192192 // Look for the view
193- IViewPart part = getTerminalsViewWithSecondaryId (id != null ? id : IUIConstants . ID , secondaryId , true );
193+ IViewPart part = getTerminalsViewWithSecondaryId (tvid , true );
194194 // Check the interface
195195 if (part instanceof ITerminalsView ) {
196196 view = (ITerminalsView ) part ;
@@ -203,20 +203,17 @@ public Optional<ITerminalsView> findConsoleView(String id, String secondaryId) {
203203 /**
204204 * Search and return a terminal view with a specific secondary id
205205 *
206- * @param id The terminals console view id. Must not be <code>null</code>.
207- * @param secondaryId The terminal console secondary id, which may be <code>null</code> which is the secondary id of
208- * the first terminal view opened. To specify reuse of any active terminal view use special value of
209- * {@link ITerminalsConnectorConstants#ANY_ACTIVE_SECONDARY_ID}.
206+ * @param tvid The terminals console view id. To specify reuse of most recent terminal view use special value of
207+ * {@link ITerminalsConnectorConstants#LAST_ACTIVE_SECONDARY_ID} for its secondary part.
210208 * @param restore <code>True</code> if to try to restore the view, <code>false</code> otherwise.
211209 *
212210 * @return The terminals console view instance or <code>null</code> if not found.
213211 */
214- private IViewPart getTerminalsViewWithSecondaryId (String id , String secondaryId , boolean restore ) {
215- Assert .isNotNull (id );
216-
212+ private IViewPart getTerminalsViewWithSecondaryId (TerminalViewId tvid , boolean restore ) {
217213 for (IViewReference ref : getActiveWorkbenchPage ().getViewReferences ()) {
218- if (ref .getId ().equals (id )) {
214+ if (ref .getId ().equals (tvid . primary () )) {
219215 String refSecondaryId = ref .getSecondaryId ();
216+ String secondaryId = tvid .secondary ().orElse (null );
220217 if (ITerminalsConnectorConstants .ANY_ACTIVE_SECONDARY_ID .equals (secondaryId )
221218 || Objects .equals (secondaryId , refSecondaryId )) {
222219 return ref .getView (restore );
@@ -229,21 +226,20 @@ private IViewPart getTerminalsViewWithSecondaryId(String id, String secondaryId,
229226 /**
230227 * Search and return the active terminals view.
231228 *
232- * @param id The terminals console view id. Must not be <code>null</code>.
233- * @param secondaryId The terminal console secondary id, which may be <code>null</code> which is the secondary id of
234- * the first terminal view opened. To specify reuse of most recent terminal view use special value of
235- * {@link ITerminalsConnectorConstants#LAST_ACTIVE_SECONDARY_ID}.
229+ * @param tvid The terminals console view id. To specify reuse of most recent terminal view use special value of
230+ * {@link ITerminalsConnectorConstants#LAST_ACTIVE_SECONDARY_ID} for its secondary part.
236231 * @return The terminals console view instance or <code>null</code> if not found.
237232 */
238- private IViewPart getActiveTerminalsView (String id , String secondaryId ) {
239- Assert .isNotNull (id );
240-
233+ private IViewPart getActiveTerminalsView (TerminalViewId tvid ) {
241234 IViewPart part = null ;
235+ String id = tvid .primary ();
242236
237+ String secondaryId = tvid .secondary ().orElse (null );
243238 if (id .equals (lastActiveViewId )) {
244239 if (ITerminalsConnectorConstants .LAST_ACTIVE_SECONDARY_ID .equals (secondaryId )
245240 || Objects .equals (secondaryId , lastActiveSecondaryViewId )) {
246- part = getTerminalsViewWithSecondaryId (lastActiveViewId , lastActiveSecondaryViewId , false );
241+ part = getTerminalsViewWithSecondaryId (new TerminalViewId (lastActiveViewId , lastActiveSecondaryViewId ),
242+ false );
247243 }
248244 }
249245
@@ -255,7 +251,7 @@ private IViewPart getActiveTerminalsView(String id, String secondaryId) {
255251 } else {
256252 finalSecondaryId = secondaryId ;
257253 }
258- part = getTerminalsViewWithSecondaryId (id , finalSecondaryId , true );
254+ part = getTerminalsViewWithSecondaryId (new TerminalViewId ( id , finalSecondaryId ) , true );
259255 if (part != null ) {
260256 lastActiveViewId = part .getViewSite ().getId ();
261257 lastActiveSecondaryViewId = part .getViewSite ().getSecondaryId ();
@@ -265,71 +261,25 @@ private IViewPart getActiveTerminalsView(String id, String secondaryId) {
265261 return part ;
266262 }
267263
268- /**
269- * Return a new secondary id to use, based on the number of open terminal views.
270- *
271- * @param id The terminals console view id. Must not be <code>null</code>.
272- * @return The next secondary id, or <code>null</code> if it is the first one
273- * @since 4.1
274- */
275- @ Override
276- public String getNextTerminalSecondaryId (String id ) {
277- Assert .isNotNull (id );
278-
279- Map <String , IViewReference > terminalViews = new HashMap <>();
280-
281- int maxNumber = 0 ;
282- for (IViewReference ref : getActiveWorkbenchPage ().getViewReferences ()) {
283- if (ref .getId ().equals (id )) {
284- if (ref .getSecondaryId () != null ) {
285- terminalViews .put (ref .getSecondaryId (), ref );
286- int scondaryIdInt = Integer .parseInt (ref .getSecondaryId ());
287- if (scondaryIdInt > maxNumber ) {
288- maxNumber = scondaryIdInt ;
289- }
290- } else {
291- // add the one with secondaryId == null with 0 by default
292- terminalViews .put (Integer .toString (0 ), ref );
293- }
294- }
295- }
296- if (terminalViews .size () == 0 ) {
297- return null ;
298- }
299-
300- int i = 0 ;
301- for (; i < maxNumber ; i ++) {
302- String secondaryIdStr = Integer .toString (i );
303- if (!terminalViews .keySet ().contains (secondaryIdStr )) {
304- // found a free slot
305- if (i == 0 ) {
306- return null ;
307- }
308- return Integer .toString (i );
309- }
310- }
311- // add a new one
312- return Integer .toString (i + 1 );
313- }
314-
315264 /**
316265 * Show the terminals console view specified by the given id.
317266 * <p>
318267 * <b>Note:</b> The method must be called within the UI thread.
319268 *
320- * @param id The terminals console view id or <code>null</code> to show the default terminals console view .
269+ * @param id The terminals console view id.
321270 */
322271 @ Override
323- public IViewPart showConsoleView (String id , String secondaryId ) {
272+ public IViewPart showConsoleView (TerminalViewId tvid ) {
324273 Assert .isNotNull (Display .findDisplay (Thread .currentThread ()));
325274
326275 // Get the active workbench page
327276 IWorkbenchPage page = getActiveWorkbenchPage ();
328277 if (page != null ) {
329278 try {
330279 // show the view
331- IViewPart part = getActiveTerminalsView (id != null ? id : IUIConstants . ID , secondaryId );
280+ IViewPart part = getActiveTerminalsView (tvid );
332281 if (part == null ) {
282+ String secondaryId = tvid .secondary ().orElse (null );
333283 String finalSecondaryId ;
334284 if (ITerminalsConnectorConstants .LAST_ACTIVE_SECONDARY_ID .equals (secondaryId )
335285 || ITerminalsConnectorConstants .ANY_ACTIVE_SECONDARY_ID .equals (secondaryId )) {
@@ -339,8 +289,7 @@ public IViewPart showConsoleView(String id, String secondaryId) {
339289 } else {
340290 finalSecondaryId = secondaryId ;
341291 }
342- part = page .showView (id != null ? id : IUIConstants .ID , finalSecondaryId ,
343- IWorkbenchPage .VIEW_ACTIVATE );
292+ part = page .showView (tvid .primary (), finalSecondaryId , IWorkbenchPage .VIEW_ACTIVATE );
344293 }
345294 // and force the view to the foreground
346295 page .bringToTop (part );
@@ -356,20 +305,20 @@ public IViewPart showConsoleView(String id, String secondaryId) {
356305 /**
357306 * Bring the terminals console view, specified by the given id, to the top of the view stack.
358307 *
359- * @param id The terminals console view id or <code>null</code> to show the default terminals console view .
308+ * @param tvid The terminals console view id.
360309 * @param secondaryId The terminals console view secondary id or <code>null</code>.
361310 * @param activate If <code>true</code> activate the console view.
362311 */
363- private IViewPart bringToTop (String id , String secondaryId , boolean activate ) {
312+ private IViewPart bringToTop (TerminalViewId tvid , boolean activate ) {
364313 // Get the active workbench page
365314 IWorkbenchPage page = getActiveWorkbenchPage ();
366315 if (page != null ) {
367316 // get (last) active terminal view
368- IViewPart activePart = getActiveTerminalsView (id != null ? id : IUIConstants . ID , secondaryId );
317+ IViewPart activePart = getActiveTerminalsView (tvid );
369318 if (activePart == null ) {
370319 // Create a new one
371- IViewPart newPart = showConsoleView (id != null ? id : IUIConstants . ID ,
372- getNextTerminalSecondaryId ( IUIConstants . ID ));
320+ IViewPart newPart = showConsoleView (
321+ new TerminalViewId ( tvid . primary (), new TerminalViewId (). next (). secondary () ));
373322 return newPart ;
374323 }
375324
@@ -389,19 +338,17 @@ private IViewPart bringToTop(String id, String secondaryId, boolean activate) {
389338 * <p>
390339 * <b>Note:</b> The method must be called within the UI thread.
391340 *
392- * @param id The terminals console view id or <code>null</code> to show the default terminals console view.
393- * @param secondaryId The terminal console secondary id, which may be <code>null</code> which is the secondary id of
394- * the first terminal view opened. To specify reuse of most recent terminal view use special value of
395- * {@link ITerminalsConnectorConstants#LAST_ACTIVE_SECONDARY_ID}.
341+ * @param tvid The terminals console view id. To specify reuse of most recent terminal view use special value of
342+ * {@link ITerminalsConnectorConstants#LAST_ACTIVE_SECONDARY_ID} for its secondary part.
396343 * @param title The console title. Must not be <code>null</code>.
397344 * @param encoding The terminal encoding or <code>null</code>.
398345 * @param connector The terminal connector. Must not be <code>null</code>.
399346 * @param data The custom terminal data node or <code>null</code>.
400347 * @param flags The flags controlling how the console is opened or <code>null</code> to use defaults.
401348 */
402349 @ Override
403- public CTabItem openConsole (String id , String secondaryId , String title , String encoding ,
404- ITerminalConnector connector , Object data , Map <String , Boolean > flags ) {
350+ public CTabItem openConsole (TerminalViewId tvid , String title , String encoding , ITerminalConnector connector ,
351+ Object data , Map <String , Boolean > flags ) {
405352 Assert .isNotNull (title );
406353 Assert .isNotNull (connector );
407354 Assert .isNotNull (Display .findDisplay (Thread .currentThread ()));
@@ -414,7 +361,7 @@ public CTabItem openConsole(String id, String secondaryId, String title, String
414361 : false ;
415362
416363 // Make the consoles view visible
417- IViewPart part = bringToTop (id , secondaryId , activate );
364+ IViewPart part = bringToTop (tvid , activate );
418365 if (!(part instanceof ITerminalsView view )) {
419366 return null ;
420367 }
@@ -427,7 +374,8 @@ public CTabItem openConsole(String id, String secondaryId, String title, String
427374
428375 // Lookup an existing console first
429376 String secId = ((IViewSite ) part .getSite ()).getSecondaryId ();
430- CTabItem item = (CTabItem ) findConsole (id , secId , title , connector , data ).orElse (null );
377+ CTabItem item = (CTabItem ) findConsole (new TerminalViewId (tvid .primary (), secId ), title , connector , data )
378+ .orElse (null );
431379
432380 // Switch to the tab folder page _before_ calling TabFolderManager#createItem(...).
433381 // The createItem(...) method invokes the corresponding connect and this may take
@@ -472,23 +420,21 @@ public CTabItem openConsole(String id, String secondaryId, String title, String
472420 * <b>Note:</b> The method must be called within the UI thread.
473421 * <b>Note:</b> The method will handle unified console titles itself.
474422 *
475- * @param id The terminals console view id or <code>null</code> to show the default terminals console view.
476- * @param secondaryId The terminals console view secondary id or <code>null</code>.
423+ * @param tvid The terminals console view id.
477424 * @param title The console title. Must not be <code>null</code>.
478425 * @param connector The terminal connector. Must not be <code>null</code>.
479426 * @param data The custom terminal data node or <code>null</code>.
480427 *
481428 * @return The corresponding console tab item or <code>null</code>.
482429 */
483430 @ Override
484- public Optional <Widget > findConsole (String id , String secondaryId , String title , ITerminalConnector connector ,
485- Object data ) {
431+ public Optional <Widget > findConsole (TerminalViewId tvid , String title , ITerminalConnector connector , Object data ) {
486432 Assert .isNotNull (title );
487433 Assert .isNotNull (connector );
488434 Assert .isNotNull (Display .findDisplay (Thread .currentThread ()));
489435
490436 // Get the console view
491- ITerminalsView view = findConsoleView (id , secondaryId ).orElse (null );
437+ ITerminalsView view = findConsoleView (tvid ).orElse (null );
492438 if (view == null ) {
493439 return Optional .empty ();
494440 }
@@ -548,14 +494,14 @@ public Optional<Widget> findConsole(ITerminalControl control) {
548494 * <p>
549495 * <b>Note:</b> The method will handle unified console titles itself.
550496 *
551- * @param id The terminals console view id or <code>null</code> to show the default terminals console view .
497+ * @param tvid The terminals console view id.
552498 * @param title The console title. Must not be <code>null</code>.
553499 * @param connector The terminal connector. Must not be <code>null</code>.
554500 * @param data The custom terminal data node or <code>null</code>.
555501 *
556502 * @return The corresponding console tab item or <code>null</code>.
557503 */
558- private CTabItem findConsoleForTerminalConnector (String id , String title , ITerminalConnector connector ,
504+ private CTabItem findConsoleForTerminalConnector (TerminalViewId tvid , String title , ITerminalConnector connector ,
559505 Object data ) {
560506 Assert .isNotNull (title );
561507 Assert .isNotNull (connector );
@@ -564,7 +510,7 @@ private CTabItem findConsoleForTerminalConnector(String id, String title, ITermi
564510 if (page != null ) {
565511 IViewReference [] refs = page .getViewReferences ();
566512 for (IViewReference ref : refs ) {
567- if (ref .getId ().equals (id )) {
513+ if (ref .getId ().equals (tvid . primary () )) {
568514 IViewPart part = ref .getView (true );
569515 if (part instanceof ITerminalsView ) {
570516 // Get the tab folder manager associated with the view
@@ -589,18 +535,19 @@ private CTabItem findConsoleForTerminalConnector(String id, String title, ITermi
589535 * <b>Note:</b> The method must be called within the UI thread.
590536 * <b>Note:</b> The method will handle unified console titles itself.
591537 *
538+ * @param tvid The terminals console view id.
592539 * @param title The console title. Must not be <code>null</code>.
593540 * @param connector The terminal connector. Must not be <code>null</code>.
594541 * @param data The custom terminal data node or <code>null</code>.
595542 */
596543 @ Override
597- public void closeConsole (String id , String title , ITerminalConnector connector , Object data ) {
544+ public void closeConsole (TerminalViewId tvid , String title , ITerminalConnector connector , Object data ) {
598545 Assert .isNotNull (title );
599546 Assert .isNotNull (connector );
600547 Assert .isNotNull (Display .findDisplay (Thread .currentThread ()));
601548
602549 // Lookup the console with this connector
603- CTabItem console = findConsoleForTerminalConnector (id , title , connector , data );
550+ CTabItem console = findConsoleForTerminalConnector (tvid , title , connector , data );
604551 // If found, dispose the console
605552 if (console != null ) {
606553 console .dispose ();
@@ -613,18 +560,19 @@ public void closeConsole(String id, String title, ITerminalConnector connector,
613560 * <b>Note:</b> The method must be called within the UI thread.
614561 * <b>Note:</b> The method will handle unified console titles itself.
615562 *
563+ * @param tvid The terminals console view id.
616564 * @param title The console title. Must not be <code>null</code>.
617565 * @param connector The terminal connector. Must not be <code>null</code>.
618566 * @param data The custom terminal data node or <code>null</code>.
619567 */
620568 @ Override
621- public void terminateConsole (String id , String title , ITerminalConnector connector , Object data ) {
569+ public void terminateConsole (TerminalViewId tvid , String title , ITerminalConnector connector , Object data ) {
622570 Assert .isNotNull (title );
623571 Assert .isNotNull (connector );
624572 Assert .isNotNull (Display .findDisplay (Thread .currentThread ()));
625573
626574 // Lookup the console
627- CTabItem console = findConsoleForTerminalConnector (id , title , connector , data );
575+ CTabItem console = findConsoleForTerminalConnector (tvid , title , connector , data );
628576 // If found, disconnect the console
629577 if (console != null && !console .isDisposed ()) {
630578 ITerminalViewControl terminal = (ITerminalViewControl ) console .getData ();
0 commit comments