From e3c4aa5dffecc8f62958c44035b2e58de0228eb4 Mon Sep 17 00:00:00 2001 From: Javier Date: Sun, 14 Jun 2015 17:17:12 +0200 Subject: better synchronization status reporting --- mainwindow.cc | 27 ++++++++++++++++++++++++++- mainwindow.h | 5 +++++ notebookmodel.cc | 42 ++++++++++++++++++++++++++++++++++++++++-- notebookmodel.h | 4 ++++ smartpenmanager.cc | 19 +++++++++++++++++++ smartpenmanager.h | 3 +++ smartpensyncer.cc | 9 +++++++++ smartpensyncer.h | 2 ++ 8 files changed, 108 insertions(+), 3 deletions(-) diff --git a/mainwindow.cc b/mainwindow.cc index 0fdf38d..b49a8da 100644 --- a/mainwindow.cc +++ b/mainwindow.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -13,7 +14,8 @@ MainWindow::MainWindow(QWidget *parent) : _media(new Phonon::MediaObject(this)), _mediaOutput(new Phonon::AudioOutput(this)), _replay(new PaperReplay(this)), - _replayModel(new PaperReplayModel(_replay, this)) + _replayModel(new PaperReplayModel(_replay, this)), + _statusLabel(new QLabel) { ui->setupUi(this); ui->notebookTree->setModel(_notebooks); @@ -30,6 +32,11 @@ MainWindow::MainWindow(QWidget *parent) : _media->setTickInterval(500); ui->replaySlider->setMediaObject(_media); ui->pauseButton->setVisible(false); + ui->statusBar->addWidget(_statusLabel, 1); + connect(_notebooks, SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(handleNotebookRowsInserted(QModelIndex,int,int))); + connect(_manager, SIGNAL(pensBeingSynchronizedChanged()), + this, SLOT(handlePensBeingSynchronizedChanged())); connect(_media, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(handleMediaStateChange(Phonon::State))); connect(_media, SIGNAL(totalTimeChanged(qint64)), @@ -140,6 +147,14 @@ void MainWindow::handleNotebookSelected(const QModelIndex &index) _notebooks->data(child, Qt::DisplayRole).toString()); } +void MainWindow::handleNotebookRowsInserted(const QModelIndex &index, int start, int end) +{ + Q_UNUSED(index); + Q_UNUSED(start); + Q_UNUSED(end); + QTimer::singleShot(200, ui->notebookTree, SLOT(expandAll())); +} + void MainWindow::handleCurPageChanged() { ui->pageEdit->setText(QString::number(ui->notebookView->curPage() + 1)); @@ -227,6 +242,16 @@ void MainWindow::handleMediaTick(qint64 time) ui->mediaPosLabel->setText(formatDuration(time)); } +void MainWindow::handlePensBeingSynchronizedChanged() +{ + QStringList pens = _manager->pensBeingSynchronized(); + if (pens.isEmpty()) { + _statusLabel->setText(QString()); + } else { + _statusLabel->setText(tr("Synchronizing %1...").arg(pens.join(", "))); + } +} + void MainWindow::handleExport() { if (_curNotebookName == PAPER_REPLAY) { diff --git a/mainwindow.h b/mainwindow.h index 9bce36a..72d8898 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -2,6 +2,7 @@ #define MAINWINDOW_H #include +#include #include #include #include "notebookmodel.h" @@ -30,6 +31,7 @@ public slots: private slots: void handleNotebookSelected(const QModelIndex &index); + void handleNotebookRowsInserted(const QModelIndex &index, int start, int end); void handleCurPageChanged(); void handlePaperReplaySelected(const QModelIndex &index); void handlePaperReplayRequested(const QString &file, qint64 time); @@ -38,6 +40,7 @@ private slots: void handleMediaStateChange(Phonon::State state); void handleMediaTotalTimeChanged(qint64 time); void handleMediaTick(qint64 time); + void handlePensBeingSynchronizedChanged(); void handleExport(); private: @@ -57,6 +60,8 @@ private: PaperReplay *_replay; PaperReplayModel *_replayModel; + + QLabel *_statusLabel; }; #endif // MAINWINDOW_H diff --git a/notebookmodel.cc b/notebookmodel.cc index 2b7c99f..2139ee7 100644 --- a/notebookmodel.cc +++ b/notebookmodel.cc @@ -4,6 +4,7 @@ #include #include #include "paperreplay.h" +#include "afdnotebook.h" #include "notebookmodel.h" #define NUM_COLUMNS 3 @@ -66,6 +67,15 @@ QVariant NotebookModel::data(const QModelIndex &index, int role) const return _pens[penIndex]; } break; + case Qt::DecorationRole: + switch (index.column()) { + case 2: + if (isPenLocked(_pens[penIndex])) { + return QApplication::style()->standardIcon(QStyle::SP_BrowserReload); + } + break; + } + break; } } else { const QString &penName = _pens[id]; @@ -77,7 +87,10 @@ QVariant NotebookModel::data(const QModelIndex &index, int role) const case 0: return notebooks.at(index.row()); case 1: - return 0; + if (notebookName != PAPER_REPLAY) { + return estimatePagesOfNotebook(penName, notebookName); + } + break; } break; case Qt::DecorationRole: @@ -90,6 +103,7 @@ QVariant NotebookModel::data(const QModelIndex &index, int role) const if (isNotebookLocked(penName, notebookName)) { return QApplication::style()->standardIcon(QStyle::SP_BrowserReload); } + break; } case Qt::TextAlignmentRole: switch (index.column()) { @@ -240,6 +254,8 @@ void NotebookModel::refreshPen(const QString &name) QModelIndex penIndex = index(indexOfPen(name), 0, QModelIndex()); + emit dataChanged(penIndex, index(penIndex.row(), NUM_COLUMNS - 1, QModelIndex())); + int i = 0, j = 0; while (i < curNotebooks.size() && j < diskNotebooks.size()) { int comp = QString::compare(curNotebooks[i], diskNotebooks[j], Qt::CaseInsensitive); @@ -283,9 +299,14 @@ int NotebookModel::indexOfPen(const QString &name) } } +QDir NotebookModel::penDir(const QString &pen) const +{ + return QDir(penDirectory(pen)); +} + QDir NotebookModel::notebookDir(const QString &pen, const QString ¬ebook) const { - return QDir(_dataDir.filePath("%1.pen/%2.afd").arg(pen, notebook)); + return QDir(notebookDirectory(pen, notebook)); } QIcon NotebookModel::getNotebookIcon(const QString &pen, const QString ¬ebook) const @@ -311,6 +332,16 @@ QIcon NotebookModel::getNotebookIcon(const QString &pen, const QString ¬ebook return icon; } +bool NotebookModel::isPenLocked(const QString &pen) const +{ + QDir dir = penDir(pen); + if (dir.exists(".sync.lck")) { + return true; // TODO check if stale + } else { + return false; + } +} + bool NotebookModel::isNotebookLocked(const QString &pen, const QString ¬ebook) const { QDir dir = notebookDir(pen, notebook); @@ -321,6 +352,13 @@ bool NotebookModel::isNotebookLocked(const QString &pen, const QString ¬ebook } } +int NotebookModel::estimatePagesOfNotebook(const QString &pen, const QString ¬ebook) const +{ + QDir dataDir(notebookDirectory(pen, notebook) + "/data"); + QStringList pages = dataDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + return pages.count(); +} + void NotebookModel::handleChangedDirectory(const QString &path) { qDebug() << "changed" << path; diff --git a/notebookmodel.h b/notebookmodel.h index 1f52088..cbe94c6 100644 --- a/notebookmodel.h +++ b/notebookmodel.h @@ -33,10 +33,14 @@ private: private: int indexOfPen(const QString &name); + QDir penDir(const QString &pen) const; QDir notebookDir(const QString &pen, const QString ¬ebook) const; QIcon getNotebookIcon(const QString &pen, const QString ¬ebook) const; + bool isPenLocked(const QString &pen) const; bool isNotebookLocked(const QString &pen, const QString ¬ebook) const; + int estimatePagesOfNotebook(const QString &pen, const QString ¬ebook) const; + private slots: void handleChangedDirectory(const QString &path); diff --git a/smartpenmanager.cc b/smartpenmanager.cc index ad6416b..b64f333 100644 --- a/smartpenmanager.cc +++ b/smartpenmanager.cc @@ -38,6 +38,22 @@ SmartpenManager::~SmartpenManager() udev_unref(_udev); } +QStringList SmartpenManager::pensBeingSynchronized() const +{ + QStringList pens; + pens.reserve(_syncers.size()); + for (QMap::const_iterator it = _syncers.begin(); + it != _syncers.end(); ++it) { + QString name = it.value()->penName(); + if (name.isEmpty()) { + Smartpen::Address addr = it.value()->penAddress(); + name = QString("%1-%2").arg(addr.first, addr.second); + } + pens.append(name); + } + return pens; +} + void SmartpenManager::handleMonitorActivity() { qDebug() << "udev activity"; @@ -55,6 +71,7 @@ void SmartpenManager::handleSyncerFinished() qDebug() << "Finished synchronization with pen with address:" << addr; _syncers.remove(addr); syncer->deleteLater(); + emit pensBeingSynchronizedChanged(); } void SmartpenManager::processDevice(udev_device *dev) @@ -67,6 +84,8 @@ void SmartpenManager::processDevice(udev_device *dev) SmartpenSyncer *syncer = new SmartpenSyncer(addr, this); _syncers.insert(addr, syncer); connect(syncer, SIGNAL(finished()), SLOT(handleSyncerFinished())); + connect(syncer, SIGNAL(penNameChanged()), SIGNAL(pensBeingSynchronizedChanged())); syncer->start(); + emit pensBeingSynchronizedChanged(); } } diff --git a/smartpenmanager.h b/smartpenmanager.h index ab6f159..77b0978 100644 --- a/smartpenmanager.h +++ b/smartpenmanager.h @@ -19,8 +19,11 @@ public: explicit SmartpenManager(QObject *parent = 0); ~SmartpenManager(); + QStringList pensBeingSynchronized() const; + signals: void syncComplete(const QString &penName); + void pensBeingSynchronizedChanged(); public slots: diff --git a/smartpensyncer.cc b/smartpensyncer.cc index 7119812..654b0eb 100644 --- a/smartpensyncer.cc +++ b/smartpensyncer.cc @@ -58,6 +58,11 @@ Smartpen::Address SmartpenSyncer::penAddress() const return _addr; } +QString SmartpenSyncer::penName() const +{ + return _penName; +} + void SmartpenSyncer::abort() { _aborted = true; @@ -73,6 +78,7 @@ void SmartpenSyncer::run() _penName = _pen->getPenName(); qDebug() << "got pen name:" << _penName; + emit penNameChanged(); QVariantMap penInfo = _pen->getPenInfo(); if (penInfo.isEmpty()) { @@ -102,6 +108,8 @@ bool SmartpenSyncer::syncPen() QDateTime lastSyncTime = getTimestampFileDate(_penDataDir.filePath(".lastsync")); QList changes = _pen->getChangeList(lastSyncTime); + setTimestampFileDate(_penDataDir.filePath(".sync.lck")); + foreach(const Smartpen::ChangeReport &change, changes) { if (!change.guid.isEmpty()) { qDebug() << "Synchronizing guid: " << change.guid << change.title; @@ -117,6 +125,7 @@ bool SmartpenSyncer::syncPen() } setTimestampFileDate(_penDataDir.filePath(".lastsync")); + removeTimestampFile(_penDataDir.filePath(".sync.lck")); return true; } diff --git a/smartpensyncer.h b/smartpensyncer.h index 7d8e0c9..107030b 100644 --- a/smartpensyncer.h +++ b/smartpensyncer.h @@ -13,8 +13,10 @@ public: ~SmartpenSyncer(); Smartpen::Address penAddress() const; + QString penName() const; signals: + void penNameChanged(); public slots: void abort(); -- cgit v1.2.3