2013-10-01 15:52:07 +04:00
|
|
|
/*
|
|
|
|
* 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
|
2016-10-25 12:00:07 +03:00
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
2013-10-01 15:52:07 +04:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2014-07-11 02:31:24 +04:00
|
|
|
#include "owncloudgui.h"
|
2022-08-04 15:41:49 +03:00
|
|
|
|
2014-07-11 02:31:24 +04:00
|
|
|
#include "account.h"
|
2022-08-04 15:41:49 +03:00
|
|
|
#include "accountmanager.h"
|
2014-12-17 16:09:57 +03:00
|
|
|
#include "accountstate.h"
|
2022-08-04 15:41:49 +03:00
|
|
|
#include "application.h"
|
|
|
|
#include "callstatechecker.h"
|
|
|
|
#include "emojimodel.h"
|
|
|
|
#include "fileactivitylistmodel.h"
|
|
|
|
#include "folderman.h"
|
|
|
|
#include "guiutility.h"
|
|
|
|
#include "logbrowser.h"
|
|
|
|
#include "logger.h"
|
2014-07-07 17:49:48 +04:00
|
|
|
#include "openfilemanager.h"
|
2022-08-04 15:41:49 +03:00
|
|
|
#include "owncloudsetupwizard.h"
|
|
|
|
#include "progressdispatcher.h"
|
|
|
|
#include "settingsdialog.h"
|
|
|
|
#include "theme.h"
|
|
|
|
#include "wheelhandler.h"
|
2023-05-02 14:55:17 +03:00
|
|
|
#include "syncconflictsmodel.h"
|
2022-07-25 19:57:18 +03:00
|
|
|
#include "filedetails/filedetails.h"
|
|
|
|
#include "filedetails/shareemodel.h"
|
|
|
|
#include "filedetails/sharemodel.h"
|
|
|
|
#include "filedetails/sortedsharemodel.h"
|
2022-09-14 02:03:56 +03:00
|
|
|
#include "tray/sortedactivitylistmodel.h"
|
2022-08-04 15:41:49 +03:00
|
|
|
#include "tray/syncstatussummary.h"
|
|
|
|
#include "tray/unifiedsearchresultslistmodel.h"
|
|
|
|
|
2017-07-23 21:58:00 +03:00
|
|
|
#ifdef WITH_LIBCLOUDPROVIDERS
|
|
|
|
#include "cloudproviders/cloudprovidermanager.h"
|
|
|
|
#endif
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2020-06-24 14:50:17 +03:00
|
|
|
#include <QQmlApplicationEngine>
|
2013-10-01 15:52:07 +04:00
|
|
|
#include <QDesktopServices>
|
2016-03-30 13:19:09 +03:00
|
|
|
#include <QDir>
|
2013-10-01 15:52:07 +04:00
|
|
|
#include <QMessageBox>
|
2017-07-23 21:58:00 +03:00
|
|
|
#include <QSignalMapper>
|
2017-12-15 11:45:28 +03:00
|
|
|
#ifdef WITH_LIBCLOUDPROVIDERS
|
2017-07-23 21:58:00 +03:00
|
|
|
#include <QtDBus/QDBusConnection>
|
|
|
|
#include <QtDBus/QDBusInterface>
|
2017-12-15 11:45:28 +03:00
|
|
|
#endif
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2014-08-28 19:23:44 +04:00
|
|
|
|
2019-10-27 18:51:07 +03:00
|
|
|
#include <QQmlEngine>
|
|
|
|
#include <QQmlComponent>
|
|
|
|
#include <QQmlApplicationEngine>
|
|
|
|
#include <QQuickItem>
|
|
|
|
#include <QQmlContext>
|
|
|
|
|
2014-11-10 00:34:07 +03:00
|
|
|
namespace OCC {
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2022-05-09 19:07:01 +03:00
|
|
|
Q_LOGGING_CATEGORY(lcOwnCloudGui, "com.nextcloud.owncloudgui")
|
|
|
|
|
2015-05-13 13:54:31 +03:00
|
|
|
const char propertyAccountC[] = "oc_account";
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
ownCloudGui::ownCloudGui(Application *parent)
|
|
|
|
: QObject(parent)
|
2018-11-11 12:56:22 +03:00
|
|
|
, _tray(nullptr)
|
2020-10-22 04:57:29 +03:00
|
|
|
, _settingsDialog(nullptr)
|
2018-11-11 12:56:22 +03:00
|
|
|
, _logBrowser(nullptr)
|
2017-12-15 11:45:28 +03:00
|
|
|
#ifdef WITH_LIBCLOUDPROVIDERS
|
2017-07-23 21:58:00 +03:00
|
|
|
, _bus(QDBusConnection::sessionBus())
|
2017-12-15 11:45:28 +03:00
|
|
|
#endif
|
2013-10-01 15:52:07 +04:00
|
|
|
, _app(parent)
|
|
|
|
{
|
2020-01-11 19:34:56 +03:00
|
|
|
_tray = Systray::instance();
|
2020-06-24 14:50:17 +03:00
|
|
|
_tray->setTrayEngine(new QQmlApplicationEngine(this));
|
2014-08-19 16:09:53 +04:00
|
|
|
// for the beginning, set the offline icon until the account was verified
|
2020-01-05 23:06:42 +03:00
|
|
|
_tray->setIcon(Theme::instance()->folderOfflineIcon(/*systray?*/ true));
|
2013-10-01 15:52:07 +04:00
|
|
|
|
|
|
|
_tray->show();
|
|
|
|
|
2019-12-02 16:10:18 +03:00
|
|
|
connect(_tray.data(), &QSystemTrayIcon::activated,
|
|
|
|
this, &ownCloudGui::slotTrayClicked);
|
2019-10-27 18:51:07 +03:00
|
|
|
|
2020-01-05 23:06:42 +03:00
|
|
|
connect(_tray.data(), &Systray::openHelp,
|
|
|
|
this, &ownCloudGui::slotHelp);
|
|
|
|
|
2020-07-07 00:17:33 +03:00
|
|
|
connect(_tray.data(), &Systray::openAccountWizard,
|
|
|
|
this, &ownCloudGui::slotNewAccountWizard);
|
|
|
|
|
2020-01-04 19:22:56 +03:00
|
|
|
connect(_tray.data(), &Systray::openSettings,
|
|
|
|
this, &ownCloudGui::slotShowSettings);
|
|
|
|
|
|
|
|
connect(_tray.data(), &Systray::shutdown,
|
|
|
|
this, &ownCloudGui::slotShutdown);
|
2020-05-20 01:09:41 +03:00
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
ProgressDispatcher *pd = ProgressDispatcher::instance();
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(pd, &ProgressDispatcher::progressInfo, this,
|
|
|
|
&ownCloudGui::slotUpdateProgress);
|
2013-10-01 15:52:07 +04:00
|
|
|
|
|
|
|
FolderMan *folderMan = FolderMan::instance();
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(folderMan, &FolderMan::folderSyncStateChange,
|
|
|
|
this, &ownCloudGui::slotSyncStateChange);
|
|
|
|
|
|
|
|
connect(Logger::instance(), &Logger::guiLog,
|
|
|
|
this, &ownCloudGui::slotShowTrayMessage);
|
|
|
|
connect(Logger::instance(), &Logger::optionalGuiLog,
|
|
|
|
this, &ownCloudGui::slotShowOptionalTrayMessage);
|
|
|
|
connect(Logger::instance(), &Logger::guiMessage,
|
|
|
|
this, &ownCloudGui::slotShowGuiMessage);
|
2022-08-04 15:41:49 +03:00
|
|
|
|
|
|
|
qmlRegisterType<SyncStatusSummary>("com.nextcloud.desktopclient", 1, 0, "SyncStatusSummary");
|
|
|
|
qmlRegisterType<EmojiModel>("com.nextcloud.desktopclient", 1, 0, "EmojiModel");
|
|
|
|
qmlRegisterType<UserStatusSelectorModel>("com.nextcloud.desktopclient", 1, 0, "UserStatusSelectorModel");
|
|
|
|
qmlRegisterType<ActivityListModel>("com.nextcloud.desktopclient", 1, 0, "ActivityListModel");
|
2022-09-09 18:29:17 +03:00
|
|
|
qmlRegisterType<FileActivityListModel>("com.nextcloud.desktopclient", 1, 0, "FileActivityListModel");
|
2022-09-14 02:03:56 +03:00
|
|
|
qmlRegisterType<SortedActivityListModel>("com.nextcloud.desktopclient", 1, 0, "SortedActivityListModel");
|
2022-08-04 15:41:49 +03:00
|
|
|
qmlRegisterType<WheelHandler>("com.nextcloud.desktopclient", 1, 0, "WheelHandler");
|
|
|
|
qmlRegisterType<CallStateChecker>("com.nextcloud.desktopclient", 1, 0, "CallStateChecker");
|
2022-07-25 19:57:18 +03:00
|
|
|
qmlRegisterType<FileDetails>("com.nextcloud.desktopclient", 1, 0, "FileDetails");
|
|
|
|
qmlRegisterType<ShareModel>("com.nextcloud.desktopclient", 1, 0, "ShareModel");
|
|
|
|
qmlRegisterType<ShareeModel>("com.nextcloud.desktopclient", 1, 0, "ShareeModel");
|
|
|
|
qmlRegisterType<SortedShareModel>("com.nextcloud.desktopclient", 1, 0, "SortedShareModel");
|
2023-05-02 14:55:17 +03:00
|
|
|
qmlRegisterType<SyncConflictsModel>("com.nextcloud.desktopclient", 1, 0, "SyncConflictsModel");
|
2022-08-04 15:41:49 +03:00
|
|
|
|
|
|
|
qmlRegisterUncreatableType<UnifiedSearchResultsListModel>("com.nextcloud.desktopclient", 1, 0, "UnifiedSearchResultsListModel", "UnifiedSearchResultsListModel");
|
|
|
|
qmlRegisterUncreatableType<UserStatus>("com.nextcloud.desktopclient", 1, 0, "UserStatus", "Access to Status enum");
|
2023-02-24 16:06:29 +03:00
|
|
|
qmlRegisterUncreatableType<Sharee>("com.nextcloud.desktopclient", 1, 0, "Sharee", "Access to Type enum");
|
2022-08-04 15:41:49 +03:00
|
|
|
|
|
|
|
qRegisterMetaTypeStreamOperators<Emoji>();
|
2022-09-14 02:03:56 +03:00
|
|
|
|
|
|
|
qRegisterMetaType<ActivityListModel *>("ActivityListModel*");
|
2022-08-04 15:41:49 +03:00
|
|
|
qRegisterMetaType<UnifiedSearchResultsListModel *>("UnifiedSearchResultsListModel*");
|
|
|
|
qRegisterMetaType<UserStatus>("UserStatus");
|
2022-07-25 19:57:18 +03:00
|
|
|
qRegisterMetaType<SharePtr>("SharePtr");
|
|
|
|
qRegisterMetaType<ShareePtr>("ShareePtr");
|
2023-02-24 16:06:29 +03:00
|
|
|
qRegisterMetaType<Sharee>("Sharee");
|
2023-05-03 19:33:19 +03:00
|
|
|
qRegisterMetaType<OCC::ActivityList>("ActivityList");
|
2022-08-04 15:41:49 +03:00
|
|
|
|
|
|
|
qmlRegisterSingletonInstance("com.nextcloud.desktopclient", 1, 0, "UserModel", UserModel::instance());
|
|
|
|
qmlRegisterSingletonInstance("com.nextcloud.desktopclient", 1, 0, "UserAppsModel", UserAppsModel::instance());
|
|
|
|
qmlRegisterSingletonInstance("com.nextcloud.desktopclient", 1, 0, "Theme", Theme::instance());
|
|
|
|
qmlRegisterSingletonInstance("com.nextcloud.desktopclient", 1, 0, "Systray", Systray::instance());
|
2020-01-12 23:19:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::createTray()
|
|
|
|
{
|
2020-01-11 17:05:37 +03:00
|
|
|
_tray->create();
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
2017-07-23 21:58:00 +03:00
|
|
|
#ifdef WITH_LIBCLOUDPROVIDERS
|
|
|
|
void ownCloudGui::setupCloudProviders()
|
|
|
|
{
|
|
|
|
new CloudProviderManager(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ownCloudGui::cloudProviderApiAvailable()
|
|
|
|
{
|
|
|
|
if (!_bus.isConnected()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
QDBusInterface dbus_iface("org.freedesktop.CloudProviderManager", "/org/freedesktop/CloudProviderManager",
|
|
|
|
"org.freedesktop.CloudProvider.Manager1", _bus);
|
|
|
|
|
|
|
|
if (!dbus_iface.isValid()) {
|
|
|
|
qCInfo(lcApplication) << "DBus interface unavailable";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-11-10 00:30:29 +03:00
|
|
|
// This should rather be in application.... or rather in ConfigFile?
|
2015-09-02 12:10:01 +03:00
|
|
|
void ownCloudGui::slotOpenSettingsDialog()
|
2013-10-01 15:52:07 +04:00
|
|
|
{
|
2013-10-30 19:31:47 +04:00
|
|
|
// if account is set up, start the configuration wizard.
|
2015-04-17 18:56:17 +03:00
|
|
|
if (!AccountManager::instance()->accounts().isEmpty()) {
|
2015-11-10 14:33:36 +03:00
|
|
|
if (_settingsDialog.isNull() || QApplication::activeWindow() != _settingsDialog) {
|
2015-09-02 12:10:01 +03:00
|
|
|
slotShowSettings();
|
|
|
|
} else {
|
|
|
|
_settingsDialog->close();
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
} else {
|
2017-03-30 14:46:20 +03:00
|
|
|
qCInfo(lcApplication) << "No configured folders yet, starting setup wizard";
|
2016-11-18 14:17:05 +03:00
|
|
|
slotNewAccountWizard();
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-16 19:59:16 +03:00
|
|
|
void ownCloudGui::slotOpenMainDialog()
|
|
|
|
{
|
2022-06-30 18:42:39 +03:00
|
|
|
_tray->showWindow();
|
2020-06-16 19:59:16 +03:00
|
|
|
}
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
void ownCloudGui::slotTrayClicked(QSystemTrayIcon::ActivationReason reason)
|
|
|
|
{
|
2022-07-25 14:43:54 +03:00
|
|
|
if (reason == QSystemTrayIcon::DoubleClick && UserModel::instance()->currentUser()->hasLocalFolder()) {
|
|
|
|
UserModel::instance()->openCurrentAccountLocalFolder();
|
|
|
|
} else if (reason == QSystemTrayIcon::Trigger) {
|
2017-04-20 09:55:44 +03:00
|
|
|
if (OwncloudSetupWizard::bringWizardToFrontIfVisible()) {
|
|
|
|
// brought wizard to front
|
2022-07-25 19:57:18 +03:00
|
|
|
} else if (_tray->raiseDialogs()) {
|
|
|
|
// Brings dialogs hidden by other apps to front, returns true if any raised
|
2020-01-05 18:25:32 +03:00
|
|
|
} else if (_tray->isOpen()) {
|
|
|
|
_tray->hideWindow();
|
2017-04-20 09:55:44 +03:00
|
|
|
} else {
|
2020-01-18 20:17:43 +03:00
|
|
|
if (AccountManager::instance()->accounts().isEmpty()) {
|
|
|
|
this->slotOpenSettingsDialog();
|
|
|
|
} else {
|
|
|
|
_tray->showWindow();
|
|
|
|
}
|
|
|
|
|
2014-08-12 16:47:43 +04:00
|
|
|
}
|
|
|
|
}
|
2017-04-20 09:55:44 +03:00
|
|
|
// FIXME: Also make sure that any auto updater dialogue https://github.com/owncloud/client/issues/5613
|
|
|
|
// or SSL error dialog also comes to front.
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
2015-04-28 16:13:39 +03:00
|
|
|
void ownCloudGui::slotSyncStateChange(Folder *folder)
|
2013-10-01 15:52:07 +04:00
|
|
|
{
|
2013-10-02 17:28:33 +04:00
|
|
|
slotComputeOverallSyncStatus();
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2015-04-28 16:13:39 +03:00
|
|
|
if (!folder) {
|
2014-08-19 16:08:31 +04:00
|
|
|
return; // Valid, just a general GUI redraw was needed.
|
|
|
|
}
|
|
|
|
|
2015-04-28 16:13:39 +03:00
|
|
|
auto result = folder->syncResult();
|
|
|
|
|
2017-03-30 14:46:20 +03:00
|
|
|
qCInfo(lcApplication) << "Sync state changed for folder " << folder->remoteUrl().toString() << ": " << result.statusString();
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2018-04-10 13:20:12 +03:00
|
|
|
if (result.status() == SyncResult::Success
|
|
|
|
|| result.status() == SyncResult::Problem
|
|
|
|
|| result.status() == SyncResult::SyncAbortRequested
|
|
|
|
|| result.status() == SyncResult::Error) {
|
2013-10-02 17:28:33 +04:00
|
|
|
Logger::instance()->enterNextLogFile();
|
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotFoldersChanged()
|
|
|
|
{
|
2013-10-02 17:28:33 +04:00
|
|
|
slotComputeOverallSyncStatus();
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
2013-10-02 20:16:24 +04:00
|
|
|
void ownCloudGui::slotOpenPath(const QString &path)
|
|
|
|
{
|
2014-07-07 17:49:48 +04:00
|
|
|
showInFileManager(path);
|
2013-10-02 20:16:24 +04:00
|
|
|
}
|
|
|
|
|
2013-11-25 18:33:35 +04:00
|
|
|
void ownCloudGui::slotAccountStateChanged()
|
2013-11-23 03:14:02 +04:00
|
|
|
{
|
2014-04-14 19:51:57 +04:00
|
|
|
slotComputeOverallSyncStatus();
|
2013-11-23 03:14:02 +04:00
|
|
|
}
|
|
|
|
|
2016-03-02 13:59:36 +03:00
|
|
|
void ownCloudGui::slotTrayMessageIfServerUnsupported(Account *account)
|
|
|
|
{
|
|
|
|
if (account->serverVersionUnsupported()) {
|
|
|
|
slotShowTrayMessage(
|
|
|
|
tr("Unsupported Server Version"),
|
2018-06-29 10:43:53 +03:00
|
|
|
tr("The server on account %1 runs an unsupported version %2. "
|
2016-03-02 13:59:36 +03:00
|
|
|
"Using this client with unsupported server versions is untested and "
|
|
|
|
"potentially dangerous. Proceed at your own risk.")
|
|
|
|
.arg(account->displayName(), account->serverVersion()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
void ownCloudGui::slotComputeOverallSyncStatus()
|
2013-10-01 15:52:07 +04:00
|
|
|
{
|
2015-05-13 14:10:14 +03:00
|
|
|
bool allSignedOut = true;
|
2016-03-01 18:07:11 +03:00
|
|
|
bool allPaused = true;
|
2017-10-06 12:54:16 +03:00
|
|
|
bool allDisconnected = true;
|
2015-07-01 13:30:18 +03:00
|
|
|
QVector<AccountStatePtr> problemAccounts;
|
2017-10-06 12:54:16 +03:00
|
|
|
auto setStatusText = [&](const QString &text) {
|
2020-08-19 17:32:57 +03:00
|
|
|
// FIXME: So this doesn't do anything? Needs to be revisited
|
|
|
|
Q_UNUSED(text)
|
2017-10-06 12:54:16 +03:00
|
|
|
// Don't overwrite the status if we're currently syncing
|
2020-11-26 19:19:20 +03:00
|
|
|
if (FolderMan::instance()->isAnySyncRunning())
|
2017-10-06 12:54:16 +03:00
|
|
|
return;
|
2020-01-05 23:06:42 +03:00
|
|
|
//_actionStatus->setText(text);
|
2017-10-06 12:54:16 +03:00
|
|
|
};
|
|
|
|
|
2015-05-13 14:10:14 +03:00
|
|
|
foreach (auto a, AccountManager::instance()->accounts()) {
|
|
|
|
if (!a->isSignedOut()) {
|
|
|
|
allSignedOut = false;
|
2013-11-23 03:14:02 +04:00
|
|
|
}
|
2015-07-01 13:30:18 +03:00
|
|
|
if (!a->isConnected()) {
|
|
|
|
problemAccounts.append(a);
|
2017-10-06 12:54:16 +03:00
|
|
|
} else {
|
|
|
|
allDisconnected = false;
|
2015-07-01 13:30:18 +03:00
|
|
|
}
|
|
|
|
}
|
2016-03-01 18:07:11 +03:00
|
|
|
foreach (Folder *f, FolderMan::instance()->map()) {
|
|
|
|
if (!f->syncPaused()) {
|
|
|
|
allPaused = false;
|
|
|
|
}
|
|
|
|
}
|
2015-07-01 13:30:18 +03:00
|
|
|
|
|
|
|
if (!problemAccounts.empty()) {
|
2020-01-05 23:06:42 +03:00
|
|
|
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
|
2017-10-06 12:54:16 +03:00
|
|
|
if (allDisconnected) {
|
|
|
|
setStatusText(tr("Disconnected"));
|
|
|
|
} else {
|
|
|
|
setStatusText(tr("Disconnected from some accounts"));
|
|
|
|
}
|
2015-08-10 14:09:05 +03:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
// Windows has a 128-char tray tooltip length limit.
|
|
|
|
QStringList accountNames;
|
|
|
|
foreach (AccountStatePtr a, problemAccounts) {
|
|
|
|
accountNames.append(a->account()->displayName());
|
|
|
|
}
|
|
|
|
_tray->setToolTip(tr("Disconnected from %1").arg(accountNames.join(QLatin1String(", "))));
|
|
|
|
#else
|
2015-07-01 13:30:18 +03:00
|
|
|
QStringList messages;
|
|
|
|
messages.append(tr("Disconnected from accounts:"));
|
|
|
|
foreach (AccountStatePtr a, problemAccounts) {
|
|
|
|
QString message = tr("Account %1: %2").arg(a->account()->displayName(), a->stateString(a->state()));
|
|
|
|
if (!a->connectionErrors().empty()) {
|
|
|
|
message += QLatin1String("\n");
|
|
|
|
message += a->connectionErrors().join(QLatin1String("\n"));
|
|
|
|
}
|
|
|
|
messages.append(message);
|
2014-04-14 19:51:57 +04:00
|
|
|
}
|
2015-07-01 13:30:18 +03:00
|
|
|
_tray->setToolTip(messages.join(QLatin1String("\n\n")));
|
2015-08-10 14:09:05 +03:00
|
|
|
#endif
|
2015-07-01 13:30:18 +03:00
|
|
|
return;
|
2013-11-23 03:14:02 +04:00
|
|
|
}
|
2015-05-13 14:10:14 +03:00
|
|
|
|
|
|
|
if (allSignedOut) {
|
2020-01-05 23:06:42 +03:00
|
|
|
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
|
2015-05-13 14:10:14 +03:00
|
|
|
_tray->setToolTip(tr("Please sign in"));
|
2017-10-06 12:54:16 +03:00
|
|
|
setStatusText(tr("Signed out"));
|
2015-05-13 14:10:14 +03:00
|
|
|
return;
|
2016-03-01 18:07:11 +03:00
|
|
|
} else if (allPaused) {
|
2020-01-05 23:06:42 +03:00
|
|
|
_tray->setIcon(Theme::instance()->syncStateIcon(SyncResult::Paused, true));
|
2016-03-01 18:07:11 +03:00
|
|
|
_tray->setToolTip(tr("Account synchronization is disabled"));
|
2017-10-06 12:54:16 +03:00
|
|
|
setStatusText(tr("Synchronization is paused"));
|
2016-03-01 18:07:11 +03:00
|
|
|
return;
|
2015-05-13 14:10:14 +03:00
|
|
|
}
|
|
|
|
|
2015-10-05 07:21:19 +03:00
|
|
|
// display the info of the least successful sync (eg. do not just display the result of the latest sync)
|
2013-10-01 15:52:07 +04:00
|
|
|
QString trayMessage;
|
|
|
|
FolderMan *folderMan = FolderMan::instance();
|
|
|
|
Folder::Map map = folderMan->map();
|
2018-01-23 16:11:20 +03:00
|
|
|
|
|
|
|
SyncResult::Status overallStatus = SyncResult::Undefined;
|
|
|
|
bool hasUnresolvedConflicts = false;
|
|
|
|
FolderMan::trayOverallStatus(map.values(), &overallStatus, &hasUnresolvedConflicts);
|
|
|
|
|
|
|
|
// If the sync succeeded but there are unresolved conflicts,
|
|
|
|
// show the problem icon!
|
|
|
|
auto iconStatus = overallStatus;
|
|
|
|
if (iconStatus == SyncResult::Success && hasUnresolvedConflicts) {
|
|
|
|
iconStatus = SyncResult::Problem;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we don't get a status for whatever reason, that's a Problem
|
|
|
|
if (iconStatus == SyncResult::Undefined) {
|
|
|
|
iconStatus = SyncResult::Problem;
|
|
|
|
}
|
|
|
|
|
2020-01-05 23:06:42 +03:00
|
|
|
QIcon statusIcon = Theme::instance()->syncStateIcon(iconStatus, true);
|
2018-01-23 16:11:20 +03:00
|
|
|
_tray->setIcon(statusIcon);
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2015-07-01 13:30:18 +03:00
|
|
|
// create the tray blob message, check if we have an defined state
|
2018-01-23 16:11:20 +03:00
|
|
|
if (map.count() > 0) {
|
2015-08-10 14:09:05 +03:00
|
|
|
#ifdef Q_OS_WIN
|
2017-10-06 12:54:16 +03:00
|
|
|
// Windows has a 128-char tray tooltip length limit.
|
2018-01-23 16:11:20 +03:00
|
|
|
trayMessage = folderMan->trayTooltipStatusString(overallStatus, hasUnresolvedConflicts, false);
|
2015-08-10 14:09:05 +03:00
|
|
|
#else
|
2017-10-06 12:54:16 +03:00
|
|
|
QStringList allStatusStrings;
|
|
|
|
foreach (Folder *folder, map.values()) {
|
2018-01-23 16:11:20 +03:00
|
|
|
QString folderMessage = FolderMan::trayTooltipStatusString(
|
|
|
|
folder->syncResult().status(),
|
|
|
|
folder->syncResult().hasUnresolvedConflicts(),
|
|
|
|
folder->syncPaused());
|
2017-10-06 12:54:16 +03:00
|
|
|
allStatusStrings += tr("Folder %1: %2").arg(folder->shortGuiLocalPath(), folderMessage);
|
2013-10-15 19:00:53 +04:00
|
|
|
}
|
2017-10-06 12:54:16 +03:00
|
|
|
trayMessage = allStatusStrings.join(QLatin1String("\n"));
|
|
|
|
#endif
|
2013-10-01 15:52:07 +04:00
|
|
|
_tray->setToolTip(trayMessage);
|
2017-10-06 12:54:16 +03:00
|
|
|
|
2018-01-23 16:11:20 +03:00
|
|
|
if (overallStatus == SyncResult::Success || overallStatus == SyncResult::Problem) {
|
|
|
|
if (hasUnresolvedConflicts) {
|
|
|
|
setStatusText(tr("Unresolved conflicts"));
|
|
|
|
} else {
|
|
|
|
setStatusText(tr("Up to date"));
|
|
|
|
}
|
|
|
|
} else if (overallStatus == SyncResult::Paused) {
|
2017-10-06 12:54:16 +03:00
|
|
|
setStatusText(tr("Synchronization is paused"));
|
|
|
|
} else {
|
|
|
|
setStatusText(tr("Error during synchronization"));
|
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
} else {
|
2015-07-01 13:30:18 +03:00
|
|
|
_tray->setToolTip(tr("There are no sync folders configured."));
|
2017-10-06 12:54:16 +03:00
|
|
|
setStatusText(tr("No sync folders configured"));
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-06 12:55:45 +03:00
|
|
|
void ownCloudGui::hideAndShowTray()
|
|
|
|
{
|
|
|
|
_tray->hide();
|
|
|
|
_tray->show();
|
|
|
|
}
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg)
|
|
|
|
{
|
2022-05-09 19:07:01 +03:00
|
|
|
qCDebug(lcOwnCloudGui) << "Going to show notification with title: '" << title << "' and message: '" << msg << "'";
|
|
|
|
if (_tray) {
|
2013-10-01 15:52:07 +04:00
|
|
|
_tray->showMessage(title, msg);
|
2022-05-09 19:07:01 +03:00
|
|
|
} else {
|
2017-03-30 14:46:20 +03:00
|
|
|
qCWarning(lcApplication) << "Tray not ready: " << msg;
|
2022-05-09 19:07:01 +03:00
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
2022-05-10 17:12:15 +03:00
|
|
|
void ownCloudGui::slotShowTrayUpdateMessage(const QString &title, const QString &msg, const QUrl &webUrl)
|
|
|
|
{
|
|
|
|
if(_tray) {
|
|
|
|
_tray->showUpdateMessage(title, msg, webUrl);
|
|
|
|
} else {
|
|
|
|
qCWarning(lcApplication) << "Tray not ready: " << msg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
void ownCloudGui::slotShowOptionalTrayMessage(const QString &title, const QString &msg)
|
|
|
|
{
|
2018-02-15 22:21:08 +03:00
|
|
|
slotShowTrayMessage(title, msg);
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2015-10-05 07:21:19 +03:00
|
|
|
* open the folder with the given Alias
|
2013-10-01 15:52:07 +04:00
|
|
|
*/
|
|
|
|
void ownCloudGui::slotFolderOpenAction(const QString &alias)
|
|
|
|
{
|
|
|
|
Folder *f = FolderMan::instance()->folder(alias);
|
|
|
|
if (f) {
|
2017-03-30 14:46:20 +03:00
|
|
|
qCInfo(lcApplication) << "opening local url " << f->path();
|
2014-06-20 13:26:41 +04:00
|
|
|
QUrl url = QUrl::fromLocalFile(f->path());
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2013-12-03 19:23:49 +04:00
|
|
|
#ifdef Q_OS_WIN
|
2013-10-01 15:52:07 +04:00
|
|
|
// work around a bug in QDesktopServices on Win32, see i-net
|
|
|
|
QString filePath = f->path();
|
|
|
|
|
|
|
|
if (filePath.startsWith(QLatin1String("\\\\")) || filePath.startsWith(QLatin1String("//")))
|
2015-01-14 19:39:14 +03:00
|
|
|
url = QUrl::fromLocalFile(QDir::toNativeSeparators(filePath));
|
2013-10-01 15:52:07 +04:00
|
|
|
else
|
|
|
|
url = QUrl::fromLocalFile(filePath);
|
|
|
|
#endif
|
|
|
|
QDesktopServices::openUrl(url);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-30 15:36:20 +03:00
|
|
|
void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo &progress)
|
2013-10-01 15:52:07 +04:00
|
|
|
{
|
|
|
|
Q_UNUSED(folder);
|
|
|
|
|
2020-08-18 18:41:02 +03:00
|
|
|
// FIXME: Lots of messages computed for nothing in this method, needs revisiting
|
2017-07-11 13:52:40 +03:00
|
|
|
if (progress.status() == ProgressInfo::Discovery) {
|
2020-08-18 18:41:02 +03:00
|
|
|
#if 0
|
2018-02-21 11:39:55 +03:00
|
|
|
if (!progress._currentDiscoveredRemoteFolder.isEmpty()) {
|
2021-07-28 22:35:13 +03:00
|
|
|
_actionStatus->setText(tr("Checking for changes in remote \"%1\"")
|
2020-08-18 18:41:02 +03:00
|
|
|
.arg(progress._currentDiscoveredRemoteFolder));
|
2018-02-21 11:39:55 +03:00
|
|
|
} else if (!progress._currentDiscoveredLocalFolder.isEmpty()) {
|
2021-07-28 22:35:13 +03:00
|
|
|
_actionStatus->setText(tr("Checking for changes in local \"%1\"")
|
2020-08-18 18:41:02 +03:00
|
|
|
.arg(progress._currentDiscoveredLocalFolder));
|
2017-07-11 13:52:40 +03:00
|
|
|
}
|
2020-08-18 18:41:02 +03:00
|
|
|
#endif
|
2017-07-11 13:52:40 +03:00
|
|
|
} else if (progress.status() == ProgressInfo::Done) {
|
2017-10-06 12:54:16 +03:00
|
|
|
QTimer::singleShot(2000, this, &ownCloudGui::slotComputeOverallSyncStatus);
|
2017-07-11 13:52:40 +03:00
|
|
|
}
|
|
|
|
if (progress.status() != ProgressInfo::Propagation) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (progress.totalSize() == 0) {
|
2019-02-13 12:15:33 +03:00
|
|
|
qint64 currentFile = progress.currentFile();
|
|
|
|
qint64 totalFileCount = qMax(progress.totalFiles(), currentFile);
|
2016-08-15 14:36:53 +03:00
|
|
|
QString msg;
|
|
|
|
if (progress.trustEta()) {
|
2019-11-15 01:15:49 +03:00
|
|
|
msg = tr("Syncing %1 of %2 (%3 left)")
|
2016-08-15 14:36:53 +03:00
|
|
|
.arg(currentFile)
|
|
|
|
.arg(totalFileCount)
|
|
|
|
.arg(Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta));
|
|
|
|
} else {
|
|
|
|
msg = tr("Syncing %1 of %2")
|
|
|
|
.arg(currentFile)
|
|
|
|
.arg(totalFileCount);
|
|
|
|
}
|
2020-01-05 23:06:42 +03:00
|
|
|
//_actionStatus->setText(msg);
|
2014-12-11 13:32:05 +03:00
|
|
|
} else {
|
2015-01-30 15:36:20 +03:00
|
|
|
QString totalSizeStr = Utility::octetsToString(progress.totalSize());
|
2016-08-15 14:36:53 +03:00
|
|
|
QString msg;
|
|
|
|
if (progress.trustEta()) {
|
|
|
|
msg = tr("Syncing %1 (%2 left)")
|
|
|
|
.arg(totalSizeStr, Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta));
|
|
|
|
} else {
|
|
|
|
msg = tr("Syncing %1")
|
|
|
|
.arg(totalSizeStr);
|
|
|
|
}
|
2020-01-05 23:06:42 +03:00
|
|
|
//_actionStatus->setText(msg);
|
2014-12-11 13:32:05 +03:00
|
|
|
}
|
2014-05-12 18:36:27 +04:00
|
|
|
|
2020-01-05 23:06:42 +03:00
|
|
|
if (!progress._lastCompletedItem.isEmpty()) {
|
2014-03-14 20:18:26 +04:00
|
|
|
|
2014-03-20 17:43:10 +04:00
|
|
|
QString kindStr = Progress::asResultString(progress._lastCompletedItem);
|
|
|
|
QString timeStr = QTime::currentTime().toString("hh:mm");
|
|
|
|
QString actionText = tr("%1 (%2, %3)").arg(progress._lastCompletedItem._file, kindStr, timeStr);
|
2020-05-18 21:54:23 +03:00
|
|
|
auto *action = new QAction(actionText, this);
|
2014-03-20 17:43:10 +04:00
|
|
|
Folder *f = FolderMan::instance()->folder(folder);
|
|
|
|
if (f) {
|
|
|
|
QString fullPath = f->path() + '/' + progress._lastCompletedItem._file;
|
|
|
|
if (QFile(fullPath).exists()) {
|
2017-09-20 17:49:41 +03:00
|
|
|
connect(action, &QAction::triggered, this, [this, fullPath] { this->slotOpenPath(fullPath); });
|
2014-03-20 17:43:10 +04:00
|
|
|
} else {
|
|
|
|
action->setEnabled(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (_recentItemsActions.length() > 5) {
|
|
|
|
_recentItemsActions.takeFirst()->deleteLater();
|
|
|
|
}
|
|
|
|
_recentItemsActions.append(action);
|
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
2015-07-03 11:59:44 +03:00
|
|
|
void ownCloudGui::slotLogin()
|
|
|
|
{
|
|
|
|
if (auto account = qvariant_cast<AccountStatePtr>(sender()->property(propertyAccountC))) {
|
2017-06-13 14:49:26 +03:00
|
|
|
account->account()->resetRejectedCertificates();
|
2015-12-09 13:06:28 +03:00
|
|
|
account->signIn();
|
2015-07-03 11:59:44 +03:00
|
|
|
} else {
|
2016-03-01 18:07:11 +03:00
|
|
|
auto list = AccountManager::instance()->accounts();
|
2015-07-03 11:59:44 +03:00
|
|
|
foreach (const auto &a, list) {
|
2015-12-09 13:06:28 +03:00
|
|
|
a->signIn();
|
2015-07-03 11:59:44 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotLogout()
|
|
|
|
{
|
|
|
|
auto list = AccountManager::instance()->accounts();
|
|
|
|
if (auto account = qvariant_cast<AccountStatePtr>(sender()->property(propertyAccountC))) {
|
|
|
|
list.clear();
|
|
|
|
list.append(account);
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach (const auto &ai, list) {
|
2015-12-09 13:06:28 +03:00
|
|
|
ai->signOutByUi();
|
2015-07-03 11:59:44 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-18 14:17:05 +03:00
|
|
|
void ownCloudGui::slotNewAccountWizard()
|
|
|
|
{
|
|
|
|
OwncloudSetupWizard::runWizard(qApp, SLOT(slotownCloudWizardDone(int)));
|
|
|
|
}
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
void ownCloudGui::slotShowGuiMessage(const QString &title, const QString &message)
|
|
|
|
{
|
2020-05-18 21:54:23 +03:00
|
|
|
auto *msgBox = new QMessageBox;
|
2017-02-20 15:58:35 +03:00
|
|
|
msgBox->setWindowFlags(msgBox->windowFlags() | Qt::WindowStaysOnTopHint);
|
2013-10-01 15:52:07 +04:00
|
|
|
msgBox->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
msgBox->setText(message);
|
|
|
|
msgBox->setWindowTitle(title);
|
|
|
|
msgBox->setIcon(QMessageBox::Information);
|
|
|
|
msgBox->open();
|
|
|
|
}
|
|
|
|
|
2013-11-26 06:15:03 +04:00
|
|
|
void ownCloudGui::slotShowSettings()
|
2013-10-01 15:52:07 +04:00
|
|
|
{
|
|
|
|
if (_settingsDialog.isNull()) {
|
2019-12-01 04:45:19 +03:00
|
|
|
_settingsDialog = new SettingsDialog(this);
|
2013-10-01 15:52:07 +04:00
|
|
|
_settingsDialog->setAttribute(Qt::WA_DeleteOnClose, true);
|
|
|
|
_settingsDialog->show();
|
|
|
|
}
|
2014-07-07 17:20:37 +04:00
|
|
|
raiseDialog(_settingsDialog.data());
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
2019-12-21 05:04:31 +03:00
|
|
|
void ownCloudGui::slotSettingsDialogActivated()
|
|
|
|
{
|
|
|
|
emit isShowingSettingsDialog();
|
|
|
|
}
|
|
|
|
|
2013-11-29 14:18:59 +04:00
|
|
|
void ownCloudGui::slotShowSyncProtocol()
|
|
|
|
{
|
|
|
|
slotShowSettings();
|
2018-03-26 22:02:03 +03:00
|
|
|
//_settingsDialog->showActivityPage();
|
2013-11-29 14:18:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
void ownCloudGui::slotShutdown()
|
2013-10-01 15:52:07 +04:00
|
|
|
{
|
2015-04-27 18:14:25 +03:00
|
|
|
// explicitly close windows. This is somewhat of a hack to ensure
|
|
|
|
// that saving the geometries happens ASAP during a OS shutdown
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
// those do delete on close
|
|
|
|
if (!_settingsDialog.isNull())
|
|
|
|
_settingsDialog->close();
|
2013-10-02 17:28:33 +04:00
|
|
|
if (!_logBrowser.isNull())
|
|
|
|
_logBrowser->deleteLater();
|
2020-01-04 19:22:56 +03:00
|
|
|
_app->quit();
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
void ownCloudGui::slotToggleLogBrowser()
|
|
|
|
{
|
|
|
|
if (_logBrowser.isNull()) {
|
|
|
|
// init the log browser.
|
|
|
|
_logBrowser = new LogBrowser;
|
|
|
|
// ## TODO: allow new log name maybe?
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_logBrowser->isVisible()) {
|
|
|
|
_logBrowser->hide();
|
|
|
|
} else {
|
2014-07-07 17:20:37 +04:00
|
|
|
raiseDialog(_logBrowser);
|
2013-10-02 17:28:33 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotOpenOwnCloud()
|
|
|
|
{
|
2015-05-13 13:54:31 +03:00
|
|
|
if (auto account = qvariant_cast<AccountPtr>(sender()->property(propertyAccountC))) {
|
2021-02-05 11:06:25 +03:00
|
|
|
Utility::openBrowser(account->url());
|
2013-10-30 19:31:47 +04:00
|
|
|
}
|
2013-10-02 17:28:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotHelp()
|
|
|
|
{
|
|
|
|
QDesktopServices::openUrl(QUrl(Theme::instance()->helpUrl()));
|
|
|
|
}
|
|
|
|
|
2014-07-07 17:20:37 +04:00
|
|
|
void ownCloudGui::raiseDialog(QWidget *raiseWidget)
|
|
|
|
{
|
2020-06-10 04:47:49 +03:00
|
|
|
if (raiseWidget && !raiseWidget->parentWidget()) {
|
2014-07-07 17:20:37 +04:00
|
|
|
// Qt has a bug which causes parent-less dialogs to pop-under.
|
|
|
|
raiseWidget->showNormal();
|
|
|
|
raiseWidget->raise();
|
|
|
|
raiseWidget->activateWindow();
|
2020-06-25 17:25:11 +03:00
|
|
|
#ifdef Q_OS_WIN
|
2020-03-24 14:01:04 +03:00
|
|
|
// Windows disallows raising a Window when you're not the active application.
|
|
|
|
// Use a common hack to attach to the active application
|
|
|
|
const auto activeProcessId = GetWindowThreadProcessId(GetForegroundWindow(), nullptr);
|
|
|
|
if (activeProcessId != qApp->applicationPid()) {
|
|
|
|
const auto threadId = GetCurrentThreadId();
|
|
|
|
// don't step here with a debugger...
|
|
|
|
if (AttachThreadInput(threadId, activeProcessId, true))
|
|
|
|
{
|
|
|
|
const auto hwnd = reinterpret_cast<HWND>(raiseWidget->winId());
|
|
|
|
SetForegroundWindow(hwnd);
|
|
|
|
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
|
|
|
AttachThreadInput(threadId, activeProcessId, false);
|
|
|
|
}
|
|
|
|
}
|
2014-08-12 16:47:43 +04:00
|
|
|
#endif
|
2014-07-07 17:20:37 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
|
2022-07-25 19:57:18 +03:00
|
|
|
void ownCloudGui::slotShowShareDialog(const QString &localPath) const
|
2015-01-13 15:50:41 +03:00
|
|
|
{
|
2022-07-25 19:57:18 +03:00
|
|
|
_tray->createShareDialog(localPath);
|
2015-01-13 15:50:41 +03:00
|
|
|
}
|
|
|
|
|
2022-07-25 19:57:18 +03:00
|
|
|
void ownCloudGui::slotShowFileActivityDialog(const QString &localPath) const
|
2016-01-20 15:17:54 +03:00
|
|
|
{
|
2022-07-25 19:57:18 +03:00
|
|
|
_tray->createFileActivityDialog(localPath);
|
2016-01-20 15:17:54 +03:00
|
|
|
}
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
} // end namespace
|