libtdepim

progressdialog.cpp
1/*
2 * progressdialog.cpp
3 *
4 * Copyright (c) 2004 Till Adam <adam@kde.org>,
5 * David Faure <faure@kde.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 * In addition, as a special exception, the copyright holders give
21 * permission to link the code of this program with any edition of
22 * the TQt library by Trolltech AS, Norway (or with modified versions
23 * of TQt that use the same license as TQt), and distribute linked
24 * combinations including the two. You must obey the GNU General
25 * Public License in all respects for all of the code used other than
26 * TQt. If you modify this file, you may extend this exception to
27 * your version of the file, but you are not obligated to do so. If
28 * you do not wish to do so, delete this exception statement from
29 * your version.
30 */
31
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include <tqapplication.h>
37#include <tqlayout.h>
38#include <tqprogressbar.h>
39#include <tqtimer.h>
40#include <tqheader.h>
41#include <tqobject.h>
42#include <tqscrollview.h>
43#include <tqtoolbutton.h>
44#include <tqpushbutton.h>
45#include <tqvbox.h>
46#include <tqtooltip.h>
47
48#include <tdelocale.h>
49#include <kdialog.h>
50#include <kstdguiitem.h>
51#include <kiconloader.h>
52#include <kdebug.h>
53
54#include "progressdialog.h"
55#include "progressmanager.h"
56#include "ssllabel.h"
57#include <tqwhatsthis.h>
58
59namespace KPIM {
60
61class TransactionItem;
62
63TransactionItemView::TransactionItemView( TQWidget * parent,
64 const char * name,
65 WFlags f )
66 : TQScrollView( parent, name, f ) {
67 setFrameStyle( NoFrame );
68 mBigBox = new TQVBox( viewport() );
69 mBigBox->setSpacing( 5 );
70 addChild( mBigBox );
71 setResizePolicy( TQScrollView::AutoOneFit ); // Fit so that the box expands horizontally
72}
73
74TransactionItem* TransactionItemView::addTransactionItem( ProgressItem* item, bool first )
75{
76 TransactionItem *ti = new TransactionItem( mBigBox, item, first );
77 ti->hide();
78 TQTimer::singleShot( 1000, ti, TQ_SLOT( show() ) );
79 return ti;
80}
81
82void TransactionItemView::resizeContents( int w, int h )
83{
84 // (handling of TQEvent::LayoutHint in TQScrollView calls this method)
85 //kdDebug(5300) << k_funcinfo << w << "," << h << endl;
86 TQScrollView::resizeContents( w, h );
87 // Tell the layout in the parent (progressdialog) that our size changed
88 updateGeometry();
89 // Resize the parent (progressdialog) - this works but resize horizontally too often
90 //parentWidget()->adjustSize();
91
92 TQApplication::sendPostedEvents( 0, TQEvent::ChildInserted );
93 TQApplication::sendPostedEvents( 0, TQEvent::LayoutHint );
94 TQSize sz = parentWidget()->sizeHint();
95 int currentWidth = parentWidget()->width();
96 // Don't resize to sz.width() every time when it only reduces a little bit
97 if ( currentWidth < sz.width() || currentWidth > sz.width() + 100 )
98 currentWidth = sz.width();
99 parentWidget()->resize( currentWidth, sz.height() );
100}
101
102TQSize TransactionItemView::sizeHint() const
103{
104 return minimumSizeHint();
105}
106
107TQSize TransactionItemView::minimumSizeHint() const
108{
109 int f = 2 * frameWidth();
110 // Make room for a vertical scrollbar in all cases, to avoid a horizontal one
111 int vsbExt = verticalScrollBar()->sizeHint().width();
112 int minw = topLevelWidget()->width() / 3;
113 int maxh = topLevelWidget()->height() / 2;
114 TQSize sz( mBigBox->minimumSizeHint() );
115 sz.setWidth( TQMAX( sz.width(), minw ) + f + vsbExt );
116 sz.setHeight( TQMIN( sz.height(), maxh ) + f );
117 return sz;
118}
119
120
121void TransactionItemView::slotLayoutFirstItem()
122{
123 /*
124 The below relies on some details in TQt's behaviour regarding deleting
125 objects. This slot is called from the destroyed signal of an item just
126 going away. That item is at that point still in the list of chilren, but
127 since the vtable is already gone, it will have type TQObject. The first
128 one with both the right name and the right class therefor is what will
129 be the first item very shortly. That's the one we want to remove the
130 hline for.
131 */
132 TQObject *o = mBigBox->child( "TransactionItem", "KPIM::TransactionItem" );
133 TransactionItem *ti = dynamic_cast<TransactionItem*>( o );
134 if ( ti ) {
135 ti->hideHLine();
136 }
137}
138
139
140// ----------------------------------------------------------------------------
141
142TransactionItem::TransactionItem( TQWidget* parent,
143 ProgressItem *item, bool first )
144 : TQVBox( parent, "TransactionItem" ), mCancelButton( 0 ), mItem( item )
145
146{
147 setSpacing( 2 );
148 setMargin( 2 );
149 setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
150
151 mFrame = new TQFrame( this );
152 mFrame->setFrameShape( TQFrame::HLine );
153 mFrame->setFrameShadow( TQFrame::Raised );
154 mFrame->show();
155 setStretchFactor( mFrame, 3 );
156
157 TQHBox *h = new TQHBox( this );
158 h->setSpacing( 5 );
159
160 mItemLabel = new TQLabel( item->label(), h );
161 // always interpret the label text as RichText, but disable word wrapping
162 mItemLabel->setTextFormat( TQt::RichText );
163 mItemLabel->setAlignment( TQt::AlignAuto | TQt::AlignVCenter | TQt::SingleLine );
164 h->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
165
166 mProgress = new TQProgressBar( 100, h );
167 mProgress->setProgress( item->progress() );
168
169 if ( item->canBeCanceled() ) {
170 mCancelButton = new TQPushButton( SmallIcon( "cancel" ), TQString(), h );
171 TQToolTip::add( mCancelButton, i18n("Cancel this operation.") );
172 connect ( mCancelButton, TQ_SIGNAL( clicked() ),
173 this, TQ_SLOT( slotItemCanceled() ));
174 }
175
176 h = new TQHBox( this );
177 h->setSpacing( 5 );
178 h->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
179 mSSLLabel = new SSLLabel( h );
180 mSSLLabel->setSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ) );
181 mItemStatus = new TQLabel( item->status(), h );
182 // always interpret the status text as RichText, but disable word wrapping
183 mItemStatus->setTextFormat( TQt::RichText );
184 mItemStatus->setAlignment( TQt::AlignAuto | TQt::AlignVCenter | TQt::SingleLine );
185 // richtext leads to sizeHint acting as if wrapping was enabled though,
186 // so make sure we only ever have the height of one line.
187 mItemStatus->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored ) );
188 mItemStatus->setFixedHeight( mItemLabel->sizeHint().height() );
189 setCrypto( item->usesCrypto() );
190 if( first ) hideHLine();
191}
192
193TransactionItem::~TransactionItem()
194{
195}
196
197void TransactionItem::hideHLine()
198{
199 mFrame->hide();
200}
201
202void TransactionItem::setProgress( int progress )
203{
204 mProgress->setProgress( progress );
205}
206
207void TransactionItem::setLabel( const TQString& label )
208{
209 mItemLabel->setText( label );
210}
211
212void TransactionItem::setStatus( const TQString& status )
213{
214 mItemStatus->setText( status );
215}
216
217void TransactionItem::setCrypto( bool on )
218{
219 if (on)
220 mSSLLabel->setEncrypted( true );
221 else
222 mSSLLabel->setEncrypted( false );
223
224 mSSLLabel->setState( mSSLLabel->lastState() );
225}
226
227void TransactionItem::setTotalSteps( int totalSteps )
228{
229 mProgress->setTotalSteps( totalSteps );
230}
231
232void TransactionItem::slotItemCanceled()
233{
234 if ( mItem )
235 mItem->cancel();
236}
237
238
239void TransactionItem::addSubTransaction( ProgressItem* /*item*/ )
240{
241
242}
243
244
245// ---------------------------------------------------------------------------
246
247ProgressDialog::ProgressDialog( TQWidget* alignWidget, TQWidget* parent, const char* name )
248 : OverlayWidget( alignWidget, parent, name ), mWasLastShown( false )
249{
250 setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); // TQFrame
251 setSpacing( 0 ); // TQHBox
252 setMargin( 1 );
253
254 mScrollView = new TransactionItemView( this, "ProgressScrollView" );
255
256 // No more close button for now, since there is no more autoshow
257 /*
258 TQVBox* rightBox = new TQVBox( this );
259 TQToolButton* pbClose = new TQToolButton( rightBox );
260 pbClose->setAutoRaise(true);
261 pbClose->setSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ) );
262 pbClose->setFixedSize( 16, 16 );
263 pbClose->setIconSet( TDEGlobal::iconLoader()->loadIconSet( "window-close", TDEIcon::Small, 14 ) );
264 TQToolTip::add( pbClose, i18n( "Hide detailed progress window" ) );
265 connect(pbClose, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotClose()));
266 TQWidget* spacer = new TQWidget( rightBox ); // don't let the close button take up all the height
267 rightBox->setStretchFactor( spacer, 100 );
268 */
269
270 /*
271 * Get the singleton ProgressManager item which will inform us of
272 * appearing and vanishing items.
273 */
274 ProgressManager *pm = ProgressManager::instance();
275 connect ( pm, TQ_SIGNAL( progressItemAdded( KPIM::ProgressItem* ) ),
276 this, TQ_SLOT( slotTransactionAdded( KPIM::ProgressItem* ) ) );
277 connect ( pm, TQ_SIGNAL( progressItemCompleted( KPIM::ProgressItem* ) ),
278 this, TQ_SLOT( slotTransactionCompleted( KPIM::ProgressItem* ) ) );
279 connect ( pm, TQ_SIGNAL( progressItemProgress( KPIM::ProgressItem*, unsigned int ) ),
280 this, TQ_SLOT( slotTransactionProgress( KPIM::ProgressItem*, unsigned int ) ) );
281 connect ( pm, TQ_SIGNAL( progressItemStatus( KPIM::ProgressItem*, const TQString& ) ),
282 this, TQ_SLOT( slotTransactionStatus( KPIM::ProgressItem*, const TQString& ) ) );
283 connect ( pm, TQ_SIGNAL( progressItemLabel( KPIM::ProgressItem*, const TQString& ) ),
284 this, TQ_SLOT( slotTransactionLabel( KPIM::ProgressItem*, const TQString& ) ) );
285 connect ( pm, TQ_SIGNAL( progressItemUsesCrypto(KPIM::ProgressItem*, bool) ),
286 this, TQ_SLOT( slotTransactionUsesCrypto( KPIM::ProgressItem*, bool ) ) );
287 connect ( pm, TQ_SIGNAL( progressItemUsesBusyIndicator(KPIM::ProgressItem*, bool) ),
288 this, TQ_SLOT( slotTransactionUsesBusyIndicator( KPIM::ProgressItem*, bool ) ) );
289 connect ( pm, TQ_SIGNAL( showProgressDialog() ),
290 this, TQ_SLOT( slotShow() ) );
291}
292
293void ProgressDialog::closeEvent( TQCloseEvent* e )
294{
295 e->accept();
296 hide();
297}
298
299
300/*
301 * Destructor
302 */
303ProgressDialog::~ProgressDialog()
304{
305 // no need to delete child widgets.
306}
307
308void ProgressDialog::slotTransactionAdded( ProgressItem *item )
309{
310 TransactionItem *parent = 0;
311 if ( item->parent() ) {
312 if ( mTransactionsToListviewItems.contains( item->parent() ) ) {
313 parent = mTransactionsToListviewItems[ item->parent() ];
314 parent->addSubTransaction( item );
315 }
316 } else {
317 const bool first = mTransactionsToListviewItems.empty();
318 TransactionItem *ti = mScrollView->addTransactionItem( item, first );
319 if ( ti )
320 mTransactionsToListviewItems.replace( item, ti );
321 if ( first && mWasLastShown )
322 TQTimer::singleShot( 1000, this, TQ_SLOT( slotShow() ) );
323
324 }
325}
326
327void ProgressDialog::slotTransactionCompleted( ProgressItem *item )
328{
329 if ( mTransactionsToListviewItems.contains( item ) ) {
330 TransactionItem *ti = mTransactionsToListviewItems[ item ];
331 mTransactionsToListviewItems.remove( item );
332 ti->setItemComplete();
333 TQTimer::singleShot( 3000, ti, TQ_SLOT( deleteLater() ) );
334 // see the slot for comments as to why that works
335 connect ( ti, TQ_SIGNAL( destroyed() ),
336 mScrollView, TQ_SLOT( slotLayoutFirstItem() ) );
337 }
338 // This was the last item, hide.
339 if ( mTransactionsToListviewItems.empty() )
340 TQTimer::singleShot( 3000, this, TQ_SLOT( slotHide() ) );
341}
342
343void ProgressDialog::slotTransactionCanceled( ProgressItem* )
344{
345}
346
347void ProgressDialog::slotTransactionProgress( ProgressItem *item,
348 unsigned int progress )
349{
350 if ( mTransactionsToListviewItems.contains( item ) ) {
351 TransactionItem *ti = mTransactionsToListviewItems[ item ];
352 ti->setProgress( progress );
353 }
354}
355
356void ProgressDialog::slotTransactionStatus( ProgressItem *item,
357 const TQString& status )
358{
359 if ( mTransactionsToListviewItems.contains( item ) ) {
360 TransactionItem *ti = mTransactionsToListviewItems[ item ];
361 ti->setStatus( status );
362 }
363}
364
365void ProgressDialog::slotTransactionLabel( ProgressItem *item,
366 const TQString& label )
367{
368 if ( mTransactionsToListviewItems.contains( item ) ) {
369 TransactionItem *ti = mTransactionsToListviewItems[ item ];
370 ti->setLabel( label );
371 }
372}
373
374
375void ProgressDialog::slotTransactionUsesCrypto( ProgressItem *item,
376 bool value )
377{
378 if ( mTransactionsToListviewItems.contains( item ) ) {
379 TransactionItem *ti = mTransactionsToListviewItems[ item ];
380 ti->setCrypto( value );
381 }
382}
383
384void ProgressDialog::slotTransactionUsesBusyIndicator( KPIM::ProgressItem *item, bool value )
385{
386 if ( mTransactionsToListviewItems.contains( item ) ) {
387 TransactionItem *ti = mTransactionsToListviewItems[ item ];
388 if ( value )
389 ti->setTotalSteps( 0 );
390 else
391 ti->setTotalSteps( 100 );
392 }
393}
394
395void ProgressDialog::slotShow()
396{
397 setVisible( true );
398}
399
400void ProgressDialog::slotHide()
401{
402 // check if a new item showed up since we started the timer. If not, hide
403 if ( mTransactionsToListviewItems.isEmpty() ) {
404 setVisible( false );
405 }
406}
407
408void ProgressDialog::slotClose()
409{
410 mWasLastShown = false;
411 setVisible( false );
412}
413
414void ProgressDialog::setVisible( bool b )
415{
416 if ( b )
417 show();
418 else
419 hide();
420 emit visibilityChanged( b );
421}
422
423void ProgressDialog::slotToggleVisibility()
424{
425 /* Since we are only hiding with a timeout, there is a short period of
426 * time where the last item is still visible, but clicking on it in
427 * the statusbarwidget should not display the dialog, because there
428 * are no items to be shown anymore. Guard against that.
429 */
430 mWasLastShown = !isShown();
431 if ( isShown() || !mTransactionsToListviewItems.isEmpty() )
432 setVisible( !isShown() );
433}
434
435}
436
437#include "progressdialog.moc"
TDEPIM classes for drag and drop of mails.