]> cloud.milkyroute.net Git - dolphin.git/blob - src/tagcloud/taggingpopup.cpp
3e59c80d1a584ff2c748d8757ecd420674ce186a
[dolphin.git] / src / tagcloud / taggingpopup.cpp
1 /*
2 This file is part of the Nepomuk KDE project.
3 Copyright (C) 2007 Sebastian Trueg <trueg@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20 #include "taggingpopup.h"
21
22 #include <QtCore/QEventLoop>
23 #include <QtCore/QPointer>
24 #include <QtGui/QApplication>
25 #include <QtGui/QDesktopWidget>
26 #include <QtGui/QMouseEvent>
27
28 #include <KDebug>
29 #include <KDialog>
30
31
32 class Nepomuk::TaggingPopup::Private
33 {
34 public:
35 Private( TaggingPopup* parent )
36 : eventLoop( 0 ),
37 m_parent( parent ) {
38 }
39
40 QEventLoop* eventLoop;
41 QPoint popupPos;
42
43 QRect geometryForPopupPos( const QPoint& p ) {
44 QSize size = m_parent->sizeHint();
45
46 // we want a little margin
47 const int margin = KDialog::marginHint();
48 size.setHeight( size.height() + margin*2 );
49 size.setWidth( size.width() + margin*2 );
50
51 QRect screen = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber( p ) );
52
53 // calculate popup position
54 QPoint pos( p.x() - size.width()/2, p.y() - size.height()/2 );
55
56 // ensure we do not leave the desktop
57 if ( pos.x() + size.width() > screen.right() ) {
58 pos.setX( screen.right() - size.width() );
59 }
60 else if ( pos.x() < screen.left() ) {
61 pos.setX( screen.left() );
62 }
63
64 if ( pos.y() + size.height() > screen.bottom() ) {
65 pos.setY( screen.bottom() - size.height() );
66 }
67 else if ( pos.y() < screen.top() ) {
68 pos.setY( screen.top() );
69 }
70
71 return QRect( pos, size );
72 }
73
74 private:
75 TaggingPopup* m_parent;
76 };
77
78
79 Nepomuk::TaggingPopup::TaggingPopup( QWidget* parent )
80 : TagCloud( parent ),
81 d( new Private( this ) )
82 {
83 setFrameStyle( QFrame::Box|QFrame::Plain );
84 setWindowFlags( Qt::Popup );
85 }
86
87
88 Nepomuk::TaggingPopup::~TaggingPopup()
89 {
90 delete d;
91 }
92
93
94 void Nepomuk::TaggingPopup::popup( const QPoint& p )
95 {
96 setGeometry( d->geometryForPopupPos( p ) );
97 d->popupPos = p;
98
99 show();
100 }
101
102
103 void Nepomuk::TaggingPopup::exec( const QPoint& pos )
104 {
105 QEventLoop eventLoop;
106 d->eventLoop = &eventLoop;
107 popup( pos );
108
109 QPointer<QObject> guard = this;
110 (void) eventLoop.exec();
111 if ( !guard.isNull() )
112 d->eventLoop = 0;
113 }
114
115
116 void Nepomuk::TaggingPopup::mousePressEvent( QMouseEvent* e )
117 {
118 if ( !rect().contains( e->pos() ) ) {
119 hide();
120 }
121 else {
122 TagCloud::mousePressEvent( e );
123 }
124 }
125
126
127 void Nepomuk::TaggingPopup::hideEvent( QHideEvent* e )
128 {
129 Q_UNUSED( e );
130 if ( d->eventLoop ) {
131 d->eventLoop->exit();
132 }
133 }
134
135
136 bool Nepomuk::TaggingPopup::event( QEvent* e )
137 {
138 if ( e->type() == QEvent::LayoutRequest ) {
139 if ( isVisible() ) {
140 setGeometry( d->geometryForPopupPos( d->popupPos ) );
141 return true;
142 }
143 }
144
145 return TagCloud::event( e );
146 }
147