1
0
mirror of https://github.com/chylex/Nextcloud-Desktop.git synced 2026-04-05 14:34:16 +02:00

Compare commits

..

190 Commits

Author SHA1 Message Date
Daniel Molkentin
ee080222d8 Bump version 2013-04-11 12:52:58 +04:00
Daniel Molkentin
c7aaa3ab28 Add 1.2.4 changelog 2013-04-11 12:34:33 +04:00
Daniel Molkentin
fcde01fd4c Clarify string in folder wizard 2013-04-11 10:57:19 +04:00
Jenkins for ownCloud
83be334ee8 [tx-robot] updated from transifex 2013-04-11 01:02:21 +02:00
Jenkins for ownCloud
819f76c2b9 [tx-robot] updated from transifex 2013-04-10 01:02:30 +02:00
Jenkins for ownCloud
783b16676f [tx-robot] updated from transifex 2013-04-09 01:09:43 +02:00
Klaas Freitag
aa6160ab62 Fixed some valgrind warnings. 2013-04-08 14:50:47 +02:00
Jenkins for ownCloud
8bae06802b [tx-robot] updated from transifex 2013-04-06 00:06:25 +02:00
Jenkins for ownCloud
a20f572448 [tx-robot] updated from transifex 2013-04-05 00:24:21 +02:00
Daniel Molkentin
f74aa1e9a6 terminate if more than one thread is being started. 2013-04-04 17:25:53 +02:00
Klaas Freitag
86525570aa Fix default config storage path. 2013-04-04 15:19:45 +02:00
Jenkins for ownCloud
d11ce781d0 [tx-robot] updated from transifex 2013-04-04 00:07:40 +02:00
Klaas Freitag
be5a50a000 Merge branch 'confdir' of https://github.com/smessmer/mirall into smessmer-confdir 2013-04-03 14:42:13 +02:00
dragotin
7309a894bc Merge pull request #477 from rominf/master
Fix for bug with folders adding
2013-04-03 04:39:17 -07:00
Jenkins for ownCloud
310f29d3fd [tx-robot] updated from transifex 2013-04-03 00:04:53 +02:00
Daniel Molkentin
07db03d6bc 1.2.3 2013-04-02 15:27:37 +02:00
Daniel Molkentin
d68c4b379f Unbreak self-signed certificate handling 2013-04-02 15:22:27 +02:00
Daniel Molkentin
396a12dfde Amend ChangeLog 2013-04-02 10:14:02 +02:00
Jenkins for ownCloud
c79f4f91a8 [tx-robot] updated from transifex 2013-04-02 00:05:14 +02:00
Klaas Freitag
bec2f7c9b9 Removed verbose logging on Win32. 2013-03-28 11:14:16 +01:00
Jenkins for ownCloud
d4c8cad0e2 [tx-robot] updated from transifex 2013-03-27 00:11:52 +01:00
Daniel Molkentin
0ad2bd4b91 Add favlink generation support for Nautilus 2013-03-25 18:00:58 +01:00
Daniel Molkentin
dcc8f9fa6c Fix favlink manual test 2013-03-25 18:00:25 +01:00
Markus Goetz
d7a93c74aa OS X: Fix creation of Finder Favorite 2013-03-25 14:57:34 +01:00
Daniel Molkentin
408547611b Manual test for favlinks 2013-03-25 12:53:40 +01:00
rominf
a8f0e79046 Skipping folders with no absolute path. 2013-03-23 10:48:37 +04:00
Jenkins for ownCloud
3e45147497 [tx-robot] updated from transifex 2013-03-23 00:07:09 +01:00
Daniel Molkentin
48310d3f5e Add 1.2.2 changelog 2013-03-22 14:59:22 +01:00
Daniel Molkentin
1831a975eb SSLErrorDialog: We cannot use the existing key chain
... use the one returned by the new server instead.
2013-03-22 14:59:22 +01:00
Jenkins for ownCloud
a766a44bcf [tx-robot] updated from transifex 2013-03-22 12:08:57 +01:00
Jenkins for ownCloud
287f1c55ff [tx-robot] updated from transifex 2013-03-22 00:05:37 +01:00
Daniel Molkentin
1c6523bcec Add plugin for screenreader support 2013-03-21 17:49:03 +03:00
Daniel Molkentin
337c6d3e4e Try to avoid crash on Mac OS during setup
... by moving setupFavLink to a place only called
if the folder to be referenced exists for sure.
2013-03-21 12:50:47 +01:00
Jenkins for ownCloud
4a57957420 [tx-robot] updated from transifex 2013-03-21 00:05:23 +01:00
Daniel Molkentin
c633302f31 Use the certificateChain() in the SSL error dialog
This includes the self-signed certificate anyway, and the previous
behavior led to funny side-effects.
2013-03-20 15:53:55 +01:00
Daniel Molkentin
db95e7291d bump version 2013-03-19 16:30:17 +01:00
Klaas Freitag
ae54c27805 Added office doc lock files. 2013-03-19 16:20:00 +01:00
Daniel Molkentin
284285d441 Do not follow symlinks when recursing
We do not support symlinks anyway
2013-03-18 14:12:25 +01:00
Jenkins for ownCloud
2554a67cc7 [tx-robot] updated from transifex 2013-03-15 00:08:00 +01:00
Jenkins for ownCloud
e2cccd8615 [tx-robot] updated from transifex 2013-03-13 00:07:52 +01:00
Jenkins for ownCloud
948a98a871 [tx-robot] updated from transifex 2013-03-12 00:15:38 +01:00
Daniel Molkentin
b50d201154 Merge pull request #423 from hefee/master
adding WITH_DOC parameter to cmake
2013-03-11 08:28:51 -07:00
hefee
25a3ceb94d adding WITH_DOC parameter to cmake
Fixes #412
2013-03-11 16:18:20 +01:00
Jenkins for ownCloud
c514fe371a [tx-robot] updated from transifex 2013-03-10 00:08:00 +01:00
Jenkins for ownCloud
9169c70efe [tx-robot] updated from transifex 2013-03-09 00:07:47 +01:00
Jenkins for ownCloud
3c07cea229 [tx-robot] updated from transifex 2013-03-08 00:27:56 +01:00
Klaas Freitag
d3f51c611f Some more troubleshooting details. 2013-03-06 08:51:04 +01:00
Jenkins for ownCloud
21123bb029 [tx-robot] updated from transifex 2013-03-04 00:09:00 +01:00
Jenkins for ownCloud
fb8d11650c [tx-robot] updated from transifex 2013-03-03 00:08:15 +01:00
Jan-Christoph Borchardt
2c250050d5 add http and https icons for connection feedback 2013-03-01 16:09:10 +01:00
Jenkins for ownCloud
e9b3cbf3f7 [tx-robot] updated from transifex 2013-02-28 00:07:02 +01:00
Jenkins for ownCloud
d31a6e6179 [tx-robot] updated from transifex 2013-02-27 00:10:59 +01:00
Klaas Freitag
26d8c213b0 Updated Changelog. 2013-02-26 12:08:40 +01:00
Daniel Molkentin
bcb9491f6a RC1 -> final 2013-02-26 11:32:32 +01:00
Klaas Freitag
9d2c3ebad3 Move config.h out of header files. 2013-02-25 09:54:19 +01:00
Daniel Molkentin
ad063b0634 Make chinese translations work on OS X
... by mapping chinese script codes to country
 codes as used by Qt and Transifex.
2013-02-24 15:44:38 +01:00
Daniel Molkentin
8765538458 Be more permission when loading languages
Accept languages when they only exist for mirall,
but not for Qt and QtKeychain (Fixes #359). This
is more permissive than before, but while fixing
#359, it became evident that supporting "partial"
translations might actually be beneficial.
2013-02-24 15:44:38 +01:00
Jenkins for ownCloud
dd4aa14a8c [tx-robot] updated from transifex 2013-02-23 00:06:50 +01:00
Jenkins for ownCloud
99814539eb [tx-robot] updated from transifex 2013-02-22 00:10:10 +01:00
Daniel Molkentin
dbec98ff48 Manual update of avail translations 2013-02-21 18:35:33 +03:00
Daniel Molkentin
e2e14f2184 Do not install docs on OS X 2013-02-21 15:26:31 +01:00
Daniel Molkentin
e85291c4ba en language is implied 2013-02-21 15:17:13 +01:00
Klaas Freitag
58a5405343 Dont do the doc build step on every build. 2013-02-21 14:01:16 +01:00
Klaas Freitag
4ba85311da Handle all cases in switches. 2013-02-21 13:36:51 +01:00
Daniel Molkentin
3cf7003101 Load UI languages instead of locales where possible
Load Qt translations consistently along the way.
This only has been verified on mac and needs adoption
for win32.
2013-02-21 13:19:54 +01:00
Klaas Freitag
ae558a5889 Add a appNameGUI method to the theming. 2013-02-21 12:21:42 +01:00
Jenkins for ownCloud
0b0b762c6c [tx-robot] updated from transifex 2013-02-21 00:13:24 +01:00
Klaas Freitag
55a4fd752d Fix commit fd83bf - add treewalk success check. 2013-02-20 17:26:07 +01:00
Klaas Freitag
136b699106 Make sure to restart sync after folder add. 2013-02-20 16:06:46 +01:00
Klaas Freitag
fd83bf2089 Remove unused variable doTreeWalk. 2013-02-20 10:06:45 +01:00
Jenkins for ownCloud
75f075feb0 [tx-robot] updated from transifex 2013-02-20 00:04:39 +01:00
Klaas Freitag
817039ddf3 Simplify and fix startup: Steer starting of sync from folderman. 2013-02-19 17:24:10 +01:00
Klaas Freitag
6d6deaf6c4 Setup folders added after setup wizard ended. 2013-02-19 12:04:36 +01:00
Klaas Freitag
9c63b89bac Removed useless warning. 2013-02-19 09:34:33 +01:00
Jenkins for ownCloud
2a6e084219 [tx-robot] updated from transifex 2013-02-19 00:08:08 +01:00
Klaas Freitag
ec120cd64c Make folderman load folders at start and update later. 2013-02-18 18:31:29 +02:00
Klaas Freitag
a9173b1aa1 Add setters for update check and max log lines 2013-02-18 17:17:03 +02:00
Klaas Freitag
89f7f75af2 If a new server is configured, take the proxy config to the new config
file.
2013-02-18 17:16:10 +02:00
Daniel Molkentin
8809ac0c4a remove unused connect 2013-02-18 14:56:50 +01:00
Daniel Molkentin
7a03164a9a Handle server offline state on application start gracefully 2013-02-18 14:56:50 +01:00
Jenkins for ownCloud
406254cd04 [tx-robot] updated from transifex 2013-02-18 00:07:57 +01:00
Jenkins for ownCloud
f01eeed9d0 [tx-robot] updated from transifex 2013-02-17 00:27:55 +01:00
Jenkins for ownCloud
5b6439e29d [tx-robot] updated from transifex 2013-02-16 00:07:02 +01:00
Daniel Molkentin
38954c2193 Remove obsolete signal. 2013-02-15 19:29:38 +01:00
Daniel Molkentin
5954fb280c Centralize error handling for csync steps
...as a preparation for offline handling.
As a side-effect, removed the last instance
of goto in mirall.
2013-02-15 19:29:27 +01:00
Daniel Molkentin
8e63652fb3 Send OEM string to update detector. 2013-02-15 18:39:25 +01:00
Jenkins for ownCloud
365dfd5380 [tx-robot] updated from transifex 2013-02-15 00:08:10 +01:00
Daniel Molkentin
1c70fb3ba4 Set csync config dir in mirall properly
Otherwise canceling the sync cannot remove the lock file
2013-02-14 17:36:11 +01:00
Daniel Molkentin
e5af8e87b3 Fix crash when pausing mirall. 2013-02-14 17:36:11 +01:00
Daniel Molkentin
bfbec24f43 Add more debug in case inotify fails
We should probably make this at least a visible error, because it's a
limitation set by the kernel/the distro and we would require root
permissions to adjust the value.

Right now all that happens is that syncing is not immediate, but only
run every 30 secs (due to server polling).
2013-02-14 17:36:11 +01:00
Daniel Molkentin
8dd97a358a Introduce SyncPrepare state
SyncPrepare is when the folder class prepares the actual syncing,
i.e. does treewalks and runs the reconceiler in case of mirall. The actual
SyncRunning state will only be entered if there is actually anything to
sync.

Fixes #289
2013-02-14 17:36:11 +01:00
Daniel Molkentin
7290afc6fe Minimize Sync notification notification
Notifies only in the end of a complete sync run now

Migitates/fixes #314
2013-02-14 17:36:11 +01:00
Daniel Molkentin
2ba20369ea Remove unused gitfolder class for now 2013-02-14 17:36:11 +01:00
Daniel Molkentin
804aef6548 Remove stray code 2013-02-14 17:36:11 +01:00
Daniel Molkentin
85f49b6af4 Fix guard position 2013-02-14 17:36:11 +01:00
Daniel Molkentin
68afc6011d proxy dialog: no extra heading 2013-02-14 17:36:11 +01:00
Daniel Molkentin
524ffcd0e1 owncloud setup: Fix label style 2013-02-14 17:36:11 +01:00
Jenkins for ownCloud
a7303205b4 [tx-robot] updated from transifex 2013-02-14 00:08:08 +01:00
Jenkins for ownCloud
8a06b2d136 [tx-robot] updated from transifex 2013-02-13 00:06:54 +01:00
Daniel Molkentin
7ba8a55fa5 Merge pull request #313 from hefee/doc2default
creating doc to default target
2013-02-12 11:48:00 -08:00
Daniel Molkentin
ee7dc8e1c5 Merge pull request #312 from hefee/master
usefull manpages for owncloud and mirall
2013-02-12 11:47:41 -08:00
Jenkins for ownCloud
3556f90d68 [tx-robot] updated from transifex 2013-02-12 00:20:28 +01:00
Klaas Freitag
6d984b505d Handle not stored password correctly. 2013-02-11 14:21:53 +01:00
Klaas Freitag
8d9336f9f4 Removed obsolete scheduler start. 2013-02-11 14:21:21 +01:00
Klaas Freitag
2b5e694181 Set default argument to method. 2013-02-11 14:20:32 +01:00
Klaas Freitag
aa983e4966 Make user password dialog real async working. 2013-02-11 14:18:45 +01:00
Klaas Freitag
424b3a9dfc cleanup comments and dupes. 2013-02-11 14:18:16 +01:00
Jenkins for ownCloud
5a3bc7af9a [tx-robot] updated from transifex 2013-02-11 00:05:57 +01:00
Klaas Freitag
4501ec10dc Make sure that journals are wiped if server changes + some utility
functions.
2013-02-10 20:04:03 +01:00
Klaas Freitag
699ae176df Revert "Allow setting of custom poll interval through status.php"
This reverts commit 39a89e8fc7.

Conflicts:
	src/mirall/folderman.cpp
	src/mirall/folderman.h
2013-02-10 14:57:57 +01:00
Klaas Freitag
9297b3b850 Add chrome download file to exclude list 2013-02-10 14:48:17 +01:00
Klaas Freitag
cac5f81388 Clear pending network requests in setup wizard on back. 2013-02-10 14:03:09 +01:00
Klaas Freitag
28af8068e9 Always return QNetworkReply* on mkdir and also on checkInstall. 2013-02-10 14:01:38 +01:00
Sebastian Kügler
a1d64af7b1 API additions for the Plasma client
This patch contains a few (source-compatible) API additions needed for
the Plasma client.

* return QNetworkReply* to caller for tracking status and error of
  requests such as mkdir, getWebDAVPath and getRequest
* Add a setter for the QNetworkAccessManager. This allows us to route at
  least some of the network requests through KIO in the Plasma client
* Add a setter for the remotePollInterval. This should be enough API to
* make it possible to adapt the polling interval to the client's machine
  state, e.g. sync less often on battery, or somesuch
2013-02-10 13:10:53 +01:00
dragotin
edbb79b79c Merge pull request #5 from sebasje/mkdirreply
Return QNetworkReply from remote mkdir
2013-02-10 02:34:36 -08:00
dragotin
a000a7b52e Merge pull request #4 from sebasje/requestreply
Return QNetworkReply from getRequests
2013-02-10 02:34:14 -08:00
Klaas Freitag
0a427541d6 Added config file setter for poll interval. Thx for pull request. 2013-02-10 11:27:21 +01:00
Klaas Freitag
1c297c56a2 Stop authentication tries already after the first attempt without
success.
2013-02-10 11:02:39 +01:00
Klaas Freitag
6f9bbc431d Properly stop syncing when connection manager opens. 2013-02-10 11:02:39 +01:00
Klaas Freitag
f62626e3eb Delete existing folders properly before adding new ones. 2013-02-10 11:02:38 +01:00
Jenkins for ownCloud
28fcd75494 [tx-robot] updated from transifex 2013-02-10 00:11:52 +01:00
Klaas Freitag
39a89e8fc7 Allow setting of custom poll interval through status.php 2013-02-09 14:04:04 +01:00
Klaas Freitag
38a8096732 Fixed sorting of header entries, ie. public / protected / private. 2013-02-09 14:03:05 +01:00
Klaas Freitag
d358c839ce Fixed typos. 2013-02-09 12:46:08 +01:00
hefee
17901e7bc7 fixing typo in mirall.1.rst 2013-02-09 12:28:43 +01:00
hefee
0ea16c04cc moving description of config file and client optinos to own files.
* split usage to three files: usage, conffile, options
* fixing minor typos in mirall.1.rst and owncloud1.rst
* owncloud.1 uses include conffile, options
* mirall.1 uses include conffile, options
* Fixes: #183
2013-02-09 12:23:32 +01:00
Klaas Freitag
f1e0cd1c9c Cleaned up used icons. 2013-02-09 10:32:29 +01:00
hefee
e1f404a011 adding maclocation 2013-02-09 10:30:56 +01:00
hefee
69715d2182 merging from owncloud/master 2013-02-09 10:16:38 +01:00
hefee
0285213140 removing asciidoc, now creating manpages via sphinx again 2013-02-09 10:10:23 +01:00
hefee
1a907f23f0 moving generation of manpages to sphinx
--HG--
rename : doc/mirall.1.txt => doc/mirall.1.rst
rename : doc/owncloud.1.txt => doc/owncloud.1.rst
2013-02-09 10:05:45 +01:00
Jenkins for ownCloud
1296be71ed [tx-robot] updated from transifex 2013-02-09 00:15:51 +01:00
hefee
0ebcdbbb3f no more different cmake parameter is needed 2013-02-08 18:57:25 +01:00
dragotin
891ced0fca Merge pull request #318 from LukeOwncloud/patch-1
Update doc/usage.rst
2013-02-08 09:45:30 -08:00
dragotin
6276bb3873 Merge pull request #322 from hefee/soname
adding soname version to libowncloudsync and libmirallsync
2013-02-08 09:42:32 -08:00
Klaas Freitag
dbb0cbaff8 Removed build of obsolete mirallsync lib which is equal to owncloudsync. 2013-02-08 19:18:36 +01:00
Sandro Knauß
cfa777260c removing version for mirallsync (it is'nt build anymore :) 2013-02-08 18:37:29 +01:00
Sandro Knauß
66fc273db6 merging with default 2013-02-08 18:36:26 +01:00
hefee
9c9e377cf4 adding soname version to libowncloudsync and libmirallsync 2013-02-08 18:21:59 +01:00
Jenkins for ownCloud
f75eb24bfe [tx-robot] updated from transifex 2013-02-08 00:14:28 +01:00
LukeOwncloud
a617a04295 Update doc/usage.rst 2013-02-07 08:50:49 +01:00
Jenkins for ownCloud
dc16f277ce [tx-robot] updated from transifex 2013-02-07 00:12:34 +01:00
Klaas Freitag
07258deaaf Fix build for mirall target. 2013-02-06 15:05:34 +01:00
Klaas Freitag
7b53e0f953 Fix return from non void function. 2013-02-06 14:58:31 +01:00
Klaas Freitag
2ac764bd1a Fix compile without OWNCLOUD_CLIENT define, thx Jenkins 2013-02-06 11:58:14 +02:00
Klaas Freitag
82d2851a6b Set username in connection dialog if there. 2013-02-06 11:42:36 +02:00
Klaas Freitag
7a3be71452 The user name is not really to be protected. 2013-02-06 11:41:47 +02:00
Klaas Freitag
977a513ee5 Always set the connect result to en/disable the Finish button. 2013-02-06 11:21:50 +02:00
Klaas Freitag
22cbebb7a7 Fix build on debian with ancient Qt, thanks Mr. Jenkins for notifying. 2013-02-06 10:41:25 +02:00
Klaas Freitag
72b2e6778a Use new ownCloudInfo / CredentialStore interface. 2013-02-06 10:09:02 +02:00
Klaas Freitag
08babbf38d Set credentials in ownCloudInfo after these have been fetched. 2013-02-06 10:09:02 +02:00
Klaas Freitag
2ae5ae6962 Change interface to not support customHandles. 2013-02-06 10:09:02 +02:00
Klaas Freitag
fa6331a40a Removed use of CredentialStore from class and added setter for
credentials.

This makes handling of temporar credentials for the setup dialog easier
and streamlines the code.
2013-02-06 10:09:02 +02:00
Klaas Freitag
cece465947 Link libdl explicitely. 2013-02-06 10:09:02 +02:00
Jenkins for ownCloud
3f97047abc [tx-robot] updated from transifex 2013-02-06 00:07:36 +01:00
Daniel Molkentin
b6d5213880 Add suffix, to be added with -DVERSION_SUFFIX=... 2013-02-05 15:42:53 +01:00
Daniel Molkentin
0bcb65db29 Do not allow to press Finished if connection to the server fails
This does not yet consider cases where the connection
succeeds but webdav fails.
2013-02-05 15:40:59 +01:00
Klaas Freitag
7734656ae3 Make mirall packager for win bundle the new openSSL dlls. 2013-02-05 14:37:39 +01:00
Klaas Freitag
c14e17e271 Set to version 1.2.1pre 2013-02-05 14:37:39 +01:00
hefee
1f4ea2c60e only add instalation dir if we are creating doc 2013-02-04 18:31:48 +01:00
hefee
edb4ff6b98 adding doc to default if CREATEDOC is set 2013-02-04 18:10:51 +01:00
Sandro Knauß
279bb47ab4 add creating manpages to CMakeLists 2013-02-04 17:36:56 +01:00
Sandro Knauß
7ef92748ea adding manpages for mirall and owncloud 2013-02-04 16:56:39 +01:00
Sandro Knauß
0e6e614318 adding --monoicons option to usage.rst 2013-02-04 16:55:50 +01:00
Jenkins for ownCloud
a5b6c3add7 [tx-robot] updated from transifex 2013-02-04 00:07:05 +01:00
Daniel Molkentin
fd30d8b0d1 Typo 2013-02-03 13:39:34 +01:00
Daniel Molkentin
5944acf8a6 Hack: Do not leak FDs when neon is built with gnutls (Linux)
Previously, this would cause Mirall to crash sooner or later.

Fixes #154
2013-02-03 13:37:03 +01:00
Jenkins for ownCloud
58ace7c774 [tx-robot] updated from transifex 2013-02-02 00:09:05 +01:00
Jenkins for ownCloud
a07444412b [tx-robot] updated from transifex 2013-02-01 00:20:42 +01:00
mjkent
339f59a4e8 Merge pull request #284 from mjkent/854852959c95935efd8902f05d9935b04bb9f04c
Improve command line argument handling
2013-01-31 15:00:37 -08:00
Jenkins for ownCloud
4beb9b3efc [tx-robot] updated from transifex 2013-01-31 00:33:28 +01:00
Daniel Molkentin
a04cf32a69 No need to ship ocsync.conf 2013-01-30 09:48:45 +01:00
Jenkins for ownCloud
746c0359d2 [tx-robot] updated from transifex 2013-01-30 00:27:40 +01:00
Michael Kent
854852959c Changes to handling of command line options. Fix a segmentation fault with owncloud --help. Add -h as help short. If a commandline argument isn't recognized, print that it isn't recognized, print help, and abort. 2013-01-28 22:19:14 -06:00
Daniel Molkentin
1e1751e451 sign_dmg.sh: increase wait time for dmg mount 2013-01-28 21:04:43 +01:00
Jenkins for ownCloud
7cd0179adc [tx-robot] updated from transifex 2013-01-28 00:06:52 +01:00
Jenkins for ownCloud
c0543cdbaf [tx-robot] updated from transifex 2013-01-27 00:07:31 +01:00
Daniel Molkentin
d681066dc2 Results bubble: _localPrefix might not end in a separator 2013-01-26 20:47:20 +01:00
Jenkins for ownCloud
b81939bff5 [tx-robot] updated from transifex 2013-01-26 00:11:18 +01:00
Daniel Molkentin
f8685c97f1 CPack: more parameterization 2013-01-25 15:59:13 +01:00
Daniel Molkentin
11e06c33db Fix compilation on win/mac 2013-01-25 15:46:23 +01:00
Daniel Molkentin
c0f2f5bcaa Load Qt translations from app dir/bundle, too 2013-01-25 15:41:18 +01:00
Daniel Molkentin
bfee6402a6 Simplify NSIS template 2013-01-25 12:56:00 +01:00
Klaas Freitag
4fac62560e Removed remove of list of configured sync folder on reconfiguration.
The removal of the configured folders was needed as long as the
csync journal was based in on the folder name of the sync folder.
Now that every folder has its own sync journal its not longer needed.
2013-01-25 11:33:00 +01:00
Jenkins for ownCloud
d780055b0e [tx-robot] updated from transifex 2013-01-25 00:07:05 +01:00
Jenkins for ownCloud
3f5c53425b [tx-robot] updated from transifex 2013-01-24 00:08:40 +01:00
Sebastian Meßmer
4caca2ce1a The configuration directory is a static attribute in mirallconfigfile class 2013-01-14 00:48:26 +01:00
Sebastian Meßmer
e0645b4b63 Allow setting the configuration directory on command line 2013-01-02 19:08:14 +01:00
Sebastian Kügler
591b71cf18 Return QNetworkReply from remote mkdir
This patch allows the client implementation to react to specific results
of mkdir requests

I need this patch to be able to catch errors from creating remote
folders.
2012-09-11 05:26:07 +02:00
Sebastian Kügler
76e9687d6f Return QNetworkReply from getRequests
This patch allows the client implementation to react to specific
getRequests, such as folder checks, etc. It allows to connect
client-specific slots to requests, catch its errors and handle them
separately.

I need this patch to be able to check more than one remote folder on the
server, and not mix up their job's signal handling.
2012-09-11 03:35:32 +02:00
116 changed files with 12636 additions and 8687 deletions

View File

@@ -1,6 +1,50 @@
ChangeLog
=========
version 1.2.4 (release 2013-04-11 ), csync 0.70.6 required
* [Fixes] Clarify string in folder wizard
* [Fixes] Fixed some valgrind warnings
* [Fixes] Ensure that only one sync thread can ever run
* [Fixes] Fix default config storage path
* [Fixes] Skip folders with no absolute path
* [Fixes] Allow setting the configuration directory on command line
version 1.2.3 (release 2013-04-02 ), csync 0.70.5 required
* [Fixes] Unbreak self-signed certificate handling
version 1.2.2 (release 2013-04-02 ), csync 0.70.5 required
* [Fixes] Do not crash when local file tree contains symlinks
* [Fixes] Correctly handle locked files on Windows
* [Fixes] Display errors in all members of the SSL chain
* [Fixes] Enable Accessibility features on Windows
* [Fixes] Make setupFavLink work properly on Mac OS
* [Fixes] Ignore temporary files created by MS Office
* [Gui] Support Nautilus in setupFavLink
version 1.2.1 (release 2013-02-26 ), csync 0.70.4 required
* [Fixes] Leave configured folders on configuration changes.
* [Fixes] Do not allow to finish the setup dialog if connection can't be established.
* [Fixes] Better handling of credentials in setup dialog.
* [Fixes] Do not leak fd's to /dev/null when using gnutls
* [Fixes] Stop sync scheduling when configuration wizard starts.
* [Fixes] Clear pending network requests when stepping back in config wizard.
* [Fixes] User password dialog asynchronous issues.
* [Fixes] Make folderman starting and stoping the scheduling.
* [Fixes] Various minor fixes and cleanups.
* [Fixes] Crash on pausing sync
* [Fixes] Stale lock file after pausing sync
* [App] Load translations from app dir or bundle as well.
* [Platform] Build fixes and simplifications, ie. build only one lib.
* [Platform] Added some getter/setters for configuration values.
* [Platform] Added man pages.
* [Platform] Simplified/fixed credential store usage and custom configs.
* [Platform] Added soname version to libowncloudsync.
* [Platform] Pull in Qt translations
* [Gui] Make sync result popups less annoyingq
* [Gui] Fix for result popup
version 1.2.0 (release 2013-01-24 ), csync 0.70.2 required
* [GUI] New status dialog to show a detailed list of synced files.
* [GUI] New tray notifications about synced files.
@@ -51,10 +95,6 @@ version 1.1.1 (release 2012-10-18), csync 0.60.1 required
* [Fixes] csync: Allow single quote (') in file names
* [Fixes] csync: Remove stray temporary files
version 1.1.0 (release 2012-10-10), csync 0.60.0 required
* [GUI] Added an about dialog
* [GUI] Improved themeing capabilities of the client.
* [GUI] Minor fixes in folder assistant.
* [GUI] Reworked tray context menu.
* [GUI] Users can now sync the server root folder.
* [Fixes] Proxy support: now supports Proxy Auto-Configuration (PAC)
@@ -149,4 +189,3 @@ version 1.0.1 (release 2012-04-18), csync 0.50.5 required
* [Platform] MacOSX Bundle creation added
* [Platform] Enabled ranslations on Windows.

View File

@@ -45,12 +45,12 @@ if(WIN32)
# CPACK_INCLUDE_TOPLEVEL_DIRECTORY Controls whether CPack adds a top-level directory, usually of the form ProjectName-Version-OS, to the top of package tree. 0 to disable, 1 to enable
# CPACK_INSTALL_CMAKE_PROJECTS List of four values: Build directory, Project Name, Project Component, Directory in the package /home/andy/vtk/CMake-bin;CMake;ALL;/
set( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md" ) # File used as a description of a project /path/to/project/ReadMe.txt
set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "ownCloud Syncing Client" ) # Description summary of a project
set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "${APPLICATION_NAME} Syncing Client" ) # Description summary of a project
# CPACK_PACKAGE_EXECUTABLES List of pairs of executables and labels. Used by the NSIS generator to create Start Menu shortcuts. ccmake;CMake
set( CPACK_PACKAGE_INSTALL_DIRECTORY ${APPLICATION_NAME} ) # Installation directory on the target system -> C:\Program Files\fellody
set( CPACK_PACKAGE_INSTALL_REGISTRY_KEY ${APPLICATION_NAME} ) # Registry key used when installing this project CMake 2.5.0
set( CPACK_PACKAGE_NAME ${APPLICATION_NAME} ) # Package name, defaults to the project name
set( CPACK_PACKAGE_VENDOR "http://owncloud.com" ) # Package vendor name
set( CPACK_PACKAGE_VENDOR "http://${APPLICATION_DOMAIN}" ) # Package vendor name
endif()
# set( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt" ) # License file for the project, used by the STGZ, NSIS, and PackageMaker generators. /home/andy/vtk/CMake/Copyright.txt

View File

@@ -1,5 +1,6 @@
set( VERSION_MAJOR 1 )
set( VERSION_MINOR 2 )
set( VERSION_PATCH 0 )
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set( VERSION_PATCH 4 )
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX})
set( SOVERSION 0 )

View File

@@ -11,7 +11,7 @@ mount="/Volumes/$(basename $src_dmg|cut -d"-" -f1)"
test -e $tmp_dmg && rm -rf $tmp_dmg
hdiutil convert $src_dmg -format UDRW -o $tmp_dmg
open $tmp_dmg
sleep 2s
sleep 12s
pushd $mount
codesign -s "$identity" $mount/*.app
popd

View File

@@ -8,9 +8,6 @@
!define APPLICATION_LICENSE "@APPLICATION_LICENSE@"
!define WIN_SETUP_BITMAP_PATH "@WIN_SETUP_BITMAP_PATH@"
!define MUI_FINISHPAGE_LINK_LOCATION "http://www.${APPLICATION_DOMAIN}"
;-----------------------------------------------------------------------------
; Some installer script options (comment-out options not required)
;-----------------------------------------------------------------------------
@@ -34,9 +31,11 @@
!endif
!define MING_BIN "${MING_PATH}/bin"
!define MING_LIB "${MING_PATH}/lib"
!define MING_SHARE "${MING_PATH}/share"
!define BUILD_PATH "@CMAKE_BINARY_DIR@"
!define SOURCE_PATH "@CMAKE_SOURCE_DIR@"
!define QT_DLL_PATH "${MING_BIN}"
!define ACCESSIBLE_DLL_PATH "${MING_LIB}/qt4/plugins/accessible"
!define SQLITE_DLL_PATH "${MING_LIB}/qt4/plugins/sqldrivers"
!define IMAGEFORMATS_DLL_PATH "${MING_LIB}/qt4/plugins/imageformats"
@@ -64,7 +63,6 @@
; Initial installer setup and definitions.
;-----------------------------------------------------------------------------
Name "@CPACK_NSIS_PACKAGE_NAME@"
Caption "${APPLICATION_NAME} Setup"
BrandingText "${APPLICATION_NAME} ${VERSION} -- ${BUILD_TIME}"
OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
InstallDir "$PROGRAMFILES\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
@@ -105,13 +103,11 @@ ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
!define MUI_ICON ${NSI_PATH}\installer.ico
!define MUI_UNICON ${NSI_PATH}\installer.ico
!define MUI_WELCOMEFINISHPAGE_BITMAP ${WIN_SETUP_BITMAP_PATH}/welcome.bmp
!define MUI_WELCOMEPAGE_TITLE "Welcome to the @CPACK_PACKAGE_NAME@ ${VERSION} Setup Wizard"
!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation.$\r$\n$\r$\n$_CLICK"
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP ${WIN_SETUP_BITMAP_PATH}/page_header.bmp
!define MUI_COMPONENTSPAGE_SMALLDESC
!define MUI_FINISHPAGE_TITLE "@CPACK_PACKAGE_NAME@ Setup Completed"
!define MUI_FINISHPAGE_LINK "Click here to visit the @CPACK_PACKAGE_NAME@ website."
!define MUI_FINISHPAGE_LINK "www.${APPLICATION_DOMAIN}"
!define MUI_FINISHPAGE_LINK_LOCATION "http://www.${APPLICATION_DOMAIN}"
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
!ifdef OPTION_FINISHPAGE_RELEASE_NOTES
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
@@ -288,22 +284,83 @@ Section "${APPLICATION_NAME}" SEC_OWNCLOUD
;Main executable.
File "${BUILD_PATH}\bin\${APPLICATION_EXECUTABLE}"
File "${BUILD_PATH}\src\libowncloudsync.dll"
File "${BUILD_PATH}\src\mirall_ca.qm"
File "${BUILD_PATH}\src\mirall_cs_CZ.qm"
File "${BUILD_PATH}\src\mirall_da.qm"
File "${BUILD_PATH}\src\mirall_de.qm"
File "${BUILD_PATH}\src\mirall_el.qm"
File "${BUILD_PATH}\src\mirall_en.qm"
File "${BUILD_PATH}\src\mirall_eo.qm"
File "${BUILD_PATH}\src\mirall_es.qm"
File "${BUILD_PATH}\src\mirall_es_AR.qm"
File "${BUILD_PATH}\src\mirall_et_EE.qm"
File "${BUILD_PATH}\src\mirall_eu.qm"
File "${BUILD_PATH}\src\mirall_fa.qm"
File "${BUILD_PATH}\src\mirall_fi_FI.qm"
File "${BUILD_PATH}\src\mirall_fr.qm"
File "${BUILD_PATH}\src\mirall_gl.qm"
File "${BUILD_PATH}\src\mirall_he.qm"
File "${BUILD_PATH}\src\mirall_hr.qm"
File "${BUILD_PATH}\src\mirall_hu_HU.qm"
File "${BUILD_PATH}\src\mirall_it.qm"
File "${BUILD_PATH}\src\mirall_ja_JP.qm"
File "${BUILD_PATH}\src\mirall_ko.qm"
File "${BUILD_PATH}\src\mirall_lb.qm"
File "${BUILD_PATH}\src\mirall_lt_LT.qm"
File "${BUILD_PATH}\src\mirall_lv.qm"
File "${BUILD_PATH}\src\mirall_mk.qm"
File "${BUILD_PATH}\src\mirall_ms_MY.qm"
File "${BUILD_PATH}\src\mirall_nb_NO.qm"
File "${BUILD_PATH}\src\mirall_nl.qm"
File "${BUILD_PATH}\src\mirall_oc.qm"
File "${BUILD_PATH}\src\mirall_pl.qm"
File "${BUILD_PATH}\src\mirall_pt_BR.qm"
File "${BUILD_PATH}\src\mirall_pt_PT.qm"
File "${BUILD_PATH}\src\mirall_ro.qm"
File "${BUILD_PATH}\src\mirall_ru.qm"
File "${BUILD_PATH}\src\mirall_ru_RU.qm"
File "${BUILD_PATH}\src\mirall_si_LK.qm"
File "${BUILD_PATH}\src\mirall_sk_SK.qm"
File "${BUILD_PATH}\src\mirall_sl.qm"
File "${BUILD_PATH}\src\mirall_sr@latin.qm"
File "${BUILD_PATH}\src\mirall_sv.qm"
File "${BUILD_PATH}\src\mirall_ta_LK.qm"
File "${BUILD_PATH}\src\mirall_th_TH.qm"
File "${BUILD_PATH}\src\mirall_tr.qm"
File "${BUILD_PATH}\src\mirall_uk.qm"
File "${BUILD_PATH}\src\mirall_vi.qm"
File "${BUILD_PATH}\src\mirall_zh_CN.qm"
File "${BUILD_PATH}\src\mirall_zh_TW.qm"
#File "${MING_SHARE}\qt4\translations\qt_ar.qm"
File "${MING_SHARE}\qt4\translations\qt_cs.qm"
File "${MING_SHARE}\qt4\translations\qt_da.qm"
File "${MING_SHARE}\qt4\translations\qt_de.qm"
File "${MING_SHARE}\qt4\translations\qt_es.qm"
File "${MING_SHARE}\qt4\translations\qt_fa.qm"
File "${MING_SHARE}\qt4\translations\qt_fr.qm"
File "${MING_SHARE}\qt4\translations\qt_gl.qm"
File "${MING_SHARE}\qt4\translations\qt_he.qm"
File "${MING_SHARE}\qt4\translations\qt_hu.qm"
File "${MING_SHARE}\qt4\translations\qt_ja.qm"
File "${MING_SHARE}\qt4\translations\qt_ko.qm"
File "${MING_SHARE}\qt4\translations\qt_lt.qm"
File "${MING_SHARE}\qt4\translations\qt_pl.qm"
File "${MING_SHARE}\qt4\translations\qt_pt.qm"
File "${MING_SHARE}\qt4\translations\qt_ru.qm"
File "${MING_SHARE}\qt4\translations\qt_sk.qm"
File "${MING_SHARE}\qt4\translations\qt_sl.qm"
File "${MING_SHARE}\qt4\translations\qt_sv.qm"
File "${MING_SHARE}\qt4\translations\qt_uk.qm"
File "${MING_SHARE}\qt4\translations\qt_zh_CN.qm"
File "${MING_SHARE}\qt4\translations\qt_zh_TW.qm"
File "${MING_SHARE}\qt4\translations\qt_zh_TW.qm"
File "${MING_SHARE}\qt4\translations\qtkeychain_de.qm"
SetOutPath "$INSTDIR\accessible"
File "${ACCESSIBLE_DLL_PATH}\qtaccessiblewidgets4.dll"
SetOutPath "$INSTDIR\modules"
; FIXME: fix installation dir of module, currently needs manual copying to
@@ -349,11 +406,10 @@ Section "${APPLICATION_NAME}" SEC_OWNCLOUD
;File "${MING_BIN}\libpng15-15.dll"
;File "${MING_BIN}\libjpeg-8.dll"
File "${MING_BIN}\zlib1.dll"
File "${MING_BIN}\libcrypto-8.dll"
File "${MING_BIN}\libssl-8.dll"
File "${MING_BIN}\libcrypto-10.dll"
File "${MING_BIN}\libssl-10.dll"
; CSync configs
File "${CSYNC_CONFIG_DIR}/ocsync.conf"
File "${SOURCE_PATH}/sync-exclude.lst"
SectionEnd

View File

@@ -13,7 +13,15 @@ if(SPHINX_FOUND)
set(LATEX_LOGO "${CMAKE_CURRENT_SOURCE_DIR}/logo-blue.pdf")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" conf.py @ONLY)
add_custom_target(doc DEPENDS doc-html doc-man COMMENT "Building documentation...")
if(WITH_DOC)
add_custom_target(doc ALL DEPENDS doc-html doc-man COMMENT "Building documentation...")
install(DIRECTORY ${SPHINX_HTML_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(DIRECTORY ${SPHINX_MAN_DIR} DESTINATION ${CMAKE_INSTALL_MANDIR})
else(WITH_DOC)
add_custom_target(doc DEPENDS doc-html doc-man COMMENT "Building documentation...")
endif(WITH_DOC)
if(PDFLATEX_FOUND)
# if this still fails on Debian/Ubuntu, run
# apt-get install texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended
@@ -26,6 +34,9 @@ if(SPHINX_FOUND)
add_custom_target(doc-pdf make -C ${SPHINX_PDF_DIR} all-pdf
DEPENDS doc-latex )
add_dependencies(doc doc-pdf)
if (WITH_DOC)
install(DIRECTORY ${SPHINX_PDF_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
endif (WITH_DOC)
endif(PDFLATEX_FOUND)
if (EXISTS ${QT_QCOLLECTIONGENERATOR_EXECUTABLE})
add_custom_target( doc-qch-sphinx ${SPHINX_EXECUTABLE}
@@ -37,6 +48,9 @@ if(SPHINX_FOUND)
${SPHINX_QCH_DIR}/*.qhcp
DEPENDS doc-qch-sphinx )
add_dependencies(doc doc-qch)
if (WITH_DOC)
install(DIRECTORY ${SPHINX_QCH_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
endif (WITH_DOC)
endif()
add_custom_target( doc-html ${SPHINX_EXECUTABLE}
-q -c . -b html
@@ -48,6 +62,7 @@ if(SPHINX_FOUND)
-d ${SPHINX_CACHE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_MAN_DIR} )
## Building CHM files requires HTML Help Workshop. Since it requires wine
## with special dependencies, it's impossible to write a cmake check for it.
## This is why doc-chm is not a dependency for doc. Instead, run

View File

@@ -151,6 +151,10 @@ To build in installer (requires the mingw32-cross-nsis packages)::
make package
Known cmake parameters:
* WITH_DOC=TRUE: create doc and manpages via running ``make``; also adds install statements to be able to install it via ``make install``.
.. _`ownCloud repository from OBS`: http://software.opensuse.org/download/package?project=isv:ownCloud:devel&package=owncloud-client
.. _CSync: http://www.csync.org
.. _`Client Download Page`: http://owncloud.org/sync-clients/

View File

@@ -213,12 +213,14 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'owncloud', u'ownCloud Client Manual',
('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.
#man_show_urls = False
man_show_urls = True
# -- Options for Texinfo output ------------------------------------------------

31
doc/conffile.rst Normal file
View File

@@ -0,0 +1,31 @@
ownCloud Client reads a configuration file.
On Linux it can be found in:
``$HOME/.local/share/data/ownCloud/owncloud.cfg``
On Windows it can be found in:
``%LOCALAPPDATA%\ownCloud\owncloud.cfg``
On Mac it can be found in:
``$HOME/Library/Application Support/ownCloud``
It contains settings in the ini file format known from Windows.
.. note:: Changes here should be done carefully as wrong settings can cause disfunctionality.
.. 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``)
Poll time for the remote repository in milliseconds
``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.

38
doc/mirall.1.rst Normal file
View File

@@ -0,0 +1,38 @@
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)`

15
doc/options.rst Normal file
View File

@@ -0,0 +1,15 @@
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.
``--flushlog``
flush the log file after every write.
``--monoicons``
Use black/white pictograms for systray.

37
doc/owncloud.1.rst Normal file
View File

@@ -0,0 +1,37 @@
owncloud(1)
-----------
SYNOPSIS
========
*owncloud* [`OPTIONS`...]
DESCRIPTION
===========
owncloud is a file synchronisation desktop utility it is 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.
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)`

View File

@@ -5,7 +5,7 @@ Troubleshooting
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
address bar.
address bar.
If you are not prompted to enter your user name and password, please verify
that your server installation is working correctly.
@@ -14,6 +14,13 @@ Troubleshooting
your provided are correct, please ensure that your authentication backend
is configured properly.
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. I 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.
:The desktop client fails for an unknown reason:
Start the client with ``--logwindow``. You can also open a log window for an
@@ -26,3 +33,10 @@ Troubleshooting
The log output can help you with tracking down problem, and if you report
a bug, it's useful to include the output.
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
``/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. More information about the apache logging can be found at
``http://httpd.apache.org/docs/current/logs.html``.

View File

@@ -13,46 +13,12 @@ connections as well as pausing a sync connection.
A right click on the tray icon gives other configuration options.
Command line switches
---------------------
Options
-------
.. index:: command line switches, command line, options, parameters
ownCloud Client supports the following command line switches:
+--------------------------+------------------------------------------------+
| Switch | Action |
+==========================+================================================+
| ``--logwindow`` | open a window to show log output at startup. |
+--------------------------+------------------------------------------------+
| ``--logfile <filename>`` | write log output to file. |
+--------------------------+------------------------------------------------+
| ``--flushlog`` | flush the log file after every write. |
+--------------------------+------------------------------------------------+
.. include:: options.rst
Config File
-----------
.. index:: config file
ownCloud Client reads a configuration file which on Linux can be found at ``$HOME/.local/share/data/ownCloud/owncloud.cfg``
On Windows, it can be found in ``\Users\<name>\AppData\Local\ownCloud\owncloud.cfg``
.. todo:: Mac?
It contains settings in the ini file format known from Windows.
.. note:: Changes here should be done carefully as wrong settings can cause disfunctionality.
These are config settings that may be changed:
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
| Setting | Data Type | Unit | Default | Description |
+===========================+===========+==============+===========+=====================================================+
| ``remotePollinterval`` | integer | milliseconds | ``30000`` | Poll time for the remote repository |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
| ``maxLogLines`` | integer | lines | ``20000`` | Maximum count of log lines shown in the log window |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
* ``remotePollinterval`` The frequency used for polling for remote changes on
the ownCloud Server.
.. include:: conffile.rst

View File

@@ -1,24 +1,16 @@
<RCC>
<qresource prefix="/mirall">
<file>resources/mirall-32.png</file>
<file>resources/mirall-64.png</file>
<file>resources/mirall-128.png</file>
<file>resources/folder-grey-32.png</file>
<file>resources/folder-remote-32.png</file>
<file>resources/folder-grey-22.png</file>
<file>resources/folder-remote-22.png</file>
<file>resources/mirall-22.png</file>
<file>resources/mirall-48.png</file>
<file>resources/folder-grey-48.png</file>
<file>resources/folder-remote-48.png</file>
<file>resources/dialog-close.png</file>
<file>resources/dialog-ok.png</file>
<file>resources/dialog-cancel.png</file>
<file>resources/view-refresh.png</file>
<file>resources/folder-favorites.png</file>
<file>resources/folder-sync-48.png</file>
<file>resources/folder-important.png</file>
<file>resources/folder-remote-32.png</file>
<file>resources/folder-remote.png</file>
<file>resources/folder-sync.png</file>
<file>resources/folder-grey.png</file>
<file>resources/mirall-32.png</file>
<file>resources/mirall-128.png</file>
<file>resources/mirall-48.png</file>
<file>resources/task-ongoing.png</file>
<file>resources/view-refresh.png</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
resources/lock-http.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

BIN
resources/lock-https.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -64,7 +64,6 @@ set(libsync_SRCS
mirall/folderman.cpp
mirall/folder.cpp
mirall/folderwatcher.cpp
mirall/gitfolder.cpp
mirall/syncresult.cpp
mirall/unisonfolder.cpp
mirall/networklocation.cpp
@@ -85,7 +84,6 @@ set(libsync_HEADERS
mirall/folderman.h
mirall/folder.h
mirall/folderwatcher.h
mirall/gitfolder.h
mirall/unisonfolder.h
mirall/csyncfolder.h
mirall/owncloudfolder.h
@@ -115,6 +113,7 @@ qt4_wrap_cpp(syncMoc ${libsync_HEADERS})
list(APPEND libsync_LINK_TARGETS
${QT_LIBRARIES}
${CSYNC_LIBRARY}
dl
)
if(QTKEYCHAIN_FOUND)
@@ -122,20 +121,21 @@ if(QTKEYCHAIN_FOUND)
include_directories(${QTKEYCHAIN_INCLUDE_DIR})
endif()
add_library(mirallsync SHARED ${libsync_SRCS} ${syncMoc})
add_library(owncloudsync SHARED ${libsync_SRCS} ${syncMoc})
set_target_properties( owncloudsync PROPERTIES COMPILE_DEFINITIONS OWNCLOUD_CLIENT)
set_target_properties( owncloudsync PROPERTIES
VERSION ${VERSION}
SOVERSION ${SOVERSION}
)
target_link_libraries(mirallsync ${libsync_LINK_TARGETS} )
target_link_libraries(owncloudsync ${libsync_LINK_TARGETS} )
if ( APPLE )
target_link_libraries(mirallsync /System/Library/Frameworks/CoreServices.framework)
target_link_libraries(owncloudsync /System/Library/Frameworks/CoreServices.framework)
endif()
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
install(TARGETS mirallsync owncloudsync
install(TARGETS owncloudsync
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
@@ -146,7 +146,7 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_SHORTNAME}.desktop DESTINATION share/applications )
endif()
else()
install(TARGETS mirallsync owncloudsync DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
install(TARGETS owncloudsync DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
endif()
set(mirall_SRCS
@@ -233,7 +233,7 @@ endif(NOT WIN32)
add_executable( mirall WIN32 main.cpp ${final_src})
target_link_libraries(mirall ${QT_LIBRARIES} )
target_link_libraries(mirall mirallsync)
target_link_libraries(mirall owncloudsync)
target_link_libraries(mirall ${CSYNC_LIBRARY})
set_target_properties( mirall PROPERTIES
@@ -260,8 +260,13 @@ else()
else()
install(FILES /usr/local/lib/ocsync-0/ocsync_owncloud.so DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Plugins)
endif()
install(FILES ${mirall_I18N} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/translations)
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
install(FILES ${mirall_I18N} DESTINATION ${QM_DIR})
file(GLOB qt_I18N ${QT_TRANSLATIONS_DIR}/qt_??.qm ${QT_TRANSLATIONS_DIR}/qt_??_??.qm)
install(FILES ${qt_I18N} DESTINATION ${QM_DIR})
file(GLOB qtkeychain_I18N ${QT_TRANSLATIONS_DIR}/qtkeychain*.qm)
install(FILES ${qtkeychain_I18N} DESTINATION ${QM_DIR})
list(APPEND dirs "/usr/local/lib")
endif()
@@ -280,7 +285,7 @@ install(TARGETS ${APPLICATION_EXECUTABLE}
BUNDLE DESTINATION "."
)
#FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unneccessary
#FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unnecessary
# currently it needs to be done because the code right above needs to be executed no matter
# if building a bundle or not and the install_qt4_executable needs to be called afterwards
if(BUILD_OWNCLOUD_OSX_BUNDLE)

View File

@@ -32,8 +32,10 @@ int main(int argc, char **argv)
return 0;
}
// if help requested, show on command line and exit.
if( ! app.giveHelp() )
if( ! app.giveHelp() ) {
return app.exec();
} else {
app.showHelp();
}
}

View File

@@ -33,10 +33,6 @@
#include "mirall/credentialstore.h"
#include "mirall/logger.h"
// for version information
#include "config.h"
#include <csync.h>
#ifdef WITH_CSYNC
#include "mirall/csyncfolder.h"
#endif
@@ -52,6 +48,10 @@
#include <QNetworkProxy>
#include <QNetworkProxyFactory>
#ifdef Q_OS_LINUX
#include <dlfcn.h>
#endif
namespace Mirall {
// application logging handler.
@@ -61,6 +61,22 @@ void mirallLogCatcher(QtMsgType type, const char *msg)
Logger::instance()->mirallLog( QString::fromUtf8(msg) );
}
namespace {
QString applicationTrPath()
{
#ifdef Q_OS_LINUX
// FIXME - proper path!
return QLatin1String("/usr/share/mirall/i18n/");
#endif
#ifdef Q_OS_MAC
return QApplication::applicationDirPath()+QLatin1String("/../Resources/Translations"); // path defaults to app dir.
#endif
#ifdef Q_OS_WIN32
return QApplication::applicationDirPath();
#endif
}
}
// ----------------------------------------------------------------------------------
Application::Application(int &argc, char **argv) :
@@ -79,36 +95,24 @@ Application::Application(int &argc, char **argv) :
_helpOnly(false),
_fileItemDialog(0)
{
setApplicationName( _theme->appName() );
setApplicationName( _theme->appNameGUI() );
setWindowIcon( _theme->applicationIcon() );
parseOptions(arguments());
setupTranslations();
setupLogBrowser();
//no need to waste time;
if ( _helpOnly ) return;
QTranslator *qtTranslator = new QTranslator(this);
qtTranslator->load(QLatin1String("qt_") + QLocale::system().name(),
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
installTranslator(qtTranslator);
QTranslator *mirallTranslator = new QTranslator(this);
QString locale = Theme::instance()->enforcedLocale();
if (locale.isEmpty()) locale = QLocale::system().name();
#ifdef Q_OS_LINUX
// FIXME - proper path!
mirallTranslator->load(QLatin1String("mirall_") + locale, QLatin1String("/usr/share/mirall/i18n/"));
// HACK: bump the refcount for libgnutls by calling dlopen()
// so gnutls, which is an dependency of libneon on some linux
// distros, and does not cleanup it's FDs properly, does
// not get unloaded. This works around a FD exhaustion crash
// (#154). We are not using gnutls at all and it's fine
// if loading fails, so no error handling is performed here.
dlopen("libgnutls.so", RTLD_LAZY|RTLD_NODELETE);
#endif
#ifdef Q_OS_MAC
mirallTranslator->load(QLatin1String("mirall_") + locale, applicationDirPath()+QLatin1String("/../translations") ); // path defaults to app dir.
#endif
#ifdef Q_OS_WIN32
mirallTranslator->load(QLatin1String("mirall_") + locale, applicationDirPath());
#endif
installTranslator(mirallTranslator);
connect( this, SIGNAL(messageReceived(QString)), SLOT(slotParseOptions(QString)));
connect( Logger::instance(), SIGNAL(guiLog(QString,QString)),
@@ -117,6 +121,7 @@ Application::Application(int &argc, char **argv) :
_folderMan = new FolderMan(this);
connect( _folderMan, SIGNAL(folderSyncStateChange(QString)),
this,SLOT(slotSyncStateChange(QString)));
_folderMan->setSyncEnabled(false);
/* use a signal mapper to map the open requests to the alias names */
_folderOpenActionMapper = new QSignalMapper(this);
@@ -136,9 +141,6 @@ Application::Application(int &argc, char **argv) :
connect( _statusDialog, SIGNAL(removeFolderAlias( const QString&)),
SLOT(slotRemoveFolder(const QString&)));
connect( _statusDialog, SIGNAL(openLogBrowser()), this, SLOT(slotOpenLogBrowser()));
connect( _statusDialog, SIGNAL(enableFolderAlias(QString,bool)),
SLOT(slotEnableFolder(QString,bool)));
connect( _statusDialog, SIGNAL(infoFolderAlias(const QString&)),
@@ -158,6 +160,10 @@ Application::Application(int &argc, char **argv) :
setupSystemTray();
setupProxy();
int cnt = _folderMan->setupFolders();
_statusDialog->setFolderList( _folderMan->map() );
QObject::connect( this, SIGNAL(messageReceived(QString)),
this, SLOT(slotOpenStatus()) );
@@ -178,7 +184,7 @@ Application::~Application()
{
delete _tray; // needed, see ctor
if( _fileItemDialog) delete _fileItemDialog;
if( _statusDialog ) delete _statusDialog;
if( _statusDialog && ! _helpOnly) delete _statusDialog;
qDebug() << "* Mirall shutdown";
}
@@ -222,9 +228,9 @@ void Application::slotOwnCloudFound( const QString& url, const QString& versionS
this, SLOT(slotNoOwnCloudFound(QNetworkReply*)));
if( version.startsWith("4.0") ) {
QMessageBox::warning(0, tr("%1 Server Mismatch").arg(_theme->appName()),
QMessageBox::warning(0, tr("%1 Server Mismatch").arg(_theme->appNameGUI()),
tr("<p>The configured server for this client is too old.</p>"
"<p>Please update to the latest %1 server and restart the client.</p>").arg(_theme->appName()));
"<p>Please update to the latest %1 server and restart the client.</p>").arg(_theme->appNameGUI()));
return;
}
@@ -233,17 +239,10 @@ void Application::slotOwnCloudFound( const QString& url, const QString& versionS
void Application::slotNoOwnCloudFound( QNetworkReply* reply )
{
qDebug() << "** Application: NO ownCloud found!";
QString msg;
if( reply ) {
QString url( reply->url().toString() );
url.remove( QLatin1String("/status.php") );
msg = tr("<p>The %1 at %2 could not be reached.</p>").arg(_theme->appName()).arg( url );
msg += tr("<p>The detailed error message is<br/><tt>%1</tt></p>").arg( reply->errorString() );
}
msg += tr("<p>Please check your configuration by clicking on the tray icon.</p>");
Q_UNUSED(reply)
qDebug() << "** Application: NO ownCloud found! Going offline";
QMessageBox::warning(0, tr("%1 Connection Failed").arg(_theme->appName()), msg );
_actionAddFolder->setEnabled( false );
// Disconnect.
@@ -257,6 +256,7 @@ void Application::slotNoOwnCloudFound( QNetworkReply* reply )
this,SLOT(slotAuthCheck(QString,QNetworkReply*)));
setupContextMenu();
QTimer::singleShot( 30*1000, this, SLOT( slotStartFolderSetup() ));
}
void Application::slotFetchCredentials()
@@ -273,7 +273,7 @@ void Application::slotFetchCredentials()
} else {
qDebug() << "Can not try again to fetch Credentials.";
trayMessage = tr("%1 user credentials are wrong. Please check configuration.")
.arg(Theme::instance()->appName());
.arg(Theme::instance()->appNameGUI());
}
if( !trayMessage.isEmpty() ) {
@@ -303,6 +303,8 @@ void Application::slotCredentialsFetched(bool ok)
_actionAddFolder->setEnabled( false );
_actionOpenStatus->setEnabled( false );
} else {
ownCloudInfo::instance()->setCredentials( CredentialStore::instance()->user(),
CredentialStore::instance()->password() );
// Credential fetched ok.
QTimer::singleShot( 0, this, SLOT( slotCheckAuthentication() ));
}
@@ -326,16 +328,16 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
if( reply->error() == QNetworkReply::AuthenticationRequiredError ) { // returned if the user is wrong.
qDebug() << "******** Password is wrong!";
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appName()),
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appNameGUI()),
tr("<p>Your %1 credentials are not correct.</p>"
"<p>Please correct them by starting the configuration dialog from the tray!</p>")
.arg(_theme->appName()));
.arg(_theme->appNameGUI()));
_actionAddFolder->setEnabled( false );
ok = false;
} else if( reply->error() == QNetworkReply::OperationCanceledError ) {
// the username was wrong and ownCloudInfo was closing the request after a couple of auth tries.
qDebug() << "******** Username or password is wrong!";
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appName()),
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appNameGUI()),
tr("<p>Either your user name or your password are not correct.</p>"
"<p>Please correct it by starting the configuration dialog from the tray!</p>"));
_actionAddFolder->setEnabled( false );
@@ -348,19 +350,22 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
if( ok ) {
qDebug() << "######## Credentials are ok!";
int cnt = _folderMan->setupFolders();
if( cnt ) {
_tray->setIcon( _theme->syncStateIcon( SyncResult::NotYetStarted, true ) );
_tray->show();
_folderMan->setSyncEnabled(true);
QMetaObject::invokeMethod(_folderMan, "slotScheduleFolderSync");
if( _tray )
_tray->showMessage(tr("%1 Sync Started").arg(_theme->appName()),
tr("Sync started for %1 configured sync folder(s).").arg(cnt));
_tray->setIcon( _theme->syncStateIcon( SyncResult::NotYetStarted, true ) );
_tray->show();
_statusDialog->setFolderList( _folderMan->map() );
computeOverallSyncStatus();
int cnt = _folderMan->map().size();
if( _tray )
_tray->showMessage(tr("%1 Sync Started").arg(_theme->appNameGUI()),
tr("Sync started for %1 configured sync folder(s).").arg(cnt));
// queue up the sync for all folders.
_folderMan->slotScheduleAllFolders();
computeOverallSyncStatus();
}
_actionAddFolder->setEnabled( true );
_actionOpenStatus->setEnabled( true );
setupContextMenu();
@@ -408,14 +413,17 @@ void Application::slotSSLFailed( QNetworkReply *reply, QList<QSslError> errors )
void Application::slotownCloudWizardDone( int res )
{
if( res == QDialog::Accepted ) {
int cnt = _folderMan->setupFolders();
qDebug() << "Set up " << cnt << " folders.";
_statusDialog->setFolderList( _folderMan->map() );
}
_folderMan->setSyncEnabled( true );
slotStartFolderSetup( res );
}
void Application::setupActions()
{
_actionOpenoC = new QAction(tr("Open %1 in browser...").arg(_theme->appName()), this);
_actionOpenoC = new QAction(tr("Open %1 in browser...").arg(_theme->appNameGUI()), this);
QObject::connect(_actionOpenoC, SIGNAL(triggered(bool)), SLOT(slotOpenOwnCloud()));
_actionOpenStatus = new QAction(tr("Open status..."), this);
QObject::connect(_actionOpenStatus, SIGNAL(triggered(bool)), SLOT(slotOpenStatus()));
@@ -463,7 +471,7 @@ void Application::setupContextMenu()
// it will trigger a bug in Ubuntu's SNI bridge patch (11.10, 12.04).
_tray->setContextMenu(_contextMenu);
}
_contextMenu->setTitle(_theme->appName() );
_contextMenu->setTitle(_theme->appNameGUI() );
_contextMenu->addAction(_actionOpenStatus);
_contextMenu->addAction(_actionOpenoC);
@@ -482,7 +490,7 @@ void Application::setupContextMenu()
Folder *folder = _folderMan->map().value(li.first());
if( folder ) {
// if there is singleFolder mode, a generic open action is displayed.
QAction *action = new QAction( tr("Open %1 folder").arg(_theme->appName()), this);
QAction *action = new QAction( tr("Open %1 folder").arg(_theme->appNameGUI()), this);
action->setIcon( _theme->trayFolderIcon( folder->backend()) );
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
@@ -539,8 +547,9 @@ void Application::setupLogBrowser()
if (_showLogWindow)
slotOpenLogBrowser();
qDebug() << QString::fromLatin1( "################## %1 %2 %3 ").arg(_theme->appName())
qDebug() << QString::fromLatin1( "################## %1 %2 (%3) %4").arg(_theme->appName())
.arg( QLocale::system().name() )
.arg(property("ui_lang").toString())
.arg(_theme->version());
}
@@ -629,7 +638,7 @@ void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
void Application::slotAddFolder()
{
_folderMan->disableFoldersWithRestore();
_folderMan->setSyncEnabled(false); // do not start more syncs.
Folder::Map folderMap = _folderMan->map();
@@ -669,6 +678,8 @@ void Application::slotAddFolder()
goodData = false;
}
_folderMan->setSyncEnabled(true); // do start sync again.
if( goodData ) {
_folderMan->addFolderDefinition( backend, alias, sourceFolder, targetPath, onlyThisLAN );
Folder *f = _folderMan->setupFolderFromConfigFile( alias );
@@ -682,7 +693,8 @@ void Application::slotAddFolder()
} else {
qDebug() << "* Folder wizard cancelled";
}
_folderMan->restoreEnabledFolders();
_folderMan->setSyncEnabled(true);
_folderMan->slotScheduleAllFolders();
}
void Application::slotOpenStatus()
@@ -702,6 +714,7 @@ void Application::slotOpenStatus()
if( !cfgFile.exists() ) {
qDebug() << "No configured folders yet, start the Owncloud integration dialog.";
_folderMan->setSyncEnabled(false);
_owncloudSetupWizard->startWizard(true); // with intro
} else {
qDebug() << "#============# Status dialog starting #=============#";
@@ -738,19 +751,7 @@ void Application::slotOpenLogBrowser()
void Application::slotAbout()
{
QString devString;
#ifdef GIT_SHA1
const QString githubPrefix(QLatin1String(
"https://github.com/owncloud/mirall/commit/"));
const QString gitSha1(QLatin1String(GIT_SHA1));
devString = tr("<p><small>Built from Git revision <a href=\"%1\">%2</a>"
" on %3, %4<br>using OCsync %5 and Qt %6.</small><p>")
.arg(githubPrefix+gitSha1).arg(gitSha1.left(6))
.arg(__DATE__).arg(__TIME__)
.arg(MIRALL_STRINGIFY(LIBCSYNC_VERSION))
.arg(QT_VERSION_STR);
#endif
QMessageBox::about(0, tr("About %1").arg(_theme->appName()),
QMessageBox::about(0, tr("About %1").arg(_theme->appNameGUI()),
Theme::instance()->about());
}
@@ -824,9 +825,8 @@ void Application::slotEnableFolder(const QString& alias, const bool enable)
void Application::slotConfigure()
{
_folderMan->disableFoldersWithRestore();
_owncloudSetupWizard->startWizard(false);
_folderMan->restoreEnabledFolders();
_folderMan->setSyncEnabled(false); // do not start more syncs.
_owncloudSetupWizard->startWizard(false);
}
void Application::slotConfigureProxy()
@@ -873,10 +873,12 @@ void Application::parseOptions(const QStringList &options)
// skip file name;
if (it.hasNext()) it.next();
//parse options; if help or bad option exit
while (it.hasNext()) {
QString option = it.next();
if (option == QLatin1String("--help")) {
showHelp();
if (option == QLatin1String("--help") || option == QLatin1String("-h")) {
setHelp();
break;
} else if (option == QLatin1String("--logwindow") ||
option == QLatin1String("-l")) {
_showLogWindow = true;
@@ -884,14 +886,24 @@ void Application::parseOptions(const QStringList &options)
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
_logFile = it.next();
} else {
showHelp();
setHelp();
}
} else if (option == QLatin1String("--logflush")) {
_logFlush = true;
} else if (option == QLatin1String("--monoicons")) {
_theme->setSystrayUseMonoIcons(true);
} else if (option == QLatin1String("--confdir")) {
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
QString confDir = it.next();
MirallConfigFile::setConfDir( confDir );
} else {
showHelp();
}
} else {
setHelp();
break;
}
}
}
}
void Application::computeOverallSyncStatus()
@@ -920,6 +932,10 @@ void Application::computeOverallSyncStatus()
folderMessage = tr( "Waits to start syncing." );
overallResult.setStatus( SyncResult::NotYetStarted );
break;
case SyncResult::SyncPrepare:
folderMessage = tr( "Preparing for sync." );
overallResult.setStatus( SyncResult::SyncPrepare );
break;
case SyncResult::SyncRunning:
folderMessage = tr( "Sync is running." );
overallResult.setStatus( SyncResult::SyncRunning );
@@ -978,20 +994,97 @@ void Application::computeOverallSyncStatus()
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;
if (_theme->appName() == QLatin1String("ownCloud"))
std::cout << "For more information, see http://www.owncloud.org" << std::endl;
}
void Application::setHelp()
{
_helpOnly = true;
}
QString substLang(const QString &lang)
{
// Map the more apropriate script codes
// to country codes as used by Qt and
// transifex translation conventions.
// Simplified Chinese
if (lang == QLatin1String("zh_Hans"))
return QLatin1String("zh_CN");
// Traditional Chinese
if (lang == QLatin1String("zh_Hant"))
return QLatin1String("zh_TW");
return lang;
}
void Application::setupTranslations()
{
QStringList uiLanguages;
// uiLanguages crashes on Windows with 4.8.0 release builds
#if (QT_VERSION >= 0x040801) || (QT_VERSION >= 0x040800 && !defined(Q_OS_WIN))
uiLanguages = QLocale::system().uiLanguages();
#else
// older versions need to fall back to the systems locale
uiLanguages << QLocale::system().name();
#endif
QString enforcedLocale = Theme::instance()->enforcedLocale();
if (!enforcedLocale.isEmpty())
uiLanguages.prepend(enforcedLocale);
QTranslator *translator = new QTranslator(this);
QTranslator *qtTranslator = new QTranslator(this);
QTranslator *qtkeychainTranslator = new QTranslator(this);
foreach(QString lang, uiLanguages) {
lang.replace(QLatin1Char('-'), QLatin1Char('_')); // work around QTBUG-25973
lang = substLang(lang);
const QString trPath = applicationTrPath();
const QString trFile = QLatin1String("mirall_") + lang;
if (translator->load(trFile, trPath) ||
lang.startsWith(QLatin1String("en"))) {
// Permissive approach: Qt and keychain translations
// may be missing, but Qt translations must be there in order
// for us to accept the language. Otherwise, we try with the next.
// "en" is an exeption as it is the default language and may not
// have a translation file provided.
qDebug() << Q_FUNC_INFO << "Using" << lang << "translation";
setProperty("ui_lang", lang);
const QString qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
const QString qtTrFile = QLatin1String("qt_") + lang;
if (qtTranslator->load(qtTrFile, qtTrPath)) {
qtTranslator->load(qtTrFile, trPath);
}
const QString qtkeychainFile = QLatin1String("qt_") + lang;
if (!qtkeychainTranslator->load(qtkeychainFile, qtTrPath)) {
qtkeychainTranslator->load(qtkeychainFile, trPath);
}
if (!translator->isEmpty())
installTranslator(translator);
if (!qtTranslator->isEmpty())
installTranslator(qtTranslator);
if (!qtkeychainTranslator->isEmpty())
installTranslator(qtkeychainTranslator);
break;
}
if (property("ui_lang").isNull())
setProperty("ui_lang", "C");
}
}
bool Application::giveHelp()
{
return _helpOnly;

View File

@@ -53,6 +53,7 @@ public:
~Application();
bool giveHelp();
void showHelp();
signals:
@@ -72,6 +73,7 @@ protected slots:
protected:
void parseOptions(const QStringList& );
void setupTranslations();
void setupActions();
void setupSystemTray();
void setupContextMenu();
@@ -98,7 +100,7 @@ protected slots:
void slotStartUpdateDetector();
private:
void showHelp();
void setHelp();
void raiseDialog( QWidget* );
// configuration file -> folder

View File

@@ -12,6 +12,7 @@
*/
#include <QtGui>
#include <QInputDialog>
#include "config.h"
@@ -19,6 +20,11 @@
#include "mirall/mirallconfigfile.h"
#include "mirall/theme.h"
#ifdef WITH_QTKEYCHAIN
#include <qtkeychain/keychain.h>
using namespace QKeychain;
#endif
#define MAX_LOGIN_ATTEMPTS 3
namespace Mirall {
@@ -47,11 +53,11 @@ CredentialStore *CredentialStore::instance()
return CredentialStore::_instance;
}
QString CredentialStore::password( const QString& ) const
QString CredentialStore::password() const
{
return _passwd;
}
QString CredentialStore::user( const QString& ) const
QString CredentialStore::user() const
{
return _user;
}
@@ -103,6 +109,9 @@ void CredentialStore::fetchCredentials()
QString pwd;
_user = cfgFile.ownCloudUser();
_url = cfgFile.ownCloudUrl();
if( !cfgFile.passwordStorageAllowed() ) {
_type = CredentialStore::User;
}
QString key = keyChainKey(_url);
@@ -117,15 +126,16 @@ void CredentialStore::fetchCredentials()
case CredentialStore::User: {
/* Ask the user for the password */
/* Fixme: Move user interaction out here. */
_state = Fetching;
pwd = QInputDialog::getText(0, QApplication::translate("MirallConfigFile","Password Required"),
QApplication::translate("MirallConfigFile","Please enter your %1 password:")
.arg(Theme::instance()->appName()),
QLineEdit::Password,
QString::null, &ok);
if( !ok ) {
_state = UserCanceled;
}
_state = AsyncFetching;
_inputDialog = new QInputDialog;
_inputDialog->setWindowTitle(QApplication::translate("MirallConfigFile","Password Required") );
_inputDialog->setLabelText( QApplication::translate("MirallConfigFile","Please enter your %1 password:")
.arg(Theme::instance()->appNameGUI()));
_inputDialog->setInputMode( QInputDialog::TextInput );
_inputDialog->setTextEchoMode( QLineEdit::Password );
connect(_inputDialog, SIGNAL(finished(int)), SLOT(slotUserDialogDone(int)));
_inputDialog->exec();
break;
}
case CredentialStore::Settings: {
@@ -179,6 +189,19 @@ void CredentialStore::fetchCredentials()
}
}
void CredentialStore::slotUserDialogDone( int result )
{
if( result == QDialog::Accepted ) {
_passwd = _inputDialog->textValue();
_state = Ok;
} else {
_state = UserCanceled;
_passwd = QString::null;
}
_inputDialog->deleteLater();
emit(fetchCredentialsFinished(_state == Ok));
}
void CredentialStore::reset()
{
_state = NotFetched;
@@ -281,19 +304,20 @@ QString CredentialStore::errorMessage()
return _errorMsg;
}
QByteArray CredentialStore::basicAuthHeader() const
{
QString concatenated = _user + QLatin1Char(':') + _passwd;
const QString b(QLatin1String("Basic "));
QByteArray data = b.toLocal8Bit() + concatenated.toLocal8Bit().toBase64();
return data;
}
void CredentialStore::setCredentials( const QString& url, const QString& user, const QString& pwd )
void CredentialStore::setCredentials( const QString& url, const QString& user,
const QString& pwd, bool allowToStore )
{
_passwd = pwd;
_user = user;
if( allowToStore ) {
#ifdef WITH_QTKEYCHAIN
_type = KeyChain;
#else
_type = Settings;
#endif
} else {
_type = User;
}
_url = url;
_state = Ok;
}

View File

@@ -14,21 +14,12 @@
#ifndef CREDENTIALSTORE_H
#define CREDENTIALSTORE_H
#include "config.h"
#include <QObject>
#include <QInputDialog>
#ifdef WITH_QTKEYCHAIN
#include "qtkeychain/keychain.h"
using namespace QKeychain;
#else
// FIXME: If the slot definition below is ifdefed for some reason the slot is
// not there even if WITH_QTKEYCHAIN is defined.
namespace QKeychain {
typedef void Job;
class Job;
}
#endif
namespace Mirall {
@@ -74,8 +65,8 @@ public:
KeyChain
};
QString password( const QString& connection = QString::null ) const;
QString user( const QString& connection = QString::null ) const;
QString password( ) const;
QString user( ) const;
/**
* @brief state
@@ -91,12 +82,6 @@ public:
*/
void fetchCredentials();
/**
* @brief basicAuthHeader - return a basic authentication header.
* @return a QByteArray with a ready to use Header for HTTP basic auth.
*/
QByteArray basicAuthHeader() const;
/**
* @brief instance - singleton pointer.
* @return the singleton pointer to access the object.
@@ -109,10 +94,11 @@ public:
* This function is called from the setup wizard to set the credentials
* int this store. Note that it does not store the password.
* The function also sets the state to ok.
* @param url - the connection url
* @param user - the user name
* @param password - the password.
*/
void setCredentials( const QString&, const QString&, const QString& );
void setCredentials( const QString&, const QString&, const QString&, bool );
void saveCredentials( );
@@ -138,6 +124,7 @@ signals:
protected slots:
void slotKeyChainReadFinished( QKeychain::Job* );
void slotKeyChainWriteFinished( QKeychain::Job* );
void slotUserDialogDone(int);
private:
explicit CredentialStore(QObject *parent = 0);
@@ -152,6 +139,7 @@ private:
static QString _errorMsg;
static int _tries;
static CredentialType _type;
QInputDialog *_inputDialog;
};
}

View File

@@ -58,6 +58,8 @@ void CSyncFolder::startSync(const QStringList &pathList)
delete _thread;
_errors.clear();
_csyncError = false;
_syncResult.setStatus( SyncResult::SyncRunning );
emit syncStateChange();
_thread = new QThread(this);
_csync = new CSyncThread( path(), secondPath() );

View File

@@ -26,6 +26,8 @@
#include <unistd.h>
#endif
#include <assert.h>
#include <QDebug>
#include <QSslSocket>
#include <QDir>
@@ -91,7 +93,7 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt
errStr = tr("CSync failed to load the state db.");
break;
case CSYNC_ERR_MODULE:
errStr = tr("<p>The %1 plugin for csync could not be loaded.<br/>Please verify the installation!</p>").arg(Theme::instance()->appName());
errStr = tr("<p>The %1 plugin for csync could not be loaded.<br/>Please verify the installation!</p>").arg(Theme::instance()->appNameGUI());
break;
case CSYNC_ERR_TIMESKEW:
errStr = tr("The system time on this client is different than the system time on the server. "
@@ -139,7 +141,7 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt
errStr = tr("CSync failed to lookup proxy or server.");
break;
case CSYNC_ERR_AUTH_SERVER:
errStr = tr("CSync failed to authenticate at the %1 server.").arg(Theme::instance()->appName());
errStr = tr("CSync failed to authenticate at the %1 server.").arg(Theme::instance()->appNameGUI());
break;
case CSYNC_ERR_AUTH_PROXY:
errStr = tr("CSync failed to authenticate at the proxy.");
@@ -163,7 +165,7 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt
errStr = tr("CSync tried to create a directory that already exists.");
break;
case CSYNC_ERR_NOSPC:
errStr = tr("CSync: No space on %1 server available.").arg(Theme::instance()->appName());
errStr = tr("CSync: No space on %1 server available.").arg(Theme::instance()->appNameGUI());
break;
case CSYNC_ERR_UNSPEC:
errStr = tr("CSync unspecified error.");
@@ -226,6 +228,14 @@ int CSyncThread::treewalkFile( TREE_WALK_FILE *file, bool remote )
int re = 0;
switch(file->instruction) {
case CSYNC_INSTRUCTION_NONE:
case CSYNC_INSTRUCTION_IGNORE:
break;
default:
if (!_needsUpdate)
_needsUpdate = true;
}
switch(file->instruction) {
case CSYNC_INSTRUCTION_NONE:
// No need to do anything.
@@ -271,51 +281,88 @@ int CSyncThread::treewalkError(TREE_WALK_FILE* file)
if ( indx == -1 )
return 0;
if( item._instruction == CSYNC_INSTRUCTION_STAT_ERROR ||
item._instruction == CSYNC_INSTRUCTION_ERROR ) {
if( file &&
file->instruction == CSYNC_INSTRUCTION_STAT_ERROR ||
file->instruction == CSYNC_INSTRUCTION_ERROR ) {
_mutex.lock();
_syncedItems[indx]._instruction = item._instruction;
_syncedItems[indx]._instruction = file->instruction;
_mutex.unlock();
}
return 0;
}
struct CSyncRunScopeHelper {
CSyncRunScopeHelper(CSYNC *_ctx, CSyncThread *_parent)
: ctx(_ctx), parent(_parent)
{
t.start();
}
~CSyncRunScopeHelper() {
csync_destroy(ctx);
qDebug() << "CSync run took " << t.elapsed() << " Milliseconds";
emit(parent->finished());
}
CSYNC *ctx;
QTime t;
CSyncThread *parent;
};
void CSyncThread::handleSyncError(CSYNC *ctx, const char *state) {
CSYNC_ERROR_CODE err = csync_get_error( ctx );
const char *errMsg = csync_get_error_string( ctx );
QString errStr = csyncErrorToString(err, errMsg);
qDebug() << " #### ERROR during "<< state << ": " << errStr;
switch (err) {
case CSYNC_ERR_SERVICE_UNAVAILABLE:
case CSYNC_ERR_CONNECT:
emit csyncUnavailable();
break;
default:
emit csyncError(errStr);
}
}
void CSyncThread::startSync()
{
qDebug() << Q_FUNC_INFO << "Sync started";
static int syncsRunning = 0;
syncsRunning++;
assert(syncsRunning == 1);
qDebug() << "starting to sync " << qApp->thread() << QThread::currentThread();
CSYNC *csync;
bool doTreeWalk = true;
int proxyPort = _proxy.port();
emit(started());
_mutex.lock();
_syncedItems.clear();
_needsUpdate = false;
_mutex.unlock();
if( csync_create(&csync,
_source.toUtf8().data(),
_target.toUtf8().data()) < 0 ) {
emit csyncError( tr("CSync create failed.") );
}
_csyncConfigDir = QString::fromUtf8( csync_get_config_dir( csync ));
MirallConfigFile cfg;
csync_set_config_dir( csync, cfg.configPath().toUtf8() );
_mutex.lock();
_csyncConfigDir = cfg.configPath();
_mutex.unlock();
csync_enable_conflictcopys(csync);
MirallConfigFile cfg;
QString excludeList = cfg.excludeFile();
if( !excludeList.isEmpty() ) {
qDebug() << "==== added CSync exclude List: " << excludeList.toUtf8();
csync_add_exclude_list( csync, excludeList.toUtf8() );
}
csync_set_config_dir( csync, cfg.configPath().toUtf8() );
QTime t;
t.start();
// cleans up behind us and emits finished() to ease error handling
CSyncRunScopeHelper helper(csync, this);
csync_set_userdata(csync, this);
@@ -324,12 +371,8 @@ void CSyncThread::startSync()
csync_set_progress_callback( csync, progress );
if( csync_init(csync) < 0 ) {
CSYNC_ERROR_CODE err = csync_get_error( csync );
const char *errMsg = csync_get_error_string( csync );
QString errStr = csyncErrorToString(err, errMsg );
qDebug() << " #### ERROR csync_init: " << errStr;
emit csyncError(errStr);
goto cleanup;
handleSyncError(csync, "csync_init");
return;
}
// set module properties, mainly the proxy information.
@@ -344,63 +387,44 @@ void CSyncThread::startSync()
qDebug() << "#### Update start #################################################### >>";
if( csync_update(csync) < 0 ) {
CSYNC_ERROR_CODE err = csync_get_error( csync );
const char *errMsg = csync_get_error_string( csync );
QString errStr = csyncErrorToString(err, errMsg);
qDebug() << " #### ERROR csync_update: " << errStr;
if (err == CSYNC_ERR_SERVICE_UNAVAILABLE)
emit csyncUnavailable();
else
emit csyncError(errStr);
goto cleanup;
handleSyncError(csync, "csync_update");
return;
}
qDebug() << "<<#### Update end ###########################################################";
if( csync_reconcile(csync) < 0 ) {
CSYNC_ERROR_CODE err = csync_get_error( csync );
const char *errMsg = csync_get_error_string( csync );
QString errStr = csyncErrorToString(err, errMsg);
qDebug() << " #### ERROR csync_reconcile: " << errStr;
emit csyncError(errStr);
goto cleanup;
handleSyncError(csync, "cysnc_reconcile");
return;
}
bool walkOk = true;
if( csync_walk_local_tree(csync, &treewalkLocal, 0) < 0 ) {
qDebug() << "Error in local treewalk.";
doTreeWalk = false;
qDebug() << "Error in local treewalk.";
walkOk = false;
}
if( doTreeWalk && csync_walk_remote_tree(csync, &treewalkRemote, 0) < 0 ) {
qDebug() << "Error in remote treewalk.";
doTreeWalk = false;
if( walkOk && csync_walk_remote_tree(csync, &treewalkRemote, 0) < 0 ) {
qDebug() << "Error in remote treewalk.";
}
if (_needsUpdate)
emit(started());
if( csync_propagate(csync) < 0 ) {
CSYNC_ERROR_CODE err = csync_get_error( csync );
const char *errMsg = csync_get_error_string( csync );
QString errStr = csyncErrorToString(err, errMsg);
qDebug() << " #### ERROR csync_propagate: " << errStr;
if (err == CSYNC_ERR_SERVICE_UNAVAILABLE)
emit csyncUnavailable();
else
emit csyncError(errStr);
goto cleanup;
handleSyncError(csync, "cysnc_reconcile");
return;
}
if( csync_walk_local_tree(csync, &walkFinalize, 0) < 0 ||
if( walkOk ) {
if( csync_walk_local_tree(csync, &walkFinalize, 0) < 0 ||
csync_walk_remote_tree( csync, &walkFinalize, 0 ) < 0 ) {
qDebug() << "Error in finalize treewalk.";
} else {
qDebug() << "Error in finalize treewalk.";
} else {
// emit the treewalk results.
emit treeWalkResult(_syncedItems);
emit treeWalkResult(_syncedItems);
}
}
cleanup:
csync_destroy(csync);
qDebug() << "CSync run took " << t.elapsed() << " Milliseconds";
emit(finished());
syncsRunning--;
qDebug() << Q_FUNC_INFO << "Sync finished";
}
void CSyncThread::setConnectionDetails( const QString &user, const QString &passwd, const QNetworkProxy &proxy )

View File

@@ -1,6 +1,3 @@
#ifndef CSYNCTHREAD_H
#define CSYNCTHREAD_H
/*
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
@@ -16,6 +13,9 @@
* for more details.
*/
#ifndef CSYNCTHREAD_H
#define CSYNCTHREAD_H
#include <stdint.h>
#include <QMutex>
@@ -61,6 +61,7 @@ signals:
void started();
private:
void handleSyncError(CSYNC *ctx, const char *state);
static void progress(const char *remote_url,
enum csync_notify_type_e kind,
long long o1, long long o2,
@@ -92,6 +93,9 @@ private:
QString _source;
QString _target;
bool _needsUpdate;
friend class CSyncRunScopeHelper;
};
}

View File

@@ -25,7 +25,7 @@ QStringList FileUtils::subFoldersList(QString folder,
SubFolderListOptions options)
{
QDir dir(folder);
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
QFileInfoList list = dir.entryInfoList();
QStringList dirList;

View File

@@ -11,6 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "config.h"
#include "mirall/folder.h"
#include "mirall/folderwatcher.h"
@@ -192,6 +193,11 @@ int Folder::pollInterval() const
return _pollTimer->interval();
}
void Folder::setSyncState(SyncResult::Status state)
{
_syncResult.setStatus(state);
}
void Folder::setPollInterval(int milliseconds)
{
_pollTimer->setInterval( milliseconds );
@@ -247,12 +253,6 @@ void Folder::evaluateSync(const QStringList &pathList)
}
void Folder::startSync( const QStringList &pathList )
{
_syncResult.setStatus( SyncResult::SyncRunning );
emit syncStateChange();
}
void Folder::slotPollTimerTimeout()
{
qDebug() << "* Polling" << alias() << "for changes. Ignoring all pending events until now";

View File

@@ -15,7 +15,6 @@
#ifndef MIRALL_FOLDER_H
#define MIRALL_FOLDER_H
#include "config.h"
#include <QObject>
#include <QString>
@@ -46,6 +45,7 @@ public:
virtual ~Folder();
typedef QHash<QString, Folder*> Map;
typedef QHashIterator<QString, Folder*> MapIterator;
/**
* alias or nickname
@@ -149,6 +149,12 @@ public:
QIcon icon( int size ) const;
QTimer *_pollTimer;
signals:
void syncStateChange();
void syncStarted();
void syncFinished(const SyncResult &result);
void scheduleToSync( const QString& );
public slots:
void slotSyncFinished(const SyncResult &);
@@ -162,30 +168,40 @@ public slots:
*/
virtual void slotTerminateSync() = 0;
/**
* Sets minimum amounts of milliseconds that will separate
* poll intervals
*/
void setPollInterval( int );
protected:
/**
* The minimum amounts of seconds to wait before
* doing a full sync to see if the remote changed
*/
int pollInterval() const;
void setSyncState(SyncResult::Status state);
/**
* Sets minimum amounts of milliseconds that will separate
* poll intervals
*/
void setPollInterval( int );
signals:
void syncStateChange();
void syncStarted();
void syncFinished(const SyncResult &result);
void scheduleToSync( const QString& );
protected:
FolderWatcher *_watcher;
int _errorCount;
SyncResult _syncResult;
protected slots:
void slotOnlineChanged(bool online);
void slotPollTimerTimeout();
/* called when the watcher detect a list of changed
paths */
void slotSyncStarted();
/**
* Triggered by a file system watcher on the local sync dir
*/
virtual void slotLocalPathChanged( const QString& );
private:
/**
@@ -212,22 +228,6 @@ private:
bool _enabled;
QString _backend;
protected slots:
void slotOnlineChanged(bool online);
void slotPollTimerTimeout();
/* called when the watcher detect a list of changed
paths */
void slotSyncStarted();
/**
* Triggered by a file system watcher on the local sync dir
*/
virtual void slotLocalPathChanged( const QString& );
};
}

View File

@@ -34,13 +34,15 @@
namespace Mirall {
FolderMan::FolderMan(QObject *parent) :
QObject(parent)
QObject(parent),
_syncEnabled( true )
{
// if QDir::mkpath would not be so stupid, I would not need to have this
// duplication of folderConfigPath() here
QDir storageDir(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
MirallConfigFile cfg;
QDir storageDir(cfg.configPath());
storageDir.mkpath(QLatin1String("folders"));
_folderConfigPath = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QLatin1String("/folders");
_folderConfigPath = cfg.configPath() + QLatin1String("folders");
_folderChangeSignalMapper = new QSignalMapper(this);
connect(_folderChangeSignalMapper, SIGNAL(mapped(const QString &)),
@@ -84,7 +86,15 @@ int FolderMan::setupKnownFolders()
{
qDebug() << "* Setup folders from " << _folderConfigPath;
_folderMap.clear(); // FIXME: check if delete of folder structure happens
// 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() );
}
QDir dir( _folderConfigPath );
dir.setFilter(QDir::Files);
@@ -100,6 +110,23 @@ int FolderMan::setupKnownFolders()
return _folderMap.size();
}
void FolderMan::wipeAllJournals()
{
terminateCurrentSync();
foreach( Folder *f, _folderMap.values() ) {
f->wipe();
}
}
void FolderMan::terminateCurrentSync()
{
if( !_currentSyncFolder.isEmpty() ) {
qDebug() << "Terminating syncing on folder " << _currentSyncFolder;
terminateSyncProcess( _currentSyncFolder );
}
}
#define SLASH_TAG QLatin1String("__SLASH__")
#define BSLASH_TAG QLatin1String("__BSLASH__")
#define QMARK_TAG QLatin1String("__QMARK__")
@@ -152,38 +179,6 @@ QString FolderMan::unescapeAlias( const QString& alias ) const
return a;
}
void FolderMan::setupFavLink(const QString &folder)
{
#ifdef Q_OS_WIN
// Windows Explorer: Place under "Favorites" (Links)
wchar_t path[MAX_PATH];
SHGetSpecialFolderPath(0, path, CSIDL_PROFILE, FALSE);
QString profile = QDir::fromNativeSeparators(QString::fromWCharArray(path));
QDir folderDir(QDir::fromNativeSeparators(folder));
QString linkName = profile+QLatin1String("/Links/") + folderDir.dirName() + QLatin1String(".lnk");
if (!QFile::link(folder, linkName))
qDebug() << Q_FUNC_INFO << "linking" << folder << "to" << linkName << "failed!";
#elif defined (Q_OS_MAC)
// Finder: Place under "Places"
QString folderUrl = QUrl::fromLocalFile(folder).toString();
CFStringRef folderCFStr = CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(folderUrl.unicode()),
folder.length());
CFURLRef urlRef = CFURLCreateWithString(NULL, folderCFStr, 0);
LSSharedFileListRef placesItems = LSSharedFileListCreate(0, kLSSharedFileListFavoriteItems, 0);
if (placesItems) {
//Insert an item to the list.
LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(placesItems,
kLSSharedFileListItemBeforeFirst, 0, 0,
urlRef, 0, 0);
if (item)
CFRelease(item);
}
CFRelease(placesItems);
CFRelease(folderCFStr);
CFRelease(urlRef);
#endif
}
// filename is the name of the file only, it does not include
// the configuration directory path
Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
@@ -279,25 +274,6 @@ Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
return folder;
}
void FolderMan::disableFoldersWithRestore()
{
_folderEnabledMap.clear();
foreach( Folder *f, _folderMap ) {
// store the enabled state, then make sure it is disabled
_folderEnabledMap.insert(f->alias(), f->syncEnabled());
f->setSyncEnabled(false);
}
}
void FolderMan::restoreEnabledFolders()
{
foreach( Folder *f, _folderMap ) {
if (_folderEnabledMap.contains( f->alias() )) {
f->setSyncEnabled( _folderEnabledMap.value( f->alias() ) );
}
}
}
void FolderMan::slotEnableFolder( const QString& alias, bool enable )
{
if( ! _folderMap.contains( alias ) ) {
@@ -318,6 +294,9 @@ void FolderMan::terminateSyncProcess( const QString& alias )
Folder *f = _folderMap[alias];
if( f ) {
f->slotTerminateSync();
if(_currentSyncFolder == alias )
_currentSyncFolder = QString::null;
}
}
@@ -342,6 +321,13 @@ SyncResult FolderMan::syncResult( const QString& alias )
return res;
}
void FolderMan::slotScheduleAllFolders()
{
foreach( Folder *f, _folderMap.values() ) {
slotScheduleSync( f->alias() );
}
}
/*
* if a folder wants to be synced, it calls this slot and is added
* to the queue. The slot to actually start a sync is called afterwards.
@@ -353,15 +339,22 @@ void FolderMan::slotScheduleSync( const QString& alias )
qDebug() << "Schedule folder " << alias << " to sync!";
if( _currentSyncFolder == alias ) {
// the current folder is currently syncing.
return;
}
if( _scheduleQueue.contains( alias ) ) {
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
if( ! _scheduleQueue.contains(alias )) {
_scheduleQueue.append(alias);
} else {
_scheduleQueue.append( alias );
slotScheduleFolderSync();
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
}
slotScheduleFolderSync();
}
void FolderMan::setSyncEnabled( bool enabled )
{
_syncEnabled = enabled;
}
/*
@@ -376,6 +369,11 @@ void FolderMan::slotScheduleFolderSync()
return;
}
if( ! _syncEnabled ) {
qDebug() << "FolderMan: Syncing is disabled, no scheduling.";
return;
}
qDebug() << "XX slotScheduleFolderSync: folderQueue size: " << _scheduleQueue.count();
if( ! _scheduleQueue.isEmpty() ) {
const QString alias = _scheduleQueue.takeFirst();
@@ -427,8 +425,6 @@ void FolderMan::addFolderDefinition( const QString& backend, const QString& alia
settings.setValue(QString::fromLatin1("%1/connection").arg(escapedAlias), Theme::instance()->appName());
settings.setValue(QString::fromLatin1("%1/onlyThisLAN").arg(escapedAlias), onlyThisLAN );
settings.sync();
setupFavLink(sourceFolder);
}
void FolderMan::removeAllFolderDefinitions()

View File

@@ -37,8 +37,6 @@ public:
~FolderMan();
int setupFolders();
void disableFoldersWithRestore();
void restoreEnabledFolders();
Mirall::Folder::Map map();
@@ -73,6 +71,11 @@ public:
*/
void removeAllFolderDefinitions();
/**
* Removes csync journals from all folders.
*/
void wipeAllJournals();
signals:
/**
* signal to indicate a folder named by alias has changed its sync state.
@@ -91,6 +94,12 @@ public slots:
void terminateSyncProcess( const QString& );
// if enabled is set to false, no new folders will start to sync.
// the current one will finish.
void setSyncEnabled( bool );
void slotScheduleAllFolders();
private slots:
// slot to add a folder to the syncing queue
void slotScheduleSync( const QString & );
@@ -102,7 +111,7 @@ private:
// finds all folder configuration files
// and create the folders
int setupKnownFolders();
void setupFavLink(const QString& folder);
void terminateCurrentSync();
// Escaping of the alias which is used in QSettings AND the file
// system, thus need to be escaped.
@@ -113,11 +122,11 @@ private:
FolderWatcher *_configFolderWatcher;
Folder::Map _folderMap;
QHash<QString, bool> _folderEnabledMap;
QString _folderConfigPath;
QSignalMapper *_folderChangeSignalMapper;
QString _currentSyncFolder;
QStringList _scheduleQueue;
bool _syncEnabled;
};
}

View File

@@ -47,8 +47,7 @@ FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
_eventsEnabled(true),
_eventInterval(DEFAULT_EVENT_INTERVAL_MSEC),
_root(root),
_processTimer(new QTimer(this)),
_initialSyncDone(false)
_processTimer(new QTimer(this))
{
_d = new FolderWatcherPrivate(this);
@@ -147,13 +146,12 @@ void FolderWatcher::slotProcessTimerTimeout()
{
qDebug() << "* Processing of event queue for" << root();
if (!_pendingPathes.empty() || !_initialSyncDone) {
if (!_pendingPathes.empty() ) {
QStringList notifyPaths = _pendingPathes.keys();
_pendingPathes.clear();
//qDebug() << lastEventTime << eventTime;
qDebug() << " * Notify" << notifyPaths.size() << "change items for" << root();
emit folderChanged(notifyPaths);
_initialSyncDone = true;
}
}
@@ -172,7 +170,7 @@ void FolderWatcher::setProcessTimer()
void FolderWatcher::changeDetected(const QString& f)
{
if( ! eventsEnabled() ) {
qDebug() << "FolderWatcher::changeDetected when eventsEnabled() -> ignore";
// qDebug() << "FolderWatcher::changeDetected when eventsEnabled() -> ignore";
return;
}

View File

@@ -134,9 +134,6 @@ private:
// QStringList _pendingPaths;
QTimer *_processTimer;
QStringList _ignores;
// for the initial synchronization, without
// any file changed
bool _initialSyncDone;
friend class FolderWatcherPrivate;
};

View File

@@ -57,7 +57,7 @@ void WatcherThread::run()
_handle = 0;
return;
}
qDebug() << Q_FUNC_INFO << "Change detected in" << _path << "from" << QThread::currentThread ();
// qDebug() << Q_FUNC_INFO << "Change detected in" << _path << "from" << QThread::currentThread ();
emit changed(_path);
break;
default:

View File

@@ -38,7 +38,7 @@ FolderWizardSourcePage::FolderWizardSourcePage()
registerField(QLatin1String("sourceFolder*"), _ui.localFolderLineEdit);
_ui.localFolderLineEdit->setText( QString::fromLatin1( "%1/%2").arg( QDir::homePath() ).arg(Theme::instance()->appName() ) );
registerField(QLatin1String("alias*"), _ui.aliasLineEdit);
_ui.aliasLineEdit->setText( Theme::instance()->appName() );
_ui.aliasLineEdit->setText( Theme::instance()->appNameGUI() );
_ui.warnLabel->hide();
#if QT_VERSION >= 0x040700
@@ -82,6 +82,13 @@ bool FolderWizardSourcePage::isComplete() const
while( isOk && i != map->constEnd() ) {
Folder *f = static_cast<Folder*>(i.value());
QString folderDir = QDir( f->path() ).canonicalPath();
if( folderDir.isEmpty() )
{
isOk = true;
qDebug() << "Absolute path for folder: " << f->path() << " doesn't exist. Skipping.";
i++;
continue;
}
if( ! folderDir.endsWith(QLatin1Char('/')) ) folderDir.append(QLatin1Char('/'));
qDebug() << "Checking local path: " << folderDir << " <-> " << userInput;
@@ -209,7 +216,7 @@ void FolderWizardTargetPage::slotDirCheckReply(const QString &url, QNetworkReply
showWarn();
} else {
showWarn( tr("The folder is not available on your %1.<br/>Click to create it." )
.arg( Theme::instance()->appName() ), true );
.arg( Theme::instance()->appNameGUI() ), true );
}
emit completeChanged();
@@ -234,10 +241,10 @@ void FolderWizardTargetPage::slotCreateRemoteFolderFinished( QNetworkReply::Netw
// the webDAV server seems to return a 202 even if mkdir was successful.
if( error == QNetworkReply::NoError ||
error == QNetworkReply::ContentOperationNotPermittedError) {
showWarn( tr("Folder was successfully created on %1.").arg( Theme::instance()->appName() ), false );
showWarn( tr("Folder was successfully created on %1.").arg( Theme::instance()->appNameGUI() ), false );
slotTimerFires();
} else {
showWarn( tr("Failed to create the folder on %1.<br/>Please check manually.").arg( Theme::instance()->appName() ), false );
showWarn( tr("Failed to create the folder on %1.<br/>Please check manually.").arg( Theme::instance()->appNameGUI() ), false );
}
}
@@ -313,7 +320,7 @@ void FolderWizardTargetPage::slotOwnCloudFound( const QString& url, const QStrin
if( infoStr.isEmpty() ) {
} else {
_ui.OCLabel->setText( tr("to your <a href=\"%1\">%2</a> (version %3)").arg(url)
.arg(Theme::instance()->appName()).arg(infoStr));
.arg(Theme::instance()->appNameGUI()).arg(infoStr));
_ui.OCFolderLineEdit->setEnabled( true );
_ui.OCRadioBtn->setEnabled( true );
qDebug() << "ownCloud found on " << url << " with version: " << infoStr;
@@ -323,9 +330,9 @@ void FolderWizardTargetPage::slotOwnCloudFound( const QString& url, const QStrin
void FolderWizardTargetPage::slotNoOwnCloudFound( QNetworkReply* error )
{
qDebug() << "No ownCloud configured: " << error->error();
_ui.OCLabel->setText( tr("no configured %1 found!").arg(Theme::instance()->appName()) );
_ui.OCLabel->setText( tr("no configured %1 found!").arg(Theme::instance()->appNameGUI()) );
showWarn( tr("%1 could not be reached:<br/><tt>%2</tt>")
.arg(Theme::instance()->appName()).arg(error->errorString()));
.arg(Theme::instance()->appNameGUI()).arg(error->errorString()));
_ui.OCRadioBtn->setEnabled( false );
_ui.OCFolderLineEdit->setEnabled( false );
}
@@ -455,20 +462,29 @@ bool FolderWizardOwncloudPage::isComplete() const
FolderWizard::FolderWizard( QWidget *parent )
: QWizard(parent),
_folderWizardSourcePage(0)
_folderWizardSourcePage(0),
_folderWizardTargetPage(0)
{
_folderWizardSourcePage = new FolderWizardSourcePage();
setPage(Page_Source, _folderWizardSourcePage );
if (!Theme::instance()->singleSyncFolder())
setPage(Page_Target, new FolderWizardTargetPage());
// setPage(Page_Network, new FolderWizardNetworkPage());
// setPage(Page_Owncloud, new FolderWizardOwncloudPage());
setWindowTitle( tr( "%1 Folder Wizard" ).arg( Theme::instance()->appName() ) );
if (!Theme::instance()->singleSyncFolder()) {
_folderWizardTargetPage = new FolderWizardTargetPage();
setPage(Page_Target, _folderWizardTargetPage );
}
setWindowTitle( tr( "%1 Folder Wizard" ).arg( Theme::instance()->appNameGUI() ) );
#ifdef Q_WS_MAC
setWizardStyle( QWizard::ModernStyle );
#endif
}
FolderWizard::~FolderWizard()
{
delete _folderWizardSourcePage;
if( _folderWizardTargetPage )
delete _folderWizardTargetPage;
}
void FolderWizard::setFolderMap( Folder::Map *fm)
{
if( _folderWizardSourcePage ) {

View File

@@ -149,11 +149,13 @@ public:
};
FolderWizard(QWidget *parent = 0);
~FolderWizard();
void setFolderMap( Folder::Map* );
private:
FolderWizardSourcePage *_folderWizardSourcePage;
FolderWizardTargetPage *_folderWizardTargetPage;
};

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>520</width>
<height>360</height>
<height>367</height>
</rect>
</property>
<property name="windowTitle">
@@ -97,7 +97,7 @@
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Folder on ownCloud:</string>
<string>Remote folder:</string>
</property>
</widget>
</item>
@@ -130,7 +130,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../mirall.qrc">:/mirall/resources/folder-grey-32.png</pixmap>
<pixmap>:/mirall/resources/folder-grey-32.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "mirall/gitfolder.h"
#include <QMutexLocker>
#include <QProcess>
namespace Mirall {
GitFolder::GitFolder(const QString &alias,
const QString &path,
const QString &secondPath,
QObject *parent)
: Folder(alias, path, secondPath, parent)
{
_syncProcess = new QProcess();
}
GitFolder::~GitFolder()
{
}
void GitFolder::startSync()
{
QMutexLocker locker(&_syncMutex);
emit syncStarted();
emit syncFinished(SyncResult(SyncResult::Success));
}
} // ns

View File

@@ -1,46 +0,0 @@
/*
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef MIRALL_GITFOLDER_H
#define MIRALL_GITFOLDER_H
#include <QMutex>
#include "mirall/folder.h"
class QProcess;
namespace Mirall {
class GitFolder : public Folder
{
Q_OBJECT
public:
/**
* path : Local folder to be keep in sync
* remote: git repo url to sync from/to
*/
GitFolder(const QString &alias,
const QString &path,
const QString &secondPath, QObject *parent = 0L);
virtual ~GitFolder();
virtual void startSync();
private:
QMutex _syncMutex;
QProcess *_syncProcess;
};
}
#endif

View File

@@ -39,8 +39,10 @@ INotify::INotify(QObject *parent, int mask)
_mask(mask)
{
_fd = inotify_init();
if (_fd == -1)
qDebug() << Q_FUNC_INFO << "notify_init() failed: " << strerror(errno);
_notifier = new QSocketNotifier(_fd, QSocketNotifier::Read);
QObject::connect(_notifier, SIGNAL(activated(int)), SLOT(slotActivated(int)));
connect(_notifier, SIGNAL(activated(int)), SLOT(slotActivated(int)));
_buffer_size = DEFAULT_READ_BUFFERSIZE;
_buffer = (char *) malloc(_buffer_size);
}
@@ -112,6 +114,7 @@ INotify::~INotify()
close(_fd);
free(_buffer);
delete _notifier;
}
void INotify::addPath(const QString &path)
@@ -121,7 +124,7 @@ void INotify::addPath(const QString &path)
if( wd > -1 )
_wds[path] = wd;
else
qDebug() << "WRN: Could not watch " << path;
qDebug() << "WRN: Could not watch " << path << ':' << strerror(errno);
}
void INotify::removePath(const QString &path)

View File

@@ -15,6 +15,7 @@
#include "config.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/owncloudinfo.h"
#include "mirall/owncloudtheme.h"
#include "mirall/miralltheme.h"
#include "mirall/credentialstore.h"
@@ -29,6 +30,7 @@
namespace Mirall {
QString MirallConfigFile::_oCVersion;
QString MirallConfigFile::_confDir = QString::null;
bool MirallConfigFile::_askedUser = false;
MirallConfigFile::MirallConfigFile( const QString& appendix )
@@ -36,9 +38,23 @@ MirallConfigFile::MirallConfigFile( const QString& appendix )
{
}
void MirallConfigFile::setConfDir(const QString &value)
{
if( value.isEmpty() ) return;
QFileInfo fi(value);
if( fi.exists() && fi.isDir() ) {
qDebug() << "** Using custom dir " << value;
_confDir=value;
}
}
QString MirallConfigFile::configPath() const
{
QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
QString dir = _confDir;
if( _confDir.isEmpty() )
_confDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
if( !dir.endsWith(QLatin1Char('/')) ) dir.append(QLatin1Char('/'));
return dir;
}
@@ -83,7 +99,7 @@ QString MirallConfigFile::excludeFile() const
QString MirallConfigFile::configFile() const
{
if( qApp->applicationName().isEmpty() ) {
qApp->setApplicationName( Theme::instance()->appName() );
qApp->setApplicationName( Theme::instance()->appNameGUI() );
}
QString dir = configPath() + Theme::instance()->configFileName();
if( !_customHandle.isEmpty() ) {
@@ -125,7 +141,6 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
{
const QString file = configFile();
qDebug() << "*** writing mirall config to " << file << " Skippwd: " << skipPwd;
QString pwd( passwd );
QSettings settings( file, QSettings::IniFormat);
settings.setIniCodec( "UTF-8" );
@@ -141,9 +156,7 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
settings.beginGroup( connection );
settings.setValue( QLatin1String("url"), cloudsUrl );
settings.setValue( QLatin1String("user"), user );
if( skipPwd ) {
pwd.clear();
}
#ifdef WITH_QTKEYCHAIN
// Password is stored to QtKeyChain now by default in CredentialStore
@@ -154,13 +167,18 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
if( !skipPwd )
writePassword( passwd );
#endif
if( !skipPwd )
writePassword( passwd );
else
clearPasswordFromConfig(); // wipe the password.
settings.setValue( QLatin1String("nostoredpassword"), QVariant(skipPwd) );
settings.sync();
// check the perms, only read-write for the owner.
QFile::setPermissions( file, QFile::ReadOwner|QFile::WriteOwner );
// Store credentials temporar until the config is finalized.
CredentialStore::instance()->setCredentials( cloudsUrl, user, passwd );
ownCloudInfo::instance()->setCredentials( user, passwd, _customHandle );
}
@@ -197,6 +215,8 @@ bool MirallConfigFile::writePassword( const QString& passwd, const QString& conn
QByteArray pwdba = pwd.toUtf8();
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
settings.sync();
return true;
}
// set the url, called from redirect handling.
@@ -264,13 +284,6 @@ QString MirallConfigFile::ownCloudUrl( const QString& connection, bool webdav )
settings.setIniCodec( "UTF-8" );
settings.beginGroup( con );
// For the WebDAV connect it is required to know which version the server is running
// because the url changed :-/
if( webdav && _oCVersion.isEmpty() ) {
qDebug() << "######## Config does not yet know the ownCloud server version #########";
qDebug() << "###################### THIS SHOULD NOT HAPPEN! ########################";
}
QString url = settings.value( QLatin1String("url") ).toString();
if( ! url.isEmpty() ) {
if( ! url.endsWith(QLatin1Char('/'))) url.append(QLatin1String("/"));
@@ -314,6 +327,22 @@ int MirallConfigFile::remotePollInterval( const QString& connection ) const
return remoteInterval;
}
void MirallConfigFile::setRemotePollInterval(int interval, const QString &connection )
{
QString con( connection );
if( connection.isEmpty() ) con = defaultConnection();
if( interval < 5000 ) {
qDebug() << "Remote Poll interval of " << interval << " is below fife seconds.";
return;
}
QSettings settings( configFile(), QSettings::IniFormat );
settings.setIniCodec( "UTF-8" );
settings.beginGroup( con );
settings.setValue("remotePollInterval", interval );
settings.sync();
}
bool MirallConfigFile::passwordStorageAllowed( const QString& connection )
{
QString con( connection );
@@ -384,6 +413,20 @@ bool MirallConfigFile::ownCloudSkipUpdateCheck( const QString& connection ) cons
return skipIt;
}
void MirallConfigFile::setOwnCloudSkipUpdateCheck( bool skip, const QString& connection )
{
QString con( connection );
if( connection.isEmpty() ) con = defaultConnection();
QSettings settings( configFile(), QSettings::IniFormat );
settings.setIniCodec( "UTF-8" );
settings.beginGroup( con );
settings.setValue( QLatin1String("skipUpdateCheck"), QVariant(skip) );
settings.sync();
}
int MirallConfigFile::maxLogLines() const
{
QSettings settings( configFile(), QSettings::IniFormat );
@@ -393,6 +436,16 @@ int MirallConfigFile::maxLogLines() const
return logLines;
}
void MirallConfigFile::setMaxLogLines( int lines )
{
QSettings settings( configFile(), QSettings::IniFormat );
settings.setIniCodec( "UTF-8" );
settings.beginGroup(QLatin1String("Logging"));
settings.setValue(QLatin1String("maxLogLines"), lines);
settings.sync();
}
// remove a custom config file.
void MirallConfigFile::cleanupCustomConfig()
{
@@ -438,7 +491,17 @@ void MirallConfigFile::acceptCustomConfig()
QFile::remove( targetBak );
// inform the credential store about the password change.
CredentialStore::instance()->saveCredentials( );
QString url = ownCloudUrl();
QString user = ownCloudUser();
QString pwd = ownCloudPasswd();
bool allow = passwordStorageAllowed();
if( pwd.isEmpty() ) {
qDebug() << "Password is empty, skipping to write cred store.";
} else {
CredentialStore::instance()->setCredentials(url, user, pwd, allow);
CredentialStore::instance()->saveCredentials();
}
}
void MirallConfigFile::setProxyType(int proxyType,

View File

@@ -55,6 +55,7 @@ public:
void removeConnection( const QString& connection = QString() );
QString ownCloudUser( const QString& connection = QString() ) const;
QString ownCloudUrl( const QString& connection = QString(), bool webdav = false ) const;
void setOwnCloudUrl(const QString &connection, const QString& );
@@ -63,18 +64,22 @@ public:
QByteArray caCerts();
void setCaCerts( const QByteArray& );
bool passwordStorageAllowed(const QString &);
bool passwordStorageAllowed(const QString &connection = QString::null );
QString ownCloudVersion() const;
void setOwnCloudVersion( const QString& );
// max count of lines in the log window
int maxLogLines() const;
void setMaxLogLines(int);
bool ownCloudSkipUpdateCheck( const QString& connection = QString() ) const;
void setOwnCloudSkipUpdateCheck( bool, const QString& );
/* Server poll interval in milliseconds */
int remotePollInterval( const QString& connection = QString() ) const;
/* Set poll interval. Value in microseconds has to be larger than 5000 */
void setRemotePollInterval(int interval, const QString& connection = QString() );
// Custom Config: accept the custom config to become the main one.
void acceptCustomConfig();
@@ -93,11 +98,12 @@ public:
int proxyPort() const;
QString proxyUser() const;
QString proxyPassword() const;
static void setConfDir(const QString &value);
protected:
// these classes can only be access from CredentialStore as a friend class.
QString ownCloudPasswd( const QString& connection = QString() ) const;
QString ownCloudUser( const QString& connection = QString() ) const;
void clearPasswordFromConfig( const QString& connect = QString() );
bool writePassword( const QString& passwd, const QString& connection = QString() );
@@ -108,6 +114,7 @@ private:
private:
static bool _askedUser;
static QString _oCVersion;
static QString _confDir;
QString _customHandle;
};

View File

@@ -71,6 +71,7 @@ QIcon mirallTheme::syncStateIcon( SyncResult::Status status, bool sysTray ) cons
statusIcon = QLatin1String("dialog-close");
break;
case SyncResult::NotYetStarted:
case SyncResult::SyncPrepare:
statusIcon = QLatin1String("task-ongoing");
break;
case SyncResult::SyncRunning:

View File

@@ -61,9 +61,9 @@ ownCloudFolder::ownCloudFolder(const QString &alias,
, _csyncUnavail(false)
, _wipeDb(false)
{
_notifier = new DownloadNotifier(QDir::fromNativeSeparators(path),
replaceScheme(secondPath), this);
connect(_notifier, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
ServerActionNotifier *notifier = new ServerActionNotifier(this);
connect(notifier, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
connect(this, SIGNAL(syncFinished(SyncResult)), notifier, SLOT(slotSyncFinished(SyncResult)));
qDebug() << "****** ownCloud folder using watcher *******";
// The folder interval is set in the folder parent class.
}
@@ -111,6 +111,7 @@ void ownCloudFolder::startSync(const QStringList &pathList)
qCritical() << "* ERROR csync is still running and new sync requested.";
return;
}
delete _csync;
delete _thread;
_errors.clear();
@@ -123,7 +124,8 @@ void ownCloudFolder::startSync(const QStringList &pathList)
_syncResult.clearErrors();
// we now have watchers for everything, so every sync is remote.
_syncResult.setLocalRunOnly( false );
Folder::startSync( pathList );
_syncResult.setStatus( SyncResult::SyncPrepare );
emit syncStateChange();
QString url = replaceScheme(_secondPath);
@@ -148,18 +150,16 @@ 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);
connect(_csync, SIGNAL(fileReceived(QString)),
_notifier, SLOT(slotFileReceived(QString)), Qt::QueuedConnection);
_thread->start();
QMetaObject::invokeMethod(_csync, "startSync", Qt::QueuedConnection);
emit syncStarted();
}
void ownCloudFolder::slotCSyncStarted()
{
qDebug() << " * csync thread started";
emit syncStarted();
_syncResult.setStatus(SyncResult::SyncRunning);
emit syncStateChange();
}
void ownCloudFolder::slotCSyncError(const QString& err)
@@ -210,10 +210,7 @@ void ownCloudFolder::slotTerminateSync()
if( _thread ) {
_thread->terminate();
_thread->wait();
// TODO: crashes on win, leak for now, fix properly after 1.1.0
#ifndef Q_OS_WIN
delete _csync;
#endif
_csync->deleteLater();
delete _thread;
_csync = 0;
_thread = 0;
@@ -280,39 +277,72 @@ void ownCloudFolder::wipe()
_wipeDb = false;
}
DownloadNotifier::DownloadNotifier(const QString &localPrefix, const QString &remotePrefix, QObject *parent)
: QObject(parent), _timer(new QTimer(this)), _items(0)
ServerActionNotifier::ServerActionNotifier(QObject *parent)
: QObject(parent)
{
_timer->setSingleShot(true);
connect(_timer, SIGNAL(timeout()), SLOT(sendResults()));
_localPrefix = localPrefix;
_remotePrefix = remotePrefix;
}
void DownloadNotifier::slotFileReceived(const QString & url)
void ServerActionNotifier::slotSyncFinished(const SyncResult &result)
{
if (_url.isEmpty())
_url = url;
_items++;
_timer->stop();
_timer->start(1000);
}
SyncFileItemVector items = result.syncFileItemVector();
if (items.count() == 0)
return;
void DownloadNotifier::sendResults()
{
QString file = _url;
file.replace(_remotePrefix, _localPrefix);
file = QDir::toNativeSeparators(QDir::cleanPath(file));
if (_items == 1)
emit guiLog(tr("New file available"), tr("'%1' has been synced to this machine.").arg(file));
else
emit guiLog(tr("New files available"), tr("'%1' and %n other file(s) have been synced to this machine.",
"", _items-1).arg(file).arg(_items));
int newItems = 0;
int removedItems = 0;
int updatedItems = 0;
SyncFileItem firstItemNew;
SyncFileItem firstItemDeleted;
SyncFileItem firstItemUpdated;
foreach (const SyncFileItem &item, items) {
if (item._dir == SyncFileItem::Down) {
switch (item._instruction) {
case CSYNC_INSTRUCTION_NEW:
newItems++;
if (firstItemNew.isEmpty())
firstItemNew = item;
break;
case CSYNC_INSTRUCTION_REMOVE:
removedItems++;
if (firstItemDeleted.isEmpty())
firstItemDeleted = item;
break;
case CSYNC_INSTRUCTION_UPDATED:
updatedItems++;
if (firstItemUpdated.isEmpty())
firstItemUpdated = item;
break;
default:
// nothing.
break;
}
}
}
// reset
_items = 0;
_url = QString::null;
if (newItems > 0) {
QString file = QDir::toNativeSeparators(firstItemNew._file);
if (newItems == 1)
emit guiLog(tr("New file available"), tr("'%1' has been synced to this machine.").arg(file));
else
emit guiLog(tr("New files available"), tr("'%1' and %n other file(s) have been synced to this machine.",
"", newItems-1).arg(file));
}
if (removedItems > 0) {
QString file = QDir::toNativeSeparators(firstItemDeleted._file);
if (removedItems == 1)
emit guiLog(tr("File removed"), tr("'%1' has been removed.").arg(file));
else
emit guiLog(tr("New files available"), tr("'%1' and %n other file(s) have been removed.",
"", removedItems-1).arg(file));
}
if (updatedItems > 0) {
QString file = QDir::toNativeSeparators(firstItemUpdated._file);
if (updatedItems == 1)
emit guiLog(tr("File removed"), tr("'%1' has been updated.").arg(file));
else
emit guiLog(tr("New files available"), tr("'%1' and %n other file(s) have been updated.",
"", updatedItems-1).arg(file));
}
}
} // ns

View File

@@ -42,23 +42,17 @@ enum SyncFileStatus_s {
};
typedef SyncFileStatus_s SyncFileStatus;
class DownloadNotifier : public QObject
class ServerActionNotifier : public QObject
{
Q_OBJECT
public:
DownloadNotifier(const QString &localPrefix, const QString &remotePrefix, QObject *parent = 0);
ServerActionNotifier(QObject *parent = 0);
public slots:
void slotFileReceived(const QString&);
void slotSyncFinished(const SyncResult &result);
signals:
void guiLog(const QString&, const QString&);
private slots:
void sendResults();
private:
QTimer *_timer;
QString _url;
QString _localPrefix;
QString _remotePrefix;
int _items;
};
class ownCloudFolder : public Folder
@@ -94,7 +88,6 @@ private slots:
void slotCSyncFinished();
private:
DownloadNotifier *_notifier;
QString _secondPath;
QThread *_thread;
CSyncThread *_csync;

View File

@@ -16,7 +16,6 @@
#include "mirall/mirallconfigfile.h"
#include "mirall/version.h"
#include "mirall/theme.h"
#include "mirall/credentialstore.h"
#include <QtCore>
#include <QtGui>
@@ -26,6 +25,8 @@
#include <QHttp>
#endif
#define DEFAULT_CONNECTION QLatin1String("default");
namespace Mirall
{
@@ -48,16 +49,23 @@ ownCloudInfo* ownCloudInfo::instance()
}
ownCloudInfo::ownCloudInfo() :
QObject(0)
QObject(0),
_manager(0)
{
_connection = Theme::instance()->appName();
_manager = new QNetworkAccessManager( this );
setNetworkAccessManager( new QNetworkAccessManager( this ) );
}
void ownCloudInfo::setNetworkAccessManager( QNetworkAccessManager* qnam )
{
delete _manager;
qnam->setParent( this );
_manager = qnam;
MirallConfigFile cfg( _configHandle );
QSettings settings( cfg.configFile(), QSettings::IniFormat);
QByteArray certs = settings.value(QLatin1String("CaCertificates")).toByteArray();
QSslSocket::addDefaultCaCertificates(QSslCertificate::fromData(certs));
QSslSocket::addDefaultCaCertificates(QSslCertificate::fromData(cfg.caCerts()));
connect( _manager, SIGNAL( sslErrors(QNetworkReply*, QList<QSslError>)),
this, SIGNAL(sslFailed(QNetworkReply*, QList<QSslError>)) );
@@ -66,6 +74,7 @@ ownCloudInfo::ownCloudInfo() :
this, SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));
_certsUntrusted = false;
}
ownCloudInfo::~ownCloudInfo()
@@ -85,18 +94,18 @@ bool ownCloudInfo::isConfigured()
return cfgFile.connectionExists( _connection );
}
void ownCloudInfo::checkInstallation()
QNetworkReply *ownCloudInfo::checkInstallation()
{
/* No authentication required for this. */
getRequest( QLatin1String("status.php"), false );
return getRequest( QLatin1String("status.php"), false );
}
void ownCloudInfo::getWebDAVPath( const QString& path )
QNetworkReply* ownCloudInfo::getWebDAVPath( const QString& path )
{
getRequest( path, true );
return getRequest( path, true );
}
void ownCloudInfo::getRequest( const QString& path, bool webdav )
QNetworkReply* ownCloudInfo::getRequest( const QString& path, bool webdav )
{
qDebug() << "Get Request to " << path;
@@ -117,10 +126,11 @@ void ownCloudInfo::getRequest( const QString& path, bool webdav )
connect( reply, SIGNAL( error(QNetworkReply::NetworkError )),
this, SLOT(slotError( QNetworkReply::NetworkError )));
return reply;
}
#if QT46_IMPL
void ownCloudInfo::mkdirRequest( const QString& dir )
QNetworkReply* ownCloudInfo::mkdirRequest( const QString& dir )
{
qDebug() << "OCInfo Making dir " << dir;
@@ -131,8 +141,6 @@ void ownCloudInfo::mkdirRequest( const QString& dir )
conMode = QHttp::ConnectionModeHttps;
QHttp* qhttp = new QHttp(QString(url.encodedHost()), conMode, 0, this);
qhttp->setUser( CredentialStore::instance()->user(_connection),
CredentialStore::instance()->password(_connection) );
connect(qhttp, SIGNAL(requestStarted(int)), this,SLOT(qhttpRequestStarted(int)));
connect(qhttp, SIGNAL(requestFinished(int, bool)), this,SLOT(qhttpRequestFinished(int,bool)));
@@ -147,7 +155,18 @@ void ownCloudInfo::mkdirRequest( const QString& dir )
header.setValue("Connection", "keep-alive");
header.setContentType("application/x-www-form-urlencoded"); //important
header.setContentLength(0);
header.setValue("Authorization", CredentialStore::instance()->basicAuthHeader());
QString con = _configHandle;
if( con.isEmpty() ) con = DEFAULT_CONNECTION;
if( _credentials.contains(con)) {
oCICredentials creds = _credentials.value(con);
QString concatenated = creds.user + QLatin1Char(':') + creds.passwd;
const QString b(QLatin1String("Basic "));
QByteArray data = b.toLocal8Bit() + concatenated.toLocal8Bit().toBase64();
header.setValue("Authorization", data);
qhttp->setUser( creds.user, creds.passwd );
}
int david = qhttp->request(header,0,0);
//////////////// connect(davinfo, SIGNAL(dataSendProgress(int,int)), this, SLOT(SendStatus(int, int)));
@@ -155,7 +174,7 @@ void ownCloudInfo::mkdirRequest( const QString& dir )
//connect(_http, SIGNAL(requestFinished(int, bool)), this,SLOT(qhttpRequestFinished(int,bool)));
///////////connect(davinfo, SIGNAL(responseHeaderReceived(constQHttpResponseHeader &)), this, SLOT(RegisterBackHeader(constQHttpResponseHeader &)));
return NULL;
}
void ownCloudInfo::qhttpResponseHeaderReceived(const QHttpResponseHeader& header)
@@ -184,7 +203,7 @@ void ownCloudInfo::qhttpRequestFinished(int id, bool success )
}
}
#else
void ownCloudInfo::mkdirRequest( const QString& dir )
QNetworkReply* ownCloudInfo::mkdirRequest( const QString& dir )
{
qDebug() << "OCInfo Making dir " << dir;
_authAttempts = 0;
@@ -205,6 +224,7 @@ void ownCloudInfo::mkdirRequest( const QString& dir )
connect( reply, SIGNAL(finished()), SLOT(slotMkdirFinished()) );
connect( reply, SIGNAL( error(QNetworkReply::NetworkError )),
this, SLOT(slotError(QNetworkReply::NetworkError )));
return reply;
}
void ownCloudInfo::slotMkdirFinished()
@@ -242,16 +262,25 @@ void ownCloudInfo::slotAuthentication( QNetworkReply *reply, QAuthenticator *aut
MirallConfigFile cfgFile( configHandle );
qDebug() << "Authenticating request for " << reply->url();
if( reply->url().toString().startsWith( cfgFile.ownCloudUrl( _connection, true )) ) {
auth->setUser( CredentialStore::instance()->user() ); //_connection ) );
auth->setPassword( CredentialStore::instance()->password() ); // _connection ));
QString con = configHandle;
if( con.isEmpty() ) con = DEFAULT_CONNECTION;
if( _credentials.contains(con)) {
oCICredentials creds = _credentials.value(con);
auth->setUser( creds.user );
auth->setPassword( creds.passwd );
} else {
qDebug() << "Unable to get Credentials, not set!";
reply->close();
}
} else {
qDebug() << "WRN: attempt to authenticate to different url - attempt " <<_authAttempts;
}
if( _authAttempts > 10 ) {
if( _authAttempts > 1) {
qDebug() << "Too many attempts to authenticate. Stop request.";
reply->close();
}
}
QString ownCloudInfo::configHandle(QNetworkReply *reply)
@@ -431,6 +460,24 @@ void ownCloudInfo::slotError( QNetworkReply::NetworkError err)
qDebug() << "ownCloudInfo Network Error: " << err;
}
void ownCloudInfo::setCredentials( const QString& user, const QString& passwd,
const QString& configHandle )
{
QString con( configHandle );
if( configHandle.isEmpty() )
con = DEFAULT_CONNECTION;
if( _credentials.contains(con) ) {
qDebug() << "Overwriting credentials for connection " << con;
}
oCICredentials creds;
creds.user = user;
creds.passwd = passwd;
creds.connection = con;
_credentials[con] = creds;
}
// ============================================================================
void ownCloudInfo::setupHeaders( QNetworkRequest & req, quint64 size )
{
@@ -441,7 +488,16 @@ void ownCloudInfo::setupHeaders( QNetworkRequest & req, quint64 size )
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("Authorization"), CredentialStore::instance()->basicAuthHeader() );
QString con = _configHandle;
if( con.isEmpty() ) con = DEFAULT_CONNECTION;
if( _credentials.contains(con)) {
oCICredentials creds = _credentials.value(con);
QString concatenated = creds.user + QLatin1Char(':') + creds.passwd;
const QString b(QLatin1String("Basic "));
QByteArray data = b.toLocal8Bit() + concatenated.toLocal8Bit().toBase64();
req.setRawHeader( QByteArray("Authorization"), data );
}
if (size) {
req.setHeader( QNetworkRequest::ContentLengthHeader, size);

View File

@@ -27,6 +27,12 @@
namespace Mirall
{
typedef struct {
QString user;
QString passwd;
QString connection;
} oCICredentials;
class ownCloudInfo : public QObject
{
Q_OBJECT
@@ -39,18 +45,18 @@ public:
/**
* call status.php
*/
void checkInstallation();
QNetworkReply* checkInstallation();
/**
* a general GET request to the ownCloud. If the second bool parameter is
* true, the WebDAV server is queried.
*/
void getRequest( const QString&, bool );
QNetworkReply* getRequest( const QString&, bool );
/**
* convenience: GET request to the WebDAV server.
*/
void getWebDAVPath( const QString& );
QNetworkReply* getWebDAVPath( const QString& );
/**
* There is a global flag here if the user once decided against trusting the
@@ -68,10 +74,18 @@ public:
*/
bool certsUntrusted();
/**
* Set a NetworkAccessManager to be used
*
* This method will take ownership of the NetworkAccessManager, so you can just
* set it initially and forget about its memory management.
*/
void setNetworkAccessManager( QNetworkAccessManager *qnam );
/**
* Create a collection via owncloud. Provide a relative path.
*/
void mkdirRequest( const QString& );
QNetworkReply* mkdirRequest( const QString& );
/**
* Use a custom ownCloud configuration file identified by handle
@@ -89,6 +103,13 @@ public:
*/
QList<QSslCertificate> certificateChain() const;
/**
* Store credentials for a given connection. Empty connection parameter
* means "default connection".
*/
void setCredentials( const QString&, const QString&,
const QString& configHandle = QString::null );
signals:
// result signal with url- and version string.
void ownCloudInfoFound( const QString&, const QString&, const QString&, const QString& );
@@ -138,6 +159,7 @@ private:
QList<QSslCertificate> _certificateChain;
bool _certsUntrusted;
int _authAttempts;
QMap<QString, oCICredentials> _credentials;
};
};

View File

@@ -117,7 +117,7 @@
<string>Do not allow the local storage of the password.</string>
</property>
<property name="text">
<string>&amp;Do not store password on local machine.</string>
<string>&amp;Do not store password on local machine</string>
</property>
</widget>
</item>

View File

@@ -17,6 +17,7 @@
#include "mirall/owncloudinfo.h"
#include "mirall/folderman.h"
#include "mirall/credentialstore.h"
#include "mirall/utility.h"
#include <QtCore>
#include <QProcess>
@@ -29,6 +30,8 @@ class Theme;
OwncloudSetupWizard::OwncloudSetupWizard( FolderMan *folderMan, Theme *theme, QObject *parent ) :
QObject( parent ),
_mkdirRequestReply(0),
_checkInstallationRequest(0),
_folderMan(folderMan)
{
_process = new QProcess( this );
@@ -68,7 +71,10 @@ OwncloudSetupWizard::OwncloudSetupWizard( FolderMan *folderMan, Theme *theme, QO
// in case of cancel, terminate the owncloud-admin script.
connect( _ocWizard, SIGNAL(rejected()), _process, SLOT(terminate()));
_ocWizard->setWindowTitle( tr("%1 Connection Wizard").arg( theme ? theme->appName() : QLatin1String("Mirall") ) );
connect( _ocWizard, SIGNAL(clearPendingRequests()),
this, SLOT(slotClearPendingRequests()));
_ocWizard->setWindowTitle( tr("%1 Connection Wizard").arg( theme ? theme->appNameGUI() : QLatin1String("Mirall") ) );
}
@@ -89,12 +95,17 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
qDebug() << "Rejected the new config, use the old!";
} else if( result == QDialog::Accepted ) {
qDebug() << "Config Changes were accepted!";
// 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();
}
// save the user credentials and afterwards clear the cred store.
cfg.acceptCustomConfig();
// wipe all folder definitions so far.
if( _folderMan ) _folderMan->removeAllFolderDefinitions();
// Now write the resulting folder definition if folder names are set.
if( !( _localFolder.isEmpty() || _remoteFolder.isEmpty() ) ) { // both variables are set.
if( _folderMan ) {
@@ -130,10 +141,23 @@ void OwncloudSetupWizard::slotConnectToOCUrl( const QString& url )
qDebug() << "Connect to url: " << url;
_ocWizard->setField(QLatin1String("OCUrl"), url );
_ocWizard->appendToResultWidget(tr("Trying to connect to %1 at %2...")
.arg( Theme::instance()->appName() ).arg(url) );
.arg( Theme::instance()->appNameGUI() ).arg(url) );
testOwnCloudConnect();
}
void OwncloudSetupWizard::slotClearPendingRequests()
{
qDebug() << "Pending request: " << _mkdirRequestReply;
if( _mkdirRequestReply && _mkdirRequestReply->isRunning() ) {
qDebug() << "ABORTing pending mkdir request.";
_mkdirRequestReply->abort();
}
if( _checkInstallationRequest && _checkInstallationRequest->isRunning() ) {
qDebug() << "ABORTing pending check installation request.";
_checkInstallationRequest->abort();
}
}
void OwncloudSetupWizard::testOwnCloudConnect()
{
// write a temporary config.
@@ -149,13 +173,22 @@ void OwncloudSetupWizard::testOwnCloudConnect()
_ocWizard->field(QLatin1String("secureConnect")).toBool(),
_ocWizard->field(QLatin1String("PwdNoLocalStore")).toBool() );
// 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() );
}
}
// now start ownCloudInfo to check the connection.
ownCloudInfo* info = ownCloudInfo::instance();
info->setCustomConfigHandle( _configHandle );
if( info->isConfigured() ) {
// reset the SSL Untrust flag to let the SSL dialog appear again.
info->resetSSLUntrust();
info->checkInstallation();
_checkInstallationRequest = info->checkInstallation();
} else {
qDebug() << " ownCloud seems not to be configured, can not start test connect.";
}
@@ -164,7 +197,7 @@ void OwncloudSetupWizard::testOwnCloudConnect()
void OwncloudSetupWizard::slotOwnCloudFound( const QString& url, const QString& infoString, const QString& version, const QString& )
{
_ocWizard->appendToResultWidget(tr("<font color=\"green\">Successfully connected to %1: %2 version %3 (%4)</font><br/><br/>")
.arg( url ).arg(Theme::instance()->appName()).arg(infoString).arg(version));
.arg( url ).arg(Theme::instance()->appNameGUI()).arg(infoString).arg(version));
// enable the finish button.
_ocWizard->button( QWizard::FinishButton )->setEnabled( true );
@@ -176,7 +209,7 @@ void OwncloudSetupWizard::slotOwnCloudFound( const QString& url, const QString&
void OwncloudSetupWizard::slotNoOwnCloudFound( QNetworkReply *err )
{
_ocWizard->appendToResultWidget(tr("<font color=\"red\">Failed to connect to %1!</font>")
.arg(Theme::instance()->appName()));
.arg(Theme::instance()->appNameGUI()));
_ocWizard->appendToResultWidget(tr("Error: <tt>%1</tt>").arg(err->errorString()) );
// remove the config file again
@@ -313,12 +346,12 @@ void OwncloudSetupWizard::slotProcessFinished( int res, QProcess::ExitStatus )
qDebug() << "exit code: " << res;
if( res ) {
_ocWizard->appendToResultWidget( tr("<font color=\"red\">Installation of %1 failed!</font>").arg(Theme::instance()->appName()));
_ocWizard->appendToResultWidget( tr("<font color=\"red\">Installation of %1 failed!</font>").arg(Theme::instance()->appNameGUI()));
_ocWizard->showOCUrlLabel( false );
emit ownCloudSetupFinished( false );
} else {
// Successful installation. Write the config.
_ocWizard->appendToResultWidget( tr("<font color=\"green\">Installation of %1 succeeded!</font>").arg(Theme::instance()->appName()));
_ocWizard->appendToResultWidget( tr("<font color=\"green\">Installation of %1 succeeded!</font>").arg(Theme::instance()->appNameGUI()));
_ocWizard->showOCUrlLabel( true );
testOwnCloudConnect();
@@ -339,6 +372,14 @@ void OwncloudSetupWizard::startWizard(bool intro)
_ocWizard->setOCUrl( url );
}
#ifdef OWNCLOUD_CLIENT
QString user = cfgFile.ownCloudUser();
if( !user.isEmpty() ) {
_ocWizard->setOCUser( user );
}
bool doStore = cfgFile.passwordStorageAllowed();
_ocWizard->setAllowPasswordStorage( doStore );
if (intro)
_ocWizard->setStartId(OwncloudWizard::Page_oCWelcome);
else
@@ -381,6 +422,7 @@ void OwncloudSetupWizard::setupLocalSyncFolder()
} else {
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 {
@@ -418,7 +460,7 @@ bool OwncloudSetupWizard::createRemoteFolder( const QString& folder )
qDebug() << "creating folder on ownCloud: " << folder;
ownCloudInfo::instance()->mkdirRequest( folder );
_mkdirRequestReply = ownCloudInfo::instance()->mkdirRequest( folder );
return true;
}
@@ -452,6 +494,9 @@ void OwncloudSetupWizard::slotCreateRemoteFolderFinished( QNetworkReply::Network
void OwncloudSetupWizard::finalizeSetup( bool success )
{
// enable/disable the finish button.
_ocWizard->enableFinishOnResultWidget(success);
if( success ) {
if( !(_localFolder.isEmpty() || _remoteFolder.isEmpty() )) {
_ocWizard->appendToResultWidget( tr("A sync connection from %1 to remote directory %2 was set up.")
@@ -459,14 +504,14 @@ void OwncloudSetupWizard::finalizeSetup( bool success )
}
_ocWizard->appendToResultWidget( QLatin1String(" "));
_ocWizard->appendToResultWidget( QLatin1String("<p><font color=\"green\"><b>")
+ tr("Succesfully connected to %1!")
.arg(Theme::instance()->appName())
+ tr("Successfully connected to %1!")
.arg(Theme::instance()->appNameGUI())
+ QLatin1String("</b></font></p>"));
_ocWizard->appendToResultWidget( tr("Press Finish to permanently accept this connection."));
} else {
_ocWizard->appendToResultWidget(QLatin1String("<p><font color=\"red\">")
+ tr("Connection to %1 could not be established. Please check again.")
.arg(Theme::instance()->appName())
.arg(Theme::instance()->appNameGUI())
+ QLatin1String("</font></p>"));
}
}

View File

@@ -19,6 +19,7 @@
#include <QWidget>
#include <QProcess>
#include <QNetworkReply>
#include <QPointer>
#include "mirall/owncloudwizard.h"
#include "mirall/theme.h"
@@ -87,6 +88,7 @@ private slots:
void slotNoOwnCloudFound( QNetworkReply* );
void slotCreateRemoteFolderFinished( QNetworkReply::NetworkError );
void slotAssistantFinished( int );
void slotClearPendingRequests();
private:
bool checkOwncloudAdmin( const QString& );
@@ -98,6 +100,8 @@ private:
void testOwnCloudConnect();
OwncloudWizard *_ocWizard;
QPointer<QNetworkReply> _mkdirRequestReply;
QPointer<QNetworkReply> _checkInstallationRequest;
FolderMan *_folderMan;
QProcess *_process;

View File

@@ -124,6 +124,7 @@ QIcon ownCloudTheme::syncStateIcon( SyncResult::Status status, bool sysTray ) co
case SyncResult::SyncRunning:
statusIcon = QLatin1String("state-sync");
break;
case SyncResult::SyncPrepare:
case SyncResult::Success:
statusIcon = QLatin1String("state-ok");
break;

View File

@@ -57,7 +57,7 @@ void setupCustomMedia( QVariant variant, QLabel *label )
OwncloudWelcomePage::OwncloudWelcomePage()
{
setTitle(tr("Welcome to %1").arg(Theme::instance()->appName()));
setTitle(tr("Welcome to %1").arg(Theme::instance()->appNameGUI()));
QVBoxLayout *lay = new QVBoxLayout(this);
QLabel *content = new QLabel;
@@ -70,11 +70,11 @@ OwncloudWelcomePage::OwncloudWelcomePage()
content->setText(tr("<p>In order to connect to your %1 server, you need to provide the server address "
"as well as your credentials.</p><p>This wizard will guide you through the process.<p>"
"<p>If you have not received this information, please contact your %1 provider.</p>")
.arg(theme->appName()));
.arg(theme->appNameGUI()));
} else {
content->setText(tr("<p>In order to connect to your %1 server, you need to provide "
"your credentials.</p><p>This wizard will guide you through "
"the setup process.</p>").arg(theme->appName()));
"the setup process.</p>").arg(theme->appNameGUI()));
}
}
@@ -83,7 +83,7 @@ OwncloudSetupPage::OwncloudSetupPage()
{
_ui.setupUi(this);
setTitle(tr("Create Connection to %1").arg(Theme::instance()->appName()));
setTitle(tr("Create Connection to %1").arg(Theme::instance()->appNameGUI()));
connect(_ui.leUrl, SIGNAL(textChanged(QString)), SLOT(handleNewOcUrl(QString)));
@@ -110,6 +110,18 @@ OwncloudSetupPage::~OwncloudSetupPage()
{
}
void OwncloudSetupPage::setOCUser( const QString & user )
{
if( _ui.leUsername->text().isEmpty() ) {
_ui.leUsername->setText(user);
}
}
void OwncloudSetupPage::setAllowPasswordStorage( bool allow )
{
_ui.cbNoPasswordStore->setChecked( ! allow );
}
void OwncloudSetupPage::setOCUrl( const QString& newUrl )
{
QString url( newUrl );
@@ -423,12 +435,19 @@ OwncloudWizardResultPage::~OwncloudWizardResultPage()
void OwncloudWizardResultPage::initializePage()
{
_complete = false;
// _ui.lineEditOCAlias->setText( "Owncloud" );
}
void OwncloudWizardResultPage::setComplete(bool complete)
{
_complete = complete;
emit completeChanged();
}
bool OwncloudWizardResultPage::isComplete() const
{
return true;
return _complete;
}
void OwncloudWizardResultPage::appendResultText( const QString& msg, OwncloudWizard::LogType type )
@@ -449,7 +468,7 @@ void OwncloudWizardResultPage::appendResultText( const QString& msg, OwncloudWiz
void OwncloudWizardResultPage::showOCUrlLabel( const QString& url, bool show )
{
_ui.ocLinkLabel->setText( tr("Congratulations! Your <a href=\"%1\" title=\"%1\">new %2</a> is now up and running!")
.arg(url).arg( Theme::instance()->appName()));
.arg(url).arg( Theme::instance()->appNameGUI()));
_ui.ocLinkLabel->setOpenExternalLinks( true );
if( show ) {
@@ -509,6 +528,12 @@ QString OwncloudWizard::ocUrl() const
return url;
}
void OwncloudWizard::enableFinishOnResultWidget(bool enable)
{
OwncloudWizardResultPage *p = static_cast<OwncloudWizardResultPage*> (page( Page_Install ));
p->setComplete(enable);
}
void OwncloudWizard::slotCurrentPageChanged( int id )
{
qDebug() << "Current Wizard page changed to " << id;
@@ -545,6 +570,9 @@ void OwncloudWizard::slotCurrentPageChanged( int id )
} else {
}
}
if( id == Page_oCSetup ) {
emit clearPendingRequests();
}
}
void OwncloudWizard::showOCUrlLabel( bool show )
@@ -572,4 +600,25 @@ void OwncloudWizard::setOCUrl( const QString& url )
}
void OwncloudWizard::setOCUser( const QString& user )
{
_oCUser = user;
#ifdef OWNCLOUD_CLIENT
OwncloudSetupPage *p = static_cast<OwncloudSetupPage*>(page(Page_oCSetup));
if( p )
p->setOCUser( user );
#else
OwncloudWizardSelectTypePage *p = static_cast<OwncloudWizardSelectTypePage*>(page( Page_SelectType ));
#endif
}
void OwncloudWizard::setAllowPasswordStorage( bool allow )
{
#ifdef OWNCLOUD_CLIENT
OwncloudSetupPage *p = static_cast<OwncloudSetupPage*>(page(Page_oCSetup));
if( p )
p->setAllowPasswordStorage( allow );
#endif
}
} // end namespace

View File

@@ -41,6 +41,8 @@ public:
virtual void initializePage();
virtual int nextId() const;
void setOCUrl( const QString& );
void setOCUser( const QString& );
void setAllowPasswordStorage( bool );
protected slots:
void slotPwdStoreChanged( int );
@@ -74,10 +76,14 @@ public:
OwncloudWizard(QWidget *parent = 0L);
void setOCUrl( const QString& );
void setOCUser( const QString& );
void setAllowPasswordStorage( bool );
void setupCustomMedia( QVariant, QLabel* );
QString ocUrl() const;
void enableFinishOnResultWidget(bool enable);
public slots:
void appendToResultWidget( const QString& msg, LogType type = LogParagraph );
void slotCurrentPageChanged( int );
@@ -88,10 +94,12 @@ signals:
void connectToOCUrl( const QString& );
void installOCServer();
void installOCLocalhost();
void clearPendingRequests();
private:
QString _configFile;
QString _oCUrl;
QString _oCUser;
};
@@ -198,6 +206,8 @@ public:
virtual bool isComplete() const;
virtual void initializePage();
void setComplete(bool complete);
public slots:
void appendResultText( const QString&, OwncloudWizard::LogType type = OwncloudWizard::LogParagraph );
void showOCUrlLabel( const QString&, bool );
@@ -206,6 +216,7 @@ protected:
void setupCustomization();
private:
bool _complete;
Ui_OwncloudWizardResultPage _ui;
};

View File

@@ -159,7 +159,7 @@ p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#585858;&quot;&gt;Select if you want to create a new ownCloud either on the local machine or on your server. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; color:#585858;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#585858;&quot;&gt;This wizard will guide you through all neccessary steps.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#585858;&quot;&gt;This wizard will guide you through all necessary steps.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>

View File

@@ -14,23 +14,30 @@
<string>Proxy Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="text">
<string>Configure Proxies</string>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
<property name="buddy">
<cstring>manualSettings</cstring>
</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="1" column="0">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -73,7 +80,7 @@
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="verticalSpacing">
<number>-1</number>
<number>6</number>
</property>
<property name="leftMargin">
<number>40</number>
@@ -200,29 +207,6 @@
</item>
</layout>
</item>
<item row="2" 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="3" 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>
</layout>
</widget>
<resources/>

View File

@@ -14,14 +14,13 @@
#include "mirall/mirallconfigfile.h"
#include "mirall/utility.h"
#include "mirall/sslerrordialog.h"
#include "mirall/owncloudinfo.h"
#include <QtGui>
#include <QtNetwork>
namespace Mirall
{
#define CA_CERTS_KEY QLatin1String("CaCertificates")
SslErrorDialog::SslErrorDialog(QWidget *parent) :
QDialog(parent), _allTrusted(false)
{
@@ -42,14 +41,6 @@ SslErrorDialog::SslErrorDialog(QWidget *parent) :
}
}
QList<QSslCertificate> SslErrorDialog::storedCACerts()
{
MirallConfigFile cfg( _customConfigHandle );
QList<QSslCertificate> cacerts = QSslCertificate::fromData(cfg.caCerts());
return cacerts;
}
QString SslErrorDialog::styleSheet() const
{
@@ -66,17 +57,25 @@ QString SslErrorDialog::styleSheet() const
}
#define QL(x) QLatin1String(x)
QList<QSslCertificate> SslErrorDialog::storedCACerts()
{
MirallConfigFile cfg( _customConfigHandle );
QList<QSslCertificate> cacerts = QSslCertificate::fromData(cfg.caCerts());
return cacerts;
}
bool SslErrorDialog::setErrorList( QList<QSslError> errors )
{
QList<QSslCertificate> ourCerts = storedCACerts();
// check if unknown certs caused errors.
_unknownCerts.clear();
QStringList errorStrings;
QList<QSslCertificate> trustedCerts = SslErrorDialog::storedCACerts();
for (int i = 0; i < errors.count(); ++i) {
if (ourCerts.contains(errors.at(i).certificate()) ||
_unknownCerts.contains(errors.at(i).certificate() ))
if (trustedCerts.contains(errors.at(i).certificate()) ||
_unknownCerts.contains(errors.at(i).certificate() ))
continue;
errorStrings += errors.at(i).errorString();
if (!errors.at(i).certificate().isNull()) {
@@ -191,9 +190,7 @@ void SslErrorDialog::accept()
QSslSocket::addDefaultCaCertificates(_unknownCerts);
MirallConfigFile cfg( _customConfigHandle );
QByteArray certs = cfg.caCerts();
qDebug() << "Saving " << _unknownCerts.count() << " unknown certs.";
foreach( const QSslCertificate& cert, _unknownCerts ) {
certs += cert.toPem() + '\n';

View File

@@ -22,6 +22,7 @@
#include "ui_sslerrordialog.h"
class QSslError;
class QSslCertificate;
namespace Mirall
@@ -39,13 +40,14 @@ public:
void setCustomConfigHandle( const QString& );
QList<QSslCertificate> storedCACerts();
signals:
public slots:
void accept();
private:
QList<QSslCertificate> storedCACerts();
QString styleSheet() const;
bool _allTrusted;

View File

@@ -224,12 +224,12 @@ StatusDialog::StatusDialog( Theme *theme, QWidget *parent) :
_theme( theme )
{
setupUi( this );
setWindowTitle( QString::fromLatin1( "%1 %2" ).arg(_theme->appName(), _theme->version() ) );
setWindowTitle( QString::fromLatin1( "%1 %2" ).arg(_theme->appNameGUI(), _theme->version() ) );
_model = new FolderStatusModel();
FolderViewDelegate *delegate = new FolderViewDelegate();
_delegate = new FolderViewDelegate();
_folderList->setItemDelegate( delegate );
_folderList->setItemDelegate( _delegate );
_folderList->setModel( _model );
_folderList->setMinimumWidth( 300 );
_folderList->setEditTriggers( QAbstractItemView::NoEditTriggers );
@@ -259,6 +259,8 @@ StatusDialog::StatusDialog( Theme *theme, QWidget *parent) :
StatusDialog::~StatusDialog()
{
delete _model;
delete _delegate;
}
void StatusDialog::slotFolderActivated( const QModelIndex& indx )
@@ -312,6 +314,7 @@ void StatusDialog::slotAddFolder( Folder *folder )
QStandardItem *item = new QStandardItem();
folderToModelItem( item, folder );
_model->appendRow( item );
slotCheckConnection();
}
@@ -359,6 +362,7 @@ void StatusDialog::slotUpdateFolderState( Folder *folder )
} else {
// the dialog is not visible.
}
slotCheckConnection();
}
void StatusDialog::folderToModelItem( QStandardItem *item, Folder *f )
@@ -399,6 +403,7 @@ void StatusDialog::slotRemoveFolder()
// _model->removeRow( selected.row() );
}
}
slotCheckConnection();
}
void StatusDialog::slotRemoveSelectedFolder()
@@ -408,6 +413,7 @@ void StatusDialog::slotRemoveSelectedFolder()
_model->removeRow( selected.row() );
}
buttonsSetEnabled();
slotCheckConnection();
}
void StatusDialog::slotFetchFolder()
@@ -476,12 +482,12 @@ void StatusDialog::slotCheckConnection()
connect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotOCInfoFail(QNetworkReply*)));
_ocUrlLabel->setText( tr("Checking %1 connection...").arg(Theme::instance()->appName()));
_ocUrlLabel->setText( tr("Checking %1 connection...").arg(Theme::instance()->appNameGUI()));
qDebug() << "Check status.php from statusdialog.";
ownCloudInfo::instance()->checkInstallation();
} else {
// ownCloud is not yet configured.
_ocUrlLabel->setText( tr("No %1 connection configured.").arg(Theme::instance()->appName()));
_ocUrlLabel->setText( tr("No %1 connection configured.").arg(Theme::instance()->appNameGUI()));
_ButtonAdd->setEnabled( false);
}
}
@@ -522,7 +528,7 @@ void StatusDialog::slotOCInfoFail( QNetworkReply *reply)
QString errStr = tr("unknown problem.");
if( reply ) errStr = reply->errorString();
_ocUrlLabel->setText( tr("<p>Failed to connect to %1: <tt>%2</tt></p>").arg(Theme::instance()->appName()).arg(errStr) );
_ocUrlLabel->setText( tr("<p>Failed to connect to %1: <tt>%2</tt></p>").arg(Theme::instance()->appNameGUI()).arg(errStr) );
_ButtonAdd->setEnabled( false);
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),

View File

@@ -78,7 +78,6 @@ signals:
void enableFolderAlias( const QString&, const bool );
void infoFolderAlias( const QString& );
void openFolderAlias( const QString& );
void openLogBrowser();
/* start the add a folder wizard. */
void addASync();
@@ -107,6 +106,7 @@ private:
void folderToModelItem( QStandardItem*, Folder* );
QStandardItemModel *_model;
FolderViewDelegate *_delegate;
QUrl _OCUrl;
Theme *_theme;
};

View File

@@ -21,6 +21,10 @@ public:
return item._file == this->_file;
}
bool isEmpty() const {
return _file.isEmpty();
}
// variables
QString _file;
QString _renameTarget;

View File

@@ -58,6 +58,9 @@ QString SyncResult::statusString() const
case SetupError:
re = QLatin1String("SetupError");
break;
case SyncPrepare:
re = QLatin1String("SyncPrepare");
break;
case Unavailable:
re = QLatin1String("Not availabe");
break;

View File

@@ -31,6 +31,7 @@ public:
{
Undefined,
NotYetStarted,
SyncPrepare,
SyncRunning,
Success,
Error,

View File

@@ -71,6 +71,11 @@ QString Theme::statusHeaderText( SyncResult::Status status ) const
return resultStr;
}
QString Theme::appNameGUI() const
{
return appName();
}
QString Theme::version() const
{
return QString::fromLocal8Bit( MIRALL_STRINGIFY( MIRALL_VERSION ));

View File

@@ -37,10 +37,36 @@ public:
oCSetupResultTop // ownCloud connect result page
};
/* returns a singleton instance. */
static Theme* instance();
/**
* @brief appNameGUI - Human readable application name.
*
* Use and redefine this if the human readable name contains spaces,
* special chars and such.
*
* By default, appName() is returned.
*
* @return QString with human readable app name.
*/
virtual QString appNameGUI() const;
/**
* @brief appName - Application name (short)
*
* Use and redefine this as an application name. Keep it straight as
* it is used for config files etc. If you need a more sophisticated
* name in the GUI, redefine appNameGUI.
*
* @return QString with app name.
*/
virtual QString appName() const = 0;
/**
* @brief configFileName
* @return the name of the config file.
*/
virtual QString configFileName() const = 0;
/**

View File

@@ -61,6 +61,8 @@ bool UnisonFolder::isBusy() const
void UnisonFolder::startSync(const QStringList &pathList)
{
QMutexLocker locker(&_syncMutex);
_syncResult.setStatus( SyncResult::SyncRunning );
emit syncStateChange();
emit syncStarted();

View File

@@ -55,6 +55,7 @@ void UpdateDetector::versionCheck( Theme *theme )
}
url.addQueryItem( QLatin1String("version"), ver );
url.addQueryItem( QLatin1String("platform"), platform );
url.addQueryItem( QLatin1String("oem"), theme->appName());
_accessManager->get( QNetworkRequest( url ));
}
@@ -113,7 +114,7 @@ void UpdateDetector::slotVersionInfoArrived( QNetworkReply* reply )
msgBox.setTextFormat( Qt::RichText );
msgBox.setWindowTitle(tr("Client Version Check"));
msgBox.setIcon( QMessageBox::Information );
msgBox.setText(tr("<p>A new version of the %1 client is available.").arg(Theme::instance()->appName()));
msgBox.setText(tr("<p>A new version of the %1 client is available.").arg(Theme::instance()->appNameGUI()));
QString txt = tr("%1 is available. The installed version is %3.<p/><p>For more information see <a href=\"%2\">%2</a></p>")
.arg(ocClient.versionstring()).arg(ocClient.web()).arg(ver);

View File

@@ -12,6 +12,20 @@
*/
#include "utility.h"
#include <QDir>
#include <QFile>
#include <QUrl>
#include <QDebug>
#ifdef Q_OS_MAC
#include <CoreServices/CoreServices.h>
#endif
#ifdef Q_OS_WIN
#include <shlobj.h>
#endif
namespace Mirall {
QString Utility::formatFingerprint( const QByteArray& fmhash )
@@ -30,4 +44,50 @@ QString Utility::formatFingerprint( const QByteArray& fmhash )
return fp;
}
void Utility::setupFavLink(const QString &folder)
{
#ifdef Q_OS_WIN
// Windows Explorer: Place under "Favorites" (Links)
wchar_t path[MAX_PATH];
SHGetSpecialFolderPath(0, path, CSIDL_PROFILE, FALSE);
QString profile = QDir::fromNativeSeparators(QString::fromWCharArray(path));
QDir folderDir(QDir::fromNativeSeparators(folder));
QString linkName = profile+QLatin1String("/Links/") + folderDir.dirName() + QLatin1String(".lnk");
if (!QFile::link(folder, linkName))
qDebug() << Q_FUNC_INFO << "linking" << folder << "to" << linkName << "failed!";
#elif defined (Q_OS_MAC)
// Finder: Place under "Places"/"Favorites" on the left sidebar
CFStringRef folderCFStr = CFStringCreateWithCString(0, folder.toUtf8().data(), kCFStringEncodingUTF8);
CFURLRef urlRef = CFURLCreateWithFileSystemPath (0, folderCFStr, kCFURLPOSIXPathStyle, true);
LSSharedFileListRef placesItems = LSSharedFileListCreate(0, kLSSharedFileListFavoriteItems, 0);
if (placesItems) {
//Insert an item to the list.
LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(placesItems,
kLSSharedFileListItemLast, 0, 0,
urlRef, 0, 0);
if (item)
CFRelease(item);
}
CFRelease(placesItems);
CFRelease(folderCFStr);
CFRelease(urlRef);
#elif defined (Q_OS_UNIX)
// Nautilus: add to ~/.gtk-bookmarks
QFile gtkBookmarks(QDir::homePath()+QLatin1String("/.gtk-bookmarks"));
QByteArray folderUrl = "file://" + folder.toUtf8();
if (gtkBookmarks.open(QFile::ReadWrite)) {
QByteArray places = gtkBookmarks.readAll();
if (!places.contains(folderUrl)) {
places += folderUrl;
gtkBookmarks.reset();
gtkBookmarks.write(places + '\n');
}
}
#endif
}
}

View File

@@ -24,6 +24,7 @@ class Utility
{
public:
static QString formatFingerprint( const QByteArray& );
static void setupFavLink( const QString &folder );
};
}

View File

@@ -2,6 +2,7 @@
*~
*.bak
*.part
*.crdownload
*.unison*
*csync_timedif.ctmp*
@@ -30,3 +31,6 @@ Thumbs.db
.htaccess
Icon\r*
~$*
.~lock.*

View File

@@ -0,0 +1,16 @@
######################################################################
# Automatically generated by qmake (2.01a) Do. Mär 21 15:22:28 2013
######################################################################
TEMPLATE = app
CONFIG -= app_bundle
DEPENDPATH += .
INCLUDEPATH += .
macx {
LIBS += -framework CoreFoundation -framework CoreServices
}
# Input
HEADERS += ../../../src/mirall/utility.h
SOURCES += main.cpp ../../../src/mirall/utility.cpp

View File

@@ -0,0 +1,10 @@
#include "../../../src/mirall/utility.h"
#include <QDir>
int main(int argc, char* argv[])
{
QString dir="/tmp/linktest/";
QDir().mkpath(dir);
Mirall::Utility::setupFavLink(dir);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More