File indexing completed on 2025-02-09 07:11:33

0001 /*
0002     This file is part of the Kasten Framework, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2018 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "tabbar.hpp"
0010 
0011 // Qt
0012 #include <QMouseEvent>
0013 #include <QDragEnterEvent>
0014 #include <QDragMoveEvent>
0015 
0016 namespace Kasten {
0017 
0018 TabBar::TabBar(QWidget* parent)
0019     : QTabBar(parent)
0020 {
0021     setAcceptDrops(true);
0022     setChangeCurrentOnDrag(true);
0023 
0024     // catch non-LMB double clicks
0025     installEventFilter(this);
0026 
0027     connect(this, &QTabBar::tabBarDoubleClicked,
0028             this, &TabBar::onTabBarDoubleClicked);
0029 }
0030 
0031 TabBar::~TabBar() = default;
0032 
0033 void TabBar::mouseReleaseEvent(QMouseEvent* event)
0034 {
0035     if (tabsClosable()) {
0036         if (event->button() == Qt::MiddleButton) {
0037             const int tabIndex = tabAt(event->pos());
0038             if (tabIndex != -1) {
0039                 Q_EMIT tabCloseRequested(tabIndex);
0040             } else {
0041                 Q_EMIT mouseMiddleClick();
0042             }
0043             event->setAccepted(true);
0044             return;
0045         }
0046     }
0047 
0048     QTabBar::mouseReleaseEvent(event);
0049 }
0050 
0051 void TabBar::dragEnterEvent(QDragEnterEvent* event)
0052 {
0053     // accept the entering in general, independent of being over a tab or not
0054     // as rejecting here seems not revertable in moveevents
0055     bool accept = false;
0056     // The receivers of the testCanDecode() signal has to adjust
0057     // 'accept' accordingly.
0058     Q_EMIT testCanDecode(event, accept);
0059 
0060     if (accept) {
0061         event->setAccepted(true);
0062         return;
0063     }
0064 
0065     QTabBar::dragEnterEvent(event);
0066 }
0067 
0068 void TabBar::dragMoveEvent(QDragMoveEvent* event)
0069 {
0070     if (tabAt(event->pos()) == -1) {
0071         bool accept = false;
0072         // The receivers of the testCanDecode() signal has to adjust
0073         // 'accept' accordingly.
0074         Q_EMIT testCanDecode(event, accept);
0075 
0076         if (accept) {
0077             event->setAccepted(true);
0078             return;
0079         }
0080     }
0081 
0082     QTabBar::dragMoveEvent(event);
0083 }
0084 
0085 void TabBar::dropEvent(QDropEvent* event)
0086 {
0087     if (tabAt(event->pos()) == -1) {
0088         Q_EMIT receivedDropEvent(event);
0089         return;
0090     }
0091 
0092     QTabBar::dropEvent(event);
0093 }
0094 
0095 
0096 bool TabBar::eventFilter(QObject* object, QEvent* event)
0097 {
0098     if (object == this) {
0099         // TODO Qt6: Move to mouseDoubleClickEvent when fixme in qttabbar.cpp is resolved
0100         // see "fixme Qt 6: move to mouseDoubleClickEvent(), here for BC reasons." in qtabbar.cpp
0101         if (event->type() == QEvent::MouseButtonDblClick) {
0102             // block tabBarDoubleClicked signals with RMB, see https://bugs.kde.org/show_bug.cgi?id=356016
0103             auto* mouseEvent = static_cast<const QMouseEvent*>(event);
0104             if (mouseEvent->button() != Qt::LeftButton) {
0105                 return true;
0106             }
0107         }
0108     }
0109     return QObject::eventFilter(object, event);
0110 }
0111 
0112 void TabBar::onTabBarDoubleClicked(int index)
0113 {
0114     if (index == -1) {
0115         Q_EMIT emptySpaceMouseDoubleClicked();
0116     }
0117 }
0118 
0119 }
0120 
0121 #include "moc_tabbar.cpp"