summaryrefslogtreecommitdiffstats
path: root/libtdepim/progressdialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libtdepim/progressdialog.cpp')
-rw-r--r--libtdepim/progressdialog.cpp437
1 files changed, 437 insertions, 0 deletions
diff --git a/libtdepim/progressdialog.cpp b/libtdepim/progressdialog.cpp
new file mode 100644
index 000000000..bd5b594c6
--- /dev/null
+++ b/libtdepim/progressdialog.cpp
@@ -0,0 +1,437 @@
+/** -*- c++ -*-
+ * progressdialog.cpp
+ *
+ * Copyright (c) 2004 Till Adam <adam@kde.org>,
+ * David Faure <faure@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program 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 TQt library by Trolltech AS, Norway (or with modified versions
+ * of TQt that use the same license as TQt), 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
+ * TQt. 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <tqapplication.h>
+#include <tqlayout.h>
+#include <tqprogressbar.h>
+#include <tqtimer.h>
+#include <tqheader.h>
+#include <tqobject.h>
+#include <tqscrollview.h>
+#include <tqtoolbutton.h>
+#include <tqpushbutton.h>
+#include <tqvbox.h>
+#include <tqtooltip.h>
+
+#include <klocale.h>
+#include <kdialog.h>
+#include <kstdguiitem.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+
+#include "progressdialog.h"
+#include "progressmanager.h"
+#include "ssllabel.h"
+#include <tqwhatsthis.h>
+
+namespace KPIM {
+
+class TransactionItem;
+
+TransactionItemView::TransactionItemView( TQWidget * parent,
+ const char * name,
+ WFlags f )
+ : TQScrollView( parent, name, f ) {
+ setFrameStyle( NoFrame );
+ mBigBox = new TQVBox( viewport() );
+ mBigBox->setSpacing( 5 );
+ addChild( mBigBox );
+ setResizePolicy( TQScrollView::AutoOneFit ); // Fit so that the box expands horizontally
+}
+
+TransactionItem* TransactionItemView::addTransactionItem( ProgressItem* item, bool first )
+{
+ TransactionItem *ti = new TransactionItem( mBigBox, item, first );
+ ti->hide();
+ TQTimer::singleShot( 1000, ti, TQT_SLOT( show() ) );
+ return ti;
+}
+
+void TransactionItemView::resizeContents( int w, int h )
+{
+ // (handling of TQEvent::LayoutHint in TQScrollView calls this method)
+ //kdDebug(5300) << k_funcinfo << w << "," << h << endl;
+ TQScrollView::resizeContents( w, h );
+ // Tell the tqlayout in the parent (progressdialog) that our size changed
+ updateGeometry();
+ // Resize the parent (progressdialog) - this works but resize horizontally too often
+ //parentWidget()->adjustSize();
+
+ TQApplication::sendPostedEvents( 0, TQEvent::ChildInserted );
+ TQApplication::sendPostedEvents( 0, TQEvent::LayoutHint );
+ TQSize sz = parentWidget()->tqsizeHint();
+ int currentWidth = parentWidget()->width();
+ // Don't resize to sz.width() every time when it only reduces a little bit
+ if ( currentWidth < sz.width() || currentWidth > sz.width() + 100 )
+ currentWidth = sz.width();
+ parentWidget()->resize( currentWidth, sz.height() );
+}
+
+TQSize TransactionItemView::tqsizeHint() const
+{
+ return tqminimumSizeHint();
+}
+
+TQSize TransactionItemView::tqminimumSizeHint() const
+{
+ int f = 2 * frameWidth();
+ // Make room for a vertical scrollbar in all cases, to avoid a horizontal one
+ int vsbExt = verticalScrollBar()->tqsizeHint().width();
+ int minw = tqtopLevelWidget()->width() / 3;
+ int maxh = tqtopLevelWidget()->height() / 2;
+ TQSize sz( mBigBox->tqminimumSizeHint() );
+ sz.setWidth( TQMAX( sz.width(), minw ) + f + vsbExt );
+ sz.setHeight( TQMIN( sz.height(), maxh ) + f );
+ return sz;
+}
+
+
+void TransactionItemView::slotLayoutFirstItem()
+{
+ /*
+ The below relies on some details in TQt's behaviour regarding deleting
+ objects. This slot is called from the destroyed signal of an item just
+ going away. That item is at that point still in the list of chilren, but
+ since the vtable is already gone, it will have type TQObject. The first
+ one with both the right name and the right class therefor is what will
+ be the first item very shortly. That's the one we want to remove the
+ hline for.
+ */
+ TQObject *o = mBigBox->child( "TransactionItem", "KPIM::TransactionItem" );
+ TransactionItem *ti = dynamic_cast<TransactionItem*>( o );
+ if ( ti ) {
+ ti->hideHLine();
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+TransactionItem::TransactionItem( TQWidget* parent,
+ ProgressItem *item, bool first )
+ : TQVBox( parent, "TransactionItem" ), mCancelButton( 0 ), mItem( item )
+
+{
+ setSpacing( 2 );
+ setMargin( 2 );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
+
+ mFrame = new TQFrame( this );
+ mFrame->setFrameShape( TQFrame::HLine );
+ mFrame->setFrameShadow( TQFrame::Raised );
+ mFrame->show();
+ setStretchFactor( mFrame, 3 );
+
+ TQHBox *h = new TQHBox( this );
+ h->setSpacing( 5 );
+
+ mItemLabel = new TQLabel( item->label(), h );
+ // always interpret the label text as RichText, but disable word wrapping
+ mItemLabel->setTextFormat( TQt::RichText );
+ mItemLabel->tqsetAlignment( TQt::AlignAuto | TQt::AlignVCenter | TQt::SingleLine );
+ h->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
+
+ mProgress = new TQProgressBar( 100, h );
+ mProgress->setProgress( item->progress() );
+
+ if ( item->canBeCanceled() ) {
+ mCancelButton = new TQPushButton( SmallIcon( "cancel" ), TQString(), h );
+ TQToolTip::add( mCancelButton, i18n("Cancel this operation.") );
+ connect ( mCancelButton, TQT_SIGNAL( clicked() ),
+ this, TQT_SLOT( slotItemCanceled() ));
+ }
+
+ h = new TQHBox( this );
+ h->setSpacing( 5 );
+ h->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
+ mSSLLabel = new SSLLabel( h );
+ mSSLLabel->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ) );
+ mItemtqStatus = new TQLabel( item->status(), h );
+ // always interpret the status text as RichText, but disable word wrapping
+ mItemtqStatus->setTextFormat( TQt::RichText );
+ mItemtqStatus->tqsetAlignment( TQt::AlignAuto | TQt::AlignVCenter | TQt::SingleLine );
+ // richtext leads to tqsizeHint acting as if wrapping was enabled though,
+ // so make sure we only ever have the height of one line.
+ mItemtqStatus->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored ) );
+ mItemtqStatus->setFixedHeight( mItemLabel->tqsizeHint().height() );
+ setCrypto( item->usesCrypto() );
+ if( first ) hideHLine();
+}
+
+TransactionItem::~TransactionItem()
+{
+}
+
+void TransactionItem::hideHLine()
+{
+ mFrame->hide();
+}
+
+void TransactionItem::setProgress( int progress )
+{
+ mProgress->setProgress( progress );
+}
+
+void TransactionItem::setLabel( const TQString& label )
+{
+ mItemLabel->setText( label );
+}
+
+void TransactionItem::setqStatus( const TQString& status )
+{
+ mItemtqStatus->setText( status );
+}
+
+void TransactionItem::setCrypto( bool on )
+{
+ if (on)
+ mSSLLabel->setEncrypted( true );
+ else
+ mSSLLabel->setEncrypted( false );
+
+ mSSLLabel->setState( mSSLLabel->lastState() );
+}
+
+void TransactionItem::setTotalSteps( int totalSteps )
+{
+ mProgress->setTotalSteps( totalSteps );
+}
+
+void TransactionItem::slotItemCanceled()
+{
+ if ( mItem )
+ mItem->cancel();
+}
+
+
+void TransactionItem::addSubTransaction( ProgressItem* /*item*/ )
+{
+
+}
+
+
+// ---------------------------------------------------------------------------
+
+ProgressDialog::ProgressDialog( TQWidget* alignWidget, TQWidget* parent, const char* name )
+ : OverlayWidget( alignWidget, parent, name ), mWasLastShown( false )
+{
+ setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); // TQFrame
+ setSpacing( 0 ); // TQHBox
+ setMargin( 1 );
+
+ mScrollView = new TransactionItemView( this, "ProgressScrollView" );
+
+ // No more close button for now, since there is no more autoshow
+ /*
+ TQVBox* rightBox = new TQVBox( this );
+ TQToolButton* pbClose = new TQToolButton( rightBox );
+ pbClose->setAutoRaise(true);
+ pbClose->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ) );
+ pbClose->setFixedSize( 16, 16 );
+ pbClose->setIconSet( KGlobal::iconLoader()->loadIconSet( "fileclose", KIcon::Small, 14 ) );
+ TQToolTip::add( pbClose, i18n( "Hide detailed progress window" ) );
+ connect(pbClose, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotClose()));
+ TQWidget* spacer = new TQWidget( rightBox ); // don't let the close button take up all the height
+ rightBox->setStretchFactor( spacer, 100 );
+ */
+
+ /*
+ * Get the singleton ProgressManager item which will inform us of
+ * appearing and vanishing items.
+ */
+ ProgressManager *pm = ProgressManager::instance();
+ connect ( pm, TQT_SIGNAL( progressItemAdded( KPIM::ProgressItem* ) ),
+ this, TQT_SLOT( slotTransactionAdded( KPIM::ProgressItem* ) ) );
+ connect ( pm, TQT_SIGNAL( progressItemCompleted( KPIM::ProgressItem* ) ),
+ this, TQT_SLOT( slotTransactionCompleted( KPIM::ProgressItem* ) ) );
+ connect ( pm, TQT_SIGNAL( progressItemProgress( KPIM::ProgressItem*, unsigned int ) ),
+ this, TQT_SLOT( slotTransactionProgress( KPIM::ProgressItem*, unsigned int ) ) );
+ connect ( pm, TQT_SIGNAL( progressItemtqStatus( KPIM::ProgressItem*, const TQString& ) ),
+ this, TQT_SLOT( slotTransactiontqStatus( KPIM::ProgressItem*, const TQString& ) ) );
+ connect ( pm, TQT_SIGNAL( progressItemLabel( KPIM::ProgressItem*, const TQString& ) ),
+ this, TQT_SLOT( slotTransactionLabel( KPIM::ProgressItem*, const TQString& ) ) );
+ connect ( pm, TQT_SIGNAL( progressItemUsesCrypto(KPIM::ProgressItem*, bool) ),
+ this, TQT_SLOT( slotTransactionUsesCrypto( KPIM::ProgressItem*, bool ) ) );
+ connect ( pm, TQT_SIGNAL( progressItemUsesBusyIndicator(KPIM::ProgressItem*, bool) ),
+ this, TQT_SLOT( slotTransactionUsesBusyIndicator( KPIM::ProgressItem*, bool ) ) );
+ connect ( pm, TQT_SIGNAL( showProgressDialog() ),
+ this, TQT_SLOT( slotShow() ) );
+}
+
+void ProgressDialog::closeEvent( TQCloseEvent* e )
+{
+ e->accept();
+ hide();
+}
+
+
+/*
+ * Destructor
+ */
+ProgressDialog::~ProgressDialog()
+{
+ // no need to delete child widgets.
+}
+
+void ProgressDialog::slotTransactionAdded( ProgressItem *item )
+{
+ TransactionItem *parent = 0;
+ if ( item->parent() ) {
+ if ( mTransactionsToListviewItems.contains( item->parent() ) ) {
+ parent = mTransactionsToListviewItems[ item->parent() ];
+ parent->addSubTransaction( item );
+ }
+ } else {
+ const bool first = mTransactionsToListviewItems.empty();
+ TransactionItem *ti = mScrollView->addTransactionItem( item, first );
+ if ( ti )
+ mTransactionsToListviewItems.replace( item, ti );
+ if ( first && mWasLastShown )
+ TQTimer::singleShot( 1000, this, TQT_SLOT( slotShow() ) );
+
+ }
+}
+
+void ProgressDialog::slotTransactionCompleted( ProgressItem *item )
+{
+ if ( mTransactionsToListviewItems.contains( item ) ) {
+ TransactionItem *ti = mTransactionsToListviewItems[ item ];
+ mTransactionsToListviewItems.remove( item );
+ ti->setItemComplete();
+ TQTimer::singleShot( 3000, ti, TQT_SLOT( deleteLater() ) );
+ // see the slot for comments as to why that works
+ connect ( ti, TQT_SIGNAL( destroyed() ),
+ mScrollView, TQT_SLOT( slotLayoutFirstItem() ) );
+ }
+ // This was the last item, hide.
+ if ( mTransactionsToListviewItems.empty() )
+ TQTimer::singleShot( 3000, this, TQT_SLOT( slotHide() ) );
+}
+
+void ProgressDialog::slotTransactionCanceled( ProgressItem* )
+{
+}
+
+void ProgressDialog::slotTransactionProgress( ProgressItem *item,
+ unsigned int progress )
+{
+ if ( mTransactionsToListviewItems.contains( item ) ) {
+ TransactionItem *ti = mTransactionsToListviewItems[ item ];
+ ti->setProgress( progress );
+ }
+}
+
+void ProgressDialog::slotTransactiontqStatus( ProgressItem *item,
+ const TQString& status )
+{
+ if ( mTransactionsToListviewItems.contains( item ) ) {
+ TransactionItem *ti = mTransactionsToListviewItems[ item ];
+ ti->setqStatus( status );
+ }
+}
+
+void ProgressDialog::slotTransactionLabel( ProgressItem *item,
+ const TQString& label )
+{
+ if ( mTransactionsToListviewItems.contains( item ) ) {
+ TransactionItem *ti = mTransactionsToListviewItems[ item ];
+ ti->setLabel( label );
+ }
+}
+
+
+void ProgressDialog::slotTransactionUsesCrypto( ProgressItem *item,
+ bool value )
+{
+ if ( mTransactionsToListviewItems.contains( item ) ) {
+ TransactionItem *ti = mTransactionsToListviewItems[ item ];
+ ti->setCrypto( value );
+ }
+}
+
+void ProgressDialog::slotTransactionUsesBusyIndicator( KPIM::ProgressItem *item, bool value )
+{
+ if ( mTransactionsToListviewItems.contains( item ) ) {
+ TransactionItem *ti = mTransactionsToListviewItems[ item ];
+ if ( value )
+ ti->setTotalSteps( 0 );
+ else
+ ti->setTotalSteps( 100 );
+ }
+}
+
+void ProgressDialog::slotShow()
+{
+ setVisible( true );
+}
+
+void ProgressDialog::slotHide()
+{
+ // check if a new item showed up since we started the timer. If not, hide
+ if ( mTransactionsToListviewItems.isEmpty() ) {
+ setVisible( false );
+ }
+}
+
+void ProgressDialog::slotClose()
+{
+ mWasLastShown = false;
+ setVisible( false );
+}
+
+void ProgressDialog::setVisible( bool b )
+{
+ if ( b )
+ show();
+ else
+ hide();
+ emit visibilityChanged( b );
+}
+
+void ProgressDialog::slotToggleVisibility()
+{
+ /* Since we are only hiding with a timeout, there is a short period of
+ * time where the last item is still visible, but clicking on it in
+ * the statusbarwidget should not display the dialog, because there
+ * are no items to be shown anymore. Guard against that.
+ */
+ mWasLastShown = !isShown();
+ if ( isShown() || !mTransactionsToListviewItems.isEmpty() )
+ setVisible( !isShown() );
+}
+
+}
+
+#include "progressdialog.moc"