]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphintabbar.cpp
4c918e6114db4625c57b402fa9585fea14bf4b3f
[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 class PreventFocusWhileHidden : public QObject
17 {
18 public:
19 PreventFocusWhileHidden(QObject *parent)
20 : QObject(parent){};
21
22 protected:
23 bool eventFilter(QObject *obj, QEvent *ev) override
24 {
25 switch (ev->type()) {
26 case QEvent::Hide:
27 static_cast<QWidget *>(obj)->setFocusPolicy(Qt::NoFocus);
28 return false;
29 case QEvent::Show:
30 static_cast<QWidget *>(obj)->setFocusPolicy(Qt::TabFocus);
31 return false;
32 default:
33 return false;
34 }
35 };
36 };
37
38 DolphinTabBar::DolphinTabBar(QWidget *parent)
39 : QTabBar(parent)
40 , m_autoActivationIndex(-1)
41 , m_tabToBeClosedOnMiddleMouseButtonRelease(-1)
42 {
43 setAcceptDrops(true);
44 setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
45 setMovable(true);
46 setTabsClosable(true);
47
48 setFocusPolicy(Qt::NoFocus);
49 installEventFilter(new PreventFocusWhileHidden(this));
50
51 m_autoActivationTimer = new QTimer(this);
52 m_autoActivationTimer->setSingleShot(true);
53 m_autoActivationTimer->setInterval(800);
54 connect(m_autoActivationTimer, &QTimer::timeout, this, &DolphinTabBar::slotAutoActivationTimeout);
55 }
56
57 void DolphinTabBar::dragEnterEvent(QDragEnterEvent *event)
58 {
59 const QMimeData *mimeData = event->mimeData();
60 const int index = tabAt(event->position().toPoint());
61
62 if (mimeData->hasUrls()) {
63 event->acceptProposedAction();
64 updateAutoActivationTimer(index);
65 }
66
67 QTabBar::dragEnterEvent(event);
68 }
69
70 void DolphinTabBar::dragLeaveEvent(QDragLeaveEvent *event)
71 {
72 updateAutoActivationTimer(-1);
73
74 QTabBar::dragLeaveEvent(event);
75 }
76
77 void DolphinTabBar::dragMoveEvent(QDragMoveEvent *event)
78 {
79 const QMimeData *mimeData = event->mimeData();
80 const int index = tabAt(event->position().toPoint());
81
82 if (mimeData->hasUrls()) {
83 updateAutoActivationTimer(index);
84 }
85
86 QTabBar::dragMoveEvent(event);
87 }
88
89 void DolphinTabBar::dropEvent(QDropEvent *event)
90 {
91 // Disable the auto activation timer
92 updateAutoActivationTimer(-1);
93
94 const QMimeData *mimeData = event->mimeData();
95 const int index = tabAt(event->position().toPoint());
96
97 if (mimeData->hasUrls()) {
98 Q_EMIT tabDropEvent(index, event);
99 }
100
101 QTabBar::dropEvent(event);
102 }
103
104 void DolphinTabBar::mousePressEvent(QMouseEvent *event)
105 {
106 const int index = tabAt(event->pos());
107
108 if (index >= 0 && event->button() == Qt::MiddleButton) {
109 m_tabToBeClosedOnMiddleMouseButtonRelease = index;
110 return;
111 }
112
113 QTabBar::mousePressEvent(event);
114 }
115
116 void DolphinTabBar::mouseReleaseEvent(QMouseEvent *event)
117 {
118 const int index = tabAt(event->pos());
119
120 if (index >= 0 && index == m_tabToBeClosedOnMiddleMouseButtonRelease && event->button() == Qt::MiddleButton) {
121 // Mouse middle click on a tab closes this tab.
122 Q_EMIT tabCloseRequested(index);
123 return;
124 }
125
126 QTabBar::mouseReleaseEvent(event);
127 }
128
129 void DolphinTabBar::mouseDoubleClickEvent(QMouseEvent *event)
130 {
131 if (event->buttons() & Qt::LeftButton) {
132 int index = tabAt(event->pos());
133
134 if (index < 0) {
135 // empty tabbar area case
136 index = currentIndex();
137 }
138 // Double left click on the tabbar opens a new activated tab
139 // with the url from the doubleclicked tab or currentTab otherwise.
140 Q_EMIT openNewActivatedTab(index);
141 }
142
143 QTabBar::mouseDoubleClickEvent(event);
144 }
145
146 void DolphinTabBar::contextMenuEvent(QContextMenuEvent *event)
147 {
148 const int index = tabAt(event->pos());
149
150 if (index >= 0) {
151 // Tab context menu
152 QMenu menu(this);
153
154 QAction *newTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@action:inmenu", "New Tab"));
155 QAction *detachTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-detach")), i18nc("@action:inmenu", "Detach Tab"));
156 QAction *closeOtherTabsAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-close-other")), i18nc("@action:inmenu", "Close Other Tabs"));
157 QAction *closeTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-close")), i18nc("@action:inmenu", "Close Tab"));
158
159 QAction *selectedAction = menu.exec(event->globalPos());
160 if (selectedAction == newTabAction) {
161 Q_EMIT openNewActivatedTab(index);
162 } else if (selectedAction == detachTabAction) {
163 Q_EMIT tabDetachRequested(index);
164 } else if (selectedAction == closeOtherTabsAction) {
165 const int tabCount = count();
166 for (int i = 0; i < index; i++) {
167 Q_EMIT tabCloseRequested(0);
168 }
169 for (int i = index + 1; i < tabCount; i++) {
170 Q_EMIT tabCloseRequested(1);
171 }
172 } else if (selectedAction == closeTabAction) {
173 Q_EMIT tabCloseRequested(index);
174 }
175
176 return;
177 }
178
179 QTabBar::contextMenuEvent(event);
180 }
181
182 void DolphinTabBar::slotAutoActivationTimeout()
183 {
184 if (m_autoActivationIndex >= 0) {
185 setCurrentIndex(m_autoActivationIndex);
186 updateAutoActivationTimer(-1);
187 }
188 }
189
190 void DolphinTabBar::updateAutoActivationTimer(const int index)
191 {
192 if (m_autoActivationIndex != index) {
193 m_autoActivationIndex = index;
194
195 if (m_autoActivationIndex < 0) {
196 m_autoActivationTimer->stop();
197 } else {
198 m_autoActivationTimer->start();
199 }
200 }
201 }
202
203 #include "moc_dolphintabbar.cpp"