Changeset View
Changeset View
Standalone View
Standalone View
src/ViewManager.cpp
Show All 19 Lines | |||||
20 | // Own | 20 | // Own | ||
21 | #include "ViewManager.h" | 21 | #include "ViewManager.h" | ||
22 | 22 | | |||
23 | #include <config-konsole.h> | 23 | #include <config-konsole.h> | ||
24 | 24 | | |||
25 | // Qt | 25 | // Qt | ||
26 | #include <QStringList> | 26 | #include <QStringList> | ||
27 | #include <QAction> | 27 | #include <QAction> | ||
28 | #include <QBoxLayout> | ||||
28 | 29 | | |||
29 | // KDE | 30 | // KDE | ||
30 | #include <KAcceleratorManager> | 31 | #include <KAcceleratorManager> | ||
31 | #include <KLocalizedString> | 32 | #include <KLocalizedString> | ||
32 | #include <KActionCollection> | 33 | #include <KActionCollection> | ||
33 | #include <KConfigGroup> | 34 | #include <KConfigGroup> | ||
34 | 35 | | |||
35 | // Konsole | 36 | // Konsole | ||
▲ Show 20 Lines • Show All 369 Lines • ▼ Show 20 Line(s) | 403 | { | |||
405 | if (_viewSplitter.isNull()) { | 406 | if (_viewSplitter.isNull()) { | ||
406 | return; | 407 | return; | ||
407 | } | 408 | } | ||
408 | 409 | | |||
409 | Session *session = qobject_cast<Session *>(sender()); | 410 | Session *session = qobject_cast<Session *>(sender()); | ||
410 | Q_ASSERT(session); | 411 | Q_ASSERT(session); | ||
411 | 412 | | |||
412 | // close attached views | 413 | // close attached views | ||
413 | QList<TerminalDisplay *> children = _viewSplitter->findChildren<TerminalDisplay *>(); | 414 | QList<TerminalWidget *> children = _viewSplitter->findChildren<TerminalWidget *>(); | ||
414 | 415 | | |||
415 | foreach (TerminalDisplay *view, children) { | 416 | foreach (auto *view, children) { | ||
416 | if (_sessionMap[view] == session) { | 417 | if (_sessionMap[view->terminalDisplay()] == session) { | ||
417 | _sessionMap.remove(view); | 418 | _sessionMap.remove(view->terminalDisplay()); | ||
418 | view->deleteLater(); | 419 | view->deleteLater(); | ||
419 | } | 420 | } | ||
420 | } | 421 | } | ||
421 | 422 | | |||
422 | // Only remove the controller from factory() if it's actually controlling | 423 | // Only remove the controller from factory() if it's actually controlling | ||
423 | // the session from the sender. | 424 | // the session from the sender. | ||
424 | // This fixes BUG: 348478 - messed up menus after a detached tab is closed | 425 | // This fixes BUG: 348478 - messed up menus after a detached tab is closed | ||
425 | if ((!_pluggedController.isNull()) && (_pluggedController->session() == session)) { | 426 | if ((!_pluggedController.isNull()) && (_pluggedController->session() == session)) { | ||
Show All 25 Lines | |||||
451 | 452 | | |||
452 | void ViewManager::splitView(Qt::Orientation orientation) | 453 | void ViewManager::splitView(Qt::Orientation orientation) | ||
453 | { | 454 | { | ||
454 | ViewContainer *container = createContainer(); | 455 | ViewContainer *container = createContainer(); | ||
455 | 456 | | |||
456 | // iterate over each session which has a view in the current active | 457 | // iterate over each session which has a view in the current active | ||
457 | // container and create a new view for that session in a new container | 458 | // container and create a new view for that session in a new container | ||
458 | foreach (QWidget *view, _viewSplitter->activeContainer()->views()) { | 459 | foreach (QWidget *view, _viewSplitter->activeContainer()->views()) { | ||
459 | Session *session = _sessionMap[qobject_cast<TerminalDisplay *>(view)]; | 460 | TerminalWidget *currView = qobject_cast<TerminalWidget*>(view); | ||
460 | TerminalDisplay *display = createTerminalDisplay(session); | 461 | Session *session = _sessionMap[currView->terminalDisplay()]; | ||
462 | | ||||
463 | auto terminalWidget = new TerminalWidget(session->sessionId()); | ||||
461 | const Profile::Ptr profile = SessionManager::instance()->sessionProfile(session); | 464 | const Profile::Ptr profile = SessionManager::instance()->sessionProfile(session); | ||
462 | applyProfileToView(display, profile); | | |||
463 | ViewProperties *properties = createController(session, display); | | |||
464 | 465 | | |||
465 | _sessionMap[display] = session; | 466 | applyProfileToView(terminalWidget->terminalDisplay(), profile); | ||
467 | ViewProperties *properties = createController(session, terminalWidget); | ||||
468 | | ||||
469 | _sessionMap[terminalWidget->terminalDisplay()] = session; | ||||
466 | 470 | | |||
467 | container->addView(display, properties); | 471 | container->addView(terminalWidget, properties); | ||
468 | session->addView(display); | 472 | session->addView(terminalWidget->terminalDisplay()); | ||
469 | } | 473 | } | ||
470 | 474 | | |||
471 | _viewSplitter->addContainer(container, orientation); | 475 | _viewSplitter->addContainer(container, orientation); | ||
472 | emit splitViewToggle(_viewSplitter->containers().count() > 0); | 476 | emit splitViewToggle(_viewSplitter->containers().count() > 0); | ||
473 | 477 | | |||
474 | // focus the new container | 478 | // focus the new container | ||
475 | container->containerWidget()->setFocus(); | 479 | container->containerWidget()->setFocus(); | ||
476 | 480 | | |||
477 | // ensure that the active view is focused after the split / unsplit | 481 | // ensure that the active view is focused after the split / unsplit | ||
478 | ViewContainer *activeContainer = _viewSplitter->activeContainer(); | 482 | ViewContainer *activeContainer = _viewSplitter->activeContainer(); | ||
479 | QWidget *activeView = activeContainer != nullptr ? activeContainer->activeView() : nullptr; | 483 | QWidget *activeView = activeContainer != nullptr ? activeContainer->activeView() : nullptr; | ||
480 | 484 | | |||
481 | if (activeView != nullptr) { | 485 | if (activeView != nullptr) { | ||
482 | activeView->setFocus(Qt::OtherFocusReason); | 486 | activeView->setFocus(Qt::OtherFocusReason); | ||
483 | } | 487 | } | ||
484 | } | 488 | } | ||
485 | 489 | | |||
486 | void ViewManager::removeContainer(ViewContainer *container) | 490 | void ViewManager::removeContainer(ViewContainer *container) | ||
487 | { | 491 | { | ||
488 | // remove session map entries for views in this container | 492 | // remove session map entries for views in this container | ||
489 | foreach (QWidget *view, container->views()) { | 493 | foreach (QWidget *view, container->views()) { | ||
490 | TerminalDisplay *display = qobject_cast<TerminalDisplay *>(view); | 494 | TerminalWidget *currView = qobject_cast<TerminalWidget*>(view); | ||
491 | Q_ASSERT(display); | 495 | Q_ASSERT(currView); | ||
492 | _sessionMap.remove(display); | 496 | _sessionMap.remove(currView->terminalDisplay()); | ||
493 | } | 497 | } | ||
494 | 498 | | |||
495 | _viewSplitter->removeContainer(container); | 499 | _viewSplitter->removeContainer(container); | ||
496 | container->deleteLater(); | 500 | container->deleteLater(); | ||
497 | 501 | | |||
498 | emit splitViewToggle(_viewSplitter->containers().count() > 1); | 502 | emit splitViewToggle(_viewSplitter->containers().count() > 1); | ||
499 | } | 503 | } | ||
500 | 504 | | |||
Show All 27 Lines | 530 | { | |||
528 | 532 | | |||
529 | foreach (ViewContainer *container, _viewSplitter->containers()) { | 533 | foreach (ViewContainer *container, _viewSplitter->containers()) { | ||
530 | if (container != active) { | 534 | if (container != active) { | ||
531 | removeContainer(container); | 535 | removeContainer(container); | ||
532 | } | 536 | } | ||
533 | } | 537 | } | ||
534 | } | 538 | } | ||
535 | 539 | | |||
536 | SessionController *ViewManager::createController(Session *session, TerminalDisplay *view) | 540 | SessionController *ViewManager::createController(Session *session, TerminalWidget *view) | ||
537 | { | 541 | { | ||
538 | // create a new controller for the session, and ensure that this view manager | 542 | // create a new controller for the session, and ensure that this view manager | ||
539 | // is notified when the view gains the focus | 543 | // is notified when the view gains the focus | ||
540 | auto controller = new SessionController(session, view, this); | 544 | auto controller = new SessionController(session, view, this); | ||
541 | connect(controller, &Konsole::SessionController::focused, this, | 545 | connect(controller, &Konsole::SessionController::focused, this, | ||
542 | &Konsole::ViewManager::controllerChanged); | 546 | &Konsole::ViewManager::controllerChanged); | ||
543 | connect(session, &Konsole::Session::destroyed, controller, | 547 | connect(session, &Konsole::Session::destroyed, controller, | ||
544 | &Konsole::SessionController::deleteLater); | 548 | &Konsole::SessionController::deleteLater); | ||
Show All 24 Lines | 565 | { | |||
569 | emit activeViewChanged(controller); | 573 | emit activeViewChanged(controller); | ||
570 | } | 574 | } | ||
571 | 575 | | |||
572 | SessionController *ViewManager::activeViewController() const | 576 | SessionController *ViewManager::activeViewController() const | ||
573 | { | 577 | { | ||
574 | return _pluggedController; | 578 | return _pluggedController; | ||
575 | } | 579 | } | ||
576 | 580 | | |||
577 | IncrementalSearchBar *ViewManager::searchBar() const | | |||
578 | { | | |||
579 | return _viewSplitter->activeSplitter()->activeContainer()->searchBar(); | | |||
580 | } | | |||
581 | | ||||
582 | void ViewManager::createView(Session *session, ViewContainer *container, int index) | 581 | void ViewManager::createView(Session *session, ViewContainer *container, int index) | ||
583 | { | 582 | { | ||
584 | // notify this view manager when the session finishes so that its view | 583 | // notify this view manager when the session finishes so that its view | ||
585 | // can be deleted | 584 | // can be deleted | ||
586 | // | 585 | // | ||
587 | // Use Qt::UniqueConnection to avoid duplicate connection | 586 | // Use Qt::UniqueConnection to avoid duplicate connection | ||
588 | connect(session, &Konsole::Session::finished, this, &Konsole::ViewManager::sessionFinished, | 587 | connect(session, &Konsole::Session::finished, this, &Konsole::ViewManager::sessionFinished, | ||
589 | Qt::UniqueConnection); | 588 | Qt::UniqueConnection); | ||
590 | 589 | | |||
591 | TerminalDisplay *display = createTerminalDisplay(session); | 590 | auto *terminalWidget = new TerminalWidget(session->sessionId()); | ||
592 | const Profile::Ptr profile = SessionManager::instance()->sessionProfile(session); | 591 | const Profile::Ptr profile = SessionManager::instance()->sessionProfile(session); | ||
593 | applyProfileToView(display, profile); | 592 | applyProfileToView(terminalWidget->terminalDisplay(), profile); | ||
594 | 593 | | |||
595 | // set initial size | 594 | ViewProperties *properties = createController(session, terminalWidget); | ||
596 | const QSize &preferredSize = session->preferredSize(); | 595 | | ||
597 | // FIXME: +1 is needed here for getting the expected rows | 596 | _sessionMap[terminalWidget->terminalDisplay()] = session; | ||
598 | // Note that the display shouldn't need to take into account the tabbar. | 597 | container->addView(terminalWidget, properties, index); | ||
599 | // However, it appears that taking into account the tabbar is needed. | 598 | session->addView(terminalWidget->terminalDisplay()); | ||
600 | // If tabbar is not visible, no +1 is needed here; however, depending on | | |||
601 | // settings/tabbar style, +2 might be needed. | | |||
602 | // 1st attempt at fixing the above: | | |||
603 | // Guess if tabbar will NOT be visible; ignore ShowNavigationAsNeeded | | |||
604 | int heightAdjustment = 0; | | |||
605 | if (_navigationVisibility != ViewContainer::AlwaysHideNavigation) { | | |||
606 | heightAdjustment = 2; | | |||
607 | } | | |||
608 | | ||||
609 | display->setSize(preferredSize.width(), preferredSize.height() + heightAdjustment); | | |||
610 | ViewProperties *properties = createController(session, display); | | |||
611 | | ||||
612 | _sessionMap[display] = session; | | |||
613 | container->addView(display, properties, index); | | |||
614 | session->addView(display); | | |||
615 | 599 | | |||
616 | // tell the session whether it has a light or dark background | 600 | // tell the session whether it has a light or dark background | ||
617 | session->setDarkBackground(colorSchemeForProfile(profile)->hasDarkBackground()); | 601 | session->setDarkBackground(colorSchemeForProfile(profile)->hasDarkBackground()); | ||
618 | 602 | | |||
619 | if (container == _viewSplitter->activeContainer()) { | 603 | if (container == _viewSplitter->activeContainer()) { | ||
620 | container->setActiveView(display); | 604 | container->setActiveView(terminalWidget); | ||
621 | display->setFocus(Qt::OtherFocusReason); | 605 | terminalWidget->setFocus(Qt::OtherFocusReason); | ||
622 | } | 606 | } | ||
623 | 607 | | |||
624 | updateDetachViewState(); | 608 | updateDetachViewState(); | ||
625 | } | 609 | } | ||
626 | 610 | | |||
627 | void ViewManager::createView(Session *session) | 611 | void ViewManager::createView(Session *session) | ||
628 | { | 612 | { | ||
629 | // create the default container | 613 | // create the default container | ||
▲ Show 20 Lines • Show All 206 Lines • ▼ Show 20 Line(s) | 819 | if (!_viewSplitter.isNull()) { | |||
836 | updateDetachViewState(); | 820 | updateDetachViewState(); | ||
837 | } | 821 | } | ||
838 | // The below causes the menus to be messed up | 822 | // The below causes the menus to be messed up | ||
839 | // Only happens when using the tab bar close button | 823 | // Only happens when using the tab bar close button | ||
840 | // if (_pluggedController) | 824 | // if (_pluggedController) | ||
841 | // emit unplugController(_pluggedController); | 825 | // emit unplugController(_pluggedController); | ||
842 | } | 826 | } | ||
843 | 827 | | |||
844 | TerminalDisplay *ViewManager::createTerminalDisplay(Session *session) | | |||
845 | { | | |||
846 | auto display = new TerminalDisplay(nullptr); | | |||
847 | display->setRandomSeed(session->sessionId() * 31); | | |||
848 | | ||||
849 | return display; | | |||
850 | } | | |||
851 | | ||||
852 | const ColorScheme *ViewManager::colorSchemeForProfile(const Profile::Ptr profile) | 828 | const ColorScheme *ViewManager::colorSchemeForProfile(const Profile::Ptr profile) | ||
853 | { | 829 | { | ||
854 | const ColorScheme *colorScheme = ColorSchemeManager::instance()-> | 830 | const ColorScheme *colorScheme = ColorSchemeManager::instance()-> | ||
855 | findColorScheme(profile->colorScheme()); | 831 | findColorScheme(profile->colorScheme()); | ||
856 | if (colorScheme == nullptr) { | 832 | if (colorScheme == nullptr) { | ||
857 | colorScheme = ColorSchemeManager::instance()->defaultColorScheme(); | 833 | colorScheme = ColorSchemeManager::instance()->defaultColorScheme(); | ||
858 | } | 834 | } | ||
859 | Q_ASSERT(colorScheme); | 835 | Q_ASSERT(colorScheme); | ||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Line(s) | 993 | { | |||
1020 | QSet<Session *> unique; | 996 | QSet<Session *> unique; | ||
1021 | 997 | | |||
1022 | // first: sessions in the active container, preserving the order | 998 | // first: sessions in the active container, preserving the order | ||
1023 | ViewContainer *container = _viewSplitter->activeContainer(); | 999 | ViewContainer *container = _viewSplitter->activeContainer(); | ||
1024 | Q_ASSERT(container); | 1000 | Q_ASSERT(container); | ||
1025 | if (container == nullptr) { | 1001 | if (container == nullptr) { | ||
1026 | return; | 1002 | return; | ||
1027 | } | 1003 | } | ||
1028 | TerminalDisplay *activeview = qobject_cast<TerminalDisplay *>(container->activeView()); | 1004 | auto *activeview = qobject_cast<TerminalWidget *>(container->activeView()); | ||
1029 | 1005 | | |||
1030 | QListIterator<QWidget *> viewIter(container->views()); | 1006 | QListIterator<QWidget *> viewIter(container->views()); | ||
1031 | int tab = 1; | 1007 | int tab = 1; | ||
1032 | while (viewIter.hasNext()) { | 1008 | while (viewIter.hasNext()) { | ||
1033 | TerminalDisplay *view = qobject_cast<TerminalDisplay *>(viewIter.next()); | 1009 | auto *view = qobject_cast<TerminalWidget *>(viewIter.next()); | ||
1034 | Q_ASSERT(view); | 1010 | Q_ASSERT(view); | ||
1035 | Session *session = _sessionMap[view]; | 1011 | Session *session = _sessionMap[view->terminalDisplay()]; | ||
1036 | ids << SessionManager::instance()->getRestoreId(session); | 1012 | ids << SessionManager::instance()->getRestoreId(session); | ||
1037 | unique.insert(session); | 1013 | unique.insert(session); | ||
1038 | if (view == activeview) { | 1014 | if (view == activeview) { | ||
1039 | group.writeEntry("Active", tab); | 1015 | group.writeEntry("Active", tab); | ||
1040 | } | 1016 | } | ||
1041 | tab++; | 1017 | tab++; | ||
1042 | } | 1018 | } | ||
1043 | 1019 | | |||
1044 | // second: all other sessions, in random order | 1020 | // second: all other sessions, in random order | ||
1045 | // we don't want to have sessions restored that are not connected | 1021 | // we don't want to have sessions restored that are not connected | ||
1046 | foreach (Session *session, _sessionMap) { | 1022 | foreach (Session *session, _sessionMap) { | ||
1047 | if (!unique.contains(session)) { | 1023 | if (!unique.contains(session)) { | ||
1048 | ids << SessionManager::instance()->getRestoreId(session); | 1024 | ids << SessionManager::instance()->getRestoreId(session); | ||
1049 | unique.insert(session); | 1025 | unique.insert(session); | ||
1050 | } | 1026 | } | ||
1051 | } | 1027 | } | ||
1052 | 1028 | | |||
1053 | group.writeEntry("Sessions", ids); | 1029 | group.writeEntry("Sessions", ids); | ||
1054 | } | 1030 | } | ||
1055 | 1031 | | |||
1056 | void ViewManager::restoreSessions(const KConfigGroup &group) | 1032 | void ViewManager::restoreSessions(const KConfigGroup &group) | ||
1057 | { | 1033 | { | ||
1058 | QList<int> ids = group.readEntry("Sessions", QList<int>()); | 1034 | QList<int> ids = group.readEntry("Sessions", QList<int>()); | ||
1059 | int activeTab = group.readEntry("Active", 0); | 1035 | int activeTab = group.readEntry("Active", 0); | ||
1060 | TerminalDisplay *display = nullptr; | 1036 | TerminalWidget *display = nullptr; | ||
1061 | 1037 | | |||
1062 | int tab = 1; | 1038 | int tab = 1; | ||
1063 | foreach (int id, ids) { | 1039 | foreach (int id, ids) { | ||
1064 | Session *session = SessionManager::instance()->idToSession(id); | 1040 | Session *session = SessionManager::instance()->idToSession(id); | ||
1065 | 1041 | | |||
1066 | if (session == nullptr) { | 1042 | if (session == nullptr) { | ||
1067 | qWarning() << "Unable to load session with id" << id; | 1043 | qWarning() << "Unable to load session with id" << id; | ||
1068 | // Force a creation of a default session below | 1044 | // Force a creation of a default session below | ||
1069 | ids.clear(); | 1045 | ids.clear(); | ||
1070 | break; | 1046 | break; | ||
1071 | } | 1047 | } | ||
1072 | 1048 | | |||
1073 | createView(session); | 1049 | createView(session); | ||
1074 | if (!session->isRunning()) { | 1050 | if (!session->isRunning()) { | ||
1075 | session->run(); | 1051 | session->run(); | ||
1076 | } | 1052 | } | ||
1077 | if (tab++ == activeTab) { | 1053 | if (tab++ == activeTab) { | ||
1078 | display = qobject_cast<TerminalDisplay *>(activeView()); | 1054 | display = qobject_cast<TerminalWidget *>(activeView()); | ||
1079 | } | 1055 | } | ||
1080 | } | 1056 | } | ||
1081 | 1057 | | |||
1082 | if (display != nullptr) { | 1058 | if (display != nullptr) { | ||
1083 | _viewSplitter->activeContainer()->setActiveView(display); | 1059 | _viewSplitter->activeContainer()->setActiveView(display); | ||
1084 | display->setFocus(Qt::OtherFocusReason); | 1060 | display->terminalDisplay()->setFocus(Qt::OtherFocusReason); | ||
1085 | } | 1061 | } | ||
1086 | 1062 | | |||
1087 | if (ids.isEmpty()) { // Session file is unusable, start default Profile | 1063 | if (ids.isEmpty()) { // Session file is unusable, start default Profile | ||
1088 | Profile::Ptr profile = ProfileManager::instance()->defaultProfile(); | 1064 | Profile::Ptr profile = ProfileManager::instance()->defaultProfile(); | ||
1089 | Session *session = SessionManager::instance()->createSession(profile); | 1065 | Session *session = SessionManager::instance()->createSession(profile); | ||
1090 | createView(session); | 1066 | createView(session); | ||
1091 | if (!session->isRunning()) { | 1067 | if (!session->isRunning()) { | ||
1092 | session->run(); | 1068 | session->run(); | ||
▲ Show 20 Lines • Show All 207 Lines • Show Last 20 Lines |