File indexing completed on 2024-03-24 17:22:45
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Emmanuel Pescosta <emmanuelpescosta099@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "dolphintabbar.h" 0008 0009 #include <KLocalizedString> 0010 0011 #include <QDragEnterEvent> 0012 #include <QMenu> 0013 #include <QMimeData> 0014 #include <QTimer> 0015 0016 class PreventFocusWhileHidden : public QObject 0017 { 0018 public: 0019 PreventFocusWhileHidden(QObject *parent) 0020 : QObject(parent){}; 0021 0022 protected: 0023 bool eventFilter(QObject *obj, QEvent *ev) override 0024 { 0025 switch (ev->type()) { 0026 case QEvent::Hide: 0027 static_cast<QWidget *>(obj)->setFocusPolicy(Qt::NoFocus); 0028 return false; 0029 case QEvent::Show: 0030 static_cast<QWidget *>(obj)->setFocusPolicy(Qt::TabFocus); 0031 return false; 0032 default: 0033 return false; 0034 } 0035 }; 0036 }; 0037 0038 DolphinTabBar::DolphinTabBar(QWidget *parent) 0039 : QTabBar(parent) 0040 , m_autoActivationIndex(-1) 0041 , m_tabToBeClosedOnMiddleMouseButtonRelease(-1) 0042 { 0043 setAcceptDrops(true); 0044 setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); 0045 setMovable(true); 0046 setTabsClosable(true); 0047 0048 setFocusPolicy(Qt::NoFocus); 0049 installEventFilter(new PreventFocusWhileHidden(this)); 0050 0051 m_autoActivationTimer = new QTimer(this); 0052 m_autoActivationTimer->setSingleShot(true); 0053 m_autoActivationTimer->setInterval(800); 0054 connect(m_autoActivationTimer, &QTimer::timeout, this, &DolphinTabBar::slotAutoActivationTimeout); 0055 } 0056 0057 void DolphinTabBar::dragEnterEvent(QDragEnterEvent *event) 0058 { 0059 const QMimeData *mimeData = event->mimeData(); 0060 const int index = tabAt(event->position().toPoint()); 0061 0062 if (mimeData->hasUrls()) { 0063 event->acceptProposedAction(); 0064 updateAutoActivationTimer(index); 0065 } 0066 0067 QTabBar::dragEnterEvent(event); 0068 } 0069 0070 void DolphinTabBar::dragLeaveEvent(QDragLeaveEvent *event) 0071 { 0072 updateAutoActivationTimer(-1); 0073 0074 QTabBar::dragLeaveEvent(event); 0075 } 0076 0077 void DolphinTabBar::dragMoveEvent(QDragMoveEvent *event) 0078 { 0079 const QMimeData *mimeData = event->mimeData(); 0080 const int index = tabAt(event->position().toPoint()); 0081 0082 if (mimeData->hasUrls()) { 0083 updateAutoActivationTimer(index); 0084 } 0085 0086 QTabBar::dragMoveEvent(event); 0087 } 0088 0089 void DolphinTabBar::dropEvent(QDropEvent *event) 0090 { 0091 // Disable the auto activation timer 0092 updateAutoActivationTimer(-1); 0093 0094 const QMimeData *mimeData = event->mimeData(); 0095 const int index = tabAt(event->position().toPoint()); 0096 0097 if (mimeData->hasUrls()) { 0098 Q_EMIT tabDropEvent(index, event); 0099 } 0100 0101 QTabBar::dropEvent(event); 0102 } 0103 0104 void DolphinTabBar::mousePressEvent(QMouseEvent *event) 0105 { 0106 const int index = tabAt(event->pos()); 0107 0108 if (index >= 0 && event->button() == Qt::MiddleButton) { 0109 m_tabToBeClosedOnMiddleMouseButtonRelease = index; 0110 return; 0111 } 0112 0113 QTabBar::mousePressEvent(event); 0114 } 0115 0116 void DolphinTabBar::mouseReleaseEvent(QMouseEvent *event) 0117 { 0118 const int index = tabAt(event->pos()); 0119 0120 if (index >= 0 && index == m_tabToBeClosedOnMiddleMouseButtonRelease && event->button() == Qt::MiddleButton) { 0121 // Mouse middle click on a tab closes this tab. 0122 Q_EMIT tabCloseRequested(index); 0123 return; 0124 } 0125 0126 QTabBar::mouseReleaseEvent(event); 0127 } 0128 0129 void DolphinTabBar::mouseDoubleClickEvent(QMouseEvent *event) 0130 { 0131 if (event->buttons() & Qt::LeftButton) { 0132 int index = tabAt(event->pos()); 0133 0134 if (index < 0) { 0135 // empty tabbar area case 0136 index = currentIndex(); 0137 } 0138 // Double left click on the tabbar opens a new activated tab 0139 // with the url from the doubleclicked tab or currentTab otherwise. 0140 Q_EMIT openNewActivatedTab(index); 0141 } 0142 0143 QTabBar::mouseDoubleClickEvent(event); 0144 } 0145 0146 void DolphinTabBar::contextMenuEvent(QContextMenuEvent *event) 0147 { 0148 const int index = tabAt(event->pos()); 0149 0150 if (index >= 0) { 0151 // Tab context menu 0152 QMenu menu(this); 0153 0154 QAction *newTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@action:inmenu", "New Tab")); 0155 QAction *detachTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-detach")), i18nc("@action:inmenu", "Detach Tab")); 0156 QAction *closeOtherTabsAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-close-other")), i18nc("@action:inmenu", "Close Other Tabs")); 0157 QAction *closeTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-close")), i18nc("@action:inmenu", "Close Tab")); 0158 0159 QAction *selectedAction = menu.exec(event->globalPos()); 0160 if (selectedAction == newTabAction) { 0161 Q_EMIT openNewActivatedTab(index); 0162 } else if (selectedAction == detachTabAction) { 0163 Q_EMIT tabDetachRequested(index); 0164 } else if (selectedAction == closeOtherTabsAction) { 0165 const int tabCount = count(); 0166 for (int i = 0; i < index; i++) { 0167 Q_EMIT tabCloseRequested(0); 0168 } 0169 for (int i = index + 1; i < tabCount; i++) { 0170 Q_EMIT tabCloseRequested(1); 0171 } 0172 } else if (selectedAction == closeTabAction) { 0173 Q_EMIT tabCloseRequested(index); 0174 } 0175 0176 return; 0177 } 0178 0179 QTabBar::contextMenuEvent(event); 0180 } 0181 0182 void DolphinTabBar::slotAutoActivationTimeout() 0183 { 0184 if (m_autoActivationIndex >= 0) { 0185 setCurrentIndex(m_autoActivationIndex); 0186 updateAutoActivationTimer(-1); 0187 } 0188 } 0189 0190 void DolphinTabBar::updateAutoActivationTimer(const int index) 0191 { 0192 if (m_autoActivationIndex != index) { 0193 m_autoActivationIndex = index; 0194 0195 if (m_autoActivationIndex < 0) { 0196 m_autoActivationTimer->stop(); 0197 } else { 0198 m_autoActivationTimer->start(); 0199 } 0200 } 0201 } 0202 0203 #include "moc_dolphintabbar.cpp"