Commit 194a852d authored by Francesco Cecconi's avatar Francesco Cecconi

Prevent the dragging of the last tab in a split view.

BUG: 210871
REVIEW: 107640
FIXED-IN: 4.12
parent ab5e15b1
......@@ -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<QWidget*> 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)
{
......
......@@ -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<QStackedWidget> _stackWidget;
QPointer<QWidget> _containerWidget;
ViewManager* _connectedViewManager;
QVBoxLayout* _layout;
QHBoxLayout* _tabBarLayout;
QToolButton* _newTabButton;
......
......@@ -21,6 +21,7 @@
// Own
#include "ViewContainerTabBar.h"
#include "ViewContainer.h"
// Qt
#include <QtCore/QMimeData>
......@@ -33,12 +34,14 @@
#include <KIcon>
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<ViewContainerTabBar*>(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)
......
......@@ -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;
};
}
......
......@@ -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<ViewContainer*>(sender());
SessionController* controller = qobject_cast<SessionController*>(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<ViewContainer> sourceContainer = qobject_cast<ViewContainer*>(sourceTabbedContainer);
if (_viewSplitter->containers().contains(sourceContainer)) {
return;
} else {
ViewManager* sourceViewManager = sourceTabbedContainer->connectedViewManager();
// do not remove the last tab on the window
if (qobject_cast<ViewSplitter*>(sourceViewManager->widget())->containers().size() > 1) {
return;
}
}
}
createView(controller->session(), container, index);
controller->session()->refresh();
moved = true;
}
void ViewManager::setNavigationMethod(NavigationMethod method)
{
_navigationMethod = method;
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment