libtdepim

statusbarprogresswidget.cpp
1 /*
2  statusbarprogresswidget.cpp
3 
4  This file is part of KMail, the KDE mail client.
5 
6  (C) 2004 KMail Authors
7  Includes StatusbarProgressWidget which is based on KIOLittleProgressDlg
8  by Matt Koss <koss@miesto.sk>
9 
10  KMail is free software; you can redistribute it and/or modify it
11  under the terms of the GNU General Public License, version 2, as
12  published by the Free Software Foundation.
13 
14  KMail is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 
23  In addition, as a special exception, the copyright holders give
24  permission to link the code of this program with any edition of
25  the TQt library by Trolltech AS, Norway (or with modified versions
26  of TQt that use the same license as TQt), and distribute linked
27  combinations including the two. You must obey the GNU General
28  Public License in all respects for all of the code used other than
29  TQt. If you modify this file, you may extend this exception to
30  your version of the file, but you are not obligated to do so. If
31  you do not wish to do so, delete this exception statement from
32  your version.
33 */
34 
35 
36 #include "ssllabel.h"
37 using KPIM::SSLLabel;
38 #include "progressmanager.h"
39 using KPIM::ProgressItem;
41 
42 #include <kprogress.h>
43 #include <kiconloader.h>
44 #include <kdebug.h>
45 
46 #include <tqtimer.h>
47 #include <tqlabel.h>
48 #include <tqpushbutton.h>
49 #include <tqtooltip.h>
50 #include <tdelocale.h>
51 #include <tqlayout.h>
52 #include <tqwidgetstack.h>
53 #include <tqframe.h>
54 
55 #include "progressdialog.h"
56 #include "statusbarprogresswidget.h"
57 
58 using namespace KPIM;
59 
60 //-----------------------------------------------------------------------------
61 StatusbarProgressWidget::StatusbarProgressWidget( ProgressDialog* progressDialog, TQWidget* parent, bool button )
62  : TQFrame( parent ), mCurrentItem( 0 ), mProgressDialog( progressDialog ),
63  mDelayTimer( 0 ), mBusyTimer( 0 )
64 {
65  m_bShowButton = button;
66  int w = fontMetrics().width( " 999.9 kB/s 00:00:01 " ) + 8;
67  box = new TQHBoxLayout( this, 0, 0 );
68 
69  m_pButton = new TQPushButton( this );
70  m_pButton->setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum,
71  TQSizePolicy::Minimum ) );
72  m_pButton->setPixmap( SmallIcon( "go-up" ) );
73  box->addWidget( m_pButton );
74  stack = new TQWidgetStack( this );
75  stack->setMaximumHeight( fontMetrics().height() );
76  box->addWidget( stack );
77 
78  m_sslLabel = new SSLLabel( this );
79  box->addWidget( m_sslLabel );
80 
81  TQToolTip::add( m_pButton, i18n("Open detailed progress dialog") );
82 
83  m_pProgressBar = new KProgress( this );
84  m_pProgressBar->setLineWidth( 1 );
85  m_pProgressBar->setFrameStyle( TQFrame::Box );
86  m_pProgressBar->installEventFilter( this );
87  m_pProgressBar->setMinimumWidth( w );
88  stack->addWidget( m_pProgressBar, 1 );
89 
90  m_pLabel = new TQLabel( TQString(), this );
91  m_pLabel->setAlignment( AlignHCenter | AlignVCenter );
92  m_pLabel->installEventFilter( this );
93  m_pLabel->setMinimumWidth( w );
94  stack->addWidget( m_pLabel, 2 );
95  m_pButton->setMaximumHeight( fontMetrics().height() );
96  setMinimumWidth( minimumSizeHint().width() );
97 
98  mode = None;
99  setMode();
100 
101  connect( m_pButton, TQ_SIGNAL( clicked() ),
102  progressDialog, TQ_SLOT( slotToggleVisibility() ) );
103 
104  connect ( ProgressManager::instance(), TQ_SIGNAL( progressItemAdded( KPIM::ProgressItem * ) ),
105  this, TQ_SLOT( slotProgressItemAdded( KPIM::ProgressItem * ) ) );
106  connect ( ProgressManager::instance(), TQ_SIGNAL( progressItemCompleted( KPIM::ProgressItem * ) ),
107  this, TQ_SLOT( slotProgressItemCompleted( KPIM::ProgressItem * ) ) );
108  connect ( ProgressManager::instance(), TQ_SIGNAL(progressItemUsesBusyIndicator(KPIM::ProgressItem*,bool)),
109  this, TQ_SLOT( updateBusyMode() ) );
110 
111  connect ( progressDialog, TQ_SIGNAL( visibilityChanged( bool )),
112  this, TQ_SLOT( slotProgressDialogVisible( bool ) ) );
113 
114  mDelayTimer = new TQTimer( this );
115  connect ( mDelayTimer, TQ_SIGNAL( timeout() ),
116  this, TQ_SLOT( slotShowItemDelayed() ) );
117 }
118 
119 // There are three cases: no progressitem, one progressitem (connect to it directly),
120 // or many progressitems (display busy indicator). Let's call them 0,1,N.
121 // In slot..Added we can only end up in 1 or N.
122 // In slot..Removed we can end up in 0, 1, or we can stay in N if we were already.
123 
124 void StatusbarProgressWidget::updateBusyMode()
125 {
126  connectSingleItem(); // if going to 1 item
127  if ( mCurrentItem ) { // Exactly one item
128  delete mBusyTimer;
129  mBusyTimer = 0;
130  mDelayTimer->start( 1000, true );
131  }
132  else { // N items
133  if ( !mBusyTimer ) {
134  mBusyTimer = new TQTimer( this );
135  connect( mBusyTimer, TQ_SIGNAL( timeout() ),
136  this, TQ_SLOT( slotBusyIndicator() ) );
137  mDelayTimer->start( 1000, true );
138  }
139  }
140 }
141 
142 void StatusbarProgressWidget::slotProgressItemAdded( ProgressItem *item )
143 {
144  if ( item->parent() )
145  return; // we are only interested in top level items
146 
147  updateBusyMode();
148 }
149 
150 void StatusbarProgressWidget::slotProgressItemCompleted( ProgressItem *item )
151 {
152  if ( item->parent() ) return; // we are only interested in top level items
153  connectSingleItem(); // if going back to 1 item
154  if ( ProgressManager::instance()->isEmpty() ) { // No item
155  // Done. In 5s the progress-widget will close, then we can clean up the statusbar
156  TQTimer::singleShot( 5000, this, TQ_SLOT( slotClean() ) );
157  } else if ( mCurrentItem ) { // Exactly one item
158  delete mBusyTimer;
159  mBusyTimer = 0;
160  activateSingleItemMode();
161  }
162 }
163 
164 void StatusbarProgressWidget::connectSingleItem()
165 {
166  if ( mCurrentItem ) {
167  disconnect ( mCurrentItem, TQ_SIGNAL( progressItemProgress( KPIM::ProgressItem *, unsigned int ) ),
168  this, TQ_SLOT( slotProgressItemProgress( KPIM::ProgressItem *, unsigned int ) ) );
169  mCurrentItem = 0;
170  }
171  mCurrentItem = ProgressManager::instance()->singleItem();
172  if ( mCurrentItem ) {
173  connect ( mCurrentItem, TQ_SIGNAL( progressItemProgress( KPIM::ProgressItem *, unsigned int ) ),
174  this, TQ_SLOT( slotProgressItemProgress( KPIM::ProgressItem *, unsigned int ) ) );
175  }
176 }
177 
178 void StatusbarProgressWidget::activateSingleItemMode()
179 {
180  m_pProgressBar->setTotalSteps( 100 );
181  m_pProgressBar->setProgress( mCurrentItem->progress() );
182  m_pProgressBar->setPercentageVisible( true );
183 }
184 
185 void StatusbarProgressWidget::slotShowItemDelayed()
186 {
187  bool noItems = ProgressManager::instance()->isEmpty();
188  if ( mCurrentItem ) {
189  activateSingleItemMode();
190  } else if ( !noItems ) { // N items
191  m_pProgressBar->setTotalSteps( 0 );
192  m_pProgressBar->setPercentageVisible( false );
193  Q_ASSERT( mBusyTimer );
194  if ( mBusyTimer )
195  mBusyTimer->start( 100 );
196  }
197 
198  if ( !noItems && mode == None ) {
199  mode = Progress;
200  setMode();
201  }
202 }
203 
204 void StatusbarProgressWidget::slotBusyIndicator()
205 {
206  int p = m_pProgressBar->progress();
207  m_pProgressBar->setProgress( p + 10 );
208 }
209 
210 void StatusbarProgressWidget::slotProgressItemProgress( ProgressItem *item, unsigned int value )
211 {
212  Q_ASSERT( item == mCurrentItem); // the only one we should be connected to
213  m_pProgressBar->setProgress( value );
214 }
215 
216 void StatusbarProgressWidget::slotSetSSL( bool ssl )
217 {
218  m_sslLabel->setEncrypted( ssl );
219 }
220 
221 void StatusbarProgressWidget::setMode() {
222  switch ( mode ) {
223  case None:
224  if ( m_bShowButton ) {
225  m_pButton->hide();
226  }
227  m_sslLabel->setState( SSLLabel::Done );
228  // show the empty label in order to make the status bar look better
229  stack->show();
230  stack->raiseWidget( m_pLabel );
231  break;
232 
233 #if 0
234  case Label:
235  if ( m_bShowButton ) {
236  m_pButton->show();
237  }
238  m_sslLabel->setState( m_sslLabel->lastState() );
239  stack->show();
240  stack->raiseWidget( m_pLabel );
241  break;
242 #endif
243 
244  case Progress:
245  stack->show();
246  stack->raiseWidget( m_pProgressBar );
247  if ( m_bShowButton ) {
248  m_pButton->show();
249  }
250  m_sslLabel->setState( m_sslLabel->lastState() );
251  break;
252  }
253 }
254 
255 void StatusbarProgressWidget::slotClean()
256 {
257  // check if a new item showed up since we started the timer. If not, clear
258  if ( ProgressManager::instance()->isEmpty() ) {
259  m_pProgressBar->setProgress( 0 );
260  //m_pLabel->clear();
261  mode = None;
262  setMode();
263  }
264 }
265 
266 bool StatusbarProgressWidget::eventFilter( TQObject *, TQEvent *ev )
267 {
268  if ( ev->type() == TQEvent::MouseButtonPress ) {
269  TQMouseEvent *e = (TQMouseEvent*)ev;
270 
271  if ( e->button() == TQt::LeftButton && mode != None ) { // toggle view on left mouse button
272  // Consensus seems to be that we should show/hide the fancy dialog when the user
273  // clicks anywhere in the small one.
274  mProgressDialog->slotToggleVisibility();
275  return true;
276  }
277  }
278  return false;
279 }
280 
281 void StatusbarProgressWidget::slotProgressDialogVisible( bool b )
282 {
283  // Update the hide/show button when the detailed one is shown/hidden
284  if ( b ) {
285  m_pButton->setPixmap( SmallIcon( "go-down" ) );
286  TQToolTip::remove( m_pButton );
287  TQToolTip::add( m_pButton, i18n("Hide detailed progress window") );
288  setMode();
289  } else {
290  m_pButton->setPixmap( SmallIcon( "go-up" ) );
291  TQToolTip::remove( m_pButton );
292  TQToolTip::add( m_pButton, i18n("Show detailed progress window") );
293  }
294 }
295 
296 #include "statusbarprogresswidget.moc"
The ProgressManager singleton keeps track of all ongoing transactions and notifies observers (progres...
TDEPIM classes for drag and drop of mails.