diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 3c95d925f..eaa6a22b7 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -22,8 +22,6 @@ set(client_UI_SRCS generalsettings.ui ignorelisteditor.ui networksettings.ui - protocolwidget.ui - issueswidget.ui activitywidget.ui synclogdialog.ui settingsdialog.ui @@ -70,8 +68,6 @@ set(client_SRCS openfilemanager.cpp owncloudgui.cpp owncloudsetupwizard.cpp - protocolwidget.cpp - issueswidget.cpp activitydata.cpp activitylistmodel.cpp activitywidget.cpp diff --git a/src/gui/activityitemdelegate.cpp b/src/gui/activityitemdelegate.cpp index fb5d7096a..ea0fdcd87 100644 --- a/src/gui/activityitemdelegate.cpp +++ b/src/gui/activityitemdelegate.cpp @@ -131,7 +131,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & int top = option.rect.top() + margin - offset; int buttonSize = option.rect.height()/2.5; - // Secondary will be 'Dismiss' or '...' + // Secondary will be 'Dismiss' or '...' multiple options button secondaryButton.rect = option.rect; secondaryButton.icon = QIcon(QLatin1String(":/client/resources/dialog-close.png")); if(customList.size() > 1) @@ -170,7 +170,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & int top = option.rect.top() + margin - offset; int buttonSize = option.rect.height()/2.5; - // Secondary will be 'Dismiss' or '...' + // Secondary will be 'open file manager' with the folder icon secondaryButton.rect = option.rect; secondaryButton.icon = QIcon(QLatin1String(":/client/resources/folder-grey.png")); @@ -184,7 +184,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & secondaryButton.features |= QStyleOptionButton::Flat; secondaryButton.state |= QStyle::State_Raised; - // Primary button will be 'More Information' + // Primary button will be 'open browser' primaryButton.rect = option.rect; primaryButton.text = tr("Open Browser"); right = secondaryButton.rect.left() - rightMargin; @@ -251,8 +251,6 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & if (option.state & QStyle::State_Selected) painter->setPen(option.palette.color(cg, QPalette::HighlightedText)); - - qDebug() << "Message text: " << messageText; const QString elidedMessage = fm.elidedText(messageText, Qt::ElideRight, spaceLeftForText); painter->drawText(messageTextBox, elidedMessage); } @@ -285,11 +283,15 @@ bool ActivityItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, int x = option.rect.left() + option.rect.width() - buttonsWidth - _timeWidth; int y = option.rect.top(); + // clickable area for ... if (mouseEventX > x && mouseEventX < x + buttonsWidth){ if(mouseEventY > y && mouseEventY < y + _buttonHeight){ + + // ...primary button ('more information' on notifications or 'open browser' on errors) if (mouseEventX > x && mouseEventX < x + _primaryButtonWidth) emit primaryButtonClickedOnItemView(index); + // ...secondary button ('dismiss' on notifications or 'open file manager' on errors) x += _primaryButtonWidth + _spaceBetweenButtons; if (mouseEventX > x && mouseEventX < x + _secondaryButtonWidth) emit secondaryButtonClickedOnItemView(index); diff --git a/src/gui/activitylistmodel.cpp b/src/gui/activitylistmodel.cpp index 3ff139131..de2423294 100644 --- a/src/gui/activitylistmodel.cpp +++ b/src/gui/activitylistmodel.cpp @@ -120,7 +120,6 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const return a._message; break; case ActivityItemDelegate::LinkRole: - qDebug() << "Link Role!" << a._link; return a._link; break; case ActivityItemDelegate::AccountRole: @@ -151,14 +150,11 @@ bool ActivityListModel::canFetchMore(const QModelIndex &) const if (_activityLists.count() == 0) return true; - //for (auto i = _activityLists.begin(); i != _activityLists.end(); ++i) { - //foreach(Activity activity, _activityLists){ - if (_accountState && _accountState->isConnected()) { - if (_activityLists.count() == 0 && !_currentlyFetching) { - return true; - } + if (_accountState && _accountState->isConnected()) { + if (_activityLists.count() == 0 && !_currentlyFetching) { + return true; } - //} + } return false; } diff --git a/src/gui/activitywidget.cpp b/src/gui/activitywidget.cpp index 43b9205a6..8d11a3ca0 100644 --- a/src/gui/activitywidget.cpp +++ b/src/gui/activitywidget.cpp @@ -29,8 +29,6 @@ #include "accountstate.h" #include "accountmanager.h" #include "activityitemdelegate.h" -#include "protocolwidget.h" -#include "issueswidget.h" #include "QProgressIndicator.h" #include "notificationwidget.h" #include "notificationconfirmjob.h" @@ -39,7 +37,7 @@ #include "ocsjob.h" #include "configfile.h" #include "guiutility.h" - +#include "socketapi.h" #include "ui_activitywidget.h" #include @@ -109,6 +107,7 @@ ActivityWidget::~ActivityWidget() delete _ui; } +// TODO void ActivityWidget::slotProgressInfo(const QString &folder, const ProgressInfo &progress) { if (progress.status() == ProgressInfo::Starting) { @@ -123,14 +122,20 @@ void ActivityWidget::slotItemCompleted(const QString &folder, const SyncFileItem if (!folderInstance) return; - // check if we are adding it to the right account and if it is useful information (error) + // check if we are adding it to the right account and if it is useful information (protocol errors) if(folderInstance->accountState() == _accountState){ + QString pathToFile = QString("%1/%2").arg(folderInstance->cleanPath(), item->_file); + qCWarning(lcActivity) << "Item " << pathToFile << " retrieved resulted in " << item->_errorString; + Activity activity; activity._type = Activity::ErrorType; activity._dateTime = QDateTime::fromString(QDateTime::currentDateTime().toString(), Qt::ISODate); activity._subject = item->_errorString; activity._message = item->_originalFile; - // TODO: use the full path to the file + + // TODO: maybe use the full path to access the file in the browser + // folderInstance->accountState()->account()->deprecatedPrivateLinkUrl(item->_fileId).toString(); + activity._link = folderInstance->accountState()->account()->url(); activity._status = item->_status; activity._accName = folderInstance->accountState()->account()->displayName(); @@ -143,8 +148,8 @@ void ActivityWidget::slotItemCompleted(const QString &folder, const SyncFileItem al._isPrimary = true; activity._links.append(al); + // add 'protocol error' to activity list _model->addErrorToActivityList(activity); - // add error widget } } @@ -156,6 +161,8 @@ void ActivityWidget::addError(const QString &folderAlias, const QString &message return; if(folderInstance->accountState() == _accountState){ + qCWarning(lcActivity) << "Item " << folderInstance->shortGuiLocalPath() << " retrieved resulted in " << message; + Activity activity; activity._type = Activity::ErrorType; activity._dateTime = QDateTime::fromString(QDateTime::currentDateTime().toString(), Qt::ISODate); @@ -174,6 +181,7 @@ void ActivityWidget::addError(const QString &folderAlias, const QString &message activity._links.append(link); } + // add 'other errors' to activity list _model->addErrorToActivityList(activity); } } @@ -181,9 +189,10 @@ void ActivityWidget::addError(const QString &folderAlias, const QString &message void ActivityWidget::slotPrimaryButtonClickedOnListView(const QModelIndex &index){ QUrl link = qvariant_cast(index.data(ActivityItemDelegate::LinkRole)); - qDebug() << "Tyring to open link: " << link; - if(!link.isEmpty()) + if(!link.isEmpty()){ + qCWarning(lcActivity) << "Opening" << link.toString() << "in browser for Notification/Activity" << qvariant_cast(index.data(ActivityItemDelegate::ActionTextRole)); Utility::openBrowser(link, this); + } } void ActivityWidget::slotSecondaryButtonClickedOnListView(const QModelIndex &index){ @@ -196,10 +205,13 @@ void ActivityWidget::slotSecondaryButtonClickedOnListView(const QModelIndex &ind if(qvariant_cast(index.data(ActivityItemDelegate::ActionRole)) == Activity::Type::NotificationType){ const QString accountName = index.data(ActivityItemDelegate::AccountRole).toString(); if(actionLinks.size() == 1){ - if(actionLinks.at(0)._verb == "DELETE") + if(actionLinks.at(0)._verb == "DELETE"){ + qCWarning(lcActivity) << "Dismissing Notification/Activity" << qvariant_cast(index.data(ActivityItemDelegate::ActionTextRole)); slotSendNotificationRequest(index.data(ActivityItemDelegate::AccountRole).toString(), actionLinks.at(0)._link, actionLinks.at(0)._verb, index.row()); + } } else if(actionLinks.size() > 1){ QMenu menu; + qCWarning(lcActivity) << "Displaying menu for Notification/Activity" << qvariant_cast(index.data(ActivityItemDelegate::ActionTextRole)); foreach (ActivityLink actionLink, actionLinks) { QAction *menuAction = new QAction(actionLink._label, &menu); connect(menuAction, &QAction::triggered, this, [this, index, accountName, actionLink] { @@ -212,10 +224,10 @@ void ActivityWidget::slotSecondaryButtonClickedOnListView(const QModelIndex &ind } if(qvariant_cast(index.data(ActivityItemDelegate::ActionRole)) == Activity::Type::ErrorType){ - QString fileName = index.data(ActivityItemDelegate::PathRole).toString(); - // check if this is actually a folder + // check if this is actually a folder that we can open if (FolderMan::instance()->folderForPath(actionLinks.first()._link)) { if (QFile(actionLinks.first()._link).exists()) { + qCWarning(lcActivity) << "Opening path" << actionLinks.first()._link << "in the file manager for Notification/Activity" << qvariant_cast(index.data(ActivityItemDelegate::ActionTextRole)); showInFileManager(actionLinks.first()._link); } } @@ -231,8 +243,8 @@ void ActivityWidget::slotNotificationRequestFinished(int statusCode) qCWarning(lcActivity) << "Notification Request to Server failed, leave notification visible."; } else { // to do use the model to rebuild the list or remove the item - qDebug() << "Notification to be removed from row" << row; - _model->removeFromActivityList(row); + qCWarning(lcActivity) << "Notification Request to Server successed, rebuilding list."; + _model->removeFromActivityList(row); } } @@ -358,7 +370,7 @@ void ActivityWidget::slotOpenFile(QModelIndex indx) qCDebug(lcActivity) << indx.isValid() << indx.data(ActivityItemDelegate::PathRole).toString() << QFile::exists(indx.data(ActivityItemDelegate::PathRole).toString()); if (indx.isValid()) { QString fullPath = indx.data(ActivityItemDelegate::PathRole).toString(); - // TO DO: use full path to file + // TODO: use full path to file if (QFile::exists(fullPath)) { showInFileManager(fullPath); } @@ -422,7 +434,6 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList &list) void ActivityWidget::slotSendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row) { qCInfo(lcActivity) << "Server Notification Request " << verb << link << "on account" << accountName; - NotificationWidget *theSender = qobject_cast(sender()); const QStringList validVerbs = QStringList() << "GET" << "PUT" @@ -436,8 +447,6 @@ void ActivityWidget::slotSendNotificationRequest(const QString &accountName, con QUrl l(link); job->setLinkAndVerb(l, verb); job->setProperty("activityRow", QVariant::fromValue(row)); - // save the activity to be hidden or the QModelIndex - //job->setProperty(); connect(job, &AbstractNetworkJob::networkError, this, &ActivityWidget::slotNotifyNetworkError); connect(job, &NotificationConfirmJob::jobFinished, @@ -566,20 +575,6 @@ ActivitySettings::ActivitySettings(AccountState *accountState, QWidget *parent) // connect a model signal to stop the animation connect(_activityWidget, &ActivityWidget::rowsInserted, _progressIndicator, &QProgressIndicator::stopAnimation); connect(_activityWidget, &ActivityWidget::rowsInserted, this, &ActivitySettings::slotDisplayActivities); - - //_protocolWidget = new ProtocolWidget(this); - //_vbox->addWidget(_protocolWidget); -// _protocolTabId = _tab->addTab(_protocolWidget, Theme::instance()->syncStateIcon(SyncResult::Success), tr("Sync Protocol")); -// connect(_protocolWidget, &ProtocolWidget::copyToClipboard, this, &ActivitySettings::slotCopyToClipboard); - -// _issuesWidget = new IssuesWidget(this); -// _vbox->addWidget(_issuesWidget); -// _syncIssueTabId = _tab->addTab(_issuesWidget, Theme::instance()->syncStateIcon(SyncResult::Problem), QString()); -// slotShowIssueItemCount(0); // to display the label. -// connect(_issuesWidget, &IssuesWidget::issueCountUpdated, -// this, &ActivitySettings::slotShowIssueItemCount); -// connect(_issuesWidget, &IssuesWidget::copyToClipboard, -// this, &ActivitySettings::slotCopyToClipboard); } void ActivitySettings::slotDisplayActivities(){ @@ -599,27 +594,16 @@ void ActivitySettings::slotShowIssueItemCount(int cnt) //: %1 is the number of not synced files. cntText = tr("Not Synced (%1)").arg(cnt); } - //_tab->setTabText(_syncIssueTabId, cntText); } +// TODO void ActivitySettings::slotCopyToClipboard() { QString text; QTextStream ts(&text); - //int idx = _tab->currentIndex(); QString message; -// if (idx == _protocolTabId) { -// // the protocol widget -// //_protocolWidget->storeSyncActivity(ts); -// message = tr("The sync activity list has been copied to the clipboard."); -// } else if (idx == _syncIssueTabId) { -// // issues Widget -// message = tr("The list of unsynced items has been copied to the clipboard."); -// //_issuesWidget->storeSyncIssues(ts); -// } - QApplication::clipboard()->setText(text); emit guiLog(tr("Copied to clipboard"), message); diff --git a/src/gui/activitywidget.h b/src/gui/activitywidget.h index 17a01b0e0..3e04bb915 100644 --- a/src/gui/activitywidget.h +++ b/src/gui/activitywidget.h @@ -36,8 +36,6 @@ namespace OCC { class Account; class AccountStatusPtr; -class ProtocolWidget; -class IssuesWidget; class JsonApiJob; class NotificationWidget; class ActivityListModel; @@ -168,8 +166,6 @@ private: bool event(QEvent *e) Q_DECL_OVERRIDE; ActivityWidget *_activityWidget; - ProtocolWidget *_protocolWidget; - IssuesWidget *_issuesWidget; QProgressIndicator *_progressIndicator; QVBoxLayout *_vbox; QTimer _notificationCheckTimer; diff --git a/src/gui/iconjob.cpp b/src/gui/iconjob.cpp index decd9a211..c77a925b1 100644 --- a/src/gui/iconjob.cpp +++ b/src/gui/iconjob.cpp @@ -28,12 +28,8 @@ IconJob::IconJob(const QUrl &url, QObject *parent) : void IconJob::finished(QNetworkReply *reply) { - if (reply->error() != QNetworkReply::NoError) { - qDebug() << reply->url() << " - " << reply->errorString(); + if (reply->error() != QNetworkReply::NoError) return; - } - - qDebug() << "Icon job finished for " << reply->url(); reply->deleteLater(); emit jobFinished(reply->readAll()); diff --git a/src/gui/issueswidget.cpp b/src/gui/issueswidget.cpp deleted file mode 100644 index 04359dcae..000000000 --- a/src/gui/issueswidget.cpp +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright (C) by Klaas Freitag - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include -#include - -#include "issueswidget.h" -#include "configfile.h" -#include "syncresult.h" -#include "syncengine.h" -#include "logger.h" -#include "theme.h" -#include "folderman.h" -#include "syncfileitem.h" -#include "folder.h" -#include "openfilemanager.h" -#include "activityitemdelegate.h" -#include "protocolwidget.h" -#include "accountstate.h" -#include "account.h" -#include "accountmanager.h" -#include "common/syncjournalfilerecord.h" -#include "elidedlabel.h" - - -#include "ui_issueswidget.h" - -#include - -namespace OCC { - -/** - * If more issues are reported than this they will not show up - * to avoid performance issues around sorting this many issues. - */ -static const int maxIssueCount = 50000; - -static QPair pathsWithIssuesKey(const ProtocolItem::ExtraData &data) -{ - return qMakePair(data.folderName, data.path); -} - -IssuesWidget::IssuesWidget(QWidget *parent) - : QWidget(parent) - , _ui(new Ui::IssuesWidget) -{ - _ui->setupUi(this); - - connect(ProgressDispatcher::instance(), &ProgressDispatcher::progressInfo, - this, &IssuesWidget::slotProgressInfo); - connect(ProgressDispatcher::instance(), &ProgressDispatcher::itemCompleted, - this, &IssuesWidget::slotItemCompleted); - connect(ProgressDispatcher::instance(), &ProgressDispatcher::syncError, - this, &IssuesWidget::addError); - - connect(_ui->_treeWidget, &QTreeWidget::itemActivated, this, &IssuesWidget::slotOpenFile); - connect(_ui->copyIssuesButton, &QAbstractButton::clicked, this, &IssuesWidget::copyToClipboard); - - _ui->_treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); - connect(_ui->_treeWidget, &QTreeWidget::customContextMenuRequested, this, &IssuesWidget::slotItemContextMenu); - - connect(_ui->showIgnores, &QAbstractButton::toggled, this, &IssuesWidget::slotRefreshIssues); - connect(_ui->showWarnings, &QAbstractButton::toggled, this, &IssuesWidget::slotRefreshIssues); - connect(_ui->filterAccount, static_cast(&QComboBox::currentIndexChanged), this, &IssuesWidget::slotRefreshIssues); - connect(_ui->filterAccount, static_cast(&QComboBox::currentIndexChanged), this, &IssuesWidget::slotUpdateFolderFilters); - connect(_ui->filterFolder, static_cast(&QComboBox::currentIndexChanged), this, &IssuesWidget::slotRefreshIssues); - for (auto account : AccountManager::instance()->accounts()) { - slotAccountAdded(account.data()); - } - connect(AccountManager::instance(), &AccountManager::accountAdded, - this, &IssuesWidget::slotAccountAdded); - connect(AccountManager::instance(), &AccountManager::accountRemoved, - this, &IssuesWidget::slotAccountRemoved); - connect(FolderMan::instance(), &FolderMan::folderListChanged, - this, &IssuesWidget::slotUpdateFolderFilters); - - - // Adjust copyToClipboard() when making changes here! - QStringList header; - header << tr("Time"); - header << tr("File"); - header << tr("Folder"); - header << tr("Issue"); - - int timestampColumnExtra = 0; -#ifdef Q_OS_WIN - timestampColumnExtra = 20; // font metrics are broken on Windows, see #4721 -#endif - - _ui->_treeWidget->setHeaderLabels(header); - int timestampColumnWidth = - ActivityItemDelegate::rowHeight() // icon - + _ui->_treeWidget->fontMetrics().width(ProtocolItem::timeString(QDateTime::currentDateTime())) - + timestampColumnExtra; - _ui->_treeWidget->setColumnWidth(0, timestampColumnWidth); - _ui->_treeWidget->setColumnWidth(1, 180); - _ui->_treeWidget->setColumnCount(4); - _ui->_treeWidget->setRootIsDecorated(false); - _ui->_treeWidget->setTextElideMode(Qt::ElideMiddle); - _ui->_treeWidget->header()->setObjectName("ActivityErrorListHeader"); -#if defined(Q_OS_MAC) - _ui->_treeWidget->setMinimumWidth(400); -#endif - - _reenableSorting.setInterval(5000); - connect(&_reenableSorting, &QTimer::timeout, this, - [this]() { _ui->_treeWidget->setSortingEnabled(true); }); - - _ui->_tooManyIssuesWarning->hide(); - connect(this, &IssuesWidget::issueCountUpdated, this, - [this](int count) { _ui->_tooManyIssuesWarning->setVisible(count >= maxIssueCount); }); - - _ui->_conflictHelp->hide(); - _ui->_conflictHelp->setText( - tr("There were conflicts. Check the documentation on how to resolve them.") - .arg(Theme::instance()->conflictHelpUrl())); -} - -IssuesWidget::~IssuesWidget() -{ - delete _ui; -} - -void IssuesWidget::showEvent(QShowEvent *ev) -{ - ConfigFile cfg; - cfg.restoreGeometryHeader(_ui->_treeWidget->header()); - - // Sorting by section was newly enabled. But if we restore the header - // from a state where sorting was disabled, both of these flags will be - // false and sorting will be impossible! - _ui->_treeWidget->header()->setSectionsClickable(true); - _ui->_treeWidget->header()->setSortIndicatorShown(true); - - // Switch back to "first important, then by time" ordering - _ui->_treeWidget->sortByColumn(0, Qt::DescendingOrder); - - QWidget::showEvent(ev); -} - -void IssuesWidget::hideEvent(QHideEvent *ev) -{ - ConfigFile cfg; - cfg.saveGeometryHeader(_ui->_treeWidget->header()); - QWidget::hideEvent(ev); -} - -static bool persistsUntilLocalDiscovery(QTreeWidgetItem *item) -{ - const auto data = ProtocolItem::extraData(item); - return data.status == SyncFileItem::Conflict - || (data.status == SyncFileItem::FileIgnored && data.direction == SyncFileItem::Up); -} - -void IssuesWidget::cleanItems(const std::function &shouldDelete) -{ - _ui->_treeWidget->setSortingEnabled(false); - - // The issue list is a state, clear it and let the next sync fill it - // with ignored files and propagation errors. - int itemCnt = _ui->_treeWidget->topLevelItemCount(); - for (int cnt = itemCnt - 1; cnt >= 0; cnt--) { - QTreeWidgetItem *item = _ui->_treeWidget->topLevelItem(cnt); - if (shouldDelete(item)) { - _pathsWithIssues.remove(pathsWithIssuesKey(ProtocolItem::extraData(item))); - delete item; - } - } - - _ui->_treeWidget->setSortingEnabled(true); - - // update the tabtext - emit(issueCountUpdated(_ui->_treeWidget->topLevelItemCount())); -} - -void IssuesWidget::addItem(QTreeWidgetItem *item) -{ - if (!item) - return; - - int count = _ui->_treeWidget->topLevelItemCount(); - if (count >= maxIssueCount) - return; - - _ui->_treeWidget->setSortingEnabled(false); - _reenableSorting.start(); - - // Insert item specific errors behind the others - int insertLoc = 0; - if (!item->text(1).isEmpty()) { - for (int i = 0; i < count; ++i) { - if (_ui->_treeWidget->topLevelItem(i)->text(1).isEmpty()) { - insertLoc = i + 1; - } else { - break; - } - } - } - - // Wipe any existing message for the same folder and path - auto newData = ProtocolItem::extraData(item); - if (_pathsWithIssues.contains(pathsWithIssuesKey(newData))) { - for (int i = 0; i < count; ++i) { - auto otherItem = _ui->_treeWidget->topLevelItem(i); - auto otherData = ProtocolItem::extraData(otherItem); - if (otherData.path == newData.path && otherData.folderName == newData.folderName) { - delete otherItem; - break; - } - } - } - - _ui->_treeWidget->insertTopLevelItem(insertLoc, item); - _pathsWithIssues.insert(pathsWithIssuesKey(newData)); - item->setHidden(!shouldBeVisible(item, currentAccountFilter(), currentFolderFilter())); - emit issueCountUpdated(_ui->_treeWidget->topLevelItemCount()); -} - -void IssuesWidget::slotOpenFile(QTreeWidgetItem *item, int) -{ - QString fileName = item->text(1); - if (Folder *folder = ProtocolItem::folder(item)) { - // folder->path() always comes back with trailing path - QString fullPath = folder->path() + fileName; - if (QFile(fullPath).exists()) { - showInFileManager(fullPath); - } - } -} - -void IssuesWidget::slotProgressInfo(const QString &folder, const ProgressInfo &progress) -{ - if (progress.status() == ProgressInfo::Reconcile) { - // Wipe all non-persistent entries - as well as the persistent ones - // in cases where a local discovery was done. - auto f = FolderMan::instance()->folder(folder); - if (!f) - return; - const auto &engine = f->syncEngine(); - const auto style = engine.lastLocalDiscoveryStyle(); - cleanItems([&](QTreeWidgetItem *item) { - if (ProtocolItem::extraData(item).folderName != folder) - return false; - if (style == LocalDiscoveryStyle::FilesystemOnly) - return true; - if (!persistsUntilLocalDiscovery(item)) - return true; - - // Definitely wipe the entry if the file no longer exists - if (!QFileInfo(f->path() + ProtocolItem::extraData(item).path).exists()) - return true; - - auto path = QFileInfo(ProtocolItem::extraData(item).path).dir().path().toUtf8(); - if (path == ".") - path.clear(); - - return engine.shouldDiscoverLocally(path); - }); - } - if (progress.status() == ProgressInfo::Done) { - // We keep track very well of pending conflicts. - // Inform other components about them. - QStringList conflicts; - auto tree = _ui->_treeWidget; - for (int i = 0; i < tree->topLevelItemCount(); ++i) { - auto item = tree->topLevelItem(i); - auto data = ProtocolItem::extraData(item); - if (data.folderName == folder - && data.status == SyncFileItem::Conflict) { - conflicts.append(data.path); - } - } - emit ProgressDispatcher::instance()->folderConflicts(folder, conflicts); - - _ui->_conflictHelp->setHidden(Theme::instance()->conflictHelpUrl().isEmpty() || conflicts.isEmpty()); - } -} - -void IssuesWidget::slotItemCompleted(const QString &folder, const SyncFileItemPtr &item) -{ - if (!item->showInIssuesTab()) - return; - QTreeWidgetItem *line = ProtocolItem::create(folder, *item); - if (!line) - return; - addItem(line); -} - -void IssuesWidget::slotRefreshIssues() -{ - auto tree = _ui->_treeWidget; - auto filterFolderAlias = currentFolderFilter(); - auto filterAccount = currentAccountFilter(); - - for (int i = 0; i < tree->topLevelItemCount(); ++i) { - auto item = tree->topLevelItem(i); - item->setHidden(!shouldBeVisible(item, filterAccount, filterFolderAlias)); - } - - _ui->_treeWidget->setColumnHidden(2, !filterFolderAlias.isEmpty()); -} - -void IssuesWidget::slotAccountAdded(AccountState *account) -{ - _ui->filterAccount->addItem(account->account()->displayName(), QVariant::fromValue(account)); - updateAccountChoiceVisibility(); -} - -void IssuesWidget::slotAccountRemoved(AccountState *account) -{ - for (int i = _ui->filterAccount->count() - 1; i >= 0; --i) { - if (account == _ui->filterAccount->itemData(i).value()) - _ui->filterAccount->removeItem(i); - } - updateAccountChoiceVisibility(); -} - -void IssuesWidget::slotItemContextMenu(const QPoint &pos) -{ - auto item = _ui->_treeWidget->itemAt(pos); - if (!item) - return; - auto globalPos = _ui->_treeWidget->viewport()->mapToGlobal(pos); - ProtocolItem::openContextMenu(globalPos, item, this); -} - -void IssuesWidget::updateAccountChoiceVisibility() -{ - bool visible = _ui->filterAccount->count() > 2; - _ui->filterAccount->setVisible(visible); - _ui->accountLabel->setVisible(visible); - slotUpdateFolderFilters(); -} - -AccountState *IssuesWidget::currentAccountFilter() const -{ - return _ui->filterAccount->currentData().value(); -} - -QString IssuesWidget::currentFolderFilter() const -{ - return _ui->filterFolder->currentData().toString(); -} - -bool IssuesWidget::shouldBeVisible(QTreeWidgetItem *item, AccountState *filterAccount, - const QString &filterFolderAlias) const -{ - bool visible = true; - auto data = ProtocolItem::extraData(item); - auto status = data.status; - visible &= (_ui->showIgnores->isChecked() || status != SyncFileItem::FileIgnored); - visible &= (_ui->showWarnings->isChecked() - || (status != SyncFileItem::SoftError - && status != SyncFileItem::Restoration)); - - const auto &folderalias = data.folderName; - if (filterAccount) { - auto folder = FolderMan::instance()->folder(folderalias); - visible &= folder && folder->accountState() == filterAccount; - } - visible &= (filterFolderAlias.isEmpty() || filterFolderAlias == folderalias); - - return visible; -} - -void IssuesWidget::slotUpdateFolderFilters() -{ - auto account = _ui->filterAccount->currentData().value(); - - // If there is no account selector, show folders for the single - // available account - if (_ui->filterAccount->isHidden() && _ui->filterAccount->count() > 1) { - account = _ui->filterAccount->itemData(1).value(); - } - - if (!account) { - _ui->filterFolder->setCurrentIndex(0); - } - _ui->filterFolder->setEnabled(account != 0); - - for (int i = _ui->filterFolder->count() - 1; i >= 1; --i) { - _ui->filterFolder->removeItem(i); - } - - // Find all selectable folders while figuring out if we need a folder - // selector in the first place - bool anyAccountHasMultipleFolders = false; - QSet accountsWithFolders; - for (auto folder : FolderMan::instance()->map().values()) { - if (accountsWithFolders.contains(folder->accountState())) - anyAccountHasMultipleFolders = true; - accountsWithFolders.insert(folder->accountState()); - - if (folder->accountState() != account) - continue; - _ui->filterFolder->addItem(folder->shortGuiLocalPath(), folder->alias()); - } - - // If we don't need the combo box, hide it. - _ui->filterFolder->setVisible(anyAccountHasMultipleFolders); - _ui->folderLabel->setVisible(anyAccountHasMultipleFolders); - - // If there's no choice, select the only folder and disable - if (_ui->filterFolder->count() == 2 && anyAccountHasMultipleFolders) { - _ui->filterFolder->setCurrentIndex(1); - _ui->filterFolder->setEnabled(false); - } -} - -void IssuesWidget::storeSyncIssues(QTextStream &ts) -{ - int topLevelItems = _ui->_treeWidget->topLevelItemCount(); - - for (int i = 0; i < topLevelItems; i++) { - QTreeWidgetItem *child = _ui->_treeWidget->topLevelItem(i); - if (child->isHidden()) - continue; - ts << right - // time stamp - << qSetFieldWidth(20) - << child->data(0, Qt::DisplayRole).toString() - // separator - << qSetFieldWidth(0) << "," - - // file name - << qSetFieldWidth(64) - << child->data(1, Qt::DisplayRole).toString() - // separator - << qSetFieldWidth(0) << "," - - // folder - << qSetFieldWidth(30) - << child->data(2, Qt::DisplayRole).toString() - // separator - << qSetFieldWidth(0) << "," - - // action - << qSetFieldWidth(15) - << child->data(3, Qt::DisplayRole).toString() - << qSetFieldWidth(0) - << endl; - } -} - -void IssuesWidget::showFolderErrors(const QString &folderAlias) -{ - auto folder = FolderMan::instance()->folder(folderAlias); - if (!folder) - return; - - _ui->filterAccount->setCurrentIndex( - qMax(0, _ui->filterAccount->findData(QVariant::fromValue(folder->accountState())))); - _ui->filterFolder->setCurrentIndex( - qMax(0, _ui->filterFolder->findData(folderAlias))); - _ui->showIgnores->setChecked(false); - _ui->showWarnings->setChecked(false); -} - -void IssuesWidget::addError(const QString &folderAlias, const QString &message, - ErrorCategory category) -{ - auto folder = FolderMan::instance()->folder(folderAlias); - if (!folder) - return; - - QStringList columns; - QDateTime timestamp = QDateTime::currentDateTime(); - const QString timeStr = ProtocolItem::timeString(timestamp); - const QString longTimeStr = ProtocolItem::timeString(timestamp, QLocale::LongFormat); - - columns << timeStr; - columns << ""; // no "File" entry - columns << folder->shortGuiLocalPath(); - columns << message; - - QIcon icon = Theme::instance()->syncStateIcon(SyncResult::Error); - - QTreeWidgetItem *twitem = new ProtocolItem(columns); - twitem->setData(0, Qt::SizeHintRole, QSize(0, ActivityItemDelegate::rowHeight())); - twitem->setIcon(0, icon); - twitem->setToolTip(0, longTimeStr); - twitem->setToolTip(3, message); - ProtocolItem::ExtraData data; - data.timestamp = timestamp; - data.folderName = folderAlias; - data.status = SyncFileItem::NormalError; - ProtocolItem::setExtraData(twitem, data); - - addItem(twitem); - addErrorWidget(twitem, message, category); -} - -void IssuesWidget::addErrorWidget(QTreeWidgetItem *item, const QString &message, ErrorCategory category) -{ - QWidget *widget = 0; - if (category == ErrorCategory::InsufficientRemoteStorage) { - widget = new QWidget; - auto layout = new QHBoxLayout; - widget->setLayout(layout); - - auto label = new ElidedLabel(message, widget); - label->setElideMode(Qt::ElideMiddle); - layout->addWidget(label); - - auto button = new QPushButton("Retry all uploads", widget); - button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); - auto folderAlias = ProtocolItem::extraData(item).folderName; - connect(button, &QPushButton::clicked, - this, [this, folderAlias]() { retryInsufficentRemoteStorageErrors(folderAlias); }); - layout->addWidget(button); - } - - if (widget) { - item->setText(3, QString()); - } - _ui->_treeWidget->setItemWidget(item, 3, widget); -} - -void IssuesWidget::retryInsufficentRemoteStorageErrors(const QString &folderAlias) -{ - auto folderman = FolderMan::instance(); - auto folder = folderman->folder(folderAlias); - if (!folder) - return; - - folder->journalDb()->wipeErrorBlacklistCategory(SyncJournalErrorBlacklistRecord::InsufficientRemoteStorage); - folderman->scheduleFolderNext(folder); -} -} diff --git a/src/gui/issueswidget.h b/src/gui/issueswidget.h deleted file mode 100644 index 2a897a8b3..000000000 --- a/src/gui/issueswidget.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) by Klaas Freitag - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef ISSUESWIDGET_H -#define ISSUESWIDGET_H - -#include -#include -#include -#include - -#include "progressdispatcher.h" -#include "owncloudgui.h" - -#include "ui_issueswidget.h" - -class QPushButton; - -namespace OCC { -class SyncResult; - -namespace Ui { - class ProtocolWidget; -} -class Application; - -/** - * @brief The ProtocolWidget class - * @ingroup gui - */ -class IssuesWidget : public QWidget -{ - Q_OBJECT -public: - explicit IssuesWidget(QWidget *parent = 0); - ~IssuesWidget(); - QSize sizeHint() const { return ownCloudGui::settingsDialogSize(); } - - void storeSyncIssues(QTextStream &ts); - void showFolderErrors(const QString &folderAlias); - -public slots: - void addError(const QString &folderAlias, const QString &message, ErrorCategory category); - void slotProgressInfo(const QString &folder, const ProgressInfo &progress); - void slotItemCompleted(const QString &folder, const SyncFileItemPtr &item); - void slotOpenFile(QTreeWidgetItem *item, int); - -protected: - void showEvent(QShowEvent *); - void hideEvent(QHideEvent *); - -signals: - void copyToClipboard(); - void issueCountUpdated(int); - -private slots: - void slotRefreshIssues(); - void slotUpdateFolderFilters(); - void slotAccountAdded(AccountState *account); - void slotAccountRemoved(AccountState *account); - void slotItemContextMenu(const QPoint &pos); - -private: - void updateAccountChoiceVisibility(); - AccountState *currentAccountFilter() const; - QString currentFolderFilter() const; - bool shouldBeVisible(QTreeWidgetItem *item, AccountState *filterAccount, - const QString &filterFolderAlias) const; - void cleanItems(const std::function &shouldDelete); - void addItem(QTreeWidgetItem *item); - - /// Add the special error widget for the category, if any - void addErrorWidget(QTreeWidgetItem *item, const QString &message, ErrorCategory category); - - /// Wipes all insufficient remote storgage blacklist entries - void retryInsufficentRemoteStorageErrors(const QString &folderAlias); - - /// Each insert disables sorting, this timer reenables it - QTimer _reenableSorting; - - /// Optimization: keep track of all folder/paths pairs that have an associated issue - QSet> _pathsWithIssues; - - Ui::IssuesWidget *_ui; -}; -} - -#endif diff --git a/src/gui/issueswidget.ui b/src/gui/issueswidget.ui deleted file mode 100644 index f1c2d8fdf..000000000 --- a/src/gui/issueswidget.ui +++ /dev/null @@ -1,198 +0,0 @@ - - - OCC::IssuesWidget - - - - 0 - 0 - 580 - 578 - - - - Form - - - - - - List of issues - - - Qt::PlainText - - - - - - - - - - - Account - - - - - - - - <no filter> - - - - - - - - Folder - - - - - - - false - - - - <no filter> - - - - - - - - - - - - Show warnings - - - true - - - - - - - Show ignored files - - - true - - - - - - - - - - - true - - - false - - - true - - - 4 - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - - - - - - - - There were too many issues. Not all will be visible here. - - - true - - - - - - - There were conflicts. Check the documentation on how to resolve them. - - - true - - - true - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 0 - - - - - - - - Copy the issues list to the clipboard. - - - Copy - - - - - - - - - - - - - - - diff --git a/src/gui/protocolwidget.cpp b/src/gui/protocolwidget.cpp deleted file mode 100644 index 086e7d205..000000000 --- a/src/gui/protocolwidget.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) by Klaas Freitag - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include -#include - -#include "protocolwidget.h" -#include "configfile.h" -#include "syncresult.h" -#include "logger.h" -#include "theme.h" -#include "folderman.h" -#include "syncfileitem.h" -#include "folder.h" -#include "openfilemanager.h" -#include "activityitemdelegate.h" -#include "guiutility.h" -#include "accountstate.h" - -#include "ui_protocolwidget.h" - -#include - -Q_DECLARE_METATYPE(OCC::ProtocolItem::ExtraData) - -namespace OCC { - -QString ProtocolItem::timeString(QDateTime dt, QLocale::FormatType format) -{ - const QLocale loc = QLocale::system(); - QString dtFormat = loc.dateTimeFormat(format); - static const QRegExp re("(HH|H|hh|h):mm(?!:s)"); - dtFormat.replace(re, "\\1:mm:ss"); - return loc.toString(dt, dtFormat); -} - -ProtocolItem::ExtraData ProtocolItem::extraData(const QTreeWidgetItem *item) -{ - return item->data(0, Qt::UserRole).value(); -} - -void ProtocolItem::setExtraData(QTreeWidgetItem *item, const ExtraData &data) -{ - item->setData(0, Qt::UserRole, QVariant::fromValue(data)); -} - -ProtocolItem *ProtocolItem::create(const QString &folder, const SyncFileItem &item) -{ - auto f = FolderMan::instance()->folder(folder); - if (!f) { - return 0; - } - - QStringList columns; - QDateTime timestamp = QDateTime::currentDateTime(); - const QString timeStr = timeString(timestamp); - const QString longTimeStr = timeString(timestamp, QLocale::LongFormat); - - columns << timeStr; - columns << Utility::fileNameForGuiUse(item._originalFile); - columns << f->shortGuiLocalPath(); - - // If the error string is set, it's prefered because it is a useful user message. - QString message = item._errorString; - if (message.isEmpty()) { - message = Progress::asResultString(item); - } - columns << message; - - QIcon icon; - if (item._status == SyncFileItem::NormalError - || item._status == SyncFileItem::FatalError - || item._status == SyncFileItem::DetailError - || item._status == SyncFileItem::BlacklistedError) { - icon = Theme::instance()->syncStateIcon(SyncResult::Error); - } else if (Progress::isWarningKind(item._status)) { - icon = Theme::instance()->syncStateIcon(SyncResult::Problem); - } - - if (ProgressInfo::isSizeDependent(item)) { - columns << Utility::octetsToString(item._size); - } - - ProtocolItem *twitem = new ProtocolItem(columns); - // Warning: The data and tooltips on the columns define an implicit - // interface and can only be changed with care. - twitem->setData(0, Qt::SizeHintRole, QSize(0, ActivityItemDelegate::rowHeight())); - twitem->setIcon(0, icon); - twitem->setToolTip(0, longTimeStr); - twitem->setToolTip(1, item._file); - twitem->setToolTip(3, message); - ProtocolItem::ExtraData data; - data.timestamp = timestamp; - data.path = item._file; - data.folderName = folder; - data.status = item._status; - data.size = item._size; - data.direction = item._direction; - ProtocolItem::setExtraData(twitem, data); - return twitem; -} - -SyncJournalFileRecord ProtocolItem::syncJournalRecord(QTreeWidgetItem *item) -{ - SyncJournalFileRecord rec; - auto f = folder(item); - if (!f) - return rec; - f->journalDb()->getFileRecord(extraData(item).path, &rec); - return rec; -} - -Folder *ProtocolItem::folder(QTreeWidgetItem *item) -{ - return FolderMan::instance()->folder(extraData(item).folderName); -} - -void ProtocolItem::openContextMenu(QPoint globalPos, QTreeWidgetItem *item, QWidget *parent) -{ - auto f = folder(item); - if (!f) - return; - AccountPtr account = f->accountState()->account(); - auto rec = syncJournalRecord(item); - // rec might not be valid - - auto menu = new QMenu(parent); - - if (rec.isValid()) { - // "Open in Browser" action - auto openInBrowser = menu->addAction(ProtocolWidget::tr("Open in browser")); - QObject::connect(openInBrowser, &QAction::triggered, parent, [parent, account, rec]() { - fetchPrivateLinkUrl(account, rec._path, rec.numericFileId(), parent, - [parent](const QString &url) { - Utility::openBrowser(url, parent); - }); - }); - } - - // More actions will be conditionally added to the context menu here later - - if (menu->actions().isEmpty()) { - delete menu; - return; - } - - menu->setAttribute(Qt::WA_DeleteOnClose); - menu->popup(globalPos); -} - -bool ProtocolItem::operator<(const QTreeWidgetItem &other) const -{ - int column = treeWidget()->sortColumn(); - if (column == 0) { - // Items with empty "File" column are larger than others, - // otherwise sort by time (this uses lexicographic ordering) - return std::forward_as_tuple(text(1).isEmpty(), extraData(this).timestamp) - < std::forward_as_tuple(other.text(1).isEmpty(), extraData(&other).timestamp); - } else if (column == 4) { - return extraData(this).size < extraData(&other).size; - } - - return QTreeWidgetItem::operator<(other); -} - -ProtocolWidget::ProtocolWidget(QWidget *parent) - : QWidget(parent) - , _ui(new Ui::ProtocolWidget) -{ - _ui->setupUi(this); - - connect(ProgressDispatcher::instance(), &ProgressDispatcher::itemCompleted, - this, &ProtocolWidget::slotItemCompleted); - - connect(_ui->_treeWidget, &QTreeWidget::itemActivated, this, &ProtocolWidget::slotOpenFile); - - _ui->_treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); - connect(_ui->_treeWidget, &QTreeWidget::customContextMenuRequested, this, &ProtocolWidget::slotItemContextMenu); - - // Adjust copyToClipboard() when making changes here! - QStringList header; - header << tr("Time"); - header << tr("File"); - header << tr("Folder"); - header << tr("Action"); - header << tr("Size"); - - int timestampColumnExtra = 0; -#ifdef Q_OS_WIN - timestampColumnExtra = 20; // font metrics are broken on Windows, see #4721 -#endif - - _ui->_treeWidget->setHeaderLabels(header); - int timestampColumnWidth = - _ui->_treeWidget->fontMetrics().width(ProtocolItem::timeString(QDateTime::currentDateTime())) - + timestampColumnExtra; - _ui->_treeWidget->setColumnWidth(0, timestampColumnWidth); - _ui->_treeWidget->setColumnWidth(1, 180); - _ui->_treeWidget->setColumnCount(5); - _ui->_treeWidget->setRootIsDecorated(false); - _ui->_treeWidget->setTextElideMode(Qt::ElideMiddle); - _ui->_treeWidget->header()->setObjectName("ActivityListHeader"); -#if defined(Q_OS_MAC) - _ui->_treeWidget->setMinimumWidth(400); -#endif - _ui->_headerLabel->setText(tr("Local sync protocol")); - - QPushButton *copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole); - copyBtn->setToolTip(tr("Copy the activity list to the clipboard.")); - copyBtn->setEnabled(true); - connect(copyBtn, &QAbstractButton::clicked, this, &ProtocolWidget::copyToClipboard); -} - -ProtocolWidget::~ProtocolWidget() -{ - delete _ui; -} - -void ProtocolWidget::showEvent(QShowEvent *ev) -{ - ConfigFile cfg; - cfg.restoreGeometryHeader(_ui->_treeWidget->header()); - - // Sorting by section was newly enabled. But if we restore the header - // from a state where sorting was disabled, both of these flags will be - // false and sorting will be impossible! - _ui->_treeWidget->header()->setSectionsClickable(true); - _ui->_treeWidget->header()->setSortIndicatorShown(true); - - // Switch back to "by time" ordering - _ui->_treeWidget->sortByColumn(0, Qt::DescendingOrder); - - QWidget::showEvent(ev); -} - -void ProtocolWidget::hideEvent(QHideEvent *ev) -{ - ConfigFile cfg; - cfg.saveGeometryHeader(_ui->_treeWidget->header()); - QWidget::hideEvent(ev); -} - -void ProtocolWidget::slotItemContextMenu(const QPoint &pos) -{ - auto item = _ui->_treeWidget->itemAt(pos); - if (!item) - return; - auto globalPos = _ui->_treeWidget->viewport()->mapToGlobal(pos); - ProtocolItem::openContextMenu(globalPos, item, this); -} - -void ProtocolWidget::slotOpenFile(QTreeWidgetItem *item, int) -{ - QString fileName = item->text(1); - if (Folder *folder = ProtocolItem::folder(item)) { - // folder->path() always comes back with trailing path - QString fullPath = folder->path() + fileName; - if (QFile(fullPath).exists()) { - showInFileManager(fullPath); - } - } -} - -void ProtocolWidget::slotItemCompleted(const QString &folder, const SyncFileItemPtr &item) -{ - if (!item->showInProtocolTab()) - return; - QTreeWidgetItem *line = ProtocolItem::create(folder, *item); - if (line) { - // Limit the number of items - int itemCnt = _ui->_treeWidget->topLevelItemCount(); - while (itemCnt > 2000) { - delete _ui->_treeWidget->takeTopLevelItem(itemCnt - 1); - itemCnt--; - } - _ui->_treeWidget->insertTopLevelItem(0, line); - } -} - -void ProtocolWidget::storeSyncActivity(QTextStream &ts) -{ - int topLevelItems = _ui->_treeWidget->topLevelItemCount(); - - for (int i = 0; i < topLevelItems; i++) { - QTreeWidgetItem *child = _ui->_treeWidget->topLevelItem(i); - ts << right - // time stamp - << qSetFieldWidth(20) - << child->data(0, Qt::DisplayRole).toString() - // separator - << qSetFieldWidth(0) << "," - - // file name - << qSetFieldWidth(64) - << child->data(1, Qt::DisplayRole).toString() - // separator - << qSetFieldWidth(0) << "," - - // folder - << qSetFieldWidth(30) - << child->data(2, Qt::DisplayRole).toString() - // separator - << qSetFieldWidth(0) << "," - - // action - << qSetFieldWidth(15) - << child->data(3, Qt::DisplayRole).toString() - // separator - << qSetFieldWidth(0) << "," - - // size - << qSetFieldWidth(10) - << child->data(4, Qt::DisplayRole).toString() - << qSetFieldWidth(0) - << endl; - } -} - -} diff --git a/src/gui/protocolwidget.h b/src/gui/protocolwidget.h deleted file mode 100644 index 33244ad33..000000000 --- a/src/gui/protocolwidget.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) by Klaas Freitag - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef PROTOCOLWIDGET_H -#define PROTOCOLWIDGET_H - -#include -#include -#include - -#include "progressdispatcher.h" -#include "owncloudgui.h" - -#include "ui_protocolwidget.h" - -class QPushButton; - -namespace OCC { -class SyncResult; - -namespace Ui { - class ProtocolWidget; -} -class Application; - -/** - * The items used in the protocol and issue QTreeWidget - * - * Special sorting: It allows items for global entries to be moved to the top if the - * sorting section is the "Time" column. - */ -class ProtocolItem : public QTreeWidgetItem -{ -public: - using QTreeWidgetItem::QTreeWidgetItem; - - // Shared with IssueWidget - static ProtocolItem *create(const QString &folder, const SyncFileItem &item); - static QString timeString(QDateTime dt, QLocale::FormatType format = QLocale::NarrowFormat); - - struct ExtraData - { - ExtraData() - : status(SyncFileItem::NoStatus) - , direction(SyncFileItem::None) - { - } - - QString path; - QString folderName; - QDateTime timestamp; - quint64 size = 0; - SyncFileItem::Status status BITFIELD(4); - SyncFileItem::Direction direction BITFIELD(3); - }; - - static ExtraData extraData(const QTreeWidgetItem *item); - static void setExtraData(QTreeWidgetItem *item, const ExtraData &data); - - static SyncJournalFileRecord syncJournalRecord(QTreeWidgetItem *item); - static Folder *folder(QTreeWidgetItem *item); - - static void openContextMenu(QPoint globalPos, QTreeWidgetItem *item, QWidget *parent); - -private: - bool operator<(const QTreeWidgetItem &other) const override; -}; - -/** - * @brief The ProtocolWidget class - * @ingroup gui - */ -class ProtocolWidget : public QWidget -{ - Q_OBJECT -public: - explicit ProtocolWidget(QWidget *parent = 0); - ~ProtocolWidget(); - QSize sizeHint() const { return ownCloudGui::settingsDialogSize(); } - - void storeSyncActivity(QTextStream &ts); - -public slots: - void slotItemCompleted(const QString &folder, const SyncFileItemPtr &item); - void slotOpenFile(QTreeWidgetItem *item, int); - -protected: - void showEvent(QShowEvent *); - void hideEvent(QHideEvent *); - -private slots: - void slotItemContextMenu(const QPoint &pos); - -signals: - void copyToClipboard(); - -private: - Ui::ProtocolWidget *_ui; -}; -} -#endif // PROTOCOLWIDGET_H diff --git a/src/gui/protocolwidget.ui b/src/gui/protocolwidget.ui deleted file mode 100644 index 7cec20f9d..000000000 --- a/src/gui/protocolwidget.ui +++ /dev/null @@ -1,73 +0,0 @@ - - - OCC::ProtocolWidget - - - - 0 - 0 - 612 - 515 - - - - Form - - - - - - TextLabel - - - Qt::PlainText - - - - - - - true - - - false - - - true - - - true - - - 4 - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - - - - - - - - diff --git a/src/gui/servernotificationhandler.cpp b/src/gui/servernotificationhandler.cpp index 66d4ac51f..60dafe63f 100644 --- a/src/gui/servernotificationhandler.cpp +++ b/src/gui/servernotificationhandler.cpp @@ -80,7 +80,6 @@ void ServerNotificationHandler::slotIconDownloaded(QByteArray iconData){ QPixmap pixmap; pixmap.loadFromData(iconData); iconCache.insert(sender()->property("activityId").toInt(), QIcon(pixmap)); - qDebug() << "Icon cached for activity " << sender()->property("activityId").toInt(); } void ServerNotificationHandler::slotNotificationsReceived(const QJsonDocument &json, int statusCode) diff --git a/src/gui/settingsdialog.cpp b/src/gui/settingsdialog.cpp index 7aa1a3abe..8f1a9707e 100644 --- a/src/gui/settingsdialog.cpp +++ b/src/gui/settingsdialog.cpp @@ -25,7 +25,6 @@ #include "owncloudgui.h" #include "activitywidget.h" #include "accountmanager.h" -#include "protocolwidget.h" #include #include @@ -400,8 +399,6 @@ public: btn->setDefaultAction(this); btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); - // btn->setMinimumWidth(qMax(parent->sizeHint().height() * buttonSizeRatio, - // btn->sizeHint().width())); return btn; } }; @@ -430,10 +427,8 @@ void SettingsDialog::slotRefreshActivityAccountStateSender() void SettingsDialog::slotRefreshActivity(AccountState *accountState) { - if (accountState->isConnected()) { - qDebug() << "!! Fetching activities and notifications for" << accountState->account()->displayName(); + if (accountState->isConnected()) _activitySettings[accountState]->slotRefresh(); - } } } // namespace OCC diff --git a/src/gui/synclogdialog.cpp b/src/gui/synclogdialog.cpp index eb58721d8..85f043f1a 100644 --- a/src/gui/synclogdialog.cpp +++ b/src/gui/synclogdialog.cpp @@ -27,7 +27,7 @@ namespace OCC { -SyncLogDialog::SyncLogDialog(QWidget *parent, ProtocolWidget *protoWidget) +SyncLogDialog::SyncLogDialog(QWidget *parent) : QDialog(parent) , _ui(new Ui::SyncLogDialog) { @@ -35,10 +35,6 @@ SyncLogDialog::SyncLogDialog(QWidget *parent, ProtocolWidget *protoWidget) _ui->setupUi(this); - if (protoWidget) { - _ui->logWidgetLayout->addWidget(protoWidget); - } - QPushButton *closeButton = _ui->buttonBox->button(QDialogButtonBox::Close); if (closeButton) { connect(closeButton, &QAbstractButton::clicked, this, &QWidget::close); diff --git a/src/gui/synclogdialog.h b/src/gui/synclogdialog.h index c530c35ab..1a224728d 100644 --- a/src/gui/synclogdialog.h +++ b/src/gui/synclogdialog.h @@ -16,8 +16,6 @@ #ifndef SyncLogDialog_H #define SyncLogDialog_H -#include "protocolwidget.h" - #include namespace OCC { @@ -37,7 +35,7 @@ class SyncLogDialog : public QDialog Q_OBJECT public: - explicit SyncLogDialog(QWidget *parent = 0, ProtocolWidget *protoWidget = 0); + explicit SyncLogDialog(QWidget *parent = 0); ~SyncLogDialog(); private slots: