diff --git a/src/ViewContainer.cpp b/src/ViewContainer.cpp index 63c187dd6..a6dd49040 100644 --- a/src/ViewContainer.cpp +++ b/src/ViewContainer.cpp @@ -43,6 +43,7 @@ #include "ViewProperties.h" #include "ViewContainerTabBar.h" #include "ProfileList.h" +#include "ViewManager.h" // TODO Perhaps move everything which is Konsole-specific into different files @@ -254,15 +255,16 @@ QList ViewContainer::widgetsForItem(ViewProperties* item) const return _navigation.keys(item); } -TabbedViewContainer::TabbedViewContainer(NavigationPosition position , QObject* parent) +TabbedViewContainer::TabbedViewContainer(NavigationPosition position, ViewManager* connectedViewManager, QObject* parent) : ViewContainer(position, parent) + , _connectedViewManager(connectedViewManager) , _contextMenuTabIndex(0) { _containerWidget = new QWidget; _stackWidget = new QStackedWidget(); // The tab bar - _tabBar = new ViewContainerTabBar(_containerWidget); + _tabBar = new ViewContainerTabBar(_containerWidget, this); _tabBar->setSupportedMimeType(ViewProperties::mimeType()); connect(_tabBar, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int))); @@ -272,8 +274,8 @@ TabbedViewContainer::TabbedViewContainer(NavigationPosition position , QObject* connect(_tabBar, SIGNAL(initiateDrag(int)), this, SLOT(startTabDrag(int))); connect(_tabBar, SIGNAL(querySourceIndex(const QDropEvent*,int&)), this, SLOT(querySourceIndex(const QDropEvent*,int&))); - connect(_tabBar, SIGNAL(moveViewRequest(int,const QDropEvent*,bool&)), - this, SLOT(onMoveViewRequest(int,const QDropEvent*,bool&))); + connect(_tabBar, SIGNAL(moveViewRequest(int,const QDropEvent*,bool&,TabbedViewContainer*)), + this, SLOT(onMoveViewRequest(int,const QDropEvent*,bool&,TabbedViewContainer*))); connect(_tabBar, SIGNAL(contextMenu(int,QPoint)), this, SLOT(openTabContextMenu(int,QPoint))); @@ -529,10 +531,10 @@ void TabbedViewContainer::querySourceIndex(const QDropEvent* event, int& sourceI sourceIndex = index; } -void TabbedViewContainer::onMoveViewRequest(int index, const QDropEvent* event, bool& success) +void TabbedViewContainer::onMoveViewRequest(int index, const QDropEvent* event ,bool& success, TabbedViewContainer* sourceTabbedContainer) { const int droppedId = ViewProperties::decodeMimeData(event->mimeData()); - emit moveViewRequest(index, droppedId, success); + emit moveViewRequest(index, droppedId, success, sourceTabbedContainer); } void TabbedViewContainer::tabDoubleClicked(int index) @@ -703,6 +705,11 @@ void TabbedViewContainer::updateIcon(ViewProperties* item) } } +ViewManager* TabbedViewContainer::connectedViewManager() +{ + return _connectedViewManager; +} + StackedViewContainer::StackedViewContainer(QObject* parent) : ViewContainer(NavigationPositionTop, parent) { diff --git a/src/ViewContainer.h b/src/ViewContainer.h index d5bdf736f..60d2bd9ef 100644 --- a/src/ViewContainer.h +++ b/src/ViewContainer.h @@ -50,6 +50,7 @@ namespace Konsole { class IncrementalSearchBar; class ViewProperties; +class TabbedViewContainer; /** * An interface for container widgets which can hold one or more views. * @@ -285,8 +286,9 @@ signals: * @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); + void moveViewRequest(int index, int id, bool& success, TabbedViewContainer* sourceContainer); /** Emitted when the active view changes */ void activeViewChanged(QWidget* view); @@ -350,6 +352,7 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(ViewContainer::Features) class ViewContainerTabBar; +class ViewManager; /** * An alternative tabbed view container which uses a QTabBar and QStackedWidget @@ -364,7 +367,7 @@ public: * Constructs a new tabbed view container. Supported positions * are NavigationPositionTop and NavigationPositionBottom. */ - TabbedViewContainer(NavigationPosition position , QObject* parent); + TabbedViewContainer(NavigationPosition position, ViewManager* connectedViewManager, QObject* parent); virtual ~TabbedViewContainer(); virtual QWidget* containerWidget() const; @@ -376,6 +379,9 @@ public: virtual void setNewViewMenu(QMenu* menu); virtual void setStyleSheet(const QString& styleSheet); + // return associated view manager + ViewManager* connectedViewManager(); + protected: virtual void addViewWidget(QWidget* view , int index); virtual void removeViewWidget(QWidget* view); @@ -399,7 +405,7 @@ private slots: void tabContextMenuDetachTab(); void startTabDrag(int index); void querySourceIndex(const QDropEvent* event, int& sourceIndex); - void onMoveViewRequest(int index, const QDropEvent* event, bool& success); + void onMoveViewRequest(int index, const QDropEvent* event, bool& success, TabbedViewContainer* sourceTabbedContainer); signals: void detachTab(ViewContainer * self, QWidget * activeView); @@ -415,6 +421,7 @@ private: ViewContainerTabBar* _tabBar; QPointer _stackWidget; QPointer _containerWidget; + ViewManager* _connectedViewManager; QVBoxLayout* _layout; QHBoxLayout* _tabBarLayout; QToolButton* _newTabButton; diff --git a/src/ViewContainerTabBar.cpp b/src/ViewContainerTabBar.cpp index c3a9dd131..74b5f758e 100644 --- a/src/ViewContainerTabBar.cpp +++ b/src/ViewContainerTabBar.cpp @@ -21,6 +21,7 @@ // Own #include "ViewContainerTabBar.h" +#include "ViewContainer.h" // Qt #include @@ -33,12 +34,14 @@ #include using Konsole::ViewContainerTabBar; +using Konsole::TabbedViewContainer; -ViewContainerTabBar::ViewContainerTabBar(QWidget* parent) +ViewContainerTabBar::ViewContainerTabBar(QWidget* parent, TabbedViewContainer* container) : KTabBar(parent) , _dropIndicator(0) , _dropIndicatorIndex(-1) , _drawIndicatorDisabled(false) + , _connectedContainer(container) { setDrawBase(true); setDocumentMode(true); @@ -94,7 +97,16 @@ void ViewContainerTabBar::dropEvent(QDropEvent* event) const int index = dropIndex(event->pos()); bool success = false; - emit moveViewRequest(index, event, success); + + ViewContainerTabBar* sourceContainerTabBar = static_cast(event->source()); + + // check if the moved tab is the last of source view. + if (sourceContainerTabBar->count() == 1) { + TabbedViewContainer* sourceTabbedContainer = sourceContainerTabBar->connectedTabbedViewContainer(); + emit moveViewRequest(index, event, success, sourceTabbedContainer); + } else { + emit moveViewRequest(index, event, success, NULL); + } if (success) event->accept(); @@ -102,6 +114,11 @@ void ViewContainerTabBar::dropEvent(QDropEvent* event) event->ignore(); } +TabbedViewContainer* ViewContainerTabBar::connectedTabbedViewContainer() +{ + return _connectedContainer; +} + void ViewContainerTabBar::setDropIndicator(int index, bool drawDisabled) { if (!parentWidget() || _dropIndicatorIndex == index) diff --git a/src/ViewContainerTabBar.h b/src/ViewContainerTabBar.h index 5b97abce2..45a328a7a 100644 --- a/src/ViewContainerTabBar.h +++ b/src/ViewContainerTabBar.h @@ -29,12 +29,14 @@ class QLabel; namespace Konsole { +class TabbedViewContainer; + class ViewContainerTabBar : public KTabBar { Q_OBJECT public: - explicit ViewContainerTabBar(QWidget* parent); + ViewContainerTabBar(QWidget* parent, TabbedViewContainer* container); // returns a pixmap image of a tab for use with QDrag QPixmap dragDropPixmap(int tab); @@ -42,10 +44,12 @@ public: // set the mimetype of which the tabbar support d&d void setSupportedMimeType(const QString& mimeType); + // return associated tabbed container + TabbedViewContainer* connectedTabbedViewContainer(); + signals: void querySourceIndex(const QDropEvent* event, int& sourceIndex) const; - - void moveViewRequest(int index, const QDropEvent* event, bool& success); + void moveViewRequest(int index, const QDropEvent* event, bool& success, TabbedViewContainer* sourceTabbedContainer); protected: virtual void dragEnterEvent(QDragEnterEvent* event); @@ -70,6 +74,7 @@ private: int _dropIndicatorIndex; bool _drawIndicatorDisabled; QString _supportedMimeType; + TabbedViewContainer* _connectedContainer; }; } diff --git a/src/ViewManager.cpp b/src/ViewManager.cpp index 4b9708e4a..f8643aa50 100644 --- a/src/ViewManager.cpp +++ b/src/ViewManager.cpp @@ -600,7 +600,7 @@ ViewContainer* ViewManager::createContainer() switch (_navigationMethod) { case TabbedNavigation: { - container = new TabbedViewContainer(_navigationPosition, _viewSplitter); + container = new TabbedViewContainer(_navigationPosition, this, _viewSplitter); connect(container, SIGNAL(detachTab(ViewContainer*,QWidget*)), this, SLOT(detachView(ViewContainer*,QWidget*)) @@ -637,14 +637,15 @@ ViewContainer* ViewManager::createContainer() connect(container, SIGNAL(newViewRequest()), this, SIGNAL(newViewRequest())); connect(container, SIGNAL(newViewRequest(Profile::Ptr)), this, SIGNAL(newViewRequest(Profile::Ptr))); - connect(container, SIGNAL(moveViewRequest(int,int,bool&)), - this , SLOT(containerMoveViewRequest(int,int,bool&))); + connect(container, SIGNAL(moveViewRequest(int,int,bool&,TabbedViewContainer*)), + this , SLOT(containerMoveViewRequest(int,int,bool&,TabbedViewContainer*))); connect(container , SIGNAL(viewRemoved(QWidget*)) , this , SLOT(viewDestroyed(QWidget*))); connect(container , SIGNAL(activeViewChanged(QWidget*)) , this , SLOT(viewActivated(QWidget*))); return container; } -void ViewManager::containerMoveViewRequest(int index, int id, bool& moved) + +void ViewManager::containerMoveViewRequest(int index, int id, bool& moved, TabbedViewContainer* sourceTabbedContainer) { ViewContainer* container = qobject_cast(sender()); SessionController* controller = qobject_cast(ViewProperties::propertiesById(id)); @@ -652,10 +653,27 @@ void ViewManager::containerMoveViewRequest(int index, int id, bool& moved) if (!controller) return; + // do not move the last tab in a splitted view. + if (sourceTabbedContainer) { + QPointer sourceContainer = qobject_cast(sourceTabbedContainer); + + if (_viewSplitter->containers().contains(sourceContainer)) { + return; + } else { + ViewManager* sourceViewManager = sourceTabbedContainer->connectedViewManager(); + + // do not remove the last tab on the window + if (qobject_cast(sourceViewManager->widget())->containers().size() > 1) { + return; + } + } + } + createView(controller->session(), container, index); controller->session()->refresh(); moved = true; } + void ViewManager::setNavigationMethod(NavigationMethod method) { _navigationMethod = method; diff --git a/src/ViewManager.h b/src/ViewManager.h index f039a27ef..fac28239e 100644 --- a/src/ViewManager.h +++ b/src/ViewManager.h @@ -333,7 +333,7 @@ private slots: // called when a ViewContainer requests a view be // moved - void containerMoveViewRequest(int index, int id, bool& success); + void containerMoveViewRequest(int index, int id, bool& success, TabbedViewContainer* sourceTabbedContainer); void detachView(ViewContainer* container, QWidget* view);