summaryrefslogtreecommitdiffstats
path: root/libkdepim/statusbarprogresswidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libkdepim/statusbarprogresswidget.cpp')
-rw-r--r--libkdepim/statusbarprogresswidget.cpp287
1 files changed, 287 insertions, 0 deletions
diff --git a/libkdepim/statusbarprogresswidget.cpp b/libkdepim/statusbarprogresswidget.cpp
new file mode 100644
index 000000000..3d0229fc5
--- /dev/null
+++ b/libkdepim/statusbarprogresswidget.cpp
@@ -0,0 +1,287 @@
+/*
+ statusbarprogresswidget.cpp
+
+ This file is part of KMail, the KDE mail client.
+
+ (C) 2004 KMail Authors
+ Includes StatusbarProgressWidget which is based on KIOLittleProgressDlg
+ by Matt Koss <koss@miesto.sk>
+
+ KMail is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License, version 2, as
+ published by the Free Software Foundation.
+
+ KMail is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#include "ssllabel.h"
+using KPIM::SSLLabel;
+#include "progressmanager.h"
+using KPIM::ProgressItem;
+using KPIM::ProgressManager;
+
+#include <kprogress.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+
+#include <qtimer.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+#include <klocale.h>
+#include <qlayout.h>
+#include <qwidgetstack.h>
+#include <qframe.h>
+
+#include "progressdialog.h"
+#include "statusbarprogresswidget.h"
+
+using namespace KPIM;
+
+//-----------------------------------------------------------------------------
+StatusbarProgressWidget::StatusbarProgressWidget( ProgressDialog* progressDialog, QWidget* parent, bool button )
+ : QFrame( parent ), mCurrentItem( 0 ), mProgressDialog( progressDialog ),
+ mDelayTimer( 0 ), mBusyTimer( 0 )
+{
+ m_bShowButton = button;
+ int w = fontMetrics().width( " 999.9 kB/s 00:00:01 " ) + 8;
+ box = new QHBoxLayout( this, 0, 0 );
+
+ m_pButton = new QPushButton( this );
+ m_pButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum,
+ QSizePolicy::Minimum ) );
+ m_pButton->setPixmap( SmallIcon( "up" ) );
+ box->addWidget( m_pButton );
+ stack = new QWidgetStack( this );
+ stack->setMaximumHeight( fontMetrics().height() );
+ box->addWidget( stack );
+
+ m_sslLabel = new SSLLabel( this );
+ box->addWidget( m_sslLabel );
+
+ QToolTip::add( m_pButton, i18n("Open detailed progress dialog") );
+
+ m_pProgressBar = new KProgress( this );
+ m_pProgressBar->setLineWidth( 1 );
+ m_pProgressBar->setFrameStyle( QFrame::Box );
+ m_pProgressBar->installEventFilter( this );
+ m_pProgressBar->setMinimumWidth( w );
+ stack->addWidget( m_pProgressBar, 1 );
+
+ m_pLabel = new QLabel( QString::null, this );
+ m_pLabel->setAlignment( AlignHCenter | AlignVCenter );
+ m_pLabel->installEventFilter( this );
+ m_pLabel->setMinimumWidth( w );
+ stack->addWidget( m_pLabel, 2 );
+ m_pButton->setMaximumHeight( fontMetrics().height() );
+ setMinimumWidth( minimumSizeHint().width() );
+
+ mode = None;
+ setMode();
+
+ connect( m_pButton, SIGNAL( clicked() ),
+ progressDialog, SLOT( slotToggleVisibility() ) );
+
+ connect ( ProgressManager::instance(), SIGNAL( progressItemAdded( KPIM::ProgressItem * ) ),
+ this, SLOT( slotProgressItemAdded( KPIM::ProgressItem * ) ) );
+ connect ( ProgressManager::instance(), SIGNAL( progressItemCompleted( KPIM::ProgressItem * ) ),
+ this, SLOT( slotProgressItemCompleted( KPIM::ProgressItem * ) ) );
+
+ connect ( progressDialog, SIGNAL( visibilityChanged( bool )),
+ this, SLOT( slotProgressDialogVisible( bool ) ) );
+
+ mDelayTimer = new QTimer( this );
+ connect ( mDelayTimer, SIGNAL( timeout() ),
+ this, SLOT( slotShowItemDelayed() ) );
+}
+
+// There are three cases: no progressitem, one progressitem (connect to it directly),
+// or many progressitems (display busy indicator). Let's call them 0,1,N.
+// In slot..Added we can only end up in 1 or N.
+// In slot..Removed we can end up in 0, 1, or we can stay in N if we were already.
+
+void StatusbarProgressWidget::slotProgressItemAdded( ProgressItem *item )
+{
+ if ( item->parent() ) return; // we are only interested in top level items
+ connectSingleItem(); // if going to 1 item
+ if ( mCurrentItem ) { // Exactly one item
+ delete mBusyTimer;
+ mBusyTimer = 0;
+ mDelayTimer->start( 1000, true );
+ }
+ else { // N items
+ if ( !mBusyTimer ) {
+ mBusyTimer = new QTimer( this );
+ connect( mBusyTimer, SIGNAL( timeout() ),
+ this, SLOT( slotBusyIndicator() ) );
+ mDelayTimer->start( 1000, true );
+ }
+ }
+}
+
+void StatusbarProgressWidget::slotProgressItemCompleted( ProgressItem *item )
+{
+ if ( item->parent() ) return; // we are only interested in top level items
+ connectSingleItem(); // if going back to 1 item
+ if ( ProgressManager::instance()->isEmpty() ) { // No item
+ // Done. In 5s the progress-widget will close, then we can clean up the statusbar
+ QTimer::singleShot( 5000, this, SLOT( slotClean() ) );
+ } else if ( mCurrentItem ) { // Exactly one item
+ delete mBusyTimer;
+ mBusyTimer = 0;
+ activateSingleItemMode();
+ }
+}
+
+void StatusbarProgressWidget::connectSingleItem()
+{
+ if ( mCurrentItem ) {
+ disconnect ( mCurrentItem, SIGNAL( progressItemProgress( KPIM::ProgressItem *, unsigned int ) ),
+ this, SLOT( slotProgressItemProgress( KPIM::ProgressItem *, unsigned int ) ) );
+ mCurrentItem = 0;
+ }
+ mCurrentItem = ProgressManager::instance()->singleItem();
+ if ( mCurrentItem ) {
+ connect ( mCurrentItem, SIGNAL( progressItemProgress( KPIM::ProgressItem *, unsigned int ) ),
+ this, SLOT( slotProgressItemProgress( KPIM::ProgressItem *, unsigned int ) ) );
+ }
+}
+
+void StatusbarProgressWidget::activateSingleItemMode()
+{
+ m_pProgressBar->setTotalSteps( 100 );
+ m_pProgressBar->setProgress( mCurrentItem->progress() );
+ m_pProgressBar->setPercentageVisible( true );
+}
+
+void StatusbarProgressWidget::slotShowItemDelayed()
+{
+ bool noItems = ProgressManager::instance()->isEmpty();
+ if ( mCurrentItem ) {
+ activateSingleItemMode();
+ } else if ( !noItems ) { // N items
+ m_pProgressBar->setTotalSteps( 0 );
+ m_pProgressBar->setPercentageVisible( false );
+ Q_ASSERT( mBusyTimer );
+ if ( mBusyTimer )
+ mBusyTimer->start( 100 );
+ }
+
+ if ( !noItems && mode == None ) {
+ mode = Progress;
+ setMode();
+ }
+}
+
+void StatusbarProgressWidget::slotBusyIndicator()
+{
+ int p = m_pProgressBar->progress();
+ m_pProgressBar->setProgress( p + 10 );
+}
+
+void StatusbarProgressWidget::slotProgressItemProgress( ProgressItem *item, unsigned int value )
+{
+ Q_ASSERT( item == mCurrentItem); // the only one we should be connected to
+ m_pProgressBar->setProgress( value );
+}
+
+void StatusbarProgressWidget::slotSetSSL( bool ssl )
+{
+ m_sslLabel->setEncrypted( ssl );
+}
+
+void StatusbarProgressWidget::setMode() {
+ switch ( mode ) {
+ case None:
+ if ( m_bShowButton ) {
+ m_pButton->hide();
+ }
+ m_sslLabel->setState( SSLLabel::Done );
+ // show the empty label in order to make the status bar look better
+ stack->show();
+ stack->raiseWidget( m_pLabel );
+ break;
+
+#if 0
+ case Label:
+ if ( m_bShowButton ) {
+ m_pButton->show();
+ }
+ m_sslLabel->setState( m_sslLabel->lastState() );
+ stack->show();
+ stack->raiseWidget( m_pLabel );
+ break;
+#endif
+
+ case Progress:
+ stack->show();
+ stack->raiseWidget( m_pProgressBar );
+ if ( m_bShowButton ) {
+ m_pButton->show();
+ }
+ m_sslLabel->setState( m_sslLabel->lastState() );
+ break;
+ }
+}
+
+void StatusbarProgressWidget::slotClean()
+{
+ // check if a new item showed up since we started the timer. If not, clear
+ if ( ProgressManager::instance()->isEmpty() ) {
+ m_pProgressBar->setProgress( 0 );
+ //m_pLabel->clear();
+ mode = None;
+ setMode();
+ }
+}
+
+bool StatusbarProgressWidget::eventFilter( QObject *, QEvent *ev )
+{
+ if ( ev->type() == QEvent::MouseButtonPress ) {
+ QMouseEvent *e = (QMouseEvent*)ev;
+
+ if ( e->button() == LeftButton && mode != None ) { // toggle view on left mouse button
+ // Consensus seems to be that we should show/hide the fancy dialog when the user
+ // clicks anywhere in the small one.
+ mProgressDialog->slotToggleVisibility();
+ return true;
+ }
+ }
+ return false;
+}
+
+void StatusbarProgressWidget::slotProgressDialogVisible( bool b )
+{
+ // Update the hide/show button when the detailed one is shown/hidden
+ if ( b ) {
+ m_pButton->setPixmap( SmallIcon( "down" ) );
+ QToolTip::remove( m_pButton );
+ QToolTip::add( m_pButton, i18n("Hide detailed progress window") );
+ setMode();
+ } else {
+ m_pButton->setPixmap( SmallIcon( "up" ) );
+ QToolTip::remove( m_pButton );
+ QToolTip::add( m_pButton, i18n("Show detailed progress window") );
+ }
+}
+
+#include "statusbarprogresswidget.moc"