]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphintabbar.cpp
[Tab Bar] Accept proposed action only ontop of a tab
[dolphin.git] / src / dolphintabbar.cpp
1 /*
2 * SPDX-FileCopyrightText: 2014 Emmanuel Pescosta <emmanuelpescosta099@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "dolphintabbar.h"
8
9 #include <KLocalizedString>
10
11 #include <QDragEnterEvent>
12 #include <QMenu>
13 #include <QMimeData>
14 #include <QTimer>
15
16 DolphinTabBar::DolphinTabBar(QWidget* parent) :
17 QTabBar(parent),
18 m_autoActivationIndex(-1),
19 m_tabToBeClosedOnMiddleMouseButtonRelease(-1)
20 {
21 setAcceptDrops(true);
22 setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
23 setMovable(true);
24 setTabsClosable(true);
25
26 m_autoActivationTimer = new QTimer(this);
27 m_autoActivationTimer->setSingleShot(true);
28 m_autoActivationTimer->setInterval(800);
29 connect(m_autoActivationTimer, &QTimer::timeout,
30 this, &DolphinTabBar::slotAutoActivationTimeout);
31 }
32
33 void DolphinTabBar::dragEnterEvent(QDragEnterEvent* event)
34 {
35 const QMimeData* mimeData = event->mimeData();
36 const int index = tabAt(event->pos());
37
38 if (mimeData->hasUrls()) {
39 if (index >= 0) {
40 event->acceptProposedAction();
41 } else {
42 event->setDropAction(Qt::IgnoreAction);
43 // Still need to accept it to receive dragMoveEvent
44 event->accept();
45 }
46 updateAutoActivationTimer(index);
47 }
48
49 QTabBar::dragEnterEvent(event);
50 }
51
52 void DolphinTabBar::dragLeaveEvent(QDragLeaveEvent* event)
53 {
54 updateAutoActivationTimer(-1);
55
56 QTabBar::dragLeaveEvent(event);
57 }
58
59 void DolphinTabBar::dragMoveEvent(QDragMoveEvent* event)
60 {
61 const QMimeData* mimeData = event->mimeData();
62 const int index = tabAt(event->pos());
63
64 if (mimeData->hasUrls()) {
65 if (index >= 0) {
66 event->acceptProposedAction();
67 } else {
68 event->setDropAction(Qt::IgnoreAction);
69 }
70 updateAutoActivationTimer(index);
71 }
72
73 QTabBar::dragMoveEvent(event);
74 }
75
76 void DolphinTabBar::dropEvent(QDropEvent* event)
77 {
78 // Disable the auto activation timer
79 updateAutoActivationTimer(-1);
80
81 const QMimeData* mimeData = event->mimeData();
82 const int index = tabAt(event->pos());
83
84 if (index >= 0 && mimeData->hasUrls()) {
85 Q_EMIT tabDropEvent(index, event);
86 }
87
88 QTabBar::dropEvent(event);
89 }
90
91 void DolphinTabBar::mousePressEvent(QMouseEvent* event)
92 {
93 const int index = tabAt(event->pos());
94
95 if (index >= 0 && event->button() == Qt::MiddleButton) {
96 m_tabToBeClosedOnMiddleMouseButtonRelease = index;
97 return;
98 }
99
100 QTabBar::mousePressEvent(event);
101 }
102
103 void DolphinTabBar::mouseReleaseEvent(QMouseEvent *event)
104 {
105 const int index = tabAt(event->pos());
106
107 if (index >= 0 && index == m_tabToBeClosedOnMiddleMouseButtonRelease
108 && event->button() == Qt::MiddleButton) {
109 // Mouse middle click on a tab closes this tab.
110 Q_EMIT tabCloseRequested(index);
111 return;
112 }
113
114 QTabBar::mouseReleaseEvent(event);
115 }
116
117 void DolphinTabBar::mouseDoubleClickEvent(QMouseEvent* event)
118 {
119 const int index = tabAt(event->pos());
120
121 if (index < 0) {
122 // Double click on the empty tabbar area opens a new activated tab
123 // with the url from the current tab.
124 Q_EMIT openNewActivatedTab(currentIndex());
125 return;
126 }
127
128 QTabBar::mouseDoubleClickEvent(event);
129 }
130
131 void DolphinTabBar::contextMenuEvent(QContextMenuEvent* event)
132 {
133 const int index = tabAt(event->pos());
134
135 if (index >= 0) {
136 // Tab context menu
137 QMenu menu(this);
138
139 QAction* newTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@action:inmenu", "New Tab"));
140 QAction* detachTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-detach")), i18nc("@action:inmenu", "Detach Tab"));
141 QAction* closeOtherTabsAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-close-other")), i18nc("@action:inmenu", "Close Other Tabs"));
142 QAction* closeTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-close")), i18nc("@action:inmenu", "Close Tab"));
143
144 QAction* selectedAction = menu.exec(event->globalPos());
145 if (selectedAction == newTabAction) {
146 Q_EMIT openNewActivatedTab(index);
147 } else if (selectedAction == detachTabAction) {
148 Q_EMIT tabDetachRequested(index);
149 } else if (selectedAction == closeOtherTabsAction) {
150 const int tabCount = count();
151 for (int i = 0; i < index; i++) {
152 Q_EMIT tabCloseRequested(0);
153 }
154 for (int i = index + 1; i < tabCount; i++) {
155 Q_EMIT tabCloseRequested(1);
156 }
157 } else if (selectedAction == closeTabAction) {
158 Q_EMIT tabCloseRequested(index);
159 }
160
161 return;
162 }
163
164 QTabBar::contextMenuEvent(event);
165 }
166
167 void DolphinTabBar::slotAutoActivationTimeout()
168 {
169 if (m_autoActivationIndex >= 0) {
170 setCurrentIndex(m_autoActivationIndex);
171 updateAutoActivationTimer(-1);
172 }
173 }
174
175 void DolphinTabBar::updateAutoActivationTimer(const int index)
176 {
177 if (m_autoActivationIndex != index) {
178 m_autoActivationIndex = index;
179
180 if (m_autoActivationIndex < 0) {
181 m_autoActivationTimer->stop();
182 } else {
183 m_autoActivationTimer->start();
184 }
185 }
186 }