mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-23 21:46:03 +03:00
Removes Protocol and Issues widget files and references.
- Minor changes: - Improves comments and qCWarning messages - Removes commented out code. - adds TODO's. Signed-off-by: Camila San <hello@camila.codes>
This commit is contained in:
parent
ab3c6da5d7
commit
11484d5588
16 changed files with 42 additions and 1436 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 <climits>
|
||||
|
@ -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<QString>(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<QString>(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<Activity::Type>(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<QString>(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<QString>(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<Activity::Type>(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<QString>(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<NotificationWidget *>(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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -1,540 +0,0 @@
|
|||
/*
|
||||
* 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>
|
||||
#include <QtWidgets>
|
||||
|
||||
#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 <climits>
|
||||
|
||||
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<QString, QString> 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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &IssuesWidget::slotRefreshIssues);
|
||||
connect(_ui->filterAccount, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &IssuesWidget::slotUpdateFolderFilters);
|
||||
connect(_ui->filterFolder, static_cast<void (QComboBox::*)(int)>(&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. <a href=\"%1\">Check the documentation on how to resolve them.</a>")
|
||||
.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<bool(QTreeWidgetItem *)> &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<AccountState *>())
|
||||
_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<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 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<AccountState *>();
|
||||
|
||||
// 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<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);
|
||||
}
|
||||
|
||||
// Find all selectable folders while figuring out if we need a folder
|
||||
// selector in the first place
|
||||
bool anyAccountHasMultipleFolders = false;
|
||||
QSet<AccountState *> 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);
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* 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 <QTimer>
|
||||
|
||||
#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<bool(QTreeWidgetItem *)> &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<QPair<QString, QString>> _pathsWithIssues;
|
||||
|
||||
Ui::IssuesWidget *_ui;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,198 +0,0 @@
|
|||
<?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="accountFolderLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="accountLabel">
|
||||
<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="folderLabel">
|
||||
<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="sortingEnabled">
|
||||
<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_2" stretch="1,0">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="_tooManyIssuesWarning">
|
||||
<property name="text">
|
||||
<string>There were too many issues. Not all will be visible here.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="_conflictHelp">
|
||||
<property name="text">
|
||||
<string>There were conflicts. Check the documentation on how to resolve them.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</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>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,330 +0,0 @@
|
|||
/*
|
||||
* 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>
|
||||
#include <QtWidgets>
|
||||
|
||||
#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 <climits>
|
||||
|
||||
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<ExtraData>();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* 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 PROTOCOLWIDGET_H
|
||||
#define PROTOCOLWIDGET_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDateTime>
|
||||
#include <QLocale>
|
||||
|
||||
#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
|
|
@ -1,73 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OCC::ProtocolWidget</class>
|
||||
<widget class="QWidget" name="OCC::ProtocolWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>612</width>
|
||||
<height>515</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="_headerLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<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="sortingEnabled">
|
||||
<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 row="2" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="_dialogButtonBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -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)
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "owncloudgui.h"
|
||||
#include "activitywidget.h"
|
||||
#include "accountmanager.h"
|
||||
#include "protocolwidget.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QStandardItemModel>
|
||||
|
@ -400,8 +399,6 @@ public:
|
|||
btn->setDefaultAction(this);
|
||||
btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
// btn->setMinimumWidth(qMax<int>(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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
#ifndef SyncLogDialog_H
|
||||
#define SyncLogDialog_H
|
||||
|
||||
#include "protocolwidget.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
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:
|
||||
|
|
Loading…
Reference in a new issue