ignorelisteditor.ui
networksettings.ui
protocolwidget.ui
+ issueswidget.ui
activitywidget.ui
synclogdialog.ui
settingsdialog.ui
owncloudgui.cpp
owncloudsetupwizard.cpp
protocolwidget.cpp
+ issueswidget.cpp
activitydata.cpp
activitylistmodel.cpp
activitywidget.cpp
"background-color: %1; width: 1px;"
"}";
+/**
+ * Adjusts the mouse cursor based on the region it is on over the folder tree view.
+ *
+ * Used to show that one can click the red error list box by changing the cursor
+ * to the pointing hand.
+ */
+class MouseCursorChanger : public QObject
+{
+ Q_OBJECT
+public:
+ MouseCursorChanger(QObject *parent)
+ : QObject(parent)
+ {
+ }
+
+ QTreeView *folderList;
+ FolderStatusModel *model;
+
+protected:
+ bool eventFilter(QObject *watched, QEvent *event) override
+ {
+ if (event->type() == QEvent::HoverMove) {
+ Qt::CursorShape shape = Qt::ArrowCursor;
+ auto pos = folderList->mapFromGlobal(QCursor::pos());
+ auto index = folderList->indexAt(pos);
+ if (model->classify(index) == FolderStatusModel::RootFolder
+ && (FolderStatusDelegate::errorsListRect(folderList->visualRect(index)).contains(pos)
+ || FolderStatusDelegate::optionsButtonRect(folderList->visualRect(index),folderList->layoutDirection()).contains(pos))) {
+ shape = Qt::PointingHandCursor;
+ }
+ folderList->setCursor(shape);
+ }
+ return QObject::eventFilter(watched, event);
+ }
+};
+
AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent)
: QWidget(parent)
, ui(new Ui::AccountSettings)
#endif
new ToolTipUpdater(ui->_folderList);
+ auto mouseCursorChanger = new MouseCursorChanger(this);
+ mouseCursorChanger->folderList = ui->_folderList;
+ mouseCursorChanger->model = _model;
+ ui->_folderList->setMouseTracking(true);
+ ui->_folderList->setAttribute(Qt::WA_Hover, true);
+ ui->_folderList->installEventFilter(mouseCursorChanger);
+
createAccountToolbox();
connect(AccountManager::instance(), SIGNAL(accountAdded(AccountState *)),
SLOT(slotAccountAdded(AccountState *)));
slotCustomContextMenuRequested(pos);
return;
}
+ if (FolderStatusDelegate::errorsListRect(tv->visualRect(indx)).contains(pos)) {
+ emit showIssuesList(_model->data(indx, FolderStatusDelegate::FolderAliasRole).toString());
+ return;
+ }
// Expand root items on single click
if (_accountState && _accountState->state() == AccountState::Connected) {
}
} // namespace OCC
+
+#include "accountsettings.moc"
signals:
void folderChanged();
void openFolderAlias(const QString &);
+ void showIssuesList(const QString &folderAlias);
public slots:
void slotOpenOC();
#include "accountmanager.h"
#include "activityitemdelegate.h"
#include "protocolwidget.h"
+#include "issueswidget.h"
#include "QProgressIndicator.h"
#include "notificationwidget.h"
#include "notificationconfirmjob.h"
_tab = new QTabWidget(this);
hbox->addWidget(_tab);
_activityWidget = new ActivityWidget(this);
- _activityTabId = _tab->insertTab(0, _activityWidget, Theme::instance()->applicationIcon(), tr("Server Activity"));
+ _activityTabId = _tab->addTab(_activityWidget, Theme::instance()->applicationIcon(), tr("Server Activity"));
connect(_activityWidget, SIGNAL(copyToClipboard()), this, SLOT(slotCopyToClipboard()));
connect(_activityWidget, SIGNAL(hideActivityTab(bool)), this, SLOT(setActivityTabHidden(bool)));
connect(_activityWidget, SIGNAL(guiLog(QString, QString)), this, SIGNAL(guiLog(QString, QString)));
connect(_activityWidget, SIGNAL(newNotification()), SLOT(slotShowActivityTab()));
_protocolWidget = new ProtocolWidget(this);
- _tab->insertTab(1, _protocolWidget, Theme::instance()->syncStateIcon(SyncResult::Success), tr("Sync Protocol"));
+ _protocolTabId = _tab->addTab(_protocolWidget, Theme::instance()->syncStateIcon(SyncResult::Success), tr("Sync Protocol"));
connect(_protocolWidget, SIGNAL(copyToClipboard()), this, SLOT(slotCopyToClipboard()));
- connect(_protocolWidget, SIGNAL(issueItemCountUpdated(int)),
- this, SLOT(slotShowIssueItemCount(int)));
- // Add the not-synced list into the tab
- QWidget *w = new QWidget;
- QVBoxLayout *vbox2 = new QVBoxLayout(w);
- vbox2->addWidget(new QLabel(tr("List of ignored or erroneous files"), this));
- vbox2->addWidget(_protocolWidget->issueWidget());
- QDialogButtonBox *dlgButtonBox = new QDialogButtonBox(this);
- vbox2->addWidget(dlgButtonBox);
- QPushButton *_copyBtn = dlgButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
- _copyBtn->setToolTip(tr("Copy the activity list to the clipboard."));
- _copyBtn->setEnabled(true);
- connect(_copyBtn, SIGNAL(clicked()), this, SLOT(slotCopyToClipboard()));
-
- w->setLayout(vbox2);
- _syncIssueTabId = _tab->insertTab(2, w, Theme::instance()->syncStateIcon(SyncResult::Problem), QString());
+ _issuesWidget = new IssuesWidget(this);
+ _syncIssueTabId = _tab->addTab(_issuesWidget, Theme::instance()->syncStateIcon(SyncResult::Problem), QString());
slotShowIssueItemCount(0); // to display the label.
+ connect(_issuesWidget, SIGNAL(issueCountUpdated(int)),
+ this, SLOT(slotShowIssueItemCount(int)));
+ connect(_issuesWidget, SIGNAL(copyToClipboard()),
+ this, SLOT(slotCopyToClipboard()));
// Add a progress indicator to spin if the acitivity list is updated.
_progressIndicator = new QProgressIndicator(this);
if (hidden && _activityTabId > -1) {
_tab->removeTab(_activityTabId);
_activityTabId = -1;
+ _protocolTabId -= 1;
+ _syncIssueTabId -= 1;
}
if (!hidden && _activityTabId == -1) {
_activityTabId = _tab->insertTab(0, _activityWidget, Theme::instance()->applicationIcon(), tr("Server Activity"));
+ _protocolTabId += 1;
+ _syncIssueTabId += 1;
}
}
}
}
+void ActivitySettings::slotShowIssuesTab(const QString &folderAlias)
+{
+ if (_syncIssueTabId == -1)
+ return;
+ _tab->setCurrentIndex(_syncIssueTabId);
+
+ _issuesWidget->showFolderErrors(folderAlias);
+}
+
void ActivitySettings::slotCopyToClipboard()
{
QString text;
int idx = _tab->currentIndex();
QString message;
- if (idx == 0) {
+ if (idx == _activityTabId) {
// the activity widget
_activityWidget->storeActivityList(ts);
message = tr("The server activity list has been copied to the clipboard.");
- } else if (idx == 1) {
+ } else if (idx == _protocolTabId) {
// the protocol widget
_protocolWidget->storeSyncActivity(ts);
message = tr("The sync activity list has been copied to the clipboard.");
- } else if (idx == 2) {
+ } else if (idx == _syncIssueTabId) {
// issues Widget
message = tr("The list of unsynced items has been copied to the clipboard.");
- _protocolWidget->storeSyncIssues(ts);
+ _issuesWidget->storeSyncIssues(ts);
}
QApplication::clipboard()->setText(text);
class Account;
class AccountStatusPtr;
class ProtocolWidget;
+class IssuesWidget;
class JsonApiJob;
class NotificationWidget;
class ActivityListModel;
void setNotificationRefreshInterval(quint64 interval);
+ void slotShowIssuesTab(const QString &folderAlias);
+
private slots:
void slotCopyToClipboard();
void setActivityTabHidden(bool hidden);
QTabWidget *_tab;
int _activityTabId;
+ int _protocolTabId;
int _syncIssueTabId;
ActivityWidget *_activityWidget;
ProtocolWidget *_protocolWidget;
+ IssuesWidget *_issuesWidget;
QProgressIndicator *_progressIndicator;
QTimer _notificationCheckTimer;
QHash<AccountState *, QElapsedTimer> _timeSinceLastCheck;
return QStyle::visualRect(direction, within, r);
}
+QRect FolderStatusDelegate::errorsListRect(QRect within)
+{
+ QFont font = QFont();
+ QFont aliasFont = makeAliasFont(font);
+ QFontMetrics fm(font);
+ QFontMetrics aliasFm(aliasFont);
+ within.setTop(within.top() + FolderStatusDelegate::rootFolderHeightWithoutErrors(fm, aliasFm));
+ return within;
+}
+
} // namespace OCC
* return the position of the option button within the item
*/
static QRect optionsButtonRect(QRect within, Qt::LayoutDirection direction);
+ static QRect errorsListRect(QRect within);
static int rootFolderHeightWithoutErrors(const QFontMetrics &fm, const QFontMetrics &aliasFm);
private:
--- /dev/null
+/*
+ * Copyright (C) by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 <QtGui>
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+#include <QtWidgets>
+#endif
+
+#include "issueswidget.h"
+#include "configfile.h"
+#include "syncresult.h"
+#include "logger.h"
+#include "utility.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 "ui_issueswidget.h"
+
+#include <climits>
+
+namespace OCC {
+
+IssuesWidget::IssuesWidget(QWidget *parent)
+ : QWidget(parent)
+ , _ui(new Ui::IssuesWidget)
+{
+ _ui->setupUi(this);
+
+ connect(ProgressDispatcher::instance(), SIGNAL(progressInfo(QString, ProgressInfo)),
+ this, SLOT(slotProgressInfo(QString, ProgressInfo)));
+ connect(ProgressDispatcher::instance(), SIGNAL(itemCompleted(QString, SyncFileItemPtr)),
+ this, SLOT(slotItemCompleted(QString, SyncFileItemPtr)));
+
+ connect(_ui->_treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)), SLOT(slotOpenFile(QTreeWidgetItem *, int)));
+ connect(_ui->copyIssuesButton, SIGNAL(clicked()), SIGNAL(copyToClipboard()));
+
+ connect(_ui->showIgnores, SIGNAL(toggled(bool)), SLOT(slotRefreshIssues()));
+ connect(_ui->showWarnings, SIGNAL(toggled(bool)), SLOT(slotRefreshIssues()));
+ connect(_ui->filterAccount, SIGNAL(currentIndexChanged(int)), SLOT(slotRefreshIssues()));
+ connect(_ui->filterAccount, SIGNAL(currentIndexChanged(int)), SLOT(slotUpdateFolderFilters()));
+ connect(_ui->filterFolder, SIGNAL(currentIndexChanged(int)), SLOT(slotRefreshIssues()));
+ for (auto account : AccountManager::instance()->accounts()) {
+ slotAccountAdded(account.data());
+ }
+ connect(AccountManager::instance(), SIGNAL(accountAdded(AccountState *)),
+ SLOT(slotAccountAdded(AccountState *)));
+ connect(AccountManager::instance(), SIGNAL(accountRemoved(AccountState *)),
+ SLOT(slotAccountRemoved(AccountState *)));
+
+
+ // 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(ProtocolWidget::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
+}
+
+IssuesWidget::~IssuesWidget()
+{
+ delete _ui;
+}
+
+void IssuesWidget::showEvent(QShowEvent *ev)
+{
+ ConfigFile cfg;
+ cfg.restoreGeometryHeader(_ui->_treeWidget->header());
+ QWidget::showEvent(ev);
+}
+
+void IssuesWidget::hideEvent(QHideEvent *ev)
+{
+ ConfigFile cfg;
+ cfg.saveGeometryHeader(_ui->_treeWidget->header());
+ QWidget::hideEvent(ev);
+}
+
+void IssuesWidget::cleanItems(const QString &folder)
+{
+ // 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);
+ QString itemFolder = item->data(2, Qt::UserRole).toString();
+ if (itemFolder == folder) {
+ delete item;
+ }
+ }
+ // update the tabtext
+ emit(issueCountUpdated(_ui->_treeWidget->topLevelItemCount()));
+}
+
+void IssuesWidget::slotOpenFile(QTreeWidgetItem *item, int)
+{
+ QString folderName = item->data(2, Qt::UserRole).toString();
+ QString fileName = item->text(1);
+
+ Folder *folder = FolderMan::instance()->folder(folderName);
+ if (folder) {
+ // 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.isUpdatingEstimates()) {
+ // The sync is restarting, clean the old items
+ cleanItems(folder);
+ } else if (progress.completedFiles() >= progress.totalFiles()) {
+ //Sync completed
+ }
+}
+
+void IssuesWidget::slotItemCompleted(const QString &folder, const SyncFileItemPtr &item)
+{
+ if (!item->hasErrorStatus())
+ return;
+ QTreeWidgetItem *line = ProtocolWidget::createCompletedTreewidgetItem(folder, *item);
+ if (!line)
+ return;
+
+ _ui->_treeWidget->insertTopLevelItem(0, line);
+ line->setHidden(!shouldBeVisible(line, currentAccountFilter(), currentFolderFilter()));
+ emit issueCountUpdated(_ui->_treeWidget->topLevelItemCount());
+}
+
+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));
+ }
+}
+
+void IssuesWidget::slotAccountAdded(AccountState *account)
+{
+ _ui->filterAccount->addItem(account->account()->displayName(), QVariant::fromValue(account));
+}
+
+void IssuesWidget::slotAccountRemoved(AccountState *account)
+{
+ for (int i = _ui->filterAccount->count() - 1; i >= 0; --i) {
+ if (account == _ui->filterAccount->itemData(i).value<AccountState *>())
+ _ui->filterAccount->removeItem(i);
+ }
+}
+
+AccountState *IssuesWidget::currentAccountFilter() const
+{
+ return _ui->filterAccount->currentData().value<AccountState *>();
+}
+
+QString IssuesWidget::currentFolderFilter() const
+{
+ return _ui->filterFolder->currentData().toString();
+}
+
+bool IssuesWidget::shouldBeVisible(QTreeWidgetItem *item, AccountState *filterAccount,
+ const QString &filterFolderAlias) const
+{
+ bool visible = true;
+ auto status = item->data(0, Qt::UserRole);
+ visible &= (_ui->showIgnores->isChecked() || status != SyncFileItem::FileIgnored);
+ visible &= (_ui->showWarnings->isChecked()
+ || (status != SyncFileItem::SoftError
+ && status != SyncFileItem::Conflict
+ && status != SyncFileItem::Restoration));
+
+ auto folderalias = item->data(2, Qt::UserRole).toString();
+ 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<AccountState *>();
+
+ 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);
+ }
+ for (auto folder : FolderMan::instance()->map().values()) {
+ if (folder->accountState() != account)
+ continue;
+ _ui->filterFolder->addItem(folder->shortGuiLocalPath(), folder->alias());
+ }
+}
+
+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);
+}
+}
--- /dev/null
+/*
+ * Copyright (C) by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 <QDialog>
+#include <QDateTime>
+#include <QLocale>
+
+#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 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);
+
+private:
+ AccountState *currentAccountFilter() const;
+ QString currentFolderFilter() const;
+ bool shouldBeVisible(QTreeWidgetItem *item, AccountState *filterAccount,
+ const QString &filterFolderAlias) const;
+ void cleanItems(const QString &folder);
+
+ Ui::IssuesWidget *_ui;
+};
+}
+
+#endif
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OCC::IssuesWidget</class>
+ <widget class="QWidget" name="OCC::IssuesWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>580</width>
+ <height>578</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="_headerLabel">
+ <property name="text">
+ <string>List of issues</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Account</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="filterAccount">
+ <item>
+ <property name="text">
+ <string><no filter></string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Folder</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="filterFolder">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <item>
+ <property name="text">
+ <string><no filter></string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QFormLayout" name="formLayout_2">
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="showWarnings">
+ <property name="text">
+ <string>Show warnings</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="showIgnores">
+ <property name="text">
+ <string>Show ignored files</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="_treeWidget">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="columnCount">
+ <number>4</number>
+ </property>
+ <column>
+ <property name="text">
+ <string notr="true">1</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string notr="true">2</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string notr="true">3</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string notr="true">4</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="copyIssuesButton">
+ <property name="toolTip">
+ <string>Copy the issues list to the clipboard.</string>
+ </property>
+ <property name="text">
+ <string>Copy</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
ProtocolWidget::ProtocolWidget(QWidget *parent)
: QWidget(parent)
- , IgnoredIndicatorRole(Qt::UserRole + 1)
, _ui(new Ui::ProtocolWidget)
{
_ui->setupUi(this);
- connect(ProgressDispatcher::instance(), SIGNAL(progressInfo(QString, ProgressInfo)),
- this, SLOT(slotProgressInfo(QString, ProgressInfo)));
connect(ProgressDispatcher::instance(), SIGNAL(itemCompleted(QString, SyncFileItemPtr)),
this, SLOT(slotItemCompleted(QString, SyncFileItemPtr)));
copyBtn->setToolTip(tr("Copy the activity list to the clipboard."));
copyBtn->setEnabled(true);
connect(copyBtn, SIGNAL(clicked()), SIGNAL(copyToClipboard()));
-
- // this view is used to display all errors such as real errors, soft errors and ignored files
- // it is instantiated here, but made accessible via the method issueWidget() so that it can
- // be embedded into another gui element.
- _issueItemView = new QTreeWidget(this);
- header.removeLast();
- _issueItemView->setHeaderLabels(header);
- timestampColumnWidth =
- ActivityItemDelegate::rowHeight() // icon
- + _issueItemView->fontMetrics().width(timeString(QDateTime::currentDateTime()))
- + timestampColumnExtra;
- _issueItemView->setColumnWidth(0, timestampColumnWidth);
- _issueItemView->setColumnWidth(1, 180);
- _issueItemView->setColumnCount(4);
- _issueItemView->setRootIsDecorated(false);
- _issueItemView->setTextElideMode(Qt::ElideMiddle);
- _issueItemView->header()->setObjectName("ActivityErrorListHeader");
- connect(_issueItemView, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
- SLOT(slotOpenFile(QTreeWidgetItem *, int)));
}
ProtocolWidget::~ProtocolWidget()
QWidget::hideEvent(ev);
}
-void ProtocolWidget::cleanItems(const QString &folder)
-{
- // The issue list is a state, clear it and let the next sync fill it
- // with ignored files and propagation errors.
- int itemCnt = _issueItemView->topLevelItemCount();
- for (int cnt = itemCnt - 1; cnt >= 0; cnt--) {
- QTreeWidgetItem *item = _issueItemView->topLevelItem(cnt);
- QString itemFolder = item->data(2, Qt::UserRole).toString();
- if (itemFolder == folder) {
- delete item;
- }
- }
- // update the tabtext
- emit(issueItemCountUpdated(_issueItemView->topLevelItemCount()));
-}
-QString ProtocolWidget::timeString(QDateTime dt, QLocale::FormatType format) const
+QString ProtocolWidget::timeString(QDateTime dt, QLocale::FormatType format)
{
const QLocale loc = QLocale::system();
QString dtFormat = loc.dateTimeFormat(format);
}
QTreeWidgetItem *twitem = new QTreeWidgetItem(columns);
- if (item._status == SyncFileItem::FileIgnored) {
- // Tell that we want to remove it on the next sync.
- twitem->setData(0, IgnoredIndicatorRole, true);
- }
-
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);
+ twitem->setData(0, Qt::UserRole, item._status);
twitem->setData(2, Qt::UserRole, folder);
return twitem;
}
-void ProtocolWidget::slotProgressInfo(const QString &folder, const ProgressInfo &progress)
-{
- if (!progress.isUpdatingEstimates()) {
- // The sync is restarting, clean the old items
- cleanItems(folder);
- } else if (progress.completedFiles() >= progress.totalFiles()) {
- //Sync completed
- }
-}
-
void ProtocolWidget::slotItemCompleted(const QString &folder, const SyncFileItemPtr &item)
{
+ if (item->hasErrorStatus())
+ return;
QTreeWidgetItem *line = createCompletedTreewidgetItem(folder, *item);
if (line) {
- if (item->hasErrorStatus()) {
- _issueItemView->insertTopLevelItem(0, line);
- emit issueItemCountUpdated(_issueItemView->topLevelItemCount());
- } else {
- // 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);
+ // 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();
}
}
-void ProtocolWidget::storeSyncIssues(QTextStream &ts)
-{
- int topLevelItems = _issueItemView->topLevelItemCount();
-
- for (int i = 0; i < topLevelItems; i++) {
- QTreeWidgetItem *child = _issueItemView->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()
- << qSetFieldWidth(0)
- << endl;
- }
-}
}
~ProtocolWidget();
QSize sizeHint() const { return ownCloudGui::settingsDialogSize(); }
- QTreeWidget *issueWidget() { return _issueItemView; }
void storeSyncActivity(QTextStream &ts);
- void storeSyncIssues(QTextStream &ts);
+
+ // Shared with IssueWidget
+ static QTreeWidgetItem *createCompletedTreewidgetItem(const QString &folder, const SyncFileItem &item);
+ static QString timeString(QDateTime dt, QLocale::FormatType format = QLocale::NarrowFormat);
public slots:
- void slotProgressInfo(const QString &folder, const ProgressInfo &progress);
void slotItemCompleted(const QString &folder, const SyncFileItemPtr &item);
void slotOpenFile(QTreeWidgetItem *item, int);
signals:
void copyToClipboard();
- void issueItemCountUpdated(int);
private:
- void setSyncResultStatus(const SyncResult &result);
- void cleanItems(const QString &folder);
-
- QTreeWidgetItem *createCompletedTreewidgetItem(const QString &folder, const SyncFileItem &item);
-
- QString timeString(QDateTime dt, QLocale::FormatType format = QLocale::NarrowFormat) const;
-
- const int IgnoredIndicatorRole;
Ui::ProtocolWidget *_ui;
- QTreeWidget *_issueItemView;
};
}
#endif // PROTOCOLWIDGET_H
}
}
+void SettingsDialog::showIssuesList(const QString &folderAlias)
+{
+ if (!_activityAction)
+ return;
+ _activityAction->trigger();
+ _activitySettings->slotShowIssuesTab(folderAlias);
+}
+
void SettingsDialog::accountAdded(AccountState *s)
{
auto height = _toolBar->sizeHint().height();
connect(accountSettings, SIGNAL(folderChanged()), _gui, SLOT(slotFoldersChanged()));
connect(accountSettings, SIGNAL(openFolderAlias(const QString &)),
_gui, SLOT(slotFolderOpenAction(QString)));
+ connect(accountSettings, SIGNAL(showIssuesList(QString)), SLOT(showIssuesList(QString)));
connect(s->account().data(), SIGNAL(accountChangedAvatar()), SLOT(slotAccountAvatarChanged()));
slotRefreshActivity(s);
public slots:
void showFirstPage();
void showActivityPage();
+ void showIssuesList(const QString &folderAlias);
void slotSwitchPage(QAction *action);
void slotRefreshActivity(AccountState *accountState);
void slotAccountAvatarChanged();
setCurrentPanelIndex(preferencePanelCount() - 1 - 2);
}
+void SettingsDialogMac::showIssuesList(const QString &folderAlias)
+{
+ // Count backwards (0-based) from the last panel (multiple accounts can be on the left)
+ setCurrentPanelIndex(preferencePanelCount() - 1 - 2);
+ _activitySettings->slotShowIssuesTab(folderAlias);
+}
+
+
void SettingsDialogMac::accountAdded(AccountState *s)
{
QIcon accountIcon = MacStandardIcon::icon(MacStandardIcon::UserAccounts);
connect(accountSettings, &AccountSettings::folderChanged, _gui, &ownCloudGui::slotFoldersChanged);
connect(accountSettings, &AccountSettings::openFolderAlias, _gui, &ownCloudGui::slotFolderOpenAction);
+ connect(accountSettings, &AccountSettings::showIssuesList, this, &SettingsDialogMac::showIssuesList);
connect(s->account().data(), SIGNAL(accountChangedAvatar()), this, SLOT(slotAccountAvatarChanged()));
public slots:
void showActivityPage();
+ void showIssuesList(const QString &folderAlias);
void slotRefreshActivity(AccountState *accountState);
private slots: