mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2026-04-07 01:34:16 +02:00
Compare commits
106 Commits
v1.3.0-bet
...
v1.3.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b206a3b8e2 | ||
|
|
3bff5a061b | ||
|
|
0bc9b6f44e | ||
|
|
905f70a186 | ||
|
|
a8707b681d | ||
|
|
5d8f9f5346 | ||
|
|
a441b1d562 | ||
|
|
6e2042cd55 | ||
|
|
bb8b58dc66 | ||
|
|
9cd099056b | ||
|
|
0adbc032ae | ||
|
|
22a679fb8c | ||
|
|
35a67fab0a | ||
|
|
fdc8117211 | ||
|
|
24208e6137 | ||
|
|
46c7026726 | ||
|
|
01ad3c4d81 | ||
|
|
4ac98bde73 | ||
|
|
f42a6d6ef6 | ||
|
|
9055c6ade7 | ||
|
|
1356a5bbaa | ||
|
|
3c320c2736 | ||
|
|
969757199e | ||
|
|
60f1c65a48 | ||
|
|
b87b0e16e6 | ||
|
|
8ed0b1be55 | ||
|
|
91b5f1076f | ||
|
|
8ec2457965 | ||
|
|
82d79b1188 | ||
|
|
e33601becd | ||
|
|
334443adbb | ||
|
|
99579e8a2a | ||
|
|
89438f7ace | ||
|
|
d323ec5dd9 | ||
|
|
bb5cf37330 | ||
|
|
4b0bdd648c | ||
|
|
5588fbe695 | ||
|
|
12ea381205 | ||
|
|
99fbf25fb2 | ||
|
|
b37645e14d | ||
|
|
1ec5a1aaa2 | ||
|
|
3eb7acde25 | ||
|
|
e53e39cfad | ||
|
|
1a17f40233 | ||
|
|
10094a997a | ||
|
|
2af38b093f | ||
|
|
b03c168175 | ||
|
|
1c6bc84d2d | ||
|
|
541239c17b | ||
|
|
74b4ade15a | ||
|
|
205502fd3b | ||
|
|
54e4217216 | ||
|
|
d2579a7754 | ||
|
|
76580840dd | ||
|
|
779e59156c | ||
|
|
b0f0d0b1cd | ||
|
|
858dcb53bd | ||
|
|
9d7db88fcb | ||
|
|
2099b7c6a0 | ||
|
|
4442564ad2 | ||
|
|
12148b5c9b | ||
|
|
d7d77a49fc | ||
|
|
b70c2f5c20 | ||
|
|
033249423f | ||
|
|
0c959e8661 | ||
|
|
79785241ea | ||
|
|
0090862313 | ||
|
|
a4a68c6622 | ||
|
|
49b4c341ae | ||
|
|
7c1f91abdd | ||
|
|
1f2ba7e254 | ||
|
|
8014bcb7c4 | ||
|
|
b1c8bf5954 | ||
|
|
0eb6740bac | ||
|
|
96531b548a | ||
|
|
f3371360ed | ||
|
|
c1b92f9fed | ||
|
|
b028ca0738 | ||
|
|
a9aab30d55 | ||
|
|
efbad3a3c8 | ||
|
|
b6ed959f98 | ||
|
|
477953f965 | ||
|
|
aaf59cece5 | ||
|
|
e88b7e8ec2 | ||
|
|
078b09b5f4 | ||
|
|
0d06fe764a | ||
|
|
94f8c39a9e | ||
|
|
7d1bd9da86 | ||
|
|
ed8cdf6910 | ||
|
|
7ee83847c8 | ||
|
|
52eca1362f | ||
|
|
eec1af09c4 | ||
|
|
c651c8cbf9 | ||
|
|
da6a398624 | ||
|
|
1418512a9f | ||
|
|
dd2859880b | ||
|
|
f38d8ba2e4 | ||
|
|
fdd52a2520 | ||
|
|
e2c0792043 | ||
|
|
e8889530b0 | ||
|
|
23f67d950a | ||
|
|
0bd1f507ab | ||
|
|
2bcfc143f6 | ||
|
|
9dc21bf8a3 | ||
|
|
70f627ba06 | ||
|
|
0683c26d41 |
@@ -1,6 +1,6 @@
|
||||
set( VERSION_MAJOR 1 )
|
||||
set( VERSION_MINOR 3 )
|
||||
set( VERSION_PATCH 0 )
|
||||
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX}beta1)
|
||||
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX}beta4)
|
||||
set( SOVERSION 0 )
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'ownCloud Client Manual'
|
||||
copyright = u'2012, The ownCloud developers'
|
||||
copyright = u'2013, The ownCloud developers'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@@ -215,8 +215,6 @@ latex_documents = [
|
||||
man_pages = [
|
||||
('owncloud.1', 'owncloud', u'File synchronisation desktop utility.',
|
||||
[u'The ownCloud developers'], 1),
|
||||
('mirall.1', 'mirall', u'File synchronisation desktop utility.',
|
||||
[u'The ownCloud developers'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
@@ -250,7 +248,7 @@ texinfo_documents = [
|
||||
epub_title = u'ownCloud Client Manual'
|
||||
epub_author = u'The ownCloud developers'
|
||||
epub_publisher = u'The ownCloud developers'
|
||||
epub_copyright = u'2012, The ownCloud developers'
|
||||
epub_copyright = u'2013, The ownCloud developers'
|
||||
|
||||
# The language of the text. It defaults to the language option
|
||||
# or en if the language is not set.
|
||||
|
||||
@@ -16,8 +16,6 @@ It contains settings in the ini file format known from Windows.
|
||||
|
||||
.. note:: Changes may be overwritten by using ownCloud's configuration dialog.
|
||||
|
||||
.. note:: The new version is less precise in this regard.
|
||||
|
||||
These are config settings that may be changed:
|
||||
|
||||
``remotePollinterval`` (default: ``30000``)
|
||||
@@ -26,6 +24,3 @@ These are config settings that may be changed:
|
||||
``maxLogLines`` (default: ``20000``)
|
||||
Maximum count of log lines shown in the log window
|
||||
|
||||
``remotePollinterval``
|
||||
The frequency used for polling for remote changes on the ownCloud Server.
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ Mac OS X
|
||||
Installing the ownCloud client on your Mac follows the normal app installation
|
||||
pattern:
|
||||
|
||||
1. Download the installation file Click ownCloud-1.1.1.dmg, a window with the
|
||||
1. Download the installation file Click ownCloud-x.y.z.dmg, a window with the
|
||||
2. ownCloud icon opens In that window, drag the ownCloud application into the
|
||||
3. ‘Applications’ folder on the right hand side From ‘Applications’, choose
|
||||
ownCloud
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
mirall(1)
|
||||
---------
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
*mirall* [`OPTIONS`...]
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
mirall is a file synchronisation desktop utility.
|
||||
It synchronizes files on your local machine with an ownCloud Server. If you
|
||||
make a change to the files on one computer, it will flow across the others
|
||||
using this desktop sync clients.
|
||||
|
||||
Normally you start the client by click on the desktop icon or start from the
|
||||
application menu. After starting an ownCloud icon appears in the system tray.
|
||||
|
||||
Options
|
||||
=======
|
||||
.. include:: options.rst
|
||||
|
||||
Config File
|
||||
===========
|
||||
.. include:: conffile.rst
|
||||
|
||||
BUGS
|
||||
====
|
||||
|
||||
Please report bugs at https://github.com/owncloud/core/issues.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
`csync(1)`, `mirall(1)`
|
||||
|
||||
@@ -3,8 +3,11 @@ ownCloud Client supports the following command line switches:
|
||||
``--logwindow``
|
||||
open a window to show log output at startup.
|
||||
|
||||
``--logfile`` `<filename>`
|
||||
write log output to file.
|
||||
``--logfile`` `<file>`
|
||||
write log output to a single file
|
||||
|
||||
``--logdir`` `<dir>`
|
||||
write log output to dir, one for each sync run.
|
||||
|
||||
``--flushlog``
|
||||
flush the log file after every write.
|
||||
@@ -12,4 +15,3 @@ ownCloud Client supports the following command line switches:
|
||||
``--monoicons``
|
||||
Use black/white pictograms for systray.
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ SYNOPSIS
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
owncloud is a file synchronisation desktop utility it is based on mirall.
|
||||
ownCloud is a file synchronisation desktop utility based on mirall.
|
||||
It synchronizes files on your local machine with an ownCloud Server. If you
|
||||
make a change to the files on one computer, it will flow across the others
|
||||
using this desktop sync clients.
|
||||
@@ -33,5 +33,5 @@ Please report bugs at https://github.com/owncloud/core/issues.
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
`csync(1)`, `mirall(1)`
|
||||
`csync(1)`
|
||||
|
||||
|
||||
@@ -4,9 +4,12 @@ Doc Build Convenience Scripts
|
||||
* ``htmlhelp.sh``: A script to install Microsoft HTML Workshop on Linux or Mac OS using Wine, along with some dependencies.
|
||||
* ``htmlhelp.reg``: Registry file to override some DLLs with their native version and set the right Windows version.
|
||||
|
||||
Those files have been taken from the HTML Help Project (http://code.google.com/p/htmlhelp/wiki/HHW4Wine).
|
||||
Those files have been taken from the `HTML Help Project`_.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
The HTML Help Project has licensed its software under LGPLv3 terms.
|
||||
The HTML Help Project has licensed_ its software under LGPLv2.1 terms
|
||||
|
||||
.. _HTML Help Project: http://code.google.com/p/htmlhelp/wiki/HHW4Wine
|
||||
.. _licensed: https://code.google.com/p/htmlhelp/source/browse/trunk/pyhtmlhelp/COPYING
|
||||
|
||||
@@ -6,9 +6,10 @@ basic reasons: Either the server setup has a problem or the client
|
||||
has a bug. When reporting bugs, it is crucial to find out what part
|
||||
of the system causes the problem.
|
||||
|
||||
Here are a couple of useful steps to isolate the problem.
|
||||
Identifying basic functionality problems
|
||||
----------------------------------------
|
||||
|
||||
:A general ownCloud Server test:
|
||||
:Perform a general ownCloud Server test:
|
||||
A very first check is to verify that you can log on to ownClouds web
|
||||
application. Assuming your ownCloud instance is installed at
|
||||
``http://yourserver.com/owncloud``, type
|
||||
@@ -18,8 +19,12 @@ Here are a couple of useful steps to isolate the problem.
|
||||
see a red warning box on the page, your server setup is not correct or needs
|
||||
fixes. Please verify that your server installation is working correctly.
|
||||
|
||||
:All desktop clients fail to connect to ownCloud:
|
||||
The ownCloud syncing use the built in WebDAV server of ownCloud.
|
||||
:Ensure the WebDAV API is working:
|
||||
If all desktop clients fail to connect to ownCloud, but the access via the
|
||||
web interface works, the problem often is a mis-configuration of the WebDAV
|
||||
API.
|
||||
|
||||
The ownCloud client uses the built-in WebDAV access of the server content.
|
||||
Verify that you can log on to ownClouds WebDAV server. Assuming your ownCloud
|
||||
instance is installed at ``http://yourserver.com/owncloud``, type
|
||||
``http://yourserver.com/owncloud/remote.php/webdav`` into your browsers
|
||||
@@ -31,17 +36,38 @@ Here are a couple of useful steps to isolate the problem.
|
||||
|
||||
:Use a WebDAV command line tool to test:
|
||||
A more sophisticated test is to use a WebDAV command line client and log
|
||||
into the ownCloud WebDAV server, such as a little app called cadaver, available
|
||||
on Linux. It can be used to further verify that the WebDAV server is running
|
||||
properly, for example by performing PROPFIND calls:
|
||||
into the ownCloud WebDAV server, such as a little app called cadaver,
|
||||
available on Linux. It can be used to further verify that the WebDAV server is
|
||||
running properly, for example by performing PROPFIND calls:
|
||||
|
||||
``propget .`` called within cadaver will return some properties of the current
|
||||
directory and thus be a successful WebDAV connect.
|
||||
|
||||
Isolating other issues
|
||||
----------------------
|
||||
|
||||
If the sync result is unreliable, please ensure that the folder synced with
|
||||
ownCloud is not shared with other syncing apps.
|
||||
|
||||
.. note:: Syncing the same directory with ownCloud and other sync software such
|
||||
as Unison, rsync, Microsoft Windows Offline Folders or cloud services
|
||||
such as DropBox or Microsoft SkyDrive is not supported and should
|
||||
not be attempted. In the worst case, doing so can result in data
|
||||
loss.
|
||||
|
||||
If you are operating your own server and use the local storage backend (the
|
||||
default), make sure that ownCloud has exclusive access to the directory.
|
||||
|
||||
.. note:: The data directory on the server is exclusive to ownCloud and must
|
||||
not be modified manually.
|
||||
|
||||
If you are using a different backend, you can try to exclude a bug in the
|
||||
backend by reverting to the local backend.
|
||||
|
||||
Logfiles
|
||||
========
|
||||
|
||||
Doing effective debugging requires to provide as much as relevant logfiles as
|
||||
Doing effective debugging requires to provide as much as relevant logs as
|
||||
possible. The log output can help you with tracking down problem, and if you
|
||||
report a bug, you're advised to include the output.
|
||||
|
||||
@@ -57,23 +83,27 @@ starting the client again with this parameter. Syntax:
|
||||
* Mac OS X: ``/Applications/owncloud.app/Contents/MacOS/owncloud --logwindow``
|
||||
* Linux: ``owncloud --logwindow``
|
||||
|
||||
It is also possible to directly log into a file, which is an useful option
|
||||
It is also possible to directly log to a directory, which is an useful option
|
||||
in case the problem only happens ocassionally. In that case it is better to
|
||||
create a huge logfile than piping the whole log through the log window.
|
||||
create a huge amount of data, as the log window has a limited buffer.
|
||||
|
||||
To create a log file, start the client with ``--logfile <filename>``.
|
||||
To write logs to disk, start the client with ``--logfile <file>``, where
|
||||
``<file`` is the file you want to log to, or ``--logdir <dir>``, where ``<dir>``
|
||||
is an existing directory. In case of ``--logdir``, each sync run will create a
|
||||
new file.
|
||||
|
||||
:ownCloud server Logfile:
|
||||
The ownCloud server maintains an ownCloud specific logfile as well. It can and
|
||||
must be enabled through the ownCloud Administration page. There you can adjust
|
||||
the loglevel. It is advisable to set it to a verbose level like ``Debug`` or ``Info``.
|
||||
the loglevel. It is advisable to set it to a verbose level like ``Debug`` or
|
||||
``Info``.
|
||||
|
||||
The logfile can be viewed either in the web interface or can be found in the
|
||||
filesystem in the ownCloud server data dir.
|
||||
|
||||
:Webserver Logfiles:
|
||||
Also, please take a look at your webservers error log file to check if there
|
||||
are problems. For apache on linux, the error logs usually can be found at
|
||||
are problems. For Apache on Linux, the error logs usually can be found at
|
||||
``/var/log/apache2``. A file called ``error_log`` shows errors like PHP code
|
||||
problems. A file called ``access_log`` usually records all requests handled
|
||||
by the server. Especially the access_log is a very good debugging tool as the
|
||||
@@ -82,4 +112,3 @@ log line contains a lot of information of every request and it's result.
|
||||
More information about the apache logging can be found at
|
||||
``http://httpd.apache.org/docs/current/logs.html``.
|
||||
|
||||
|
||||
|
||||
@@ -7,11 +7,42 @@ application menu. In the system tray, an ownCloud icon appears.
|
||||
|
||||
.. index:: start application
|
||||
|
||||
A left click on the tray icon open a status dialog which gives an overview on
|
||||
the configured sync folders and allows to add and remove more sync folder
|
||||
connections as well as pausing a sync connection.
|
||||
Overview
|
||||
--------
|
||||
|
||||
A right click on the tray icon gives other configuration options.
|
||||
ownCloud is represented by an icon in the Desktop's system tray, also known
|
||||
as notification area.
|
||||
|
||||
The clients menu is accessed with a right click (Windows, Linux) or left click
|
||||
(Mac OS).
|
||||
|
||||
The status of the current sync can be observed in the Status dialog, available
|
||||
trough the ``Open status...`` option. On Windows, a left click on the tray icon
|
||||
also opens the status dialog.
|
||||
|
||||
.. note:: Until the intial setup has finished, the Connection Wizard will be
|
||||
shown instead when left-clicking on Windows.
|
||||
|
||||
The dialog provides an overview on the configured sync folders and allows to add
|
||||
and remove more sync folder connections as well as pausing a sync connection.
|
||||
|
||||
Changing your password
|
||||
----------------------
|
||||
|
||||
Use the ``Configure`` option. It will open the Connection Wizard, which next to
|
||||
reconfiguring your connection to use a different user or server also will allow
|
||||
to change the password for the local account, or to switch from HTTP to HTTPS.
|
||||
|
||||
Setting up a proxy
|
||||
------------------
|
||||
|
||||
By default, the configured system proxy will be picked up. This may not be
|
||||
working reliable on some Linux distributions, as only the ``http_proxy``
|
||||
variable gets parsed. You can configure a proxy different from your
|
||||
system default by choosing ``Configure proxy...`` from the menu.
|
||||
|
||||
By default, ownCloud expects a HTTP proxy. If you want to specify a SOCKS5
|
||||
proxy instead, tick the "Use as SOCKSv5 proxy" option.
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
@@ -20,6 +20,8 @@ PHP version:
|
||||
|
||||
ownCloud version:
|
||||
|
||||
Storage backend:
|
||||
|
||||
### Client configuration
|
||||
Client version:
|
||||
|
||||
@@ -31,18 +33,14 @@ Installation path of client:
|
||||
|
||||
### Logs
|
||||
|
||||
#### output of `owncloud --logwindow` or `owncloud --logfile log.txt`
|
||||
```
|
||||
Insert your log output here
|
||||
```
|
||||
Please use Gist (https://gist.github.com/) or a similar code paster for longer
|
||||
logs.
|
||||
|
||||
#### Web server error log
|
||||
```
|
||||
Insert your webserver log here
|
||||
```
|
||||
```Template for output < 10 lines```
|
||||
|
||||
#### ownCloud log (data/owncloud.log)
|
||||
```
|
||||
Insert your ownCloud log here
|
||||
```
|
||||
1. Output of `owncloud --logwindow` or `owncloud --logfile log.txt`
|
||||
|
||||
2. Web server error log:
|
||||
|
||||
3. ownCloud log (data/owncloud.log):
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<file>resources/folder-grey.png</file>
|
||||
<file>resources/task-ongoing.png</file>
|
||||
<file>resources/view-refresh.png</file>
|
||||
<file>resources/warning-16.png</file>
|
||||
<file>resources/owncloud_logo_blue.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
BIN
resources/warning-16.png
Normal file
BIN
resources/warning-16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 596 B |
22
src/3rdparty/LGPL_EXCEPTION.txt
vendored
Normal file
22
src/3rdparty/LGPL_EXCEPTION.txt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Digia Qt LGPL Exception version 1.1
|
||||
|
||||
As an additional permission to the GNU Lesser General Public License version
|
||||
2.1, the object code form of a "work that uses the Library" may incorporate
|
||||
material from a header file that is part of the Library. You may distribute
|
||||
such object code under terms of your choice, provided that:
|
||||
(i) the header files of the Library have not been modified; and
|
||||
(ii) the incorporated material is limited to numerical parameters, data
|
||||
structure layouts, accessors, macros, inline functions and
|
||||
templates; and
|
||||
(iii) you comply with the terms of Section 6 of the GNU Lesser General
|
||||
Public License version 2.1.
|
||||
|
||||
Moreover, you may apply this exception to a modified version of the Library,
|
||||
provided that such modification does not involve copying material from the
|
||||
Library into the modified Library's header files unless such material is
|
||||
limited to (i) numerical parameters; (ii) data structure layouts;
|
||||
(iii) accessors; and (iv) small macros, templates and inline functions of
|
||||
five lines or less in length.
|
||||
|
||||
Furthermore, you are not required to apply this additional permission to a
|
||||
modified version of the Library.
|
||||
@@ -29,12 +29,15 @@
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/updatedetector.h"
|
||||
#include "mirall/proxydialog.h"
|
||||
#include "mirall/version.h"
|
||||
#include "mirall/credentialstore.h"
|
||||
#include "mirall/logger.h"
|
||||
|
||||
#include "mirall/inotify.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QHash>
|
||||
@@ -51,10 +54,26 @@ namespace Mirall {
|
||||
void mirallLogCatcher(QtMsgType type, const char *msg)
|
||||
{
|
||||
Q_UNUSED(type)
|
||||
Logger::instance()->mirallLog( QString::fromUtf8(msg) );
|
||||
// qDebug() exports to local8Bit, which is not always UTF-8
|
||||
Logger::instance()->mirallLog( QString::fromLocal8Bit(msg) );
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
static const char optionsC[] =
|
||||
"Options:\n"
|
||||
" -h --help : show this help screen.\n"
|
||||
" --logwindow : open a window to show log output.\n"
|
||||
" --logfile <filename> : write log output to file <filename>.\n"
|
||||
" --logdir <name> : write each sync log output in a new file\n"
|
||||
" in directory <name>.\n"
|
||||
" --logexpire <hours> : removes logs older than <hours> hours.\n"
|
||||
" (to be used with --logdir)\n"
|
||||
" --logflush : flush the log file after every write.\n"
|
||||
" --monoicons : Use black/white pictograms for systray.\n"
|
||||
" --confdir <dirname> : Use the given configuration directory.\n"
|
||||
;
|
||||
|
||||
QString applicationTrPath()
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
@@ -83,11 +102,13 @@ Application::Application(int &argc, char **argv) :
|
||||
_theme(Theme::instance()),
|
||||
_updateDetector(0),
|
||||
_logBrowser(0),
|
||||
_logExpire(0),
|
||||
_showLogWindow(false),
|
||||
_logFlush(false),
|
||||
_helpOnly(false),
|
||||
_fileItemDialog(0),
|
||||
_statusDialog(0)
|
||||
_statusDialog(0),
|
||||
_folderWizard(0)
|
||||
{
|
||||
setApplicationName( _theme->appNameGUI() );
|
||||
setWindowIcon( _theme->applicationIcon() );
|
||||
@@ -114,12 +135,6 @@ Application::Application(int &argc, char **argv) :
|
||||
|
||||
setQuitOnLastWindowClosed(false);
|
||||
|
||||
_folderWizard = new FolderWizard;
|
||||
|
||||
_owncloudSetupWizard = new OwncloudSetupWizard( _folderMan, _theme, this );
|
||||
connect( _owncloudSetupWizard, SIGNAL(ownCloudWizardDone(int)),
|
||||
this, SLOT(slotownCloudWizardDone(int)));
|
||||
|
||||
_statusDialog = new StatusDialog( _theme );
|
||||
connect( _statusDialog, SIGNAL(addASync()), this, SLOT(slotAddFolder()) );
|
||||
|
||||
@@ -191,7 +206,7 @@ void Application::slotStartFolderSetup( int result )
|
||||
|
||||
ownCloudInfo::instance()->checkInstallation();
|
||||
} else {
|
||||
_owncloudSetupWizard->startWizard();
|
||||
slotConfigure();
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Setup Wizard was canceled. No reparsing of config.";
|
||||
@@ -247,23 +262,28 @@ void Application::slotFetchCredentials()
|
||||
{
|
||||
QString trayMessage;
|
||||
|
||||
if( CredentialStore::instance()->canTryAgain() ) {
|
||||
connect( CredentialStore::instance(), SIGNAL(fetchCredentialsFinished(bool)),
|
||||
this, SLOT(slotCredentialsFetched(bool)) );
|
||||
CredentialStore::instance()->fetchCredentials();
|
||||
if( CredentialStore::instance()->state() == CredentialStore::TooManyAttempts ) {
|
||||
trayMessage = tr("Too many incorrect password attempts.");
|
||||
}
|
||||
if( CredentialStore::instance()->state() == CredentialStore::Ok ) {
|
||||
// the credentials are still valid and ok.
|
||||
slotCredentialsFetched( true );
|
||||
} else {
|
||||
qDebug() << "Can not try again to fetch Credentials.";
|
||||
trayMessage = tr("%1 user credentials are wrong. Please check configuration.")
|
||||
.arg(Theme::instance()->appNameGUI());
|
||||
}
|
||||
if( CredentialStore::instance()->canTryAgain() ) {
|
||||
connect( CredentialStore::instance(), SIGNAL(fetchCredentialsFinished(bool)),
|
||||
this, SLOT(slotCredentialsFetched(bool)) );
|
||||
CredentialStore::instance()->fetchCredentials();
|
||||
if( CredentialStore::instance()->state() == CredentialStore::TooManyAttempts ) {
|
||||
trayMessage = tr("Too many incorrect password attempts.");
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Can not try again to fetch Credentials.";
|
||||
trayMessage = tr("%1 user credentials are wrong. Please check configuration.")
|
||||
.arg(Theme::instance()->appNameGUI());
|
||||
}
|
||||
|
||||
if( !trayMessage.isEmpty() ) {
|
||||
_tray->showMessage(tr("Credentials"), trayMessage);
|
||||
_actionOpenStatus->setEnabled( false );
|
||||
_actionAddFolder->setEnabled( false );
|
||||
if( !trayMessage.isEmpty() ) {
|
||||
_tray->showMessage(tr("Credentials"), trayMessage);
|
||||
_actionOpenStatus->setEnabled( false );
|
||||
_actionAddFolder->setEnabled( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,8 +373,6 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
|
||||
_actionAddFolder->setEnabled( true );
|
||||
_actionOpenStatus->setEnabled( true );
|
||||
setupContextMenu();
|
||||
} else {
|
||||
slotFetchCredentials();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,6 +421,7 @@ void Application::slotownCloudWizardDone( int res )
|
||||
}
|
||||
_folderMan->setSyncEnabled( true );
|
||||
slotStartFolderSetup( res );
|
||||
_owncloudSetupWizard.reset(0);
|
||||
}
|
||||
|
||||
void Application::setupActions()
|
||||
@@ -522,7 +541,9 @@ void Application::setupLogBrowser()
|
||||
_logBrowser = new LogBrowser;
|
||||
qInstallMsgHandler( mirallLogCatcher );
|
||||
// ## TODO: allow new log name maybe?
|
||||
if (!_logFile.isEmpty()) {
|
||||
if (!_logDirectory.isEmpty()) {
|
||||
enterNextLogFile();
|
||||
} else if (!_logFile.isEmpty()) {
|
||||
qDebug() << "Logging into logfile: " << _logFile << " with flush " << _logFlush;
|
||||
_logBrowser->setLogFile( _logFile, _logFlush );
|
||||
}
|
||||
@@ -538,38 +559,74 @@ void Application::setupLogBrowser()
|
||||
|
||||
}
|
||||
|
||||
void Application::setupProxy()
|
||||
void Application::enterNextLogFile()
|
||||
{
|
||||
//
|
||||
Mirall::MirallConfigFile cfg;
|
||||
int proxy = cfg.proxyType();
|
||||
if (_logBrowser && !_logDirectory.isEmpty()) {
|
||||
QDir dir(_logDirectory);
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(".");
|
||||
}
|
||||
|
||||
switch(proxy) {
|
||||
case QNetworkProxy::NoProxy: {
|
||||
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
|
||||
break;
|
||||
}
|
||||
case QNetworkProxy::DefaultProxy: {
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
break;
|
||||
}
|
||||
// Find out what is the file with the highest nymber if any
|
||||
QStringList files = dir.entryList(QStringList("owncloud.log.*"),
|
||||
QDir::Files);
|
||||
QRegExp rx("owncloud.log.(\\d+)");
|
||||
uint maxNumber = 0;
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
foreach(const QString &s, files) {
|
||||
if (rx.exactMatch(s)) {
|
||||
maxNumber = qMax(maxNumber, rx.cap(1).toUInt());
|
||||
if (_logExpire > 0) {
|
||||
QFileInfo fileInfo = dir.absoluteFilePath(s);
|
||||
if (fileInfo.lastModified().addSecs(60*60 * _logExpire) < now) {
|
||||
dir.remove(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case QNetworkProxy::Socks5Proxy: {
|
||||
proxy = QNetworkProxy::HttpProxy;
|
||||
cfg.setProxyType(proxy);
|
||||
// fall through
|
||||
QString filename = _logDirectory + "/owncloud.log." + QString::number(maxNumber+1);
|
||||
_logBrowser->setLogFile(filename , _logFlush);
|
||||
}
|
||||
case QNetworkProxy::HttpProxy:{
|
||||
QNetworkProxy proxy;
|
||||
proxy.setType(QNetworkProxy::HttpProxy);
|
||||
proxy.setHostName(cfg.proxyHostName());
|
||||
proxy.setPort(cfg.proxyPort());
|
||||
}
|
||||
|
||||
QNetworkProxy proxyFromConfig(const MirallConfigFile& cfg)
|
||||
{
|
||||
QNetworkProxy proxy;
|
||||
proxy.setHostName(cfg.proxyHostName());
|
||||
proxy.setPort(cfg.proxyPort());
|
||||
if (cfg.proxyNeedsAuth()) {
|
||||
proxy.setUser(cfg.proxyUser());
|
||||
proxy.setPassword(cfg.proxyPassword());
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
void Application::setupProxy()
|
||||
{
|
||||
Mirall::MirallConfigFile cfg;
|
||||
int proxyType = cfg.proxyType();
|
||||
QNetworkProxy proxy = proxyFromConfig(cfg);
|
||||
|
||||
switch(proxyType) {
|
||||
case QNetworkProxy::NoProxy:
|
||||
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
|
||||
break;
|
||||
case QNetworkProxy::DefaultProxy:
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
break;
|
||||
case QNetworkProxy::Socks5Proxy:
|
||||
proxy.setType(QNetworkProxy::Socks5Proxy);
|
||||
QNetworkProxy::setApplicationProxy(proxy);
|
||||
break;
|
||||
case QNetworkProxy::HttpProxy:
|
||||
proxy.setType(QNetworkProxy::HttpProxy);
|
||||
QNetworkProxy::setApplicationProxy(proxy);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
_folderMan->setProxy();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -614,7 +671,7 @@ void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
|
||||
slotFetchCredentials();
|
||||
}
|
||||
#if defined Q_WS_WIN || defined Q_WS_X11
|
||||
if( reason == QSystemTrayIcon::Trigger && _actionOpenStatus->isEnabled() ) {
|
||||
if( reason == QSystemTrayIcon::Trigger ) {
|
||||
slotOpenStatus();
|
||||
}
|
||||
#endif
|
||||
@@ -622,63 +679,58 @@ void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
|
||||
|
||||
void Application::slotAddFolder()
|
||||
{
|
||||
_folderMan->setSyncEnabled(false); // do not start more syncs.
|
||||
/** Helper class to ensure sync is always switched back on */
|
||||
class SyncDisabler
|
||||
{
|
||||
public:
|
||||
SyncDisabler(Application *app) : _app(app)
|
||||
{
|
||||
_app->_folderMan->setSyncEnabled(false);
|
||||
}
|
||||
~SyncDisabler() {
|
||||
_app->_folderMan->setSyncEnabled(true);
|
||||
_app->computeOverallSyncStatus();
|
||||
_app->_folderMan->slotScheduleAllFolders();
|
||||
}
|
||||
private:
|
||||
Application *_app;
|
||||
};
|
||||
|
||||
Folder::Map folderMap = _folderMan->map();
|
||||
|
||||
_folderWizard->setFolderMap( &folderMap );
|
||||
|
||||
_folderWizard->restart();
|
||||
|
||||
if (_folderWizard->exec() == QDialog::Accepted) {
|
||||
qDebug() << "* Folder wizard completed";
|
||||
|
||||
bool goodData = true;
|
||||
|
||||
QString alias = _folderWizard->field(QLatin1String("alias")).toString();
|
||||
QString sourceFolder = _folderWizard->field(QLatin1String("sourceFolder")).toString();
|
||||
QString backend = QLatin1String("csync");
|
||||
QString targetPath;
|
||||
bool onlyThisLAN = false;
|
||||
bool onlyOnline = false;
|
||||
|
||||
if (_folderWizard->field(QLatin1String("local?")).toBool()) {
|
||||
// setup a local csync folder
|
||||
targetPath = _folderWizard->field(QLatin1String("targetLocalFolder")).toString();
|
||||
} else if (_folderWizard->field(QLatin1String("remote?")).toBool()) {
|
||||
// setup a remote csync folder
|
||||
targetPath = _folderWizard->field(QLatin1String("targetURLFolder")).toString();
|
||||
onlyOnline = _folderWizard->field(QLatin1String("onlyOnline?")).toBool();
|
||||
onlyThisLAN = _folderWizard->field(QLatin1String("onlyThisLAN?")).toBool();
|
||||
(void) onlyOnline;
|
||||
(void) onlyThisLAN;
|
||||
} else if( _folderWizard->field(QLatin1String("OC?")).toBool() ||
|
||||
Theme::instance()->singleSyncFolder()) {
|
||||
// setup a ownCloud folder
|
||||
backend = QLatin1String("owncloud");
|
||||
targetPath = _folderWizard->field(QLatin1String("targetOCFolder")).toString(); //empty in single folder mode
|
||||
} else {
|
||||
qWarning() << "* Folder not local and note remote?";
|
||||
goodData = false;
|
||||
if (_folderWizard) {
|
||||
raiseDialog(_folderWizard);
|
||||
return;
|
||||
}
|
||||
|
||||
_folderMan->setSyncEnabled(true); // do start sync again.
|
||||
// disables sync queuing while in scope
|
||||
SyncDisabler disableSync(this);
|
||||
|
||||
if( goodData ) {
|
||||
_folderMan->addFolderDefinition( backend, alias, sourceFolder, targetPath, onlyThisLAN );
|
||||
Folder::Map folderMap = _folderMan->map();
|
||||
_folderWizard = new FolderWizard;
|
||||
_folderWizard->setFolderMap( &folderMap );
|
||||
|
||||
if (_folderWizard->exec() == QDialog::Accepted) {
|
||||
qDebug() << "* Folder wizard completed";
|
||||
|
||||
QString alias = _folderWizard->field(QLatin1String("alias")).toString();
|
||||
QString sourceFolder = _folderWizard->field(QLatin1String("sourceFolder")).toString();
|
||||
QString targetPath = _folderWizard->field(QLatin1String("OCFolderLineEdit")).toString();
|
||||
QString backend = QLatin1String("owncloud");
|
||||
|
||||
if (!FolderMan::ensureJournalGone( sourceFolder ))
|
||||
return;
|
||||
_folderMan->addFolderDefinition( backend, alias, sourceFolder, targetPath, false );
|
||||
Folder *f = _folderMan->setupFolderFromConfigFile( alias );
|
||||
if( f ) {
|
||||
_statusDialog->slotAddFolder( f );
|
||||
_statusDialog->buttonsSetEnabled();
|
||||
setupContextMenu();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
qDebug() << "* Folder wizard cancelled";
|
||||
}
|
||||
_folderMan->setSyncEnabled(true);
|
||||
_folderMan->slotScheduleAllFolders();
|
||||
} else {
|
||||
qDebug() << "* Folder wizard cancelled";
|
||||
}
|
||||
_folderWizard->deleteLater();
|
||||
_folderWizard = 0;
|
||||
}
|
||||
|
||||
void Application::slotOpenStatus()
|
||||
@@ -688,7 +740,7 @@ void Application::slotOpenStatus()
|
||||
QWidget *raiseWidget = 0;
|
||||
|
||||
// check if there is a mirall.cfg already.
|
||||
if( _owncloudSetupWizard->wizard()->isVisible() ) {
|
||||
if( _owncloudSetupWizard && _owncloudSetupWizard->wizard()->isVisible() ) {
|
||||
raiseWidget = _owncloudSetupWizard->wizard();
|
||||
}
|
||||
|
||||
@@ -698,8 +750,7 @@ void Application::slotOpenStatus()
|
||||
|
||||
if( !cfgFile.exists() ) {
|
||||
qDebug() << "No configured folders yet, start the Owncloud integration dialog.";
|
||||
_folderMan->setSyncEnabled(false);
|
||||
_owncloudSetupWizard->startWizard();
|
||||
slotConfigure();
|
||||
} else {
|
||||
qDebug() << "#============# Status dialog starting #=============#";
|
||||
raiseWidget = _statusDialog;
|
||||
@@ -746,16 +797,14 @@ void Application::slotAbout()
|
||||
void Application::slotRemoveFolder( const QString& alias )
|
||||
{
|
||||
int ret = QMessageBox::question( 0, tr("Confirm Folder Remove"),
|
||||
tr("Do you really want to remove upload folder <i>%1</i>?").arg(alias),
|
||||
tr("<p>Do you really want to stop syncing the upload folder <i>%1</i>?</p>"
|
||||
"<p><b>Note:</b> This will not remove the files from your client.</p>").arg(alias),
|
||||
QMessageBox::Yes|QMessageBox::No );
|
||||
|
||||
if( ret == QMessageBox::No ) {
|
||||
return;
|
||||
}
|
||||
Folder *f = _folderMan->folder(alias);
|
||||
if( f && _overallStatusStrings.contains( f->alias() )) {
|
||||
_overallStatusStrings.remove( f->alias() );
|
||||
}
|
||||
|
||||
_folderMan->slotRemoveFolder( alias );
|
||||
_statusDialog->slotRemoveSelectedFolder( );
|
||||
@@ -809,6 +858,15 @@ void Application::slotEnableFolder(const QString& alias, const bool enable)
|
||||
|
||||
void Application::slotConfigure()
|
||||
{
|
||||
if (_owncloudSetupWizard && !_owncloudSetupWizard->wizard()->isVisible()) {
|
||||
raiseDialog(_owncloudSetupWizard->wizard());
|
||||
return;
|
||||
}
|
||||
|
||||
_owncloudSetupWizard.reset(new OwncloudSetupWizard( _folderMan, _theme, this ));;
|
||||
connect( _owncloudSetupWizard.data(), SIGNAL(ownCloudWizardDone(int)),
|
||||
this, SLOT(slotownCloudWizardDone(int)));
|
||||
|
||||
_folderMan->setSyncEnabled(false); // do not start more syncs.
|
||||
_owncloudSetupWizard->startWizard();
|
||||
}
|
||||
@@ -846,6 +904,10 @@ void Application::slotSyncStateChange( const QString& alias )
|
||||
computeOverallSyncStatus();
|
||||
|
||||
qDebug() << "Sync state changed for folder " << alias << ": " << result.statusString();
|
||||
|
||||
if (result.status() == SyncResult::Success || result.status() == SyncResult::Error) {
|
||||
enterNextLogFile();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::parseOptions(const QStringList &options)
|
||||
@@ -869,6 +931,18 @@ void Application::parseOptions(const QStringList &options)
|
||||
} else {
|
||||
setHelp();
|
||||
}
|
||||
} else if (option == QLatin1String("--logdir")) {
|
||||
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
|
||||
_logDirectory = it.next();
|
||||
} else {
|
||||
setHelp();
|
||||
}
|
||||
} else if (option == QLatin1String("--logexpire")) {
|
||||
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
|
||||
_logExpire = it.next().toInt();
|
||||
} else {
|
||||
setHelp();
|
||||
}
|
||||
} else if (option == QLatin1String("--logflush")) {
|
||||
_logFlush = true;
|
||||
} else if (option == QLatin1String("--monoicons")) {
|
||||
@@ -892,11 +966,12 @@ void Application::computeOverallSyncStatus()
|
||||
|
||||
// display the info of the least successful sync (eg. not just display the result of the latest sync
|
||||
SyncResult overallResult(SyncResult::Undefined );
|
||||
QMap<QString, QString> overallStatusStrings;
|
||||
QString trayMessage;
|
||||
Folder::Map map = _folderMan->map();
|
||||
|
||||
foreach ( Folder *syncedFolder, map.values() ) {
|
||||
QString folderMessage = _overallStatusStrings[syncedFolder->alias()];
|
||||
QString folderMessage;
|
||||
|
||||
SyncResult folderResult = syncedFolder->syncResult();
|
||||
SyncResult::Status syncStatus = folderResult.status();
|
||||
@@ -926,9 +1001,9 @@ void Application::computeOverallSyncStatus()
|
||||
break;
|
||||
case SyncResult::Success:
|
||||
if( overallResult.status() == SyncResult::Undefined ) {
|
||||
folderMessage = tr( "Last Sync was successful." );
|
||||
overallResult.setStatus( SyncResult::Success );
|
||||
}
|
||||
folderMessage = tr( "Last Sync was successful." );
|
||||
break;
|
||||
case SyncResult::Error:
|
||||
overallResult.setStatus( SyncResult::Error );
|
||||
@@ -950,15 +1025,13 @@ void Application::computeOverallSyncStatus()
|
||||
}
|
||||
|
||||
qDebug() << "Folder in overallStatus Message: " << syncedFolder << " with name " << syncedFolder->alias();
|
||||
QString msg = QString::fromLatin1("Folder %1: %2").arg(syncedFolder->alias()).arg(folderMessage);
|
||||
if( msg != _overallStatusStrings[syncedFolder->alias()] ) {
|
||||
_overallStatusStrings[syncedFolder->alias()] = msg;
|
||||
}
|
||||
QString msg = tr("Folder %1: %2").arg(syncedFolder->alias(), folderMessage);
|
||||
overallStatusStrings[syncedFolder->alias()] = msg;
|
||||
}
|
||||
|
||||
// create the tray blob message, check if we have an defined state
|
||||
if( overallResult.status() != SyncResult::Undefined ) {
|
||||
QStringList allStatusStrings = _overallStatusStrings.values();
|
||||
QStringList allStatusStrings = overallStatusStrings.values();
|
||||
if( ! allStatusStrings.isEmpty() )
|
||||
trayMessage = allStatusStrings.join(QLatin1String("\n"));
|
||||
else
|
||||
@@ -971,22 +1044,48 @@ void Application::computeOverallSyncStatus()
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers for displaying messages. Note that there is no console on Windows.
|
||||
#ifdef Q_OS_WIN
|
||||
// Format as <pre> HTML
|
||||
static inline void toHtml(QString &t)
|
||||
{
|
||||
t.replace(QLatin1Char('&'), QLatin1String("&"));
|
||||
t.replace(QLatin1Char('<'), QLatin1String("<"));
|
||||
t.replace(QLatin1Char('>'), QLatin1String(">"));
|
||||
t.insert(0, QLatin1String("<html><pre>"));
|
||||
t.append(QLatin1String("</pre></html>"));
|
||||
}
|
||||
|
||||
static void displayHelpText(QString t) // No console on Windows.
|
||||
{
|
||||
toHtml(t);
|
||||
QMessageBox::information(0, Theme::instance()->appNameGUI(), t);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void displayHelpText(const QString &t)
|
||||
{
|
||||
std::cout << qPrintable(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Application::showHelp()
|
||||
{
|
||||
setHelp();
|
||||
std::cout << _theme->appName().toLatin1().constData() << " version " <<
|
||||
_theme->version().toLatin1().constData() << std::endl << std::endl;
|
||||
std::cout << "File synchronisation desktop utility." << std::endl << std::endl;
|
||||
std::cout << "Options:" << std::endl;
|
||||
std::cout << " -h --help : show this help screen." << std::endl;
|
||||
std::cout << " --logwindow : open a window to show log output." << std::endl;
|
||||
std::cout << " --logfile <filename> : write log output to file <filename>." << std::endl;
|
||||
std::cout << " --logflush : flush the log file after every write." << std::endl;
|
||||
std::cout << " --monoicons : Use black/white pictograms for systray." << std::endl;
|
||||
std::cout << " --confdir <dirname> : Use the given configuration directory." << std::endl;
|
||||
std::cout << std::endl;
|
||||
setHelp();
|
||||
QString helpText;
|
||||
QTextStream stream(&helpText);
|
||||
stream << _theme->appName().toLatin1().constData()
|
||||
<< QLatin1String(" version ")
|
||||
<< _theme->version().toLatin1().constData() << endl;
|
||||
|
||||
stream << QLatin1String("File synchronisation desktop utility.") << endl << endl
|
||||
<< QLatin1String(optionsC);
|
||||
|
||||
if (_theme->appName() == QLatin1String("ownCloud"))
|
||||
std::cout << "For more information, see http://www.owncloud.org" << std::endl;
|
||||
stream << endl << "For more information, see http://www.owncloud.org" << endl;
|
||||
|
||||
displayHelpText(helpText);
|
||||
}
|
||||
|
||||
void Application::setHelp()
|
||||
@@ -994,6 +1093,30 @@ void Application::setHelp()
|
||||
_helpOnly = true;
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
bool Application::winEventFilter(MSG *pMsg, long *result)
|
||||
{
|
||||
if (pMsg->message == WM_POWERBROADCAST) {
|
||||
switch(pMsg->wParam) {
|
||||
case PBT_APMPOWERSTATUSCHANGE:
|
||||
qDebug() << "WM_POWERBROADCAST: Power state changed";
|
||||
break;
|
||||
case PBT_APMSUSPEND:
|
||||
qDebug() << "WM_POWERBROADCAST: Entering low power state";
|
||||
break;
|
||||
case PBT_APMRESUMEAUTOMATIC:
|
||||
qDebug() << "WM_POWERBROADCAST: Resuming from low power state";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return SharedTools::QtSingleApplication::winEventFilter(pMsg, result);
|
||||
}
|
||||
#endif
|
||||
|
||||
QString substLang(const QString &lang)
|
||||
{
|
||||
// Map the more apropriate script codes
|
||||
|
||||
@@ -79,10 +79,16 @@ protected:
|
||||
void setupContextMenu();
|
||||
void setupLogBrowser();
|
||||
void setupProxy();
|
||||
void enterNextLogFile();
|
||||
|
||||
//folders have to be disabled while making config changes
|
||||
void computeOverallSyncStatus();
|
||||
|
||||
// reimplemented
|
||||
#if defined(Q_WS_WIN)
|
||||
bool winEventFilter( MSG * message, long * result );
|
||||
#endif
|
||||
|
||||
protected slots:
|
||||
void slotTrayClicked( QSystemTrayIcon::ActivationReason );
|
||||
void slotFolderOpenAction(const QString & );
|
||||
@@ -118,7 +124,7 @@ private:
|
||||
#endif
|
||||
|
||||
FolderWizard *_folderWizard;
|
||||
OwncloudSetupWizard *_owncloudSetupWizard;
|
||||
QScopedPointer<OwncloudSetupWizard> _owncloudSetupWizard;
|
||||
SslErrorDialog *_sslErrorDialog;
|
||||
|
||||
// tray's menu
|
||||
@@ -130,9 +136,10 @@ private:
|
||||
Theme *_theme;
|
||||
QSignalMapper *_folderOpenActionMapper;
|
||||
UpdateDetector *_updateDetector;
|
||||
QMap<QString, QString> _overallStatusStrings;
|
||||
LogBrowser *_logBrowser;
|
||||
QString _logFile;
|
||||
QString _logDirectory;
|
||||
int _logExpire;
|
||||
bool _showLogWindow;
|
||||
bool _logFlush;
|
||||
bool _helpOnly;
|
||||
|
||||
@@ -69,30 +69,18 @@ CredentialStore::CredState CredentialStore::state()
|
||||
|
||||
bool CredentialStore::canTryAgain()
|
||||
{
|
||||
bool canDoIt = false;
|
||||
|
||||
if( _tries > MAX_LOGIN_ATTEMPTS ) {
|
||||
qDebug() << "canTryAgain: Max attempts reached.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if( _state == NotFetched ) {
|
||||
/* Since QtKeyChain is required now, it makes sense to only query once. */
|
||||
if( _state == NotFetched || _state == AsyncWriting ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch( _type ) {
|
||||
case CredentialStore::User:
|
||||
canDoIt = true;
|
||||
break;
|
||||
case CredentialStore::Settings:
|
||||
break;
|
||||
case CredentialStore::KeyChain:
|
||||
canDoIt = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return canDoIt;
|
||||
}
|
||||
|
||||
void CredentialStore::fetchCredentials()
|
||||
@@ -135,7 +123,7 @@ void CredentialStore::fetchCredentials()
|
||||
_inputDialog->setTextEchoMode( QLineEdit::Password );
|
||||
|
||||
connect(_inputDialog, SIGNAL(finished(int)), SLOT(slotUserDialogDone(int)));
|
||||
_inputDialog->exec();
|
||||
_inputDialog->open();
|
||||
break;
|
||||
}
|
||||
case CredentialStore::Settings: {
|
||||
@@ -147,7 +135,7 @@ void CredentialStore::fetchCredentials()
|
||||
}
|
||||
case CredentialStore::KeyChain: {
|
||||
// If the credentials are here already, return.
|
||||
if( _state == Ok ) {
|
||||
if( _state == Ok || _state == AsyncWriting ) {
|
||||
emit(fetchCredentialsFinished(true));
|
||||
return;
|
||||
}
|
||||
@@ -347,6 +335,7 @@ void CredentialStore::saveCredentials( )
|
||||
|
||||
connect( job, SIGNAL(finished(QKeychain::Job*)), this,
|
||||
SLOT(slotKeyChainWriteFinished(QKeychain::Job*)));
|
||||
_state = AsyncWriting;
|
||||
job->start();
|
||||
#endif
|
||||
break;
|
||||
@@ -371,17 +360,23 @@ void CredentialStore::slotKeyChainWriteFinished( QKeychain::Job *job )
|
||||
qDebug() << "Error with keychain: " << pwdJob->errorString();
|
||||
if( err == NoBackendAvailable || err == NotImplemented ||
|
||||
pwdJob->errorString().contains(QLatin1String("Could not open wallet"))) {
|
||||
_state = NoKeychainBackend;
|
||||
_type = Settings;
|
||||
saveCredentials();
|
||||
} else {
|
||||
_state = Error;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Successfully stored password for user " << _user;
|
||||
// Try to remove password formerly stored in the config file.
|
||||
MirallConfigFile cfgFile;
|
||||
cfgFile.clearPasswordFromConfig();
|
||||
_state = NotFetched;
|
||||
_tries = 0;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Error: KeyChain Write Password Job failed!";
|
||||
_state = Error;
|
||||
}
|
||||
#else
|
||||
(void) job;
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
AccessDenied,
|
||||
NoKeychainBackend,
|
||||
Error,
|
||||
AsyncWriting,
|
||||
TooManyAttempts };
|
||||
|
||||
enum CredentialType {
|
||||
|
||||
@@ -58,6 +58,8 @@ CSyncThread::~CSyncThread()
|
||||
|
||||
}
|
||||
|
||||
//Convert an error code from csync to a user readable string.
|
||||
// Keep that function thread safe as it can be called from the sync thread or the main thread
|
||||
QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errString )
|
||||
{
|
||||
QString errStr;
|
||||
@@ -106,8 +108,6 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt
|
||||
break;
|
||||
case CSYNC_ERR_ACCESS_FAILED:
|
||||
errStr = tr("<p>The target directory does not exist.</p><p>Please check the sync setup.</p>");
|
||||
// this is critical. The database has to be removed.
|
||||
emit wipeDb();
|
||||
break;
|
||||
case CSYNC_ERR_REMOTE_CREATE:
|
||||
case CSYNC_ERR_REMOTE_STAT:
|
||||
@@ -191,6 +191,11 @@ int CSyncThread::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
|
||||
int re = 0;
|
||||
|
||||
if (file->instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
&& file->instruction != CSYNC_INSTRUCTION_REMOVE) {
|
||||
_hasFiles = true;
|
||||
}
|
||||
|
||||
switch(file->instruction) {
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
case CSYNC_INSTRUCTION_IGNORE:
|
||||
@@ -245,8 +250,8 @@ int CSyncThread::treewalkError(TREE_WALK_FILE* file)
|
||||
return 0;
|
||||
|
||||
if( file &&
|
||||
file->instruction == CSYNC_INSTRUCTION_STAT_ERROR ||
|
||||
file->instruction == CSYNC_INSTRUCTION_ERROR ) {
|
||||
(file->instruction == CSYNC_INSTRUCTION_STAT_ERROR ||
|
||||
file->instruction == CSYNC_INSTRUCTION_ERROR) ) {
|
||||
_mutex.lock();
|
||||
_syncedItems[indx]._instruction = file->instruction;
|
||||
_mutex.unlock();
|
||||
@@ -310,6 +315,7 @@ void CSyncThread::startSync()
|
||||
// cleans up behind us and emits finished() to ease error handling
|
||||
CSyncRunScopeHelper helper(_csync_ctx, this);
|
||||
|
||||
csync_set_module_property(_csync_ctx, "csync_context", _csync_ctx);
|
||||
csync_set_userdata(_csync_ctx, this);
|
||||
|
||||
// csync_set_auth_callback( _csync_ctx, getauth );
|
||||
@@ -327,6 +333,7 @@ void CSyncThread::startSync()
|
||||
return;
|
||||
}
|
||||
|
||||
_hasFiles = false;
|
||||
bool walkOk = true;
|
||||
if( csync_walk_local_tree(_csync_ctx, &treewalkLocal, 0) < 0 ) {
|
||||
qDebug() << "Error in local treewalk.";
|
||||
@@ -336,6 +343,16 @@ void CSyncThread::startSync()
|
||||
qDebug() << "Error in remote treewalk.";
|
||||
}
|
||||
|
||||
if (!_hasFiles && !_syncedItems.isEmpty()) {
|
||||
qDebug() << Q_FUNC_INFO << "All the files are going to be removed, asking the user";
|
||||
bool cancel = true;
|
||||
emit aboutToRemoveAllFiles(_syncedItems.first()._dir, &cancel);
|
||||
if (cancel) {
|
||||
qDebug() << Q_FUNC_INFO << "Abort sync";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (_needsUpdate)
|
||||
emit(started());
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
CSyncThread(CSYNC *);
|
||||
~CSyncThread();
|
||||
|
||||
QString csyncErrorToString( CSYNC_ERROR_CODE, const char * );
|
||||
static QString csyncErrorToString( CSYNC_ERROR_CODE, const char * );
|
||||
|
||||
Q_INVOKABLE void startSync();
|
||||
|
||||
@@ -56,6 +56,8 @@ signals:
|
||||
void finished();
|
||||
void started();
|
||||
|
||||
void aboutToRemoveAllFiles(SyncFileItem::Direction direction, bool *cancel);
|
||||
|
||||
private:
|
||||
void handleSyncError(CSYNC *ctx, const char *state);
|
||||
static void progress(const char *remote_url,
|
||||
@@ -79,6 +81,8 @@ private:
|
||||
CSYNC *_csync_ctx;
|
||||
bool _needsUpdate;
|
||||
|
||||
bool _hasFiles; // true if there is at least one file that is not ignored or removed
|
||||
|
||||
friend class CSyncRunScopeHelper;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -123,7 +123,10 @@ void FileItemDialog::slotSetFolderMessage()
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
int secs = _lastSyncTime.secsTo(now);
|
||||
|
||||
_timelabel->setText(tr("%1 (finished %n sec. ago)", "", secs).arg(_folderMessage));
|
||||
if (secs < 60)
|
||||
_timelabel->setText(tr("%1 (last finished %n sec. ago)", "", secs).arg(_folderMessage));
|
||||
else
|
||||
_timelabel->setText(tr("%1 (last finished %n min. ago)", "", secs/60).arg(_folderMessage));
|
||||
}
|
||||
|
||||
void FileItemDialog::copyToClipboard()
|
||||
|
||||
@@ -173,6 +173,11 @@ public slots:
|
||||
*/
|
||||
void setPollInterval( int );
|
||||
|
||||
/**
|
||||
* If folder is network-based, reimplement to react to proxy changes
|
||||
*/
|
||||
virtual void setProxy() {}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The minimum amounts of seconds to wait before
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#endif
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QMessageBox>
|
||||
#include <QtCore>
|
||||
|
||||
namespace Mirall {
|
||||
@@ -79,20 +80,28 @@ void FolderMan::slotReparseConfiguration()
|
||||
setupKnownFolders();
|
||||
}
|
||||
|
||||
int FolderMan::unloadAllFolders()
|
||||
{
|
||||
// first terminate sync jobs.
|
||||
terminateCurrentSync();
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
// clear the list of existing folders.
|
||||
Folder::MapIterator i(_folderMap);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
delete _folderMap.take( i.key() );
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int FolderMan::setupKnownFolders()
|
||||
{
|
||||
qDebug() << "* Setup folders from " << _folderConfigPath;
|
||||
|
||||
// first terminate sync jobs.
|
||||
terminateCurrentSync();
|
||||
|
||||
// clear the list of existing folders.
|
||||
Folder::MapIterator i(_folderMap);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
delete _folderMap.take( i.key() );
|
||||
}
|
||||
unloadAllFolders();
|
||||
|
||||
QDir dir( _folderConfigPath );
|
||||
dir.setFilter(QDir::Files);
|
||||
@@ -117,6 +126,25 @@ void FolderMan::wipeAllJournals()
|
||||
}
|
||||
}
|
||||
|
||||
bool FolderMan::ensureJournalGone(const QString &localPath)
|
||||
{
|
||||
|
||||
// remove old .csync_journal file
|
||||
QString stateDbFile = localPath+QLatin1String("/.csync_journal.db");
|
||||
while (QFile::exists(stateDbFile) && !QFile::remove(stateDbFile)) {
|
||||
int ret = QMessageBox::warning(0, tr("Could not reset folder state"),
|
||||
tr("An old sync journal '%1' was found, "
|
||||
"but could not be removed. Please make sure "
|
||||
"that no application is currently using it.")
|
||||
.arg(QDir::fromNativeSeparators(QDir::cleanPath(stateDbFile))),
|
||||
QMessageBox::Retry|QMessageBox::Abort);
|
||||
if (ret == QMessageBox::Abort) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FolderMan::terminateCurrentSync()
|
||||
{
|
||||
if( !_currentSyncFolder.isEmpty() ) {
|
||||
@@ -235,7 +263,7 @@ Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
|
||||
folder->setConfigFile(file);
|
||||
} else {
|
||||
qWarning() << "unknown backend" << backend;
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,12 +303,18 @@ void FolderMan::slotEnableFolder( const QString& alias, bool enable )
|
||||
// csync still remains in a stable state, regardless of that.
|
||||
void FolderMan::terminateSyncProcess( const QString& alias )
|
||||
{
|
||||
Folder *f = _folderMap[alias];
|
||||
if( f ) {
|
||||
f->slotTerminateSync();
|
||||
QString folderAlias = alias;
|
||||
if( alias.isEmpty() ) {
|
||||
folderAlias = _currentSyncFolder;
|
||||
}
|
||||
if( ! folderAlias.isEmpty() ) {
|
||||
Folder *f = _folderMap[folderAlias];
|
||||
if( f ) {
|
||||
f->slotTerminateSync();
|
||||
|
||||
if(_currentSyncFolder == alias )
|
||||
_currentSyncFolder = QString::null;
|
||||
if(_currentSyncFolder == folderAlias )
|
||||
_currentSyncFolder = QString::null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,6 +471,8 @@ void FolderMan::removeFolder( const QString& alias )
|
||||
{
|
||||
Folder *f = 0;
|
||||
|
||||
_scheduleQueue.removeAll(alias);
|
||||
|
||||
if( _folderMap.contains( alias )) {
|
||||
qDebug() << "Removing " << alias;
|
||||
f = _folderMap.take( alias );
|
||||
@@ -455,4 +491,53 @@ void FolderMan::removeFolder( const QString& alias )
|
||||
}
|
||||
}
|
||||
|
||||
QString FolderMan::getBackupName( const QString& fullPathName ) const
|
||||
{
|
||||
if( fullPathName.isEmpty() ) return QString::null;
|
||||
|
||||
QString newName = fullPathName + QLatin1String(".oC_bak");
|
||||
QFileInfo fi( newName );
|
||||
int cnt = 1;
|
||||
do {
|
||||
if( fi.exists() ) {
|
||||
newName = fullPathName + QString( ".oC_bak_%1").arg(cnt++);
|
||||
fi.setFile(newName);
|
||||
}
|
||||
} while( fi.exists() );
|
||||
|
||||
return newName;
|
||||
}
|
||||
|
||||
bool FolderMan::startFromScratch( const QString& localFolder )
|
||||
{
|
||||
if( localFolder.isEmpty() ) return false;
|
||||
|
||||
QFileInfo fi( localFolder );
|
||||
if( fi.exists() && fi.isDir() ) {
|
||||
QDir file = fi.dir();
|
||||
|
||||
// check if there are files in the directory.
|
||||
if( file.count() == 0 ) {
|
||||
// directory is existing, but its empty. Use it.
|
||||
qDebug() << "startFromScratch: Directory is empty!";
|
||||
return true;
|
||||
}
|
||||
QString newName = getBackupName( fi.absoluteFilePath() );
|
||||
|
||||
if( file.rename( fi.absoluteFilePath(), newName )) {
|
||||
if( file.mkdir( fi.absoluteFilePath() ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FolderMan::setProxy()
|
||||
{
|
||||
foreach( Folder *f, _folderMap.values() ) {
|
||||
f->setProxy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,6 +76,23 @@ public:
|
||||
*/
|
||||
void wipeAllJournals();
|
||||
|
||||
/**
|
||||
* Ensures that a given directory does not contain a .csync_journal.
|
||||
*
|
||||
* @returns false if the journal could not be removed, false otherwise.
|
||||
*/
|
||||
static bool ensureJournalGone(const QString &path);
|
||||
|
||||
/**
|
||||
* Creates a new and empty local directory.
|
||||
*/
|
||||
bool startFromScratch( const QString& );
|
||||
|
||||
/**
|
||||
* called whenever proxy configuration changes
|
||||
*/
|
||||
void setProxy();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* signal to indicate a folder named by alias has changed its sync state.
|
||||
@@ -92,7 +109,10 @@ public slots:
|
||||
|
||||
void slotReparseConfiguration();
|
||||
|
||||
void terminateSyncProcess( const QString& );
|
||||
void terminateSyncProcess( const QString& alias = QString::null );
|
||||
|
||||
/* delete all folder objects */
|
||||
int unloadAllFolders();
|
||||
|
||||
// if enabled is set to false, no new folders will start to sync.
|
||||
// the current one will finish.
|
||||
@@ -112,6 +132,7 @@ private:
|
||||
// and create the folders
|
||||
int setupKnownFolders();
|
||||
void terminateCurrentSync();
|
||||
QString getBackupName( const QString& ) const;
|
||||
|
||||
// Escaping of the alias which is used in QSettings AND the file
|
||||
// system, thus need to be escaped.
|
||||
|
||||
@@ -36,7 +36,8 @@ FolderWizardSourcePage::FolderWizardSourcePage()
|
||||
{
|
||||
_ui.setupUi(this);
|
||||
registerField(QLatin1String("sourceFolder*"), _ui.localFolderLineEdit);
|
||||
_ui.localFolderLineEdit->setText( QString::fromLatin1( "%1/%2").arg( QDir::homePath() ).arg(Theme::instance()->appName() ) );
|
||||
QString defaultPath = QString::fromLatin1( "%1/%2").arg( QDir::homePath() ).arg(Theme::instance()->appName() );
|
||||
_ui.localFolderLineEdit->setText( QDir::toNativeSeparators( defaultPath ) );
|
||||
registerField(QLatin1String("alias*"), _ui.aliasLineEdit);
|
||||
_ui.aliasLineEdit->setText( Theme::instance()->appNameGUI() );
|
||||
|
||||
@@ -64,7 +65,7 @@ void FolderWizardSourcePage::cleanupPage()
|
||||
|
||||
bool FolderWizardSourcePage::isComplete() const
|
||||
{
|
||||
QFileInfo selFile( _ui.localFolderLineEdit->text() );
|
||||
QFileInfo selFile( QDir::fromNativeSeparators(_ui.localFolderLineEdit->text()) );
|
||||
QString userInput = selFile.canonicalFilePath();
|
||||
|
||||
QString warnString;
|
||||
@@ -94,7 +95,8 @@ bool FolderWizardSourcePage::isComplete() const
|
||||
qDebug() << "Checking local path: " << folderDir << " <-> " << userInput;
|
||||
if( QFileInfo( f->path() ) == userInput ) {
|
||||
isOk = false;
|
||||
warnString.append( tr("The local path %1 is already an upload folder.<br/>Please pick another one!").arg(userInput) );
|
||||
warnString.append( tr("The local path %1 is already an upload folder.<br/>Please pick another one!")
|
||||
.arg(QDir::toNativeSeparators(userInput)) );
|
||||
}
|
||||
if( isOk && folderDir.startsWith( userInput )) {
|
||||
qDebug() << "A already configured folder is child of the current selected";
|
||||
@@ -148,7 +150,7 @@ void FolderWizardSourcePage::on_localFolderChooseBtn_clicked()
|
||||
tr("Select the source folder"),
|
||||
QDesktopServices::storageLocation(QDesktopServices::HomeLocation));
|
||||
if (!dir.isEmpty()) {
|
||||
_ui.localFolderLineEdit->setText(dir);
|
||||
_ui.localFolderLineEdit->setText(QDir::toNativeSeparators(dir));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +168,7 @@ FolderWizardTargetPage::FolderWizardTargetPage()
|
||||
_ui.setupUi(this);
|
||||
_ui.warnFrame->hide();
|
||||
|
||||
registerField(QLatin1String("targetOCFolder"), _ui.OCFolderLineEdit);
|
||||
registerField(QLatin1String("OCFolderLineEdit"), _ui.OCFolderLineEdit);
|
||||
|
||||
connect( _ui.OCFolderLineEdit, SIGNAL(textChanged(QString)),
|
||||
SLOT(slotFolderTextChanged(QString)));
|
||||
@@ -213,11 +215,10 @@ void FolderWizardTargetPage::slotDirCheckReply(const QString &url, QNetworkReply
|
||||
|
||||
void FolderWizardTargetPage::slotCreateRemoteFolder()
|
||||
{
|
||||
_ui.OCFolderLineEdit->setEnabled( false );
|
||||
|
||||
const QString folder = _ui.OCFolderLineEdit->text();
|
||||
if( folder.isEmpty() ) return;
|
||||
|
||||
_ui.OCFolderLineEdit->setEnabled( false );
|
||||
qDebug() << "creating folder on ownCloud: " << folder;
|
||||
ownCloudInfo::instance()->mkdirRequest( folder );
|
||||
}
|
||||
@@ -244,8 +245,8 @@ FolderWizardTargetPage::~FolderWizardTargetPage()
|
||||
bool FolderWizardTargetPage::isComplete() const
|
||||
{
|
||||
QString dir = _ui.OCFolderLineEdit->text();
|
||||
if( dir.isEmpty() ) {
|
||||
showWarn( tr("Better do not use the remote root directory.<br/>If you do, you can <b>not</b> mirror another local folder."), false);
|
||||
if( dir.isEmpty() || dir == QLatin1String("/") ) {
|
||||
showWarn( tr("If you sync the root folder, you can <b>not</b> configure another sync directory."), false);
|
||||
return true;
|
||||
} else {
|
||||
if( _dirChecked ) {
|
||||
|
||||
@@ -98,9 +98,7 @@ public:
|
||||
|
||||
enum {
|
||||
Page_Source,
|
||||
Page_Target,
|
||||
Page_Network,
|
||||
Page_Owncloud
|
||||
Page_Target
|
||||
};
|
||||
|
||||
FolderWizard(QWidget *parent = 0);
|
||||
|
||||
@@ -113,15 +113,12 @@ LogBrowser::LogBrowser(QWidget *parent) :
|
||||
|
||||
setModal(false);
|
||||
|
||||
// needs to be a queued connection as logs from other threads come in
|
||||
connect(Logger::instance(), SIGNAL(newLog(QString)),this,SLOT(slotNewLog(QString)), Qt::QueuedConnection);
|
||||
// Direct connection for log comming from this thread, and queued for the one in a different thread
|
||||
connect(Logger::instance(), SIGNAL(newLog(QString)),this,SLOT(slotNewLog(QString)), Qt::AutoConnection);
|
||||
}
|
||||
|
||||
LogBrowser::~LogBrowser()
|
||||
{
|
||||
if( _logstream ) {
|
||||
_logFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void LogBrowser::slotNewLog( const QString& msg )
|
||||
@@ -138,6 +135,9 @@ void LogBrowser::slotNewLog( const QString& msg )
|
||||
|
||||
void LogBrowser::setLogFile( const QString & name, bool flush )
|
||||
{
|
||||
if( _logstream ) {
|
||||
_logFile.close();
|
||||
}
|
||||
_logFile.setFileName( name );
|
||||
|
||||
if(!_logFile.open(QIODevice::WriteOnly)) {
|
||||
@@ -150,7 +150,7 @@ void LogBrowser::setLogFile( const QString & name, bool flush )
|
||||
return;
|
||||
}
|
||||
_doFileFlush = flush;
|
||||
_logstream = new QTextStream( &_logFile );
|
||||
_logstream.reset(new QTextStream( &_logFile ));
|
||||
}
|
||||
|
||||
void LogBrowser::slotFind()
|
||||
|
||||
@@ -67,7 +67,7 @@ private:
|
||||
|
||||
QFile _logFile;
|
||||
bool _doFileFlush;
|
||||
QTextStream *_logstream;
|
||||
QScopedPointer<QTextStream> _logstream;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -374,26 +374,23 @@ QString MirallConfigFile::ownCloudPasswd( const QString& connection ) const
|
||||
settings.setIniCodec( "UTF-8" );
|
||||
settings.beginGroup( con );
|
||||
|
||||
QString pwd;
|
||||
|
||||
QByteArray pwdba = settings.value(QLatin1String("passwd")).toByteArray();
|
||||
if( pwdba.isEmpty() ) {
|
||||
// check the password entry, cleartext from before
|
||||
// read it and convert to base64, delete the cleartext entry.
|
||||
QString p = settings.value(QLatin1String("password")).toString();
|
||||
|
||||
if( ! p.isEmpty() ) {
|
||||
// its there, save base64-encoded and delete.
|
||||
|
||||
pwdba = p.toUtf8();
|
||||
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
|
||||
settings.remove( QLatin1String("password") );
|
||||
settings.sync();
|
||||
}
|
||||
if( !pwdba.isEmpty() ) {
|
||||
return QString::fromUtf8( QByteArray::fromBase64(pwdba) );
|
||||
}
|
||||
pwd = QString::fromUtf8( QByteArray::fromBase64(pwdba) );
|
||||
|
||||
return pwd;
|
||||
// check the password entry, cleartext from before
|
||||
// read it and convert to base64, delete the cleartext entry.
|
||||
QString p = settings.value(QLatin1String("password")).toString();
|
||||
|
||||
if( ! p.isEmpty() ) {
|
||||
// its there, save base64-encoded and delete.
|
||||
pwdba = p.toUtf8();
|
||||
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
|
||||
settings.remove( QLatin1String("password") );
|
||||
settings.sync();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
QString MirallConfigFile::ownCloudVersion() const
|
||||
@@ -515,7 +512,7 @@ void MirallConfigFile::acceptCustomConfig()
|
||||
|
||||
void MirallConfigFile::setProxyType(int proxyType,
|
||||
const QString& host,
|
||||
int port,
|
||||
int port, bool needsAuth,
|
||||
const QString& user,
|
||||
const QString& pass)
|
||||
{
|
||||
@@ -524,11 +521,15 @@ void MirallConfigFile::setProxyType(int proxyType,
|
||||
settings.beginGroup(QLatin1String("proxy"));
|
||||
|
||||
settings.setValue(QLatin1String("type"), proxyType);
|
||||
settings.setValue(QLatin1String("host"), host);
|
||||
settings.setValue(QLatin1String("port"), port);
|
||||
settings.setValue(QLatin1String("user"), user);
|
||||
settings.setValue(QLatin1String("pass"), pass.toUtf8().toBase64());
|
||||
|
||||
if (proxyType == QNetworkProxy::HttpProxy ||
|
||||
proxyType == QNetworkProxy::Socks5Proxy) {
|
||||
settings.setValue(QLatin1String("host"), host);
|
||||
settings.setValue(QLatin1String("port"), port);
|
||||
settings.setValue(QLatin1String("needsAuth"), needsAuth);
|
||||
settings.setValue(QLatin1String("user"), user);
|
||||
settings.setValue(QLatin1String("pass"), pass.toUtf8().toBase64());
|
||||
}
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
@@ -556,6 +557,11 @@ int MirallConfigFile::proxyPort() const
|
||||
return getValue(QLatin1String("port"), QLatin1String("proxy")).toInt();
|
||||
}
|
||||
|
||||
bool MirallConfigFile::proxyNeedsAuth() const
|
||||
{
|
||||
return getValue(QLatin1String("needsAuth"), QLatin1String("proxy")).toBool();
|
||||
}
|
||||
|
||||
QString MirallConfigFile::proxyUser() const
|
||||
{
|
||||
return getValue(QLatin1String("user"), QLatin1String("proxy")).toString();
|
||||
|
||||
@@ -89,13 +89,14 @@ public:
|
||||
// proxy settings
|
||||
void setProxyType(int proxyType,
|
||||
const QString& host = QString(),
|
||||
int port = 0,
|
||||
int port = 0, bool needsAuth = false,
|
||||
const QString& user = QString(),
|
||||
const QString& pass = QString());
|
||||
|
||||
int proxyType() const;
|
||||
QString proxyHostName() const;
|
||||
int proxyPort() const;
|
||||
bool proxyNeedsAuth() const;
|
||||
QString proxyUser() const;
|
||||
QString proxyPassword() const;
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <QNetworkProxy>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkProxyFactory>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
@@ -67,7 +69,6 @@ ownCloudFolder::ownCloudFolder(const QString &alias,
|
||||
, _csync(0)
|
||||
, _csyncError(false)
|
||||
, _csyncUnavail(false)
|
||||
, _wipeDb(false)
|
||||
{
|
||||
ServerActionNotifier *notifier = new ServerActionNotifier(this);
|
||||
connect(notifier, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
|
||||
@@ -97,26 +98,13 @@ ownCloudFolder::ownCloudFolder(const QString &alias,
|
||||
csync_set_auth_callback( _csync_ctx, getauth );
|
||||
|
||||
if( csync_init( _csync_ctx ) < 0 ) {
|
||||
qDebug() << "Could not initialize csync!";
|
||||
qDebug() << "Could not initialize csync!" << csync_get_error(_csync_ctx) << csync_get_error_string(_csync_ctx);
|
||||
slotCSyncError(CSyncThread::csyncErrorToString(csync_get_error(_csync_ctx), csync_get_error_string(_csync_ctx)));
|
||||
csync_destroy(_csync_ctx);
|
||||
_csync_ctx = 0;
|
||||
}
|
||||
setProxy();
|
||||
|
||||
if( _csync_ctx ) {
|
||||
/* Store proxy */
|
||||
QList<QNetworkProxy> proxies = QNetworkProxyFactory::proxyForQuery(QUrl(cfgFile.ownCloudUrl()));
|
||||
// We set at least one in Application
|
||||
Q_ASSERT(proxies.count() > 0);
|
||||
QNetworkProxy proxy = proxies.first();
|
||||
int proxyPort = proxy.port();
|
||||
|
||||
csync_set_module_property(_csync_ctx, "proxy_type", (char*) proxyTypeToCStr(proxy.type()) );
|
||||
csync_set_module_property(_csync_ctx, "proxy_host", proxy.hostName().toUtf8().data() );
|
||||
csync_set_module_property(_csync_ctx, "proxy_port", &proxyPort );
|
||||
csync_set_module_property(_csync_ctx, "proxy_user", proxy.user().toUtf8().data() );
|
||||
csync_set_module_property(_csync_ctx, "proxy_pwd" , proxy.password().toUtf8().data() );
|
||||
|
||||
csync_set_module_property(_csync_ctx, "csync_context", _csync_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,10 +115,39 @@ ownCloudFolder::~ownCloudFolder()
|
||||
csync_request_abort(_csync_ctx);
|
||||
_thread->wait();
|
||||
}
|
||||
delete _csync;
|
||||
// Destroy csync here.
|
||||
csync_destroy(_csync_ctx);
|
||||
}
|
||||
|
||||
void ownCloudFolder::setProxy()
|
||||
{
|
||||
if( _csync_ctx ) {
|
||||
/* Store proxy */
|
||||
MirallConfigFile cfgFile;
|
||||
QUrl proxyUrl(cfgFile.ownCloudUrl());
|
||||
QList<QNetworkProxy> proxies = QNetworkProxyFactory::proxyForQuery(proxyUrl);
|
||||
// We set at least one in Application
|
||||
Q_ASSERT(proxies.count() > 0);
|
||||
QNetworkProxy proxy = proxies.first();
|
||||
if (proxy.type() == QNetworkProxy::NoProxy) {
|
||||
qDebug() << "Passing NO proxy to csync for" << cfgFile.ownCloudUrl();
|
||||
} else {
|
||||
qDebug() << "Passing" << proxy.hostName() << "of proxy type " << proxy.type()
|
||||
<< " to csync for" << cfgFile.ownCloudUrl();
|
||||
}
|
||||
int proxyPort = proxy.port();
|
||||
|
||||
csync_set_module_property(_csync_ctx, "proxy_type", (char*) proxyTypeToCStr(proxy.type()) );
|
||||
csync_set_module_property(_csync_ctx, "proxy_host", proxy.hostName().toUtf8().data() );
|
||||
csync_set_module_property(_csync_ctx, "proxy_port", &proxyPort );
|
||||
csync_set_module_property(_csync_ctx, "proxy_user", proxy.user().toUtf8().data() );
|
||||
csync_set_module_property(_csync_ctx, "proxy_pwd" , proxy.password().toUtf8().data() );
|
||||
|
||||
csync_set_module_property(_csync_ctx, "csync_context", _csync_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
const char* ownCloudFolder::proxyTypeToCStr(QNetworkProxy::ProxyType type)
|
||||
{
|
||||
switch (type) {
|
||||
@@ -244,6 +261,13 @@ void ownCloudFolder::startSync()
|
||||
|
||||
void ownCloudFolder::startSync(const QStringList &pathList)
|
||||
{
|
||||
if (!_csync_ctx) {
|
||||
qDebug() << Q_FUNC_INFO << "_csync_ctx is empty. probably because csync_init has failed.";
|
||||
// the error should already be set
|
||||
QMetaObject::invokeMethod(this, "slotCSyncFinished", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_thread && _thread->isRunning()) {
|
||||
qCritical() << "* ERROR csync is still running and new sync requested.";
|
||||
return;
|
||||
@@ -255,7 +279,6 @@ void ownCloudFolder::startSync(const QStringList &pathList)
|
||||
_errors.clear();
|
||||
_csyncError = false;
|
||||
_csyncUnavail = false;
|
||||
_wipeDb = false;
|
||||
|
||||
MirallConfigFile cfgFile;
|
||||
|
||||
@@ -270,6 +293,8 @@ void ownCloudFolder::startSync(const QStringList &pathList)
|
||||
_csync->moveToThread(_thread);
|
||||
|
||||
qRegisterMetaType<SyncFileItemVector>("SyncFileItemVector");
|
||||
qRegisterMetaType<SyncFileItem::Direction>("SyncFileItem::Direction");
|
||||
|
||||
connect( _csync, SIGNAL(treeWalkResult(const SyncFileItemVector&)),
|
||||
this, SLOT(slotThreadTreeWalkResult(const SyncFileItemVector&)), Qt::QueuedConnection);
|
||||
|
||||
@@ -277,6 +302,11 @@ void ownCloudFolder::startSync(const QStringList &pathList)
|
||||
connect(_csync, SIGNAL(finished()), SLOT(slotCSyncFinished()), Qt::QueuedConnection);
|
||||
connect(_csync, SIGNAL(csyncError(QString)), SLOT(slotCSyncError(QString)), Qt::QueuedConnection);
|
||||
connect(_csync, SIGNAL(csyncUnavailable()), SLOT(slotCsyncUnavailable()), Qt::QueuedConnection);
|
||||
|
||||
//blocking connection so the message box happens in this thread, but block the csync thread.
|
||||
connect(_csync, SIGNAL(aboutToRemoveAllFiles(SyncFileItem::Direction,bool*)),
|
||||
SLOT(slotAboutToRemoveAllFiles(SyncFileItem::Direction,bool*)), Qt::BlockingQueuedConnection);
|
||||
|
||||
_thread->start();
|
||||
QMetaObject::invokeMethod(_csync, "startSync", Qt::QueuedConnection);
|
||||
emit syncStarted();
|
||||
@@ -310,7 +340,6 @@ void ownCloudFolder::slotCSyncFinished()
|
||||
qDebug() << " ** error Strings: " << _errors;
|
||||
_syncResult.setErrorStrings( _errors );
|
||||
qDebug() << " * owncloud csync thread finished with error";
|
||||
if( _wipeDb ) wipe();
|
||||
} else if (_csyncUnavail) {
|
||||
_syncResult.setStatus(SyncResult::Unavailable);
|
||||
} else {
|
||||
@@ -404,7 +433,6 @@ void ownCloudFolder::wipe()
|
||||
if( ctmpFile.exists() ) {
|
||||
ctmpFile.remove();
|
||||
}
|
||||
_wipeDb = false;
|
||||
}
|
||||
|
||||
ServerActionNotifier::ServerActionNotifier(QObject *parent)
|
||||
@@ -475,5 +503,30 @@ void ServerActionNotifier::slotSyncFinished(const SyncResult &result)
|
||||
}
|
||||
}
|
||||
|
||||
void ownCloudFolder::slotAboutToRemoveAllFiles(SyncFileItem::Direction direction, bool *cancel)
|
||||
{
|
||||
QString msg = direction == SyncFileItem::Down ?
|
||||
tr("This sync would remove all the files in the local sync folder '%1'.\n"
|
||||
"If you or your administrator have reset your account on the server, choose"
|
||||
"\"Keep files\". If you want your data to be removed, choose \"Remove all files\".") :
|
||||
tr("This sync would remove all the files in the sync folder '%1'.\n"
|
||||
"This might be because the folder was silently reconfigured, or that all"
|
||||
"the file were manually removed.\n"
|
||||
"Are you sure you want to perform this operation?");
|
||||
QMessageBox msgBox(QMessageBox::Warning, tr("Remove All Files?"),
|
||||
msg.arg(alias()));
|
||||
msgBox.addButton(tr("Remove all files"), QMessageBox::DestructiveRole);
|
||||
QPushButton* keepBtn = msgBox.addButton(tr("Keep files"), QMessageBox::ActionRole);
|
||||
if (msgBox.exec() == -1) {
|
||||
*cancel = true;
|
||||
return;
|
||||
}
|
||||
*cancel = msgBox.clickedButton() == keepBtn;
|
||||
if (*cancel) {
|
||||
wipe();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // ns
|
||||
|
||||
|
||||
@@ -72,9 +72,12 @@ public:
|
||||
/* get status about a singel file. */
|
||||
SyncFileStatus fileStatus( const QString& );
|
||||
|
||||
void setProxy();
|
||||
|
||||
public slots:
|
||||
void startSync();
|
||||
void slotTerminateSync();
|
||||
void slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool*);
|
||||
|
||||
protected slots:
|
||||
void slotLocalPathChanged( const QString& );
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
|
||||
#include "mirall/owncloudinfo.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/version.h"
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/utility.h"
|
||||
#include "mirall/logger.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
@@ -64,7 +65,8 @@ ownCloudInfo::ownCloudInfo() :
|
||||
_manager(0)
|
||||
{
|
||||
_connection = Theme::instance()->appName();
|
||||
|
||||
connect(this, SIGNAL(guiLog(QString,QString)),
|
||||
Logger::instance(), SIGNAL(guiLog(QString,QString)));
|
||||
setNetworkAccessManager( new QNetworkAccessManager( this ) );
|
||||
|
||||
}
|
||||
@@ -164,10 +166,9 @@ QNetworkReply* ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
connect(qhttp, SIGNAL(requestFinished(int, bool)), this,SLOT(qhttpRequestFinished(int,bool)));
|
||||
connect(qhttp, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), this, SLOT(qhttpResponseHeaderReceived(QHttpResponseHeader)));
|
||||
//connect(qhttp, SIGNAL(authenticationRequired(QString,quint16,QAuthenticator*)), this, SLOT(qhttpAuthenticationRequired(QString,quint16,QAuthenticator*)));
|
||||
|
||||
QHttpRequestHeader header("MKCOL", QString(url.encodedPath()), 1,1); /* header */
|
||||
header.setValue("Host", QString(url.encodedHost()));
|
||||
header.setValue("User-Agent", QString("mirall-%1").arg(MIRALL_STRINGIFY(MIRALL_VERSION)).toAscii() );
|
||||
header.setValue("User-Agent", Utility::userAgentString());
|
||||
header.setValue("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
|
||||
header.setValue("Accept-Language", "it,de-de;q=0.8,it-it;q=0.6,en-us;q=0.4,en;q=0.2");
|
||||
header.setValue("Connection", "keep-alive");
|
||||
@@ -482,7 +483,39 @@ bool ownCloudInfo::certsUntrusted()
|
||||
|
||||
void ownCloudInfo::slotError( QNetworkReply::NetworkError err)
|
||||
{
|
||||
qDebug() << "ownCloudInfo Network Error: " << err;
|
||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||
|
||||
qDebug() << "ownCloudInfo Network Error"
|
||||
<< err << ":" << reply->errorString();
|
||||
|
||||
switch (err) {
|
||||
case QNetworkReply::ProxyConnectionRefusedError:
|
||||
emit guiLog(tr("Proxy Refused Connection "),
|
||||
tr("The configured proxy has refused the connection. "
|
||||
"Please check the proxy settings."));
|
||||
break;
|
||||
case QNetworkReply::ProxyConnectionClosedError:
|
||||
emit guiLog(tr("Proxy Closed Connection"),
|
||||
tr("The configured proxy has closed the connection. "
|
||||
"Please check the proxy settings."));
|
||||
break;
|
||||
case QNetworkReply::ProxyNotFoundError:
|
||||
emit guiLog(tr("Proxy Not Found"),
|
||||
tr("The configured proxy could not be found. "
|
||||
"Please check the proxy settings."));
|
||||
break;
|
||||
case QNetworkReply::ProxyAuthenticationRequiredError:
|
||||
emit guiLog(tr("Proxy Authentication Error"),
|
||||
tr("The configured proxy requires login but the proxy credentials "
|
||||
"are invalid. Please check the proxy settings."));
|
||||
break;
|
||||
case QNetworkReply::ProxyTimeoutError:
|
||||
emit guiLog(tr("Proxy Connection Timed Out"),
|
||||
tr("The connection to the configured proxy has timed out."));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ownCloudInfo::setCredentials( const QString& user, const QString& passwd,
|
||||
@@ -511,8 +544,7 @@ void ownCloudInfo::setupHeaders( QNetworkRequest & req, quint64 size )
|
||||
QUrl url( cfgFile.ownCloudUrl( QString::null, false ) );
|
||||
qDebug() << "Setting up host header: " << url.host();
|
||||
req.setRawHeader( QByteArray("Host"), url.host().toUtf8() );
|
||||
req.setRawHeader( QByteArray("User-Agent"), QString::fromLatin1("mirall-%1")
|
||||
.arg(QLatin1String(MIRALL_STRINGIFY(MIRALL_VERSION))).toAscii());
|
||||
req.setRawHeader( QByteArray("User-Agent"), Utility::userAgentString());
|
||||
|
||||
QString con = _configHandle;
|
||||
if( con.isEmpty() ) con = DEFAULT_CONNECTION;
|
||||
|
||||
@@ -118,7 +118,7 @@ signals:
|
||||
|
||||
void webdavColCreated( QNetworkReply::NetworkError );
|
||||
void sslFailed( QNetworkReply *reply, QList<QSslError> errors );
|
||||
|
||||
void guiLog( const QString& title, const QString& content );
|
||||
public slots:
|
||||
|
||||
protected slots:
|
||||
|
||||
@@ -6,14 +6,39 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>540</width>
|
||||
<height>374</height>
|
||||
<width>583</width>
|
||||
<height>448</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QLabel" name="topLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
@@ -30,6 +55,194 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="resultLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QWidget" name="advancedBox" native="true">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Local Folder</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>pbSelectLocalFolder</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pbSelectLocalFolder">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>pbSelectLocalFolder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QWidget" name="resolutionWidget" native="true">
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="radioButton">
|
||||
<property name="text">
|
||||
<string>&Keep local data</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><small>Syncs your existing data to new location.</small></string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="cbSyncFromScratch">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If this box is checked, existing content in the local directory will be erased to start a clean sync from the server.</p><p>Do not check this if the local content should be uploaded to the servers directory.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Start a clean sync</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><small>Erases the contents of the local folder before syncing using the new settings.</small></string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
@@ -128,28 +341,12 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
<string>Error Label</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>48</width>
|
||||
<height>58</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
@@ -209,132 +406,10 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<widget class="QGroupBox" name="advancedBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Local Folder</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>pbSelectLocalFolder</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pbSelectLocalFolder">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>/home/kf/ownCloud</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="selectiveSyncLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Selective Sync:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="selectiveSyncLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbBoxMode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sync Entire &Account</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbSelectiveMode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Choose &Folders</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>43</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="resultLayout"/>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="3">
|
||||
<item row="8" column="0" colspan="3">
|
||||
<widget class="QLabel" name="syncModeLabel">
|
||||
<property name="text">
|
||||
<string>Street Creds Homie!</string>
|
||||
<string>Status message</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
@@ -344,28 +419,44 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="3">
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>48</width>
|
||||
<height>58</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="bottomLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QLabel" name="topLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<item row="6" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
@@ -34,7 +34,7 @@ OwncloudSetupWizard::OwncloudSetupWizard( FolderMan *folderMan, Theme *theme, QO
|
||||
_checkInstallationRequest(0),
|
||||
_folderMan(folderMan)
|
||||
{
|
||||
_ocWizard = new OwncloudWizard;
|
||||
_ocWizard = new OwncloudWizard();
|
||||
|
||||
connect( _ocWizard, SIGNAL(connectToOCUrl( const QString& ) ),
|
||||
this, SLOT(slotConnectToOCUrl( const QString& )));
|
||||
@@ -44,13 +44,12 @@ OwncloudSetupWizard::OwncloudSetupWizard( FolderMan *folderMan, Theme *theme, QO
|
||||
connect( _ocWizard, SIGNAL(clearPendingRequests()),
|
||||
this, SLOT(slotClearPendingRequests()));
|
||||
|
||||
_ocWizard->setWindowTitle( tr("%1 Connection Wizard").arg( theme ? theme->appNameGUI() : QLatin1String("Mirall") ) );
|
||||
|
||||
_ocWizard->setWindowTitle( tr("%1 Connection Wizard").arg( theme->appNameGUI() ) );
|
||||
}
|
||||
|
||||
OwncloudSetupWizard::~OwncloudSetupWizard()
|
||||
{
|
||||
// delete _ocWizard; FIXME: this crashes!
|
||||
_ocWizard->deleteLater();
|
||||
}
|
||||
|
||||
OwncloudWizard *OwncloudSetupWizard::wizard() {
|
||||
@@ -63,28 +62,37 @@ void OwncloudSetupWizard::startWizard()
|
||||
MirallConfigFile cfgFile;
|
||||
// Fill the entry fields with existing values.
|
||||
QString url = cfgFile.ownCloudUrl();
|
||||
if( !url.isEmpty() ) {
|
||||
_ocWizard->setOCUrl( url );
|
||||
}
|
||||
QString user = cfgFile.ownCloudUser();
|
||||
bool configExists = !( url.isEmpty() || user.isEmpty() );
|
||||
_ocWizard->setConfigExists( configExists );
|
||||
|
||||
if( !user.isEmpty() ) {
|
||||
_ocWizard->setOCUser( user );
|
||||
}
|
||||
|
||||
if( !url.isEmpty() ) {
|
||||
_ocWizard->setOCUrl( url );
|
||||
}
|
||||
|
||||
_remoteFolder = Theme::instance()->defaultServerFolder();
|
||||
// remoteFolder may be empty, which means /
|
||||
|
||||
_localFolder = Theme::instance()->defaultClientFolder();
|
||||
QString localFolder = Theme::instance()->defaultClientFolder();
|
||||
|
||||
// if its a relative path, prepend with users home dir, otherwise use as absolute path
|
||||
if( !_localFolder.startsWith(QLatin1Char('/')) ) {
|
||||
_localFolder = QDir::homePath() + QDir::separator() + Theme::instance()->defaultClientFolder();
|
||||
if( !localFolder.startsWith(QLatin1Char('/')) ) {
|
||||
localFolder = QDir::homePath() + QDir::separator() + Theme::instance()->defaultClientFolder();
|
||||
}
|
||||
_ocWizard->setFolderNames(_localFolder, _remoteFolder);
|
||||
_ocWizard->setProperty("localFolder", localFolder);
|
||||
_ocWizard->setRemoteFolder(_remoteFolder);
|
||||
|
||||
_ocWizard->setStartId(OwncloudWizard::Page_oCSetup);
|
||||
|
||||
_ocWizard->restart();
|
||||
|
||||
// settings re-initialized in initPage must be set here after restart
|
||||
_ocWizard->setMultipleFoldersExist(_folderMan->map().count() > 1);
|
||||
|
||||
_ocWizard->show();
|
||||
}
|
||||
|
||||
@@ -105,26 +113,61 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
|
||||
|
||||
// go through all folders and remove the journals if the server changed.
|
||||
MirallConfigFile prevCfg;
|
||||
if( prevCfg.ownCloudUrl() != cfg.ownCloudUrl() ) {
|
||||
qDebug() << "ownCloud URL has changed, journals needs to be wiped.";
|
||||
_folderMan->wipeAllJournals();
|
||||
QUrl prevUrl( prevCfg.ownCloudUrl() );
|
||||
QUrl newUrl( cfg.ownCloudUrl() );
|
||||
|
||||
bool urlHasChanged = (prevUrl.host() != newUrl.host() || prevUrl.path() != newUrl.path());
|
||||
|
||||
// if the user changed, its also a changed url.
|
||||
if( prevCfg.ownCloudUser() != cfg.ownCloudUser() ) {
|
||||
urlHasChanged = true;
|
||||
qDebug() << "The User has changed, same as url change.";
|
||||
}
|
||||
|
||||
// save the user credentials and afterwards clear the cred store.
|
||||
cfg.acceptCustomConfig();
|
||||
const QString localFolder = _ocWizard->localFolder();
|
||||
bool acceptCfg = true;
|
||||
|
||||
// Now write the resulting folder definition if folder names are set.
|
||||
if( !( _localFolder.isEmpty() || _remoteFolder.isEmpty() ) ) { // both variables are set.
|
||||
if( _folderMan ) {
|
||||
_folderMan->addFolderDefinition( QLatin1String("owncloud"), Theme::instance()->appName(),
|
||||
_localFolder, _remoteFolder, false );
|
||||
_ocWizard->appendToConfigurationLog(tr("<font color=\"green\"><b>Local sync folder %1 successfully created!</b></font>").arg(_localFolder));
|
||||
} else {
|
||||
qDebug() << "WRN: Folderman is zero in Setup Wizzard.";
|
||||
if( urlHasChanged ) {
|
||||
_folderMan->unloadAllFolders();
|
||||
|
||||
bool startFromScratch = _ocWizard->field( "OCSyncFromScratch" ).toBool();
|
||||
if( startFromScratch ) {
|
||||
// first try to rename (backup) the current local dir.
|
||||
bool renameOk = false;
|
||||
while( !renameOk ) {
|
||||
renameOk = _folderMan->startFromScratch(localFolder);
|
||||
if( ! renameOk ) {
|
||||
QMessageBox::StandardButton but;
|
||||
but = QMessageBox::question( 0, tr("Folder rename failed"),
|
||||
tr("Can't remove and back up the folder because the folder or a file in it is open in another program."
|
||||
"Please close the folder or file and hit retry or cancel the setup."), QMessageBox::Retry | QMessageBox::Abort, QMessageBox::Retry);
|
||||
if( but == QMessageBox::Abort ) {
|
||||
renameOk = true;
|
||||
acceptCfg = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// save the user credentials and afterwards clear the cred store.
|
||||
if( acceptCfg ) {
|
||||
cfg.acceptCustomConfig();
|
||||
}
|
||||
|
||||
// Now write the resulting folder definition if folder names are set.
|
||||
if( acceptCfg && urlHasChanged ) {
|
||||
_folderMan->removeAllFolderDefinitions();
|
||||
_folderMan->addFolderDefinition( QLatin1String("owncloud"), Theme::instance()->appName(),
|
||||
localFolder, _remoteFolder, false );
|
||||
_ocWizard->appendToConfigurationLog(tr("<font color=\"green\"><b>Local sync folder %1 successfully created!</b></font>").arg(localFolder));
|
||||
} else {
|
||||
// url is unchanged. Only the password was changed.
|
||||
if( acceptCfg ) {
|
||||
qDebug() << "Only password was changed, no changes to folder configuration.";
|
||||
} else {
|
||||
qDebug() << "User interrupted change of configuration.";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qDebug() << "WRN: Got unknown dialog result code " << result;
|
||||
}
|
||||
|
||||
// clear the custom config handle
|
||||
@@ -192,10 +235,8 @@ void OwncloudSetupWizard::testOwnCloudConnect()
|
||||
// If there is already a config, take its proxy config.
|
||||
if( ownCloudInfo::instance()->isConfigured() ) {
|
||||
MirallConfigFile prevCfg;
|
||||
if( prevCfg.proxyType() != QNetworkProxy::DefaultProxy ) {
|
||||
cfgFile.setProxyType( prevCfg.proxyType(), prevCfg.proxyHostName(), prevCfg.proxyPort(),
|
||||
prevCfg.proxyUser(), prevCfg.proxyPassword() );
|
||||
}
|
||||
cfgFile.setProxyType( prevCfg.proxyType(), prevCfg.proxyHostName(), prevCfg.proxyPort(),
|
||||
prevCfg.proxyNeedsAuth(), prevCfg.proxyUser(), prevCfg.proxyPassword() );
|
||||
}
|
||||
|
||||
// now start ownCloudInfo to check the connection.
|
||||
@@ -251,26 +292,27 @@ void OwncloudSetupWizard::setupLocalSyncFolder()
|
||||
{
|
||||
if( ! _folderMan ) return;
|
||||
|
||||
qDebug() << "Setup local sync folder for new oC connection " << _localFolder;
|
||||
QDir fi( _localFolder );
|
||||
const QString localFolder = _ocWizard->property("localFolder").toString();
|
||||
qDebug() << "Setup local sync folder for new oC connection " << localFolder;
|
||||
QDir fi( localFolder );
|
||||
// FIXME: Show problems with local folder properly.
|
||||
|
||||
bool localFolderOk = true;
|
||||
if( fi.exists() ) {
|
||||
// there is an existing local folder. If its non empty, it can only be synced if the
|
||||
// ownCloud is newly created.
|
||||
_ocWizard->appendToConfigurationLog( tr("Local sync folder %1 already exists, setting it up for sync.<br/><br/>").arg(_localFolder));
|
||||
_ocWizard->appendToConfigurationLog( tr("Local sync folder %1 already exists, setting it up for sync.<br/><br/>").arg(localFolder));
|
||||
} else {
|
||||
QString res = tr("Creating local sync folder %1... ").arg(_localFolder);
|
||||
if( fi.mkpath( _localFolder ) ) {
|
||||
Utility::setupFavLink( _localFolder );
|
||||
QString res = tr("Creating local sync folder %1... ").arg(localFolder);
|
||||
if( fi.mkpath( localFolder ) ) {
|
||||
Utility::setupFavLink( localFolder );
|
||||
// FIXME: Create a local sync folder.
|
||||
res += tr("ok");
|
||||
} else {
|
||||
res += tr("failed.");
|
||||
qDebug() << "Failed to create " << fi.path();
|
||||
localFolderOk = false;
|
||||
_ocWizard->displayError(tr("Could not create local folder %1").arg(_localFolder));
|
||||
_ocWizard->displayError(tr("Could not create local folder %1").arg(localFolder));
|
||||
}
|
||||
_ocWizard->appendToConfigurationLog( res );
|
||||
}
|
||||
@@ -305,7 +347,7 @@ void OwncloudSetupWizard::slotAuthCheckReply( const QString&, QNetworkReply *rep
|
||||
qDebug() << "******** Remote folder found, all cool!";
|
||||
} else if( errId == QNetworkReply::AuthenticationRequiredError ) { // returned if the user is wrong.
|
||||
qDebug() << "******** Password is wrong!";
|
||||
error = tr("Credentials are wrong!");
|
||||
error = tr("The given credentials do not authenticate.");
|
||||
ok = false;
|
||||
} else if( errId == QNetworkReply::OperationCanceledError ) {
|
||||
// the username was wrong and ownCloudInfo was closing the request after a couple of auth tries.
|
||||
@@ -328,7 +370,7 @@ void OwncloudSetupWizard::slotAuthCheckReply( const QString&, QNetworkReply *rep
|
||||
if( !ok ) {
|
||||
_ocWizard->displayError(error);
|
||||
} else {
|
||||
_ocWizard->setFolderNames( _localFolder, _remoteFolder );
|
||||
_ocWizard->setRemoteFolder( _remoteFolder );
|
||||
}
|
||||
|
||||
finalizeSetup( ok );
|
||||
@@ -369,13 +411,11 @@ void OwncloudSetupWizard::slotCreateRemoteFolderFinished( QNetworkReply::Network
|
||||
"<br/>Please go back and check your credentials.</p>"));
|
||||
_ocWizard->appendToConfigurationLog( tr("<p><font color=\"red\">Remote folder creation failed probably because the provided credentials are wrong.</font>"
|
||||
"<br/>Please go back and check your credentials.</p>"));
|
||||
_localFolder.clear();
|
||||
_remoteFolder.clear();
|
||||
success = false;
|
||||
} else {
|
||||
_ocWizard->appendToConfigurationLog( tr("Remote folder %1 creation failed with error <tt>%2</tt>.").arg(_remoteFolder).arg(error));
|
||||
_ocWizard->displayError( tr("Remote folder %1 creation failed with error <tt>%2</tt>.").arg(_remoteFolder).arg(error) );
|
||||
_localFolder.clear();
|
||||
_remoteFolder.clear();
|
||||
success = false;
|
||||
}
|
||||
@@ -388,10 +428,11 @@ void OwncloudSetupWizard::finalizeSetup( bool success )
|
||||
// enable/disable the finish button.
|
||||
_ocWizard->enableFinishOnResultWidget(success);
|
||||
|
||||
const QString localFolder = _ocWizard->property("localFolder").toString();
|
||||
if( success ) {
|
||||
if( !(_localFolder.isEmpty() || _remoteFolder.isEmpty() )) {
|
||||
if( !(localFolder.isEmpty() || _remoteFolder.isEmpty() )) {
|
||||
_ocWizard->appendToConfigurationLog( tr("A sync connection from %1 to remote directory %2 was set up.")
|
||||
.arg(_localFolder).arg(_remoteFolder));
|
||||
.arg(localFolder).arg(_remoteFolder));
|
||||
}
|
||||
_ocWizard->appendToConfigurationLog( QLatin1String(" "));
|
||||
_ocWizard->appendToConfigurationLog( QLatin1String("<p><font color=\"green\"><b>")
|
||||
|
||||
@@ -95,7 +95,6 @@ private:
|
||||
FolderMan *_folderMan;
|
||||
|
||||
QString _configHandle;
|
||||
QString _localFolder;
|
||||
QString _remoteFolder;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
#include "owncloudtheme.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
#include <QVariant>
|
||||
#include <QPixmap>
|
||||
#include <QIcon>
|
||||
#include <QStyle>
|
||||
#include <QApplication>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "mirall/version.h"
|
||||
#include "config.h"
|
||||
|
||||
@@ -78,32 +80,6 @@ QString ownCloudTheme::about() const
|
||||
.arg(devString);
|
||||
}
|
||||
|
||||
QPixmap ownCloudTheme::splashScreen() const
|
||||
{
|
||||
return QPixmap(QLatin1String(":/mirall/resources/owncloud_splash.png"));
|
||||
}
|
||||
|
||||
QIcon ownCloudTheme::folderIcon( const QString& backend ) const
|
||||
{
|
||||
QString name;
|
||||
|
||||
if( backend == QLatin1String("owncloud")) {
|
||||
name = QLatin1String( "owncloud-framed" );
|
||||
}
|
||||
if( backend == QLatin1String("unison" )) {
|
||||
name = QLatin1String( "folder-sync" );
|
||||
}
|
||||
if( backend == QLatin1String("csync" )) {
|
||||
name = QLatin1String( "folder-remote" );
|
||||
}
|
||||
if( backend.isEmpty() || backend == QLatin1String("none") ) {
|
||||
name = QLatin1String("folder-grey");
|
||||
}
|
||||
|
||||
qDebug() << "==> load folder icon " << name;
|
||||
return themeIcon( name );
|
||||
}
|
||||
|
||||
QIcon ownCloudTheme::trayFolderIcon( const QString& ) const
|
||||
{
|
||||
QPixmap fallback = qApp->style()->standardPixmap(QStyle::SP_FileDialogNewFolder);
|
||||
@@ -118,7 +94,19 @@ QIcon ownCloudTheme::folderDisabledIcon( ) const
|
||||
|
||||
QIcon ownCloudTheme::applicationIcon( ) const
|
||||
{
|
||||
return themeIcon( QLatin1String("owncloud") );
|
||||
return themeIcon( QLatin1String("owncloud-icon") );
|
||||
}
|
||||
|
||||
QVariant ownCloudTheme::customMedia(Theme::CustomMediaType type)
|
||||
{
|
||||
if (type == Theme::oCSetupTop) {
|
||||
return QCoreApplication::translate("ownCloudTheme",
|
||||
"If you don't have an ownCloud server yet, "
|
||||
"see <a href=\"https://owncloud.com\">owncloud.com</a> for more info.",
|
||||
"Top text in setup wizard. Keep short!");
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QColor ownCloudTheme::wizardHeaderBackgroundColor() const
|
||||
|
||||
@@ -34,6 +34,8 @@ public:
|
||||
QIcon folderDisabledIcon() const;
|
||||
QIcon applicationIcon() const;
|
||||
|
||||
QVariant customMedia(CustomMediaType type);
|
||||
|
||||
QColor wizardHeaderBackgroundColor() const;
|
||||
QColor wizardHeaderTitleColor() const;
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
#include "mirall/owncloudwizard.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/theme.h"
|
||||
#include <QProgressIndicator.h>
|
||||
|
||||
#include "QProgressIndicator.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
@@ -52,26 +53,23 @@ OwncloudSetupPage::OwncloudSetupPage()
|
||||
_ui.setupUi(this);
|
||||
|
||||
Theme *theme = Theme::instance();
|
||||
setTitle( tr("<font color=\"%1\" size=\"5\">Connect to your %2 Server</font>")
|
||||
setTitle( tr("<font color=\"%1\" size=\"5\">Connect to %2</font>")
|
||||
.arg(theme->wizardHeaderTitleColor().name()).arg( theme->appNameGUI()));
|
||||
setSubTitle( tr("<font color=\"%1\">Enter user credentials to access your %2</font>")
|
||||
.arg(theme->wizardHeaderTitleColor().name()).arg(theme->appNameGUI()));
|
||||
|
||||
connect(_ui.leUrl, SIGNAL(textChanged(QString)), SLOT(handleNewOcUrl(QString)));
|
||||
setSubTitle( tr("<font color=\"%1\">Enter user credentials</font>")
|
||||
.arg(theme->wizardHeaderTitleColor().name()));
|
||||
|
||||
registerField( QLatin1String("OCUrl"), _ui.leUrl );
|
||||
registerField( QLatin1String("OCUser"), _ui.leUsername );
|
||||
registerField( QLatin1String("OCPasswd"), _ui.lePassword);
|
||||
connect( _ui.lePassword, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged()));
|
||||
connect( _ui.leUsername, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged()));
|
||||
connect( _ui.cbAdvanced, SIGNAL(stateChanged (int)), SLOT(slotToggleAdvanced(int)));
|
||||
connect( _ui.pbSelectLocalFolder, SIGNAL(clicked()), SLOT(slotSelectFolder()));
|
||||
registerField( QLatin1String("OCSyncFromScratch"), _ui.cbSyncFromScratch);
|
||||
|
||||
_ui.errorLabel->setVisible(true);
|
||||
_ui.advancedBox->setVisible(false);
|
||||
|
||||
_progressIndi = new QProgressIndicator;
|
||||
_ui.resultLayout->addWidget( _progressIndi );
|
||||
_progressIndi->setVisible(false);
|
||||
_ui.resultLayout->setEnabled(false);
|
||||
|
||||
// Error label
|
||||
QString style = QLatin1String("border: 1px solid #eed3d7; border-radius: 5px; padding: 3px;"
|
||||
@@ -82,20 +80,17 @@ OwncloudSetupPage::OwncloudSetupPage()
|
||||
_ui.errorLabel->setWordWrap(true);
|
||||
_ui.errorLabel->setVisible(false);
|
||||
|
||||
// ButtonGroup for
|
||||
_selectiveSyncButtons = new QButtonGroup;
|
||||
_selectiveSyncButtons->addButton( _ui.pbBoxMode );
|
||||
_selectiveSyncButtons->addButton( _ui.pbSelectiveMode );
|
||||
connect( _selectiveSyncButtons, SIGNAL(buttonClicked (QAbstractButton*)),
|
||||
SLOT(slotChangedSelective(QAbstractButton*)));
|
||||
|
||||
_ui.selectiveSyncLabel->setVisible(false);
|
||||
_ui.pbBoxMode->setVisible(false);
|
||||
_ui.pbSelectiveMode->setVisible(false);
|
||||
|
||||
_checking = false;
|
||||
|
||||
setupCustomization();
|
||||
|
||||
connect(_ui.leUrl, SIGNAL(textChanged(QString)), SLOT(slotUrlChanged(QString)));
|
||||
connect( _ui.leUsername, SIGNAL(textChanged(QString)), this, SLOT(slotUserChanged(QString)));
|
||||
|
||||
connect( _ui.lePassword, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged()));
|
||||
connect( _ui.leUsername, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged()));
|
||||
connect( _ui.cbAdvanced, SIGNAL(stateChanged (int)), SLOT(slotToggleAdvanced(int)));
|
||||
connect( _ui.pbSelectLocalFolder, SIGNAL(clicked()), SLOT(slotSelectFolder()));
|
||||
}
|
||||
|
||||
OwncloudSetupPage::~OwncloudSetupPage()
|
||||
@@ -106,49 +101,41 @@ OwncloudSetupPage::~OwncloudSetupPage()
|
||||
void OwncloudSetupPage::slotToggleAdvanced(int state)
|
||||
{
|
||||
_ui.advancedBox->setVisible( state == Qt::Checked );
|
||||
wizard()->resize(wizard()->sizeHint());
|
||||
}
|
||||
slotHandleUserInput();
|
||||
QSize size = wizard()->sizeHint();
|
||||
// need to substract header for some reason
|
||||
size -= QSize(0, 63);
|
||||
|
||||
void OwncloudSetupPage::slotChangedSelective(QAbstractButton* button)
|
||||
{
|
||||
if( button = _ui.pbBoxMode ) {
|
||||
// box mode - sync the entire oC
|
||||
} else {
|
||||
// content mode, select folder list.
|
||||
}
|
||||
wizard()->setMinimumSize(size);
|
||||
wizard()->resize(size);
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setOCUser( const QString & user )
|
||||
{
|
||||
if( _ui.leUsername->text().isEmpty() ) {
|
||||
_ui.leUsername->setText(user);
|
||||
}
|
||||
_ocUser = user;
|
||||
_ui.leUsername->setText(user);
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setServerUrl( const QString& newUrl )
|
||||
{
|
||||
QString url( newUrl );
|
||||
if( url.isEmpty() ) {
|
||||
_oCUrl = newUrl;
|
||||
if( _oCUrl.isEmpty() ) {
|
||||
_ui.leUrl->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
_ui.leUrl->setText( url );
|
||||
_ui.leUrl->setText( _oCUrl );
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setupCustomization()
|
||||
{
|
||||
// set defaults for the customize labels.
|
||||
|
||||
// _ui.topLabel->hide();
|
||||
_ui.topLabel->hide();
|
||||
_ui.bottomLabel->hide();
|
||||
|
||||
Theme *theme = Theme::instance();
|
||||
QVariant variant = theme->customMedia( Theme::oCSetupTop );
|
||||
if( variant.isNull() ) {
|
||||
_ui.topLabel->setOpenExternalLinks(true);
|
||||
_ui.topLabel->setText("If you don't have an ownCloud server yet, see <a href=\"https://owncloud.com\">owncloud.com</a> for more info.");
|
||||
} else {
|
||||
if( !variant.isNull() ) {
|
||||
setupCustomMedia( variant, _ui.topLabel );
|
||||
}
|
||||
|
||||
@@ -157,19 +144,27 @@ void OwncloudSetupPage::setupCustomization()
|
||||
|
||||
QString fixUrl = theme->overrideServerUrl();
|
||||
if( !fixUrl.isEmpty() ) {
|
||||
_ui.label_2->hide();
|
||||
setServerUrl( fixUrl );
|
||||
_ui.leUrl->setEnabled( false );
|
||||
_ui.leUrl->hide();
|
||||
}
|
||||
}
|
||||
|
||||
// slot hit from textChanged of the url entry field.
|
||||
void OwncloudSetupPage::handleNewOcUrl(const QString& ocUrl)
|
||||
void OwncloudSetupPage::slotUserChanged(const QString& user )
|
||||
{
|
||||
QString url = ocUrl;
|
||||
int len = 0;
|
||||
bool visible = false;
|
||||
slotHandleUserInput();
|
||||
}
|
||||
|
||||
// slot hit from textChanged of the url entry field.
|
||||
void OwncloudSetupPage::slotUrlChanged(const QString& ocUrl)
|
||||
{
|
||||
slotHandleUserInput();
|
||||
|
||||
#if 0
|
||||
QString url = ocUrl;
|
||||
bool visible = false;
|
||||
|
||||
if (url.startsWith(QLatin1String("https://"))) {
|
||||
_ui.urlLabel->setPixmap( QPixmap(":/mirall/resources/security-high.png"));
|
||||
_ui.urlLabel->setToolTip(tr("This url is secure. You can use it."));
|
||||
@@ -181,7 +176,6 @@ void OwncloudSetupPage::handleNewOcUrl(const QString& ocUrl)
|
||||
visible = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool OwncloudSetupPage::isComplete() const
|
||||
@@ -196,6 +190,107 @@ void OwncloudSetupPage::initializePage()
|
||||
{
|
||||
_connected = false;
|
||||
_checking = false;
|
||||
_multipleFoldersExist = false;
|
||||
|
||||
// call to init label
|
||||
slotHandleUserInput();
|
||||
|
||||
if( _configExists ) {
|
||||
_ui.lePassword->setFocus();
|
||||
} else {
|
||||
_ui.leUrl->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
bool OwncloudSetupPage::urlHasChanged()
|
||||
{
|
||||
bool change = false;
|
||||
const QChar slash('/');
|
||||
|
||||
QUrl currentUrl( url() );
|
||||
QUrl initialUrl( _oCUrl );
|
||||
|
||||
QString currentPath = currentUrl.path();
|
||||
QString initialPath = initialUrl.path();
|
||||
|
||||
// add a trailing slash.
|
||||
if( ! currentPath.endsWith( slash )) currentPath += slash;
|
||||
if( ! initialPath.endsWith( slash )) initialPath += slash;
|
||||
|
||||
if( currentUrl.host() != initialUrl.host() ||
|
||||
currentPath != initialPath ) {
|
||||
change = true;
|
||||
}
|
||||
|
||||
if( !change) { // no change yet, check the user.
|
||||
QString user = _ui.leUsername->text().simplified();
|
||||
if( user != _ocUser ) change = true;
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
// Called if the user changes the user- or url field. Adjust the texts and
|
||||
// evtl. warnings on the dialog.
|
||||
void OwncloudSetupPage::slotHandleUserInput()
|
||||
{
|
||||
// if the url has not changed, return.
|
||||
if( ! urlHasChanged() ) {
|
||||
// disable the advanced button as nothing has changed.
|
||||
_ui.cbAdvanced->setEnabled(false);
|
||||
_ui.advancedBox->setEnabled(false);
|
||||
} else {
|
||||
// Enable advanced stuff for new connection configuration.
|
||||
_ui.cbAdvanced->setEnabled(true);
|
||||
_ui.advancedBox->setEnabled(true);
|
||||
}
|
||||
|
||||
const QString locFolder = localFolder();
|
||||
|
||||
// check if the local folder exists. If so, and if its not empty, show a warning.
|
||||
QDir dir( locFolder );
|
||||
QStringList entries = dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
|
||||
|
||||
QString t;
|
||||
|
||||
if( !urlHasChanged() && _configExists ) {
|
||||
// This is the password change mode: No change to the url and a config
|
||||
// to an ownCloud exists.
|
||||
t = tr("Change the Password for your configured account.");
|
||||
} else {
|
||||
// Complete new setup.
|
||||
_ui.pbSelectLocalFolder->setText(QDir::toNativeSeparators(locFolder));
|
||||
|
||||
if( _remoteFolder.isEmpty() || _remoteFolder == QLatin1String("/") ) {
|
||||
t = tr("Your entire account will be synced to the local folder '%1'.")
|
||||
.arg(QDir::toNativeSeparators(locFolder));
|
||||
} else {
|
||||
t = tr("%1 folder '%2' is synced to local folder '%3'")
|
||||
.arg(Theme::instance()->appName()).arg(_remoteFolder)
|
||||
.arg(QDir::toNativeSeparators(locFolder));
|
||||
}
|
||||
|
||||
if ( _multipleFoldersExist ) {
|
||||
t += tr("<p><small><strong>Warning:</strong> You currently have multiple folders "
|
||||
"configured. If you continue with the current settings, the folder configurations "
|
||||
"will be discarded and a single root folder sync will be created!</small></p>");
|
||||
}
|
||||
|
||||
if( entries.count() > 0) {
|
||||
// the directory is not empty
|
||||
if (!_ui.cbAdvanced->isChecked()) {
|
||||
t += tr("<p><small><strong>Warning:</strong> The local directory is not empty. "
|
||||
"Pick a resolution in the advanced settings!</small></p>");
|
||||
}
|
||||
_ui.resolutionWidget->setVisible(true);
|
||||
} else {
|
||||
// the dir is empty, which means that there is no problem.
|
||||
_ui.resolutionWidget->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
_ui.syncModeLabel->setText(t);
|
||||
_ui.syncModeLabel->setFixedHeight(_ui.syncModeLabel->sizeHint().height());
|
||||
}
|
||||
|
||||
int OwncloudSetupPage::nextId() const
|
||||
@@ -209,9 +304,16 @@ QString OwncloudSetupPage::url() const
|
||||
return url;
|
||||
}
|
||||
|
||||
QString OwncloudSetupPage::localFolder() const
|
||||
{
|
||||
QString folder = wizard()->property("localFolder").toString();
|
||||
return folder;
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setConnected( bool comp )
|
||||
{
|
||||
_connected = comp;
|
||||
_ui.resultLayout->setEnabled(true);
|
||||
_progressIndi->setVisible(false);
|
||||
_progressIndi->stopAnimation();
|
||||
}
|
||||
@@ -223,6 +325,7 @@ bool OwncloudSetupPage::validatePage()
|
||||
if( ! _connected) {
|
||||
setErrorString(QString::null);
|
||||
_checking = true;
|
||||
_ui.resultLayout->setEnabled(true);
|
||||
_progressIndi->setVisible(true);
|
||||
_progressIndi->startAnimation();
|
||||
emit completeChanged();
|
||||
@@ -253,40 +356,26 @@ void OwncloudSetupPage::setErrorString( const QString& err )
|
||||
|
||||
void OwncloudSetupPage::stopSpinner()
|
||||
{
|
||||
// _ui.addressLayout->removeWidget( _progressIndi );
|
||||
|
||||
_ui.resultLayout->setEnabled(false);
|
||||
_progressIndi->setVisible(false);
|
||||
_progressIndi->stopAnimation();
|
||||
}
|
||||
|
||||
OwncloudSetupPage::SyncMode OwncloudSetupPage::syncMode()
|
||||
{
|
||||
if( _selectiveSyncButtons->checkedButton() &&
|
||||
_selectiveSyncButtons->checkedButton() == _ui.pbSelectiveMode ) {
|
||||
return SelectiveMode;
|
||||
}
|
||||
return BoxMode;
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setFolderNames( const QString& localFolder, const QString& remoteFolder )
|
||||
void OwncloudSetupPage::setRemoteFolder( const QString& remoteFolder )
|
||||
{
|
||||
_ui.pbSelectLocalFolder->setText(localFolder);
|
||||
if( !remoteFolder.isEmpty() )
|
||||
if( !remoteFolder.isEmpty() ) {
|
||||
_remoteFolder = remoteFolder;
|
||||
|
||||
QString t;
|
||||
if( _remoteFolder.isEmpty() || _remoteFolder == QLatin1String("/") ) {
|
||||
t = tr("Your entire account will be synced to the local folder '%1'").arg(localFolder);
|
||||
} else {
|
||||
t = tr("ownCloud folder '%1' is synced to local folder '%2'").arg(_remoteFolder).arg(localFolder);
|
||||
}
|
||||
|
||||
_ui.syncModeLabel->setText(t);
|
||||
}
|
||||
|
||||
QString OwncloudSetupPage::selectedLocalFolder() const
|
||||
void OwncloudSetupPage::setMultipleFoldersExist(bool exist)
|
||||
{
|
||||
return _ui.pbSelectLocalFolder->text();
|
||||
_multipleFoldersExist = exist;
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::slotSelectFolder()
|
||||
@@ -294,7 +383,9 @@ void OwncloudSetupPage::slotSelectFolder()
|
||||
|
||||
QString dir = QFileDialog::getExistingDirectory(0, tr("Local Sync Folder"), QDir::homePath());
|
||||
if( !dir.isEmpty() ) {
|
||||
setFolderNames(dir);
|
||||
_ui.pbSelectLocalFolder->setText(dir);
|
||||
wizard()->setProperty("localFolder", dir);
|
||||
slotHandleUserInput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,6 +395,21 @@ OwncloudSetupPage::SyncMode OwncloudWizard::syncMode()
|
||||
return OwncloudSetupPage::BoxMode;
|
||||
}
|
||||
|
||||
void OwncloudWizard::setMultipleFoldersExist(bool exist)
|
||||
{
|
||||
_setupPage->setMultipleFoldersExist(exist);
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setConfigExists( bool config )
|
||||
{
|
||||
_configExists = config;
|
||||
|
||||
if (config == true) {
|
||||
setSubTitle( tr("<font color=\"%1\">Change your user credentials</font>")
|
||||
.arg(Theme::instance()->wizardHeaderTitleColor().name()));
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
OwncloudWizardResultPage::OwncloudWizardResultPage()
|
||||
@@ -314,8 +420,8 @@ OwncloudWizardResultPage::OwncloudWizardResultPage()
|
||||
Theme *theme = Theme::instance();
|
||||
setTitle( tr("<font color=\"%1\" size=\"5\">Everything set up!</font>")
|
||||
.arg(theme->wizardHeaderTitleColor().name()));
|
||||
setSubTitle( tr("<font color=\"%1\">Enter user credentials to access your %2</font>")
|
||||
.arg(theme->wizardHeaderTitleColor().name()).arg(theme->appNameGUI()));
|
||||
// required to show header in QWizard's modern style
|
||||
setSubTitle( QLatin1String(" ") );
|
||||
|
||||
_ui.pbOpenLocal->setText("Open local folder");
|
||||
_ui.pbOpenServer->setText(tr("Open %1").arg(Theme::instance()->appNameGUI()));
|
||||
@@ -327,8 +433,8 @@ OwncloudWizardResultPage::OwncloudWizardResultPage()
|
||||
|
||||
_ui.pbOpenLocal->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
|
||||
// _ui.pbOpenServer->setIcon(QIcon(":/mirall/resources/owncloud_logo_blue.png"));
|
||||
_ui.pbOpenServer->setIcon(theme->applicationIcon().pixmap(48));
|
||||
QIcon appIcon = theme->applicationIcon();
|
||||
_ui.pbOpenServer->setIcon(appIcon.pixmap(48));
|
||||
_ui.pbOpenServer->setText(tr("Open %1").arg(theme->appNameGUI()));
|
||||
_ui.pbOpenServer->setIconSize(QSize(48, 48));
|
||||
_ui.pbOpenServer->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
@@ -351,19 +457,25 @@ bool OwncloudWizardResultPage::isComplete() const
|
||||
return _complete;
|
||||
}
|
||||
|
||||
void OwncloudWizardResultPage::setFolderNames( const QString& localFolder, const QString& remoteFolder )
|
||||
void OwncloudWizardResultPage::initializePage()
|
||||
{
|
||||
_localFolder = localFolder;
|
||||
const QString localFolder = wizard()->property("localFolder").toString();
|
||||
QString text;
|
||||
if( remoteFolder == QLatin1String("/") ||
|
||||
remoteFolder.isEmpty() ) {
|
||||
text = tr("Your entire account is synced to the local folder <i>%1</i>").arg(localFolder);
|
||||
if( _remoteFolder == QLatin1String("/") || _remoteFolder.isEmpty() ) {
|
||||
text = tr("Your entire account is synced to the local folder <i>%1</i>")
|
||||
.arg(QDir::toNativeSeparators(localFolder));
|
||||
} else {
|
||||
text = tr("ownCloud folder <i>%1</i> is synced to local folder <i>%2</i>").arg(remoteFolder).arg(localFolder);
|
||||
text = tr("ownCloud folder <i>%1</i> is synced to local folder <i>%2</i>")
|
||||
.arg(_remoteFolder).arg(QDir::toNativeSeparators(localFolder));
|
||||
}
|
||||
_ui.localFolderLabel->setText( text );
|
||||
|
||||
}
|
||||
|
||||
void OwncloudWizardResultPage::setRemoteFolder(const QString &remoteFolder)
|
||||
{
|
||||
_remoteFolder = remoteFolder;
|
||||
}
|
||||
|
||||
void OwncloudWizardResultPage::setupCustomization()
|
||||
{
|
||||
@@ -382,7 +494,8 @@ void OwncloudWizardResultPage::setupCustomization()
|
||||
*/
|
||||
|
||||
OwncloudWizard::OwncloudWizard(QWidget *parent)
|
||||
: QWizard(parent)
|
||||
: QWizard(parent),
|
||||
_configExists(false)
|
||||
{
|
||||
_setupPage = new OwncloudSetupPage;
|
||||
_resultPage = new OwncloudWizardResultPage;
|
||||
@@ -409,6 +522,11 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
||||
setSubTitleFormat(Qt::RichText);
|
||||
}
|
||||
|
||||
QString OwncloudWizard::localFolder() const
|
||||
{
|
||||
return(_setupPage->localFolder());
|
||||
}
|
||||
|
||||
QString OwncloudWizard::ocUrl() const
|
||||
{
|
||||
QString url = field("OCUrl").toString().simplified();
|
||||
@@ -420,10 +538,10 @@ void OwncloudWizard::enableFinishOnResultWidget(bool enable)
|
||||
_resultPage->setComplete(enable);
|
||||
}
|
||||
|
||||
void OwncloudWizard::setFolderNames( const QString& localFolder, const QString& remoteFolder )
|
||||
void OwncloudWizard::setRemoteFolder( const QString& remoteFolder )
|
||||
{
|
||||
_setupPage->setFolderNames( localFolder, remoteFolder );
|
||||
_resultPage->setFolderNames( localFolder, remoteFolder );
|
||||
_setupPage->setRemoteFolder( remoteFolder );
|
||||
_resultPage->setRemoteFolder( remoteFolder );
|
||||
}
|
||||
|
||||
void OwncloudWizard::showConnectInfo( const QString& msg )
|
||||
@@ -471,7 +589,6 @@ void OwncloudWizard::appendToConfigurationLog( const QString& msg, LogType type
|
||||
|
||||
void OwncloudWizard::setOCUrl( const QString& url )
|
||||
{
|
||||
_oCUrl = url;
|
||||
_setupPage->setServerUrl( url );
|
||||
}
|
||||
|
||||
@@ -481,9 +598,21 @@ void OwncloudWizard::setOCUser( const QString& user )
|
||||
_setupPage->setOCUser( user );
|
||||
}
|
||||
|
||||
void OwncloudWizard::setConfigExists( bool config )
|
||||
{
|
||||
_configExists = config;
|
||||
_setupPage->setConfigExists( config );
|
||||
}
|
||||
|
||||
bool OwncloudWizard::configExists()
|
||||
{
|
||||
return _configExists;
|
||||
}
|
||||
|
||||
void OwncloudWizardResultPage::slotOpenLocal()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl(_localFolder));
|
||||
const QString localFolder = wizard()->property("localFolder").toString();
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(localFolder));
|
||||
}
|
||||
|
||||
void OwncloudWizardResultPage::slotOpenServer()
|
||||
@@ -493,4 +622,5 @@ void OwncloudWizardResultPage::slotOpenServer()
|
||||
QDesktopServices::openUrl(url);
|
||||
}
|
||||
|
||||
|
||||
} // end namespace
|
||||
|
||||
@@ -50,31 +50,46 @@ public:
|
||||
void setAllowPasswordStorage( bool );
|
||||
bool validatePage();
|
||||
QString url() const;
|
||||
QString localFolder() const;
|
||||
void setConnected(bool complete);
|
||||
QString selectedLocalFolder() const;
|
||||
void setFolderNames( const QString&, const QString& remoteFolder = QString::null);
|
||||
void setRemoteFolder( const QString& remoteFolder);
|
||||
void setMultipleFoldersExist( bool exist );
|
||||
|
||||
SyncMode syncMode();
|
||||
|
||||
public slots:
|
||||
void setErrorString( const QString& );
|
||||
void setConfigExists( bool );
|
||||
void stopSpinner();
|
||||
|
||||
protected slots:
|
||||
void handleNewOcUrl(const QString& ocUrl);
|
||||
void slotUrlChanged(const QString&);
|
||||
void slotUserChanged(const QString&);
|
||||
|
||||
void setupCustomization();
|
||||
void slotToggleAdvanced(int state);
|
||||
void slotChangedSelective(QAbstractButton*);
|
||||
void slotSelectFolder();
|
||||
|
||||
signals:
|
||||
void connectToOCUrl( const QString& );
|
||||
|
||||
protected:
|
||||
void updateFoldersInfo();
|
||||
|
||||
private slots:
|
||||
void slotHandleUserInput();
|
||||
|
||||
private:
|
||||
bool urlHasChanged();
|
||||
|
||||
Ui_OwncloudSetupPage _ui;
|
||||
QString _oCUrl;
|
||||
QString _ocUser;
|
||||
bool _connected;
|
||||
bool _checking;
|
||||
bool _configExists;
|
||||
bool _multipleFoldersExist;
|
||||
|
||||
QProgressIndicator *_progressIndi;
|
||||
QButtonGroup *_selectiveSyncButtons;
|
||||
QString _remoteFolder;
|
||||
@@ -95,21 +110,25 @@ public:
|
||||
LogParagraph
|
||||
};
|
||||
|
||||
OwncloudWizard(QWidget *parent = 0L);
|
||||
OwncloudWizard(QWidget *parent = 0);
|
||||
|
||||
void setOCUrl( const QString& );
|
||||
void setOCUser( const QString& );
|
||||
|
||||
void setupCustomMedia( QVariant, QLabel* );
|
||||
QString ocUrl() const;
|
||||
QString localFolder() const;
|
||||
|
||||
void enableFinishOnResultWidget(bool enable);
|
||||
|
||||
void displayError( const QString& );
|
||||
OwncloudSetupPage::SyncMode syncMode();
|
||||
void setMultipleFoldersExist( bool );
|
||||
void setConfigExists( bool );
|
||||
bool configExists();
|
||||
|
||||
public slots:
|
||||
void setFolderNames( const QString&, const QString& );
|
||||
void setRemoteFolder( const QString& );
|
||||
void appendToConfigurationLog( const QString& msg, LogType type = LogParagraph );
|
||||
void slotCurrentPageChanged( int );
|
||||
|
||||
@@ -125,9 +144,9 @@ private:
|
||||
OwncloudWizardResultPage *_resultPage;
|
||||
|
||||
QString _configFile;
|
||||
QString _oCUrl;
|
||||
QString _oCUser;
|
||||
QStringList _setupLog;
|
||||
bool _configExists;
|
||||
};
|
||||
|
||||
|
||||
@@ -146,10 +165,11 @@ public:
|
||||
~OwncloudWizardResultPage();
|
||||
|
||||
bool isComplete() const;
|
||||
void initializePage();
|
||||
void setRemoteFolder( const QString& remoteFolder);
|
||||
|
||||
public slots:
|
||||
void setComplete(bool complete);
|
||||
void setFolderNames( const QString&, const QString& );
|
||||
|
||||
protected slots:
|
||||
void slotOpenLocal();
|
||||
@@ -160,6 +180,7 @@ protected:
|
||||
|
||||
private:
|
||||
QString _localFolder;
|
||||
QString _remoteFolder;
|
||||
bool _complete;
|
||||
|
||||
Ui_OwncloudWizardResultPage _ui;
|
||||
|
||||
@@ -35,21 +35,33 @@ Mirall::ProxyDialog::ProxyDialog( QWidget* parent )
|
||||
|
||||
// load current proxy settings
|
||||
Mirall::MirallConfigFile cfgFile;
|
||||
if (cfgFile.proxyType() == QNetworkProxy::NoProxy)
|
||||
switch (cfgFile.proxyType()) {
|
||||
case QNetworkProxy::NoProxy:
|
||||
noProxyRadioButton->setChecked(true);
|
||||
if (cfgFile.proxyType() == QNetworkProxy::DefaultProxy)
|
||||
break;
|
||||
case QNetworkProxy::DefaultProxy:
|
||||
systemProxyRadioButton->setChecked(true);
|
||||
if (cfgFile.proxyType() == QNetworkProxy::HttpProxy)
|
||||
{
|
||||
break;
|
||||
case QNetworkProxy::Socks5Proxy:
|
||||
cbSocks->setChecked(true);
|
||||
// fall through
|
||||
case QNetworkProxy::HttpProxy:
|
||||
case QNetworkProxy::HttpCachingProxy:
|
||||
manualProxyRadioButton->setChecked(true);
|
||||
hostLineEdit->setText(cfgFile.proxyHostName());
|
||||
portSpinBox->setValue(cfgFile.proxyPort());
|
||||
if (!cfgFile.proxyUser().isEmpty())
|
||||
{
|
||||
authRequiredcheckBox->setChecked(true);
|
||||
userLineEdit->setText(cfgFile.proxyUser());
|
||||
passwordLineEdit->setText(cfgFile.proxyPassword());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hostLineEdit->setText(cfgFile.proxyHostName());
|
||||
int port = cfgFile.proxyPort();
|
||||
if (port == 0) port = 8080;
|
||||
portSpinBox->setValue(port);
|
||||
if (!cfgFile.proxyUser().isEmpty())
|
||||
{
|
||||
authRequiredcheckBox->setChecked(true);
|
||||
userLineEdit->setText(cfgFile.proxyUser());
|
||||
passwordLineEdit->setText(cfgFile.proxyPassword());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,18 +79,14 @@ void Mirall::ProxyDialog::saveSettings()
|
||||
}
|
||||
if (manualProxyRadioButton->isChecked())
|
||||
{
|
||||
if (authRequiredcheckBox->isChecked())
|
||||
{
|
||||
QString user = userLineEdit->text();
|
||||
QString pass = passwordLineEdit->text();
|
||||
cfgFile.setProxyType(QNetworkProxy::HttpProxy, hostLineEdit->text(),
|
||||
portSpinBox->value(), user, pass);
|
||||
}
|
||||
else
|
||||
{
|
||||
cfgFile.setProxyType(QNetworkProxy::HttpProxy, hostLineEdit->text(),
|
||||
portSpinBox->value(), QString::null, QString::null);
|
||||
}
|
||||
int proxyType = cbSocks->isChecked() ? QNetworkProxy::Socks5Proxy
|
||||
: QNetworkProxy::HttpProxy;
|
||||
QString user = userLineEdit->text();
|
||||
QString pass = passwordLineEdit->text();
|
||||
cfgFile.setProxyType(proxyType, hostLineEdit->text(),
|
||||
portSpinBox->value(),
|
||||
authRequiredcheckBox->isChecked(),
|
||||
user, pass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,38 +6,15 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>465</width>
|
||||
<height>291</height>
|
||||
<width>405</width>
|
||||
<height>319</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Proxy Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@@ -76,18 +53,82 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>40</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="hostLabel">
|
||||
<property name="text">
|
||||
<string>Host</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="hostLineEdit">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="portLabel">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="portSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>8080</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbSocks">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use as SOCKSv5 proxy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="authRequiredcheckBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Proxy server requires password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="proxyUserLabel">
|
||||
<property name="enabled">
|
||||
@@ -143,70 +184,34 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="portLabel">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="hostLabel">
|
||||
<property name="text">
|
||||
<string>Host</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="hostLineEdit">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="authRequiredcheckBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Proxy server requires password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="portSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>8080</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
||||
@@ -64,40 +64,33 @@ FolderViewDelegate::~FolderViewDelegate()
|
||||
QSize FolderViewDelegate::sizeHint(const QStyleOptionViewItem & option ,
|
||||
const QModelIndex & index) const
|
||||
{
|
||||
int w = 0;
|
||||
|
||||
QString p = qvariant_cast<QString>(index.data(FolderPathRole));
|
||||
QFont aliasFont = QApplication::font();
|
||||
QFont font = QApplication::font();
|
||||
Q_UNUSED(option)
|
||||
QFont aliasFont = option.font;
|
||||
QFont font = option.font;
|
||||
aliasFont.setPointSize( font.pointSize() +2 );
|
||||
|
||||
QFontMetrics fm(font);
|
||||
QFontMetrics aliasFm(aliasFont);
|
||||
|
||||
int margin = aliasFm.height()/2;
|
||||
|
||||
w = 8 + fm.boundingRect( p ).width();
|
||||
int aliasMargin = aliasFm.height()/2;
|
||||
int margin = fm.height()/4;
|
||||
|
||||
// calc height
|
||||
|
||||
int h = margin; // margin to top
|
||||
int h = aliasMargin; // margin to top
|
||||
h += aliasFm.height(); // alias
|
||||
h += fm.height()/2; // between alias and local path
|
||||
h += margin; // between alias and local path
|
||||
h += fm.height(); // local path
|
||||
h += fm.height()/2; // between local and remote path
|
||||
h += margin; // between local and remote path
|
||||
h += fm.height(); // remote path
|
||||
h += margin; // bottom margin
|
||||
|
||||
int minHeight = 48 + margin + margin; // icon + margins
|
||||
|
||||
if( h < minHeight ) h = minHeight;
|
||||
h += aliasMargin; // bottom margin
|
||||
|
||||
// add some space to show an error condition.
|
||||
if( ! qvariant_cast<QString>(index.data(FolderErrorMsg)).isEmpty() ) {
|
||||
h += margin+fm.height();
|
||||
h += aliasMargin*2+fm.height();
|
||||
}
|
||||
|
||||
return QSize( w, h );
|
||||
return QSize( 0, h);
|
||||
}
|
||||
|
||||
void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
@@ -107,8 +100,8 @@ void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
||||
|
||||
painter->save();
|
||||
|
||||
QFont aliasFont = QApplication::font();
|
||||
QFont subFont = QApplication::font();
|
||||
QFont aliasFont = option.font;
|
||||
QFont subFont = option.font;
|
||||
QFont errorFont = subFont;
|
||||
|
||||
//font.setPixelSize(font.weight()+);
|
||||
@@ -117,10 +110,11 @@ void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
||||
|
||||
QFontMetrics subFm( subFont );
|
||||
QFontMetrics aliasFm( aliasFont );
|
||||
int margin = aliasFm.height()/2;
|
||||
|
||||
QIcon folderIcon = qvariant_cast<QIcon>(index.data(FolderIconRole));
|
||||
QIcon statusIcon = qvariant_cast<QIcon>(index.data(FolderStatusIcon));
|
||||
int aliasMargin = aliasFm.height()/2;
|
||||
int margin = subFm.height()/4;
|
||||
|
||||
QIcon statusIcon = qvariant_cast<QIcon>(index.data(FolderStatusIconRole));
|
||||
QString aliasText = qvariant_cast<QString>(index.data(FolderAliasRole));
|
||||
QString pathText = qvariant_cast<QString>(index.data(FolderPathRole));
|
||||
QString remotePath = qvariant_cast<QString>(index.data(FolderSecondPathRole));
|
||||
@@ -130,72 +124,80 @@ void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
||||
bool syncEnabled = index.data(FolderSyncEnabled).toBool();
|
||||
// QString syncStatus = syncEnabled? tr( "Enabled" ) : tr( "Disabled" );
|
||||
|
||||
QSize iconsize(48, 48); // = icon.actualSize(option.decorationSize);
|
||||
|
||||
QRect aliasRect = option.rect;
|
||||
QRect iconRect = option.rect;
|
||||
QRect aliasRect = option.rect;
|
||||
|
||||
iconRect.setLeft( margin );
|
||||
iconRect.setWidth( 48 );
|
||||
iconRect.setTop( iconRect.top() + margin ); // (iconRect.height()-iconsize.height())/2);
|
||||
iconRect.setLeft( aliasMargin );
|
||||
iconRect.setTop( iconRect.top() + aliasMargin ); // (iconRect.height()-iconsize.height())/2);
|
||||
|
||||
QRect statusRect = iconRect;
|
||||
statusRect.setLeft( option.rect.right() - margin - 48 );
|
||||
statusRect.setRight( option.rect.right() - margin );
|
||||
|
||||
aliasRect.setLeft(iconRect.right()+margin);
|
||||
|
||||
aliasRect.setTop(aliasRect.top() + aliasFm.height()/2 );
|
||||
aliasRect.setBottom(aliasRect.top()+subFm.height());
|
||||
// local directory box
|
||||
aliasRect.setTop(aliasRect.top() + aliasMargin );
|
||||
aliasRect.setBottom(aliasRect.top() + aliasFm.height());
|
||||
aliasRect.setRight(aliasRect.right() - aliasMargin );
|
||||
|
||||
// local directory box
|
||||
QRect localPathRect = aliasRect;
|
||||
localPathRect.setTop(aliasRect.bottom() + margin / 3);
|
||||
localPathRect.setBottom(localPathRect.top()+subFm.height());
|
||||
localPathRect.setTop(aliasRect.bottom() + margin );
|
||||
localPathRect.setBottom(localPathRect.top() + subFm.height());
|
||||
|
||||
// remote directory box
|
||||
QRect remotePathRect = localPathRect;
|
||||
remotePathRect.setTop( localPathRect.bottom() + subFm.height()/2 );
|
||||
remotePathRect.setTop( localPathRect.bottom() + margin );
|
||||
remotePathRect.setBottom( remotePathRect.top() + subFm.height());
|
||||
|
||||
iconRect.setBottom(remotePathRect.bottom());
|
||||
iconRect.setWidth(iconRect.height());
|
||||
|
||||
//painter->drawPixmap(QPoint(iconRect.right()/2,iconRect.top()/2),icon.pixmap(iconsize.width(),iconsize.height()));
|
||||
if( syncEnabled ) {
|
||||
painter->drawPixmap(QPoint(iconRect.left(),iconRect.top()), folderIcon.pixmap(iconsize.width(),iconsize.height()));
|
||||
int nextToIcon = iconRect.right()+aliasMargin;
|
||||
aliasRect.setLeft(nextToIcon);
|
||||
localPathRect.setLeft(nextToIcon);
|
||||
remotePathRect.setLeft(nextToIcon);
|
||||
|
||||
int iconSize = iconRect.width();
|
||||
|
||||
QPixmap pm = statusIcon.pixmap(iconSize, iconSize, syncEnabled ? QIcon::Normal : QIcon::Disabled );
|
||||
painter->drawPixmap(QPoint(iconRect.left(), iconRect.top()), pm);
|
||||
|
||||
if ((option.state & QStyle::State_Selected)
|
||||
&& (option.state & QStyle::State_Active)
|
||||
// Hack: Windows Vista's light blue is not contrasting enough for white
|
||||
&& !Application::style()->inherits("QWindowsVistaStyle")) {
|
||||
painter->setPen(option.palette.color(QPalette::HighlightedText));
|
||||
} else {
|
||||
painter->drawPixmap(QPoint(iconRect.left(),iconRect.top()), folderIcon.pixmap(iconsize.width(),iconsize.height(), QIcon::Disabled ));
|
||||
painter->setPen(option.palette.color(QPalette::Text));
|
||||
}
|
||||
|
||||
painter->drawPixmap(QPoint(statusRect.left(), statusRect.top()), statusIcon.pixmap(48,48));
|
||||
|
||||
QString elidedAlias = aliasFm.elidedText(aliasText, Qt::ElideRight, aliasRect.width());
|
||||
painter->setFont(aliasFont);
|
||||
painter->drawText(aliasRect, aliasText);
|
||||
painter->drawText(aliasRect, elidedAlias);
|
||||
|
||||
painter->setFont(subFont);
|
||||
painter->drawText(localPathRect.left(),localPathRect.top()+17, pathText);
|
||||
painter->drawText(remotePathRect, tr("Remote path: %1").arg(remotePath));
|
||||
QString elidedPathText = subFm.elidedText(pathText, Qt::ElideMiddle, localPathRect.width());
|
||||
painter->drawText(localPathRect, elidedPathText);
|
||||
QString elidedRemotePathText = subFm.elidedText(tr("Remote path: %1").arg(remotePath),
|
||||
Qt::ElideMiddle, remotePathRect.width());
|
||||
painter->drawText(remotePathRect, elidedRemotePathText);
|
||||
|
||||
// paint an error overlay if there is an error string
|
||||
if( !errorText.isEmpty() ) {
|
||||
QRect errorRect = localPathRect;
|
||||
errorRect.setLeft( iconRect.left());
|
||||
errorRect.setTop( iconRect.bottom()+subFm.height()/2 );
|
||||
errorRect.setHeight(subFm.height()+margin);
|
||||
errorRect.setRight( statusRect.right() );
|
||||
errorRect.setHeight(subFm.height()+aliasMargin);
|
||||
errorRect.setRight( option.rect.right()-aliasMargin );
|
||||
|
||||
painter->setBrush( QColor(0xbb, 0x4d, 0x4d) );
|
||||
painter->setPen( QColor(0xaa, 0xaa, 0xaa));
|
||||
painter->drawRoundedRect( errorRect, 4, 4 );
|
||||
|
||||
QIcon warnIcon(":/mirall/resources/warning-16");
|
||||
painter->drawPixmap( QPoint(errorRect.left()+2, errorRect.top()+2), warnIcon.pixmap(QSize(16,16)));
|
||||
QPoint warnPos(errorRect.left()+aliasMargin/2, errorRect.top()+aliasMargin/2);
|
||||
painter->drawPixmap( warnPos, warnIcon.pixmap(QSize(16,16)));
|
||||
|
||||
painter->setPen( Qt::white );
|
||||
painter->setFont(errorFont);
|
||||
QRect errorTextRect = errorRect;
|
||||
errorTextRect.setLeft( errorTextRect.left()+margin/2 +16);
|
||||
errorTextRect.setTop( errorTextRect.top()+margin/2 );
|
||||
errorTextRect.setLeft( errorTextRect.left()+aliasMargin +16);
|
||||
errorTextRect.setTop( errorTextRect.top()+aliasMargin/2 );
|
||||
|
||||
int linebreak = errorText.indexOf(QLatin1String("<br"));
|
||||
QString eText = errorText;
|
||||
@@ -236,17 +238,11 @@ StatusDialog::StatusDialog( Theme *theme, QWidget *parent) :
|
||||
connect(_ButtonClose, SIGNAL(clicked()), this, SLOT(accept()));
|
||||
connect(_ButtonRemove, SIGNAL(clicked()), this, SLOT(slotRemoveFolder()));
|
||||
|
||||
// hide these two for now...
|
||||
_ButtonFetch->setVisible( false );
|
||||
_ButtonPush->setVisible( false );
|
||||
|
||||
connect(_ButtonEnable, SIGNAL(clicked()), this, SLOT(slotEnableFolder()));
|
||||
connect(_ButtonInfo, SIGNAL(clicked()), this, SLOT(slotInfoFolder()));
|
||||
connect(_ButtonAdd, SIGNAL(clicked()), this, SLOT(slotAddSync()));
|
||||
|
||||
_ButtonRemove->setEnabled(false);
|
||||
_ButtonFetch->setEnabled(false);
|
||||
_ButtonPush->setEnabled(false);
|
||||
_ButtonEnable->setEnabled(false);
|
||||
_ButtonInfo->setEnabled(false);
|
||||
_ButtonAdd->setEnabled(true);
|
||||
@@ -268,8 +264,6 @@ void StatusDialog::slotFolderActivated( const QModelIndex& indx )
|
||||
bool state = indx.isValid();
|
||||
|
||||
_ButtonRemove->setEnabled( state );
|
||||
_ButtonFetch->setEnabled( state );
|
||||
_ButtonPush->setEnabled( state );
|
||||
_ButtonEnable->setEnabled( state );
|
||||
_ButtonInfo->setEnabled( state );
|
||||
|
||||
@@ -336,9 +330,7 @@ void StatusDialog::buttonsSetEnabled()
|
||||
|
||||
_ButtonEnable->setEnabled(isSelected);
|
||||
_ButtonRemove->setEnabled(isSelected);
|
||||
_ButtonFetch->setEnabled(isSelected);
|
||||
_ButtonInfo->setEnabled(isSelected);
|
||||
_ButtonPush->setEnabled(isSelected);
|
||||
}
|
||||
|
||||
void StatusDialog::slotUpdateFolderState( Folder *folder )
|
||||
@@ -369,8 +361,6 @@ void StatusDialog::folderToModelItem( QStandardItem *item, Folder *f )
|
||||
{
|
||||
if( ! item || !f ) return;
|
||||
|
||||
QIcon icon = _theme->folderIcon( f->backend() );
|
||||
item->setData( icon, FolderViewDelegate::FolderIconRole );
|
||||
item->setData( f->nativePath(), FolderViewDelegate::FolderPathRole );
|
||||
item->setData( f->secondPath(), FolderViewDelegate::FolderSecondPathRole );
|
||||
item->setData( f->alias(), FolderViewDelegate::FolderAliasRole );
|
||||
@@ -383,9 +373,9 @@ void StatusDialog::folderToModelItem( QStandardItem *item, Folder *f )
|
||||
|
||||
item->setData( _theme->statusHeaderText( status ), Qt::ToolTipRole );
|
||||
if( f->syncEnabled() ) {
|
||||
item->setData( _theme->syncStateIcon( status ), FolderViewDelegate::FolderStatusIcon );
|
||||
item->setData( _theme->syncStateIcon( status ), FolderViewDelegate::FolderStatusIconRole );
|
||||
} else {
|
||||
item->setData( _theme->folderDisabledIcon( ), FolderViewDelegate::FolderStatusIcon ); // size 48 before
|
||||
item->setData( _theme->folderDisabledIcon( ), FolderViewDelegate::FolderStatusIconRole ); // size 48 before
|
||||
}
|
||||
item->setData( _theme->statusHeaderText( status ), FolderViewDelegate::FolderStatus );
|
||||
item->setData( errors, FolderViewDelegate::FolderErrorMsg );
|
||||
@@ -416,30 +406,6 @@ void StatusDialog::slotRemoveSelectedFolder()
|
||||
slotCheckConnection();
|
||||
}
|
||||
|
||||
void StatusDialog::slotFetchFolder()
|
||||
{
|
||||
QModelIndex selected = _folderList->selectionModel()->currentIndex();
|
||||
if( selected.isValid() ) {
|
||||
QString alias = _model->data( selected, FolderViewDelegate::FolderAliasRole ).toString();
|
||||
qDebug() << "Fetch Folder alias " << alias;
|
||||
if( !alias.isEmpty() ) {
|
||||
emit(fetchFolderAlias( alias ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StatusDialog::slotPushFolder()
|
||||
{
|
||||
QModelIndex selected = _folderList->selectionModel()->currentIndex();
|
||||
if( selected.isValid() ) {
|
||||
QString alias = _model->data( selected, FolderViewDelegate::FolderAliasRole ).toString();
|
||||
qDebug() << "Push Folder alias " << alias;
|
||||
if( !alias.isEmpty() ) {
|
||||
emit(pushFolderAlias( alias ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StatusDialog::slotEnableFolder()
|
||||
{
|
||||
QModelIndex selected = _folderList->selectionModel()->currentIndex();
|
||||
|
||||
@@ -45,15 +45,14 @@ class FolderViewDelegate : public QStyledItemDelegate
|
||||
FolderViewDelegate();
|
||||
virtual ~FolderViewDelegate();
|
||||
|
||||
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
|
||||
enum datarole { FolderAliasRole = Qt::UserRole + 100,
|
||||
FolderPathRole,
|
||||
FolderSecondPathRole,
|
||||
FolderRemotePath,
|
||||
FolderStatus,
|
||||
FolderErrorMsg,
|
||||
FolderSyncEnabled,
|
||||
FolderStatusIconRole
|
||||
};
|
||||
void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const;
|
||||
QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const;
|
||||
@@ -73,8 +72,6 @@ public:
|
||||
|
||||
signals:
|
||||
void removeFolderAlias( const QString& );
|
||||
void fetchFolderAlias( const QString& );
|
||||
void pushFolderAlias( const QString& );
|
||||
void enableFolderAlias( const QString&, const bool );
|
||||
void infoFolderAlias( const QString& );
|
||||
void openFolderAlias( const QString& );
|
||||
@@ -85,8 +82,6 @@ signals:
|
||||
public slots:
|
||||
void slotRemoveFolder();
|
||||
void slotRemoveSelectedFolder();
|
||||
void slotFetchFolder();
|
||||
void slotPushFolder();
|
||||
void slotFolderActivated( const QModelIndex& );
|
||||
void slotOpenOC();
|
||||
void slotEnableFolder();
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>544</width>
|
||||
<height>308</height>
|
||||
<height>313</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -49,23 +49,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="_ButtonFetch">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fetch...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="_ButtonPush">
|
||||
<property name="text">
|
||||
<string>Push...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="_ButtonEnable">
|
||||
<property name="text">
|
||||
|
||||
@@ -82,7 +82,8 @@ QString Theme::version() const
|
||||
|
||||
QIcon Theme::trayFolderIcon( const QString& backend ) const
|
||||
{
|
||||
return folderIcon( backend );
|
||||
Q_UNUSED(backend)
|
||||
return applicationIcon();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -70,11 +70,6 @@ public:
|
||||
*/
|
||||
virtual QString configFileName() const = 0;
|
||||
|
||||
/**
|
||||
* get a folder icon for a given backend in a given size.
|
||||
*/
|
||||
virtual QIcon folderIcon( const QString& ) const = 0;
|
||||
|
||||
/**
|
||||
* the icon that is shown in the tray context menu left of the folder name
|
||||
*/
|
||||
@@ -86,7 +81,6 @@ public:
|
||||
virtual QIcon syncStateIcon( SyncResult::Status, bool sysTray = false ) const;
|
||||
|
||||
virtual QIcon folderDisabledIcon() const = 0;
|
||||
virtual QPixmap splashScreen() const = 0;
|
||||
|
||||
virtual QIcon applicationIcon() const = 0;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "mirall/version.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/occinfo.h"
|
||||
#include "mirall/utility.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
@@ -56,9 +57,13 @@ void UpdateDetector::versionCheck( Theme *theme )
|
||||
}
|
||||
url.addQueryItem( QLatin1String("version"), ver );
|
||||
url.addQueryItem( QLatin1String("platform"), platform );
|
||||
url.addQueryItem( QLatin1String("oem"), theme->appName());
|
||||
url.addQueryItem( QLatin1String("oem"), theme->appName() );
|
||||
|
||||
_accessManager->get( QNetworkRequest( url ));
|
||||
QNetworkRequest req( url );
|
||||
req.setRawHeader( QByteArray("Host"), url.host().toUtf8() );
|
||||
req.setRawHeader( QByteArray("User-Agent"), Utility::userAgentString() );
|
||||
|
||||
_accessManager->get( req );
|
||||
}
|
||||
|
||||
void UpdateDetector::slotOpenUpdateUrl()
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
#include "mirall/version.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QUrl>
|
||||
@@ -90,4 +93,36 @@ void Utility::setupFavLink(const QString &folder)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Qtified version of get_platforms() in csync_owncloud.c
|
||||
QString Utility::platform()
|
||||
{
|
||||
#if defined(Q_OS_WIN32)
|
||||
return QLatin1String("Windows");
|
||||
#elif defined(Q_OS_MAC)
|
||||
return QLatin1String("Macintosh");
|
||||
#elif defined(Q_OS_LINUX)
|
||||
return QLatin1String("Linux");
|
||||
#elif defined(__DragonFly__) // Q_OS_FREEBSD also defined
|
||||
return "DragonFlyBSD";
|
||||
#elif defined(Q_OS_FREEBSD)
|
||||
return QLatin1String("FreeBSD");
|
||||
#elif defined(Q_OS_NETBSD)
|
||||
return QLatin1String("NetBSD");
|
||||
#elif defined(Q_OS_OPENBSD)
|
||||
return QLatin1String("OpenBSD");
|
||||
#elif defined(Q_OS_SOLARIS)
|
||||
return "Solaris";
|
||||
#else
|
||||
return "Unknown OS"
|
||||
#endif
|
||||
}
|
||||
|
||||
QByteArray Utility::userAgentString()
|
||||
{
|
||||
return QString::fromLatin1("Mozilla/5.0 (%1) mirall/%2")
|
||||
.arg(Utility::platform())
|
||||
.arg(QLatin1String(MIRALL_STRINGIFY(MIRALL_VERSION)))
|
||||
.toLatin1();
|
||||
}
|
||||
|
||||
} // namespace Mirall
|
||||
|
||||
@@ -25,6 +25,8 @@ class Utility
|
||||
public:
|
||||
static QString formatFingerprint( const QByteArray& );
|
||||
static void setupFavLink( const QString &folder );
|
||||
static QString platform();
|
||||
static QByteArray userAgentString();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
48
test/scripts/README.rst
Normal file
48
test/scripts/README.rst
Normal file
@@ -0,0 +1,48 @@
|
||||
Torture for Mirall
|
||||
==================
|
||||
|
||||
This is a set of scripts comprising of two parts:
|
||||
|
||||
* ``torture_gen_layout.pl``: Generation of layout files (random)
|
||||
* ``torture_create_files.pl``: Generation of a real file tree based on the
|
||||
layout files (deterministic)
|
||||
|
||||
These scripts allow to produce a data set with the following criteria:
|
||||
|
||||
* realistic in naming
|
||||
* realistic in file size
|
||||
* realistic in structural size
|
||||
|
||||
without checking in the actual data. Instead, a layout file that gets generated
|
||||
once (reference.lay) is checked in. This makes it possible to produce
|
||||
standardized benchmarks for mirall. It allows allows to check for files gone
|
||||
missing in action and other kinds of corruption produced during sync run.
|
||||
|
||||
``torture_create_files.pl`` can be fine tuned via variables in the script
|
||||
header. It sources its file names from ``dict`` wordlist, file extensions and
|
||||
other parameters can be added as needed. The defaults should be reasonable
|
||||
in terms of size.
|
||||
|
||||
The ``references/`` directory contains default folder layouts.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
In order to create a reference layout and create a tree from it::
|
||||
|
||||
./torture_gen_layout.pl > reference.lay
|
||||
./torture_create_files.pl reference.lay <targetdir>
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
* Based on the layout file, write a validator that checks files for existence
|
||||
and size without requiring a full reference tree to be created via
|
||||
``./torture_gen_layout.pl``.
|
||||
|
||||
* The current file naming is fairly tame (i.e. almost within ASCII range).
|
||||
Extending it randomly is dangerous, we first need to filter all
|
||||
characters forbidden by various OSes. Or maybe not, because we want to
|
||||
see what happens? :-). Anyway, you have been warned.
|
||||
|
||||
|
||||
6698
test/scripts/references/default.lay
Normal file
6698
test/scripts/references/default.lay
Normal file
File diff suppressed because it is too large
Load Diff
23
test/scripts/torture_create_files.pl
Executable file
23
test/scripts/torture_create_files.pl
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use File::Path qw(make_path);
|
||||
use File::Basename qw(dirname);
|
||||
|
||||
if (scalar @ARGV < 2) {
|
||||
print "Usage: $0 input.lay <offsetdir>\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
my ($file, $offset_dir) = @ARGV;
|
||||
|
||||
open FILE, "<", $file or die $!;
|
||||
while (<FILE>) {
|
||||
my ($fillfile, $size) = split(/:/, $_);
|
||||
$fillfile = $offset_dir . '/' . $fillfile;
|
||||
my $dir = dirname $fillfile;
|
||||
if (!-d $dir) { make_path $dir; }
|
||||
open FILLFILE, ">", $fillfile;
|
||||
print "writing $fillfile with $size bytes\n...";
|
||||
print FILLFILE 0x01 x $size;
|
||||
close FILLFILE;
|
||||
}
|
||||
71
test/scripts/torture_gen_layout.pl
Executable file
71
test/scripts/torture_gen_layout.pl
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use Data::Random::WordList;
|
||||
|
||||
############################################################################
|
||||
|
||||
# Which extensions to randomly assign
|
||||
my @exts = ('txt', 'pdf', 'html', 'docx', 'xlsx', 'pptx', 'odt', 'ods', 'odp');
|
||||
# Maximum depth of the target structure
|
||||
my $depth = 4;
|
||||
# Maximum amount of subfolders within a folder
|
||||
my $max_subfolder = 10;
|
||||
# Maximum amount of files within a folder
|
||||
my $max_files_per_folder = 100;
|
||||
# Maximum file size
|
||||
my $max_file_size = 1024**2;
|
||||
|
||||
############################################################################
|
||||
|
||||
sub gen_entries($)
|
||||
{
|
||||
my ($count) = @_;
|
||||
my $wl = new Data::Random::WordList( wordlist => '/usr/share/dict/words' );
|
||||
my @rand_words = $wl->get_words($count);
|
||||
foreach(@rand_words) {
|
||||
$_ =~ s/\'//g;
|
||||
}
|
||||
$wl->close();
|
||||
return @rand_words;
|
||||
}
|
||||
|
||||
sub create_subdir($)
|
||||
{
|
||||
my ($depth) = @_;
|
||||
$depth--;
|
||||
my %dir_tree = ( );
|
||||
|
||||
my @dirs = gen_entries(int(rand($max_subfolders)));
|
||||
my @files = gen_entries(int(rand($max_files_per_folder)));
|
||||
|
||||
foreach my $file(@files) {
|
||||
$dir_tree{$file} = int(rand($max_file_size));
|
||||
}
|
||||
|
||||
if ($depth > 0) {
|
||||
foreach my $dir(@dirs) {
|
||||
$dir_tree{$dir} = create_subdir($depth);
|
||||
}
|
||||
}
|
||||
|
||||
return \%dir_tree;
|
||||
}
|
||||
|
||||
sub create_dir_listing(@)
|
||||
{
|
||||
my ($tree, $prefix) = @_;
|
||||
foreach my $key(keys %$tree) {
|
||||
my $entry = $tree->{$key};
|
||||
#print "$entry:".scalar $entry.":".ref $entry."\n";
|
||||
if (ref $entry eq "HASH") {
|
||||
create_dir_listing($tree->{$key}, "$prefix/$key");
|
||||
} else {
|
||||
my $ext = @exts[rand @exts];
|
||||
print "$prefix/$key.$ext:$entry\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srand();
|
||||
my $dir = create_subdir($depth);
|
||||
create_dir_listing($dir, '.');
|
||||
Reference in New Issue
Block a user