File indexing completed on 2024-05-12 05:46:31

0001 /*
0002   This program is free software; you can redistribute it and/or
0003   modify it under the terms of the GNU General Public License as
0004   published by the Free Software Foundation; either version 2 of
0005   the License or (at your option) version 3 or any later version
0006   accepted by the membership of KDE e.V. (or its successor appro-
0007   ved by the membership of KDE e.V.), which shall act as a proxy
0008   defined in Section 14 of version 3 of the license.
0009 
0010   This program is distributed in the hope that it will be useful,
0011   but WITHOUT ANY WARRANTY; without even the implied warranty of
0012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0013   GNU General Public License for more details.
0014 
0015   You should have received a copy of the GNU General Public License
0016   along with this program. If not, see http://www.gnu.org/licenses/.
0017 */
0018 
0019 /*
0020   Copyright (C) 2012 Eike Hein <hein@kde.org>
0021 */
0022 
0023 #include "viewspringloader.h"
0024 #include "viewtree.h"
0025 
0026 #include <QDragMoveEvent>
0027 #include <QTabBar>
0028 #include <QMimeData>
0029 
0030 ViewSpringLoader::ViewSpringLoader(ViewContainer* viewContainer) : QObject(viewContainer)
0031 {
0032     m_viewContainer = viewContainer;
0033 
0034     m_hoverTimer.setSingleShot(true);
0035     connect(&m_hoverTimer, &QTimer::timeout, this, &ViewSpringLoader::springLoad);
0036 }
0037 
0038 ViewSpringLoader::~ViewSpringLoader()
0039 {
0040 }
0041 
0042 void ViewSpringLoader::addWidget(QWidget* widget)
0043 {
0044     widget->installEventFilter(this);
0045 }
0046 
0047 bool ViewSpringLoader::eventFilter(QObject* watched, QEvent* event)
0048 {
0049     if (event->type() == QEvent::DragEnter)
0050     {
0051         if (!dynamic_cast<QDragEnterEvent*>(event)->mimeData()->hasFormat(QStringLiteral("application/x-konversation-chatwindow")))
0052         {
0053             m_hoveredWidget = qobject_cast<QWidget*>(watched);
0054 
0055             event->accept();
0056 
0057             return true;
0058         }
0059     }
0060     else if (event->type() == QEvent::DragMove)
0061     {
0062         QDragMoveEvent* dragMoveEvent = dynamic_cast<QDragMoveEvent*>(event);
0063 
0064         if (!dragMoveEvent->mimeData()->hasFormat(QStringLiteral("application/x-konversation-chatwindow")))
0065         {
0066             ChatWindow* hoveredView = viewForPos(watched, dragMoveEvent->pos());
0067 
0068             if (hoveredView != m_hoveredView)
0069             {
0070                 m_hoveredView = hoveredView;
0071 
0072                 if (m_hoveredView)
0073                     m_hoverTimer.start(400);
0074             }
0075 
0076             event->ignore();
0077 
0078             return true;
0079         }
0080     }
0081     else if (event->type() == QEvent::Drop || event->type() == QEvent::DragLeave)
0082     {
0083         m_hoverTimer.stop();
0084         m_hoveredWidget = nullptr;
0085         m_hoveredView = nullptr;
0086     }
0087 
0088     return QObject::eventFilter(watched, event);
0089 }
0090 
0091 void ViewSpringLoader::springLoad()
0092 {
0093     if (m_hoveredView && m_hoveredView == viewForPos(m_hoveredWidget,
0094         m_hoveredWidget->mapFromGlobal(QCursor::pos())))
0095     {
0096         m_viewContainer->showView(m_hoveredView);
0097         m_hoveredView = nullptr;
0098     }
0099 }
0100 
0101 ChatWindow* ViewSpringLoader::viewForPos(QObject* widget, const QPoint& pos)
0102 {
0103     QTabBar* tabBar = qobject_cast<QTabBar*>(widget);
0104 
0105     if (tabBar)
0106        return m_viewContainer->getViewAt(tabBar->tabAt(pos));
0107     else
0108     {
0109         ViewTree* viewTree = qobject_cast<ViewTree*>(widget->parent());
0110 
0111         if (viewTree)
0112         {
0113             const QModelIndex& idx = viewTree->indexAt(QPoint(0, pos.y()));
0114 
0115             if (idx.isValid()) {
0116                 ChatWindow* view = static_cast<ChatWindow*>(idx.internalPointer());
0117 
0118                 return view;
0119             }
0120         }
0121     }
0122 
0123     return nullptr;
0124 }