nextcloud-desktop/src/mirall/application.cpp

433 lines
14 KiB
C++
Raw Normal View History

2011-04-06 13:48:02 +04:00
/*
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
*
* 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.
*/
2011-10-13 15:55:52 +04:00
#include <QtCore>
#include <QtGui>
2011-02-17 02:21:45 +03:00
#include "mirall/constants.h"
#include "mirall/application.h"
#include "mirall/folder.h"
#include "mirall/folderwatcher.h"
#include "mirall/folderwizard.h"
#include "mirall/networklocation.h"
#include "mirall/unisonfolder.h"
#include "mirall/sitecopyfolder.h"
#include "mirall/sitecopyconfig.h"
2011-09-26 17:00:12 +04:00
#include "mirall/statusdialog.h"
#include "mirall/owncloudsetup.h"
#ifdef WITH_CSYNC
#include "mirall/csyncfolder.h"
#endif
#include "mirall/inotify.h"
2011-02-17 02:21:45 +03:00
namespace Mirall {
Application::Application(int argc, char **argv) :
QApplication(argc, argv),
2011-04-04 14:23:30 +04:00
_networkMgr(new QNetworkConfigurationManager(this)),
2011-04-06 12:56:20 +04:00
_folderSyncCount(0),
_contextMenu(0)
2011-02-17 02:21:45 +03:00
{
INotify::initialize();
2011-02-17 02:21:45 +03:00
setApplicationName("Mirall");
setQuitOnLastWindowClosed(false);
_folderWizard = new FolderWizard();
_owncloudSetup = new OwncloudSetup();
2011-09-26 17:00:12 +04:00
_statusDialog = new StatusDialog();
_folderConfigPath = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/folders";
2011-10-13 15:55:52 +04:00
connect( _statusDialog, SIGNAL(removeFolderAlias( const QString&)),
SLOT(slotRemoveFolder(const QString&)));
2011-10-18 12:22:24 +04:00
connect( _statusDialog, SIGNAL(fetchFolderAlias(const QString&)),
SLOT(slotFetchFolder( const QString&)));
2011-02-17 02:21:45 +03:00
setupActions();
setupSystemTray();
qDebug() << "* Network is" << (_networkMgr->isOnline() ? "online" : "offline");
foreach (QNetworkConfiguration netCfg, _networkMgr->allConfigurations(QNetworkConfiguration::Active)) {
//qDebug() << "Network:" << netCfg.identifier();
}
// if QDir::mkpath would not be so stupid, I would not need to have this
// duplication of folderConfigPath() here
QDir storageDir(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
storageDir.mkpath("folders");
// Look for configuration changes
_configFolderWatcher = new FolderWatcher(storageDir.path());
connect(_configFolderWatcher, SIGNAL(folderChanged(const QStringList &)),
this, SLOT(slotReparseConfiguration()));
setupKnownFolders();
2011-02-17 02:21:45 +03:00
setupContextMenu();
2011-11-04 14:41:49 +04:00
// Check if sitecopy is installed
QFileInfo fi( SITECOPY_BIN );
if( !fi.exists() ) {
QMessageBox::critical( 0, tr("Sitecopy not Installed."),
tr("The program <i>sitecopy</i> is not installed but it is needed by mirall.<br/>Please install sitecopy!"));
}
qDebug() << "Network Location: " << NetworkLocation::currentLocation().encoded();
2011-02-17 02:21:45 +03:00
}
Application::~Application()
{
qDebug() << "* Mirall shutdown";
INotify::cleanup();
delete _networkMgr;
delete _tray;
foreach (Folder *folder, _folderMap) {
delete folder;
}
2011-02-17 02:21:45 +03:00
}
QString Application::folderConfigPath() const
{
return _folderConfigPath;
}
2011-02-17 02:21:45 +03:00
void Application::setupActions()
{
2011-10-14 18:39:53 +04:00
_actionAddFolder = new QAction(tr("Add folder..."), this);
2011-02-17 02:21:45 +03:00
QObject::connect(_actionAddFolder, SIGNAL(triggered(bool)), SLOT(slotAddFolder()));
2011-10-14 18:39:53 +04:00
_actionConfigure = new QAction(tr("Configure..."), this);
QObject::connect(_actionConfigure, SIGNAL(triggered(bool)), SLOT(slotConfigure()));
2011-02-17 02:21:45 +03:00
_actionQuit = new QAction(tr("Quit"), this);
QObject::connect(_actionQuit, SIGNAL(triggered(bool)), SLOT(quit()));
}
void Application::setupSystemTray()
{
_tray = new QSystemTrayIcon(this);
2011-10-05 17:56:56 +04:00
_tray->setIcon(QIcon::fromTheme(FOLDER_ICON_EMPTY));
2011-09-26 17:00:12 +04:00
connect(_tray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
SLOT(slotTrayClicked(QSystemTrayIcon::ActivationReason)));
2011-02-17 02:21:45 +03:00
_tray->show();
}
2011-09-26 17:00:12 +04:00
void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
{
if( reason == QSystemTrayIcon::Trigger ) {
setAllFolderSyncEnabled( false );
// check if there is a mirall.cfg already.
2011-10-14 18:39:53 +04:00
if( _owncloudSetup->wizard()->isVisible() ) {
_owncloudSetup->wizard()->show();
}
QFile fi( QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/mirall.cfg" );
if( !fi.exists() ) {
2011-09-27 21:10:01 +04:00
qDebug() << "No configured folders yet, start the Owncloud integration dialog.";
_owncloudSetup->startWizard();
2011-09-27 21:10:01 +04:00
} else {
2011-10-12 18:58:54 +04:00
_statusDialog->setFolderList( _folderMap );
_statusDialog->setOCUrl( QUrl( _owncloudSetup->ownCloudUrl()));
2011-10-14 18:39:53 +04:00
2011-10-20 12:26:40 +04:00
_statusDialog->show();
2011-09-27 21:10:01 +04:00
}
setAllFolderSyncEnabled( true );
2011-09-26 17:00:12 +04:00
}
}
2011-02-17 02:21:45 +03:00
void Application::setupContextMenu()
{
2011-04-06 12:56:20 +04:00
delete _contextMenu;
_contextMenu = new QMenu();
2011-10-14 18:39:53 +04:00
_contextMenu->setTitle(tr( "Mirall" ));
_contextMenu->addAction(_actionConfigure);
2011-04-06 12:56:20 +04:00
_contextMenu->addAction(_actionAddFolder);
2011-10-14 18:39:53 +04:00
_contextMenu->addSeparator();
// here all folders should be added
foreach (Folder *folder, _folderMap) {
2011-04-06 12:56:20 +04:00
_contextMenu->addAction(folder->openAction());
}
2011-04-06 12:56:20 +04:00
_contextMenu->addSeparator();
2011-04-06 12:56:20 +04:00
_contextMenu->addAction(_actionQuit);
_tray->setContextMenu(_contextMenu);
2011-02-17 02:21:45 +03:00
}
void Application::slotReparseConfiguration()
{
setupKnownFolders();
setupContextMenu();
}
2011-02-17 02:21:45 +03:00
void Application::slotAddFolder()
{
setAllFolderSyncEnabled( false );
_folderWizard->setFolderMap( &_folderMap );
_folderWizard->restart();
if (_folderWizard->exec() == QDialog::Accepted) {
qDebug() << "* Folder wizard completed";
QString alias = _folderWizard->field("alias").toString();
QSettings settings(folderConfigPath() + "/" + alias, QSettings::IniFormat);
settings.setValue("folder/backend", "csync");
settings.setValue("folder/path", _folderWizard->field("sourceFolder"));
if (_folderWizard->field("local?").toBool()) {
settings.setValue("backend:csync/secondPath", _folderWizard->field("targetLocalFolder"));
} else if (_folderWizard->field("remote?").toBool()) {
settings.setValue("backend:csync/secondPath", _folderWizard->field("targetURLFolder"));
bool onlyOnline = _folderWizard->field("onlyOnline?").toBool();
settings.setValue("folder/onlyOnline", onlyOnline);
if (onlyOnline) {
bool onlyThisLAN = _folderWizard->field("onlyThisLAN?").toBool();
settings.setValue("folder/onlyThisLAN", onlyThisLAN);
if (onlyThisLAN) {
settings.setValue("folder/onlyOnline", true);
}
}
} else if( _folderWizard->field("OC?").toBool()) {
settings.setValue("folder/backend", "sitecopy");
settings.setValue("backend:sitecopy/targetPath", _folderWizard->field("targetOCFolder"));
settings.setValue("backend:sitecopy/alias", _folderWizard->field("alias"));
qDebug() << "Now writing sitecopy config " << _folderWizard->field("alias").toString(); ;
SitecopyConfig scConfig;
scConfig.writeSiteConfig( alias,
_folderWizard->field("sourceFolder").toString(), /* local path */
_folderWizard->field("targetOCFolder").toString() );
} else {
qWarning() << "* Folder not local and note remote?";
return;
}
settings.sync();
setupFolderFromConfigFile(alias);
setupContextMenu();
}
else
qDebug() << "* Folder wizard cancelled";
setAllFolderSyncEnabled( true );
2011-02-17 02:21:45 +03:00
}
2011-10-13 15:55:52 +04:00
void Application::slotRemoveFolder( const QString& alias )
{
QString configFile = folderConfigPath() + "/" + alias;
QFile file( configFile );
int ret = QMessageBox::question( 0, tr("Confirm Folder Remove"), tr("Do you really want to remove upload folder <i>%1</i>?").arg(alias),
QMessageBox::Yes|QMessageBox::No );
if( ret == QMessageBox::No ) {
return;
}
if( _folderMap.contains( alias )) {
qDebug() << "Removing " << alias;
2011-10-13 15:55:52 +04:00
Folder *f = _folderMap.take( alias );
delete f;
} else {
qDebug() << "!! Can not remove " << alias << ", not in folderMap.";
2011-10-13 15:55:52 +04:00
}
if( file.exists() ) {
qDebug() << "Remove folder config file " << configFile;
file.remove();
}
SitecopyConfig scConfig;
if( ! scConfig.removeFolderConfig( alias ) ) {
qDebug() << "Failed to remove folder config for " << alias;
} else {
setupKnownFolders();
_statusDialog->setFolderList( _folderMap );
}
}
2011-10-18 12:22:24 +04:00
void Application::slotFetchFolder( const QString& alias )
{
qDebug() << "start to fetch folder with alias " << alias;
if( ! _folderMap.contains( alias ) ) {
qDebug() << "!! Can not fetch alias " << alias << ", can not be found in folderMap.";
return;
}
Folder *f = _folderMap[alias];
if( f->backend() == "sitecopy" ) {
if( QMessageBox::question( 0, tr("Confirm Folder Fetch"), tr("Do you really want to fetch the folder with alias <i>%1</i> from your ownCloud?<br/>"
"This overwrites your local data in directory <i>%2</i>!").arg(alias).arg(f->path()),
QMessageBox::Yes|QMessageBox::No ) == QMessageBox::Yes ) {
SiteCopyFolder *sf = static_cast<SiteCopyFolder*>( f );
sf->fetchFromOC();
} else {
qDebug() << "!! Can only fetch backend type sitecopy, this one has " << f->backend();
}
}
}
2011-10-14 18:39:53 +04:00
void Application::slotConfigure()
{
setAllFolderSyncEnabled( false );
2011-10-14 18:39:53 +04:00
_owncloudSetup->startWizard();
setAllFolderSyncEnabled( true );
2011-10-14 18:39:53 +04:00
}
void Application::setupKnownFolders()
{
2011-10-13 15:55:52 +04:00
qDebug() << "* Setup folders from " << folderConfigPath();
_folderMap.clear();
QDir dir(folderConfigPath());
dir.setFilter(QDir::Files);
QStringList list = dir.entryList();
foreach (QString file, list) {
setupFolderFromConfigFile(file);
}
if( list.size() ) _tray->setIcon(QIcon::fromTheme(FOLDER_ICON));
}
// filename is the name of the file only, it does not include
// the configuration directory path
void Application::setupFolderFromConfigFile(const QString &file) {
2011-04-04 14:23:30 +04:00
Folder *folder = 0L;
qDebug() << " ` -> setting up:" << file;
QSettings settings(folderConfigPath() + "/" + file, QSettings::IniFormat);
qDebug() << " -> file path: " + settings.fileName();
if (!settings.contains("folder/path")) {
qWarning() << " `->" << file << "is not a valid folder configuration";
return;
}
QVariant path = settings.value("folder/path").toString();
if (path.isNull() || !QFileInfo(path.toString()).isDir()) {
qWarning() << " `->" << path.toString() << "does not exist. Skipping folder" << file;
_tray->showMessage(tr("Unknown folder"),
tr("Folder %1 does not exist").arg(path.toString()),
QSystemTrayIcon::Critical);
return;
}
2011-10-18 12:22:24 +04:00
QString backend = settings.value("folder/backend").toString();
if (!backend.isEmpty()) {
if( backend == "sitecopy") {
QString targetPath = settings.value("backend:sitecopy/targetPath").toString();
SiteCopyFolder *scf = new SiteCopyFolder( file, /* file is the same as the alias */
2011-11-04 14:41:49 +04:00
path.toString(),
targetPath,
this);
QFileInfo fi( SITECOPY_BIN );
if( ! fi.exists() ) {
SyncResult sr( SyncResult::SetupError );
sr.setErrorString( tr("Sitecopy is not installed!"));
scf->slotSyncFinished( sr );
}
folder = scf;
} else if (backend == "unison") {
2011-04-06 11:52:02 +04:00
folder = new UnisonFolder(file,
path.toString(),
2011-04-04 14:23:30 +04:00
settings.value("backend:unison/secondPath").toString(),
this);
} else if (backend == "csync") {
#ifdef WITH_CSYNC
folder = new CSyncFolder(file,
path.toString(),
settings.value("backend:csync/secondPath").toString(),
this);
#else
qCritical() << "* csync suport not enabled!! ignoring:" << file;
#endif
}
else {
qWarning() << "unknown backend" << backend;
return;
}
}
2011-10-18 12:22:24 +04:00
folder->setBackend( backend );
2011-04-06 17:57:18 +04:00
folder->setOnlyOnlineEnabled(settings.value("folder/onlyOnline", false).toBool());
folder->setOnlyThisLANEnabled(settings.value("folder/onlyThisLAN", false).toBool());
2011-04-04 14:23:30 +04:00
_folderMap[file] = folder;
2011-11-04 14:41:49 +04:00
qDebug() << "Adding folder to Folder Map " << folder;
2011-04-04 14:23:30 +04:00
QObject::connect(folder, SIGNAL(syncStarted()), SLOT(slotFolderSyncStarted()));
2011-04-08 13:36:53 +04:00
QObject::connect(folder, SIGNAL(syncFinished(const SyncResult &)), SLOT(slotFolderSyncFinished(const SyncResult &)));
2011-04-04 14:23:30 +04:00
}
void Application::slotFolderSyncStarted()
{
_folderSyncCount++;
if (_folderSyncCount > 0) {
_tray->setIcon(QIcon::fromTheme(FOLDER_SYNC_ICON));
2011-04-04 14:23:30 +04:00
}
}
2011-04-08 13:36:53 +04:00
void Application::slotFolderSyncFinished(const SyncResult &result)
2011-04-04 14:23:30 +04:00
{
_folderSyncCount--;
2011-04-08 13:36:53 +04:00
Folder *folder = dynamic_cast<Folder *>(sender());
2011-04-04 14:23:30 +04:00
if (_folderSyncCount < 1) {
2011-04-08 13:36:53 +04:00
if (result.result() == SyncResult::Success) {
_tray->setIcon(QIcon::fromTheme(FOLDER_ICON));
//_tray->showMessage(tr("Folder %1").arg(folder->alias()),
// tr("Synchronization successfull"),
// QSystemTrayIcon::Information);
}
else {
_tray->setIcon(QIcon::fromTheme(FOLDER_SYNC_ERROR));
_tray->showMessage(tr("Folder %1").arg(folder->alias()),
2011-10-13 18:41:24 +04:00
result.errorString(),
/* tr("Synchronization did not finish successfully"), */
2011-04-08 13:36:53 +04:00
QSystemTrayIcon::Warning);
}
2011-04-04 14:23:30 +04:00
}
2011-10-13 18:41:24 +04:00
if( _statusDialog->isVisible() ) {
_statusDialog->setFolderList( _folderMap );
}
}
void Application::setAllFolderSyncEnabled( bool stat )
{
if( stat )
qDebug() << " ** Enabling folder sync!";
else
qDebug() << " ** Disabling folder sync!";
foreach( Folder *f, _folderMap ) {
f->setSyncEnabled( stat );
}
}
2011-02-17 02:21:45 +03:00
} // namespace Mirall
#include "application.moc"