- removed the sitecopy files and last references

- Fix status dialog:
 * display local and remote folder names
 * fixed status icon
 * fixed sizing when font size changes
 * fixed enable/disable buttons
- moved second path to folder base class
- added remote folder role to status dellegate
This commit is contained in:
Klaas Freitag 2012-03-26 13:20:15 +02:00
parent b9a861c95c
commit 248a0cfed8
19 changed files with 112 additions and 749 deletions

View file

@ -47,7 +47,6 @@ mirall/networklocation.cpp
mirall/temporarydir.cpp
mirall/syncresult.cpp
mirall/unisonfolder.cpp
mirall/sitecopyfolder.cpp
mirall/statusdialog.cpp
mirall/owncloudwizard.cpp
mirall/owncloudsetupwizard.cpp
@ -72,7 +71,6 @@ set(mirall_HEADERS
mirall/owncloudinfo.h
mirall/owncloudsetupwizard.h
mirall/owncloudwizard.h
mirall/sitecopyfolder.h
mirall/statusdialog.h
mirall/unisonfolder.h
mirall/theme.h

View file

@ -26,8 +26,6 @@
#include "mirall/folderwizard.h"
#include "mirall/networklocation.h"
#include "mirall/unisonfolder.h"
#include "mirall/sitecopyfolder.h"
#include "mirall/sitecopyconfig.h"
#include "mirall/owncloudfolder.h"
#include "mirall/statusdialog.h"
#include "mirall/owncloudsetupwizard.h"
@ -302,17 +300,6 @@ void Application::slotFetchFolder( const QString& alias )
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();
}
}
}
void Application::slotPushFolder( const QString& alias )
@ -326,16 +313,6 @@ void Application::slotPushFolder( const QString& alias )
Folder *f = _folderMap[alias];
if( f->backend() == "sitecopy" ) {
if( QMessageBox::question( 0, tr("Confirm Folder Push"), tr("Do you really want to push the folder with alias <i>%1</i> to your ownCloud?<br/>"
"This overwrites your remote data with data in directory <i>%2</i>!").arg(alias).arg(f->path()),
QMessageBox::Yes|QMessageBox::No ) == QMessageBox::Yes ) {
SiteCopyFolder *sf = static_cast<SiteCopyFolder*>( f );
sf->pushToOC();
} else {
qDebug() << "!! Can only fetch backend type sitecopy, this one has " << f->backend();
}
}
}
#endif
@ -400,7 +377,7 @@ void Application::slotEnableFolder(const QString& alias, const bool enable)
qDebug() << "Application: enable folder with alias " << alias;
_folderMan->slotEnableFolder( alias, enable );
_statusDialog->slotUpdateFolderState( _folderMan->folder( alias ));
slotSyncStateChange( alias );
}

View file

@ -30,8 +30,7 @@ CSyncFolder::CSyncFolder(const QString &alias,
const QString &path,
const QString &secondPath,
QObject *parent)
: Folder(alias, path, parent)
, _secondPath(secondPath)
: Folder(alias, path, secondPath, parent)
, _csync(0)
, _csyncError(false)
@ -47,11 +46,6 @@ bool CSyncFolder::isBusy() const
return false;
}
QString CSyncFolder::secondPath() const
{
return _secondPath;
}
void CSyncFolder::startSync(const QStringList &pathList)
{
if (_csync && _csync->isRunning()) {

View file

@ -34,7 +34,6 @@ public:
const QString &path,
const QString &secondPath, QObject *parent = 0L);
virtual ~CSyncFolder();
QString secondPath() const;
virtual void startSync(const QStringList &pathList);
virtual bool isBusy() const;
protected slots:
@ -43,7 +42,6 @@ protected slots:
void slotCSyncError( const QString& );
private:
bool _csyncError;
QString _secondPath;
CSyncThread *_csync;
QStringList _errors;
};

View file

@ -23,10 +23,11 @@
namespace Mirall {
Folder::Folder(const QString &alias, const QString &path, QObject *parent)
Folder::Folder(const QString &alias, const QString &path, const QString& secondPath, QObject *parent)
: QObject(parent),
_errorCount(0),
_path(path),
_secondPath(secondPath),
_pollTimer(new QTimer(this)),
_alias(alias),
_onlyOnlineEnabled(false),
@ -74,6 +75,11 @@ QString Folder::path() const
return _path;
}
QString Folder::secondPath() const
{
return _secondPath;
}
bool Folder::syncEnabled() const
{
return _enabled;
@ -88,6 +94,15 @@ void Folder::setSyncEnabled( bool doit )
if( doit && ! _pollTimer->isActive() ) {
_pollTimer->start();
}
if( doit ) {
// undefined until next sync
_syncResult.setStatus( SyncResult::Undefined );
evaluateSync( QStringList() );
} else {
// disabled.
_syncResult.setStatus( SyncResult::Disabled );
}
}
bool Folder::onlyOnlineEnabled() const

View file

@ -48,7 +48,7 @@ class Folder : public QObject
Q_OBJECT
public:
Folder(const QString &alias, const QString &path, QObject *parent = 0L);
Folder(const QString&, const QString&, const QString& , QObject*parent = 0L);
virtual ~Folder();
typedef QHash<QString, Folder*> Map;
@ -62,6 +62,7 @@ public:
* local folder path
*/
QString path() const;
virtual QString secondPath() const;
/**
* switch sync on or off
@ -167,7 +168,6 @@ protected:
#endif
int _errorCount;
private:
/**
@ -177,7 +177,7 @@ private:
void evaluateSync(const QStringList &pathList);
QString _path;
QString _secondPath;
QString _alias;
bool _onlyOnlineEnabled;
bool _onlyThisLANEnabled;

View file

@ -20,10 +20,9 @@ namespace Mirall {
GitFolder::GitFolder(const QString &alias,
const QString &path,
const QString &remote,
const QString &secondPath,
QObject *parent)
: Folder(alias, path, parent)
, _remote(remote)
: Folder(alias, path, secondPath, parent)
{
_syncProcess = new QProcess();
}

View file

@ -32,14 +32,13 @@ public:
*/
GitFolder(const QString &alias,
const QString &path,
const QString &remote, QObject *parent = 0L);
const QString &secondPath, QObject *parent = 0L);
virtual ~GitFolder();
virtual void startSync();
private:
QMutex _syncMutex;
QProcess *_syncProcess;
QString _remote;
};
}

View file

@ -33,7 +33,7 @@ ownCloudFolder::ownCloudFolder(const QString &alias,
const QString &path,
const QString &secondPath,
QObject *parent)
: Folder(alias, path, parent)
: Folder(alias, path, secondPath, parent)
, _secondPath(secondPath)
, _localCheckOnly( false )
, _csync(0)
@ -82,7 +82,15 @@ bool ownCloudFolder::isBusy() const
QString ownCloudFolder::secondPath() const
{
return _secondPath;
QString re(_secondPath);
MirallConfigFile cfg;
const QString ocUrl = cfg.ownCloudUrl(QString(), true);
qDebug() << "**** " << ocUrl << " <-> " << re;
if( re.startsWith( ocUrl ) ) {
re.remove( ocUrl );
}
return re;
}
void ownCloudFolder::startSync()

View file

@ -18,8 +18,6 @@
#include <QDesktopServices>
#include "mirall/owncloudsetupwizard.h"
#include "mirall/sitecopyconfig.h"
#include "mirall/sitecopyfolder.h"
#include "mirall/mirallwebdav.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/owncloudinfo.h"

View file

@ -1,212 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@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.
*/
#include "sitecopyconfig.h"
#include "owncloudinfo.h"
namespace Mirall {
SitecopyConfig::SitecopyConfig()
{
// file patterns to be exclude
_ExcludePatterns.append("*.bak");
_ExcludePatterns.append("*~");
_ExcludePatterns.append(".*");
_ExcludePatterns.append("\"#*#\"");
}
/*
* this uses the users ownCloud config written in mirall.cfg
*/
void SitecopyConfig::writeSiteConfig( const QString& alias, const QString& localPath, const QString& targetPath )
{
ownCloudInfo ocInfo;
writeSiteConfig( localPath, alias, ocInfo.url(), ocInfo.user(), ocInfo.password(), targetPath );
}
void SitecopyConfig::writeSiteConfig( const QString& localPath,
const QString& siteAlias, const QString& url,
const QString& user, const QString& passwd,
const QString& remoteFolder )
{
parseSiteConfig( );
qDebug() << "*** Writing Site Alias " << siteAlias;
// now all configured sites are in the hash _Sites.
foreach( QString site, _Sites.keys() ) {
qDebug() << "Known site: " << site;
}
// check if there is already a oc site.
QHash<QString, QString> ocDefs;
if( _Sites.contains( siteAlias ) ) {
ocDefs = _Sites[siteAlias];
}
qDebug() << "The url is " << url;
QUrl ocUrl( url );
QString host = ocUrl.host();
QString path = ocUrl.path();
qDebug() << "Split url, host: " << host << " and path: " << path;
// FIXME: Check if user settings are overwritten
ocDefs["server"] = host;
ocDefs["protocol"] = "webdav";
ocDefs["local"] = localPath;
// patch sent from Dominik Schmidt <dev@dominik-schmidt.de> to enable secure connection:
if( ocUrl.scheme() == "https" || ocUrl.scheme() == "webdavs" ) {
ocDefs["http"] = "secure";
}
QString webdavBase = "files/webdav.php";
if( !remoteFolder.isEmpty() && remoteFolder != "/" ) {
webdavBase += "/" + remoteFolder;
}
if( !path.endsWith( QChar('/')) ) {
webdavBase.prepend( QChar('/') );
}
ocDefs["remote"] = path + webdavBase;
if( ! passwd.isEmpty() ) {
ocDefs["password"] = passwd;
}
ocDefs["username"] = user;
_Sites.insert( siteAlias, ocDefs );
qDebug() << "** Now Writing!";
if( sitecopyConfigToFile() ) {
qDebug() << "Success in writing the sitecopy config file.";
} else {
qDebug() << "Failed to write the sitecopy config file.";
}
}
bool SitecopyConfig::sitecopyConfigToFile()
{
QFile configFile( QDir::homePath() + "/.sitecopyrc" );
if( !configFile.open( QIODevice::WriteOnly | QIODevice::Text )) {
qDebug() << "Failed to open config file to write.";
return false;
}
QTextStream out(&configFile);
foreach( QString site, _Sites.keys() ) {
QHash<QString, QString> configs = _Sites[site];
qDebug() << "Writing site: <" << site << ">";
out << "site " << site << '\n';
foreach( QString configKey, configs.keys() ) {
out << " " << configKey << " " << configs[configKey] << '\n';
qDebug() << " Setting: " << configKey << ": " << configs[configKey];
}
foreach( QString pattern, _ExcludePatterns ) {
out << " exclude " << pattern << '\n';
}
out << '\n';
}
configFile.close();
configFile.setPermissions( QFile::ReadOwner | QFile::WriteOwner );
// check if the .sitecopy dir is there, if not, create
if( !QFile::exists( QDir::homePath() + "/.sitecopy" ) ) {
QDir home( QDir::homePath() );
if( home.mkdir( ".sitecopy" ) ) {
QFile::setPermissions( QDir::homePath() + "/.sitecopy",
QFile::ReadOwner | QFile::WriteOwner | QFile::ExeUser );
}
}
return true;
}
bool SitecopyConfig::removeFolderConfig( const QString& alias )
{
bool res = false;
if( alias.isEmpty() ) return res;
if( parseSiteConfig() ) {
if( _Sites.contains( alias )) {
_Sites.remove( alias );
if( sitecopyConfigToFile() ) {
qDebug() << "Successfully removed sitecopy folder config for " << alias;
res = true;
}
} else {
qDebug() << "Can not remove alias " << alias << " - not in sitecopy config.";
}
}
return res;
}
bool SitecopyConfig::parseSiteConfig( )
{
QFile configFile( QDir::homePath() + "/.sitecopyrc" );
if( ! configFile.exists() ) {
qDebug() << "No site config file. Create one!";
return false;
}
if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
while (!configFile.atEnd()) {
QByteArray line = configFile.readLine();
processConfigLine( line.simplified() );
}
if( ! _CurrSiteName.isEmpty() ) {
_Sites.insert(_CurrSiteName, _CurrSite);
} else {
qDebug() << "ERR: No current Site name found";
return false;
}
qDebug() << "The end of parsing.";
return true;
}
void SitecopyConfig::processConfigLine( const QString& line )
{
if( line.isEmpty() ) return;
QStringList li = line.split( QRegExp( "\\s+") );
if( li.size() < 2 ) {
qDebug() << "Unable to parse line, return: " << line;
return;
}
const QString key = li[0];
const QString val = li[1];
qDebug() << "Key: " << key << ", Value " << val;
if( key == QString::fromLatin1("site") && !val.isEmpty() ) {
qDebug() << "Found site " << val;
if( !_CurrSiteName.isEmpty() && !_CurrSite.isEmpty() ) {
// save to the sites hash first
_Sites.insert( _CurrSiteName, _CurrSite );
_CurrSite.clear();
}
if( !val.isEmpty() ) {
_CurrSiteName = val;
// new site entry.
if( _Sites.contains( val ) ) {
_CurrSite = _Sites[val];
}
} else {
qDebug() << "Found empty site name, can not parse, fix manually!";
_CurrSiteName.clear();
}
} else {
_CurrSite.insert( key, val );
}
}
}

View file

@ -1,54 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@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.
*/
#ifndef SITECOPYCONFIG_H
#define SITECOPYCONFIG_H
#include <QtCore>
namespace Mirall {
class SitecopyConfig
{
public:
SitecopyConfig();
/**
* write a sitecopy config for ownCloud.
* The ownCloud config values are taken from the users ownCloud config in mirall.cfg
*/
void writeSiteConfig( const QString& alias, const QString& localPath,
const QString& targetPath );
void writeSiteConfig( const QString& localPath, const QString& siteAlias,
const QString& host, const QString& user,
const QString& passwd,
const QString& remoteFolder = QString() );
bool removeFolderConfig( const QString& );
bool parseSiteConfig();
private:
void processConfigLine( const QString& );
bool sitecopyConfigToFile();
QHash<QString, QHash<QString, QString> > _Sites;
QHash<QString, QString> _CurrSite;
// QHash<QString, QStringList> _ChangesHash;
QStringList _ExcludePatterns;
QString _CurrSiteName;
};
};
#endif // SITECOPYCONFIG_H

View file

@ -1,295 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@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.
*/
#include <QDebug>
#include <QDir>
#include <QMutexLocker>
#include <QStringList>
#include <QTextStream>
#include <QTextCodec>
#include "mirall/sitecopyfolder.h"
namespace Mirall {
SiteCopyFolder::SiteCopyFolder( const QString &alias,
const QString &path,
const QString &secondPath,
QObject *parent)
: Folder(alias, path, parent),
_SiteCopy(new QProcess(this)),
_syncCount(0),
_remotePath( secondPath )
{
QObject::connect(_SiteCopy, SIGNAL(readyReadStandardOutput()),
SLOT(slotReadyReadStandardOutput()));
QObject::connect(_SiteCopy, SIGNAL(readyReadStandardError()),
SLOT(slotReadyReadStandardError()));
QObject::connect(_SiteCopy, SIGNAL(stateChanged(QProcess::ProcessState)),
SLOT(slotStateChanged(QProcess::ProcessState)));
QObject::connect(_SiteCopy, SIGNAL(error(QProcess::ProcessError)),
SLOT(slotError(QProcess::ProcessError)));
QObject::connect(_SiteCopy, SIGNAL(started()),
SLOT(slotStarted()));
QObject::connect(_SiteCopy, SIGNAL(finished(int, QProcess::ExitStatus)),
SLOT(slotFinished(int, QProcess::ExitStatus)));
}
SiteCopyFolder::~SiteCopyFolder()
{
}
bool SiteCopyFolder::isBusy() const
{
return (_SiteCopy->state() != QProcess::NotRunning);
}
QString SiteCopyFolder::remotePath() const
{
return _remotePath;
}
void SiteCopyFolder::startSync(const QStringList &pathList)
{
QMutexLocker locker(&_syncMutex);
QFileInfo fi( SITECOPY_BIN );
if( ! fi.exists() ) {
SyncResult sr( SyncResult::SetupError );
sr.setErrorString( tr("Sitecopy is not installed!"));
this->slotSyncFinished( sr );
return;
}
emit syncStarted();
qDebug() << "PATHLIST: " << pathList;
_pathListEmpty = (pathList.count() == 0);
startSiteCopy( "--fetch", FlatList );
}
void SiteCopyFolder::fetchFromOC()
{
QMutexLocker locker( &_syncMutex );
qDebug() << "starting to sync from ownCloud";
setSyncEnabled( true );
startSiteCopy( "--fetch", Sync );
}
void SiteCopyFolder::pushToOC()
{
QMutexLocker locker( &_syncMutex );
qDebug() << "starting to sync to ownCloud";
setSyncEnabled( true );
startSiteCopy( "--update", Sync );
}
void SiteCopyFolder::startSiteCopy( const QString& command, SiteCopyState nextState )
{
if( _SiteCopy->state() == QProcess::Running ) {
qDebug() << "Process currently running - come back later.";
return;
}
if( alias().isEmpty() ) {
qDebug() << "Site name not set, can not perform commands!";
return;
}
const QString programm( SITECOPY_BIN );
QStringList args;
args << command << alias();
qDebug() << "** starting command " << args;
_NextStep = nextState;
_lastOutput.clear();
_SiteCopy->start( programm, args );
}
void SiteCopyFolder::slotStarted()
{
qDebug() << " * SiteCopy process started ( PID " << _SiteCopy->pid() << ")";
_syncCount++;
//qDebug() << _SiteCopy->readAllStandardOutput();;
}
void SiteCopyFolder::slotFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
qDebug() << " * SiteCopy process finished with status" << exitCode;
if( exitCode == -1 ) {
qDebug() << "Configuration Error, stop processing.";
SyncResult res( SyncResult::Error );
res.setErrorString( tr("Sitecopy configuration problem, check $HOME/.sitecopyrc"));
incrementErrorCount();
emit( syncFinished( res ));
}
if( exitCode > 1 ) {
// error has happened.
QString out( _lastOutput );
SyncResult res( SyncResult::Error );
res.setErrorString( out );
qDebug() << "An error happened: " << out;
incrementErrorCount();
emit syncFinished( res );
return;
}
if( _NextStep == Sync ) {
startSiteCopy( "--sync", Finish ); // sync local with cloud data.
} else if( _NextStep == Update ) {
startSiteCopy( "--update", Finish ); // update from owncloud
} else if( _NextStep == Finish ) {
qDebug() << "Finished!";
emit syncFinished( SyncResult(SyncResult::Success) );
// mLocalChangesSeen = false;
} else if( _NextStep == Status ) {
startSiteCopy( "--fetch", FlatList );
} else if( _NextStep == FlatList ) {
startSiteCopy( "--flatlist", ExecuteStatus );
} else if( _NextStep == ExecuteStatus ) {
if( exitCode == 1 ) {
qDebug() << "Exit-Code: Sync Needed!";
analyzeStatus();
if( _ChangesHash.contains("deleted") && _pathListEmpty ) {
// problem: Files were added on the cloud. If we say update,
// the new files are going to be deleted. Lets warn the user.
qDebug() << "!!!! Better not call update, changes happened on the cloud!";
SyncResult res( SyncResult::Disabled );
res.setErrorString( tr("The ownCloud changed. Disabling syncing for security reasons."));
res.setSyncChanges( _ChangesHash );
setSyncEnabled( false );
emit syncFinished( res );
} else {
startSiteCopy( "--update", Status );
}
} else if( exitCode == 0 ) {
qDebug() << "No update needed, remote is in sync.";
SyncResult res( SyncResult::Success );
// store the analyze results into the sync result data structure.
res.setSyncChanges( _ChangesHash );
// No update needed
emit syncFinished( res );
} else {
qDebug() << "Got an unknown exit code " << exitCode;
emit syncFinished( SyncResult( SyncResult::Error ) );
}
}
_lastOutput.clear();
}
void SiteCopyFolder::analyzeStatus()
{
QString out( _lastOutput );
qDebug() << "Output: " << out;
_ChangesHash.clear();
QStringList items;
QString action;
QStringList li = out.split(QChar('\n'));
foreach( QString l, li ) {
if( l.startsWith( "sectstart|") ) {
action = l.mid(10);
qDebug() << "starting to parse " << action;
}
if( l.startsWith( "sectend|")) {
action = l.mid(8);
_ChangesHash.insert( action, items );
items.clear();
}
if( l.startsWith( "item|" )) {
QString item = l.mid(5);
items << item;
}
if( l.startsWith("siteend") ) {
#if 0
if( l.endsWith("unchanged") ) {
// we are synced and don't do anything
// emit statusChange( Unchanged );
// FIXME: Bug handling
emit syncFinished( SyncResult(SyncResult::Success) );
} else if( l.endsWith("changed")) {
startSiteCopy( "--update", Status );
if( mLocalChangesSeen ) {
// emit statusChange( SyncToNeeded );
} else {
// emit statusChange( SyncFromNeeded );
}
}
#endif
}
}
}
void SiteCopyFolder::slotReadyReadStandardOutput()
{
QByteArray arr = _SiteCopy->readAllStandardOutput();
if( _NextStep == Finish ) {
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
// render the output to status line
QString string = codec->toUnicode( arr );
int pos = string.indexOf( QChar('\n'));
if( pos > -1 ) {
QString newLine = string.mid( 1+pos );
_StatusString = newLine;
} else {
// no newline, append to the status string
_StatusString.append( string );
}
emit statusString( _StatusString );
} else { /* if( _NextStep == DisplayStatus ) { */
_lastOutput += arr;
}
// QTextStream stream(&_lastOutput);
// stream << _SiteCopy->readAllStandardOutput();;
}
void SiteCopyFolder::slotReadyReadStandardError()
{
QTextStream stream(&_lastOutput);
stream << _SiteCopy->readAllStandardError();
}
void SiteCopyFolder::slotStateChanged(QProcess::ProcessState state)
{
//qDebug() << "changed: " << state;
}
void SiteCopyFolder::slotError(QProcess::ProcessError error)
{
//qDebug() << "error: " << error;
}
} // ns

View file

@ -1,84 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@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.
*/
#ifndef MIRALL_SiteCopyFOLDER_H
#define MIRALL_SiteCopyFOLDER_H
#include <QMutex>
#include <QProcess>
#include <QStringList>
#include "mirall/folder.h"
#define SITECOPY_BIN "/usr/bin/sitecopy"
class QProcess;
namespace Mirall {
class SiteCopyFolder : public Folder
{
Q_OBJECT
public:
enum SiteCopyState { Sync, Update, Finish, Status, FlatList, ExecuteStatus };
SiteCopyFolder(const QString &alias,
const QString &path,
const QString &secondPath, QObject *parent = 0L);
virtual ~SiteCopyFolder();
virtual void startSync(const QStringList &pathList);
// load data from ownCloud to the local directory.
void fetchFromOC();
// push data from the local directory to ownCloud
void pushToOC();
virtual bool isBusy() const;
QString remotePath() const;
signals:
void statusString( const QString& );
protected slots:
void slotReadyReadStandardOutput();
void slotReadyReadStandardError();
void slotStateChanged(QProcess::ProcessState);
void slotFinished(int exitCode, QProcess::ExitStatus exitStatus);
void slotStarted();
void slotError(QProcess::ProcessError);
void startSiteCopy( const QString&, SiteCopyState );
void analyzeStatus();
private:
QMutex _syncMutex;
QProcess *_SiteCopy;
int _syncCount;
bool _pathListEmpty;
QByteArray _lastOutput;
QString _StatusString;
QString _remotePath;
SiteCopyState _NextStep;
QString _siteCopyAlias;
QHash<QString, QStringList> _ChangesHash;
};
}
#endif

View file

@ -61,14 +61,30 @@ FolderViewDelegate::~FolderViewDelegate()
QSize FolderViewDelegate::sizeHint(const QStyleOptionViewItem & option ,
const QModelIndex & index) const
{
int h = 70; // height 64 + 4px margin top and down
int w = 0;
QString p = qvariant_cast<QString>(index.data(FolderPathRole));
QFont aliasFont = QApplication::font();
QFont font = QApplication::font();
aliasFont.setPointSize( font.pointSize() +2 );
QFontMetrics fm(font);
QFontMetrics aliasFm(aliasFont);
w = 8 + fm.boundingRect( p ).width();
// calc height
int h = aliasFm.height()/2; // margin to top
h += aliasFm.height(); // alias
h += fm.height()/2; // between alias and local path
h += fm.height(); // local path
h += fm.height()/2; // between local and remote path
h += fm.height(); // remote path
h += aliasFm.height()/2; // bottom margin
int minHeight = 48 + fm.height()/2 + fm.height()/2; // icon + margins
if( h < minHeight ) h = minHeight;
return QSize( w, h );
}
@ -77,58 +93,64 @@ void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
{
QStyledItemDelegate::paint(painter,option,index);
QSize s = sizeHint( option, index );
painter->save();
QFont font = QApplication::font();
QFont aliasFont = QApplication::font();
QFont subFont = QApplication::font();
//font.setPixelSize(font.weight()+);
font.setBold(true);
subFont.setWeight(subFont.weight() - 4);
QFontMetrics fm(font);
aliasFont.setBold(true);
aliasFont.setPointSize( subFont.pointSize()+2 );
QFontMetrics subFm( subFont );
QFontMetrics aliasFm( aliasFont );
QIcon icon = qvariant_cast<QIcon>(index.data(FolderIconRole));
QIcon statusIcon = qvariant_cast<QIcon>(index.data(FolderStatusIcon));
QString aliasText = qvariant_cast<QString>(index.data(FolderAliasRole));
QString pathText = qvariant_cast<QString>(index.data(FolderPathRole));
QString remotePath = qvariant_cast<QString>(index.data(FolderSecondPathRole));
QString statusText = qvariant_cast<QString>(index.data(FolderStatus));
bool syncEnabled = index.data(FolderSyncEnabled).toBool();
QString syncStatus = syncEnabled? tr( "Enabled" ) : tr( "Disabled" );
QSize iconsize(48,48); // = icon.actualSize(option.decorationSize);
QRect headerRect = option.rect;
QRect aliasRect = option.rect;
QRect iconRect = option.rect;
iconRect.setRight(iconsize.width()+30);
iconRect.setTop(iconRect.top()+5);
headerRect.setLeft(iconRect.right());
headerRect.setTop(headerRect.top()+5);
headerRect.setBottom(headerRect.top()+fm.height());
iconRect.setRight( iconsize.width()+30 );
iconRect.setTop( iconRect.top() + (iconRect.height()-iconsize.height())/2);
aliasRect.setLeft(iconRect.right());
QRect subheaderRect = headerRect;
subheaderRect.setTop(headerRect.bottom());
QFontMetrics fmSub( subFont );
subheaderRect.setBottom(subheaderRect.top()+fmSub.height());
QRect statusRect = subheaderRect;
statusRect.setTop( subheaderRect.bottom() + 5);
statusRect.setBottom( statusRect.top() + fmSub.height());
aliasRect.setTop(aliasRect.top() + aliasFm.height()/2 );
aliasRect.setBottom(aliasRect.top()+subFm.height());
QRect lastSyncRect = statusRect;
lastSyncRect.setTop( statusRect.bottom());
lastSyncRect.setBottom( lastSyncRect.top() + fmSub.height());
// local directory box
QRect localPathRect = aliasRect;
localPathRect.setTop(aliasRect.bottom() + subFm.height() / 2);
localPathRect.setBottom(localPathRect.top()+subFm.height());
// remote directory box
QRect remotePathRect = localPathRect;
remotePathRect.setTop( localPathRect.bottom() + subFm.height()/2 );
remotePathRect.setBottom( remotePathRect.top() + subFm.height());
//painter->drawPixmap(QPoint(iconRect.right()/2,iconRect.top()/2),icon.pixmap(iconsize.width(),iconsize.height()));
painter->drawPixmap(QPoint(iconRect.left()+15,iconRect.top()),icon.pixmap(iconsize.width(),iconsize.height()));
painter->drawPixmap(QPoint(option.rect.right() - 4 - 48, option.rect.top() + 8 ), statusIcon.pixmap( 48,48));
painter->drawPixmap(QPoint(option.rect.right() - 4 - 48, option.rect.top() + (option.rect.height()-48)/2 ), statusIcon.pixmap(48,48));
painter->setFont(font);
painter->drawText(headerRect, aliasText);
painter->setFont(aliasFont);
painter->drawText(aliasRect, aliasText);
painter->setFont(subFont);
painter->drawText(subheaderRect.left(),subheaderRect.top()+17, pathText);
painter->drawText(lastSyncRect, tr("Last Sync: %1").arg( statusText ));
painter->drawText(statusRect, tr("Sync Status: %1").arg( syncStatus ));
painter->drawText(localPathRect.left(),localPathRect.top()+17, pathText);
painter->drawText(remotePathRect, tr("Remote path: %1").arg(remotePath));
// painter->drawText(lastSyncRect, tr("Last Sync: %1").arg( statusText ));
// painter->drawText(statusRect, tr("Sync Status: %1").arg( syncStatus ));
painter->restore();
}
@ -247,24 +269,29 @@ void StatusDialog::slotUpdateFolderState( Folder *folder )
}
if( item ) {
folderToModelItem( item, folder );
} else {
qDebug() << " OO Error: did not find model item for folder " << folder->alias();
}
}
void StatusDialog::folderToModelItem( QStandardItem *item, Folder *f )
{
QIcon icon = _theme->folderIcon( f->backend(), 48 );
item->setData( icon, FolderViewDelegate::FolderIconRole );
item->setData( f->path(), FolderViewDelegate::FolderPathRole );
item->setData( f->alias(), FolderViewDelegate::FolderAliasRole );
item->setData( icon, FolderViewDelegate::FolderIconRole );
item->setData( f->path(), FolderViewDelegate::FolderPathRole );
item->setData( f->secondPath(), FolderViewDelegate::FolderSecondPathRole );
item->setData( f->alias(), FolderViewDelegate::FolderAliasRole );
item->setData( f->syncEnabled(), FolderViewDelegate::FolderSyncEnabled );
qDebug() << "***** Folder is SyncEnabled: " << f->syncEnabled();
SyncResult res = f->syncResult();
SyncResult::Status status = res.status();
qDebug() << "Folder state is now " << status;
QString errors = res.errorStrings().join("<br/>");
item->setData( _theme->syncStateIcon( status, 64 ), FolderViewDelegate::FolderStatusIcon );
item->setData( _theme->statusHeaderText( status ), Qt::ToolTipRole );
item->setData( _theme->syncStateIcon( status, 48 ), FolderViewDelegate::FolderStatusIcon );
item->setData( _theme->statusHeaderText( status ), FolderViewDelegate::FolderStatus );
item->setData( errors, FolderViewDelegate::FolderErrorMsg );
}
@ -316,6 +343,9 @@ void StatusDialog::slotEnableFolder()
qDebug() << "Toggle enabled/disabled Folder alias " << alias << " - current state: " << folderEnabled;
if( !alias.isEmpty() ) {
emit(enableFolderAlias( alias, !folderEnabled ));
// set the button text accordingly.
slotFolderActivated( selected );
}
}
}

View file

@ -45,14 +45,15 @@ class FolderViewDelegate : public QStyledItemDelegate
FolderViewDelegate();
virtual ~FolderViewDelegate();
enum datarole { FolderAliasRole = Qt::UserRole + 100,
FolderPathRole = Qt::UserRole + 101,
FolderIconRole = Qt::UserRole + 102,
FolderRemotePath = Qt::UserRole + 103,
FolderStatus = Qt::UserRole + 104,
FolderErrorMsg = Qt::UserRole + 105,
FolderStatusIcon = Qt::UserRole + 106,
FolderSyncEnabled = Qt::UserRole + 107
enum datarole { FolderAliasRole = Qt::UserRole + 100,
FolderPathRole = Qt::UserRole + 101,
FolderSecondPathRole = Qt::UserRole + 102,
FolderIconRole = Qt::UserRole + 103,
FolderRemotePath = Qt::UserRole + 104,
FolderStatus = Qt::UserRole + 105,
FolderErrorMsg = Qt::UserRole + 106,
FolderStatusIcon = Qt::UserRole + 107,
FolderSyncEnabled = Qt::UserRole + 108
};
void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const;
QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const;

View file

@ -69,19 +69,19 @@ QString Theme::statusHeaderText( SyncResult::Status status ) const
QString resultStr;
if( status == SyncResult::NotYetStarted ) {
resultStr = tr("Not yet started");
resultStr = tr("Sync has not yet started");
} else if( status == SyncResult::SyncRunning ) {
resultStr = tr("Sync running");
resultStr = tr("Sync is running");
} else if( status == SyncResult::Success ) {
resultStr = tr("Success");
resultStr = tr("Sync Success");
} else if( status == SyncResult::Error ) {
resultStr = tr("Error");
resultStr = tr("Sync Error");
} else if( status == SyncResult::Disabled ) {
resultStr = tr("Disabled");
resultStr = tr("Sync Disabled");
} else if( status == SyncResult::SetupError ) {
resultStr = tr( "Setup Error" );
} else {
resultStr = tr("Undefined");
resultStr = tr("Status undefined");
}
return resultStr;
}

View file

@ -26,9 +26,8 @@ namespace Mirall {
const QString &path,
const QString &secondPath,
QObject *parent)
: Folder(alias, path, parent),
: Folder(alias, path, secondPath, parent),
_unison(new QProcess(this)),
_secondPath(secondPath),
_syncCount(0)
{
QObject::connect(_unison, SIGNAL(readyReadStandardOutput()),
@ -59,11 +58,6 @@ bool UnisonFolder::isBusy() const
return (_unison->state() != QProcess::NotRunning);
}
QString UnisonFolder::secondPath() const
{
return _secondPath;
}
void UnisonFolder::startSync(const QStringList &pathList)
{
QMutexLocker locker(&_syncMutex);

View file

@ -34,8 +34,6 @@ public:
const QString &secondPath, QObject *parent = 0L);
virtual ~UnisonFolder();
QString secondPath() const;
virtual void startSync(const QStringList &pathList);
virtual bool isBusy() const;
@ -50,7 +48,6 @@ protected slots:
private:
QMutex _syncMutex;
QProcess *_unison;
QString _secondPath;
int _syncCount;
QString _lastOutput;