mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-23 13:35:58 +03:00
WIP: introduce folder manager to separate folder management from
GUI and ease the Application object
This commit is contained in:
parent
591054ed8f
commit
04841c940d
5 changed files with 428 additions and 254 deletions
|
@ -55,6 +55,7 @@ mirall/mirallwebdav.cpp
|
|||
mirall/theme.cpp
|
||||
mirall/miralltheme.cpp
|
||||
mirall/owncloudtheme.cpp
|
||||
mirall/folderman.cpp
|
||||
)
|
||||
|
||||
if(CSYNC_FOUND)
|
||||
|
|
|
@ -45,7 +45,6 @@ namespace Mirall {
|
|||
Application::Application(int argc, char **argv) :
|
||||
QApplication(argc, argv),
|
||||
_networkMgr(new QNetworkConfigurationManager(this)),
|
||||
_folderSyncCount(0),
|
||||
_contextMenu(0)
|
||||
{
|
||||
INotify::initialize();
|
||||
|
@ -56,13 +55,14 @@ Application::Application(int argc, char **argv) :
|
|||
_theme = new mirallTheme();
|
||||
#endif
|
||||
|
||||
_folderMan = new FolderMan();
|
||||
|
||||
setApplicationName( _theme->appName() );
|
||||
setQuitOnLastWindowClosed(false);
|
||||
|
||||
_folderWizard = new FolderWizard();
|
||||
_owncloudSetup = new OwncloudSetup();
|
||||
_statusDialog = new StatusDialog();
|
||||
_folderConfigPath = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/folders";
|
||||
|
||||
connect( _statusDialog, SIGNAL(removeFolderAlias( const QString&)),
|
||||
SLOT(slotRemoveFolder(const QString&)));
|
||||
|
@ -83,19 +83,14 @@ Application::Application(int argc, char **argv) :
|
|||
//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();
|
||||
setupContextMenu();
|
||||
|
||||
/* setup the folder list */
|
||||
int cnt = _folderMan->setupFolders();
|
||||
|
||||
if( cnt ) _tray->setIcon(QIcon::fromTheme(MIRALL_ICON, QIcon( QString( ":/mirall/resources/%1").arg(MIRALL_ICON))));
|
||||
|
||||
|
||||
qDebug() << "Network Location: " << NetworkLocation::currentLocation().encoded();
|
||||
}
|
||||
|
||||
|
@ -105,16 +100,8 @@ Application::~Application()
|
|||
INotify::cleanup();
|
||||
|
||||
delete _networkMgr;
|
||||
delete _folderMan;
|
||||
delete _tray;
|
||||
|
||||
foreach (Folder *folder, _folderMap) {
|
||||
delete folder;
|
||||
}
|
||||
}
|
||||
|
||||
QString Application::folderConfigPath() const
|
||||
{
|
||||
return _folderConfigPath;
|
||||
}
|
||||
|
||||
void Application::setupActions()
|
||||
|
@ -141,7 +128,7 @@ void Application::setupSystemTray()
|
|||
void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
|
||||
{
|
||||
if( reason == QSystemTrayIcon::Trigger ) {
|
||||
disableFoldersWithRestore();
|
||||
_folderMan->disableFoldersWithRestore();
|
||||
// check if there is a mirall.cfg already.
|
||||
if( _owncloudSetup->wizard()->isVisible() ) {
|
||||
_owncloudSetup->wizard()->show();
|
||||
|
@ -155,10 +142,12 @@ void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
|
|||
|
||||
_statusDialog->show();
|
||||
}
|
||||
restoreEnabledFolders();
|
||||
if ( !_folderMap.isEmpty() && _statusDialog->isVisible() ) {
|
||||
_statusDialog->setFolderList( _folderMap );
|
||||
}
|
||||
_folderMan->restoreEnabledFolders();
|
||||
|
||||
// FIXME:
|
||||
// if ( !_folderMap.isEmpty() && _statusDialog->isVisible() ) {
|
||||
// _statusDialog->setFolderList( _folderMap );
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +161,7 @@ void Application::setupContextMenu()
|
|||
_contextMenu->addSeparator();
|
||||
|
||||
// here all folders should be added
|
||||
foreach (Folder *folder, _folderMap) {
|
||||
foreach (Folder *folder, _folderMan->map() ) {
|
||||
_contextMenu->addAction(folder->openAction());
|
||||
}
|
||||
|
||||
|
@ -182,68 +171,59 @@ void Application::setupContextMenu()
|
|||
_tray->setContextMenu(_contextMenu);
|
||||
}
|
||||
|
||||
void Application::slotReparseConfiguration()
|
||||
{
|
||||
setupKnownFolders();
|
||||
setupContextMenu();
|
||||
}
|
||||
|
||||
void Application::slotAddFolder()
|
||||
{
|
||||
disableFoldersWithRestore();
|
||||
_folderMan->disableFoldersWithRestore();
|
||||
|
||||
_folderWizard->setFolderMap( &_folderMap );
|
||||
Folder::Map folderMap = _folderMan->map();
|
||||
|
||||
_folderWizard->setFolderMap( &folderMap );
|
||||
|
||||
_folderWizard->restart();
|
||||
|
||||
if (_folderWizard->exec() == QDialog::Accepted) {
|
||||
qDebug() << "* Folder wizard completed";
|
||||
|
||||
QString alias = _folderWizard->field("alias").toString();
|
||||
bool goodData = true;
|
||||
|
||||
QSettings settings(folderConfigPath() + "/" + alias, QSettings::IniFormat);
|
||||
settings.setValue("folder/backend", "csync");
|
||||
settings.setValue("folder/path", _folderWizard->field("sourceFolder"));
|
||||
QString alias = _folderWizard->field("alias").toString();
|
||||
QString sourceFolder = _folderWizard->field("sourceFolder").toString();
|
||||
QString backend = QString::fromLocal8Bit("csync");
|
||||
QString targetPath;
|
||||
bool onlyThisLAN = false;
|
||||
bool onlyOnline = false;
|
||||
|
||||
if (_folderWizard->field("local?").toBool()) {
|
||||
settings.setValue("backend:csync/secondPath", _folderWizard->field("targetLocalFolder"));
|
||||
// setup a local csync folder
|
||||
targetPath = _folderWizard->field("targetLocalFolder").toString();
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
// setup a remote csync folder
|
||||
targetPath = _folderWizard->field("targetURLFolder").toString();
|
||||
onlyOnline = _folderWizard->field("onlyOnline?").toBool();
|
||||
onlyThisLAN = _folderWizard->field("onlyThisLAN?").toBool();
|
||||
} else if( _folderWizard->field("OC?").toBool()) {
|
||||
settings.setValue("folder/backend", "owncloud");
|
||||
settings.setValue("backend:owncloud/targetPath", _folderWizard->field("targetOCFolder"));
|
||||
settings.setValue("backend:owncloud/alias", _folderWizard->field("alias"));
|
||||
|
||||
qDebug() << "Now writing owncloud config " << _folderWizard->field("alias").toString(); ;
|
||||
// setup a ownCloud folder
|
||||
backend = QString::fromLocal8Bit("owncloud");
|
||||
targetPath = _folderWizard->field("targetOCFolder").toString();
|
||||
} else {
|
||||
qWarning() << "* Folder not local and note remote?";
|
||||
return;
|
||||
goodData = false;
|
||||
}
|
||||
|
||||
settings.sync();
|
||||
setupFolderFromConfigFile(alias);
|
||||
setupContextMenu();
|
||||
if( goodData ) {
|
||||
_folderMan->addFolderDefinition( backend, alias, sourceFolder, targetPath, onlyThisLAN );
|
||||
}
|
||||
#ifdef PUT_TO_FOLDERMAN
|
||||
|
||||
#endif
|
||||
} else {
|
||||
qDebug() << "* Folder wizard cancelled";
|
||||
}
|
||||
restoreEnabledFolders();
|
||||
_folderMan->restoreEnabledFolders();
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
|
@ -251,28 +231,10 @@ void Application::slotRemoveFolder( const QString& alias )
|
|||
return;
|
||||
}
|
||||
|
||||
if( _folderMap.contains( alias )) {
|
||||
qDebug() << "Removing " << alias;
|
||||
Folder *f = _folderMap.take( alias );
|
||||
delete f;
|
||||
} else {
|
||||
qDebug() << "!! Can not remove " << alias << ", not in folderMap.";
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
_folderMan->slotRemoveFolder( alias );
|
||||
}
|
||||
|
||||
#ifdef HAVE_FETCH_AND_PUSH
|
||||
void Application::slotFetchFolder( const QString& alias )
|
||||
{
|
||||
qDebug() << "start to fetch folder with alias " << alias;
|
||||
|
@ -318,22 +280,17 @@ void Application::slotPushFolder( const QString& alias )
|
|||
qDebug() << "!! Can only fetch backend type sitecopy, this one has " << f->backend();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void Application::slotInfoFolder( const QString& alias )
|
||||
{
|
||||
qDebug() << "details of folder with alias " << alias;
|
||||
|
||||
if( ! _folderMap.contains( alias ) ) {
|
||||
qDebug() << "!! Can not get details of alias " << alias << ", can not be found in folderMap.";
|
||||
return;
|
||||
}
|
||||
|
||||
Folder *folder = _folderMap[alias];
|
||||
SyncResult folderResult = _folderMan->syncResult( alias );
|
||||
|
||||
QString folderMessage = tr( "Last sync was succesful" );
|
||||
SyncResult folderResult = folder->lastSyncResult();
|
||||
|
||||
SyncResult::Result syncResult = folderResult.result();
|
||||
if ( syncResult == SyncResult::Error ) {
|
||||
folderMessage = tr( "%1" ).arg( folderResult.errorString() );
|
||||
|
@ -345,7 +302,7 @@ void Application::slotInfoFolder( const QString& alias )
|
|||
folderMessage = tr( "Undefined state" );
|
||||
}
|
||||
|
||||
QMessageBox infoBox( QMessageBox::Information, tr( "Folder information" ), folder->alias(), QMessageBox::Ok );
|
||||
QMessageBox infoBox( QMessageBox::Information, tr( "Folder information" ), alias, QMessageBox::Ok );
|
||||
|
||||
infoBox.setInformativeText(folderMessage);
|
||||
qDebug() << "informative text: " << infoBox.informativeText();
|
||||
|
@ -381,140 +338,28 @@ void Application::slotEnableFolder(const QString& alias, const bool enable)
|
|||
{
|
||||
qDebug() << "enable folder with alias " << alias;
|
||||
|
||||
if( ! _folderMap.contains( alias ) ) {
|
||||
qDebug() << "!! Can not enable alias " << alias << ", can not be found in folderMap.";
|
||||
return;
|
||||
}
|
||||
_folderMan->slotEnableFolder( alias, enable );
|
||||
|
||||
Folder *f = _folderMap[alias];
|
||||
f->setSyncEnabled(enable);
|
||||
}
|
||||
|
||||
void Application::slotConfigure()
|
||||
{
|
||||
disableFoldersWithRestore();
|
||||
_folderMan->disableFoldersWithRestore();
|
||||
_owncloudSetup->startWizard();
|
||||
restoreEnabledFolders();
|
||||
}
|
||||
|
||||
void Application::setupKnownFolders()
|
||||
{
|
||||
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(MIRALL_ICON, QIcon( QString( ":/mirall/resources/%1").arg(MIRALL_ICON))));
|
||||
}
|
||||
|
||||
// filename is the name of the file only, it does not include
|
||||
// the configuration directory path
|
||||
void Application::setupFolderFromConfigFile(const QString &file) {
|
||||
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;
|
||||
}
|
||||
|
||||
QString backend = settings.value("folder/backend").toString();
|
||||
if (!backend.isEmpty()) {
|
||||
if( backend == "sitecopy") {
|
||||
qCritical() << "* sitecopy is not longer supported in this release." << endl;
|
||||
} else if (backend == "unison") {
|
||||
folder = new UnisonFolder(file,
|
||||
path.toString(),
|
||||
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 support not enabled!! ignoring:" << file;
|
||||
#endif
|
||||
} else if( backend == "owncloud" ) {
|
||||
#ifdef WITH_CSYNC
|
||||
QUrl url( _owncloudSetup->fullOwnCloudUrl() );
|
||||
QString existPath = url.path();
|
||||
qDebug() << "existing path: " << existPath;
|
||||
QString newPath = settings.value("backend:owncloud/targetPath").toString();
|
||||
if( !existPath.isEmpty() ) {
|
||||
// cut off the trailing slash
|
||||
if( existPath.endsWith('/') ) {
|
||||
existPath.truncate( existPath.length()-1 );
|
||||
}
|
||||
// cut off the leading slash
|
||||
if( newPath.startsWith('/') ) {
|
||||
newPath.remove(0,1);
|
||||
}
|
||||
}
|
||||
|
||||
url.setPath( QString("%1/files/webdav.php/%2").arg(existPath).arg(newPath) );
|
||||
|
||||
folder = new ownCloudFolder( file, path.toString(),
|
||||
url.toString(),
|
||||
this );
|
||||
|
||||
|
||||
#else
|
||||
qCritical() << "* owncloud support not enabled!! ignoring:" << file;
|
||||
#endif
|
||||
}
|
||||
|
||||
else {
|
||||
qWarning() << "unknown backend" << backend;
|
||||
return;
|
||||
}
|
||||
}
|
||||
folder->setBackend( backend );
|
||||
folder->setOnlyOnlineEnabled(settings.value("folder/onlyOnline", false).toBool());
|
||||
folder->setOnlyThisLANEnabled(settings.value("folder/onlyThisLAN", false).toBool());
|
||||
|
||||
_folderMap[file] = folder;
|
||||
qDebug() << "Adding folder to Folder Map " << folder;
|
||||
QObject::connect(folder, SIGNAL(syncStarted()), SLOT(slotFolderSyncStarted()));
|
||||
QObject::connect(folder, SIGNAL(syncFinished(const SyncResult &)), SLOT(slotFolderSyncFinished(const SyncResult &)));
|
||||
_folderMan->restoreEnabledFolders();
|
||||
}
|
||||
|
||||
// FIXME: Better start- and end handling
|
||||
void Application::slotFolderSyncStarted()
|
||||
{
|
||||
_folderSyncCount++;
|
||||
|
||||
if (_folderSyncCount > 0) {
|
||||
_tray->setIcon(QIcon::fromTheme(FOLDER_SYNC_ICON, QIcon( QString( ":/mirall/resources/%1").arg(FOLDER_SYNC_ICON))));
|
||||
}
|
||||
_tray->setIcon(QIcon::fromTheme(FOLDER_SYNC_ICON, QIcon( QString( ":/mirall/resources/%1").arg(FOLDER_SYNC_ICON))));
|
||||
}
|
||||
|
||||
void Application::slotFolderSyncFinished(const SyncResult &result)
|
||||
{
|
||||
_folderSyncCount--;
|
||||
|
||||
// in case the sending folder is needed:
|
||||
// Folder *folder = dynamic_cast<Folder *>(sender());
|
||||
|
||||
if( _folderSyncCount == 0 ) {
|
||||
// if( _folderSyncCount == 0 ) {
|
||||
computeOverallSyncStatus();
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
void Application::computeOverallSyncStatus()
|
||||
|
@ -523,7 +368,9 @@ void Application::computeOverallSyncStatus()
|
|||
// display the info of the least succesful sync (eg. not just display the result of the latest sync
|
||||
SyncResult overallResult = SyncResult::Success;
|
||||
QString trayMessage;
|
||||
foreach ( Folder *syncedFolder, _folderMap ) {
|
||||
Folder::Map map = _folderMan->map();
|
||||
|
||||
foreach ( Folder *syncedFolder, map ) {
|
||||
QString folderMessage;
|
||||
SyncResult folderResult = syncedFolder->lastSyncResult();
|
||||
SyncResult::Result syncResult = folderResult.result();
|
||||
|
@ -574,28 +421,10 @@ void Application::computeOverallSyncStatus()
|
|||
|
||||
// Only refresh the folder if it is being shown
|
||||
if( _statusDialog->isVisible() ) {
|
||||
_statusDialog->setFolderList( _folderMap );
|
||||
_statusDialog->setFolderList( map );
|
||||
}
|
||||
}
|
||||
|
||||
void Application::disableFoldersWithRestore()
|
||||
{
|
||||
_folderEnabledMap.clear();
|
||||
foreach( Folder *f, _folderMap ) {
|
||||
// store the enabled state, then make sure it is disabled
|
||||
_folderEnabledMap.insert(f->alias(), f->syncEnabled());
|
||||
f->setSyncEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::restoreEnabledFolders()
|
||||
{
|
||||
foreach( Folder *f, _folderMap ) {
|
||||
if (_folderEnabledMap.contains( f->alias() )) {
|
||||
f->setSyncEnabled( _folderEnabledMap.value( f->alias() ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Mirall
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "mirall/syncresult.h"
|
||||
#include "mirall/folder.h"
|
||||
|
||||
#include "mirall/folderman.h"
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class QSystemTrayIcon;
|
||||
|
@ -43,11 +45,12 @@ signals:
|
|||
|
||||
protected slots:
|
||||
|
||||
void slotReparseConfiguration();
|
||||
void slotAddFolder();
|
||||
void slotRemoveFolder( const QString& );
|
||||
#ifdef HAVE_FETCH_AND_PUSH
|
||||
void slotFetchFolder( const QString& );
|
||||
void slotPushFolder( const QString& );
|
||||
#endif
|
||||
void slotEnableFolder( const QString&, const bool );
|
||||
void slotInfoFolder( const QString& );
|
||||
void slotConfigure();
|
||||
|
@ -57,23 +60,11 @@ protected slots:
|
|||
|
||||
protected:
|
||||
|
||||
QString folderConfigPath() const;
|
||||
|
||||
void setupActions();
|
||||
void setupSystemTray();
|
||||
void setupContextMenu();
|
||||
|
||||
// finds all folder configuration files
|
||||
// and create the folders
|
||||
void setupKnownFolders();
|
||||
|
||||
// creates a folder for a specific
|
||||
// configuration
|
||||
void setupFolderFromConfigFile(const QString &filename);
|
||||
|
||||
//folders have to be disabled while making config changes
|
||||
void disableFoldersWithRestore();
|
||||
void restoreEnabledFolders();
|
||||
void computeOverallSyncStatus();
|
||||
|
||||
protected slots:
|
||||
|
@ -81,19 +72,13 @@ protected slots:
|
|||
|
||||
private:
|
||||
// configuration file -> folder
|
||||
Folder::Map _folderMap;
|
||||
QSystemTrayIcon *_tray;
|
||||
QAction *_actionQuit;
|
||||
QAction *_actionAddFolder;
|
||||
QAction *_actionConfigure;
|
||||
|
||||
QNetworkConfigurationManager *_networkMgr;
|
||||
QString _folderConfigPath;
|
||||
|
||||
// counter tracking number of folders doing a sync
|
||||
int _folderSyncCount;
|
||||
|
||||
FolderWatcher *_configFolderWatcher;
|
||||
FolderWizard *_folderWizard;
|
||||
OwncloudSetup *_owncloudSetup;
|
||||
|
||||
|
@ -101,8 +86,7 @@ private:
|
|||
QMenu *_contextMenu;
|
||||
StatusDialog *_statusDialog;
|
||||
|
||||
QHash<QString, bool> _folderEnabledMap;
|
||||
|
||||
FolderMan *_folderMan;
|
||||
Theme *_theme;
|
||||
};
|
||||
|
||||
|
|
275
src/mirall/folderman.cpp
Normal file
275
src/mirall/folderman.cpp
Normal file
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* 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 <QDesktopServices>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QSettings>
|
||||
#include <QUrl>
|
||||
|
||||
#include "mirall/unisonfolder.h"
|
||||
#include "mirall/csyncfolder.h"
|
||||
#include "mirall/owncloudfolder.h"
|
||||
#include "mirall/syncresult.h"
|
||||
#include "mirall/folderman.h"
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
FolderMan::FolderMan(QObject *parent) :
|
||||
QObject(parent),
|
||||
_folderSyncCount(0)
|
||||
|
||||
{
|
||||
_folderConfigPath = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/folders";
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
FolderMan::~FolderMan()
|
||||
{
|
||||
foreach (Folder *folder, _folderMap) {
|
||||
delete folder;
|
||||
}
|
||||
}
|
||||
|
||||
Mirall::Folder::Map FolderMan::map()
|
||||
{
|
||||
return _folderMap;
|
||||
}
|
||||
|
||||
|
||||
int FolderMan::setupFolders()
|
||||
{
|
||||
QDir storageDir(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
|
||||
|
||||
// setup a handler to look for configuration changes
|
||||
_configFolderWatcher = new FolderWatcher(storageDir.path());
|
||||
connect(_configFolderWatcher, SIGNAL(folderChanged(const QStringList &)),
|
||||
this, SLOT(slotReparseConfiguration()));
|
||||
|
||||
return setupKnownFolders();
|
||||
|
||||
}
|
||||
|
||||
QString FolderMan::folderConfigPath() const
|
||||
{
|
||||
return _folderConfigPath;
|
||||
}
|
||||
|
||||
|
||||
int FolderMan::setupKnownFolders()
|
||||
{
|
||||
qDebug() << "* Setup folders from " << folderConfigPath();
|
||||
|
||||
_folderMap.clear();
|
||||
QDir dir(folderConfigPath());
|
||||
dir.setFilter(QDir::Files);
|
||||
QStringList list = dir.entryList();
|
||||
foreach (QString file, list) {
|
||||
setupFolderFromConfigFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
// filename is the name of the file only, it does not include
|
||||
// the configuration directory path
|
||||
Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
|
||||
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 folder;
|
||||
}
|
||||
|
||||
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 folder;
|
||||
}
|
||||
|
||||
QString backend = settings.value("folder/backend").toString();
|
||||
if (!backend.isEmpty()) {
|
||||
if( backend == "sitecopy") {
|
||||
qCritical() << "* sitecopy is not longer supported in this release." << endl;
|
||||
} else if (backend == "unison") {
|
||||
folder = new UnisonFolder(file,
|
||||
path.toString(),
|
||||
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 support not enabled!! ignoring:" << file;
|
||||
#endif
|
||||
} else if( backend == "owncloud" ) {
|
||||
#ifdef WITH_CSYNC
|
||||
QUrl url; // ( _owncloudSetup->fullOwnCloudUrl() );
|
||||
QString existPath = url.path();
|
||||
qDebug() << "existing path: " << existPath;
|
||||
QString newPath = settings.value("backend:owncloud/targetPath").toString();
|
||||
if( !existPath.isEmpty() ) {
|
||||
// cut off the trailing slash
|
||||
if( existPath.endsWith('/') ) {
|
||||
existPath.truncate( existPath.length()-1 );
|
||||
}
|
||||
// cut off the leading slash
|
||||
if( newPath.startsWith('/') ) {
|
||||
newPath.remove(0,1);
|
||||
}
|
||||
}
|
||||
|
||||
url.setPath( QString("%1/files/webdav.php/%2").arg(existPath).arg(newPath) );
|
||||
|
||||
folder = new ownCloudFolder( file, path.toString(),
|
||||
url.toString(),
|
||||
this );
|
||||
|
||||
|
||||
#else
|
||||
qCritical() << "* owncloud support not enabled!! ignoring:" << file;
|
||||
#endif
|
||||
}
|
||||
|
||||
else {
|
||||
qWarning() << "unknown backend" << backend;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
folder->setBackend( backend );
|
||||
folder->setOnlyOnlineEnabled(settings.value("folder/onlyOnline", false).toBool());
|
||||
folder->setOnlyThisLANEnabled(settings.value("folder/onlyThisLAN", false).toBool());
|
||||
|
||||
_folderMap[file] = folder;
|
||||
qDebug() << "Adding folder to Folder Map " << folder;
|
||||
QObject::connect(folder, SIGNAL(syncStarted()), SLOT(slotFolderSyncStarted()));
|
||||
QObject::connect(folder, SIGNAL(syncFinished(const SyncResult &)), SLOT(slotFolderSyncFinished(const SyncResult &)));
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
void FolderMan::disableFoldersWithRestore()
|
||||
{
|
||||
_folderEnabledMap.clear();
|
||||
foreach( Folder *f, _folderMap ) {
|
||||
// store the enabled state, then make sure it is disabled
|
||||
_folderEnabledMap.insert(f->alias(), f->syncEnabled());
|
||||
f->setSyncEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FolderMan::restoreEnabledFolders()
|
||||
{
|
||||
foreach( Folder *f, _folderMap ) {
|
||||
if (_folderEnabledMap.contains( f->alias() )) {
|
||||
f->setSyncEnabled( _folderEnabledMap.value( f->alias() ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FolderMan::slotEnableFolder( const QString& alias, bool enable )
|
||||
{
|
||||
if( ! _folderMap.contains( alias ) ) {
|
||||
qDebug() << "!! Can not enable alias " << alias << ", can not be found in folderMap.";
|
||||
return;
|
||||
}
|
||||
|
||||
Folder *f = _folderMap[alias];
|
||||
f->setSyncEnabled(enable);
|
||||
}
|
||||
|
||||
SyncResult FolderMan::syncResult( const QString& alias )
|
||||
{
|
||||
SyncResult res;
|
||||
if( _folderMap.contains( alias ) ) {
|
||||
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void FolderMan::slotFolderSyncStarted( )
|
||||
{
|
||||
_folderSyncCount++;
|
||||
}
|
||||
|
||||
void FolderMan::slotFolderSyncFinished( const SyncResult& )
|
||||
{
|
||||
_folderSyncCount--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a folder definition to the config
|
||||
* Params:
|
||||
* QString backend
|
||||
* QString alias
|
||||
* QString sourceFolder on local machine
|
||||
* QString targetPath on remote
|
||||
* bool onlyThisLAN, currently unused.
|
||||
*/
|
||||
Folder* FolderMan::addFolderDefinition( const QString& backend, const QString& alias,
|
||||
const QString& sourceFolder, const QString& targetPath,
|
||||
bool onlyThisLAN )
|
||||
{
|
||||
// Create a settings file named after the alias
|
||||
QSettings settings(folderConfigPath() + "/" + alias, QSettings::IniFormat);
|
||||
|
||||
settings.setValue(QString("%1/localPath").arg(alias), sourceFolder );
|
||||
settings.setValue(QString("%1/targetPath").arg(alias), targetPath );
|
||||
settings.setValue(QString("%1/backend").arg(alias), backend );
|
||||
settings.setValue(QString("%1/connection").arg(alias), QString::fromLocal8Bit("ownCloud"));
|
||||
settings.setValue(QString("%1/onlyThisLAN").arg(alias), onlyThisLAN );
|
||||
settings.sync();
|
||||
|
||||
Folder *folder = setupFolderFromConfigFile(alias);
|
||||
// setupContextMenu(); FIXME: Refresh GUI elements.
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
void FolderMan::slotRemoveFolder( const QString& alias )
|
||||
{
|
||||
if( alias.isEmpty() ) return;
|
||||
|
||||
if( _folderMap.contains( alias )) {
|
||||
qDebug() << "Removing " << alias;
|
||||
Folder *f = _folderMap.take( alias );
|
||||
delete f;
|
||||
} else {
|
||||
qDebug() << "!! Can not remove " << alias << ", not in folderMap.";
|
||||
}
|
||||
|
||||
QFile file( folderConfigPath() + "/" + alias );
|
||||
if( file.exists() ) {
|
||||
qDebug() << "Remove folder config file " << file.fileName();
|
||||
file.remove();
|
||||
}
|
||||
// FIXME: Refresh GUI elements
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#include "folderman.moc"
|
||||
|
85
src/mirall/folderman.h
Normal file
85
src/mirall/folderman.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 FOLDERMAN_H
|
||||
#define FOLDERMAN_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/folderwatcher.h"
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
class SyncResult;
|
||||
|
||||
class FolderMan : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FolderMan(QObject *parent = 0);
|
||||
~FolderMan();
|
||||
|
||||
int setupFolders();
|
||||
void disableFoldersWithRestore();
|
||||
void restoreEnabledFolders();
|
||||
|
||||
Mirall::Folder::Map map();
|
||||
|
||||
|
||||
QString folderConfigPath() const;
|
||||
/**
|
||||
* Add a folder definition to the config
|
||||
* Params:
|
||||
* QString backend
|
||||
* QString alias
|
||||
* QString sourceFolder on local machine
|
||||
* QString targetPath on remote
|
||||
* bool onlyThisLAN, currently unused.
|
||||
*/
|
||||
Folder *addFolderDefinition( const QString&, const QString&, const QString&, const QString&, bool );
|
||||
|
||||
SyncResult syncResult( const QString& );
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void slotRemoveFolder( const QString& );
|
||||
void slotEnableFolder( const QString&, bool );
|
||||
|
||||
void slotFolderSyncStarted();
|
||||
void slotFolderSyncFinished( const SyncResult& );
|
||||
|
||||
private:
|
||||
// finds all folder configuration files
|
||||
// and create the folders
|
||||
int setupKnownFolders();
|
||||
|
||||
// creates a folder for a specific
|
||||
// configuration
|
||||
Folder* setupFolderFromConfigFile(const QString & );
|
||||
|
||||
FolderWatcher *_configFolderWatcher;
|
||||
Folder::Map _folderMap;
|
||||
QHash<QString, bool> _folderEnabledMap;
|
||||
QString _folderConfigPath;
|
||||
|
||||
// counter tracking number of folders doing a sync
|
||||
int _folderSyncCount;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif // FOLDERMAN_H
|
Loading…
Reference in a new issue