source: psi/trunk/src/tools/advwidget/advwidget.cpp

Last change on this file was 2, checked in by dmik, 19 years ago

Imported original Psi 0.10 sources from Affinix

File size: 7.4 KB
Line 
1/*
2 * advwidget.cpp - AdvancedWidget template class
3 * Copyright (C) 2005 Michail Pishchagin
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library 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 GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include "advwidget.h"
22
23#include <qapplication.h>
24#include <qwidgetlist.h>
25#include <qtimer.h>
26
27#ifdef Q_OS_WIN
28#include <windows.h>
29#include <winuser.h>
30#endif
31
32// TODO: Make use of KDE taskbar flashing support
33// TODO: Use FlashWindowEx instead of FlashWindow!
34
35//----------------------------------------------------------------------------
36// AdvancedWidgetShared
37//----------------------------------------------------------------------------
38
39class AdvancedWidgetShared : public QObject
40{
41 Q_OBJECT
42public:
43 AdvancedWidgetShared();
44 ~AdvancedWidgetShared();
45};
46
47AdvancedWidgetShared::AdvancedWidgetShared()
48 : QObject(qApp)
49{
50}
51
52AdvancedWidgetShared::~AdvancedWidgetShared()
53{
54}
55
56static AdvancedWidgetShared *advancedWidgetShared = 0;
57
58//----------------------------------------------------------------------------
59// GAdvancedWidget::Private
60//----------------------------------------------------------------------------
61
62class GAdvancedWidget::Private : public QObject
63{
64 Q_OBJECT
65public:
66 Private(QWidget *parent);
67
68 static int stickAt;
69 static bool stickToWindows;
70 static bool stickEnabled;
71
72 QWidget *parentWidget;
73
74 bool flashing();
75 void doFlash(bool on);
76 void posChanging(int *x, int *y, int *width, int *height);
77
78private:
79 QTimer *flashTimer;
80 int flashCount;
81
82private slots:
83 void flashAnimate();
84};
85
86int GAdvancedWidget::Private::stickAt = 5;
87bool GAdvancedWidget::Private::stickToWindows = true;
88bool GAdvancedWidget::Private::stickEnabled = true;
89
90GAdvancedWidget::Private::Private(QWidget *parent)
91 : QObject(parent)
92{
93 if ( !advancedWidgetShared )
94 advancedWidgetShared = new AdvancedWidgetShared();
95
96 parentWidget = parent;
97 flashTimer = 0;
98 flashCount = 0;
99}
100
101void GAdvancedWidget::Private::posChanging(int *x, int *y, int *width, int *height)
102{
103 if ( stickAt <= 0 ||
104 !stickEnabled ||
105 !parentWidget->isTopLevel() ||
106 parentWidget->isMaximized() ||
107 !parentWidget->isUpdatesEnabled() )
108 {
109 return;
110 }
111
112 QWidget *p = parentWidget;
113 if ( p->pos() == QPoint(*x, *y) &&
114 p->frameSize() == QSize(*width, *height) )
115 return;
116
117 bool resizing = p->frameSize() != QSize(*width, *height);
118
119 QWidget *w;
120 QDesktopWidget *desktop = qApp->desktop();
121 QWidgetList *list;
122
123 if ( stickToWindows )
124 list = QApplication::topLevelWidgets();
125 else
126 list = new QWidgetList();
127 list->append( desktop );
128
129 QWidgetListIt it( *list );
130 for ( ; (w = it.current()); ++it ) {
131 QRect rect;
132 bool dockWidget = false;
133
134 if ( w->isDesktop() )
135 rect = ((QDesktopWidget *)w)->availableGeometry((QWidget *)parent());
136 else {
137 if ( w == p ||
138 desktop->screenNumber(p) != desktop->screenNumber(w) )
139 continue;
140
141 if ( !w->isVisible() )
142 continue;
143
144 // we want for widget to stick to outer edges of another widget, so
145 // we'll change the rect to what it'll snap
146 rect = QRect(w->frameGeometry().bottomRight(), w->frameGeometry().topLeft());
147 dockWidget = true;
148 }
149
150 if ( *x != p->x() )
151 if ( *x <= rect.left() + stickAt &&
152 *x > rect.left() - stickAt ) {
153 if ( !dockWidget ||
154 (p->frameGeometry().bottom() >= rect.bottom() &&
155 p->frameGeometry().top() <= rect.top()) ) {
156 *x = rect.left();
157 if ( resizing )
158 *width = p->frameSize().width() + p->x() - *x;
159 }
160 }
161
162 if ( *x + *width >= rect.right() - stickAt &&
163 *x + *width <= rect.right() + stickAt ) {
164 if ( !dockWidget ||
165 (p->frameGeometry().bottom() >= rect.bottom() &&
166 p->frameGeometry().top() <= rect.top()) ) {
167 if ( resizing )
168 *width = rect.right() - *x + 1;
169 else
170 *x = rect.right() - *width + 1;
171 }
172 }
173
174 if ( *y != p->y() )
175 if ( *y <= rect.top() + stickAt &&
176 *y > rect.top() - stickAt ) {
177 if ( !dockWidget ||
178 (p->frameGeometry().right() >= rect.right() &&
179 p->frameGeometry().left() <= rect.left()) ) {
180 *y = rect.top();
181 if ( resizing )
182 *height = p->frameSize().height() + p->y() - *y;
183 }
184 }
185
186 if ( *y + *height >= rect.bottom() - stickAt &&
187 *y + *height <= rect.bottom() + stickAt ) {
188 if ( !dockWidget ||
189 (p->frameGeometry().right() >= rect.right() &&
190 p->frameGeometry().left() <= rect.left()) ) {
191 if ( resizing )
192 *height = rect.bottom() - *y + 1;
193 else
194 *y = rect.bottom() - *height + 1;
195 }
196 }
197 }
198
199 delete list;
200}
201
202void GAdvancedWidget::Private::doFlash(bool yes)
203{
204#ifdef Q_WS_WIN
205 if ( yes ) {
206 if ( flashTimer )
207 return;
208 flashTimer = new QTimer(this);
209 connect(flashTimer, SIGNAL(timeout()), SLOT(flashAnimate()));
210 flashCount = 0;
211 flashAnimate(); // kick the first one immediately
212 flashTimer->start(500);
213 }
214 else {
215 if ( flashTimer ) {
216 delete flashTimer;
217 flashTimer = 0;
218 // comment this out to fix titlebar repaint on Windows??
219 //FlashWindow(winId(), false);
220 }
221 }
222#else
223 Q_UNUSED(yes)
224#endif
225}
226
227void GAdvancedWidget::Private::flashAnimate()
228{
229#ifdef Q_WS_WIN
230 FlashWindow( parentWidget->winId(), true );
231 if ( ++flashCount == 5 )
232 flashTimer->stop();
233#endif
234}
235
236bool GAdvancedWidget::Private::flashing()
237{
238 bool on = false;
239 if ( flashTimer )
240 on = flashCount & 1;
241
242 return on;
243}
244
245//----------------------------------------------------------------------------
246// GAdvancedWidget
247//----------------------------------------------------------------------------
248
249GAdvancedWidget::GAdvancedWidget(QWidget *parent, const char *name)
250 : QObject(parent, name)
251{
252 d = new Private(parent);
253}
254
255GAdvancedWidget::~GAdvancedWidget()
256{
257 delete d;
258}
259
260#ifdef Q_OS_WIN
261bool GAdvancedWidget::winEvent(MSG *msg)
262{
263 if ( msg->message == WM_WINDOWPOSCHANGING ) {
264 WINDOWPOS *wpos = (WINDOWPOS *)msg->lParam;
265
266 d->posChanging(&wpos->x, &wpos->y, &wpos->cx, &wpos->cy);
267
268 return true;
269 }
270
271 return false;
272}
273#endif
274
275void GAdvancedWidget::preSetCaption()
276{
277#ifdef Q_WS_WIN
278 if ( d->flashing() )
279 FlashWindow( d->parentWidget->winId(), true );
280#endif
281}
282
283void GAdvancedWidget::postSetCaption()
284{
285#ifdef Q_WS_WIN
286 if ( d->flashing() )
287 FlashWindow( d->parentWidget->winId(), true );
288#endif
289}
290
291void GAdvancedWidget::doFlash(bool on)
292{
293 d->doFlash( on );
294}
295
296void GAdvancedWidget::windowActivationChange(bool oldstate)
297{
298 if ( d->parentWidget->isActiveWindow() ) {
299 d->doFlash(false);
300 }
301}
302
303int GAdvancedWidget::stickAt()
304{
305 return Private::stickAt;
306}
307
308void GAdvancedWidget::setStickAt(int val)
309{
310 Private::stickAt = val;
311}
312
313bool GAdvancedWidget::stickToWindows()
314{
315 return Private::stickToWindows;
316}
317
318void GAdvancedWidget::setStickToWindows(bool val)
319{
320 Private::stickToWindows = val;
321}
322
323bool GAdvancedWidget::stickEnabled()
324{
325 return Private::stickEnabled;
326}
327
328void GAdvancedWidget::setStickEnabled(bool val)
329{
330 Private::stickEnabled = val;
331}
332
333#include "advwidget.moc"
Note: See TracBrowser for help on using the repository browser.