00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ViewManager.h"
00022
00023
00024 #include <assert.h>
00025
00026
00027 #include <QtCore/QDateTime>
00028 #include <QtCore/QSignalMapper>
00029 #include <QtGui/QMenu>
00030
00031
00032 #include <kdebug.h>
00033 #include <KAcceleratorManager>
00034 #include <KGlobal>
00035 #include <KLocale>
00036 #include <KToggleAction>
00037 #include <KXMLGUIFactory>
00038
00039
00040 #include "ColorScheme.h"
00041 #include "ProfileList.h"
00042 #include "Session.h"
00043 #include "TerminalDisplay.h"
00044 #include "SessionController.h"
00045 #include "SessionManager.h"
00046 #include "ViewContainer.h"
00047 #include "ViewSplitter.h"
00048
00049 using namespace Konsole;
00050
00051 ViewManager::ViewManager(QObject* parent , KActionCollection* collection)
00052 : QObject(parent)
00053 , _viewSplitter(0)
00054 , _actionCollection(collection)
00055 , _containerSignalMapper(new QSignalMapper(this))
00056 , _navigationMethod(TabbedNavigation)
00057 , _newViewMenu(0)
00058 {
00059
00060 _viewSplitter = new ViewSplitter(0);
00061 KAcceleratorManager::setNoAccel(_viewSplitter);
00062
00063
00064
00065
00066
00067
00068
00069 _viewSplitter->setRecursiveSplitting(false);
00070 _viewSplitter->setFocusPolicy(Qt::NoFocus);
00071
00072
00073 setupActions();
00074
00075
00076 connect( _viewSplitter , SIGNAL(allContainersEmpty()) , this , SIGNAL(empty()) );
00077 connect( _viewSplitter , SIGNAL(empty(ViewSplitter*)) , this , SIGNAL(empty()) );
00078
00079
00080 connect( _containerSignalMapper , SIGNAL(mapped(QObject*)) , this ,
00081 SLOT(containerViewsChanged(QObject*)) );
00082
00083
00084 connect( SessionManager::instance() , SIGNAL(profileChanged(Profile::Ptr)) , this,
00085 SLOT(profileChanged(Profile::Ptr)) );
00086 connect( SessionManager::instance() , SIGNAL(sessionUpdated(Session*)) , this,
00087 SLOT(updateViewsForSession(Session*)) );
00088 }
00089
00090 ViewManager::~ViewManager()
00091 {
00092 delete _newViewMenu;
00093 }
00094 QMenu* ViewManager::createNewViewMenu()
00095 {
00096 if (_newViewMenu)
00097 return _newViewMenu;
00098
00099 _newViewMenu = new QMenu(0);
00100 ProfileList* newViewProfiles = new ProfileList(false,_newViewMenu);
00101 newViewProfiles->syncWidgetActions(_newViewMenu,true);
00102 connect(newViewProfiles,SIGNAL(profileSelected(Profile::Ptr)),this,
00103 SIGNAL(newViewRequest(Profile::Ptr)));
00104
00105 return _newViewMenu;
00106 }
00107 QWidget* ViewManager::activeView() const
00108 {
00109 ViewContainer* container = _viewSplitter->activeContainer();
00110 if ( container )
00111 {
00112 return container->activeView();
00113 }
00114 else
00115 {
00116 return 0;
00117 }
00118 }
00119
00120 QWidget* ViewManager::widget() const
00121 {
00122 return _viewSplitter;
00123 }
00124
00125 void ViewManager::setupActions()
00126 {
00127 KActionCollection* collection = _actionCollection;
00128
00129 KAction* nextViewAction = new KAction( i18n("Next View") , this );
00130 KAction* previousViewAction = new KAction( i18n("Previous View") , this );
00131 KAction* nextContainerAction = new KAction( i18n("Next View Container") , this);
00132
00133 KAction* moveViewLeftAction = new KAction( i18n("Move View Left") , this );
00134 KAction* moveViewRightAction = new KAction( i18n("Move View Right") , this );
00135
00136
00137
00138 QList<QAction*> multiViewOnlyActions;
00139 multiViewOnlyActions << nextContainerAction;
00140
00141 if ( collection )
00142 {
00143 KAction* splitLeftRightAction = new KAction( KIcon("view-split-left-right"),
00144 i18nc("@action:inmenu", "Split View Left/Right"),
00145 this );
00146 splitLeftRightAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_L) );
00147 collection->addAction("split-view-left-right",splitLeftRightAction);
00148 connect( splitLeftRightAction , SIGNAL(triggered()) , this , SLOT(splitLeftRight()) );
00149
00150 KAction* splitTopBottomAction = new KAction( KIcon("view-split-top-bottom") ,
00151 i18nc("@action:inmenu", "Split View Top/Bottom"),this);
00152 splitTopBottomAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_T) );
00153 collection->addAction("split-view-top-bottom",splitTopBottomAction);
00154 connect( splitTopBottomAction , SIGNAL(triggered()) , this , SLOT(splitTopBottom()));
00155
00156 KAction* closeActiveAction = new KAction( i18nc("@action:inmenu Close Active View", "Close Active") , this );
00157 closeActiveAction->setIcon(KIcon("view-close"));
00158 closeActiveAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_S) );
00159 closeActiveAction->setEnabled(false);
00160 collection->addAction("close-active-view",closeActiveAction);
00161 connect( closeActiveAction , SIGNAL(triggered()) , this , SLOT(closeActiveView()) );
00162
00163 multiViewOnlyActions << closeActiveAction;
00164
00165 KAction* closeOtherAction = new KAction( i18nc("@action:inmenu Close Other Views", "Close Others") , this );
00166 closeOtherAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_O) );
00167 closeOtherAction->setEnabled(false);
00168 collection->addAction("close-other-views",closeOtherAction);
00169 connect( closeOtherAction , SIGNAL(triggered()) , this , SLOT(closeOtherViews()) );
00170
00171 multiViewOnlyActions << closeOtherAction;
00172
00173 KAction* detachViewAction = collection->addAction("detach-view");
00174 detachViewAction->setIcon( KIcon("tab-detach") );
00175 detachViewAction->setText( i18n("&Detach View") );
00176
00177
00178 detachViewAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_H) );
00179
00180 connect( this , SIGNAL(splitViewToggle(bool)) , this , SLOT(updateDetachViewState()) );
00181 connect( detachViewAction , SIGNAL(triggered()) , this , SLOT(detachActiveView()) );
00182
00183
00184 KAction* expandActiveAction = new KAction( i18nc("@action:inmenu", "Expand View") , this );
00185 expandActiveAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_BracketRight) );
00186 collection->addAction("expand-active-view",expandActiveAction);
00187 connect( expandActiveAction , SIGNAL(triggered()) , this , SLOT(expandActiveView()) );
00188
00189 multiViewOnlyActions << expandActiveAction;
00190
00191 KAction* shrinkActiveAction = new KAction( i18nc("@action:inmenu", "Shrink View") , this );
00192 shrinkActiveAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_BracketLeft) );
00193 collection->addAction("shrink-active-view",shrinkActiveAction);
00194 connect( shrinkActiveAction , SIGNAL(triggered()) , this , SLOT(shrinkActiveView()) );
00195
00196 multiViewOnlyActions << shrinkActiveAction;
00197
00198
00199 collection->addAction("next-view",nextViewAction);
00200 collection->addAction("previous-view",previousViewAction);
00201 collection->addAction("next-container",nextContainerAction);
00202 collection->addAction("move-view-left",moveViewLeftAction);
00203 collection->addAction("move-view-right",moveViewRightAction);
00204
00205
00206 const int SWITCH_TO_TAB_COUNT = 10;
00207 QSignalMapper* switchToTabMapper = new QSignalMapper(this);
00208 connect(switchToTabMapper,SIGNAL(mapped(int)),this,SLOT(switchToView(int)));
00209 for (int i=0;i < SWITCH_TO_TAB_COUNT;i++)
00210 {
00211 KAction* switchToTabAction = new KAction(i18n("Switch to Tab %1",i+1),this);
00212 switchToTabMapper->setMapping(switchToTabAction,i);
00213 connect(switchToTabAction,SIGNAL(triggered()),switchToTabMapper,
00214 SLOT(map()));
00215 collection->addAction(QString("switch-to-tab-%1").arg(i),switchToTabAction);
00216 }
00217 }
00218
00219 QListIterator<QAction*> iter(multiViewOnlyActions);
00220 while ( iter.hasNext() )
00221 {
00222 connect( this , SIGNAL(splitViewToggle(bool)) , iter.next() , SLOT(setEnabled(bool)) );
00223 }
00224
00225
00226 KShortcut nextViewShortcut = nextViewAction->shortcut();
00227 nextViewShortcut.setPrimary( QKeySequence(Qt::SHIFT+Qt::Key_Right) );
00228 nextViewShortcut.setAlternate( QKeySequence(Qt::CTRL+Qt::Key_PageUp) );
00229 nextViewAction->setShortcut(nextViewShortcut);
00230 connect( nextViewAction, SIGNAL(triggered()) , this , SLOT(nextView()) );
00231 _viewSplitter->addAction(nextViewAction);
00232
00233 KShortcut previousViewShortcut = previousViewAction->shortcut();
00234 previousViewShortcut.setPrimary( QKeySequence(Qt::SHIFT+Qt::Key_Left) );
00235 previousViewShortcut.setAlternate( QKeySequence(Qt::CTRL+Qt::Key_PageDown) );
00236 previousViewAction->setShortcut(previousViewShortcut);
00237 connect( previousViewAction, SIGNAL(triggered()) , this , SLOT(previousView()) );
00238 _viewSplitter->addAction(previousViewAction);
00239
00240 nextContainerAction->setShortcut( QKeySequence(Qt::SHIFT+Qt::Key_Tab) );
00241 connect( nextContainerAction , SIGNAL(triggered()) , this , SLOT(nextContainer()) );
00242 _viewSplitter->addAction(nextContainerAction);
00243
00244 moveViewLeftAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_Left) );
00245 connect( moveViewLeftAction , SIGNAL(triggered()) , this , SLOT(moveActiveViewLeft()) );
00246 _viewSplitter->addAction(moveViewLeftAction);
00247 moveViewRightAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_Right) );
00248 connect( moveViewRightAction , SIGNAL(triggered()) , this , SLOT(moveActiveViewRight()) );
00249 _viewSplitter->addAction(moveViewRightAction);
00250 }
00251 void ViewManager::switchToView(int index)
00252 {
00253 Q_ASSERT(index >= 0);
00254 ViewContainer* container = _viewSplitter->activeContainer();
00255 Q_ASSERT( container );
00256 QList<QWidget*> containerViews = container->views();
00257 if (index >= containerViews.count())
00258 return;
00259 container->setActiveView(containerViews.at(index));
00260 }
00261 void ViewManager::updateDetachViewState()
00262 {
00263 if (!_actionCollection)
00264 return;
00265
00266
00267 bool splitView = _viewSplitter->containers().count() >= 2;
00268 bool shouldEnable = splitView || _viewSplitter->activeContainer()->views().count() >= 2;
00269
00270 QAction* detachAction = _actionCollection->action("detach-view");
00271
00272 if ( detachAction && shouldEnable != detachAction->isEnabled() )
00273 detachAction->setEnabled(shouldEnable);
00274 }
00275 void ViewManager::moveActiveViewLeft()
00276 {
00277 ViewContainer* container = _viewSplitter->activeContainer();
00278 Q_ASSERT( container );
00279 container->moveActiveView( ViewContainer::MoveViewLeft );
00280 }
00281 void ViewManager::moveActiveViewRight()
00282 {
00283 ViewContainer* container = _viewSplitter->activeContainer();
00284 Q_ASSERT( container );
00285 container->moveActiveView( ViewContainer::MoveViewRight );
00286 }
00287 void ViewManager::nextContainer()
00288 {
00289 _viewSplitter->activateNextContainer();
00290 }
00291
00292 void ViewManager::nextView()
00293 {
00294 ViewContainer* container = _viewSplitter->activeContainer();
00295
00296 Q_ASSERT( container );
00297
00298 container->activateNextView();
00299 }
00300
00301 void ViewManager::previousView()
00302 {
00303 ViewContainer* container = _viewSplitter->activeContainer();
00304
00305 Q_ASSERT( container );
00306
00307 container->activatePreviousView();
00308 }
00309 void ViewManager::detachActiveView()
00310 {
00311
00312 ViewContainer* container = _viewSplitter->activeContainer();
00313 TerminalDisplay* activeView = dynamic_cast<TerminalDisplay*>(container->activeView());
00314
00315 if (!activeView)
00316 return;
00317
00318 emit viewDetached(_sessionMap[activeView]);
00319
00320 _sessionMap.remove(activeView);
00321
00322
00323 container->removeView(activeView);
00324 activeView->deleteLater();
00325
00326
00327
00328
00329 if ( _viewSplitter->containers().count() > 1 &&
00330 container->views().count() == 0 )
00331 {
00332 removeContainer(container);
00333 }
00334
00335 }
00336
00337 void ViewManager::sessionFinished()
00338 {
00339
00340
00341 if (!_viewSplitter)
00342 return;
00343
00344 Session* session = qobject_cast<Session*>(sender());
00345
00346 if ( _sessionMap[qobject_cast<TerminalDisplay*>(activeView())] == session )
00347 {
00348
00349
00350
00351 previousView();
00352 }
00353
00354 Q_ASSERT(session);
00355
00356
00357 QList<TerminalDisplay*> children = _viewSplitter->findChildren<TerminalDisplay*>();
00358
00359 foreach ( TerminalDisplay* view , children )
00360 {
00361 if ( _sessionMap[view] == session )
00362 {
00363 _sessionMap.remove(view);
00364 view->deleteLater();
00365 }
00366 }
00367
00368 }
00369
00370 void ViewManager::focusActiveView()
00371 {
00372
00373
00374
00375
00376
00377
00378 ViewContainer* container = _viewSplitter->activeContainer();
00379 if ( container )
00380 {
00381 QWidget* activeView = container->activeView();
00382 if ( activeView )
00383 {
00384 activeView->setFocus(Qt::MouseFocusReason);
00385 }
00386 }
00387 }
00388
00389
00390 void ViewManager::viewActivated( QWidget* view )
00391 {
00392 Q_ASSERT( view != 0 );
00393
00394
00395
00396
00397 view->setFocus(Qt::OtherFocusReason);
00398 }
00399
00400 void ViewManager::splitLeftRight()
00401 {
00402 splitView(Qt::Horizontal);
00403 }
00404 void ViewManager::splitTopBottom()
00405 {
00406 splitView(Qt::Vertical);
00407 }
00408
00409 void ViewManager::splitView(Qt::Orientation orientation)
00410 {
00411
00412
00413 QListIterator<QWidget*> existingViewIter(_viewSplitter->activeContainer()->views());
00414
00415 ViewContainer* container = 0;
00416
00417 while (existingViewIter.hasNext())
00418 {
00419 Session* session = _sessionMap[(TerminalDisplay*)existingViewIter.next()];
00420 TerminalDisplay* display = createTerminalDisplay(session);
00421 applyProfile(display,SessionManager::instance()->sessionProfile(session),false);
00422 ViewProperties* properties = createController(session,display);
00423
00424 _sessionMap[display] = session;
00425
00426
00427
00428 if ( !container )
00429 container = createContainer(SessionManager::instance()->sessionProfile(session));
00430
00431 container->addView(display,properties);
00432 session->addView( display );
00433 }
00434
00435 _viewSplitter->addContainer(container,orientation);
00436 emit splitViewToggle(_viewSplitter->containers().count() > 0);
00437
00438
00439 container->containerWidget()->setFocus();
00440
00441
00442 ViewContainer* activeContainer = _viewSplitter->activeContainer();
00443 QWidget* activeView = activeContainer ? activeContainer->activeView() : 0;
00444
00445 if ( activeView )
00446 activeView->setFocus(Qt::OtherFocusReason);
00447 }
00448 void ViewManager::removeContainer(ViewContainer* container)
00449 {
00450
00451 foreach( QWidget* view , container->views() )
00452 {
00453 TerminalDisplay* display = qobject_cast<TerminalDisplay*>(view);
00454 Q_ASSERT(display);
00455 _sessionMap.remove(display);
00456 }
00457
00458 _viewSplitter->removeContainer(container);
00459 container->deleteLater();
00460
00461 emit splitViewToggle( _viewSplitter->containers().count() > 1 );
00462 }
00463 void ViewManager::expandActiveView()
00464 {
00465 _viewSplitter->adjustContainerSize(_viewSplitter->activeContainer(),10);
00466 }
00467 void ViewManager::shrinkActiveView()
00468 {
00469 _viewSplitter->adjustContainerSize(_viewSplitter->activeContainer(),-10);
00470 }
00471 void ViewManager::closeActiveView()
00472 {
00473
00474 if ( _viewSplitter->containers().count() > 1 )
00475 {
00476 ViewContainer* container = _viewSplitter->activeContainer();
00477
00478 removeContainer(container);
00479
00480
00481
00482 nextContainer();
00483 }
00484 }
00485 void ViewManager::closeOtherViews()
00486 {
00487 ViewContainer* active = _viewSplitter->activeContainer();
00488
00489 QListIterator<ViewContainer*> iter(_viewSplitter->containers());
00490 while ( iter.hasNext() )
00491 {
00492 ViewContainer* next = iter.next();
00493 if ( next != active )
00494 removeContainer(next);
00495 }
00496 }
00497
00498 SessionController* ViewManager::createController(Session* session , TerminalDisplay* view)
00499 {
00500
00501
00502 SessionController* controller = new SessionController(session,view,this);
00503 connect( controller , SIGNAL(focused(SessionController*)) , this , SLOT(controllerChanged(SessionController*)) );
00504 connect( session , SIGNAL(destroyed()) , controller , SLOT(deleteLater()) );
00505 connect( view , SIGNAL(destroyed()) , controller , SLOT(deleteLater()) );
00506
00507
00508 if (!_pluggedController)
00509 controllerChanged(controller);
00510
00511 return controller;
00512 }
00513
00514 void ViewManager::controllerChanged(SessionController* controller)
00515 {
00516 if ( controller == _pluggedController )
00517 return;
00518
00519 _viewSplitter->setFocusProxy(controller->view());
00520
00521 _pluggedController = controller;
00522 emit activeViewChanged(controller);
00523 }
00524
00525 SessionController* ViewManager::activeViewController() const
00526 {
00527 return _pluggedController;
00528 }
00529
00530 IncrementalSearchBar* ViewManager::searchBar() const
00531 {
00532 return _viewSplitter->activeSplitter()->activeContainer()->searchBar();
00533 }
00534
00535 void ViewManager::createView(Session* session, ViewContainer* container, int index)
00536 {
00537
00538
00539
00540
00541 disconnect( session , SIGNAL(finished()) , this , SLOT(sessionFinished()) );
00542 connect( session , SIGNAL(finished()) , this , SLOT(sessionFinished()) );
00543
00544 bool isFirst = _sessionMap.isEmpty();
00545 TerminalDisplay* display = createTerminalDisplay(session);
00546 applyProfile(display,SessionManager::instance()->sessionProfile(session),isFirst);
00547
00548
00549 display->setSize(80,40);
00550
00551 ViewProperties* properties = createController(session,display);
00552
00553 _sessionMap[display] = session;
00554 container->addView(display,properties,index);
00555 session->addView(display);
00556
00557
00558 const Profile::Ptr profile = SessionManager::instance()->sessionProfile(session);
00559 session->setDarkBackground( colorSchemeForProfile(profile)->hasDarkBackground() );
00560
00561 if ( container == _viewSplitter->activeContainer() )
00562 {
00563 container->setActiveView(display);
00564 display->setFocus( Qt::OtherFocusReason );
00565 }
00566
00567 updateDetachViewState();
00568 }
00569
00570 void ViewManager::createView(Session* session)
00571 {
00572
00573 if (_viewSplitter->containers().count() == 0)
00574 {
00575 _viewSplitter->addContainer( createContainer(SessionManager::instance()->sessionProfile(session)) ,
00576 Qt::Vertical );
00577 emit splitViewToggle(false);
00578 }
00579
00580
00581
00582
00583
00584 QListIterator<ViewContainer*> containerIter(_viewSplitter->containers());
00585
00586 while ( containerIter.hasNext() )
00587 {
00588 ViewContainer* container = containerIter.next();
00589 createView(session,container,-1);
00590 }
00591
00592 }
00593
00594 ViewContainer* ViewManager::createContainer(const Profile::Ptr info)
00595 {
00596 Q_ASSERT( info );
00597
00598 const int tabPosition = info->property<int>(Profile::TabBarPosition);
00599
00600 ViewContainer::NavigationPosition position = ( tabPosition == Profile::TabBarTop ) ?
00601 ViewContainer::NavigationPositionTop :
00602 ViewContainer::NavigationPositionBottom;
00603
00604 ViewContainer* container = 0;
00605
00606 switch ( _navigationMethod )
00607 {
00608 case TabbedNavigation:
00609 container = new TabbedViewContainer(position,_viewSplitter);
00610 break;
00611 case NoNavigation:
00612 default:
00613 container = new StackedViewContainer(_viewSplitter);
00614 }
00615
00616
00617 connect( container , SIGNAL(viewAdded(QWidget*,ViewProperties*)) , _containerSignalMapper ,
00618 SLOT(map()) );
00619 connect( container , SIGNAL(viewRemoved(QWidget*)) , _containerSignalMapper ,
00620 SLOT(map()) );
00621 _containerSignalMapper->setMapping(container,container);
00622
00623 connect( container, SIGNAL(newViewRequest()), this, SIGNAL(newViewRequest()) );
00624 connect( container, SIGNAL(moveViewRequest(int,int,bool&)),
00625 this , SLOT(containerMoveViewRequest(int,int,bool&)) );
00626 connect( container , SIGNAL(viewRemoved(QWidget*)) , this , SLOT(viewCloseRequest(QWidget*)) );
00627 connect( container , SIGNAL(closeRequest(QWidget*)) , this , SLOT(viewCloseRequest(QWidget*)) );
00628 connect( container , SIGNAL(activeViewChanged(QWidget*)) , this , SLOT(viewActivated(QWidget*)));
00629
00630 return container;
00631 }
00632 void ViewManager::containerMoveViewRequest(int index, int id, bool& moved)
00633 {
00634 ViewContainer* container = qobject_cast<ViewContainer*>(sender());
00635 SessionController* controller = qobject_cast<SessionController*>(ViewProperties::propertiesById(id));
00636
00637 if (!controller)
00638 return;
00639
00640 createView(controller->session(),container,index);
00641 moved = true;
00642 }
00643 void ViewManager::setNavigationMethod(NavigationMethod method)
00644 {
00645 _navigationMethod = method;
00646
00647 KActionCollection* collection = _actionCollection;
00648
00649 if ( collection )
00650 {
00651 QAction* action;
00652
00653 action = collection->action( "next-view" );
00654 if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
00655
00656 action = collection->action( "previous-view" );
00657 if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
00658
00659 action = collection->action( "split-view-left-right" );
00660 if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
00661
00662 action = collection->action( "split-view-top-bottom" );
00663 if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
00664
00665 action = collection->action( "rename-session" );
00666 if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
00667 }
00668 }
00669
00670 ViewManager::NavigationMethod ViewManager::navigationMethod() const { return _navigationMethod; }
00671
00672 void ViewManager::containerViewsChanged(QObject* container)
00673 {
00674 if (_viewSplitter && container == _viewSplitter->activeContainer() )
00675 {
00676 emit viewPropertiesChanged( viewProperties() );
00677 }
00678 }
00679
00680 void ViewManager::viewCloseRequest(QWidget* view)
00681 {
00682
00683 TerminalDisplay* display = (TerminalDisplay*)view;
00684
00685 Q_ASSERT(display);
00686
00687
00688
00689 Session* session = _sessionMap[ display ];
00690 _sessionMap.remove(display);
00691 if ( session )
00692 {
00693 display->deleteLater();
00694
00695 if ( session->views().count() == 0 )
00696 session->close();
00697 }
00698
00699 if (_viewSplitter) {
00700 focusActiveView();
00701 updateDetachViewState();
00702 }
00703 }
00704
00705 TerminalDisplay* ViewManager::createTerminalDisplay(Session* session)
00706 {
00707 TerminalDisplay* display = new TerminalDisplay(0);
00708
00709
00710 display->setBellMode(TerminalDisplay::NotifyBell);
00711 display->setTerminalSizeHint(true);
00712 display->setTripleClickMode(TerminalDisplay::SelectWholeLine);
00713 display->setTerminalSizeStartup(true);
00714 display->setScrollBarPosition(TerminalDisplay::ScrollBarRight);
00715 display->setRandomSeed(session->sessionId() * 31);
00716
00717 return display;
00718 }
00719
00720 const ColorScheme* ViewManager::colorSchemeForProfile(const Profile::Ptr info) const
00721 {
00722 const ColorScheme* colorScheme = ColorSchemeManager::instance()->
00723 findColorScheme(info->colorScheme());
00724 if ( !colorScheme )
00725 colorScheme = ColorSchemeManager::instance()->defaultColorScheme();
00726 Q_ASSERT( colorScheme );
00727
00728 return colorScheme;
00729 }
00730
00731 void ViewManager::applyProfile(TerminalDisplay* view , const Profile::Ptr info,
00732 bool applyContainerSettings)
00733 {
00734 Q_ASSERT( info );
00735
00736 const ColorScheme* colorScheme = colorSchemeForProfile(info);
00737
00738
00739 emit setMenuBarVisibleRequest( info->property<bool>(Profile::ShowMenuBar) );
00740
00741
00742 if (applyContainerSettings)
00743 {
00744 ViewContainer* container = _viewSplitter->activeContainer();
00745 int tabBarMode = info->property<int>(Profile::TabBarMode);
00746 int tabBarPosition = info->property<int>(Profile::TabBarPosition);
00747 bool showNewCloseButtons = info->property<bool>(Profile::ShowNewAndCloseTabButtons);
00748
00749 if ( tabBarMode == Profile::AlwaysHideTabBar )
00750 container->setNavigationDisplayMode(ViewContainer::AlwaysHideNavigation);
00751 else if ( tabBarMode == Profile::AlwaysShowTabBar )
00752 container->setNavigationDisplayMode(ViewContainer::AlwaysShowNavigation);
00753 else if ( tabBarMode == Profile::ShowTabBarAsNeeded )
00754 container->setNavigationDisplayMode(ViewContainer::ShowNavigationAsNeeded);
00755
00756 ViewContainer::NavigationPosition position = container->navigationPosition();
00757
00758 if ( tabBarPosition == Profile::TabBarTop )
00759 position = ViewContainer::NavigationPositionTop;
00760 else if ( tabBarPosition == Profile::TabBarBottom )
00761 position = ViewContainer::NavigationPositionBottom;
00762
00763 if ( container->supportedNavigationPositions().contains(position) )
00764 container->setNavigationPosition(position);
00765
00766 if (showNewCloseButtons)
00767 {
00768 container->setFeatures(container->features()
00769 | ViewContainer::QuickNewView | ViewContainer::QuickCloseView);
00770 container->setNewViewMenu(createNewViewMenu());
00771 }
00772 else
00773 container->setFeatures(container->features()
00774 & ~ViewContainer::QuickNewView & ~ViewContainer::QuickCloseView);
00775 }
00776
00777
00778 ColorEntry table[TABLE_COLORS];
00779
00780 colorScheme->getColorTable(table , view->randomSeed() );
00781 view->setColorTable(table);
00782 view->setOpacity(colorScheme->opacity());
00783
00784
00785 view->setAntialias(info->property<bool>(Profile::AntiAliasFonts));
00786 view->setVTFont(info->font());
00787
00788
00789 int scrollBarPosition = info->property<int>(Profile::ScrollBarPosition);
00790
00791 if ( scrollBarPosition == Profile::ScrollBarHidden )
00792 view->setScrollBarPosition(TerminalDisplay::NoScrollBar);
00793 else if ( scrollBarPosition == Profile::ScrollBarLeft )
00794 view->setScrollBarPosition(TerminalDisplay::ScrollBarLeft);
00795 else if ( scrollBarPosition == Profile::ScrollBarRight )
00796 view->setScrollBarPosition(TerminalDisplay::ScrollBarRight);
00797
00798
00799 bool blinkingCursor = info->property<bool>(Profile::BlinkingCursorEnabled);
00800 view->setBlinkingCursor(blinkingCursor);
00801
00802 bool bidiEnabled = info->property<bool>(Profile::BidiRenderingEnabled);
00803 view->setBidiEnabled(bidiEnabled);
00804
00805
00806 int cursorShape = info->property<int>(Profile::CursorShape);
00807
00808 if ( cursorShape == Profile::BlockCursor )
00809 view->setKeyboardCursorShape(TerminalDisplay::BlockCursor);
00810 else if ( cursorShape == Profile::IBeamCursor )
00811 view->setKeyboardCursorShape(TerminalDisplay::IBeamCursor);
00812 else if ( cursorShape == Profile::UnderlineCursor )
00813 view->setKeyboardCursorShape(TerminalDisplay::UnderlineCursor);
00814
00815
00816 bool useCustomColor = info->property<bool>(Profile::UseCustomCursorColor);
00817 const QColor& cursorColor = info->property<QColor>(Profile::CustomCursorColor);
00818
00819 view->setKeyboardCursorColor(!useCustomColor,cursorColor);
00820
00821
00822 view->setWordCharacters( info->property<QString>(Profile::WordCharacters) );
00823 }
00824
00825 void ViewManager::updateViewsForSession(Session* session)
00826 {
00827 QListIterator<TerminalDisplay*> iter(_sessionMap.keys(session));
00828 while ( iter.hasNext() )
00829 {
00830 applyProfile(iter.next(),SessionManager::instance()->sessionProfile(session),false);
00831 }
00832 }
00833
00834 void ViewManager::profileChanged(Profile::Ptr profile)
00835 {
00836 QHashIterator<TerminalDisplay*,Session*> iter(_sessionMap);
00837
00838 while ( iter.hasNext() )
00839 {
00840 iter.next();
00841
00842
00843 if ( iter.key() != 0 &&
00844 iter.value() != 0 &&
00845 SessionManager::instance()->sessionProfile(iter.value()) == profile )
00846 {
00847 applyProfile(iter.key(),profile,true);
00848 }
00849 }
00850 }
00851
00852 QList<ViewProperties*> ViewManager::viewProperties() const
00853 {
00854 QList<ViewProperties*> list;
00855
00856 ViewContainer* container = _viewSplitter->activeContainer();
00857
00858 Q_ASSERT( container );
00859
00860 QListIterator<QWidget*> viewIter(container->views());
00861 while ( viewIter.hasNext() )
00862 {
00863 ViewProperties* properties = container->viewProperties(viewIter.next());
00864 Q_ASSERT( properties );
00865 list << properties;
00866 }
00867
00868 return list;
00869 }
00870
00871 void ViewManager::saveSessions(KConfigGroup& group)
00872 {
00873
00874 QList<int> ids;
00875 QHash<Session*,int> unique;
00876
00877
00878 ViewContainer* container = _viewSplitter->activeContainer();
00879 Q_ASSERT(container);
00880 TerminalDisplay* activeview = dynamic_cast<TerminalDisplay*>(container->activeView());
00881
00882 QListIterator<QWidget*> viewIter(container->views());
00883 int tab = 1;
00884 while (viewIter.hasNext())
00885 {
00886 TerminalDisplay *view = dynamic_cast<TerminalDisplay*>(viewIter.next());
00887 Q_ASSERT(view);
00888 Session *session = _sessionMap[view];
00889 ids << SessionManager::instance()->getRestoreId(session);
00890 if (view == activeview) group.writeEntry("Active", tab);
00891 unique.insert(session, 1);
00892 tab++;
00893 }
00894
00895
00896
00897 foreach(Session* session, _sessionMap)
00898 if (!unique.contains(session))
00899 {
00900 ids << SessionManager::instance()->getRestoreId(session);
00901 unique.insert(session, 1);
00902 }
00903
00904 group.writeEntry("Sessions", ids);
00905 }
00906
00907 void ViewManager::restoreSessions(const KConfigGroup& group)
00908 {
00909 QList<int> ids = group.readEntry("Sessions", QList<int>());
00910 int activeTab = group.readEntry("Active", 0);
00911 TerminalDisplay *display = 0;
00912
00913 int tab = 1;
00914 foreach(int id, ids)
00915 {
00916 Session *session = SessionManager::instance()->idToSession(id);
00917 createView(session);
00918 if (!session->isRunning())
00919 session->run();
00920 if (tab++ == activeTab)
00921 display = dynamic_cast<TerminalDisplay*>(activeView());
00922 }
00923
00924 if (display)
00925 {
00926 _viewSplitter->activeContainer()->setActiveView(display);
00927 display->setFocus(Qt::OtherFocusReason);
00928 }
00929 }
00930
00931 uint qHash(QPointer<TerminalDisplay> display)
00932 {
00933 return qHash((TerminalDisplay*)display);
00934 }
00935
00936 #include "ViewManager.moc"
00937
00938
00939
00940
00941
00942
00943
00944
00945