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
|
|
|
|
* the Free Software Foundation; version 2 of the License.
|
|
|
|
*
|
|
|
|
* 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 "application.h"
|
|
|
|
#include "owncloudgui.h"
|
|
|
|
#include "theme.h"
|
|
|
|
#include "folderman.h"
|
2014-11-10 01:25:57 +03:00
|
|
|
#include "configfile.h"
|
2014-07-11 02:31:24 +04:00
|
|
|
#include "utility.h"
|
|
|
|
#include "progressdispatcher.h"
|
|
|
|
#include "owncloudsetupwizard.h"
|
2015-01-13 15:50:41 +03:00
|
|
|
#include "sharedialog.h"
|
2014-02-14 06:02:59 +04:00
|
|
|
#if defined(Q_OS_MAC)
|
2014-09-12 13:25:52 +04:00
|
|
|
# include "settingsdialogmac.h"
|
2014-08-12 16:58:34 +04:00
|
|
|
# include "macwindow.h" // qtmacgoodies
|
2014-02-14 06:02:59 +04:00
|
|
|
#else
|
2014-07-11 02:31:24 +04:00
|
|
|
# include "settingsdialog.h"
|
2014-02-14 06:02:59 +04:00
|
|
|
#endif
|
2014-07-11 02:31:24 +04:00
|
|
|
#include "logger.h"
|
|
|
|
#include "logbrowser.h"
|
|
|
|
#include "account.h"
|
2014-12-17 16:09:57 +03:00
|
|
|
#include "accountstate.h"
|
2014-07-07 17:49:48 +04:00
|
|
|
#include "openfilemanager.h"
|
2015-04-09 17:19:17 +03:00
|
|
|
#include "accountmanager.h"
|
2013-11-23 03:14:02 +04:00
|
|
|
#include "creds/abstractcredentials.h"
|
2013-10-01 15:52:07 +04:00
|
|
|
|
|
|
|
#include <QDesktopServices>
|
|
|
|
#include <QMessageBox>
|
2013-10-02 20:16:24 +04:00
|
|
|
#include <QSignalMapper>
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2014-08-28 19:23:44 +04:00
|
|
|
#if defined(Q_OS_X11)
|
|
|
|
#include <QX11Info>
|
|
|
|
#endif
|
|
|
|
|
2014-11-10 00:34:07 +03:00
|
|
|
namespace OCC {
|
2013-10-01 15:52:07 +04:00
|
|
|
|
|
|
|
ownCloudGui::ownCloudGui(Application *parent) :
|
|
|
|
QObject(parent),
|
2013-10-02 17:28:33 +04:00
|
|
|
_tray(0),
|
2014-03-26 02:33:46 +04:00
|
|
|
#if defined(Q_OS_MAC)
|
|
|
|
_settingsDialog(new SettingsDialogMac(this)),
|
|
|
|
#else
|
2014-03-14 20:39:20 +04:00
|
|
|
_settingsDialog(new SettingsDialog(this)),
|
2014-03-26 02:33:46 +04:00
|
|
|
#endif
|
2013-10-02 17:28:33 +04:00
|
|
|
_logBrowser(0),
|
2013-10-01 15:52:07 +04:00
|
|
|
_recentActionsMenu(0),
|
2013-10-02 20:16:24 +04:00
|
|
|
_folderOpenActionMapper(new QSignalMapper(this)),
|
|
|
|
_recentItemsMapper(new QSignalMapper(this)),
|
2013-10-01 15:52:07 +04:00
|
|
|
_app(parent)
|
|
|
|
{
|
|
|
|
_tray = new Systray();
|
2013-10-31 13:52:19 +04:00
|
|
|
_tray->setParent(this);
|
2014-08-19 16:09:53 +04:00
|
|
|
|
|
|
|
// for the beginning, set the offline icon until the account was verified
|
|
|
|
_tray->setIcon( Theme::instance()->folderOfflineIcon(true));
|
2013-10-01 15:52:07 +04:00
|
|
|
|
|
|
|
connect(_tray.data(), SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
|
|
|
SLOT(slotTrayClicked(QSystemTrayIcon::ActivationReason)));
|
|
|
|
|
|
|
|
setupActions();
|
|
|
|
setupContextMenu();
|
|
|
|
|
|
|
|
_tray->show();
|
|
|
|
|
|
|
|
/* use a signal mapper to map the open requests to the alias names */
|
2013-10-02 20:16:24 +04:00
|
|
|
connect(_folderOpenActionMapper, SIGNAL(mapped(QString)),
|
|
|
|
this, SLOT(slotFolderOpenAction(QString)));
|
|
|
|
|
|
|
|
connect(_recentItemsMapper, SIGNAL(mapped(QString)),
|
|
|
|
this, SLOT(slotOpenPath(QString)));
|
2013-10-01 15:52:07 +04:00
|
|
|
|
|
|
|
ProgressDispatcher *pd = ProgressDispatcher::instance();
|
2015-01-30 15:36:20 +03:00
|
|
|
connect( pd, SIGNAL(progressInfo(QString,ProgressInfo)), this,
|
|
|
|
SLOT(slotUpdateProgress(QString,ProgressInfo)) );
|
2013-10-01 15:52:07 +04:00
|
|
|
|
|
|
|
FolderMan *folderMan = FolderMan::instance();
|
|
|
|
connect( folderMan, SIGNAL(folderSyncStateChange(QString)),
|
|
|
|
this,SLOT(slotSyncStateChange(QString)));
|
|
|
|
|
2013-10-02 17:55:15 +04:00
|
|
|
connect( Logger::instance(), SIGNAL(guiLog(QString,QString)),
|
|
|
|
SLOT(slotShowTrayMessage(QString,QString)));
|
|
|
|
connect( Logger::instance(), SIGNAL(optionalGuiLog(QString,QString)),
|
|
|
|
SLOT(slotShowOptionalTrayMessage(QString,QString)));
|
|
|
|
connect( Logger::instance(), SIGNAL(guiMessage(QString,QString)),
|
|
|
|
SLOT(slotShowGuiMessage(QString,QString)));
|
2014-08-01 16:28:34 +04:00
|
|
|
|
|
|
|
setupOverlayIcons();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use this to do platform specific code to make overlay icons appear
|
|
|
|
// in the gui
|
|
|
|
// MacOSX: perform a AppleScript code peace to load the Finder Plugin.
|
|
|
|
|
|
|
|
|
|
|
|
void ownCloudGui::setupOverlayIcons()
|
|
|
|
{
|
2014-10-23 14:19:19 +04:00
|
|
|
#ifdef Q_OS_MAC
|
|
|
|
const QLatin1String finderExtension("/Library/ScriptingAdditions/SyncStateFinder.osax");
|
|
|
|
if(QFile::exists(finderExtension) ) {
|
2014-08-01 16:28:34 +04:00
|
|
|
QString aScript = QString::fromUtf8("tell application \"Finder\"\n"
|
|
|
|
" try\n"
|
2014-08-28 17:44:35 +04:00
|
|
|
" «event OWNCload»\n"
|
2014-08-01 16:28:34 +04:00
|
|
|
" end try\n"
|
|
|
|
"end tell\n");
|
|
|
|
|
|
|
|
QString osascript = "/usr/bin/osascript";
|
|
|
|
QStringList processArguments;
|
|
|
|
// processArguments << "-l" << "AppleScript";
|
|
|
|
|
|
|
|
QProcess p;
|
|
|
|
p.start(osascript, processArguments);
|
|
|
|
p.write(aScript.toUtf8());
|
|
|
|
p.closeWriteChannel();
|
|
|
|
p.waitForReadyRead(-1);
|
|
|
|
QByteArray result = p.readAll();
|
|
|
|
QString resultAsString(result); // if appropriate
|
|
|
|
qDebug() << "Laod Finder Overlay-Plugin: " << resultAsString << ": " << p.exitCode()
|
|
|
|
<< (p.exitCode() != 0 ? p.errorString() : QString::null);
|
2014-10-23 14:19:19 +04:00
|
|
|
} else {
|
|
|
|
qDebug() << finderExtension << "does not exist! Finder Overlay Plugin loading failed";
|
2014-08-01 16:28:34 +04:00
|
|
|
}
|
2014-10-23 14:19:19 +04:00
|
|
|
#endif
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
2014-11-10 00:30:29 +03:00
|
|
|
// This should rather be in application.... or rather in ConfigFile?
|
2013-11-29 19:12:58 +04:00
|
|
|
void ownCloudGui::slotOpenSettingsDialog( bool openSettings )
|
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() ) {
|
2013-10-01 15:52:07 +04:00
|
|
|
if( openSettings ) {
|
2014-03-14 20:39:20 +04:00
|
|
|
if (_settingsDialog.isNull() || !_settingsDialog->isVisible()) {
|
2013-11-26 06:15:03 +04:00
|
|
|
slotShowSettings();
|
|
|
|
} else {
|
|
|
|
_settingsDialog->close();
|
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
qDebug() << "No configured folders yet, starting setup wizard";
|
2013-11-08 17:02:13 +04:00
|
|
|
OwncloudSetupWizard::runWizard(qApp, SLOT(slotownCloudWizardDone(int)));
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
|
|
|
|
{
|
|
|
|
// A click on the tray icon should only open the status window on Win and
|
|
|
|
// Linux, not on Mac. They want a menu entry.
|
|
|
|
#if !defined Q_OS_MAC
|
|
|
|
if( reason == QSystemTrayIcon::Trigger ) {
|
2013-11-29 19:12:58 +04:00
|
|
|
slotOpenSettingsDialog(true); // start settings if config is existing.
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
2014-08-12 16:47:43 +04:00
|
|
|
#else
|
|
|
|
// On Mac, if the settings dialog is already visible but hidden
|
|
|
|
// by other applications, this will bring it to the front.
|
|
|
|
if( reason == QSystemTrayIcon::Trigger ) {
|
|
|
|
if (!_settingsDialog.isNull() && _settingsDialog->isVisible()) {
|
|
|
|
slotShowSettings();
|
|
|
|
}
|
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotSyncStateChange( const QString& alias )
|
|
|
|
{
|
|
|
|
FolderMan *folderMan = FolderMan::instance();
|
|
|
|
const SyncResult& result = folderMan->syncResult( alias );
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
slotComputeOverallSyncStatus();
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2014-08-19 16:08:31 +04:00
|
|
|
if( alias.isEmpty() ) {
|
|
|
|
return; // Valid, just a general GUI redraw was needed.
|
|
|
|
}
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
qDebug() << "Sync state changed for folder " << alias << ": " << result.statusString();
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
if (result.status() == SyncResult::Success || result.status() == SyncResult::Error) {
|
|
|
|
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
|
|
|
setupContextMenu();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
|
|
|
setupContextMenu();
|
2014-04-14 19:51:57 +04:00
|
|
|
slotComputeOverallSyncStatus();
|
2013-11-23 03:14:02 +04:00
|
|
|
}
|
|
|
|
|
2014-12-03 15:10:49 +03:00
|
|
|
void ownCloudGui::setConnectionErrors( bool /*connected*/, const QStringList& fails )
|
2013-10-01 15:52:07 +04:00
|
|
|
{
|
2013-10-01 20:25:30 +04:00
|
|
|
_startupFails = fails; // store that for the settings dialog once it appears.
|
2014-08-19 16:08:31 +04:00
|
|
|
|
2014-08-19 16:10:57 +04:00
|
|
|
slotComputeOverallSyncStatus();
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
void ownCloudGui::slotComputeOverallSyncStatus()
|
2013-10-01 15:52:07 +04:00
|
|
|
{
|
2015-04-23 15:13:13 +03:00
|
|
|
#warning FIXME: overall status needs to look at all accounts
|
2015-04-17 18:56:17 +03:00
|
|
|
if (AccountState *a = AccountManager::instance()->accounts().value(0).data()) {
|
2014-12-17 16:09:57 +03:00
|
|
|
if (a->isSignedOut()) {
|
2014-08-15 17:01:01 +04:00
|
|
|
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
|
2013-11-23 03:14:02 +04:00
|
|
|
_tray->setToolTip(tr("Please sign in"));
|
|
|
|
return;
|
|
|
|
}
|
2015-02-25 11:49:39 +03:00
|
|
|
if (!a->isConnectedOrMaintenance()) {
|
2014-08-15 17:01:01 +04:00
|
|
|
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
|
2014-04-14 19:51:57 +04:00
|
|
|
_tray->setToolTip(tr("Disconnected from server"));
|
|
|
|
return;
|
|
|
|
}
|
2013-11-23 03:14:02 +04:00
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
// display the info of the least successful sync (eg. not just display the result of the latest sync
|
|
|
|
QString trayMessage;
|
|
|
|
FolderMan *folderMan = FolderMan::instance();
|
|
|
|
Folder::Map map = folderMan->map();
|
|
|
|
SyncResult overallResult = FolderMan::accountStatus(map.values());
|
|
|
|
|
2013-10-01 20:25:30 +04:00
|
|
|
if( !_startupFails.isEmpty() ) {
|
|
|
|
trayMessage = _startupFails.join(QLatin1String("\n"));
|
2013-10-15 19:00:53 +04:00
|
|
|
QIcon statusIcon;
|
|
|
|
if (_app->_startupNetworkError) {
|
|
|
|
statusIcon = Theme::instance()->syncStateIcon( SyncResult::NotYetStarted, true );
|
|
|
|
} else {
|
|
|
|
statusIcon = Theme::instance()->syncStateIcon( SyncResult::Error, true );
|
|
|
|
}
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
_tray->setIcon( statusIcon );
|
|
|
|
_tray->setToolTip(trayMessage);
|
|
|
|
} else {
|
|
|
|
// create the tray blob message, check if we have an defined state
|
|
|
|
if( overallResult.status() != SyncResult::Undefined ) {
|
|
|
|
QStringList allStatusStrings;
|
2014-12-03 19:11:42 +03:00
|
|
|
if( map.count() > 0 ) {
|
|
|
|
foreach(Folder* folder, map.values()) {
|
|
|
|
qDebug() << "Folder in overallStatus Message: " << folder << " with name " << folder->alias();
|
|
|
|
QString folderMessage = folderMan->statusToString(folder->syncResult().status(), folder->syncPaused());
|
|
|
|
allStatusStrings += tr("Folder %1: %2").arg(folder->alias(), folderMessage);
|
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
|
|
|
|
trayMessage = allStatusStrings.join(QLatin1String("\n"));
|
2014-12-03 19:11:42 +03:00
|
|
|
} else {
|
2013-10-01 15:52:07 +04:00
|
|
|
trayMessage = tr("No sync folders configured.");
|
2014-12-03 19:11:42 +03:00
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
|
|
|
|
QIcon statusIcon = Theme::instance()->syncStateIcon( overallResult.status(), true);
|
|
|
|
_tray->setIcon( statusIcon );
|
|
|
|
_tray->setToolTip(trayMessage);
|
2014-08-19 19:46:47 +04:00
|
|
|
} else {
|
|
|
|
// undefined because there are no folders.
|
2014-12-19 17:08:49 +03:00
|
|
|
QIcon icon = Theme::instance()->syncStateIcon(SyncResult::Problem, true);
|
2014-08-19 19:46:47 +04:00
|
|
|
_tray->setIcon( icon );
|
|
|
|
_tray->setToolTip(tr("There are no sync folders configured."));
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::setupContextMenu()
|
|
|
|
{
|
|
|
|
FolderMan *folderMan = FolderMan::instance();
|
|
|
|
|
2015-04-17 18:56:17 +03:00
|
|
|
#warning FIXME
|
|
|
|
AccountState *a = AccountManager::instance()->accounts().value(0).data();
|
2013-11-23 03:14:02 +04:00
|
|
|
|
|
|
|
bool isConfigured = (a != 0);
|
2013-10-01 15:52:07 +04:00
|
|
|
_actionOpenoC->setEnabled(isConfigured);
|
2013-11-25 18:33:35 +04:00
|
|
|
bool isConnected = false;
|
2013-11-23 03:14:02 +04:00
|
|
|
if (isConfigured) {
|
2014-12-17 16:09:57 +03:00
|
|
|
isConnected = a->isConnected();
|
2013-11-23 03:14:02 +04:00
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2013-11-23 03:14:02 +04:00
|
|
|
if ( _contextMenu ) {
|
2013-10-01 15:52:07 +04:00
|
|
|
_contextMenu->clear();
|
|
|
|
_recentActionsMenu->clear();
|
|
|
|
_recentActionsMenu->addAction(tr("None."));
|
|
|
|
_recentActionsMenu->addAction(_actionRecent);
|
|
|
|
} else {
|
2014-10-15 20:11:18 +04:00
|
|
|
_contextMenu.reset(new QMenu());
|
|
|
|
_recentActionsMenu = new QMenu(tr("Recent Changes"), _contextMenu.data());
|
2013-10-01 15:52:07 +04:00
|
|
|
// this must be called only once after creating the context menu, or
|
|
|
|
// it will trigger a bug in Ubuntu's SNI bridge patch (11.10, 12.04).
|
2014-10-15 20:11:18 +04:00
|
|
|
_tray->setContextMenu(_contextMenu.data());
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
_contextMenu->setTitle(Theme::instance()->appNameGUI() );
|
|
|
|
_contextMenu->addAction(_actionOpenoC);
|
|
|
|
|
|
|
|
int folderCnt = folderMan->map().size();
|
|
|
|
// add open actions for all sync folders to the tray menu
|
|
|
|
if( Theme::instance()->singleSyncFolder() ) {
|
|
|
|
// there should be exactly one folder. No sync-folder add action will be shown.
|
|
|
|
QStringList li = folderMan->map().keys();
|
|
|
|
if( li.size() == 1 ) {
|
|
|
|
Folder *folder = folderMan->map().value(li.first());
|
|
|
|
if( folder ) {
|
|
|
|
// if there is singleFolder mode, a generic open action is displayed.
|
|
|
|
QAction *action = new QAction( tr("Open %1 folder").arg(Theme::instance()->appNameGUI()), this);
|
|
|
|
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
|
|
|
|
_folderOpenActionMapper->setMapping( action, folder->alias() );
|
|
|
|
|
|
|
|
_contextMenu->addAction(action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// show a grouping with more than one folder.
|
|
|
|
if ( folderCnt > 1) {
|
|
|
|
_contextMenu->addAction(tr("Managed Folders:"))->setDisabled(true);
|
|
|
|
}
|
2014-12-19 15:59:50 +03:00
|
|
|
|
|
|
|
// Put everything first in a QMap to properly sort
|
|
|
|
QMap<QString, Folder*> folders;
|
|
|
|
for( auto i = folderMan->map().constBegin(); i != folderMan->map().constEnd(); i++) {
|
|
|
|
folders.insert(i.key(), i.value());
|
|
|
|
}
|
|
|
|
foreach (auto folder, folders) {
|
2013-10-01 15:52:07 +04:00
|
|
|
QAction *action = new QAction( tr("Open folder '%1'").arg(folder->alias()), this );
|
|
|
|
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
|
|
|
|
_folderOpenActionMapper->setMapping( action, folder->alias() );
|
|
|
|
|
|
|
|
_contextMenu->addAction(action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_contextMenu->addSeparator();
|
2013-11-23 03:14:02 +04:00
|
|
|
|
2013-11-25 18:33:35 +04:00
|
|
|
if (isConfigured && isConnected) {
|
2013-11-23 03:14:02 +04:00
|
|
|
_contextMenu->addAction(_actionQuota);
|
|
|
|
_contextMenu->addSeparator();
|
|
|
|
_contextMenu->addAction(_actionStatus);
|
|
|
|
_contextMenu->addMenu(_recentActionsMenu);
|
|
|
|
_contextMenu->addSeparator();
|
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
_contextMenu->addAction(_actionSettings);
|
|
|
|
if (!Theme::instance()->helpUrl().isEmpty()) {
|
|
|
|
_contextMenu->addAction(_actionHelp);
|
|
|
|
}
|
2014-08-26 17:46:24 +04:00
|
|
|
|
|
|
|
if(_actionCrash) {
|
|
|
|
_contextMenu->addAction(_actionCrash);
|
|
|
|
}
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
_contextMenu->addSeparator();
|
2013-11-25 18:33:35 +04:00
|
|
|
if (isConfigured && isConnected) {
|
2013-11-23 03:14:02 +04:00
|
|
|
_contextMenu->addAction(_actionLogout);
|
|
|
|
} else {
|
|
|
|
_contextMenu->addAction(_actionLogin);
|
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
_contextMenu->addAction(_actionQuit);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg)
|
|
|
|
{
|
|
|
|
if( _tray )
|
|
|
|
_tray->showMessage(title, msg);
|
|
|
|
else
|
|
|
|
qDebug() << "Tray not ready: " << msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotShowOptionalTrayMessage(const QString &title, const QString &msg)
|
|
|
|
{
|
2014-11-10 00:30:29 +03:00
|
|
|
ConfigFile cfg;
|
2013-11-26 15:22:28 +04:00
|
|
|
if (cfg.optionalDesktopNotifications()) {
|
2013-10-01 15:52:07 +04:00
|
|
|
slotShowTrayMessage(title, msg);
|
2013-11-26 15:22:28 +04:00
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* open the folder with the given Alais
|
|
|
|
*/
|
|
|
|
void ownCloudGui::slotFolderOpenAction( const QString& alias )
|
|
|
|
{
|
|
|
|
Folder *f = FolderMan::instance()->folder(alias);
|
|
|
|
if( f ) {
|
2014-06-20 13:20:37 +04:00
|
|
|
qDebug() << "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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::setupActions()
|
|
|
|
{
|
|
|
|
_actionOpenoC = new QAction(tr("Open %1 in browser").arg(Theme::instance()->appNameGUI()), this);
|
|
|
|
QObject::connect(_actionOpenoC, SIGNAL(triggered(bool)), SLOT(slotOpenOwnCloud()));
|
|
|
|
_actionQuota = new QAction(tr("Calculating quota..."), this);
|
|
|
|
_actionQuota->setEnabled( false );
|
|
|
|
_actionStatus = new QAction(tr("Unknown status"), this);
|
|
|
|
_actionStatus->setEnabled( false );
|
|
|
|
_actionSettings = new QAction(tr("Settings..."), this);
|
|
|
|
_actionRecent = new QAction(tr("Details..."), this);
|
|
|
|
_actionRecent->setEnabled( true );
|
|
|
|
|
2013-10-08 16:12:05 +04:00
|
|
|
QObject::connect(_actionRecent, SIGNAL(triggered(bool)), SLOT(slotShowSyncProtocol()));
|
2013-11-26 06:15:03 +04:00
|
|
|
QObject::connect(_actionSettings, SIGNAL(triggered(bool)), SLOT(slotShowSettings()));
|
2013-10-01 15:52:07 +04:00
|
|
|
_actionHelp = new QAction(tr("Help"), this);
|
|
|
|
QObject::connect(_actionHelp, SIGNAL(triggered(bool)), SLOT(slotHelp()));
|
|
|
|
_actionQuit = new QAction(tr("Quit %1").arg(Theme::instance()->appNameGUI()), this);
|
|
|
|
QObject::connect(_actionQuit, SIGNAL(triggered(bool)), _app, SLOT(quit()));
|
|
|
|
|
2013-11-23 03:14:02 +04:00
|
|
|
_actionLogin = new QAction(tr("Sign in..."), this);
|
|
|
|
connect(_actionLogin, SIGNAL(triggered()), _app, SLOT(slotLogin()));
|
|
|
|
_actionLogout = new QAction(tr("Sign out"), this);
|
|
|
|
connect(_actionLogout, SIGNAL(triggered()), _app, SLOT(slotLogout()));
|
|
|
|
|
2014-08-26 17:46:24 +04:00
|
|
|
if(_app->debugMode()) {
|
2015-02-17 16:02:42 +03:00
|
|
|
_actionCrash = new QAction(tr("Crash now", "Only shows in debug mode to allow testing the crash handler"), this);
|
2014-08-26 17:46:24 +04:00
|
|
|
connect(_actionCrash, SIGNAL(triggered()), _app, SLOT(slotCrash()));
|
|
|
|
} else {
|
|
|
|
_actionCrash = 0;
|
|
|
|
}
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotRefreshQuotaDisplay( qint64 total, qint64 used )
|
|
|
|
{
|
|
|
|
if (total == 0) {
|
|
|
|
_actionQuota->setText(tr("Quota n/a"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
double percent = used/(double)total*100;
|
|
|
|
QString percentFormatted = Utility::compactFormatDouble(percent, 1);
|
|
|
|
QString totalFormatted = Utility::octetsToString(total);
|
|
|
|
_actionQuota->setText(tr("%1% of %2 in use").arg(percentFormatted).arg(totalFormatted));
|
|
|
|
}
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
void ownCloudGui::slotRebuildRecentMenus()
|
2013-10-01 15:52:07 +04:00
|
|
|
{
|
|
|
|
_recentActionsMenu->clear();
|
2014-03-20 17:43:10 +04:00
|
|
|
if (!_recentItemsActions.isEmpty()) {
|
|
|
|
foreach(QAction *a, _recentItemsActions) {
|
|
|
|
_recentActionsMenu->addAction(a);
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
2014-03-20 17:43:10 +04:00
|
|
|
_recentActionsMenu->addSeparator();
|
|
|
|
} else {
|
|
|
|
_recentActionsMenu->addAction(tr("No items synced recently"))->setEnabled(false);
|
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
// add a more... entry.
|
|
|
|
_recentActionsMenu->addAction(_actionRecent);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
2014-12-11 13:32:05 +03:00
|
|
|
if (!progress._currentDiscoveredFolder.isEmpty()) {
|
|
|
|
_actionStatus->setText( tr("Discovering '%1'")
|
|
|
|
.arg( progress._currentDiscoveredFolder ));
|
2015-01-30 15:36:20 +03:00
|
|
|
} else if (progress.totalSize() == 0 ) {
|
|
|
|
quint64 currentFile = progress.currentFile();
|
|
|
|
quint64 totalFileCount = qMax(progress.totalFiles(), currentFile);
|
2014-12-11 13:32:05 +03:00
|
|
|
_actionStatus->setText( tr("Syncing %1 of %2 (%3 left)")
|
|
|
|
.arg( currentFile ).arg( totalFileCount )
|
2015-01-30 15:36:20 +03:00
|
|
|
.arg( Utility::timeToDescriptiveString(progress.totalProgress().estimatedEta, 2, " ",true) ) );
|
2014-12-11 13:32:05 +03:00
|
|
|
} else {
|
2015-01-30 15:36:20 +03:00
|
|
|
QString totalSizeStr = Utility::octetsToString( progress.totalSize() );
|
2014-12-11 13:32:05 +03:00
|
|
|
_actionStatus->setText( tr("Syncing %1 (%2 left)")
|
|
|
|
.arg( totalSizeStr )
|
2015-01-30 15:36:20 +03:00
|
|
|
.arg( Utility::timeToDescriptiveString(progress.totalProgress().estimatedEta, 2, " ",true) ) );
|
2014-12-11 13:32:05 +03:00
|
|
|
}
|
2014-05-12 18:36:27 +04:00
|
|
|
|
|
|
|
|
2014-04-29 03:43:35 +04:00
|
|
|
|
|
|
|
|
2014-03-20 17:43:10 +04:00
|
|
|
_actionRecent->setIcon( QIcon() ); // Fixme: Set a "in-progress"-item eventually.
|
2014-03-14 16:03:16 +04:00
|
|
|
|
2015-01-08 13:42:14 +03:00
|
|
|
if (!progress._lastCompletedItem.isEmpty() && !Progress::isIgnoredKind(progress._lastCompletedItem._status)) {
|
2014-03-14 20:18:26 +04:00
|
|
|
|
|
|
|
if (Progress::isWarningKind(progress._lastCompletedItem._status)) {
|
|
|
|
// display a warn icon if warnings happend.
|
2015-02-12 21:44:30 +03:00
|
|
|
QIcon warnIcon(":/client/resources/warning");
|
2014-03-14 20:18:26 +04:00
|
|
|
_actionRecent->setIcon(warnIcon);
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
QAction *action = new QAction(actionText, this);
|
|
|
|
Folder *f = FolderMan::instance()->folder(folder);
|
|
|
|
if (f) {
|
|
|
|
QString fullPath = f->path() + '/' + progress._lastCompletedItem._file;
|
|
|
|
if (QFile(fullPath).exists()) {
|
|
|
|
_recentItemsMapper->setMapping(action, fullPath);
|
|
|
|
connect(action, SIGNAL(triggered()), _recentItemsMapper, SLOT(map()));
|
|
|
|
} else {
|
|
|
|
action->setEnabled(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (_recentItemsActions.length() > 5) {
|
|
|
|
_recentItemsActions.takeFirst()->deleteLater();
|
|
|
|
}
|
|
|
|
_recentItemsActions.append(action);
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
slotRebuildRecentMenus();
|
2014-03-20 17:43:10 +04:00
|
|
|
}
|
2013-10-01 15:52:07 +04:00
|
|
|
|
2015-01-30 15:36:20 +03:00
|
|
|
if (progress.hasStarted()
|
|
|
|
&& progress.completedFiles() >= progress.totalFiles()
|
2014-08-15 17:00:10 +04:00
|
|
|
&& progress._currentDiscoveredFolder.isEmpty()) {
|
2014-03-20 17:43:10 +04:00
|
|
|
QTimer::singleShot(2000, this, SLOT(slotDisplayIdle()));
|
2013-10-01 15:52:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotDisplayIdle()
|
|
|
|
{
|
|
|
|
_actionStatus->setText(tr("Up to date"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void ownCloudGui::slotShowGuiMessage(const QString &title, const QString &message)
|
|
|
|
{
|
|
|
|
QMessageBox *msgBox = new QMessageBox;
|
|
|
|
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
|
|
|
{
|
2014-08-12 16:47:43 +04:00
|
|
|
qDebug() << Q_FUNC_INFO;
|
2013-10-01 15:52:07 +04:00
|
|
|
if (_settingsDialog.isNull()) {
|
2014-02-14 06:02:59 +04:00
|
|
|
_settingsDialog =
|
|
|
|
#if defined(Q_OS_MAC)
|
|
|
|
new SettingsDialogMac(this);
|
|
|
|
#else
|
|
|
|
new SettingsDialog(this);
|
|
|
|
#endif
|
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
|
|
|
}
|
|
|
|
|
2013-11-29 14:18:59 +04:00
|
|
|
void ownCloudGui::slotShowSyncProtocol()
|
|
|
|
{
|
|
|
|
slotShowSettings();
|
|
|
|
_settingsDialog->showActivityPage();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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();
|
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-04-17 18:56:17 +03:00
|
|
|
if (auto account = AccountManager::instance()->accounts().value(0)) {
|
|
|
|
QDesktopServices::openUrl(account->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 )
|
|
|
|
{
|
|
|
|
if( raiseWidget && raiseWidget->parentWidget() == 0) {
|
|
|
|
// Qt has a bug which causes parent-less dialogs to pop-under.
|
|
|
|
raiseWidget->showNormal();
|
|
|
|
raiseWidget->raise();
|
|
|
|
raiseWidget->activateWindow();
|
2014-08-12 16:47:43 +04:00
|
|
|
|
|
|
|
#if defined(Q_OS_MAC)
|
|
|
|
// viel hilft viel ;-)
|
|
|
|
MacWindow::bringToFront(raiseWidget);
|
2014-08-28 19:23:44 +04:00
|
|
|
#endif
|
|
|
|
#if defined(Q_OS_X11)
|
|
|
|
WId wid = widget->winId();
|
|
|
|
NETWM::init();
|
|
|
|
|
|
|
|
XEvent e;
|
|
|
|
e.xclient.type = ClientMessage;
|
|
|
|
e.xclient.message_type = NETWM::NET_ACTIVE_WINDOW;
|
|
|
|
e.xclient.display = QX11Info::display();
|
|
|
|
e.xclient.window = wid;
|
|
|
|
e.xclient.format = 32;
|
|
|
|
e.xclient.data.l[0] = 2;
|
|
|
|
e.xclient.data.l[1] = QX11Info::appTime();
|
|
|
|
e.xclient.data.l[2] = 0;
|
|
|
|
e.xclient.data.l[3] = 0l;
|
|
|
|
e.xclient.data.l[4] = 0l;
|
2014-09-06 00:07:54 +04:00
|
|
|
Display *display = QX11Info::display();
|
|
|
|
XSendEvent(display,
|
|
|
|
RootWindow(display, DefaultScreen(display)),
|
|
|
|
False, // propagate
|
|
|
|
SubstructureRedirectMask|SubstructureNotifyMask,
|
|
|
|
&e);
|
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
|
|
|
|
2015-03-11 16:09:31 +03:00
|
|
|
void ownCloudGui::slotShowShareDialog(const QString &sharePath, const QString &localPath, bool resharingAllowed)
|
2015-01-13 15:50:41 +03:00
|
|
|
{
|
2015-04-23 15:14:28 +03:00
|
|
|
const auto folder = FolderMan::instance()->folderForPath(localPath);
|
|
|
|
if (!folder) {
|
|
|
|
qDebug() << "Could not open share dialog for" << localPath << "no responsible folder found";
|
2015-01-28 12:52:55 +03:00
|
|
|
return;
|
|
|
|
}
|
2015-04-23 15:14:28 +03:00
|
|
|
const auto accountState = folder->accountState();
|
2015-01-28 12:52:55 +03:00
|
|
|
|
2015-04-23 15:14:28 +03:00
|
|
|
qDebug() << Q_FUNC_INFO << "Opening share dialog" << sharePath << localPath;
|
|
|
|
ShareDialog *w = new ShareDialog(accountState->account(), sharePath, localPath, resharingAllowed);
|
2015-01-14 15:51:02 +03:00
|
|
|
w->getShares();
|
2015-01-13 15:50:41 +03:00
|
|
|
w->setAttribute( Qt::WA_DeleteOnClose, true );
|
2015-02-16 18:46:05 +03:00
|
|
|
raiseDialog(w);
|
2015-01-13 15:50:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-10-01 15:52:07 +04:00
|
|
|
} // end namespace
|