• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeui
 

tdeui

  • tdeui
kpassivepopup.cpp
1/*
2 * copyright : (C) 2001-2002 by Richard Moore
3 * copyright : (C) 2004-2005 by Sascha Cunz
4 * License : This file is released under the terms of the LGPL, version 2.
5 * email : rich@kde.org
6 * email : sascha.cunz@tiscali.de
7 */
8
9#include <tdeconfig.h>
10
11#include <tqapplication.h>
12#include <tqlabel.h>
13#include <tqlayout.h>
14#include <tqtimer.h>
15#include <tqvbox.h>
16#include <tqpainter.h>
17#include <tqtooltip.h>
18#include <tqbitmap.h>
19#include <tqpointarray.h>
20
21#include <kdebug.h>
22#include <kdialog.h>
23#include <kpixmap.h>
24#include <kpixmapeffect.h>
25#include <tdeglobalsettings.h>
26
27#include "config.h"
28#ifdef TQ_WS_X11
29#include <netwm.h>
30#endif
31
32#include "kpassivepopup.h"
33#include "kpassivepopup.moc"
34
35class KPassivePopup::Private
36{
37public:
38 int popupStyle;
39 TQPointArray surround;
40 TQPoint anchor;
41 TQPoint fixedPosition;
42};
43
44static const int DEFAULT_POPUP_TYPE = KPassivePopup::Boxed;
45static const int DEFAULT_POPUP_TIME = 6*1000;
46static const int POPUP_FLAGS = TQt::WStyle_Customize | TQt::WDestructiveClose | TQt::WX11BypassWM
47 | TQt::WStyle_StaysOnTop | TQt::WStyle_Tool | TQt::WStyle_NoBorder;
48
49KPassivePopup::KPassivePopup( TQWidget *parent, const char *name, WFlags f )
50 : TQFrame( 0, name, (WFlags)(f ? (int)f : POPUP_FLAGS) ),
51 window( parent ? parent->winId() : 0L ), msgView( 0 ), topLayout( 0 ),
52 hideDelay( DEFAULT_POPUP_TIME ), hideTimer( new TQTimer( this, "hide_timer" ) ),
53 m_autoDelete( false )
54{
55 init( DEFAULT_POPUP_TYPE );
56}
57
58KPassivePopup::KPassivePopup( WId win, const char *name, WFlags f )
59 : TQFrame( 0, name, (WFlags)(f ? (int)f : POPUP_FLAGS) ),
60 window( win ), msgView( 0 ), topLayout( 0 ),
61 hideDelay( DEFAULT_POPUP_TIME ), hideTimer( new TQTimer( this, "hide_timer" ) ),
62 m_autoDelete( false )
63{
64 init( DEFAULT_POPUP_TYPE );
65}
66
67KPassivePopup::KPassivePopup( int popupStyle, TQWidget *parent, const char *name, WFlags f )
68 : TQFrame( 0, name, (WFlags)(f ? (int)f : POPUP_FLAGS) ),
69 window( parent ? parent->winId() : 0L ), msgView( 0 ), topLayout( 0 ),
70 hideDelay( DEFAULT_POPUP_TIME ), hideTimer( new TQTimer( this, "hide_timer" ) ),
71 m_autoDelete( false )
72{
73 init( popupStyle );
74}
75
76KPassivePopup::KPassivePopup( int popupStyle, WId win, const char *name, WFlags f )
77 : TQFrame( 0, name, (WFlags)(f ? (int)f : POPUP_FLAGS) ),
78 window( win ), msgView( 0 ), topLayout( 0 ),
79 hideDelay( DEFAULT_POPUP_TIME ), hideTimer( new TQTimer( this, "hide_timer" ) ),
80 m_autoDelete( false )
81{
82 init( popupStyle );
83}
84
85void KPassivePopup::init( int popupStyle )
86{
87 d = new Private;
88 d->popupStyle = popupStyle;
89 if( popupStyle == Boxed )
90 {
91 setFrameStyle( TQFrame::Box| TQFrame::Plain );
92 setLineWidth( 2 );
93 }
94 else if( popupStyle == Balloon )
95 {
96 setPalette(TQToolTip::palette());
97 setAutoMask(true);
98 }
99 connect( hideTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( hide() ) );
100 connect( this, TQ_SIGNAL( clicked() ), TQ_SLOT( hide() ) );
101}
102
103KPassivePopup::~KPassivePopup()
104{
105 delete d;
106}
107
108void KPassivePopup::setView( TQWidget *child )
109{
110 delete msgView;
111 msgView = child;
112
113 delete topLayout;
114 topLayout = new TQVBoxLayout( this, d->popupStyle == Balloon ? 22 : KDialog::marginHint(), KDialog::spacingHint() );
115 topLayout->addWidget( msgView );
116 topLayout->activate();
117}
118
119void KPassivePopup::setView( const TQString &caption, const TQString &text,
120 const TQPixmap &icon )
121{
122 // kdDebug() << "KPassivePopup::setView " << caption << ", " << text << endl;
123 setView( standardView( caption, text, icon, this ) );
124}
125
126static void truncateStringToFit(TQString &string, TQFont font, int max_width) {
127 bool truncated = false;
128 TQFontMetrics fm(font);
129 while (fm.width(string) > max_width) {
130 string.truncate(string.length() - 1);
131 truncated = true;
132 }
133 if (truncated) {
134 string += " ...";
135 }
136}
137
138TQVBox * KPassivePopup::standardView(const TQString& caption,
139 const TQString& text,
140 const TQPixmap& icon,
141 TQWidget *parent)
142{
143 TQString sizedCaption = caption;
144 TQString sizedText = text;
145
146#ifdef TQ_WS_X11
147 int max_width;
148
149 NETRootInfo info( tqt_xdisplay(),
150 NET::NumberOfDesktops |
151 NET::CurrentDesktop |
152 NET::WorkArea,
153 -1, false );
154 info.activate();
155 NETRect workArea = info.workArea(info.currentDesktop());
156 max_width = workArea.size.width / 3;
157#endif
158
159 TQVBox *vb = new TQVBox( parent ? parent : this );
160 vb->setSpacing( KDialog::spacingHint() );
161
162 TQHBox *hb=0;
163 if ( !icon.isNull() ) {
164 hb = new TQHBox( vb );
165 hb->setMargin( 0 );
166 hb->setSpacing( KDialog::spacingHint() );
167 ttlIcon = new TQLabel( hb, "title_icon" );
168 ttlIcon->setPixmap( icon );
169 ttlIcon->setAlignment( AlignLeft );
170 }
171
172 if ( !sizedCaption.isEmpty() ) {
173 ttl = new TQLabel( sizedCaption, hb ? hb : vb, "title_label" );
174 TQFont fnt = ttl->font();
175#ifdef TQ_WS_X11
176 truncateStringToFit(sizedCaption, fnt, max_width);
177 ttl->setText(sizedCaption);
178#endif
179 fnt.setBold( true );
180 ttl->setFont( fnt );
181 ttl->setAlignment( TQt::AlignHCenter );
182 if ( hb ) {
183 hb->setStretchFactor( ttl, 10 ); // enforce centering
184 }
185 }
186
187 if ( !sizedText.isEmpty() ) {
188 msg = new TQLabel( sizedText, vb, "msg_label" );
189#ifdef TQ_WS_X11
190 TQStringList textLines = TQStringList::split("\n", sizedText, true);
191 for (TQStringList::Iterator it = textLines.begin(); it != textLines.end(); ++it) {
192 truncateStringToFit(*it, msg->font(), max_width);
193 }
194
195 // Limit message to 5 lines of text
196 if (textLines.count() > 5) {
197 int count = 3;
198 TQStringList truncatedLines;
199 for (TQStringList::Iterator it = textLines.begin(); it != textLines.end(); ++it) {
200 truncatedLines.append(*it);
201 if (count > 5) {
202 truncatedLines.append("...");
203 break;
204 }
205 count++;
206 }
207 textLines = truncatedLines;
208 }
209 sizedText = textLines.join("\n");
210 msg->setText(sizedText);
211#endif
212 msg->setAlignment( AlignLeft );
213 }
214
215 return vb;
216}
217
218void KPassivePopup::setView( const TQString &caption, const TQString &text )
219{
220 setView( caption, text, TQPixmap() );
221}
222
223void KPassivePopup::setTimeout( int delay )
224{
225 hideDelay = delay;
226 if( hideTimer->isActive() )
227 {
228 if( delay ) {
229 hideTimer->changeInterval( delay );
230 } else {
231 hideTimer->stop();
232 }
233 }
234}
235
236void KPassivePopup::setAutoDelete( bool autoDelete )
237{
238 m_autoDelete = autoDelete;
239}
240
241void KPassivePopup::mouseReleaseEvent( TQMouseEvent *e )
242{
243 emit clicked();
244 emit clicked( e->pos() );
245}
246
247//
248// Main Implementation
249//
250
251void KPassivePopup::show()
252{
253 TQSize desiredSize = sizeHint();
254
255 if (size() != desiredSize) {
256 resize(desiredSize);
257 }
258
259 if (d->fixedPosition.isNull()) {
260 positionSelf();
261 }
262 else {
263 if( d->popupStyle == Balloon ) {
264 setAnchor(d->fixedPosition);
265 }
266 else {
267 move(d->fixedPosition);
268 }
269 }
270 TQFrame::show();
271
272 int delay = hideDelay;
273 if ( delay < 0 ) {
274 delay = DEFAULT_POPUP_TIME;
275 }
276
277 if ( delay > 0 ) {
278 hideTimer->start( delay );
279 }
280}
281
282void KPassivePopup::show(const TQPoint &p)
283{
284 d->fixedPosition = p;
285 show();
286}
287
288void KPassivePopup::hideEvent( TQHideEvent * )
289{
290 hideTimer->stop();
291 emit( hidden( this ) );
292 if ( m_autoDelete )
293 deleteLater();
294}
295
296TQRect KPassivePopup::defaultArea() const
297{
298#ifdef TQ_WS_X11
299 NETRootInfo info( tqt_xdisplay(),
300 NET::NumberOfDesktops |
301 NET::CurrentDesktop |
302 NET::WorkArea,
303 -1, false );
304 info.activate();
305 NETRect workArea = info.workArea( info.currentDesktop() );
306 TQRect r;
307 r.setRect( workArea.pos.x, workArea.pos.y, 0, 0 ); // top left
308#else
309 // FIX IT
310 TQRect r;
311 r.setRect( 100, 100, 200, 200 ); // top left
312#endif
313 return r;
314}
315
316void KPassivePopup::positionSelf()
317{
318 TQRect target;
319
320#ifdef TQ_WS_X11
321 if ( !window ) {
322 target = defaultArea();
323 }
324
325 else {
326 NETWinInfo ni( tqt_xdisplay(), window, tqt_xrootwin(),
327 NET::WMIconGeometry | NET::WMKDESystemTrayWinFor );
328
329 // Figure out where to put the popup. Note that we must handle
330 // windows that skip the taskbar cleanly
331 if ( ni.kdeSystemTrayWinFor() ) {
332 NETRect frame, win;
333 ni.kdeGeometry( frame, win );
334 target.setRect( win.pos.x, win.pos.y,
335 win.size.width, win.size.height );
336 }
337 else if ( ni.state() & NET::SkipTaskbar ) {
338 target = defaultArea();
339 }
340 else {
341 NETRect r = ni.iconGeometry();
342 target.setRect( r.pos.x, r.pos.y, r.size.width, r.size.height );
343 if ( target.isNull() ) { // bogus value, use the exact position
344 NETRect dummy;
345 ni.kdeGeometry( dummy, r );
346 target.setRect( r.pos.x, r.pos.y,
347 r.size.width, r.size.height);
348 }
349 }
350 }
351#else
352 target = defaultArea();
353#endif
354 moveNear( target );
355}
356
357void KPassivePopup::moveNear( TQRect target )
358{
359 TQPoint pos = target.topLeft();
360 int x = pos.x();
361 int y = pos.y();
362 int w = width();
363 int h = height();
364
365 TQRect r = TDEGlobalSettings::desktopGeometry(TQPoint(x+w/2,y+h/2));
366
367 if( d->popupStyle == Balloon )
368 {
369 // find a point to anchor to
370 if( x + w > r.width() ){
371 x = x + target.width();
372 }
373
374 if( y + h > r.height() ){
375 y = y + target.height();
376 }
377 } else
378 {
379 if ( x < r.center().x() )
380 x = x + target.width();
381 else
382 x = x - w;
383
384 // It's apparently trying to go off screen, so display it ALL at the bottom.
385 if ( (y + h) > r.bottom() )
386 y = r.bottom() - h;
387
388 if ( (x + w) > r.right() )
389 x = r.right() - w;
390 }
391 if ( y < r.top() )
392 y = r.top();
393
394 if ( x < r.left() )
395 x = r.left();
396
397 if( d->popupStyle == Balloon )
398 setAnchor( TQPoint( x, y ) );
399 else
400 move( x, y );
401}
402
403void KPassivePopup::setAnchor(const TQPoint &anchor)
404{
405 d->anchor = anchor;
406 updateMask();
407}
408
409void KPassivePopup::paintEvent( TQPaintEvent* pe )
410{
411 if( d->popupStyle == Balloon ) {
412 TQPainter p;
413 p.begin( this );
414 p.drawPolygon( d->surround );
415 }
416 else {
417 TQFrame::paintEvent( pe );
418 }
419}
420
421void KPassivePopup::updateMask()
422{
423 // get screen-geometry for screen our anchor is on
424 // (geometry can differ from screen to screen!
425 TQRect deskRect = TDEGlobalSettings::desktopGeometry(d->anchor);
426
427 int xh = 70, xl = 40;
428 if( width() < 80 )
429 xh = xl = 40;
430 else if( width() < 110 )
431 xh = width() - 40;
432
433 bool bottom = (d->anchor.y() + height()) > ((deskRect.y() + deskRect.height()-48));
434 bool right = (d->anchor.x() + width()) > ((deskRect.x() + deskRect.width()-48));
435
436 TQPoint corners[4] = {
437 TQPoint( width() - 50, 10 ),
438 TQPoint( 10, 10 ),
439 TQPoint( 10, height() - 50 ),
440 TQPoint( width() - 50, height() - 50 )
441 };
442
443 TQBitmap mask( width(), height(), true );
444 TQPainter p( &mask );
445 TQBrush brush( TQt::white, TQt::SolidPattern );
446 p.setBrush( brush );
447
448 int i = 0, z = 0;
449 for (; i < 4; ++i) {
450 TQPointArray corner;
451 corner.makeArc(corners[i].x(), corners[i].y(), 40, 40, i * 16 * 90, 16 * 90);
452
453 d->surround.resize( z + corner.count() );
454 for (unsigned int s = 0; s < corner.count() - 1; s++) {
455 d->surround.setPoint( z++, corner[s] );
456 }
457
458 if (bottom && i == 2) {
459 if (right) {
460 d->surround.resize( z + 3 );
461 d->surround.setPoint( z++, TQPoint( width() - xh, height() - 11 ) );
462 d->surround.setPoint( z++, TQPoint( width() - 20, height() ) );
463 d->surround.setPoint( z++, TQPoint( width() - xl, height() - 11 ) );
464 } else {
465 d->surround.resize( z + 3 );
466 d->surround.setPoint( z++, TQPoint( xl, height() - 11 ) );
467 d->surround.setPoint( z++, TQPoint( 20, height() ) );
468 d->surround.setPoint( z++, TQPoint( xh, height() - 11 ) );
469 }
470 } else if (!bottom && i == 0) {
471 if (right) {
472 d->surround.resize( z + 3 );
473 d->surround.setPoint( z++, TQPoint( width() - xl, 10 ) );
474 d->surround.setPoint( z++, TQPoint( width() - 20, 0 ) );
475 d->surround.setPoint( z++, TQPoint( width() - xh, 10 ) );
476 } else {
477 d->surround.resize( z + 3 );
478 d->surround.setPoint( z++, TQPoint( xh, 10 ) );
479 d->surround.setPoint( z++, TQPoint( 20, 0 ) );
480 d->surround.setPoint( z++, TQPoint( xl, 10 ) );
481 }
482 }
483 }
484
485 d->surround.resize( z + 1 );
486 d->surround.setPoint( z, d->surround[0] );
487 p.drawPolygon( d->surround );
488 setMask(mask);
489
490 move( right ? d->anchor.x() - width() + 20 : ( d->anchor.x() < 11 ? 11 : d->anchor.x() - 20 ),
491 bottom ? d->anchor.y() - height() : ( d->anchor.y() < 11 ? 11 : d->anchor.y() ) );
492
493 update();
494}
495
496//
497// Convenience Methods
498//
499
500KPassivePopup *KPassivePopup::message( const TQString &caption, const TQString &text,
501 const TQPixmap &icon,
502 TQWidget *parent, const char *name, int timeout )
503{
504 return message( DEFAULT_POPUP_TYPE, caption, text, icon, parent, name, timeout );
505}
506
507KPassivePopup *KPassivePopup::message( const TQString &text, TQWidget *parent, const char *name )
508{
509 return message( DEFAULT_POPUP_TYPE, TQString::null, text, TQPixmap(), parent, name );
510}
511
512KPassivePopup *KPassivePopup::message( const TQString &caption, const TQString &text,
513 TQWidget *parent, const char *name )
514{
515 return message( DEFAULT_POPUP_TYPE, caption, text, TQPixmap(), parent, name );
516}
517
518KPassivePopup *KPassivePopup::message( const TQString &caption, const TQString &text,
519 const TQPixmap &icon, WId parent, const char *name, int timeout )
520{
521 return message( DEFAULT_POPUP_TYPE, caption, text, icon, parent, name, timeout );
522}
523
524KPassivePopup *KPassivePopup::message( int popupStyle, const TQString &caption, const TQString &text,
525 const TQPixmap &icon,
526 TQWidget *parent, const char *name, int timeout )
527{
528 KPassivePopup *pop = new KPassivePopup( popupStyle, parent, name );
529 pop->setAutoDelete( true );
530 pop->setView( caption, text, icon );
531 pop->hideDelay = timeout;
532 pop->show();
533
534 return pop;
535}
536
537KPassivePopup *KPassivePopup::message( int popupStyle, const TQString &text, TQWidget *parent, const char *name )
538{
539 return message( popupStyle, TQString::null, text, TQPixmap(), parent, name );
540}
541
542KPassivePopup *KPassivePopup::message( int popupStyle, const TQString &caption, const TQString &text,
543 TQWidget *parent, const char *name )
544{
545 return message( popupStyle, caption, text, TQPixmap(), parent, name );
546}
547
548KPassivePopup *KPassivePopup::message( int popupStyle, const TQString &caption, const TQString &text,
549 const TQPixmap &icon, WId parent, const char *name, int timeout )
550{
551 KPassivePopup *pop = new KPassivePopup( popupStyle, parent, name );
552 pop->setAutoDelete( true );
553 pop->setView( caption, text, icon );
554 pop->hideDelay = timeout;
555 pop->show();
556
557 return pop;
558}
KDialog::marginHint
static int marginHint()
Return the number of pixels you shall use between a dialog edge and the outermost widget(s) according...
Definition: kdialog.cpp:104
KDialog::spacingHint
static int spacingHint()
Return the number of pixels you shall use between widgets inside a dialog according to the KDE standa...
Definition: kdialog.cpp:110
KPassivePopup
A dialog-like popup that displays messages without interupting the user.
Definition: kpassivepopup.h:67
KPassivePopup::standardView
TQVBox * standardView(const TQString &caption, const TQString &text, const TQPixmap &icon, TQWidget *parent=0L)
Returns a widget that is used as standard view if one of the setView() methods taking the TQString ar...
Definition: kpassivepopup.cpp:138
KPassivePopup::moveNear
void moveNear(TQRect target)
Moves the popup to be adjacent to the icon of the specified rectangle.
Definition: kpassivepopup.cpp:357
KPassivePopup::KPassivePopup
KPassivePopup(TQWidget *parent=0, const char *name=0, WFlags f=0)
Creates a popup for the specified widget.
Definition: kpassivepopup.cpp:49
KPassivePopup::hidden
void hidden(KPassivePopup *)
Emitted when the popup is hidden.
KPassivePopup::timeout
int timeout() const
Returns the delay before the popup is removed automatically.
Definition: kpassivepopup.h:157
KPassivePopup::setTimeout
void setTimeout(int delay)
Sets the delay for the popup is removed automatically.
Definition: kpassivepopup.cpp:223
KPassivePopup::setView
void setView(TQWidget *child)
Sets the main view to be the specified widget (which must be a child of the popup).
Definition: kpassivepopup.cpp:108
KPassivePopup::~KPassivePopup
virtual ~KPassivePopup()
Cleans up.
Definition: kpassivepopup.cpp:103
KPassivePopup::autoDelete
bool autoDelete() const
Definition: kpassivepopup.h:171
KPassivePopup::paintEvent
virtual void paintEvent(TQPaintEvent *pe)
Overwrite to paint the border when PopupStyle == Balloon.
Definition: kpassivepopup.cpp:409
KPassivePopup::setAutoDelete
virtual void setAutoDelete(bool autoDelete)
Enables / disables auto-deletion of this widget when the timeout occurs.
Definition: kpassivepopup.cpp:236
KPassivePopup::positionSelf
virtual void positionSelf()
This method positions the popup.
Definition: kpassivepopup.cpp:316
KPassivePopup::mouseReleaseEvent
virtual void mouseReleaseEvent(TQMouseEvent *e)
Reimplemented to detect mouse clicks.
Definition: kpassivepopup.cpp:241
KPassivePopup::updateMask
void updateMask()
Updates the transparency mask.
Definition: kpassivepopup.cpp:421
KPassivePopup::Boxed
@ Boxed
Information will appear in a framed box (default)
Definition: kpassivepopup.h:79
KPassivePopup::Balloon
@ Balloon
Information will appear in a comic-alike balloon.
Definition: kpassivepopup.h:80
KPassivePopup::show
virtual void show()
Reimplemented to reposition the popup.
Definition: kpassivepopup.cpp:251
KPassivePopup::defaultArea
TQRect defaultArea() const
If no relative window (eg taskbar button, system tray window) is available, use this rectangle (pass ...
Definition: kpassivepopup.cpp:296
KPassivePopup::clicked
void clicked()
Emitted when the popup is clicked.
KPassivePopup::message
static KPassivePopup * message(const TQString &text, TQWidget *parent, const char *name=0)
Convenience method that displays popup with the specified message beside the icon of the specified wi...
Definition: kpassivepopup.cpp:507
KPassivePopup::setAnchor
void setAnchor(const TQPoint &anchor)
Sets the anchor of this balloon.
Definition: kpassivepopup.cpp:403
KPassivePopup::hideEvent
virtual void hideEvent(TQHideEvent *)
Reimplemented to destroy the object when autoDelete() is enabled.
Definition: kpassivepopup.cpp:288
TDEGlobalSettings::desktopGeometry
static TQRect desktopGeometry(const TQPoint &point)
NETPoint::x
int x
NETPoint::y
int y
NETRect
NETRect::pos
NETPoint pos
NETRect::size
NETSize size
NETSize::height
int height
NETSize::width
int width

tdeui

Skip menu "tdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeui

Skip menu "tdeui"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeui by doxygen 1.9.4
This website is maintained by Timothy Pearson.