Commit d57a02bf authored by Laurent Montel's avatar Laurent Montel 😁

Implement statusbar progress indicator

parent 529be8e0
......@@ -47,6 +47,9 @@
#include "pimcommon/storageservice/storageservicejobconfig.h"
#include "pimcommon/storageservice/storageserviceabstract.h"
#include "libkdepim/progresswidget/progressdialog.h"
#include "libkdepim/progresswidget/statusbarprogresswidget.h"
#include <ktabwidget.h>
#include <KStatusNotifierItem>
#include <kstatusbar.h>
......@@ -101,9 +104,7 @@ MainWindow::MainWindow()
// then, setup our actions
setupActions();
// add a status bar
statusBar()->show();
setupStatusBar();
// a call to KXmlGuiWindow::setupGUI() populates the GUI
// with actions, using KXMLGUI.
......@@ -138,6 +139,17 @@ MainWindow::~MainWindow()
{
}
void MainWindow::setupStatusBar()
{
KPIM::ProgressDialog *progressDialog = new KPIM::ProgressDialog( statusBar(), this );
progressDialog->hide();
KPIM::StatusbarProgressWidget *littleProgress = new KPIM::StatusbarProgressWidget( progressDialog, statusBar() );
littleProgress->show();
// add a status bar
statusBar()->show();
}
void MainWindow::initStorageService()
{
StorageServiceManagerSettingsJob *settingsJob = new StorageServiceManagerSettingsJob(this);
......
......@@ -120,6 +120,7 @@ private:
void setupSystemTray();
void writeConfigs();
void initStorageService();
void setupStatusBar();
/**
Create a new post entry,
and return pointer to it's widget (Actually return value is a PostEntry instance)
......
......@@ -34,6 +34,7 @@ set(libpimcommon_storageservice_SRCS
${libpimcommon_storageservice_gdrive}
storageservice/storageserviceabstract.cpp
storageservice/storageservicemanager.cpp
storageservice/storageserviceprogressmanager.cpp
storageservice/job/storageserviceabstractjob.cpp
......@@ -84,7 +85,6 @@ set(libpimcommon_storageservice_SRCS
storageservice/widgets/storageservicetreewidget.cpp
storageservice/widgets/storageserviceprogresswidget.cpp
storageservice/widgets/storageserviceprogressindicator.cpp
storageservice/widgets/storageserviceprogressdialog.cpp
storageservice/settings/storageservicesettings.cpp
......
......@@ -8,7 +8,7 @@ N == not possible
DropBox: X X X X X X X X X X X X X X X X
YouSendIt: X X X X X I I I X X
WebDav: X X X X X X X X X X X X X X
GDrive: X X X
GDrive: X X X X
Box: X X X X I I X X X I I X X X X X
Hubic: I
UbuntuOne: X X X X
......
......@@ -16,6 +16,7 @@
*/
#include "storageservicemanager.h"
#include "storageserviceprogressmanager.h"
#include "settings/pimcommonsettings.h"
#include "storageservice/utils/storageserviceutils.h"
......@@ -199,6 +200,7 @@ void StorageServiceManager::slotShareFile()
connect(service,SIGNAL(uploadFileFailed(QString,QString)), this, SIGNAL(uploadFileFailed(QString,QString)), Qt::UniqueConnection);
connect(service,SIGNAL(shareLinkDone(QString,QString)), this, SIGNAL(shareLinkDone(QString,QString)), Qt::UniqueConnection);
Q_EMIT uploadFileStart(service);
PimCommon::StorageServiceProgressManager::self()->addProgress(service);
service->uploadFile(fileName, newName, QString());
}
}
......@@ -215,6 +217,7 @@ void StorageServiceManager::slotDownloadFile()
StorageServiceAbstract *service = mListService.value(type);
QPointer<PimCommon::StorageServiceDownloadDialog> dlg = new PimCommon::StorageServiceDownloadDialog(service, 0);
dlg->setDefaultDownloadPath(mDefaultUploadFolder);
PimCommon::StorageServiceProgressManager::self()->addProgress(service);
dlg->exec();
delete dlg;
}
......
/*
Copyright (c) 2014 Montel Laurent <montel@kde.org>
This program 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.
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
*/
#include "storageserviceprogressmanager.h"
#include "libkdepim/progresswidget/progressmanager.h"
#include "pimcommon/storageservice/storageserviceabstract.h"
#include <KGlobal>
namespace PimCommon {
class StorageServiceProgressManagerPrivate
{
public:
StorageServiceProgressManagerPrivate()
: storageServiceProgressManager( new StorageServiceProgressManager )
{
}
~StorageServiceProgressManagerPrivate()
{
delete storageServiceProgressManager;
}
StorageServiceProgressManager *storageServiceProgressManager;
};
K_GLOBAL_STATIC( StorageServiceProgressManagerPrivate, sInstance )
StorageServiceProgressManager::StorageServiceProgressManager(QObject *parent)
: QObject(parent)
{
}
StorageServiceProgressManager::~StorageServiceProgressManager()
{
}
StorageServiceProgressManager *StorageServiceProgressManager::self()
{
return sInstance->storageServiceProgressManager; //will create it
}
void StorageServiceProgressManager::addProgress(PimCommon::StorageServiceAbstract *storageService)
{
if (!mHashList.contains(storageService->storageServiceName())) {
KPIM::ProgressItem *progressItem = KPIM::ProgressManager::createProgressItem( storageService->storageServiceName() );
mHashList.insert(storageService->storageServiceName(), progressItem);
connect(progressItem, SIGNAL(progressItemCanceled(KPIM::ProgressItem*)), SLOT(slotProgressItemCanceled(KPIM::ProgressItem*)));
connect(storageService, SIGNAL(uploadFileDone(QString,QString)), SLOT(slotUploadFileDone(QString,QString)), Qt::UniqueConnection);
connect(storageService, SIGNAL(uploadFileFailed(QString,QString)), SLOT(slotUploadFileFailed(QString,QString)), Qt::UniqueConnection);
connect(storageService, SIGNAL(downLoadFileDone(QString,QString)), SLOT(slotDownloadFileDone(QString,QString)), Qt::UniqueConnection);
connect(storageService, SIGNAL(downLoadFileFailed(QString,QString)), SLOT(slotDownloadFileFailed(QString,QString)), Qt::UniqueConnection);
connect(storageService, SIGNAL(uploadDownloadFileProgress(QString,qint64,qint64)), SLOT(slotDownloadFileProgress(QString,qint64,qint64)), Qt::UniqueConnection);
}
}
void StorageServiceProgressManager::slotDownloadFileProgress(const QString &serviceName, qint64 done, qint64 total)
{
if (mHashList.contains(serviceName)) {
KPIM::ProgressItem *mProgressItem = mHashList.value(serviceName);
if (mProgressItem) {
if (total > 0)
mProgressItem->setProgress((100*done)/total);
else
mProgressItem->setProgress(100);
}
}
}
void StorageServiceProgressManager::slotDownloadFileDone(const QString &serviceName, const QString &)
{
if (mHashList.contains(serviceName)) {
KPIM::ProgressItem *mProgressItem = mHashList.value(serviceName);
if (mProgressItem) {
mProgressItem->setComplete();
}
mHashList.remove(serviceName);
}
}
void StorageServiceProgressManager::slotDownloadFileFailed(const QString &serviceName, const QString &)
{
if (mHashList.contains(serviceName)) {
KPIM::ProgressItem *mProgressItem = mHashList.value(serviceName);
if (mProgressItem) {
mProgressItem->setComplete();
}
mHashList.remove(serviceName);
}
}
void StorageServiceProgressManager::slotUploadFileDone(const QString &serviceName, const QString &)
{
if (mHashList.contains(serviceName)) {
KPIM::ProgressItem *mProgressItem = mHashList.value(serviceName);
if (mProgressItem) {
mProgressItem->setComplete();
}
mHashList.remove(serviceName);
}
}
void StorageServiceProgressManager::slotUploadFileFailed(const QString &serviceName, const QString &)
{
if (mHashList.contains(serviceName)) {
KPIM::ProgressItem *mProgressItem = mHashList.value(serviceName);
if (mProgressItem) {
mProgressItem->setComplete();
}
mHashList.remove(serviceName);
}
}
void StorageServiceProgressManager::slotProgressItemCanceled(KPIM::ProgressItem *item)
{
//TODO
}
ProgressJob::ProgressJob(const QString &serviceName, KPIM::ProgressItem *item)
: mServiceName(serviceName),
mProgressItem(item)
{
}
KPIM::ProgressItem *ProgressJob::item() const
{
return mProgressItem;
}
QString ProgressJob::serviceName() const
{
return mServiceName;
}
}
......@@ -15,65 +15,59 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef STORAGESERVICEPROGRESSDIALOG_H
#define STORAGESERVICEPROGRESSDIALOG_H
#ifndef STORAGESERVICEPROGRESSMANAGER_H
#define STORAGESERVICEPROGRESSMANAGER_H
#include <QObject>
#include "pimcommon_export.h"
#include "libkdepim/widgets/overlaywidget.h"
#include <QHash>
#include <QPointer>
namespace KPIM {
class ProgressItem;
}
#include <QScrollArea>
class KVBox;
namespace PimCommon {
class StorageServiceProgressWidget;
class StorageServiceAbstract;
class ProgressIndicatorView : public QScrollArea
class ProgressJob
{
Q_OBJECT
public:
explicit ProgressIndicatorView( QWidget * parent = 0 );
~ProgressIndicatorView();
QSize sizeHint() const;
QSize minimumSizeHint() const;
StorageServiceProgressWidget *addTransactionItem(PimCommon::StorageServiceAbstract *service, bool first);
public Q_SLOTS:
void slotLayoutFirstItem();
ProgressJob(const QString &serviceName, KPIM::ProgressItem *item);
~ProgressJob();
protected:
void resizeEvent ( QResizeEvent *event );
KPIM::ProgressItem *item() const;
QString serviceName() const;
private:
KVBox *mBigBox;
QString mServiceName;
KPIM::ProgressItem *mProgressItem;
};
class PIMCOMMON_EXPORT StorageServiceProgressDialog : public KPIM::OverlayWidget
class PIMCOMMON_EXPORT StorageServiceProgressManager : public QObject
{
Q_OBJECT
public:
explicit StorageServiceProgressDialog(QWidget *alignWidget, QWidget *parent=0);
~StorageServiceProgressDialog();
~StorageServiceProgressManager();
static StorageServiceProgressManager *self();
void addProgress(PimCommon::StorageServiceAbstract *storageService);
protected:
void setVisible(bool b);
private slots:
void slotTransactionAdded();
void slotTransactionCompleted();
void slotTransactionCanceled();
void slotTransactionProgress();
void slotTransactionUsesBusyIndicator();
void slotShow();
void slotHide();
void slotClose();
void slotToggleVisibility();
private:
//QMap<const ProgressItem *, StorageServiceProgressWidget *> mTransactionsToListviewItems;
bool mWasLastShown;
void slotProgressItemCanceled(KPIM::ProgressItem *item);
ProgressIndicatorView *mScrollView;
void slotUploadFileDone(const QString &serviceName, const QString &);
void slotUploadFileFailed(const QString &serviceName, const QString &);
void slotDownloadFileDone(const QString &serviceName, const QString &);
void slotDownloadFileFailed(const QString &serviceName, const QString &);
void slotDownloadFileProgress(const QString &serviceName, qint64 done, qint64 total);
private:
explicit StorageServiceProgressManager(QObject *parent = 0);
friend class StorageServiceProgressManagerPrivate;
QHash<QString, QPointer<KPIM::ProgressItem> > mHashList;
};
}
#endif // STORAGESERVICEPROGRESSDIALOG_H
#endif // STORAGESERVICEPROGRESSMANAGER_H
/*
Copyright (c) 2014 Montel Laurent <montel@kde.org>
This program 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.
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
*/
#include "storageserviceprogressdialog.h"
#include "storageserviceprogresswidget.h"
#include <KVBox>
#include <QScrollBar>
#include <QLayout>
using namespace PimCommon;
ProgressIndicatorView::ProgressIndicatorView(QWidget *parent)
: QScrollArea( parent )
{
setFrameStyle( NoFrame );
mBigBox = new KVBox( this );
setWidget( mBigBox );
setWidgetResizable( true );
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
}
ProgressIndicatorView::~ProgressIndicatorView()
{
}
StorageServiceProgressWidget *ProgressIndicatorView::addTransactionItem( PimCommon::StorageServiceAbstract *service, bool first )
{
StorageServiceProgressWidget *ti = new StorageServiceProgressWidget( service, mBigBox);//, first );
mBigBox->layout()->addWidget( ti );
resize( mBigBox->width(), mBigBox->height() );
return ti;
}
void ProgressIndicatorView::resizeEvent ( QResizeEvent *event )
{
// Tell the layout in the parent (StorageServiceProgressDialog) that our size changed
updateGeometry();
QSize sz = parentWidget()->sizeHint();
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() );
QScrollArea::resizeEvent( event );
}
QSize ProgressIndicatorView::sizeHint() const
{
return minimumSizeHint();
}
QSize ProgressIndicatorView::minimumSizeHint() const
{
int f = 2 * frameWidth();
// Make room for a vertical scrollbar in all cases, to avoid a horizontal one
int vsbExt = verticalScrollBar()->sizeHint().width();
int minw = topLevelWidget()->width() / 3;
int maxh = topLevelWidget()->height() / 2;
QSize sz( mBigBox->minimumSizeHint() );
sz.setWidth( qMax( sz.width(), minw ) + f + vsbExt );
sz.setHeight( qMin( sz.height(), maxh ) + f );
return sz;
}
void ProgressIndicatorView::slotLayoutFirstItem()
{
//This slot is called whenever a TransactionItem is deleted, so this is a
//good place to call updateGeometry(), so our parent takes the new size
//into account and resizes.
updateGeometry();
/*
The below relies on some details in Qt'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 QObject. 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.
*/
#if 0
TransactionItem *ti = mBigBox->findChild<KPIM::TransactionItem*>( QLatin1String("TransactionItem") );
if ( ti ) {
ti->hideHLine();
}
#endif
}
StorageServiceProgressDialog::StorageServiceProgressDialog(QWidget *alignWidget, QWidget *parent)
: KPIM::OverlayWidget(alignWidget, parent)
{
setFrameStyle( QFrame::Panel | QFrame::Sunken ); // QFrame
setAutoFillBackground( true );
mScrollView = new ProgressIndicatorView( this );
layout()->addWidget( mScrollView );
}
StorageServiceProgressDialog::~StorageServiceProgressDialog()
{
}
void StorageServiceProgressDialog::slotTransactionAdded( /*ProgressItem *item*/ )
{
#if 0
if ( item->parent() ) {
if ( mTransactionsToListviewItems.contains( item->parent() ) ) {
TransactionItem * parent = mTransactionsToListviewItems[ item->parent() ];
parent->addSubTransaction( item );
}
} else {
const bool first = mTransactionsToListviewItems.empty();
StorageServiceProgressWidget *ti = mScrollView->addTransactionItem( item, first );
if ( ti ) {
mTransactionsToListviewItems.insert( item, ti );
}
if ( first && mWasLastShown ) {
QTimer::singleShot( 1000, this, SLOT(slotShow()) );
}
}
#endif
}
void StorageServiceProgressDialog::slotTransactionCompleted( /*ProgressItem *item*/ )
{
#if 0
if ( mTransactionsToListviewItems.contains( item ) ) {
TransactionItem *ti = mTransactionsToListviewItems[ item ];
mTransactionsToListviewItems.remove( item );
ti->setItemComplete();
QTimer::singleShot( 3000, ti, SLOT(deleteLater()) );
// see the slot for comments as to why that works
connect ( ti, SIGNAL(destroyed()),
mScrollView, SLOT(slotLayoutFirstItem()) );
}
// This was the last item, hide.
if ( mTransactionsToListviewItems.empty() ) {
QTimer::singleShot( 3000, this, SLOT(slotHide()) );
}
#endif
}
void StorageServiceProgressDialog::slotTransactionCanceled( /*ProgressItem **/ )
{
}
void StorageServiceProgressDialog::slotTransactionProgress( /*ProgressItem *item, unsigned int progress*/ )
{
/*
if ( mTransactionsToListviewItems.contains( item ) ) {
TransactionItem *ti = mTransactionsToListviewItems[ item ];
ti->setProgress( progress );
}
*/
}
void StorageServiceProgressDialog::slotTransactionUsesBusyIndicator( /*KPIM::ProgressItem *item, bool value*/ )
{
#if 0
if ( mTransactionsToListviewItems.contains( item ) ) {
TransactionItem *ti = mTransactionsToListviewItems[ item ];
if ( value ) {
ti->setTotalSteps( 0 );
} else {
ti->setTotalSteps( 100 );
}
}
#endif
}
void StorageServiceProgressDialog::slotShow()
{
setVisible( true );
}
void StorageServiceProgressDialog::slotHide()
{
/*
// check if a new item showed up since we started the timer. If not, hide
if ( mTransactionsToListviewItems.isEmpty() ) {
setVisible( false );
}
*/
}
void StorageServiceProgressDialog::slotClose()
{
mWasLastShown = false;
setVisible( false );
}
void StorageServiceProgressDialog::setVisible( bool b )
{
#if 0
OverlayWidget::setVisible( b );
emit visibilityChanged( b );
#endif
}
void StorageServiceProgressDialog::slotToggleVisibility()
{
#if 0
/* 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 = isHidden();
if ( !isHidden() || !mTransactionsToListviewItems.isEmpty() ) {
setVisible( isHidden() );
}
#endif
}
......@@ -5,6 +5,7 @@ add_definitions( -DQT_NO_CAST_TO_ASCII )
include_directories(
${CMAKE_SOURCE_DIR}/pimcommon/
${CMAKE_SOURCE_DIR}/libkdepim/
)
set( storageservicemanager_kcfg_SRCS settings/storageservicemanagerglobalconfig.kcfgc )
......@@ -32,7 +33,8 @@ TARGET_LINK_LIBRARIES(storageservicemanager
${KDE4_KDEUI_LIBS}
${KDE4_KIO_LIBS}
${KDE4_SOLID_LIBS}
pimcommon
pimcommon
kdepim
)
install(TARGETS storageservicemanager ${INSTALL_TARGETS_DEFAULT_ARGS})
......
......@@ -26,6 +26,9 @@
#include "pimcommon/storageservice/storageservicejobconfig.h"
#include "pimcommon/storageservice/storageserviceabstract.h"
#include "libkdepim/progresswidget/progressdialog.h"
#include "libkdepim/progresswidget/statusbarprogresswidget.h"