diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1ba27e0d..feb4f5a2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,209 +1,210 @@ # cmake-options : -DCMAKE_DISABLE_FIND_PACKAGE_LibKonq=TRUE or FALSE; default is FALSE add_definitions(-DTRANSLATION_DOMAIN=\"konsole\") ### Handle DragonFlyBSD here instead of using __DragonFly__ IF(${CMAKE_SYSTEM_NAME} MATCHES "DragonFly") set(HAVE_OS_DRAGONFLYBSD 1) else() set(HAVE_OS_DRAGONFLYBSD 0) endif() include(CheckIncludeFiles) include(ECMAddAppIcon) configure_file(config-konsole.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-konsole.h) ### Tests if(BUILD_TESTING) find_package(Qt5Test ${QT_MIN_VERSION} CONFIG REQUIRED) add_subdirectory(autotests) add_subdirectory(tests) endif() ### Security concerns about sendText and runCommand dbus methods being public option(REMOVE_SENDTEXT_RUNCOMMAND_DBUS_METHODS "Konsole: remove sendText and runCommand dbus methods" OFF) ### Font Embedder and LineFont.h option(KONSOLE_BUILD_FONTEMBEDDER "Konsole: build fontembedder executable" OFF) option(KONSOLE_GENERATE_LINEFONT "Konsole: regenerate LineFont file" OFF) ### Konsole source files shared between embedded terminal and main application # qdbuscpp2xml -m Session.h -o org.kde.konsole.Session.xml # qdbuscpp2xml -M -s ViewManager.h -o org.kde.konsole.Konsole.xml # Generate dbus .xml files; do not store .xml in source folder qt5_generate_dbus_interface(Session.h org.kde.konsole.Session.xml OPTIONS -m) qt5_generate_dbus_interface(ViewManager.h org.kde.konsole.Window.xml OPTIONS -m) qt5_add_dbus_adaptor(sessionadaptors_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.konsole.Session.xml Session.h Konsole::Session) qt5_add_dbus_adaptor(windowadaptors_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.konsole.Window.xml ViewManager.h Konsole::ViewManager) set(konsoleprivate_SRCS ${sessionadaptors_SRCS} ${windowadaptors_SRCS} BookmarkHandler.cpp ColorScheme.cpp ColorSchemeManager.cpp ColorSchemeEditor.cpp CopyInputDialog.cpp EditProfileDialog.cpp Emulation.cpp + DetachableTabBar.cpp Filter.cpp History.cpp HistorySizeDialog.cpp HistorySizeWidget.cpp IncrementalSearchBar.cpp KeyBindingEditor.cpp KeyboardTranslator.cpp KeyboardTranslatorManager.cpp ProcessInfo.cpp Profile.cpp ProfileList.cpp ProfileReader.cpp ProfileWriter.cpp ProfileManager.cpp Pty.cpp RenameTabDialog.cpp RenameTabWidget.cpp Screen.cpp ScreenWindow.cpp ScrollState.cpp Session.cpp SessionController.cpp SessionManager.cpp SessionListModel.cpp ShellCommand.cpp TabTitleFormatButton.cpp TerminalCharacterDecoder.cpp ExtendedCharTable.cpp TerminalDisplay.cpp TerminalDisplayAccessible.cpp ViewContainer.cpp ViewManager.cpp ViewProperties.cpp ViewSplitter.cpp Vt102Emulation.cpp ZModemDialog.cpp PrintOptions.cpp konsole_wcwidth.cpp WindowSystemInfo.cpp ${CMAKE_CURRENT_BINARY_DIR}/org.kde.konsole.Window.xml ${CMAKE_CURRENT_BINARY_DIR}/org.kde.konsole.Session.xml) ecm_qt_declare_logging_category(konsoleprivate_SRCS HEADER konsoledebug.h IDENTIFIER KonsoleDebug CATEGORY_NAME org.kde.konsole) kconfig_add_kcfg_files(konsoleprivate_SRCS settings/KonsoleSettings.kcfgc) set(konsole_LIBS KF5::XmlGui Qt5::PrintSupport Qt5::Xml KF5::Notifications KF5::WindowSystem KF5::TextWidgets KF5::GuiAddons KF5::IconThemes KF5::Bookmarks KF5::I18n KF5::Pty KF5::KIOWidgets KF5::DBusAddons KF5::GlobalAccel KF5::NewStuff ) if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") #kinfo_getfile() is in libutil list(APPEND konsole_LIBS util) endif() ### Konsole Application ki18n_wrap_ui(konsoleprivate_SRCS ColorSchemeEditor.ui CopyInputDialog.ui EditProfileDialog.ui KeyBindingEditor.ui RenameTabDialog.ui RenameTabWidget.ui HistorySizeDialog.ui HistorySizeWidget.ui PrintOptions.ui settings/FileLocationSettings.ui settings/GeneralSettings.ui settings/PartInfo.ui settings/ProfileSettings.ui settings/TabBarSettings.ui) # add the resource files for the ui files qt5_add_resources( konsoleprivate_SRCS ../desktop/konsole.qrc) add_library(konsoleprivate ${konsoleprivate_SRCS}) generate_export_header(konsoleprivate BASE_NAME konsoleprivate) target_link_libraries(konsoleprivate PUBLIC ${konsole_LIBS}) set_target_properties(konsoleprivate PROPERTIES VERSION ${KONSOLEPRIVATE_VERSION_STRING} SOVERSION ${KONSOLEPRIVATE_SOVERSION} ) install(TARGETS konsoleprivate ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP) set(konsole_KDEINIT_SRCS Application.cpp MainWindow.cpp main.cpp settings/FileLocationSettings.cpp settings/GeneralSettings.cpp settings/ProfileSettings.cpp settings/TabBarSettings.cpp) # Sets the icon on Windows and OSX file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/*.png") ecm_add_app_icon(kdeinit_konsole ICONS ${ICONS_SRCS}) kf5_add_kdeinit_executable(konsole ${konsole_KDEINIT_SRCS}) target_link_libraries(kdeinit_konsole konsoleprivate KF5::XmlGui KF5::WindowSystem KF5::Bookmarks KF5::I18n KF5::KIOWidgets KF5::NotifyConfig KF5::Crash ) if(APPLE) set_target_properties(konsole PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.konsole" MACOSX_BUNDLE_BUNDLE_NAME "Konsole" MACOSX_BUNDLE_DISPLAY_NAME "Konsole" MACOSX_BUNDLE_INFO_STRING "Konsole, the KDE terminal emulator" MACOSX_BUNDLE_LONG_VERSION_STRING "Konsole ${KDE_APPLICATIONS_VERSION}" MACOSX_BUNDLE_SHORT_VERSION_STRING "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}" MACOSX_BUNDLE_BUNDLE_VERSION "${KDE_APPLICATIONS_VERSION}" MACOSX_BUNDLE_COPYRIGHT "1997-2016 The Konsole Developers") endif() install(TARGETS kdeinit_konsole konsole ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) ### Embedded Konsole KPart set(konsolepart_PART_SRCS Part.cpp settings/PartInfo.cpp settings/ProfileSettings.cpp) add_library(konsolepart MODULE ${konsolepart_PART_SRCS}) generate_export_header(konsolepart BASE_NAME konsole) kcoreaddons_desktop_to_json(konsolepart ../desktop/konsolepart.desktop) set_target_properties(konsolepart PROPERTIES DEFINE_SYMBOL KONSOLE_PART) target_link_libraries(konsolepart KF5::Parts KF5::XmlGui konsoleprivate) install(TARGETS konsolepart DESTINATION ${KDE_INSTALL_PLUGINDIR}) ### konsoleprofile command-line tool install(PROGRAMS konsoleprofile DESTINATION ${KDE_INSTALL_BINDIR}) diff --git a/src/DetachableTabBar.cpp b/src/DetachableTabBar.cpp new file mode 100644 index 00000000..d747228c --- /dev/null +++ b/src/DetachableTabBar.cpp @@ -0,0 +1,17 @@ +#include "DetachableTabBar.h" +#include + +DetachableTabBar::DetachableTabBar(QWidget *parent) : QTabBar(parent){} + +void DetachableTabBar::mouseMoveEvent(QMouseEvent *event) +{ + QTabBar::mouseMoveEvent(event); +} + +void DetachableTabBar::mouseReleaseEvent(QMouseEvent *event) +{ + QTabBar::mouseReleaseEvent(event); + if (!contentsRect().contains(event->pos())) { + emit detachTab(currentIndex()); + } +} diff --git a/src/DetachableTabBar.h b/src/DetachableTabBar.h new file mode 100644 index 00000000..1b55f5ba --- /dev/null +++ b/src/DetachableTabBar.h @@ -0,0 +1,17 @@ +#ifndef DETACHABLETABBAR_H +#define DETACHABLETABBAR_H + +#include + +class DetachableTabBar : public QTabBar { + Q_OBJECT +public: + DetachableTabBar(QWidget *parent = nullptr); +Q_SIGNALS: + void detachTab(int idx); +protected: + void mouseMoveEvent(QMouseEvent*event) override; + void mouseReleaseEvent(QMouseEvent *event) override; +}; + +#endif diff --git a/src/ViewContainer.cpp b/src/ViewContainer.cpp index b412386c..0b7ebd86 100644 --- a/src/ViewContainer.cpp +++ b/src/ViewContainer.cpp @@ -1,397 +1,404 @@ /* This file is part of the Konsole Terminal. Copyright 2006-2008 Robert Knight This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Own #include "ViewContainer.h" #include // Qt #include #include #include #include +#include // KDE #include #include #include #include // Konsole #include "IncrementalSearchBar.h" #include "ViewProperties.h" #include "ProfileList.h" #include "ViewManager.h" #include "KonsoleSettings.h" #include "SessionController.h" +#include "DetachableTabBar.h" // TODO Perhaps move everything which is Konsole-specific into different files using namespace Konsole; + TabbedViewContainer::TabbedViewContainer(ViewManager *connectedViewManager, QWidget *parent) : QTabWidget(parent), _connectedViewManager(connectedViewManager), _newTabButton(new QToolButton()) { + auto tabBarWidget = new DetachableTabBar(); + setTabBar(tabBarWidget); setDocumentMode(true); setMovable(true); tabBar()->setContextMenuPolicy(Qt::CustomContextMenu); _newTabButton->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); _newTabButton->setAutoRaise(true); connect(_newTabButton, &QToolButton::clicked, this, [this]{ emit newViewRequest(); }); connect(tabBar(), &QTabBar::tabCloseRequested, this, &TabbedViewContainer::closeTerminalTab); - connect(tabBar(), &QTabBar::tabBarDoubleClicked, this, &Konsole::TabbedViewContainer::tabDoubleClicked); connect(tabBar(), &QTabBar::customContextMenuRequested, this, &Konsole::TabbedViewContainer::openTabContextMenu); + connect(tabBarWidget, &DetachableTabBar::detachTab, this, [this](int idx) { + qDebug() << "Trying to detach this"; + }); connect(this, &TabbedViewContainer::currentChanged, this, [this](int index) { if (index != -1) { widget(index)->setFocus(); } }); // The context menu of tab bar _contextPopupMenu = new QMenu(tabBar()); connect(_contextPopupMenu, &QMenu::aboutToHide, this, [this]() { // Remove the read-only action when the popup closes for (auto &action : _contextPopupMenu->actions()) { if (action->objectName() == QStringLiteral("view-readonly")) { _contextPopupMenu->removeAction(action); break; } } }); auto detachAction = _contextPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("tab-detach")), i18nc("@action:inmenu", "&Detach Tab"), this, SLOT(tabContextMenuDetachTab())); detachAction->setObjectName(QStringLiteral("tab-detach")); auto editAction = _contextPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18nc("@action:inmenu", "&Rename Tab..."), this, SLOT(tabContextMenuRenameTab())); editAction->setObjectName(QStringLiteral("edit-rename")); auto profileMenu = new QMenu(); auto profileList = new ProfileList(false, profileMenu); profileList->syncWidgetActions(profileMenu, true); connect(profileList, &Konsole::ProfileList::profileSelected, this, static_cast(&Konsole::TabbedViewContainer::newViewRequest)); // setNewViewMenu(profileMenu); konsoleConfigChanged(); connect(KonsoleSettings::self(), &KonsoleSettings::configChanged, this, &TabbedViewContainer::konsoleConfigChanged); } TabbedViewContainer::~TabbedViewContainer() { for(int i = 0, end = count(); i < end; i++) { auto view = widget(i); disconnect(view, &QWidget::destroyed, this, &Konsole::TabbedViewContainer::viewDestroyed); } emit destroyed(this); } void TabbedViewContainer::konsoleConfigChanged() { setTabBarAutoHide((bool) KonsoleSettings::tabBarVisibility()); setTabPosition((QTabWidget::TabPosition) KonsoleSettings::tabBarPosition()); setTabsClosable(KonsoleSettings::showQuickButtons()); setCornerWidget( KonsoleSettings::showQuickButtons() ? _newTabButton : nullptr, Qt::TopLeftCorner); if (KonsoleSettings::tabBarUseUserStyleSheet()) { setCssFromFile(KonsoleSettings::tabBarUserStyleSheetFile()); } } void TabbedViewContainer::setCssFromFile(const QUrl &url) { // Let's only deal w/ local files for now if (!url.isLocalFile()) { setStyleSheet(KonsoleSettings::tabBarStyleSheet()); } QFile file(url.toLocalFile()); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { setStyleSheet(KonsoleSettings::tabBarStyleSheet()); } QString styleSheetText; QTextStream in(&file); while (!in.atEnd()) { styleSheetText.append(in.readLine()); } setStyleSheet(styleSheetText); } void TabbedViewContainer::moveActiveView(MoveDirection direction) { const int currentIndex = indexOf(currentWidget()); int newIndex = direction == MoveViewLeft ? qMax(currentIndex - 1, 0) : qMin(currentIndex + 1, count() - 1); auto swappedWidget = widget(newIndex); auto currentWidget = widget(currentIndex); auto swappedContext = _navigation[swappedWidget]; auto currentContext = _navigation[currentWidget]; if (newIndex < currentIndex) { insertTab(newIndex, currentWidget, currentContext->icon(), currentContext->title()); insertTab(currentIndex, swappedWidget, swappedContext->icon(), swappedContext->title()); } else { insertTab(currentIndex, swappedWidget, swappedContext->icon(), swappedContext->title()); insertTab(newIndex, currentWidget, currentContext->icon(), currentContext->title()); } setCurrentIndex(newIndex); } void TabbedViewContainer::addView(QWidget *view, ViewProperties *item, int index) { if (index == -1) { addTab(view, item->icon(), item->title()); } else { insertTab(index, view, item->icon(), item->title()); } _navigation[view] = item; connect(item, &Konsole::ViewProperties::titleChanged, this, &Konsole::TabbedViewContainer::updateTitle); connect(item, &Konsole::ViewProperties::iconChanged, this, &Konsole::TabbedViewContainer::updateIcon); connect(item, &Konsole::ViewProperties::activity, this, &Konsole::TabbedViewContainer::updateActivity); connect(view, &QWidget::destroyed, this, &Konsole::TabbedViewContainer::viewDestroyed); emit viewAdded(view, item); } void TabbedViewContainer::viewDestroyed(QObject *view) { auto widget = static_cast(view); const auto idx = indexOf(widget); removeTab(idx); forgetView(widget); } void TabbedViewContainer::forgetView(QWidget *view) { _navigation.remove(view); emit viewRemoved(view); if (count() == 0) { emit empty(this); } } void TabbedViewContainer::removeView(QWidget *view) { const int idx = indexOf(view); disconnect(view, &QWidget::destroyed, this, &Konsole::TabbedViewContainer::viewDestroyed); removeTab(idx); forgetView(view); } void TabbedViewContainer::activateNextView() { QWidget *active = currentWidget(); int index = indexOf(active); setCurrentIndex(index == count() - 1 ? 0 : index + 1); } void TabbedViewContainer::activateLastView() { setCurrentIndex(count() - 1); } void TabbedViewContainer::activatePreviousView() { QWidget *active = currentWidget(); int index = indexOf(active); setCurrentIndex(index == 0 ? count() - 1 : index - 1); } ViewProperties *TabbedViewContainer::viewProperties(QWidget *view) const { Q_ASSERT(_navigation.contains(view)); return _navigation[view]; } QList TabbedViewContainer::widgetsForItem(ViewProperties *item) const { return _navigation.keys(item); } void TabbedViewContainer::closeCurrentTab() { if (currentIndex() != -1) { closeTerminalTab(currentIndex()); } } void TabbedViewContainer::tabDoubleClicked(int index) { if (index >= 0) { renameTab(index); } else { emit newViewRequest(); } } void TabbedViewContainer::renameTab(int index) { if (index != -1) { _navigation[widget(index)]->rename(); } } void TabbedViewContainer::openTabContextMenu(const QPoint &point) { if (point.isNull()) { return; } const int contextMenuTabIndex = tabBar()->tabAt(point); if (contextMenuTabIndex < 0) { return; } //TODO: add a countChanged signal so we can remove this for. // Detaching in mac causes crashes. const auto isDarwin = QOperatingSystemVersion::currentType() == QOperatingSystemVersion::MacOS; for(auto action : _contextPopupMenu->actions()) { if (action->objectName() == QStringLiteral("tab-detach")) { action->setEnabled( !isDarwin && count() > 1); } } // Add the read-only action auto controller = _navigation[widget(contextMenuTabIndex)]; auto sessionController = qobject_cast(controller); if (sessionController != nullptr) { auto collection = sessionController->actionCollection(); auto readonlyAction = collection->action(QStringLiteral("view-readonly")); if (readonlyAction != nullptr) { const auto readonlyActions = _contextPopupMenu->actions(); _contextPopupMenu->insertAction(readonlyActions.last(), readonlyAction); } // Disable tab rename for (auto &action : _contextPopupMenu->actions()) { if (action->objectName() == QStringLiteral("edit-rename")) { action->setEnabled(!sessionController->isReadOnly()); break; } } } _contextPopupMenu->exec(tabBar()->mapToGlobal(point)); } void TabbedViewContainer::currentTabChanged(int index) { setCurrentIndex(index); if (widget(index) != nullptr) { emit activeViewChanged(widget(index)); } // clear activity indicators setTabActivity(index, false); } void TabbedViewContainer::wheelScrolled(int delta) { if (delta < 0) { activateNextView(); } else { activatePreviousView(); } } void TabbedViewContainer::setTabActivity(int index, bool activity) { const QPalette &palette = tabBar()->palette(); KColorScheme colorScheme(palette.currentColorGroup()); const QColor colorSchemeActive = colorScheme.foreground(KColorScheme::ActiveText).color(); const QColor normalColor = palette.text().color(); const QColor activityColor = KColorUtils::mix(normalColor, colorSchemeActive); QColor color = activity ? activityColor : QColor(); if (color != tabBar()->tabTextColor(index)) { tabBar()->setTabTextColor(index, color); } } void TabbedViewContainer::updateActivity(ViewProperties *item) { foreach (QWidget *widget, widgetsForItem(item)) { const int index = indexOf(widget); if (index != currentIndex()) { setTabActivity(index, true); } } } void TabbedViewContainer::updateTitle(ViewProperties *item) { foreach (QWidget *widget, widgetsForItem(item)) { const int index = indexOf(widget); QString tabText = item->title(); setTabToolTip(index, tabText); // To avoid having & replaced with _ (shortcut indicator) tabText.replace(QLatin1Char('&'), QLatin1String("&&")); setTabText(index, tabText); } } void TabbedViewContainer::updateIcon(ViewProperties *item) { foreach (QWidget *widget, widgetsForItem(item)) { const int index = indexOf(widget); setTabIcon(index, item->icon()); } } void TabbedViewContainer::closeTerminalTab(int idx) { auto currWidget = widget(idx); auto controller = qobject_cast(_navigation[currWidget]); controller->closeSession(); } ViewManager *TabbedViewContainer::connectedViewManager() { return _connectedViewManager; } diff --git a/src/ViewContainer.h b/src/ViewContainer.h index ba79a131..2dabf7a5 100644 --- a/src/ViewContainer.h +++ b/src/ViewContainer.h @@ -1,200 +1,201 @@ /* This file is part of the Konsole Terminal. Copyright 2006-2008 Robert Knight This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef VIEWCONTAINER_H #define VIEWCONTAINER_H // Qt #include #include #include #include #include +#include // Konsole #include "Profile.h" // Qt class QPoint; class QToolButton; class QMenu; class QDropEvent; namespace Konsole { class IncrementalSearchBar; class ViewProperties; class ViewManager; class TabbedViewContainer; /** * An interface for container widgets which can hold one or more views. * * The container widget typically displays a list of the views which * it has and provides a means of switching between them. * * Subclasses should reimplement the addViewWidget() and removeViewWidget() functions * to actually add or remove view widgets from the container widget, as well * as updating any navigation aids. */ class TabbedViewContainer : public QTabWidget { Q_OBJECT public: /** * Constructs a new view container with the specified parent. * * @param position The initial position of the navigation widget * @param parent The parent object of the container */ TabbedViewContainer(ViewManager *connectedViewManager, QWidget *parent); /** * Called when the ViewContainer is destroyed. When reimplementing this in * subclasses, use object->deleteLater() to delete any widgets or other objects * instead of 'delete object'. */ ~TabbedViewContainer() Q_DECL_OVERRIDE; /** Adds a new view to the container widget */ void addView(QWidget *view, ViewProperties *navigationItem, int index = -1); /** Removes a view from the container */ void removeView(QWidget *view); /** Returns the ViewProperties instance associated with a particular view in the container */ ViewProperties *viewProperties(QWidget *view) const; void setTabActivity(int index, bool activity); void updateTitle(ViewProperties *item); void updateIcon(ViewProperties *item); void updateActivity(ViewProperties *item); /** Changes the active view to the next view */ void activateNextView(); /** Changes the active view to the previous view */ void activatePreviousView(); /** Changes the active view to the last view */ void activateLastView(); void setCssFromFile(const QUrl& url); /** * This enum describes the directions * in which views can be re-arranged within the container * using the moveActiveView() method. */ enum MoveDirection { /** Moves the view to the left. */ MoveViewLeft, /** Moves the view to the right. */ MoveViewRight }; /** * Moves the active view within the container and * updates the order in which the views are shown * in the container's navigation widget. * * The default implementation does nothing. */ void moveActiveView(MoveDirection direction); /** Sets the menu to be shown when the new view button is clicked. * Only valid if the QuickNewView feature is enabled. * The default implementation does nothing. */ // TODO: Reenable this later. // void setNewViewMenu(QMenu *menu); void renameTab(int index); ViewManager *connectedViewManager(); void currentTabChanged(int index); void closeCurrentTab(); void wheelScrolled(int delta); void tabDoubleClicked(int index); void openTabContextMenu(const QPoint &point); Q_SIGNALS: /** Emitted when the container has no more children */ void empty(TabbedViewContainer *container); /** Emitted when the user requests to open a new view */ void newViewRequest(); /** Requests creation of a new view, with the selected profile. */ void newViewRequest(Profile::Ptr); /** * Emitted when the user requests to move a view from another container * into this container. If 'success' is set to true by a connected slot * then the original view will be removed. * * @param index Index at which to insert the new view in the container or -1 * to append it. This index should be passed to addView() when the new view * has been created. * @param id The identifier of the view. * @param success The slot handling this signal should set this to true if the * new view was successfully created. * @param sourceContainer Initial move event Tabbed view container. */ void moveViewRequest(int index, int id, bool &success, TabbedViewContainer *sourceContainer); /** Emitted when the active view changes */ void activeViewChanged(QWidget *view); /** Emitted when a view is added to the container. */ void viewAdded(QWidget *view, ViewProperties *properties); /** Emitted when a view is removed from the container. */ void viewRemoved(QWidget *view); protected: /** Returns the widgets which are associated with a particular navigation item */ QList widgetsForItem(ViewProperties *item) const; /** * Rearranges the order of widgets in the container. * * @param fromIndex Current index of the widget to move * @param toIndex New index for the widget */ void moveViewWidget(int fromIndex, int toIndex); // close tabs and unregister void closeTerminalTab(int index); private Q_SLOTS: void viewDestroyed(QObject *view); void konsoleConfigChanged(); private: void forgetView(QWidget *view); QHash _navigation; ViewManager *_connectedViewManager; QMenu *_contextPopupMenu; QToolButton *_newTabButton; }; } #endif //VIEWCONTAINER_H