/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. #include "WidgetDragFilter.h"
  19. #include "utils/Logger.h"
  20. #include <QMouseEvent>
  21. #include <QApplication>
  22. #include <QMenuBar>
  23. WidgetDragFilter::WidgetDragFilter( QObject* parent )
  24. : QObject( parent )
  25. , m_dragStarted( false )
  26. {
  27. Q_ASSERT( parent->isWidgetType() );
  28. m_target = QPointer<QWidget>(static_cast<QWidget*>(parent));
  29. m_target.data()->installEventFilter( this );
  30. }
  31. bool
  32. WidgetDragFilter::eventFilter( QObject* obj, QEvent* event )
  33. {
  34. if ( m_target.isNull() || m_target.data() != obj )
  35. return false;
  36. if ( event->type() == QEvent::MouseButtonPress )
  37. {
  38. QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
  39. if ( !canDrag( obj, mouseEvent ) )
  40. return false;
  41. if ( !( mouseEvent->modifiers() == Qt::NoModifier && mouseEvent->button() == Qt::LeftButton ) )
  42. return false;
  43. m_dragPoint = mouseEvent->pos();
  44. m_dragStarted = true;
  45. return false;
  46. }
  47. else if ( event->type() == QEvent::MouseMove )
  48. {
  49. if ( !m_dragStarted )
  50. return false;
  51. QMouseEvent* e = static_cast<QMouseEvent* >(event);
  52. if ( !canDrag( obj, e ) )
  53. {
  54. m_dragStarted = false;
  55. return false;
  56. }
  57. if ( e->buttons().testFlag( Qt::LeftButton ) )
  58. {
  59. m_target.data()->window()->move( m_target.data()->window()->pos() + ( e->pos() - m_dragPoint ) );
  60. return true;
  61. }
  62. }
  63. else if ( event->type() == QEvent::MouseButtonRelease )
  64. m_dragStarted = false;
  65. return false;
  66. }
  67. /**
  68. * Make sure we can really drag this widget. Checks inspired by Oxygen's oxygenwindowmanager.cpp
  69. */
  70. bool
  71. WidgetDragFilter::canDrag( QObject* obj, QMouseEvent* ev ) const
  72. {
  73. if ( !obj->isWidgetType() )
  74. return false;
  75. QWidget* w = static_cast< QWidget* >( obj );
  76. if ( QWidget::mouseGrabber() )
  77. return false;
  78. if ( w->cursor().shape() != Qt::ArrowCursor )
  79. return false;
  80. // Now we check various things about the child position and mouse
  81. QPoint position( ev->pos() );
  82. QWidget* child = w->childAt( position );
  83. if ( child && child->cursor().shape() != Qt::ArrowCursor )
  84. return false;
  85. // Don't want to drag menubars when selecting an action
  86. if ( QMenuBar* menuBar = qobject_cast<QMenuBar*>( w ) )
  87. {
  88. // check if there is an active action
  89. if ( menuBar->activeAction() && menuBar->activeAction()->isEnabled() )
  90. return false;
  91. // check if action at position exists and is enabled
  92. if ( QAction* action = menuBar->actionAt( position ) )
  93. {
  94. if ( action->isSeparator() )
  95. return true;
  96. if ( action->isEnabled() )
  97. return false;
  98. }
  99. }
  100. return true;
  101. }