Changeset View
Changeset View
Standalone View
Standalone View
src/DetachableTabBar.cpp
Show All 12 Lines | 1 | /* | |||
---|---|---|---|---|---|
13 | 13 | | |||
14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
17 | 02110-1301 USA. | 17 | 02110-1301 USA. | ||
18 | */ | 18 | */ | ||
19 | 19 | | |||
20 | #include "DetachableTabBar.h" | 20 | #include "DetachableTabBar.h" | ||
21 | #include "ViewContainer.h" | ||||
22 | | ||||
21 | #include <QMouseEvent> | 23 | #include <QMouseEvent> | ||
24 | #include <QApplication> | ||||
25 | | ||||
26 | namespace Konsole { | ||||
22 | 27 | | |||
23 | DetachableTabBar::DetachableTabBar(QWidget *parent) : | 28 | DetachableTabBar::DetachableTabBar(QWidget *parent) : | ||
24 | QTabBar(parent), | 29 | QTabBar(parent), | ||
25 | _draggingOutside(false) {} | 30 | dragType(DragType::NONE), | ||
31 | _originalCursor(cursor()) | ||||
32 | {} | ||||
33 | | ||||
34 | bool DetachableTabBar::droppedContainerIsNotThis(const QPoint& currentPos) const | ||||
35 | { | ||||
36 | for(const auto dropWidget : _containers) { | ||||
37 | if (dropWidget->rect().contains(dropWidget->mapFromGlobal(currentPos))) { | ||||
38 | if (dropWidget != parent()) { | ||||
39 | return true; | ||||
40 | } | ||||
41 | } | ||||
42 | } | ||||
43 | return false; | ||||
44 | } | ||||
45 | | ||||
46 | void DetachableTabBar::mousePressEvent(QMouseEvent *event) | ||||
47 | { | ||||
48 | QTabBar::mousePressEvent(event); | ||||
49 | _containers = window()->findChildren<Konsole::TabbedViewContainer*>(); | ||||
50 | } | ||||
26 | 51 | | |||
27 | void DetachableTabBar::mouseMoveEvent(QMouseEvent *event) | 52 | void DetachableTabBar::mouseMoveEvent(QMouseEvent *event) | ||
28 | { | 53 | { | ||
29 | QTabBar::mouseMoveEvent(event); | 54 | QTabBar::mouseMoveEvent(event); | ||
30 | if (!contentsRect().adjusted(-30,-30,30,30).contains(event->pos())) { | 55 | auto widgetAtPos = qApp->topLevelAt(event->globalPos()); | ||
31 | if (!_draggingOutside) { | 56 | if (widgetAtPos){ | ||
32 | _draggingOutside = true; | 57 | if (window() == widgetAtPos->window()) { | ||
33 | _originalCursor = cursor(); | 58 | if (droppedContainerIsNotThis(event->globalPos())) { | ||
34 | setCursor(QCursor(Qt::DragCopyCursor)); | 59 | if (dragType != DragType::WINDOW) { | ||
60 | dragType = DragType::WINDOW; | ||||
61 | setCursor(QCursor(Qt::DragMoveCursor)); | ||||
35 | } | 62 | } | ||
36 | } else if (_draggingOutside) { | 63 | } else { | ||
37 | _draggingOutside = false; | 64 | if (dragType != DragType::NONE) { | ||
65 | dragType = DragType::NONE; | ||||
38 | setCursor(_originalCursor); | 66 | setCursor(_originalCursor); | ||
39 | } | 67 | } | ||
40 | } | 68 | } | ||
69 | } else { | ||||
70 | if (dragType != DragType::WINDOW) { | ||||
71 | dragType = DragType::WINDOW; | ||||
72 | setCursor(QCursor(Qt::DragMoveCursor)); | ||||
73 | } | ||||
74 | } | ||||
75 | } else if (!contentsRect().adjusted(-30,-30,30,30).contains(event->pos())) { | ||||
76 | // Don't let it detach the last tab. | ||||
77 | if (count() == 1) | ||||
78 | return; | ||||
79 | if (dragType != DragType::OUTSIDE) { | ||||
80 | dragType = DragType::OUTSIDE; | ||||
81 | setCursor(QCursor(Qt::DragCopyCursor)); | ||||
82 | } | ||||
83 | } | ||||
84 | } | ||||
41 | 85 | | |||
42 | void DetachableTabBar::mouseReleaseEvent(QMouseEvent *event) | 86 | void DetachableTabBar::mouseReleaseEvent(QMouseEvent *event) | ||
43 | { | 87 | { | ||
44 | QTabBar::mouseReleaseEvent(event); | 88 | QTabBar::mouseReleaseEvent(event); | ||
45 | if (!contentsRect().adjusted(-30,-30,30,30).contains(event->pos())) { | | |||
46 | setCursor(_originalCursor); | 89 | setCursor(_originalCursor); | ||
90 | | ||||
91 | if (contentsRect().adjusted(-30,-30,30,30).contains(event->pos())) { | ||||
92 | return; | ||||
93 | } | ||||
94 | | ||||
95 | auto widgetAtPos = qApp->topLevelAt(event->globalPos()); | ||||
96 | if (!widgetAtPos) { | ||||
97 | if (count() != 1) | ||||
47 | emit detachTab(currentIndex()); | 98 | emit detachTab(currentIndex()); | ||
99 | } else if (window() != widgetAtPos->window()) { | ||||
100 | // splits have a tendency to break, forbid to detach if splitted and it's the last tab. | ||||
101 | if (_containers.size() == 1 || count() > 1) | ||||
102 | emit moveTabToWindow(currentIndex(), widgetAtPos); | ||||
103 | } else if (droppedContainerIsNotThis(event->globalPos())){ | ||||
104 | if (count() != 1) | ||||
105 | emit moveTabToWindow(currentIndex(), widgetAtPos); | ||||
48 | } | 106 | } | ||
49 | } | 107 | } | ||
108 | | ||||
109 | } |