PageRenderTime 31ms CodeModel.GetById 13ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/libtomahawk/utils/WidgetDragFilter.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 122 lines | 77 code | 21 blank | 24 comment | 32 complexity | 6e63bd0c4fce836ad84d7d0058cffc07 MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
  4 *
  5 *   Tomahawk is free software: you can redistribute it and/or modify
  6 *   it under the terms of the GNU General Public License as published by
  7 *   the Free Software Foundation, either version 3 of the License, or
  8 *   (at your option) any later version.
  9 *
 10 *   Tomahawk is distributed in the hope that it will be useful,
 11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *   GNU General Public License for more details.
 14 *
 15 *   You should have received a copy of the GNU General Public License
 16 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19#include "WidgetDragFilter.h"
 20
 21#include "utils/Logger.h"
 22
 23#include <QMouseEvent>
 24#include <QApplication>
 25#include <QMenuBar>
 26
 27WidgetDragFilter::WidgetDragFilter( QObject* parent )
 28    : QObject( parent )
 29    , m_dragStarted( false )
 30{
 31    Q_ASSERT( parent->isWidgetType() );
 32    m_target = QPointer<QWidget>(static_cast<QWidget*>(parent));
 33    m_target.data()->installEventFilter( this );
 34}
 35
 36
 37bool
 38WidgetDragFilter::eventFilter( QObject* obj, QEvent* event )
 39{
 40    if ( m_target.isNull() || m_target.data() != obj )
 41        return false;
 42
 43    if ( event->type() == QEvent::MouseButtonPress )
 44    {
 45        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
 46        if ( !canDrag( obj, mouseEvent ) )
 47            return false;
 48        if ( !( mouseEvent->modifiers() == Qt::NoModifier && mouseEvent->button() == Qt::LeftButton ) )
 49            return false;
 50
 51        m_dragPoint = mouseEvent->pos();
 52        m_dragStarted = true;
 53        return false;
 54    }
 55    else if ( event->type() == QEvent::MouseMove )
 56    {
 57        if ( !m_dragStarted )
 58            return false;
 59
 60        QMouseEvent* e = static_cast<QMouseEvent* >(event);
 61        if ( !canDrag( obj, e ) )
 62        {
 63            m_dragStarted = false;
 64            return false;
 65        }
 66
 67        if ( e->buttons().testFlag( Qt::LeftButton ) )
 68        {
 69            m_target.data()->window()->move( m_target.data()->window()->pos() + ( e->pos() - m_dragPoint ) );
 70            return true;
 71        }
 72    }
 73    else if ( event->type() == QEvent::MouseButtonRelease )
 74        m_dragStarted = false;
 75
 76    return false;
 77}
 78
 79
 80/**
 81 * Make sure we can really drag this widget. Checks inspired by Oxygen's oxygenwindowmanager.cpp
 82 */
 83bool
 84WidgetDragFilter::canDrag( QObject* obj, QMouseEvent* ev ) const
 85{
 86    if ( !obj->isWidgetType() )
 87        return false;
 88
 89    QWidget* w = static_cast< QWidget* >( obj );
 90
 91    if ( QWidget::mouseGrabber() )
 92        return false;
 93
 94    if ( w->cursor().shape() != Qt::ArrowCursor )
 95        return false;
 96
 97    // Now we check various things about the child position and mouse
 98    QPoint position( ev->pos() );
 99    QWidget* child = w->childAt( position );
100
101    if ( child && child->cursor().shape() != Qt::ArrowCursor )
102        return false;
103
104    // Don't want to drag menubars when selecting an action
105    if ( QMenuBar* menuBar = qobject_cast<QMenuBar*>( w ) )
106    {
107        // check if there is an active action
108        if ( menuBar->activeAction() && menuBar->activeAction()->isEnabled() )
109            return false;
110
111        // check if action at position exists and is enabled
112        if ( QAction* action = menuBar->actionAt( position ) )
113        {
114            if ( action->isSeparator() )
115                return true;
116            if ( action->isEnabled() )
117                return false;
118        }
119    }
120
121    return true;
122}