diff --git a/src/mirall/accountsettings.cpp b/src/mirall/accountsettings.cpp index c9eee74bb..c08194e47 100644 --- a/src/mirall/accountsettings.cpp +++ b/src/mirall/accountsettings.cpp @@ -492,7 +492,7 @@ QString AccountSettings::shortenFilename( const QString& folder, const QString& return shortFile; } -void AccountSettings::slotSetProgress( const QString& folder, Progress::Info progress ) +void AccountSettings::slotSetProgress(const QString& folder, const Progress::Info &progress ) { // qDebug() << "================================> Progress for folder " << folder << " file " << file << ": "<< p1; QStandardItem *item = itemForFolder( folder ); diff --git a/src/mirall/application.cpp b/src/mirall/application.cpp index 26293092d..928b48577 100644 --- a/src/mirall/application.cpp +++ b/src/mirall/application.cpp @@ -99,6 +99,7 @@ Application::Application(int &argc, char **argv) : _networkMgr(new QNetworkConfigurationManager(this)), _sslErrorDialog(0), _contextMenu(0), + _recentActionsMenu(0), _theme(Theme::instance()), _logBrowser(0), _logExpire(0), @@ -125,6 +126,9 @@ Application::Application(int &argc, char **argv) : connect( pd, SIGNAL(progressInfo(QString,Progress::Info)), this, SLOT(slotUpdateProgress(QString,Progress::Info)) ); + connect( pd, SIGNAL(progressSyncProblem(QString,Progress::SyncProblem)), + SLOT(slotProgressSyncProblem(QString,Progress::SyncProblem))); + // create folder manager for sync folder management FolderMan *folderMan = FolderMan::instance(); connect( folderMan, SIGNAL(folderSyncStateChange(QString)), @@ -285,6 +289,10 @@ void Application::setupActions() _actionStatus = new QAction(tr("Unknown status"), this); _actionStatus->setEnabled( false ); _actionSettings = new QAction(tr("Settings..."), this); + _actionRecent = new QAction(tr("more..."), this); + _actionRecent->setEnabled( true ); + + QObject::connect(_actionRecent, SIGNAL(triggered(bool)), SLOT(slotShowRecentChanges())); QObject::connect(_actionSettings, SIGNAL(triggered(bool)), SLOT(slotSettings())); _actionHelp = new QAction(tr("Help"), this); QObject::connect(_actionHelp, SIGNAL(triggered(bool)), SLOT(slotHelp())); @@ -316,8 +324,11 @@ void Application::setupContextMenu() if( _contextMenu ) { _contextMenu->clear(); + _recentActionsMenu->clear(); + _recentActionsMenu->addAction(tr("None.")); } else { _contextMenu = new QMenu(); + _recentActionsMenu = _contextMenu->addMenu(tr("Recent Changes...")); // this must be called only once after creating the context menu, or // it will trigger a bug in Ubuntu's SNI bridge patch (11.10, 12.04). _tray->setContextMenu(_contextMenu); @@ -359,6 +370,7 @@ void Application::setupContextMenu() _contextMenu->addAction(_actionQuota); _contextMenu->addSeparator(); _contextMenu->addAction(_actionStatus); + _contextMenu->addMenu(_recentActionsMenu); _contextMenu->addSeparator(); _contextMenu->addAction(_actionSettings); _contextMenu->addAction(_actionHelp); @@ -484,23 +496,71 @@ void Application::slotUseMonoIconsChanged(bool) computeOverallSyncStatus(); } -void Application::slotUpdateProgress(const QString &folder, Progress::Info progress) +void Application::slotProgressSyncProblem(const QString& folder, const Progress::SyncProblem& problem) +{ + Q_UNUSED(folder); + Q_UNUSED(problem); + + // display a warn icon if warnings happend. + QIcon warnIcon(":/mirall/resources/warning-16"); + _actionRecent->setIcon(warnIcon); + + rebuildRecentMenus(); +} + +void Application::rebuildRecentMenus() +{ + _recentActionsMenu->clear(); + QList progressInfoList; + progressInfoList = ProgressDispatcher::instance()->recentChangedItems(5); + + if( progressInfoList.size() == 0 ) { + _recentActionsMenu->addAction(tr("No items synced recently")); + } else { + foreach( Progress::Info info, progressInfoList ) { + QString kindStr = tr("Upload"); + if( info.kind == Progress::EndDownload ) { + kindStr = tr("Download"); + } + QString timeStr = info.timestamp.toString("hh:mm"); + + QString actionText = tr("%1 (%2, %3)").arg(info.current_file).arg(kindStr).arg(timeStr); + _recentActionsMenu->addAction( actionText ); + } + } + // add a more... entry. + _recentActionsMenu->addAction(_actionRecent); +} + +void Application::slotUpdateProgress(const QString &folder, const Progress::Info& progress) { Q_UNUSED(folder); + // shows an entry in the context menu. QString curAmount = Utility::octetsToString(progress.overall_current_bytes); QString totalAmount = Utility::octetsToString(progress.overall_transmission_size); _actionStatus->setText(tr("Syncing %1 of %2 (%3 of %4) ").arg(progress.current_file_no) .arg(progress.overall_file_count).arg(curAmount, totalAmount)); + // wipe the problem list at start of sync. + if( progress.kind == Progress::StartSync ) { + _actionRecent->setIcon( QIcon() ); // Fixme: Set a "in-progress"-item eventually. + } + + // If there was a change in the file list, redo the progress menu. + if( progress.kind == Progress::EndDownload || progress.kind == Progress::EndUpload ) { + rebuildRecentMenus(); + } + if (progress.kind == Progress::EndSync) { + rebuildRecentMenus(); // show errors. QTimer::singleShot(2000, this, SLOT(slotDisplayIdle())); } } void Application::slotDisplayIdle() { - _actionStatus->setText(tr("Idle")); + _actionStatus->setText(tr("In Sync")); } void Application::slotHelp() @@ -577,6 +637,11 @@ void Application::slotFoldersChanged() setupContextMenu(); } +void Application::slotShowRecentChanges() +{ + // not yet here. +} + void Application::slotSettings() { if (_settingsDialog.isNull()) { diff --git a/src/mirall/application.h b/src/mirall/application.h index 847376990..5372a6cb9 100644 --- a/src/mirall/application.h +++ b/src/mirall/application.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "qtsingleapplication.h" @@ -98,18 +99,22 @@ protected slots: void slotSetupProxy(); void slotRefreshQuotaDisplay( qint64 total, qint64 used ); void slotUseMonoIconsChanged( bool ); - void slotUpdateProgress(const QString&,Progress::Info); + void slotUpdateProgress(const QString&, const Progress::Info&); + void slotProgressSyncProblem(const QString& folder, const Progress::SyncProblem &problem); void slotDisplayIdle(); void slotHelp(); + void slotShowRecentChanges(); private: void setHelp(); void raiseDialog( QWidget* ); + void rebuildRecentMenus(); Systray *_tray; QAction *_actionOpenoC; QAction *_actionSettings; QAction *_actionQuota; QAction *_actionStatus; + QAction *_actionRecent; QAction *_actionHelp; QAction *_actionQuit; @@ -121,6 +126,7 @@ private: // tray's menu QMenu *_contextMenu; + QMenu *_recentActionsMenu; Theme *_theme; QSignalMapper *_folderOpenActionMapper; @@ -128,6 +134,7 @@ private: QPointer _settingsDialog; QString _logFile; QString _logDirectory; + int _logExpire; bool _showLogWindow; bool _logFlush; diff --git a/src/mirall/csyncthread.cpp b/src/mirall/csyncthread.cpp index 3d311c280..1f3d3b8c6 100644 --- a/src/mirall/csyncthread.cpp +++ b/src/mirall/csyncthread.cpp @@ -395,7 +395,7 @@ void CSyncThread::startSync() if( walkOk ) { if( csync_walk_local_tree(_csync_ctx, &walkFinalize, 0) < 0 || - csync_walk_remote_tree( _csync_ctx, &walkFinalize, 0 ) < 0 ) { + csync_walk_remote_tree(_csync_ctx, &walkFinalize, 0 ) < 0 ) { qDebug() << "Error in finalize treewalk."; } else { // emit the treewalk results. @@ -466,6 +466,7 @@ void CSyncThread::cb_progress( CSYNC_PROGRESS *progress, void *userdata ) pInfo.current_file_no = progress->current_file_no; pInfo.overall_transmission_size = progress->overall_transmission_size; pInfo.overall_current_bytes = progress->current_overall_bytes; + pInfo.timestamp = QTime::currentTime(); // Connect to something in folder! thread->transmissionProgress( pInfo ); diff --git a/src/mirall/folder.cpp b/src/mirall/folder.cpp index 27d100365..566cc8f70 100644 --- a/src/mirall/folder.cpp +++ b/src/mirall/folder.cpp @@ -630,7 +630,19 @@ void Folder::slotCSyncFinished() void Folder::slotTransmissionProgress(const Progress::Info& progress) { - ProgressDispatcher::instance()->setProgressInfo(alias(), progress); + Progress::Info newInfo = progress; + newInfo.folder = alias(); + + if(newInfo.current_file.startsWith(QLatin1String("ownclouds://")) || + newInfo.current_file.startsWith(QLatin1String("owncloud://")) ) { + // rip off the whole ownCloud URL. + QString regexp = QString("^owncloud[s]*://.*/remote.php/webdav/%1/").arg(secondPath()); + QRegExp re( regexp ); + re.setMinimal(true); + newInfo.current_file.remove(re); + } + + ProgressDispatcher::instance()->setProgressInfo(alias(), newInfo); } ServerActionNotifier::ServerActionNotifier(QObject *parent) @@ -667,7 +679,10 @@ void ServerActionNotifier::slotSyncFinished(const SyncResult &result) updatedItems++; if (firstItemUpdated.isEmpty()) firstItemUpdated = item; - break; + break; + case CSYNC_INSTRUCTION_ERROR: + qDebug() << "Got Instruction ERROR. " << result.errorString(); + break; default: // nothing. break; diff --git a/src/mirall/folder.h b/src/mirall/folder.h index d78abaf0c..653c99301 100644 --- a/src/mirall/folder.h +++ b/src/mirall/folder.h @@ -62,7 +62,7 @@ public slots: void slotSyncFinished(const SyncResult &result); signals: void guiLog(const QString&, const QString&); - void sendResults(); + private: }; diff --git a/src/mirall/progressdispatcher.cpp b/src/mirall/progressdispatcher.cpp index f7c66d110..c4ec1b22a 100644 --- a/src/mirall/progressdispatcher.cpp +++ b/src/mirall/progressdispatcher.cpp @@ -71,7 +71,8 @@ ProgressDispatcher* ProgressDispatcher::instance() { } ProgressDispatcher::ProgressDispatcher(QObject *parent) : - QObject(parent) + QObject(parent), + _problemQueueSize(50) { } @@ -81,27 +82,45 @@ ProgressDispatcher::~ProgressDispatcher() } -void ProgressDispatcher::setProgressInfo(const QString& folder, Progress::Info newProgress) +QList ProgressDispatcher::recentChangedItems(int count) +{ + return _recentChanges.mid(0, count); +} + +QList ProgressDispatcher::recentProblems(int count) +{ + return _recentProblems.mid(0, count); +} + +void ProgressDispatcher::setProgressInfo(const QString& folder, const Progress::Info& progress) { if( folder.isEmpty() ) { return; } + Progress::Info newProgress = progress; if( newProgress.kind == Progress::Error ) { - const char *msg = (const char*)newProgress.file_size; - qDebug() << "Progress-Error:" << QString::fromLocal8Bit(msg); + Progress::SyncProblem err; + err.folder = folder; + err.current_file = newProgress.current_file; + err.error_message = QString::fromLocal8Bit( (const char*)newProgress.file_size ); + err.error_code = newProgress.file_size; + + _recentProblems.enqueue( err ); + if( _recentProblems.size() > _problemQueueSize ) { + _recentProblems.dequeue(); + } + emit progressSyncProblem( folder, err ); + } else { + if( newProgress.kind == Progress::EndSync ) { + newProgress.overall_current_bytes = newProgress.overall_transmission_size; + newProgress.current_file_no = newProgress.overall_file_count; + } + if( newProgress.kind == Progress::EndDownload || newProgress.kind == Progress::EndUpload ) { + _recentChanges.enqueue(newProgress); + } + emit progressInfo( folder, newProgress ); } - if( newProgress.kind == Progress::EndSync ) { - newProgress.overall_current_bytes = newProgress.overall_transmission_size; - newProgress.current_file_no = newProgress.overall_file_count; - } - _lastProgressHash[folder] = newProgress; - - emit progressInfo( folder, newProgress ); -} - -Progress::Info ProgressDispatcher::lastProgressInfo(const QString& folder) { - return _lastProgressHash[folder]; } } diff --git a/src/mirall/progressdispatcher.h b/src/mirall/progressdispatcher.h index a8aef19aa..91c7954bc 100644 --- a/src/mirall/progressdispatcher.h +++ b/src/mirall/progressdispatcher.h @@ -16,6 +16,8 @@ #include #include +#include +#include namespace Mirall { @@ -26,7 +28,7 @@ namespace Mirall { class Progress { public: - enum ProgressKind_s { + typedef enum { Invalid, StartSync, Download, @@ -39,11 +41,11 @@ public: EndUpload, EndSync, Error - }; - typedef ProgressKind_s Kind; + } Kind; - struct ProgressInfo_s { + typedef struct { Kind kind; + QString folder; QString current_file; qint64 file_size; qint64 current_file_bytes; @@ -53,8 +55,16 @@ public: qint64 overall_transmission_size; qint64 overall_current_bytes; - }; - typedef ProgressInfo_s Info; + QTime timestamp; + + } Info; + + typedef struct { + QString folder; + QString current_file; + QString error_message; + int error_code; + } SyncProblem; static QString asString( Kind ); }; @@ -77,7 +87,8 @@ public: static ProgressDispatcher* instance(); ~ProgressDispatcher(); - Progress::Info lastProgressInfo(const QString& folder); + QList recentChangedItems(int count); + QList recentProblems(int count); signals: /** @brief Signals the progress of data transmission. @@ -87,17 +98,19 @@ signals: */ - void progressInfo( const QString& folder, Progress::Info progress ); + void progressInfo( const QString& folder, const Progress::Info& progress ); + void progressSyncProblem( const QString& folder, const Progress::SyncProblem& problem ); protected: - void setProgressInfo(const QString &folder, Progress::Info newProgress); + void setProgressInfo(const QString &folder, const Progress::Info& progress); private: ProgressDispatcher(QObject* parent = 0); + const int _problemQueueSize; + QQueue _recentChanges; + QQueue _recentProblems; static ProgressDispatcher* _instance; - - QHash _lastProgressHash; }; }