1
0
mirror of https://github.com/chylex/Nextcloud-Desktop.git synced 2026-04-08 12:13:05 +02:00

Compare commits

..

269 Commits

Author SHA1 Message Date
Jenkins for ownCloud
824c97d618 [tx-robot] updated from transifex 2012-11-26 00:03:28 +01:00
Daniel Molkentin
271d4fa22e Show last updated timestamp 2012-11-25 02:07:12 +01:00
Daniel Molkentin
a3a0202752 Fix copy/paste error 2012-11-25 01:20:25 +01:00
Daniel Molkentin
0da93f3eb5 Remove doc from the default target
The doc target requires strict parallel execution. Make it
a separate target unless we figure out how to do this with cmake.
2012-11-25 01:00:21 +01:00
Daniel Molkentin
78c7dc95a0 Add doc cmake targets (HTML, PDF, QtHelp, CHM, man)
make doc will build all of the above, except for CHM,
which needs manual preparation and can be built with
make doc-chm. See doc/scripts/README.rst for details.

We do our best to ensure to detect the required tools
before adding targets, so a build should always succeed.

Exception: On Debian and Ubuntu, the following packages are
required to build the PDF target (in addition to pdflatex
itself, which is autodetected):

* texlive-latex-recommended
* texlive-latex-extra
* texlive-fonts-recommended

If pdflatex is present, but those are not, the doc target
will fail.

Results can be found in $BUILDDIR/doc/$format.
2012-11-25 00:38:47 +01:00
Jenkins for ownCloud
f7b7669be6 [tx-robot] updated from transifex 2012-11-25 00:04:10 +01:00
Daniel Molkentin
f607cf55c6 doc: Make fit for use with make latexpdf 2012-11-24 02:35:18 +01:00
Jenkins for ownCloud
6a33b6ec33 [tx-robot] updated from transifex 2012-11-23 00:04:25 +01:00
Daniel Molkentin
e1bf2cc626 Ready for Release Candidate 2012-11-22 15:58:56 +01:00
Klaas Freitag
d15c0d046b Remove pre marker for version. 2012-11-22 12:34:21 +01:00
Klaas Freitag
f20bbe05bd Allow alias setting in Settings group name. 2012-11-22 12:32:07 +01:00
Klaas Freitag
c560fc5959 Escape [ and ] in Folder alias and file name. 2012-11-22 12:32:06 +01:00
Klaas Freitag
ee9e814f41 Getter and Setter for the config file name. 2012-11-22 12:32:06 +01:00
Jenkins for ownCloud
9e3d22af2d [tx-robot] updated from transifex 2012-11-22 00:03:15 +01:00
Klaas Freitag
c8ff747194 More changelog entries for 1.1.2 2012-11-21 16:39:25 +01:00
Daniel Molkentin
da64639f39 Update doc/building.rst
move packages into correct section
2012-11-21 15:20:15 +01:00
Daniel Molkentin
faa0f06fe3 Improve building section based on user feedback 2012-11-21 14:57:40 +01:00
Jenkins for ownCloud
2b9262f653 [tx-robot] updated from transifex 2012-11-21 00:03:40 +01:00
Klaas Freitag
01ccf679bd Fix Qt 46 build 2012-11-20 10:56:20 +01:00
dragotin
b55d6742fe Merge pull request #94 from owncloud/qt46fixurl
Fix url encoding in Qt46, Bug #93
2012-11-20 01:39:04 -08:00
Jenkins for ownCloud
fc6350cb9a [tx-robot] updated from transifex 2012-11-20 00:03:26 +01:00
Daniel Molkentin
9b8b656720 doc: Add Qt dependency to build instructions 2012-11-19 18:49:10 +01:00
Daniel Molkentin
8c9f8bdb6d doc: Fix build instructions; hint make package 2012-11-19 18:15:25 +01:00
Daniel Molkentin
be367eb94b Do not prepopulate the user field, it's usually wrong
Especially without LDAP, or in cases where the login
is an email address. If we ever want this again,
we need to make this cleverer.
2012-11-19 12:10:46 +01:00
Daniel Molkentin
aa577ce038 Remove placeholder texts for username and password
User names might be misleading, since they might be
email addresses, SMB logins including domain, etc.
2012-11-19 12:10:46 +01:00
Daniel Molkentin
53b0b96627 setup wizard: Remove subtitles 2012-11-19 12:10:46 +01:00
Daniel Molkentin
5173de5798 Theme: allow enforced locale 2012-11-19 12:10:46 +01:00
Daniel Molkentin
6457153bda Mac: Do not deploy DMG background, doesn't work 2012-11-19 12:10:45 +01:00
Daniel Molkentin
f8f188add4 Mac: Deploy sync-exclude.lst to bundle at build time 2012-11-19 12:10:45 +01:00
Jenkins for ownCloud
b6dfdc4c57 [tx-robot] updated from transifex 2012-11-19 00:02:43 +01:00
Jenkins for ownCloud
385f35d356 [tx-robot] updated from transifex 2012-11-18 00:02:57 +01:00
Klaas Freitag
afa48b0cc2 Fix url encoding in Qt46, Bug #93 2012-11-17 16:46:31 +01:00
Jenkins for ownCloud
94ed186b4c [tx-robot] updated from transifex 2012-11-17 00:03:22 +01:00
Daniel Molkentin
8fc1b38359 dialog title == menu item title 2012-11-16 13:36:16 +01:00
Klaas Freitag
9e66de07f9 Better error message for propagate fail. 2012-11-16 12:32:07 +01:00
Jenkins for ownCloud
2a53abbc20 [tx-robot] updated from transifex 2012-11-16 00:04:51 +01:00
Daniel Molkentin
ba9a07c2f2 Upate build docs 2012-11-15 14:42:10 +01:00
Daniel Molkentin
e4ae794bac Remove and do not try to commit temp editor files 2012-11-15 12:50:52 +01:00
Klaas Freitag
01e8c9dbbe Fix credentialstore on startup, promote credentials back on setup.
This fixes https://github.com/owncloud/mirall/issues/81
2012-11-15 11:43:43 +01:00
Daniel Molkentin
c5739b4d53 Remove extraneous legalese. 2012-11-15 01:07:51 +01:00
Jenkins for ownCloud
158859006b [tx-robot] updated from transifex 2012-11-15 00:04:24 +01:00
Klaas Freitag
1a5a015eb4 More changes to the Changelog. 2012-11-14 15:03:14 +01:00
Klaas Freitag
1acea008c2 Fixed package download link. 2012-11-14 15:03:14 +01:00
Jenkins for ownCloud
59a1cc4596 [tx-robot] updated from transifex 2012-11-14 00:04:41 +01:00
Klaas Freitag
39dc4cb46c Use CredentialStore also for Qt4.6 based builds. 2012-11-13 15:01:05 +01:00
Klaas Freitag
9c3b9b84ae Prepare some entries for 1.1.2 2012-11-13 11:19:34 +01:00
Klaas Freitag
a8dbed989b Use CredentialStore to manage user credentials.
This fixes the bug that if the password is not stored in the cfg
file the user could not cancel the auth dialog. Moreover it handles
various credential backends better and gives a better user experience.
2012-11-13 11:19:34 +01:00
Klaas Freitag
78be11b3cf Push Version to 1.1.2 pre 2012-11-13 11:19:34 +01:00
Jenkins for ownCloud
6f8824eacb [tx-robot] updated from transifex 2012-11-13 00:06:33 +01:00
Jenkins for ownCloud
12b5ad644d [tx-robot] updated from transifex 2012-11-12 00:03:18 +01:00
Jenkins for ownCloud
35b0a2b116 [tx-robot] updated from transifex 2012-11-10 00:03:27 +01:00
Jenkins for ownCloud
6442c7e5f7 [tx-robot] updated from transifex 2012-11-09 00:04:31 +01:00
Jenkins for ownCloud
8a394dd471 [tx-robot] updated from transifex 2012-11-08 00:04:24 +01:00
Jenkins for ownCloud
02e990b2c5 [tx-robot] updated from transifex 2012-11-07 00:04:15 +01:00
Jenkins for ownCloud
64177df3d9 [tx-robot] updated from transifex 2012-11-06 00:02:48 +01:00
Daniel Molkentin
df219dd09b Doc: use correct cmake vars 2012-11-05 14:44:10 +01:00
Daniel Molkentin
59969c3574 Qt is not C. 2012-11-05 11:44:22 +01:00
Klaas Freitag
3b9f4bf825 Merge branch 'master' of github.com:owncloud/mirall 2012-11-05 11:38:16 +01:00
Daniel Molkentin
80ecd71fc7 Doc: more trouble shooting 2012-11-05 11:36:48 +01:00
Klaas Freitag
5519bc7cbb Try to create local dir if not existing. 2012-11-05 11:36:39 +01:00
Klaas Freitag
c31f0885a4 Remove bogus space 2012-11-05 11:36:38 +01:00
Klaas Freitag
2501cc57d5 Display error status in statusdialog. 2012-11-05 11:36:38 +01:00
Klaas Freitag
fbb46b64f9 Check if local folder is proper and set error stat accordingly. 2012-11-05 11:36:38 +01:00
Klaas Freitag
4d08605b5b Also compute overall status for disabled folders. 2012-11-05 11:36:38 +01:00
Klaas Freitag
764c352c8f Calculate overallSyncStartup on startup. 2012-11-05 11:36:38 +01:00
Jenkins for ownCloud
61b9b44fa7 [tx-robot] updated from transifex 2012-11-05 00:04:23 +01:00
Daniel Molkentin
7d6eb61f1b doc: wording 2012-11-04 00:46:02 +01:00
Jenkins for ownCloud
6d17b9de4e [tx-robot] updated from transifex 2012-11-04 00:02:33 +01:00
Jenkins for ownCloud
ce45c7876c [tx-robot] updated from transifex 2012-11-03 00:03:25 +01:00
Daniel Molkentin
7cc3e7e392 Debug: fix typo 2012-11-02 16:32:26 +01:00
Daniel Molkentin
3a165ad654 Doc: add troubleshooting section 2012-11-02 16:26:56 +01:00
Daniel Molkentin
f04cf3a31e Bump version of master to 1.2pre 2012-11-02 16:14:51 +01:00
Daniel Molkentin
4fbfe7bfef Installer: Only show license on special request
GPL is a distribution license, and should thus
not be required to be accepted upon installation.
2012-11-02 16:14:33 +01:00
Daniel Molkentin
46a82b69c5 Show user name for connection in statusdialog
Move server version purely to tooltip.

Fixes issue #8.
2012-11-02 14:09:23 +01:00
Jenkins for ownCloud
0de3ae32c0 [tx-robot] updated from transifex 2012-11-02 00:05:49 +01:00
Daniel Molkentin
06e7864174 Doc: Require sphinx todo extension 2012-11-01 19:10:51 +01:00
Daniel Molkentin
8b60726a48 Doc: Introduce chapter on Architecture, Glossary 2012-11-01 19:10:01 +01:00
Daniel Molkentin
855597bfd9 Doc: formatting 2012-11-01 17:24:25 +01:00
Daniel Molkentin
827a31fa02 doc: formatting fix 2012-11-01 17:03:58 +01:00
Daniel Molkentin
20f04ec6d9 doc: small improvements 2012-11-01 16:52:07 +01:00
Daniel Molkentin
83180310af doc: add chapter on (soft-)branding 2012-11-01 16:33:27 +01:00
Jenkins for ownCloud
829bb7c5a9 [tx-robot] updated from transifex 2012-11-01 00:03:01 +01:00
Daniel Molkentin
9feb9b5262 Doc: fix typo 2012-10-31 17:22:03 +01:00
Daniel Molkentin
f2cfabcdb8 Doc: improve build instructions 2012-10-31 15:19:00 +01:00
Daniel Molkentin
6b2be97c22 Docs: add build chapter 2012-10-31 14:44:59 +01:00
Jenkins for ownCloud
616d8d39b7 [tx-robot] updated from transifex 2012-10-31 00:03:16 +01:00
Jenkins for ownCloud
69b3e9b10d [tx-robot] updated from transifex 2012-10-30 00:02:40 +01:00
Klaas Freitag
0224c3fbd6 Compare absolute path in fileStatus. 2012-10-29 14:35:02 +01:00
Klaas Freitag
78c1bc6b22 Cleanup of sync result treewalk, build up journal in owncloudfolder. 2012-10-29 12:24:20 +01:00
Klaas Freitag
993d33f779 Fix fileStatus API.
Conflicts:

	src/mirall/owncloudfolder.cpp
2012-10-29 12:23:01 +01:00
Klaas Freitag
0aa403eca3 Clean merge problems. 2012-10-29 12:20:57 +01:00
Klaas Freitag
8d1c7ddb9f Make sure that path() has a trailing slash. 2012-10-29 12:20:57 +01:00
Jenkins for ownCloud
01e601db14 [tx-robot] updated from transifex 2012-10-29 00:03:36 +01:00
Jenkins for ownCloud
0184993795 [tx-robot] updated from transifex 2012-10-28 00:03:12 +02:00
Daniel Molkentin
6b0abed4ee Remove file checked-in by accident 2012-10-27 19:30:37 +02:00
Daniel Molkentin
bf8b9246fe Add docs 2012-10-27 17:05:01 +02:00
Daniel Molkentin
6d4f712f83 Make SSL error dialog more intuitive 2012-10-27 17:05:01 +02:00
Daniel Molkentin
d2ebcd065e Fix tab order in setup page 2012-10-27 17:04:49 +02:00
Daniel Molkentin
28e15f5420 Escape HTML tags in self-signed certs 2012-10-27 17:04:49 +02:00
Daniel Molkentin
a315a3b5c7 There always must be both kinds of hashes, simplify code 2012-10-27 17:04:49 +02:00
Jenkins for ownCloud
10766182bc [tx-robot] updated from transifex 2012-10-27 00:02:51 +02:00
Dominik Schmidt
351f9aedfb Add testing skeleton 2012-10-26 20:24:12 +02:00
Jenkins for ownCloud
6757db2e53 [tx-robot] updated from transifex 2012-10-26 02:07:36 +02:00
Bartek Przybylski
55c9c3bf12 remove compilation warning 2012-10-25 23:20:00 +02:00
Jenkins for ownCloud
e52d43f68b [tx-robot] updated from transifex 2012-10-25 02:11:05 +02:00
Jenkins for ownCloud
cfe9a2476b [tx-robot] updated from transifex 2012-10-24 02:10:48 +02:00
Daniel Molkentin
efa8d7670c Show hashes of unknown certs 2012-10-24 01:44:13 +02:00
Jenkins for ownCloud
8ddba655df [tx-robot] updated from transifex 2012-10-23 02:08:12 +02:00
Daniel Molkentin
5c13115fee Remove 0% translations. 2012-10-22 16:39:56 +02:00
Thomas Müller
f948ce4015 [tx] minimum_perc = 70 2012-10-22 15:16:57 +03:00
Daniel Molkentin
2cbcd52f35 Do not allow the selection of a target in single folder mode 2012-10-22 11:32:53 +02:00
Jenkins for ownCloud
09405fc9f7 [tx-robot] updated from transifex 2012-10-22 02:08:53 +02:00
Jenkins for ownCloud
651517c3a7 [tx-robot] updated from transifex 2012-10-21 02:09:50 +02:00
Daniel Molkentin
b0801d469c If present, select first item in status dialog
The old behavior is confusing and there is no real
reason to not have an object that is default-selected.
2012-10-20 14:58:49 +02:00
Daniel Molkentin
8fbc0e7c46 Show wizard with intro when starting without account
The message box was complicated and not even correct
on some OSes. The intro page is omitted if the wizard
gets called via the "Configure" menu item.
2012-10-20 13:58:37 +02:00
Daniel Molkentin
d8728a56bc Pre-setup, disable irrelevant items in context menu 2012-10-20 13:58:37 +02:00
Jenkins for ownCloud
3e150ee47b [tx-robot] updated from transifex 2012-10-20 02:06:35 +02:00
Jenkins for ownCloud
ddc337303c [tx-robot] updated from transifex 2012-10-19 02:10:42 +02:00
Daniel Molkentin
574b6f49c2 Add .gitattributes, needed for clean git export 2012-10-18 13:42:47 +04:00
Daniel Molkentin
18a06506b8 ChangeLog updates for 1.1.1 2012-10-18 10:11:58 +02:00
Jenkins for ownCloud
bbdc7423b9 [tx-robot] updated from transifex 2012-10-18 02:11:56 +02:00
Daniel Molkentin
379da4ed0d Proper workaround for bug in Ubuntu's Qt SNI bridge. 2012-10-17 23:16:59 +02:00
Klaas Freitag
cff0fcee16 Escape the folder alias as used in QSetting and as file name. 2012-10-17 16:33:19 +02:00
Jenkins for ownCloud
94346fc12f [tx-robot] updated from transifex 2012-10-17 02:08:28 +02:00
Daniel Molkentin
257896969a Clean up argument handling
- Allow to retrospectively open log window
- Don't waste init time if only help is requested.
2012-10-16 19:06:23 +02:00
Klaas Freitag
fe665f234d Use better default value instead of constant number. 2012-10-16 10:11:24 +02:00
Daniel Molkentin
bb76365a3a Make sure SSL errors are always handled 2012-10-16 10:09:38 +02:00
Jenkins for ownCloud
dfe30c16c1 [tx-robot] updated from transifex 2012-10-16 02:10:50 +02:00
Jenkins for ownCloud
824a14ebb5 [tx-robot] updated from transifex 2012-10-15 02:11:39 +02:00
Jenkins for ownCloud
6fa9b86ee7 [tx-robot] updated from transifex 2012-10-14 02:12:35 +02:00
Jenkins for ownCloud
0955e8cc1f [tx-robot] updated from transifex 2012-10-13 02:11:26 +02:00
Daniel Molkentin
aad21c8c4a Add license to Windows installer 2012-10-12 14:44:21 +02:00
Daniel Molkentin
b7433ccad6 Revert "Hide remove button in singleFolder mode"
This reverts commit 8939e08ce1.
2012-10-12 14:44:21 +02:00
Daniel Molkentin
04642b3c6d Export repo revision indicator
To be used with git export.
2012-10-12 14:44:21 +02:00
Jenkins for ownCloud
85ac69dbe6 [tx-robot] updated from transifex 2012-10-12 02:09:27 +02:00
Jenkins for ownCloud
c491b9c064 [tx-robot] updated from transifex 2012-10-11 02:10:00 +02:00
Daniel Molkentin
d52d32f1b3 add helper script to sign app bundle 2012-10-10 16:57:07 +02:00
Daniel Molkentin
fee9616708 OS X: Remove "make install" requirment for csync 2012-10-10 16:05:17 +02:00
Daniel Molkentin
62a36cd3bb CMake: Also set CSYNC_BINARY_DIR
...so NSIS finds its resource in the right place.
2012-10-10 15:15:19 +02:00
Daniel Molkentin
60f16896ed Merge branch 'master' of github.com:owncloud/mirall 2012-10-10 14:20:17 +02:00
Daniel Molkentin
aa63a789dc Fix for prev. commmit 2012-10-10 14:19:29 +02:00
Daniel Molkentin
d599c4532c replace relative csync buildir detection magic
If you do not want to run make install for lib(o)csync,
pass -DCSYNC_LIBRARY_PATH=$your_csync_builddir
and  -DCSYNC_INCLUDE_PATH=$your_csync_srcdir/src
to cmake when building mirall.
2012-10-10 14:04:24 +02:00
Daniel Molkentin
a6acb2a4d0 Remove beta flag in preparation for packaging 2012-10-10 11:53:43 +02:00
Daniel Molkentin
824368e504 Update change log with client changes 2012-10-10 11:51:38 +02:00
Jenkins for ownCloud
c91cc8e411 [tx-robot] updated from transifex 2012-10-10 02:13:22 +02:00
Daniel Molkentin
72f3b5457e Use HTTPS for update check 2012-10-09 17:46:41 +02:00
Daniel Molkentin
e45dfdb3b2 Dirty qnam/proxy export is no longer required 2012-10-09 17:19:09 +02:00
Daniel Molkentin
19a4f8fc64 _accessManager is already initialized in the ctor 2012-10-09 17:15:46 +02:00
Daniel Molkentin
a8d6c083e3 Make code more readable. 2012-10-09 10:10:41 +02:00
Daniel Molkentin
861a66f8cb Make PAC work on Windows 2012-10-09 03:08:39 +02:00
Daniel Molkentin
3db60b4fe7 Massive simplification of proxy support.
Purposefully separated from last commit, but
associated with it: No more need for special
cases after libocsync got fixed do adhere properly.
2012-10-09 02:35:08 +02:00
Daniel Molkentin
c93721258e Working PAC support
This goes along with e0f02c in csync/dav.
2012-10-09 02:35:08 +02:00
Jenkins for ownCloud
088a6412b1 [tx-robot] updated from transifex 2012-10-09 02:10:53 +02:00
Daniel Molkentin
6459f574cc Prepare for Mac package signing. 2012-10-09 01:40:43 +02:00
Daniel Molkentin
fdfafb6e70 NSI: add proper version of ocsync.conf 2012-10-09 01:40:43 +02:00
Klaas Freitag
48d5261ba7 Use Max instead of Min of course 2012-10-08 20:43:16 +02:00
Klaas Freitag
23c598a907 Only replace the scheme at the beginning of string 2012-10-08 16:21:18 +02:00
Daniel Molkentin
d7b94c7f96 Use HttpProxy instead of Socks5Proxy. 2012-10-08 11:08:01 +02:00
Jenkins for ownCloud
3b5bc2c13f [tx-robot] updated from transifex 2012-10-07 02:10:33 +02:00
Jenkins for ownCloud
0b885b3cb4 [tx-robot] updated from transifex 2012-10-06 02:10:14 +02:00
Klaas Freitag
20a875a682 Fix SYCCONFIGDIR => SYSCONFDIR. 2012-10-05 23:01:43 +02:00
Daniel Molkentin
34b8c39878 Quick hack: do not crash on windows when pausing sync 2012-10-05 22:53:42 +02:00
Klaas Freitag
a646f72980 Merge branch 'master' of github.com:owncloud/mirall 2012-10-05 22:47:54 +02:00
Klaas Freitag
aa56d1ebea Fix SYSCONFIGDIR install of the sync-exclude file. 2012-10-05 22:47:08 +02:00
Daniel Molkentin
0ee938ac9b Prepend slash to remote folder 2012-10-05 22:42:35 +02:00
Klaas Freitag
06b2e1f645 Simplify url string from textfield to avoid unwanted spaces. 2012-10-05 22:33:16 +02:00
Klaas Freitag
7e1c58b602 Fix include path search. 2012-10-05 17:13:23 +02:00
Klaas Freitag
e0a21ebfd6 Fix to find the header even from installed ocsync packages. 2012-10-05 17:02:39 +02:00
Daniel Molkentin
06a1cfe642 Anther fix for sync pausing 2012-10-05 12:59:58 +02:00
Daniel Molkentin
cb6d056a1f Don't hardcode packag name on Mac 2012-10-05 12:18:45 +02:00
Daniel Molkentin
ae93e2aa10 Fix OS X bundle generation 2012-10-05 11:59:50 +02:00
Daniel Molkentin
7d52884699 Fix cmake for windows wrt libocsync renaming 2012-10-05 12:10:33 +04:00
Klaas Freitag
1442b4d42c Merge branch 'master' of github.com:owncloud/mirall 2012-10-05 10:03:50 +02:00
Klaas Freitag
736a8dc457 fixed name of the csync owncloud module. 2012-10-05 10:03:16 +02:00
Jenkins for ownCloud
b06ab27711 [tx-robot] updated from transifex 2012-10-05 02:08:37 +02:00
Daniel Molkentin
3a983b428f Fix bug when trying to pause a running sync 2012-10-04 14:08:23 +02:00
Klaas Freitag
e50479cae5 Push version to 1.1.0 beta3 2012-10-04 13:09:00 +02:00
Jenkins for ownCloud
a8307abe64 [tx-robot] updated from transifex 2012-10-04 02:09:59 +02:00
Jenkins for ownCloud
1e96c1b7bd [tx-robot] updated from transifex 2012-10-03 02:08:23 +02:00
Daniel Molkentin
c42f77cf23 Consistency fix: name ui and src alike 2012-10-03 00:45:54 +02:00
Daniel Molkentin
d169bc24bf ownCloudInfo must not include sslErrorDialog 2012-10-03 00:43:43 +02:00
Klaas Freitag
4d11e41e97 Merge branch 'master' of github.com:owncloud/mirall 2012-10-02 17:42:56 +02:00
Klaas Freitag
0007579ab8 Initialize pointer before use. 2012-10-02 17:42:37 +02:00
Daniel Molkentin
1752c23002 Use themed app name in password dialog. 2012-10-02 16:54:46 +02:00
Klaas Freitag
732ed57360 Merge branch 'master' of github.com:owncloud/mirall 2012-10-02 13:25:28 +02:00
Klaas Freitag
fabb353158 Use Qt proxy setting in csync in case its "default proxy" 2012-10-02 13:24:10 +02:00
Klaas Freitag
9ce10e7fe7 removed wrong header from filelist. 2012-10-02 13:18:36 +02:00
Klaas Freitag
11706c4e3e Fix header. 2012-10-02 13:17:37 +02:00
Klaas Freitag
de60d53a78 Merge branch 'sslerrordialog' of https://github.com/sebasje/mirall into sebasje-sslerrordialog
Conflicts:
	src/mirall/application.cpp
	src/mirall/application.h
	src/mirall/owncloudinfo.cpp
2012-10-02 12:34:06 +02:00
Jenkins for ownCloud
4256d0fd8a [tx-robot] updated from transifex 2012-10-02 02:08:21 +02:00
Jenkins for ownCloud
5587da946f [tx-robot] updated from transifex 2012-10-01 02:11:06 +02:00
Lukas Reschke
0b06982929 Optimize PNG files
This lossless optimization, reduces the filesize at about 25% for each
image
2012-09-30 15:27:46 +02:00
Lukas Reschke
e220de5236 Add .htaccess to sync exclude
ownCloud Server blacklists .htaccess files for security reasons - so it's useless to try to sync it.

See isBlacklisted() - fed34aecfa/lib/filesystem.php (L388)
2012-09-30 16:20:50 +03:00
Jenkins for ownCloud
3fc8e1c339 [tx-robot] updated from transifex 2012-09-30 02:08:03 +02:00
Jenkins for ownCloud
d21407181b [tx-robot] updated from transifex 2012-09-29 02:07:39 +02:00
Klaas Freitag
1c326029a3 More theming fixes. 2012-09-28 15:19:42 +02:00
Klaas Freitag
4ac85b0702 Removed more hardcoded program names and replaced by theme appName. 2012-09-28 14:22:43 +02:00
Klaas Freitag
8939e08ce1 Hide remove button in singleFolder mode 2012-09-28 13:47:43 +02:00
Klaas Freitag
7156e47355 Introduce defaultServerFolder and defaultClientFolder. 2012-09-28 13:42:22 +02:00
Klaas Freitag
94ceb95045 Remove unneeded settings-code for win32. 2012-09-28 11:36:39 +02:00
Klaas Freitag
42d7a48df9 Added missing 's' - thanks Lukas :) 2012-09-28 11:02:21 +02:00
Klaas Freitag
4691a6cae1 Merge branch 'master' of github.com:owncloud/mirall 2012-09-28 11:01:35 +02:00
Klaas Freitag
2a46a8a1ed Changelog update. 2012-09-28 11:01:06 +02:00
Jenkins for ownCloud
ee7099f8fd [tx-robot] updated from transifex 2012-09-28 02:08:28 +02:00
Klaas Freitag
dc5452a315 more useful entries for the exclude list. 2012-09-27 17:38:36 +02:00
Klaas Freitag
b41d8c3c12 Removed app name from strings even more and replaced by theme string. 2012-09-27 17:22:08 +02:00
Klaas Freitag
b34d5ca3de Deleted for the benefit of sync-exclude.lst 2012-09-27 15:33:40 +02:00
Klaas Freitag
9d3d789890 Rename ownCloudClient.ini to custom.ini and put it to /etc/ownCloud. 2012-09-27 15:28:49 +02:00
Klaas Freitag
d09693f191 Read sync-exclude.lst from /etc/ownCloud, renamed from exclude.lst. 2012-09-27 13:16:14 +02:00
Klaas Freitag
e4024015a4 Merge branch 'master' of github.com:owncloud/mirall 2012-09-27 12:30:27 +02:00
Klaas Freitag
180b99c02e Change the csync config dir to the users app path, not longer .csync. 2012-09-27 12:27:40 +02:00
Daniel Molkentin
32579dd25a Brown paper bag fix. 2012-09-27 12:22:27 +02:00
Daniel Molkentin
740370b106 Do not translate application name, it's a brand
Another reason: File system and registry names depend on it
2012-09-27 11:52:58 +02:00
Daniel Molkentin
af99be4cd5 NSIS: shut down binary before uninstall 2012-09-27 10:38:31 +02:00
Daniel Molkentin
d9d0432187 nicer Setup images 2012-09-27 10:36:43 +02:00
Jenkins for ownCloud
888181145a [tx-robot] updated from transifex 2012-09-27 02:05:13 +02:00
Daniel Molkentin
3d6a2a4966 Partial revert of 261731
An experimental change sneaked in.
2012-09-26 18:24:07 +02:00
Daniel Molkentin
6e1deab0ae Supplemental: less hardcoded uses of "ownCloud" 2012-09-26 17:01:33 +02:00
Daniel Molkentin
5df5d55fa4 Make code more readable 2012-09-26 17:01:25 +02:00
Daniel Molkentin
991a04abc5 remove arguments from ownCloudInfo ctor
its only caller is the singletons instance() method
2012-09-26 16:59:53 +02:00
Daniel Molkentin
261731c841 Consistency fixes for single folder mode 2012-09-26 16:59:47 +02:00
Daniel Molkentin
5adcc7d12f CMake: Finding files requires reference to srcdir 2012-09-26 11:29:55 +02:00
Jenkins for ownCloud
73374cb810 [tx-robot] updated from transifex 2012-09-26 02:09:01 +02:00
Daniel Molkentin
1b0744dac6 icon improvements
- more sizes
- rename state icons due to a cmake limitation
  (it globs owncloud-icon-* for mac and windows icons,
   which causes the state icons to appear as app icons)
- adjust resourcefile and theme accordingly
2012-09-25 17:14:21 +02:00
Daniel Molkentin
9d479f9061 Installers on Windows are called Setup
Also remove bogus manual line break.
2012-09-24 07:19:09 +02:00
Daniel Molkentin
783207fa40 At least the Program group should be in 'Minimal'. 2012-09-24 03:45:12 +02:00
Daniel Molkentin
ea123b1705 Fix typo 2012-09-24 03:44:32 +02:00
Daniel Molkentin
8233c0c82a Add autostart section 2012-09-24 03:44:03 +02:00
Daniel Molkentin
95f28eca5b Rename win installer BMPs as a consequence of renaming the package 2012-09-24 00:42:30 +02:00
Daniel Molkentin
00f7b10b0f Drop the -client suffix. 2012-09-23 23:39:26 +02:00
Jenkins for ownCloud
2d87466217 [tx-robot] updated from transifex 2012-09-25 02:07:37 +02:00
Daniel Molkentin
bcf9bb8238 Reuse Theme singleton 2012-09-24 19:42:48 +02:00
Daniel Molkentin
bc08f81683 More use of appName() in tr()'s. 2012-09-24 19:21:55 +02:00
Daniel Molkentin
e3a9081181 Fix default implementation of Folder::nativeSecondPath(). 2012-09-24 19:20:16 +02:00
Daniel Molkentin
2de9cc9590 Use the themes appName() instead of "ownCloud".
This turns the Theme class into a singleton.
2012-09-24 17:57:20 +02:00
Jenkins for ownCloud
a7a744eb6f [tx-robot] updated from transifex 2012-09-24 02:05:47 +02:00
Jenkins for ownCloud
6f027460d1 [tx-robot] updated from transifex 2012-09-23 02:06:37 +02:00
Jenkins for ownCloud
f1d95323b2 [tx-robot] updated from transifex 2012-09-22 02:03:37 +02:00
Daniel Molkentin
d0a66b70f4 Defer handling of pretty remote path to subclasses.
The base class cannot reasonably assume anything about
pretty printing. The subclasses know a lot better.
2012-09-21 18:33:11 +02:00
Daniel Molkentin
a05a4c3741 More templatization. 2012-09-21 13:10:55 +02:00
Jenkins for ownCloud
5255a32fac [tx-robot] updated from transifex 2012-09-21 02:07:04 +02:00
Daniel Molkentin
a94e6dbe8c NSIS: Remove stray file 2012-09-20 17:32:13 +02:00
Daniel Molkentin
663a1886e9 CMake: Centralize all application-specific parameters. 2012-09-20 17:31:18 +02:00
Klaas Freitag
1a603bd800 Update version to 1.1.0 beta2 2012-09-20 18:17:07 +03:00
Klaas Freitag
dd5d407198 Fix activation of list entries in status dialog (thanks kyle-f). 2012-09-20 18:14:22 +03:00
Daniel Molkentin
8a56a90d16 NSIS: fix typo, expand variables properly. 2012-09-20 12:21:21 +02:00
Daniel Molkentin
2c44915db9 ignore more build/IDE artifacts 2012-09-20 11:12:52 +02:00
Daniel Molkentin
aa34331489 Remove unused declaration. 2012-09-20 11:12:52 +02:00
Daniel Molkentin
50166424c8 Fix crash on exit on X11. 2012-09-20 11:12:52 +02:00
Jenkins for ownCloud
7e4ff7dc86 [tx-robot] updated from transifex 2012-09-20 02:12:07 +02:00
Klaas Freitag
8f40b2a276 Use delete[] to free mem from qstrdup, thanks valgrind. 2012-09-19 13:51:27 +03:00
Klaas Freitag
d195ad3072 Fix ownCloud icon and a layout issue. 2012-09-19 13:31:42 +03:00
Klaas Freitag
75554a2ed6 Removed hackish beta version marker in status dialog. 2012-09-19 13:02:28 +03:00
Klaas Freitag
d9f5b681cb Merge branch 'master' of github.com:owncloud/mirall 2012-09-19 12:59:20 +03:00
Klaas Freitag
45d224e922 Handle the themed singleSyncFolder-mode correctly. 2012-09-19 12:58:34 +03:00
Klaas Freitag
09d8fb9483 Add a theme switch to only allow a single sync folder for the client. 2012-09-19 12:58:02 +03:00
Klaas Freitag
a526035273 Add a method to set the enabled status of the buttons correctly. 2012-09-19 12:57:12 +03:00
Jenkins for ownCloud
f8cb8f31de [tx-robot] updated from transifex 2012-09-19 02:09:07 +02:00
Klaas Freitag
090bdcab68 Use the THEME_CLASS macro in config file class. 2012-09-18 13:55:58 +03:00
Klaas Freitag
29f3a002c4 Merge branch 'master' of github.com:owncloud/mirall 2012-09-18 13:53:42 +03:00
Klaas Freitag
a9c7b9304e Use a macro THEME_CLASS from CMakeLists.txt instead of ifdefs. 2012-09-18 13:52:52 +03:00
Jenkins for ownCloud
0b75075a4f [tx-robot] updated from transifex 2012-09-18 02:05:38 +02:00
Daniel Molkentin
881f8463e8 OS X: reintroduce LSUIElement in Info.plist 2012-09-17 21:55:57 +02:00
Daniel Molkentin
92ea6a2bef Tiny fix to previous commit 2012-09-17 21:50:30 +02:00
Daniel Molkentin
f1cd510058 Fix up Info.plist metadata for OS X
- behave correctly on retina displays
- fix focus policy
- insert correct version info from cmake
2012-09-17 21:46:18 +02:00
Daniel Molkentin
aab1c94e44 Simplify version display.
Reduces amount of required helper macros.
2012-09-17 21:23:56 +02:00
Daniel Molkentin
6d13b1b2fb Added a simple about dialog. 2012-09-17 21:06:20 +02:00
Daniel Molkentin
ff4a119c0c Don't swallow ':' when entered.
Treat entering 'http(s)://' gracefully by
removing the substring and flipping the
checkbox.
2012-09-17 19:23:53 +02:00
Sebastian Kügler
c24728b692 Move SslErrorDialog into Application
This patch makes it possible to cut out a large piece from the lib. We
want to avoid having GUI code in the daemon. For Mirall, this is now
handled in Application. for other clients, they can do whatever they
want with this signal, and implement their own SSL Error handling.

The patch isn't exactly a beauty queen, since it involves some
back-and-forth between application and owncloudinfo objects, but it
seems the only way to properly separate and abstract the UI out of
owncloudinfo, and cuts down a huge part of the dependency chain,
especially QWidget-based classes.

I haven't been able to properly test this, but if anyone can give me a
login to a server that has wrong or untrusted SSL certificates, I'll
happily do it.

Merge? *puppy eyes*
2012-09-10 23:53:49 +02:00
171 changed files with 25266 additions and 33852 deletions

4
.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
.tag export-subst
.gitignore export-ignore
.gitattributes export-ignore
.commit-template export-ignore

9
.gitignore vendored
View File

@@ -1,4 +1,7 @@
build
*build*/
*flymake*
CMakeLists.txt.user
qtcreator-build/*
CMakeLists.txt.user*
*.patch
*~
*.autosave
doc/_build/*

1
.tag Normal file
View File

@@ -0,0 +1 @@
$Format:%H$

View File

@@ -4,13 +4,19 @@ project(mirall)
set(PACKAGE "mirall")
set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules )
if ( EXISTS ${CMAKE_SOURCE_DIR}/OEM.cmake )
include ( ${CMAKE_SOURCE_DIR}/OEM.cmake )
else ()
include ( ${CMAKE_SOURCE_DIR}/OWNCLOUD.cmake )
endif()
include(${CMAKE_SOURCE_DIR}/VERSION.cmake)
configure_file( ${CMAKE_SOURCE_DIR}/src/mirall/version.h.in "${CMAKE_CURRENT_BINARY_DIR}/src/mirall/version.h" )
include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}/src/mirall/")
include(GNUInstallDirs)
## stupid, we should upstream this
if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr")
if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr" AND NOT CMAKE_INSTALL_SYSCONFDIR)
set(CMAKE_INSTALL_SYSCONFDIR "/etc")
endif()
@@ -19,7 +25,7 @@ endif()
# BUILD_OWNCLOUD_OSX_BUNDLE was not initialized OR set to true on OSX
if(APPLE AND (NOT DEFINED BUILD_OWNCLOUD_OSX_BUNDLE OR BUILD_OWNCLOUD_OSX_BUNDLE))
set(BUILD_OWNCLOUD_OSX_BUNDLE ON)
set(OWNCLOUD_OSX_BUNDLE "owncloud.app")
set(OWNCLOUD_OSX_BUNDLE "${APPLICATION_EXECUTABLE}.app")
# BUILD_OWNCLOUD_OSX_BUNDLE was disabled on OSX
elseif(APPLE AND NOT BUILD_OWNCLOUD_OSX_BUNDLE)
@@ -34,22 +40,14 @@ endif()
find_package(Qt4 4.6.0 COMPONENTS QtCore QtGui QtXml QtNetwork QtTest REQUIRED )
find_package(Csync)
find_package(INotify)
find_package(Sphinx)
find_package(PdfLatex)
set(WITH_CSYNC CSYNC_FOUND)
set(USE_INOTIFY ${INOTIFY_FOUND})
configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
macro(add_tests)
foreach( loop_var ${ARGV} )
qt4_automoc(test${loop_var}.cpp)
add_executable(test${loop_var} test${loop_var}.cpp)
target_link_libraries(test${loop_var} ${QT_LIBRARIES} mirall_static)
add_test(test${loop_var} ${CMAKE_CURRENT_BINARY_DIR}/test${loop_var} --catch_system_errors=no)
endforeach( loop_var )
endmacro(add_tests)
set(CPACK_SOURCE_IGNORE_FILES
# hidden files
"/\\\\..+$"
@@ -71,9 +69,6 @@ set(CPACK_SOURCE_IGNORE_FILES
include(OwnCloudCPack.cmake)
include(CTest)
enable_testing()
#
# This cmake builds two targets (aka apps), mirall and owncloud. For the owncloud
# target, OWNCLOUD_CLIENT needs to be a compile flag. It is set in src/CMakeLists.txt
@@ -88,13 +83,16 @@ file( GLOB TRANS_FILES ${CMAKE_SOURCE_DIR}/translations/mirall_*.ts)
set(TRANSLATIONS ${TRANS_FILES})
add_subdirectory(src)
add_subdirectory(doc)
if(UNIT_TESTING)
include(CTest)
enable_testing()
add_subdirectory(test)
endif(UNIT_TESTING)
if(BUILD_OWNCLOUD_OSX_BUNDLE)
install( FILES exclude.lst DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources )
configure_file(sync-exclude.lst ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/sync-exclude.lst COPYONLY)
else()
install( FILES exclude.lst DESTINATION ${CMAKE_INSTALL_SYSCONFDIR} )
install( FILES sync-exclude.lst DESTINATION ${CMAKE_INSTALL_SYSCONFDIR} )
endif()

319
COPYING.documentation Normal file
View File

@@ -0,0 +1,319 @@
Creative Commons Legal Code
Attribution 3.0 Unported
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
DAMAGES RESULTING FROM ITS USE.
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
CONDITIONS.
1. Definitions
a. "Adaptation" means a work based upon the Work, or upon the Work and
other pre-existing works, such as a translation, adaptation,
derivative work, arrangement of music or other alterations of a
literary or artistic work, or phonogram or performance and includes
cinematographic adaptations or any other form in which the Work may be
recast, transformed, or adapted including in any form recognizably
derived from the original, except that a work that constitutes a
Collection will not be considered an Adaptation for the purpose of
this License. For the avoidance of doubt, where the Work is a musical
work, performance or phonogram, the synchronization of the Work in
timed-relation with a moving image ("synching") will be considered an
Adaptation for the purpose of this License.
b. "Collection" means a collection of literary or artistic works, such as
encyclopedias and anthologies, or performances, phonograms or
broadcasts, or other works or subject matter other than works listed
in Section 1(f) below, which, by reason of the selection and
arrangement of their contents, constitute intellectual creations, in
which the Work is included in its entirety in unmodified form along
with one or more other contributions, each constituting separate and
independent works in themselves, which together are assembled into a
collective whole. A work that constitutes a Collection will not be
considered an Adaptation (as defined above) for the purposes of this
License.
c. "Distribute" means to make available to the public the original and
copies of the Work or Adaptation, as appropriate, through sale or
other transfer of ownership.
d. "Licensor" means the individual, individuals, entity or entities that
offer(s) the Work under the terms of this License.
e. "Original Author" means, in the case of a literary or artistic work,
the individual, individuals, entity or entities who created the Work
or if no individual or entity can be identified, the publisher; and in
addition (i) in the case of a performance the actors, singers,
musicians, dancers, and other persons who act, sing, deliver, declaim,
play in, interpret or otherwise perform literary or artistic works or
expressions of folklore; (ii) in the case of a phonogram the producer
being the person or legal entity who first fixes the sounds of a
performance or other sounds; and, (iii) in the case of broadcasts, the
organization that transmits the broadcast.
f. "Work" means the literary and/or artistic work offered under the terms
of this License including without limitation any production in the
literary, scientific and artistic domain, whatever may be the mode or
form of its expression including digital form, such as a book,
pamphlet and other writing; a lecture, address, sermon or other work
of the same nature; a dramatic or dramatico-musical work; a
choreographic work or entertainment in dumb show; a musical
composition with or without words; a cinematographic work to which are
assimilated works expressed by a process analogous to cinematography;
a work of drawing, painting, architecture, sculpture, engraving or
lithography; a photographic work to which are assimilated works
expressed by a process analogous to photography; a work of applied
art; an illustration, map, plan, sketch or three-dimensional work
relative to geography, topography, architecture or science; a
performance; a broadcast; a phonogram; a compilation of data to the
extent it is protected as a copyrightable work; or a work performed by
a variety or circus performer to the extent it is not otherwise
considered a literary or artistic work.
g. "You" means an individual or entity exercising rights under this
License who has not previously violated the terms of this License with
respect to the Work, or who has received express permission from the
Licensor to exercise rights under this License despite a previous
violation.
h. "Publicly Perform" means to perform public recitations of the Work and
to communicate to the public those public recitations, by any means or
process, including by wire or wireless means or public digital
performances; to make available to the public Works in such a way that
members of the public may access these Works from a place and at a
place individually chosen by them; to perform the Work to the public
by any means or process and the communication to the public of the
performances of the Work, including by public digital performance; to
broadcast and rebroadcast the Work by any means including signs,
sounds or images.
i. "Reproduce" means to make copies of the Work by any means including
without limitation by sound or visual recordings and the right of
fixation and reproducing fixations of the Work, including storage of a
protected performance or phonogram in digital form or other electronic
medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce,
limit, or restrict any uses free from copyright or rights arising from
limitations or exceptions that are provided for in connection with the
copyright protection under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License,
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
perpetual (for the duration of the applicable copyright) license to
exercise the rights in the Work as stated below:
a. to Reproduce the Work, to incorporate the Work into one or more
Collections, and to Reproduce the Work as incorporated in the
Collections;
b. to create and Reproduce Adaptations provided that any such Adaptation,
including any translation in any medium, takes reasonable steps to
clearly label, demarcate or otherwise identify that changes were made
to the original Work. For example, a translation could be marked "The
original work was translated from English to Spanish," or a
modification could indicate "The original work has been modified.";
c. to Distribute and Publicly Perform the Work including as incorporated
in Collections; and,
d. to Distribute and Publicly Perform Adaptations.
e. For the avoidance of doubt:
i. Non-waivable Compulsory License Schemes. In those jurisdictions in
which the right to collect royalties through any statutory or
compulsory licensing scheme cannot be waived, the Licensor
reserves the exclusive right to collect such royalties for any
exercise by You of the rights granted under this License;
ii. Waivable Compulsory License Schemes. In those jurisdictions in
which the right to collect royalties through any statutory or
compulsory licensing scheme can be waived, the Licensor waives the
exclusive right to collect such royalties for any exercise by You
of the rights granted under this License; and,
iii. Voluntary License Schemes. The Licensor waives the right to
collect royalties, whether individually or, in the event that the
Licensor is a member of a collecting society that administers
voluntary licensing schemes, via that society, from any exercise
by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now
known or hereafter devised. The above rights include the right to make
such modifications as are technically necessary to exercise the rights in
other media and formats. Subject to Section 8(f), all rights not expressly
granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made
subject to and limited by the following restrictions:
a. You may Distribute or Publicly Perform the Work only under the terms
of this License. You must include a copy of, or the Uniform Resource
Identifier (URI) for, this License with every copy of the Work You
Distribute or Publicly Perform. You may not offer or impose any terms
on the Work that restrict the terms of this License or the ability of
the recipient of the Work to exercise the rights granted to that
recipient under the terms of the License. You may not sublicense the
Work. You must keep intact all notices that refer to this License and
to the disclaimer of warranties with every copy of the Work You
Distribute or Publicly Perform. When You Distribute or Publicly
Perform the Work, You may not impose any effective technological
measures on the Work that restrict the ability of a recipient of the
Work from You to exercise the rights granted to that recipient under
the terms of the License. This Section 4(a) applies to the Work as
incorporated in a Collection, but this does not require the Collection
apart from the Work itself to be made subject to the terms of this
License. If You create a Collection, upon notice from any Licensor You
must, to the extent practicable, remove from the Collection any credit
as required by Section 4(b), as requested. If You create an
Adaptation, upon notice from any Licensor You must, to the extent
practicable, remove from the Adaptation any credit as required by
Section 4(b), as requested.
b. If You Distribute, or Publicly Perform the Work or any Adaptations or
Collections, You must, unless a request has been made pursuant to
Section 4(a), keep intact all copyright notices for the Work and
provide, reasonable to the medium or means You are utilizing: (i) the
name of the Original Author (or pseudonym, if applicable) if supplied,
and/or if the Original Author and/or Licensor designate another party
or parties (e.g., a sponsor institute, publishing entity, journal) for
attribution ("Attribution Parties") in Licensor's copyright notice,
terms of service or by other reasonable means, the name of such party
or parties; (ii) the title of the Work if supplied; (iii) to the
extent reasonably practicable, the URI, if any, that Licensor
specifies to be associated with the Work, unless such URI does not
refer to the copyright notice or licensing information for the Work;
and (iv) , consistent with Section 3(b), in the case of an Adaptation,
a credit identifying the use of the Work in the Adaptation (e.g.,
"French translation of the Work by Original Author," or "Screenplay
based on original Work by Original Author"). The credit required by
this Section 4 (b) may be implemented in any reasonable manner;
provided, however, that in the case of a Adaptation or Collection, at
a minimum such credit will appear, if a credit for all contributing
authors of the Adaptation or Collection appears, then as part of these
credits and in a manner at least as prominent as the credits for the
other contributing authors. For the avoidance of doubt, You may only
use the credit required by this Section for the purpose of attribution
in the manner set out above and, by exercising Your rights under this
License, You may not implicitly or explicitly assert or imply any
connection with, sponsorship or endorsement by the Original Author,
Licensor and/or Attribution Parties, as appropriate, of You or Your
use of the Work, without the separate, express prior written
permission of the Original Author, Licensor and/or Attribution
Parties.
c. Except as otherwise agreed in writing by the Licensor or as may be
otherwise permitted by applicable law, if You Reproduce, Distribute or
Publicly Perform the Work either by itself or as part of any
Adaptations or Collections, You must not distort, mutilate, modify or
take other derogatory action in relation to the Work which would be
prejudicial to the Original Author's honor or reputation. Licensor
agrees that in those jurisdictions (e.g. Japan), in which any exercise
of the right granted in Section 3(b) of this License (the right to
make Adaptations) would be deemed to be a distortion, mutilation,
modification or other derogatory action prejudicial to the Original
Author's honor and reputation, the Licensor will waive or not assert,
as appropriate, this Section, to the fullest extent permitted by the
applicable national law, to enable You to reasonably exercise Your
right under Section 3(b) of this License (right to make Adaptations)
but not otherwise.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
a. This License and the rights granted hereunder will terminate
automatically upon any breach by You of the terms of this License.
Individuals or entities who have received Adaptations or Collections
from You under this License, however, will not have their licenses
terminated provided such individuals or entities remain in full
compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
survive any termination of this License.
b. Subject to the above terms and conditions, the license granted here is
perpetual (for the duration of the applicable copyright in the Work).
Notwithstanding the above, Licensor reserves the right to release the
Work under different license terms or to stop distributing the Work at
any time; provided, however that any such election will not serve to
withdraw this License (or any other license that has been, or is
required to be, granted under the terms of this License), and this
License will continue in full force and effect unless terminated as
stated above.
8. Miscellaneous
a. Each time You Distribute or Publicly Perform the Work or a Collection,
the Licensor offers to the recipient a license to the Work on the same
terms and conditions as the license granted to You under this License.
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
offers to the recipient a license to the original Work on the same
terms and conditions as the license granted to You under this License.
c. If any provision of this License is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this License, and without further action
by the parties to this agreement, such provision shall be reformed to
the minimum extent necessary to make such provision valid and
enforceable.
d. No term or provision of this License shall be deemed waived and no
breach consented to unless such waiver or consent shall be in writing
and signed by the party to be charged with such waiver or consent.
e. This License constitutes the entire agreement between the parties with
respect to the Work licensed here. There are no understandings,
agreements or representations with respect to the Work not specified
here. Licensor shall not be bound by any additional provisions that
may appear in any communication from You. This License may not be
modified without the mutual written agreement of the Licensor and You.
f. The rights granted under, and the subject matter referenced, in this
License were drafted utilizing the terminology of the Berne Convention
for the Protection of Literary and Artistic Works (as amended on
September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
and the Universal Copyright Convention (as revised on July 24, 1971).
These rights and subject matter take effect in the relevant
jurisdiction in which the License terms are sought to be enforced
according to the corresponding provisions of the implementation of
those treaty provisions in the applicable national law. If the
standard suite of rights granted under applicable copyright law
includes additional rights not granted under this License, such
additional rights are deemed to be included in the License; this
License is not intended to restrict the license of any rights under
applicable law.
Creative Commons Notice
Creative Commons is not a party to this License, and makes no warranty
whatsoever in connection with the Work. Creative Commons will not be
liable to You or any party on any legal theory for any damages
whatsoever, including without limitation any general, special,
incidental or consequential damages arising in connection to this
license. Notwithstanding the foregoing two (2) sentences, if Creative
Commons has expressly identified itself as the Licensor hereunder, it
shall have all rights and obligations of Licensor.
Except for the limited purpose of indicating to the public that the
Work is licensed under the CCPL, Creative Commons does not authorize
the use by either party of the trademark "Creative Commons" or any
related trademark or logo of Creative Commons without the prior
written consent of Creative Commons. Any permitted use will be in
compliance with Creative Commons' then-current trademark usage
guidelines, as may be published on its website or otherwise made
available upon request from time to time. For the avoidance of doubt,
this trademark restriction does not form part of this License.
Creative Commons may be contacted at http://creativecommons.org/.

View File

@@ -10,6 +10,11 @@ endif(CPACK_GENERATOR MATCHES "NSIS")
set( CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@ )
set( CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@ )
if ( EXISTS "${CMAKE_SOURCE_DIR}/OEM.cmake" )
include ( "${CMAKE_SOURCE_DIR}/OEM.cmake" )
else ()
include ( "${CMAKE_SOURCE_DIR}/OWNCLOUD.cmake" )
endif()
set( CSYNC_BINARY_DIR @CSYNC_BINARY_DIR@ )
set( MINGW_ROOT @CMAKE_FIND_ROOT_PATH@ )
@@ -19,8 +24,8 @@ if(CSYNC_BINARY_DIR)
set( CSYNC_CONFIG_DIR "${CSYNC_BINARY_DIR}/config" )
else()
set( CSYNC_LIBRARY_DIR "${MINGW_ROOT}/bin" )
set( CSYNC_PLUGIN_DIR "${MINGW_ROOT}/bin/csync-0" ) #FIXME: whatever it is
set( CSYNC_CONFIG_DIR "${MINGW_ROOT}/etc/csync" )
set( CSYNC_PLUGIN_DIR "${MINGW_ROOT}/plugins-0" ) #FIXME: whatever it is
set( CSYNC_CONFIG_DIR "${MINGW_ROOT}/etc/ocsync" )
endif()
set( BUILD_OWNCLOUD_OSX_BUNDLE @BUILD_OWNCLOUD_OSX_BUNDLE@)
if(APPLE AND NOT BUILD_OWNCLOUD_OSX_BUNDLE)

View File

@@ -1,7 +1,61 @@
ChangeLog
=========
version 1.1.0 (release ), csync 0.60.0 required
*
version 1.1.2 (release 2012-11- ), csync 0.60.2 required
* [Fixes] Allow to properly cancel the password dialog.
* [Fixes] Share folder name correctly percent encoded with old Qt
4.6 builds ie. Debian.
* [Fixes] If local sync dir is not existing, create it.
* [Fixes] lots of other minor fixes.
* [GUI] Display error messages in status dialog.
* [GUI] GUI fixes for the connection wizard.
* [GUI] Show username for connection in statusdialog.
* [GUI] Show intro wizard on new connection setup.
* [APP] Use CredentialStore to better support various credential
backends.
* [APP] Handle missing local folder more robust: Create it if
missing instead of ignoring.
* [APP] Simplify treewalk code.
* [Platform] Fix Mac building
version 1.1.1 (release 2012-10-18), csync 0.60.1 required
* [GUI] Allow changing folder name in single folder mode
* [GUI] Windows: Add license to installer
* [GUI] owncloud --logwindow will bring up the log window
in an already running instance
* [Fixes] Make sure SSL errors are always handled
* [Fixes] Allow special characters in folder alias
* [Fixes] Proper workaround for Menu bug in Ubuntu
* [Fixes] csync: Fix improper memory cleanup which could
cause memory leaks and crashes
* [Fixes] csync: Fix memory leak
* [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)
on Windows, reliability fixes across all OSes.
* [Fixes] Url entry field in setup assistant handles http/https correctly.
* [Fixes] Button enable state in status dialog.
* [Fixes] Crash fixed on ending the client, tray icon related.
* [Fixes] Crash through wrong delete operator.
* [MacOS] behave correctly on retina displays.
* [MacOS] fix focus policy.
* [MacOS] Packaging improvements.
* [MacOS] Packaging improvements.
* [Platform] Windows: Setup closes client prior to uninstall.
* [Platform] Windows: ownCloud gets added to autorun by default.
* [Platform] insert correct version info from cmake.
* [Platform] csync conf file and database were moved to the users app data
directory, away from the .csync dir.
* Renamed exclude.lst to sync-exclude.lst and moved it to
/etc/appName()/ for more clean packaging. From the user path,
still exclude.lst is read if sync-exclude.lst is not existing.
* Placed custom.ini with customization options to /etc/appName()
version 1.0.5 (release 2012-08-14), csync 0.50.8 required
* [Fixes] Fixed setup dialog: Really use https if checkbox is activated.

7
OWNCLOUD.cmake Normal file
View File

@@ -0,0 +1,7 @@
set( APPLICATION_SHORTNAME "owncloud" )
set( APPLICATION_NAME "ownCloud" )
set( APPLICATION_EXECUTABLE "owncloud" )
set( APPLICATION_DOMAIN "owncloud.org" )
set( APPLICATION_VENDOR "ownCloud.org" )
set( THEME_CLASS "ownCloudTheme" )
set( APPLICATION_REV_DOMAIN "org.owncloud.desktopclient" )

View File

@@ -2,7 +2,11 @@ include( InstallRequiredSystemLibraries )
set( CPACK_PACKAGE_CONTACT "Dominik Schmidt <domme@tomahawk-player.org>" )
set( APPLICATION_NAME "ownCloud Client")
if ( EXISTS "${CMAKE_SOURCE_DIR}/OEM.cmake" )
include ( "${CMAKE_SOURCE_DIR}/OEM.cmake" )
else ()
include ( "${CMAKE_SOURCE_DIR}/OWNCLOUD.cmake" )
endif()
include( VERSION.cmake )
set( CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR} )
@@ -13,11 +17,11 @@ set( CPACK_PACKAGE_VERSION ${VERSION} )
if(APPLE)
set( CPACK_GENERATOR "DragNDrop" )
set( CPACK_SOURCE_GENERATOR "")
set( CPACK_PACKAGE_FILE_NAME ownCloudClientSetup-${CPACK_PACKAGE_VERSION} )
set( CPACK_PACKAGE_FILE_NAME ${APPLICATION_NAME}-${CPACK_PACKAGE_VERSION} )
set( CPACK_PACKAGE_ICON ${CMAKE_BINARY_DIR}/src/ownCloud.icns)
set( CPACK_DMG_DS_STORE "${CMAKE_SOURCE_DIR}/admin/osx/DS_Store.in")
set( CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/admin/osx/DMGBackground.png" )
# set( CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/admin/osx/DMGBackground.png" )
set( CPACK_DMG_FORMAT "UDBZ" )
set( CPACK_DMG_VOLUME_NAME "${APPLICATION_NAME}")
@@ -35,7 +39,7 @@ endif()
if(WIN32)
set( CPACK_PACKAGE_FILE_NAME owncloud-client-${CPACK_PACKAGE_VERSION}-setup )
set( CPACK_PACKAGE_FILE_NAME ${APPLICATION_SHORTNAME}-${CPACK_PACKAGE_VERSION}-setup )
# Package file name without extension. Also a directory of installer cmake-2.5.0-Linux-i686
# CPACK_GENERATOR CPack generator to be used STGZ;TGZ;TZ
# 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

View File

@@ -47,9 +47,7 @@ files or hang your computer.
### openSUSE
* 1-click install available in software.opensuse.org
http://software.opensuse.org/search?q=mirall&baseproject=ALL&lang=en&include_home=true&exclude_debug=true
* Refer to the download page http://owncloud.org/sync-clients/
### Source code
@@ -74,6 +72,8 @@ To generate a tarball:
## Authors
* Duncan Mac-Vicar P. <duncan@kde.org>
* Klaas Freitag <freitag@owncloud.com>
* Daniel Molkentin <danimo@owncloud.com>
## License

View File

@@ -1,5 +1,5 @@
set( VERSION_MAJOR 1 )
set( VERSION_MINOR 1 )
set( VERSION_PATCH 0 )
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}beta1 )
set( VERSION_PATCH 2 )
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}rc )

20
admin/osx/sign_dmg.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/sh -x
[ "$#" -lt 2 ] && echo "Usage: sign_dmg.sh <dmg> <identity>" && exit
src_dmg=$1
tmp_dmg=writable_$1
signed_dmg=signed_$1
identity=$2
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
pushd $mount
codesign -s "$identity" $mount/*.app
popd
diskutil eject $mount
test -e $signed_dmg && rm -rf $signed_dmg
hdiutil convert $tmp_dmg -format UDBZ -o $signed_dmg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -1,21 +0,0 @@
[Settings]
NumFields=3
[Field 1]
Type=Label
Left=0
Right=-1
Top=0
Bottom=24
[Field 2]
Type=RadioButton
Left=30
Right=-1
Top=50
Bottom=58
State=1
[Field 3]
Type=RadioButton
Left=30
Right=-1
Top=70
Bottom=78

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

View File

@@ -1,17 +1,20 @@
IF(EXISTS "${CMAKE_SOURCE_DIR}/../csync/src/csync.h")
SET(CSYNC_INCLUDE_PATH ${CMAKE_SOURCE_DIR}/../csync/src/)
ELSE()
FIND_PATH(CSYNC_INCLUDE_PATH NAMES csync/csync.h csync.h HINTS $ENV{CSYNC_DIR} )
FIND_PATH(CSYNC_INCLUDE_PATH NAMES csync.h HINTS $ENV{CSYNC_DIR} )
ENDIF()
IF(EXISTS "${CMAKE_SOURCE_DIR}/../buildcsync/src/")
IF( DEFINED CSYNC_LIBRARY_PATH AND DEFINED CSYNC_INCLUDE_PATH )
IF( WIN32 )
SET(CSYNC_LIBRARY ${CMAKE_SOURCE_DIR}/../win/buildcsync/src/libcsync.dll)
ELSE( WIN32 )
SET(CSYNC_LIBRARY ${CMAKE_SOURCE_DIR}/../buildcsync/src/libcsync.so)
ENDIF( WIN32 )
SET(CSYNC_LIBRARY ${CSYNC_LIBRARY_PATH}/src/libocsync.dll)
ELSEIF ( APPLE )
SET(CSYNC_LIBRARY ${CSYNC_LIBRARY_PATH}/src/libocsync.dylib)
ELSE()
SET(CSYNC_LIBRARY ${CSYNC_LIBRARY_PATH}/src/libocsync.so)
ENDIF( )
SET(CSYNC_BINARY_DIR ${CSYNC_LIBRARY_PATH})
ELSE()
FIND_LIBRARY(CSYNC_LIBRARY NAMES csync HINTS $ENV{CSYNC_DIR})
FIND_LIBRARY(CSYNC_LIBRARY NAMES ocsync HINTS $ENV{CSYNC_DIR})
ENDIF()
SET(CSYNC_INCLUDE_DIR ${CSYNC_INCLUDE_PATH})

View File

@@ -0,0 +1,16 @@
find_program(PDFLATEX_EXECUTABLE NAMES pdflatex
HINTS
$ENV{PDFLATEX_DIR}
PATH_SUFFIXES bin
DOC "PDF LaTeX"
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PdfLatex DEFAULT_MSG
PDFLATEX_EXECUTABLE
)
mark_as_advanced(
PDFLATEX_EXECUTABLE
)

View File

@@ -0,0 +1,16 @@
find_program(SPHINX_EXECUTABLE NAMES sphinx-build
HINTS
$ENV{SPHINX_DIR}
PATH_SUFFIXES bin
DOC "Sphinx documentation generator"
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Sphinx DEFAULT_MSG
SPHINX_EXECUTABLE
)
mark_as_advanced(
SPHINX_EXECUTABLE
)

View File

@@ -2,35 +2,31 @@
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>LSUIElement</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>owncloud</string>
<key>CFBundleGetInfoString</key>
<string></string>
<string>@APPLICATION_EXECUTABLE@</string>
<key>CFBundleIconFile</key>
<string>ownCloud.icns</string>
<key>CFBundleIdentifier</key>
<string>org.owncloud</string>
<string>@APPLICATION_REV_DOMAIN@</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>owncloud FIXME</string>
<key>CFBundleName</key>
<string>owncloudBundleName</string>
<string>@APPLICATION_NAME@ @VERSION@</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0 FIXME</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>owncloud FIXME 0.1.0</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSUIElement</key>
<true/>
<string>@VERSION@</string>
<key>CFBundleShortVersionString</key>
<string>@VERSION@</string>
<key>NSHumanReadableCopyright</key>
<string>2012 owncloud.org</string>
<string>(C) 2012 @APPLICATION_VENDOR@</string>
</dict>
</plist>

View File

@@ -1,8 +1,11 @@
;ownCloud installer script.
!define APPLICATION_NAME ownCloud
!define APPLICATION_EXECUTABLE owncloud.exe
!define APPLICATION_DOMAIN owncloud.com
!define APPLICATION_SHORTNAME "@APPLICATION_SHORTNAME@"
!define APPLICATION_NAME "@APPLICATION_NAME@"
!define APPLICATION_VENDOR "@APPLICATION_VENDOR@"
!define APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@.exe"
!define APPLICATION_DOMAIN "@APPLICATION_DOMAIN@"
!define APPLICATION_LICENSE "@APPLICATION_LICENSE@"
!define MUI_FINISHPAGE_LINK_LOCATION "http://www.${APPLICATION_DOMAIN}"
@@ -10,11 +13,14 @@
;-----------------------------------------------------------------------------
; Some installer script options (comment-out options not required)
;-----------------------------------------------------------------------------
;!define OPTION_LICENSE_AGREEMENT
!if "@APPLICATION_LICENSE@" != ""
!define OPTION_LICENSE_AGREEMENT
!endif
!define OPTION_UAC_PLUGIN_ENHANCED
!define OPTION_SECTION_SC_START_MENU
!define OPTION_SECTION_SC_DESKTOP
!define OPTION_SECTION_SC_QUICK_LAUNCH
!define OPTION_SECTION_SC_AUTOSTART
!define OPTION_FINISHPAGE
!define OPTION_FINISHPAGE_LAUNCHER
; !define OPTION_FINISHPAGE_RELEASE_NOTES
@@ -37,7 +43,7 @@
!define CSYNC_PLUGIN_DIR "@CSYNC_PLUGIN_DIR@"
!define CSYNC_CONFIG_DIR "@CSYNC_CONFIG_DIR@"
!define NSI_PATH "${SOURCE_PATH}/admin/win/nsi"
!define NSI_PATH "${source_path}/admin/win/nsi"
;-----------------------------------------------------------------------------
; Installer version
@@ -57,7 +63,7 @@
; Initial installer setup and definitions.
;-----------------------------------------------------------------------------
Name "@CPACK_NSIS_PACKAGE_NAME@"
Caption "${APPLICATION_NAME} Installer"
Caption "${APPLICATION_NAME} Setup"
BrandingText "${APPLICATION_NAME} ${VERSION} -- ${BUILD_TIME}"
OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
InstallDir "$PROGRAMFILES\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
@@ -89,7 +95,7 @@ ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
; Memento selections stored in registry.
;-----------------------------------------------------------------------------
!define MEMENTO_REGISTRY_ROOT HKLM
!define MEMENTO_REGISTRY_KEY Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}
!define MEMENTO_REGISTRY_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}"
;-----------------------------------------------------------------------------
; Modern User Interface (MUI) defintions and setup.
@@ -97,13 +103,13 @@ ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
!define MUI_ABORTWARNING
!define MUI_ICON ${NSI_PATH}\installer.ico
!define MUI_UNICON ${NSI_PATH}\installer.ico
!define MUI_WELCOMEFINISHPAGE_BITMAP ${NSI_PATH}\welcome_oc.bmp
!define MUI_WELCOMEPAGE_TITLE "@CPACK_PACKAGE_NAME@ ${VERSION} Setup$\r$\nInstaller"
!define MUI_WELCOMEFINISHPAGE_BITMAP ${NSI_PATH}\welcome_${APPLICATION_SHORTNAME}.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 ${NSI_PATH}\page_header_oc.bmp
!define MUI_HEADERIMAGE_BITMAP ${NSI_PATH}\page_header_${APPLICATION_SHORTNAME}.bmp
!define MUI_COMPONENTSPAGE_SMALLDESC
!define MUI_FINISHPAGE_TITLE "@CPACK_PACKAGE_NAME@ Install Completed"
!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_NOREBOOTSUPPORT
!ifdef OPTION_FINISHPAGE_RELEASE_NOTES
@@ -122,7 +128,7 @@ ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
;-----------------------------------------------------------------------------
!insertmacro MUI_PAGE_WELCOME
!ifdef OPTION_LICENSE_AGREEMENT
!insertmacro MUI_PAGE_LICENSE "LICENSE.txt"
!insertmacro MUI_PAGE_LICENSE "${source_path}/${APPLICATION_LICENSE}"
!endif
Page custom PageReinstall PageLeaveReinstall
!insertmacro MUI_PAGE_COMPONENTS
@@ -264,7 +270,7 @@ FunctionEnd
# INSTALLER SECTIONS #
# #
##############################################################################
Section "${APPLICATION_NAME}" SEC_OWNCLOUD_PLAYER
Section "${APPLICATION_NAME}" SEC_OWNCLOUD
SectionIn 1 2 3 RO
SetDetailsPrint listonly
@@ -302,7 +308,7 @@ Section "${APPLICATION_NAME}" SEC_OWNCLOUD_PLAYER
; FIXME: fix installation dir of module, currently needs manual copying to
; /usr/i686-w64-mingw32/sys-root/mingw/bin/csync_modules/
File "${CSYNC_PLUGIN_DIR}/csync_owncloud.dll"
File "${CSYNC_PLUGIN_DIR}/ocsync_owncloud.dll"
SetOutPath "$INSTDIR"
!endif
@@ -318,7 +324,7 @@ Section "${APPLICATION_NAME}" SEC_OWNCLOUD_PLAYER
File "${QT_DLL_PATH}\QtNetwork4.dll"
File "${QT_DLL_PATH}\QtXml4.dll"
File "${CSYNC_LIBRARY_DIR}/libcsync.dll"
File "${CSYNC_LIBRARY_DIR}/libocsync.dll"
File "${MING_BIN}\libsqlite3-0.dll"
File "${MING_BIN}\libiniparser.dll"
File "${MING_BIN}\libdl.dll"
@@ -347,8 +353,8 @@ Section "${APPLICATION_NAME}" SEC_OWNCLOUD_PLAYER
File "${MING_BIN}\libssl-8.dll"
; CSync configs
File "${CSYNC_CONFIG_DIR}/csync.conf"
File "${SOURCE_PATH}/exclude.lst"
File "${CSYNC_CONFIG_DIR}/ocsync.conf"
File "${SOURCE_PATH}/sync-exclude.lst"
SectionEnd
@@ -356,7 +362,7 @@ SectionGroup "Shortcuts"
!ifdef OPTION_SECTION_SC_START_MENU
${MementoSection} "Start Menu Program Group" SEC_START_MENU
SectionIn 1 2
SectionIn 1 2 3
SetDetailsPrint textonly
DetailPrint "Adding shortcuts for the ${APPLICATION_NAME} program group to the Start Menu."
SetDetailsPrint listonly
@@ -393,15 +399,27 @@ SectionGroup "Shortcuts"
SectionGroupEnd
!ifdef OPTION_SECTION_SC_AUTOSTART
${MementoSection} "Autostart" SEC_AUTOSTART
SectionIn 1 2
SetDetailsPrint textonly
DetailPrint "Creating Windows Start Entry"
SetDetailsPrint listonly
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Run" \
"${APPLICATION_NAME}" "$INSTDIR\${APPLICATION_EXECUTABLE}"
${MementoSectionEnd}
!endif
${MementoSectionDone}
; Installer section descriptions
;--------------------------------
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_APPLICATION} "${APPLICATION_NAME} essentials."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_START_MENU} "{APPLICATION_NAME} program group."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP} "Desktop shortcut for {APPLICATION_NAME}."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_QUICK_LAUNCH} "Quick Launch shortcut for {APPLICATION_NAME}."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_START_MENU} "${APPLICATION_NAME} program group."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP} "Desktop shortcut for ${APPLICATION_NAME}."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_QUICK_LAUNCH} "Quick Launch shortcut for ${APPLICATION_NAME}."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_QUICK_AUTOSTART} "Register ${APPLICATION_NAME} to run on Windows startup."
!insertmacro MUI_FUNCTION_DESCRIPTION_END
Section -post
@@ -428,7 +446,7 @@ Section -post
WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}" "UninstallString" '"$INSTDIR\Uninstall.exe"'
WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}" "InstallLocation" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}" "DisplayName" "${APPLICATION_NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}" "Publisher" "${APPLICATION_DOMAIN}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}" "Publisher" "${APPLICATION_VENDOR}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}" "DisplayIcon" "$INSTDIR\Uninstall.exe,0"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}" "DisplayVersion" "${VERSION}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}" "VersionMajor" "${VER_MAJOR}"
@@ -440,7 +458,7 @@ Section -post
SetDetailsPrint textonly
DetailPrint "Finsihed."
DetailPrint "Finished."
SectionEnd
##############################################################################
@@ -455,7 +473,7 @@ Var UnPageUserAppDataCheckbox_State
Var UnPageUserAppDataEditBox
Function un.UnPageUserAppData
!insertmacro MUI_HEADER_TEXT "Uninstall ${APPLICATION_DOMAIN}" "Remove ${APPLICATION_DOMAIN}'s data folder from your computer."
!insertmacro MUI_HEADER_TEXT "Uninstall ${APPLICATION_NAME}" "Remove ${APPLICATION_NAME}'s data folder from your computer."
nsDialogs::Create /NOUNLOAD 1018
Pop $UnPageUserAppDataDialog
@@ -463,10 +481,10 @@ Function un.UnPageUserAppData
Abort
${EndIf}
${NSD_CreateLabel} 0 0 100% 12u "Do you want to delete ${APPLICATION_DOMAIN}'s data folder?"
${NSD_CreateLabel} 0 0 100% 12u "Do you want to delete ${APPLICATION_NAME}'s data folder?"
Pop $0
${NSD_CreateText} 0 13u 100% 12u "$LOCALAPPDATA\${APPLICATION_DOMAIN}"
${NSD_CreateText} 0 13u 100% 12u "$LOCALAPPDATA\${APPLICATION_NAME}"
Pop $UnPageUserAppDataEditBox
SendMessage $UnPageUserAppDataEditBox ${EM_SETREADONLY} 1 0
@@ -483,6 +501,10 @@ Function un.UnPageUserAppDataLeave
${NSD_GetState} $UnPageUserAppDataCheckbox $UnPageUserAppDataCheckbox_State
FunctionEnd
Function un.EnsureOwncloudShutdown
!insertmacro CheckAndConfirmEndProcess "${APPLICATION_EXECUTABLE}"
FunctionEnd
Section Uninstall
IfFileExists "$INSTDIR\${APPLICATION_EXECUTABLE}" owncloud_installed
MessageBox MB_YESNO "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?" IDYES owncloud_installed
@@ -500,6 +522,11 @@ Section Uninstall
DeleteRegKey HKCR "${APPLICATION_NAME}"
;Windows Start entry
!ifdef OPTION_SECTION_SC_AUTOSTART
DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "${APPLICATION_NAME}"
!endif
;Start menu shortcuts.
!ifdef OPTION_SECTION_SC_START_MENU
SetShellVarContext all
@@ -528,7 +555,7 @@ Section Uninstall
${EndIf}
SetDetailsPrint textonly
DetailPrint "Finsihed."
DetailPrint "Finshed."
SectionEnd
##############################################################################
@@ -629,6 +656,9 @@ Function un.onInit
StrCmp $R0 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION "This uninstaller is already running."
Abort
;Shutdown ${APPLICATION_NAME} in order to remove locked files.
Call un.EnsureOwncloudShutdown
FunctionEnd
Function un.onUnInstSuccess

View File

@@ -1,4 +1,8 @@
#ifndef CONFIG_H
#define CONFIG_H
#cmakedefine USE_INOTIFY 1
#cmakedefine WITH_CSYNC 1
#cmakedefine THEME_CLASS @THEME_CLASS@
#endif

61
doc/CMakeLists.txt Normal file
View File

@@ -0,0 +1,61 @@
if(SPHINX_FOUND)
# Sphinx cache with pickled ReST documents
set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees")
# HTML output directory
set(SPHINX_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/html")
set(SPHINX_MAN_DIR "${CMAKE_CURRENT_BINARY_DIR}/man")
set(SPHINX_PDF_DIR "${CMAKE_CURRENT_BINARY_DIR}/latex")
set(SPHINX_QCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/qthelp")
set(SPHINX_HTMLHELP_DIR "${CMAKE_CURRENT_BINARY_DIR}/htmlhelp")
set(MSHTML_COMPILER wine 'C:\\Program Files\\HTML Help Workshop\\hhc.exe')
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(PDFLATEX_FOUND)
# if this still fails on Debian/Ubuntu, run
# apt-get install texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended
add_custom_target(doc-latex ${SPHINX_EXECUTABLE}
-q -c . -b latex
-d ${SPHINX_CACHE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_PDF_DIR} )
add_custom_target(doc-pdf make -C ${SPHINX_PDF_DIR} all-pdf
DEPENDS doc-latex )
add_dependencies(doc doc-pdf)
endif(PDFLATEX_FOUND)
if (EXISTS ${QT_QCOLLECTIONGENERATOR_EXECUTABLE})
add_custom_target( doc-qch-sphinx ${SPHINX_EXECUTABLE}
-q -c . -b qthelp
-d ${SPHINX_CACHE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_QCH_DIR} )
add_custom_target( doc-qch ${QT_QCOLLECTIONGENERATOR_EXECUTABLE}
${SPHINX_QCH_DIR}/*.qhcp
DEPENDS doc-qch-sphinx )
add_dependencies(doc doc-qch)
endif()
add_custom_target( doc-html ${SPHINX_EXECUTABLE}
-q -c . -b html
-d ${SPHINX_CACHE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_HTML_DIR} )
add_custom_target( doc-man ${SPHINX_EXECUTABLE}
-q -c . -b man
-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
## doc/scripts/htmlhelp.exe to install them and run this target
## explicitly.
add_custom_target( doc-chm-sphinx ${SPHINX_EXECUTABLE}
-q -c . -b htmlhelp
-D html_theme=basic
-d ${SPHINX_CACHE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_HTMLHELP_DIR} )
add_custom_target( doc-chm pushd ${SPHINX_HTMLHELP_DIR}; ${MSHTML_COMPILER} *.hhp; popd
DEPENDS doc-chm-sphinx )
endif(SPHINX_FOUND)

153
doc/Makefile Normal file
View File

@@ -0,0 +1,153 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OwncloudDocumentation.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OwncloudDocumentation.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/OwncloudDocumentation"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OwncloudDocumentation"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

108
doc/architecture.rst Normal file
View File

@@ -0,0 +1,108 @@
Architecture
============
.. index:: architecture
The ownCloud project provides desktop sync clients to synchronize the
contents of local directories on the desktop machines to the ownCloud.
The syncing is done with csync_, a bidirectional file synchronizing tool which
provides both a command line client as well as a library. A special module for
csync was written to synchronize with ownClouds built-in WebDAV server.
The ownCloud sync client is based on a tool called mirall initially written by
Duncan Mac Vicar. Later Klaas Freitag joined the project and enhanced it to work
with ownCloud server. Both mirall and ownCloud Client (oCC) build from the same
source, currently hosted in the ownCloud source repo on gitorious.
oCC is written in C++ using the `Qt Framework`_. As a result oCC runs on the
three important platforms Linux, Windows and MacOS.
.. _csync: http://www.csync.org
.. _`Qt Framework`: http://www.qt-project.org
The Sync Process
----------------
First it is important to recall what syncing is. Syncing tries to keep the files
on both repositories the same. That means if a file is added to one repository
it is going to be copied to the other repository. If a file is changed on one
repository, the change is propagated to the other repository. Also, if a file
is deleted on one side, it is deleted on the other. As a matter of fact, in
ownCloud syncing we do not have a typical client/server system where the
server is always master.
This is the major difference to other systems like a file backup where just
changes and new files are propagated but files never get deleted.
Sync Direction and Strategies
-----------------------------
.. index:: time stamps, file times, etag, unique id
Until the release of ownCloud 4.5 and ownCloud Client 1.1, ownCloud employed
a single file property to decide which file is newer and hence needs to be
synced to the other repository: the files modification time.
The *modification timestamp* is part of the files metadata. It is available on
every relevant filesystem and is the natural indicator for a file change.
modification timestamps do not require special action to create and have
a general meaning. One design goal of csync is to not require a special server
component, thats why it was chosen as the backend component.
To compare the modification times of two files from different systems,
it is needed to operate on the same base. Before version 1.1.0,
csync requires both sides running on the exact same time, which can
be achieved through enterprise standard `NTP time synchronisation`_ on all
machines.
Since this strategy is rather fragile without NTP, ownCloud 4.5 introduced a
unique number, which changes whenever the file changes. Although it is a unique
value, it is not a hash of the file, but a randomly chosen number, which it will
transmit in the Etag_ field. The client will store this number in a
per-directory database, located in the application directory (version 1.1) or
as a hidden file right in the directory to be synced (later versions).
Since the file number is guaranteed to change if the file changes, it can now be
used to determine if one of the files has changed.
.. todo:: describe what happens if both sides change
If the per-directory database gets removed, oCC's CSync backend will fall back
to a time-stamp based sync process to rebuild the database. Thus it should be
made sure that both server and client synchronized to NTP time before
restarting the client after a database removal. If time deviates, the sync
process might create faux conflict files, which only differ in their time.
Those need to be cleaned up manually later on and will not be synced back
to the server. However, no files will get deleted in this process.
Just like files, directories also hold a unique id, which changes whenever
one of the contained files or directories gets modified. Since this is a
recursive process, it significantly reduces the effort required for a sync
cycle, because the client will only walk directories with a modified unique id.
.. note:: oCC 1.1 and newer require file ID capabilities on the ownCloud server,
hence using them with a server earlier than 4.5.0 is not supported.
This table outlines the different sync methods attempted depending
on server/client combination:
.. index:: compatiblity table
+--------------------+-------------------+----------------------------+
| Server Version | Client Version | Sync Methods |
+====================+===================+============================+
| 4.0.x or earlier | 1.0.5 or earlier | Time Stamp |
+--------------------+-------------------+----------------------------+
| 4.0.x or earlier | 1.1 or later | n/a (incompatible) |
+--------------------+-------------------+----------------------------+
| 4.5 or later | 1.0.5 or earlier | Time Stamp |
+--------------------+-------------------+----------------------------+
| 4.5 or later | 1.1 or later | File ID, Time Stamp |
+--------------------+-------------------+----------------------------+
It is highly recommended to upgrade to ownCloud 4.5 or later with ownCloud
Client 1.1 or later, since the time stamp-based sync mechanism can
lead to data loss in certain edge-cases, especially when multiple clients
are involved and one of them is not in sync with NTP time.
.. _`NTP time synchronisation`: http://en.wikipedia.org/wiki/Network_Time_Protocol
.. _Etag: http://en.wikipedia.org/wiki/HTTP_ETag

87
doc/branding.rst Normal file
View File

@@ -0,0 +1,87 @@
Adding 3rd-Party Branding
=========================
The ownCloud Client supports theming in the setup assistant dialog in both the
account setting and the result window. These customizations do not require a
recompile of the client.
The dialogs have places where custom content can be inserted. Please take a look
on the screenshot below. For example the connection wizard has the two green
rectangles as well as the area at the bottom with the black line and the red
text.
The content places can be altered by a file called ``custom.ini`` which contains
content for the specific places in the dialogs.
On windows, the custom.ini has to be stored at
+-----------------+------------------------------------------------------------+
| OS | Path |
+=================+============================================================+
| Windows (64 bit)| ``%ProgramFiles(x86)%\ownCloud\custom.ini`` |
+-----------------+------------------------------------------------------------+
| Windows (32 bit)| ``%ProgramFiles%\ownCloud\custom.ini`` |
+-----------------+------------------------------------------------------------+
| Mac OS | ``owncloud.app/Contents/Resources/custom.ini`` |
+-----------------+------------------------------------------------------------+
| Linux | ``/etc/ownCloud/custom.ini`` |
+-----------------+------------------------------------------------------------+
The config file needs to be in a usual `Windows INI file format`_.
Under the group definition [GUICustomize] the following keys can be set:
* ``oCSetupTop``: The top area of the connect wizard, account page.
* ``oCSetupSide``: The side area of the connect wizard, account page.
* ``ocSetupBottom``: The bottom area of the connect wizard, account page
* ``oCSetupResultTop``: The top area of the connect wizard result page.
* ``oCSetupFixUrl``: A fixed url to the ownCloud instance. If this is set, the
user can not access the url entry field and it is hidden.
The keys can be set to either an image file or a `rich text`_ snippet, which
must be enclosed with double quotes. Image files must be addressed by the
complete file name. On windows, the pathes should be noted with slashes
instead of backslashes. Instead of absolute file pathes, you can use
the ``%RESOURCES`` placeholder (note the single ``%``!).
Example::
%RESOURCES/custom/myimage_top.png
.. note:: ``%RESOURCES`` is currently undefined on Linux, it points to the
directory location of ``custom.ini`` on all other platforms.
Example
~~~~~~~
A config file ``custom.ini`` like this::
[GUICustomize]
oCSetupTop=/home/kf/owncloud.com/topimg.png
oCSetupSide=/home/kf/owncloud.com/sideimg.png
oCSetupBottom="
<hr />
The Power of now: ownCloud Client
This nice ownCloud Client was presented by <a
href="http://owncloud.com">ownCloud Inc.</a>
"
oCSetupResultTop=/home/kf/owncloud.com/topimg.png
will produce this setup dialog:
.. figure:: images/branding_setup.png
Setup Dialog Customization
Packaging remarks
~~~~~~~~~~~~~~~~~
While you do not need to rebuild the client, you will need to repackage
the client on your own. This also means you will have to resign those
packages with your own signing key.
.. _`Windows INI file format`: http://en.wikipedia.org/wiki/INI_file
.. _`rich text`: http://qt-project.org/doc/qt-5.0/richtext-html-subset.html

147
doc/building.rst Normal file
View File

@@ -0,0 +1,147 @@
Building the Client
===================
This section explains how to build the ownCloud Client from source
for all major platforms. You should read this section if you want
to development on the desktop client.
Linux
-----
1. Add the `ownCloud repository from OBS`_.
2. Install the dependencies (as root, or via sudo):
* Debian/Ubuntu: ``apt-get update; apt-get build-dep owncloud-client``
* openSUSE: ``zypper ref; zypper si -d owncloud-client``
* Fedora/CentOS: ``yum install yum-utils; yum-builddep owncloud-client``
3. Follow the `generic build instructions`_.
Mac OS X
--------
Follow the `generic build instructions`_.
You can install the missing dependencies via MacPorts_ or Homebrew_.
This is only needed on the build machine, since non-standard libs
will be deployed in the app bundle.
The only exception to this rule is libiniparser_, which lacks a decent
build system. If you are using Homebrew_, you can just add it::
brew tap dschmidt/owncloud
brew install iniparser
Otherwise, you need to copy the header and lib files to
``/usr/local/include`` and ``/usr/local/lib`` respectively.
.. note::
You should not call ``make install`` at any time, since the product of the
mirall build is an app bundle. Call ``make package`` instead to create an
install-ready disk image.
Windows (cross-compile)
-----------------------
Due to the amount of dependencies that csync entails, building the client
for Windows is **currently only supported on openSUSE**, by using the MinGW
cross compiler. You can set up openSUSE 12.1 or 12.2 in a virtual machine
if you do not have it installed already.
In order to cross-compile, the following repositories need to be added
via YaST or ``zypper ar`` (adjust when using openSUSE 12.2)::
http://download.opensuse.org/repositories/isv:/ownCloud:/devel:/mingw:/win32/openSUSE_12.1/isv:ownCloud:devel:mingw:win32.repo
http://download.opensuse.org/repositories/windows:/mingw/openSUSE_12.1/windows:mingw.repo
http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_12.1/windows:mingw:win32.repo
Next, install the cross-compiler packages and the cross-compiled dependencies::
zypper si -d mingw32-csync
zypper install kdewin-png2ico mingw32-libqt4 mingw32-libqt4-devel
mingw32-libgcrypt mingw32-libgnutls mingw32-gnutls \
mingw32-libneon mingw32-libbeecrypt mingw32-libopenssl \
mingw32-openssl
For the installer, the NSIS installer packages are also required::
zypper install mingw32-cross-nsis mingw32-cross-nsis-plugin-processes \
mingw32-cross-nsis-plugin-uac
Now, follow the `generic build instructions`_, but pay attention to
the following differences:
1. For building ``libocsync``, you need to use ``mingw32-cmake`` instead
of cmake.
2. Also, you need to specify *absolute pathes* for ``CSYNC_LIBRARY_PATH``
and ``CSYNC_LIBRARY_PATH`` when running ``cmake`` on mirall.
3. for building ``mirall``, you need to use ``cmake`` again, but make sure
to append the following parameter::
``-DCMAKE_TOOLCHAIN_FILE=../mirall/admin/win/Toolchain-mingw32-openSUSE.cmake``
Finally, just build by running ``make``. ``make package`` will produce
an NSIS-based installer, provided the NSIS mingw32 packages are installed.
Generic Build Instructions
--------------------------
.. _`generic build instructions`
The ownCloud Client requires Mirall and CSync_. Mirall is the GUI frontend,
while CSync is responsible for handling the actual synchronization process.
At the moment, ownCloud Client requires a forked version of CSync. Both
CMake and Mirall can be downloaded at ownCloud's `Client Download Page`_.
If you want to build the leading edge version of the client, you should
use the latest versions of Mirall and CSync via Git_, like so::
git clone git://git.csync.org/users/freitag/csync.git ocsync
git clone git://github.com/owncloud/mirall.git
Next, create build directories::
mkdir ocsync-build
mkdir mirall-build
This guide assumes that all directories are residing next to each other.
Next, make sure to check out the 'dav' branch in the newly checked out
`ocsync` directory::
cd ocsync
git checkout dav
The first package to buidld is CSync::
cd ocsync-build
cmake -DCMAKE_BUILD_TYPE="Debug" -DLOG_TO_CALLBACK=ON -DWITH_LOG4C=OFF ../ocsync
make
You probably have to satisfy some dependencies. Make sure to install all the
needed development packages. You will need ``iniparser``, ``sqlite3`` as well as
``neon`` for the ownCloud module. ``libssh`` and ``libsmbclient`` are optional
and not required for the client to work. If you want to install the client, run
``make install`` as a final step.
Next, we build mirall::
cd ../mirall-build
cmake -DCMAKE_BUILD_TYPE="Debug" ../mirall \
-DCSYNC_LIBRARY_PATH=../ocsync-build \
-DCSYNC_INCLUDE_PATH=../ocsync/src
If this succeeds, call ``make``. The owncloud binary should appear in the
``bin`` directory. You can also run ``make install`` to install the client to
``/usr/local/bin``.
To build in installer (requires the mingw32-cross-nsis packages)::
make package
.. _`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/
.. _Git: http://git-scm.com
.. _MacPorts: http://www.macports.org
.. _Homebrew: http://mxcl.github.com/homebrew/
.. _libiniparser: http://ndevilla.free.fr/iniparser/

288
doc/conf.py.in Normal file
View File

@@ -0,0 +1,288 @@
# -*- coding: utf-8 -*-
#
# ownCloud Documentation documentation build configuration file, created by
# sphinx-quickstart on Mon Oct 22 23:16:40 2012.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.todo']
# Add any paths that contain templates here, relative to this directory.
#templates_path = ['templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'ownCloud Client Manual'
copyright = u'2012, The ownCloud developers'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '@VERSION_MAJOR@.@VERSION_MINOR@'
# The full version, including alpha/beta/rc tags.
release = '@VERSION@'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
2
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = ['themes']
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#html_theme = 'bootstrap'
html_theme = 'default'
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
html_short_title = "Client Manual"
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
html_show_sphinx = False
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'ownCloudClientManual'
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'ownCloudClientManual.tex', u'ownCloud Client Manual',
u'The ownCloud developers', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'owncloud', u'ownCloud Client Manual',
[u'The ownCloud developers'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'ownCloudClientManual', u'ownCloud Client Manual',
u'The ownCloud developers', 'ownCloud', 'The ownCloud Client Manual.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# -- Options for Epub output ---------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = u'ownCloud Client Manual'
epub_author = u'The ownCloud developers'
epub_publisher = u'The ownCloud developers'
epub_copyright = u'2012, The ownCloud developers'
# The language of the text. It defaults to the language option
# or en if the language is not set.
#epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
#epub_scheme = ''
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#epub_identifier = ''
# A unique identification for the text.
#epub_uid = ''
# A tuple containing the cover image and cover page html template filenames.
#epub_cover = ()
# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_pre_files = []
# HTML files shat should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_post_files = []
# A list of files that should not be packed into the epub file.
#epub_exclude_files = []
# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3
# Allow duplicate toc entries.
#epub_tocdup = True
# Include todos?
todo_include_todos = True

28
doc/glossary.rst Normal file
View File

@@ -0,0 +1,28 @@
Glossary
========
.. glossary::
:sorted:
ownCloud Client
oCC
Name of the official ownCloud syncing client for desktop, which runs on
Windows, Mac OS X and Linux. It is based Mirall, and uses the CSync
sync engine for synchronization with the ownCloud server.
ownCloud Server
The server counter part of ownCloud Client as provided by the ownCloud
community.
mtime
modification time
file modification time
File property used to determine whether the servers' or the clients' file
is more recent. Standard procedure in oCC 1.0.5 and earlier, used by
oCC 1.1 and later only when no sync database exists and files already
exist in the client directory.
unique id
ID assigned to every file starting with ownCloud server 4.5 and submitted
via the HTTP ``Etag``. Used to check if files on client and server have
changed.

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

22
doc/index.rst Normal file
View File

@@ -0,0 +1,22 @@
.. ownCloud Documentation documentation master file, created by
sphinx-quickstart on Mon Oct 22 23:16:40 2012.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
ownCloud Desktop Client
***********************
Contents
========
.. toctree::
:maxdepth: 2
install
usage
building
branding
architecture
troubleshooting
glossary

36
doc/install.rst Normal file
View File

@@ -0,0 +1,36 @@
Installation
============
General
-------
The latest version of ownCloud client can be obtained at
http://owncloud.org/sync-clients/.
Windows
-------
ownCloud client for Windows is provided as a NSIS-based setup file for
machine-wide install.
Mac OS X
--------
Installing the ownCloud client on your Mac follows the normal app installation
pattern:
1. Download the installation file Click ownCloud-1.1.1.dmg, a window with the
2. ownCloud icon opens In that window, drag the ownCloud application into the
3. Applications folder on the right hand side From Applications, choose
ownCloud
Linux
------
The ownCloud client is provided as in a convenient repository for a wide range
of popular Linux distributions. If you want to build the sources instead.
Supported distributions are CentOS/RHEL, Fedora, SLES, openSUSE, Ubuntu and
Debian.
To support other distributions, a source build is required.

190
doc/make.bat Normal file
View File

@@ -0,0 +1,190 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OwncloudDocumentation.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OwncloudDocumentation.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end

12
doc/scripts/README.rst Normal file
View File

@@ -0,0 +1,12 @@
Doc Build Convenience Scripts
=============================
* ``htmlhelp.sh``: A script to install Microsoft HTML Workshop on Linux or Mac OS using Wine, along with some dependencies.
* ``htmlhelp.reg``: Registry file to override some DLLs with their native version and set the right Windows version.
Those files have been taken from the HTML Help Project (http://code.google.com/p/htmlhelp/wiki/HHW4Wine).
License
-------
The HTML Help Project has licensed its software under LGPLv3 terms.

12
doc/scripts/htmlhelp.reg Executable file
View File

@@ -0,0 +1,12 @@
REGEDIT4
[HKEY_CURRENT_USER\Software\Wine]
"Version"="win2k"
[HKEY_CURRENT_USER\Software\Wine\AppDefaults\hhc.exe\DllOverrides]
"itircl"="native"
"itss"="native"
[HKEY_CURRENT_USER\Software\Wine\AppDefaults\hhw.exe\DllOverrides]
"itircl"="native"
"itss"="native"

27
doc/scripts/htmlhelp.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/sh
WINEPREFIX=${WINEPREFIX:=$HOME/.wine}
test -d "$WINEPREFIX" || wineprefixcreate
# Setup the registry
wine regedit htmlhelp.reg
# Install HTML Help Workshop
wget 'http://go.microsoft.com/fwlink/?LinkId=14188' -O htmlhelp.exe
wine htmlhelp.exe
# Install ITSS.DLL
cabextract -F hhupd.exe htmlhelp.exe
cabextract -F itircl.dll hhupd.exe
cabextract -F itss.dll hhupd.exe
cp -a itircl.dll "$WINEPREFIX/drive_c/windows/system32/"
cp -a itss.dll "$WINEPREFIX/drive_c/windows/system32/"
wine regsvr32 /s 'C:\WINDOWS\SYSTEM32\itircl.dll'
wine regsvr32 /s 'C:\WINDOWS\SYSTEM32\itss.dll'
# Install MFC40.DLL
wget -N http://activex.microsoft.com/controls/vc/mfc40.cab
cabextract -F mfc40.exe mfc40.cab
cabextract -F mfc40.dll mfc40.exe
cp -a mfc40.dll "$WINEPREFIX/drive_c/windows/system32/"

28
doc/troubleshooting.rst Normal file
View File

@@ -0,0 +1,28 @@
Troubleshooting
===============
:All of my desktop clients fail to connect to ownCloud:
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.
If you are not prompted to enter your user name and password, please verify
that your server installation is working correctly.
If you are prompted, but the authentication fails even though the credentials
your provided are correct, please ensure that your authentication backend
is configured properly.
:The desktop client fails for an unknown reason:
Start the client with ``--logwindow``. You can also open a log window for an
already running session, by simply starting the client again with this
parameter. Syntax:
* Windows: ``C:\Program Files (x86)\ownCloud\owncloud.exe --logwindow``
* Mac OS X: ``/Applications/owncloud.app/Contents/MacOS/owncloud --logwindow``
* Linux: ``owncloud --logwindow``
The log output can help you with tracking down problem, and if you report
a bug, it's useful to include the output.

66
doc/usage.rst Normal file
View File

@@ -0,0 +1,66 @@
Usage
=====
.. index:: usage, client sync usage
To start ownCloud Client, click on the desktop icon or start it from the
application menu. In the system tray, an ownCloud icon appears.
.. index:: start application
A left click on the tray icon open a status dialog which gives an overview on
the configured sync folders and allows to add and remove more sync folder
connections as well as pausing a sync connection.
A right click on the tray icon gives other configuration options.
Command line switches
---------------------
.. 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. |
+--------------------------+------------------------------------------------+
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``
.. todo:: Windows, 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 |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
| ``localPollinterval`` | integer | milliseconds | ``10000`` | Poll time for local repository |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
| ``PollTimerExceedFactor`` | integer | n/a | ``10`` | Poll Timer Exceed Factor |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
| ``maxLogLines`` | integer | lines | ``20000`` | Maximum count of log lines shown in the log window |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
* ``remotePollinterval`` is for systems which have notify for local file system changes (Linux only currently)
this is the frequency it polls for remote changes. The following two values are ignored.
* ``localPollinterval`` is for systems which poll the local file system (currently Win and Mac) this is the
frequency they poll locally. The ``remotePollInterval`` is ignored on these systems.
* ``PollTimerExceedFactor`` sets the exceed factor is the factor after which a remote poll is done. That means the effective
frequency for remote poll is ``localPollInterval * pollTimerExceedFactor``.

View File

@@ -22,13 +22,16 @@
<file>resources/owncloud_splash.png</file>
<file>resources/task-ongoing.png</file>
<file>resources/owncloud-icon-22.png</file>
<file>resources/owncloud-icon-32.png</file>
<file>resources/owncloud-icon-48.png</file>
<file>resources/owncloud-icon-framed-64.png</file>
<file>resources/owncloud-icon-sync-48.png</file>
<file>resources/owncloud-icon-error-48.png</file>
<file>resources/owncloud-icon-sync-ok-48.png</file>
<file>resources/owncloud-icon-64.png</file>
<file>resources/owncloud-icon-128.png</file>
<file>resources/owncloud-framed-64.png</file>
<file>resources/owncloud-error-48.png</file>
<file>resources/owncloud-sync-48.png</file>
<file>resources/owncloud-sync-ok-48.png</file>
<file>resources/warning-16.png</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 B

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 B

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 918 B

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 991 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

821
resources/owncloud-icon.svg Normal file
View File

@@ -0,0 +1,821 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="32"
height="32"
viewBox="0 0 32 31.999997"
enable-background="new 0 0 595.275 311.111"
xml:space="preserve"
inkscape:version="0.48.2 r9819"
sodipodi:docname="icon.svg"
inkscape:export-filename="/home/user/owncloud/core/img/icon.png"
inkscape:export-xdpi="89.826416"
inkscape:export-ydpi="89.826416"><metadata
id="metadata327"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs325"><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_1_"
id="linearGradient3353"
gradientUnits="userSpaceOnUse"
x1="288.49411"
y1="55.888199"
x2="288.49411"
y2="339.22189" /><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_2_"
id="linearGradient3355"
gradientUnits="userSpaceOnUse"
x1="251.2114"
y1="55.888199"
x2="251.2114"
y2="339.22159" /><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_3_"
id="linearGradient3357"
gradientUnits="userSpaceOnUse"
x1="293.22461"
y1="55.888199"
x2="293.22461"
y2="339.22171" /><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_4_"
id="linearGradient3359"
gradientUnits="userSpaceOnUse"
x1="375.33401"
y1="55.888199"
x2="375.33401"
y2="339.22159" /><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_5_"
id="linearGradient3361"
gradientUnits="userSpaceOnUse"
x1="334.49411"
y1="55.888199"
x2="334.49411"
y2="339.22159" /><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_6_"
id="linearGradient3363"
gradientUnits="userSpaceOnUse"
x1="458.42679"
y1="55.8867"
x2="458.42679"
y2="339.2236" /><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_7_"
id="linearGradient3365"
gradientUnits="userSpaceOnUse"
x1="413.16309"
y1="55.888199"
x2="413.16309"
y2="339.22131" /><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_8_"
id="linearGradient3367"
gradientUnits="userSpaceOnUse"
x1="290.76169"
y1="55.8867"
x2="290.76169"
y2="339.2236" /><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_9_"
id="linearGradient3369"
gradientUnits="userSpaceOnUse"
x1="346.77341"
y1="55.888199"
x2="346.77341"
y2="339.22119" />
<linearGradient
y2="339.22189"
x2="288.49411"
y1="55.888199"
x1="288.49411"
gradientUnits="userSpaceOnUse"
id="SVGID_1_">
<stop
id="stop261"
style="stop-color:#BED5E1"
offset="0" />
<stop
id="stop263"
style="stop-color:#567B8F"
offset="1" />
</linearGradient>
<linearGradient
y2="339.22159"
x2="251.2114"
y1="55.888199"
x1="251.2114"
gradientUnits="userSpaceOnUse"
id="SVGID_2_">
<stop
id="stop268"
style="stop-color:#BED5E1"
offset="0" />
<stop
id="stop270"
style="stop-color:#567B8F"
offset="1" />
</linearGradient>
<linearGradient
y2="339.22171"
x2="293.22461"
y1="55.888199"
x1="293.22461"
gradientUnits="userSpaceOnUse"
id="SVGID_3_">
<stop
id="stop275"
style="stop-color:#BED5E1"
offset="0" />
<stop
id="stop277"
style="stop-color:#567B8F"
offset="1" />
</linearGradient>
<linearGradient
y2="339.22159"
x2="375.33401"
y1="55.888199"
x1="375.33401"
gradientUnits="userSpaceOnUse"
id="SVGID_4_">
<stop
id="stop282"
style="stop-color:#BED5E1"
offset="0" />
<stop
id="stop284"
style="stop-color:#567B8F"
offset="1" />
</linearGradient>
<linearGradient
y2="339.22159"
x2="334.49411"
y1="55.888199"
x1="334.49411"
gradientUnits="userSpaceOnUse"
id="SVGID_5_">
<stop
id="stop289"
style="stop-color:#BED5E1"
offset="0" />
<stop
id="stop291"
style="stop-color:#567B8F"
offset="1" />
</linearGradient>
<linearGradient
y2="339.2236"
x2="458.42679"
y1="55.8867"
x1="458.42679"
gradientUnits="userSpaceOnUse"
id="SVGID_6_">
<stop
id="stop296"
style="stop-color:#BED5E1"
offset="0" />
<stop
id="stop298"
style="stop-color:#567B8F"
offset="1" />
</linearGradient>
<linearGradient
y2="339.22131"
x2="413.16309"
y1="55.888199"
x1="413.16309"
gradientUnits="userSpaceOnUse"
id="SVGID_7_">
<stop
id="stop303"
style="stop-color:#BED5E1"
offset="0" />
<stop
id="stop305"
style="stop-color:#567B8F"
offset="1" />
</linearGradient>
<linearGradient
y2="339.2236"
x2="290.76169"
y1="55.8867"
x1="290.76169"
gradientUnits="userSpaceOnUse"
id="SVGID_8_">
<stop
id="stop310"
style="stop-color:#BED5E1"
offset="0" />
<stop
id="stop312"
style="stop-color:#567B8F"
offset="1" />
</linearGradient>
<linearGradient
y2="339.22119"
x2="346.77341"
y1="55.888199"
x1="346.77341"
gradientUnits="userSpaceOnUse"
id="SVGID_9_">
<stop
id="stop317"
style="stop-color:#BED5E1"
offset="0" />
<stop
id="stop319"
style="stop-color:#567B8F"
offset="1" />
</linearGradient>
<linearGradient
y2="18.967093"
x2="-2.4040222"
y1="4.4573336"
x1="-2.4040222"
gradientTransform="translate(13.927091,16.573387)"
gradientUnits="userSpaceOnUse"
id="linearGradient3475"
xlink:href="#linearGradient3587-6-5-26"
inkscape:collect="always" /><linearGradient
id="linearGradient3587-6-5-26"><stop
id="stop3589-9-2-45"
style="stop-color:#000000;stop-opacity:1"
offset="0" /><stop
id="stop3591-7-4-20"
style="stop-color:#363636;stop-opacity:1"
offset="1" /></linearGradient><linearGradient
y2="18.967093"
x2="-2.4040222"
y1="4.4573336"
x1="-2.4040222"
gradientTransform="translate(13.927091,16.573387)"
gradientUnits="userSpaceOnUse"
id="linearGradient7590"
xlink:href="#linearGradient3587-6-5-26"
inkscape:collect="always" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3587-6-5-26"
id="linearGradient7614"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(15.071012,45.700897)"
x1="-2.4040222"
y1="4.4573336"
x2="-2.4040222"
y2="18.967093" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3587-6-5-26"
id="linearGradient7623"
x1="58.866638"
y1="24.928007"
x2="58.866638"
y2="93.882034"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.25,0,0,0.25,0,0.500024)" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="774"
id="namedview323"
showgrid="true"
inkscape:zoom="8"
inkscape:cx="32.984032"
inkscape:cy="11.601392"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1"
units="px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="true"
inkscape:guide-bbox="true"><inkscape:grid
type="xygrid"
id="grid3152"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
dotted="false" /></sodipodi:namedview>
<pattern
y="565.223"
width="69"
height="69"
patternUnits="userSpaceOnUse"
id="Polka_Dot_Pattern"
viewBox="2.125 -70.896 69 69"
overflow="visible">
<g
id="g4">
<polygon
fill="none"
points="71.125,-1.896 2.125,-1.896 2.125,-70.896 71.125,-70.896 "
id="polygon6" />
<polygon
fill="#F6BB60"
points="71.125,-1.896 2.125,-1.896 2.125,-70.896 71.125,-70.896 "
id="polygon8" />
<g
id="g10">
<path
fill="#FFFFFF"
d="M61.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path12" />
<path
fill="#FFFFFF"
d="M54.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path14" />
<path
fill="#FFFFFF"
d="M46.439-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path16" />
<path
fill="#FFFFFF"
d="M38.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path18" />
<path
fill="#FFFFFF"
d="M31.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path20" />
<path
fill="#FFFFFF"
d="M23.439-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path22" />
<path
fill="#FFFFFF"
d="M15.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path24" />
<path
fill="#FFFFFF"
d="M8.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path26" />
<path
fill="#FFFFFF"
d="M0.439-71.653c0.018,0.072,0.008,0.127-0.026,0.19C0.361-71.362,0.3-71.4,0.248-71.335 c-0.051,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path28" />
</g>
<g
id="g30">
<path
fill="#FFFFFF"
d="M69.439-71.653c0.018,0.072,0.008,0.127-0.026,0.19c-0.052,0.101-0.113,0.062-0.165,0.128 c-0.051,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path32" />
</g>
<path
fill="#FFFFFF"
d="M0.495-71.653c0.018,0.072,0.008,0.127-0.026,0.19c-0.052,0.101-0.113,0.062-0.165,0.128 c-0.051,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224C0.5-71.68,0.503-71.744,0.51-71.626 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path34" />
<g
id="g36">
<g
id="g38">
<path
fill="#FFFFFF"
d="M69.439-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path40" />
<path
fill="#FFFFFF"
d="M61.778-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path42" />
<path
fill="#FFFFFF"
d="M54.118-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path44" />
<path
fill="#FFFFFF"
d="M46.458-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path46" />
<path
fill="#FFFFFF"
d="M38.797-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path48" />
<path
fill="#FFFFFF"
d="M31.137-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path50" />
<path
fill="#FFFFFF"
d="M23.477-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path52" />
<path
fill="#FFFFFF"
d="M15.816-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path54" />
<path
fill="#FFFFFF"
d="M8.156-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path56" />
<path
fill="#FFFFFF"
d="M0.495-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143C2-61.45,2.217-61.397,2.391-61.46c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path58" />
</g>
<g
id="g60">
<path
fill="#FFFFFF"
d="M69.439-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path62" />
<path
fill="#FFFFFF"
d="M61.778-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path64" />
<path
fill="#FFFFFF"
d="M54.118-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path66" />
<path
fill="#FFFFFF"
d="M46.458-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path68" />
<path
fill="#FFFFFF"
d="M38.797-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path70" />
<path
fill="#FFFFFF"
d="M31.137-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path72" />
<path
fill="#FFFFFF"
d="M23.477-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path74" />
<path
fill="#FFFFFF"
d="M15.816-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path76" />
<path
fill="#FFFFFF"
d="M8.156-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path78" />
<path
fill="#FFFFFF"
d="M0.495-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-56.374,0.503-56.438,0.51-56.32 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path80" />
</g>
<g
id="g82">
<path
fill="#FFFFFF"
d="M69.439-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path84" />
<path
fill="#FFFFFF"
d="M61.778-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path86" />
<path
fill="#FFFFFF"
d="M54.118-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path88" />
<path
fill="#FFFFFF"
d="M46.458-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path90" />
<path
fill="#FFFFFF"
d="M38.797-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path92" />
<path
fill="#FFFFFF"
d="M31.137-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path94" />
<path
fill="#FFFFFF"
d="M23.477-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path96" />
<path
fill="#FFFFFF"
d="M15.816-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path98" />
<path
fill="#FFFFFF"
d="M8.156-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path100" />
<path
fill="#FFFFFF"
d="M0.495-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path102" />
</g>
<g
id="g104">
<path
fill="#FFFFFF"
d="M69.439-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path106" />
<path
fill="#FFFFFF"
d="M61.778-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path108" />
<path
fill="#FFFFFF"
d="M54.118-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path110" />
<path
fill="#FFFFFF"
d="M46.458-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path112" />
<path
fill="#FFFFFF"
d="M38.797-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path114" />
<path
fill="#FFFFFF"
d="M31.137-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path116" />
<path
fill="#FFFFFF"
d="M23.477-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path118" />
<path
fill="#FFFFFF"
d="M15.816-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path120" />
<path
fill="#FFFFFF"
d="M8.156-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 C8.15-41.004,8.149-41.02,8.14-41.04"
id="path122" />
<path
fill="#FFFFFF"
d="M0.495-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path124" />
</g>
<g
id="g126">
<path
fill="#FFFFFF"
d="M69.439-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path128" />
<path
fill="#FFFFFF"
d="M61.778-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path130" />
<path
fill="#FFFFFF"
d="M54.118-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path132" />
<path
fill="#FFFFFF"
d="M46.458-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path134" />
<path
fill="#FFFFFF"
d="M38.797-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path136" />
<path
fill="#FFFFFF"
d="M31.137-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path138" />
<path
fill="#FFFFFF"
d="M23.477-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path140" />
<path
fill="#FFFFFF"
d="M15.816-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path142" />
<path
fill="#FFFFFF"
d="M8.156-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path144" />
<path
fill="#FFFFFF"
d="M0.495-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-33.416,0.503-33.48,0.51-33.362 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path146" />
</g>
<g
id="g148">
<path
fill="#FFFFFF"
d="M69.439-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path150" />
<path
fill="#FFFFFF"
d="M61.778-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path152" />
<path
fill="#FFFFFF"
d="M54.118-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path154" />
<path
fill="#FFFFFF"
d="M46.458-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path156" />
<path
fill="#FFFFFF"
d="M38.797-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path158" />
<path
fill="#FFFFFF"
d="M31.137-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path160" />
<path
fill="#FFFFFF"
d="M23.477-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path162" />
<path
fill="#FFFFFF"
d="M15.816-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path164" />
<path
fill="#FFFFFF"
d="M8.156-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path166" />
<path
fill="#FFFFFF"
d="M0.495-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path168" />
</g>
<g
id="g170">
<path
fill="#FFFFFF"
d="M69.439-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path172" />
<path
fill="#FFFFFF"
d="M61.778-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path174" />
<path
fill="#FFFFFF"
d="M54.118-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path176" />
<path
fill="#FFFFFF"
d="M46.458-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path178" />
<path
fill="#FFFFFF"
d="M38.797-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path180" />
<path
fill="#FFFFFF"
d="M31.137-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path182" />
<path
fill="#FFFFFF"
d="M23.477-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path184" />
<path
fill="#FFFFFF"
d="M15.816-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path186" />
<path
fill="#FFFFFF"
d="M8.156-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path188" />
<path
fill="#FFFFFF"
d="M0.495-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-18.11,0.503-18.175,0.51-18.057 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path190" />
</g>
<g
id="g192">
<path
fill="#FFFFFF"
d="M69.439-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362C69-9.692,69.159-9.523,69.154-9.4c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path194" />
<path
fill="#FFFFFF"
d="M61.778-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path196" />
<path
fill="#FFFFFF"
d="M54.118-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path198" />
<path
fill="#FFFFFF"
d="M46.458-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path200" />
<path
fill="#FFFFFF"
d="M38.797-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path202" />
<path
fill="#FFFFFF"
d="M31.137-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path204" />
<path
fill="#FFFFFF"
d="M23.477-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path206" />
<path
fill="#FFFFFF"
d="M15.816-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053C17.933-7.969,17.839-8.227,18-8.34 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path208" />
<path
fill="#FFFFFF"
d="M8.156-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 C7.915-10.05,7.866-9.836,7.886-9.75C7.717-9.692,7.876-9.523,7.871-9.4C7.868-9.351,7.83-9.295,7.826-9.239 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C9.114-7.652,9.321-7.799,9.48-7.837c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path210" />
<path
fill="#FFFFFF"
d="M0.495-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 C0.254-10.05,0.205-9.836,0.225-9.75C0.056-9.692,0.215-9.523,0.21-9.4c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37C0.33-8.671,0.501-8.456,0.668-8.325c0.19,0.148,0.365,0.572,0.608,0.631 C1.454-7.652,1.66-7.799,1.819-7.837C2-7.88,2.217-7.827,2.391-7.89c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46C3.477-8.933,3.471-8.995,3.5-9.071 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path212" />
</g>
</g>
<g
id="g214">
<path
fill="#FFFFFF"
d="M69.439-2.778c0.018,0.072,0.008,0.127-0.026,0.19C69.361-2.487,69.3-2.525,69.248-2.46 c-0.051,0.062-0.099,0.276-0.079,0.362C69-2.04,69.159-1.871,69.154-1.748c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C70.397,0,70.604-0.146,70.763-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path216" />
<path
fill="#FFFFFF"
d="M61.778-2.778c0.018,0.072,0.007,0.127-0.026,0.19C61.7-2.487,61.64-2.525,61.587-2.46 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C62.737,0,62.943-0.146,63.103-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C61.915-3.117,61.78-3.02,61.781-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path218" />
<path
fill="#FFFFFF"
d="M54.118-2.778c0.018,0.072,0.007,0.127-0.026,0.19C54.04-2.487,53.98-2.525,53.927-2.46 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C55.077,0,55.283-0.146,55.442-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C54.255-3.117,54.12-3.02,54.121-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path220" />
<path
fill="#FFFFFF"
d="M46.458-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C47.416,0,47.623-0.146,47.782-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C46.594-3.117,46.459-3.02,46.46-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path222" />
<path
fill="#FFFFFF"
d="M38.797-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C39.756,0,39.962-0.146,40.122-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C38.934-3.117,38.799-3.02,38.8-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path224" />
<path
fill="#FFFFFF"
d="M31.137-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C32.095,0,32.302-0.146,32.461-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C31.273-3.117,31.139-3.02,31.14-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path226" />
<path
fill="#FFFFFF"
d="M23.477-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C24.435,0,24.642-0.146,24.801-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
id="path228" />
<path
fill="#FFFFFF"
d="M15.816-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C16.774,0,16.981-0.146,17.14-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 C15.81-2.74,15.809-2.756,15.8-2.776"
id="path230" />
<path
fill="#FFFFFF"
d="M8.156-2.778c0.018,0.072,0.007,0.127-0.026,0.19C8.077-2.487,8.018-2.525,7.965-2.46 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35C7.868-1.698,7.83-1.643,7.826-1.587 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C9.114,0,9.321-0.146,9.48-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789C8.954-3.54,8.847-3.448,8.692-3.367 c-0.17,0.088-0.139,0.166-0.318,0.224C8.292-3.117,8.158-3.02,8.159-2.92C8.16-2.805,8.164-2.869,8.17-2.751 C8.15-2.74,8.149-2.756,8.14-2.776"
id="path232" />
<path
fill="#FFFFFF"
d="M0.495-2.778c0.018,0.072,0.008,0.127-0.026,0.19C0.417-2.487,0.356-2.525,0.304-2.46 C0.253-2.397,0.205-2.184,0.225-2.098C0.056-2.04,0.215-1.871,0.21-1.748c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37C0.33-1.019,0.501-0.804,0.668-0.673c0.19,0.148,0.365,0.572,0.608,0.631 C1.454,0,1.66-0.146,1.819-0.185C2-0.228,2.217-0.175,2.391-0.237c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46C3.477-1.28,3.471-1.343,3.5-1.419 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789C1.293-3.54,1.187-3.448,1.031-3.367 c-0.17,0.088-0.139,0.166-0.318,0.224C0.632-3.117,0.498-3.02,0.498-2.92C0.5-2.805,0.503-2.869,0.51-2.751 C0.489-2.74,0.488-2.756,0.479-2.776"
id="path234" />
</g>
</g>
</pattern>
<path
sodipodi:nodetypes="sscscsscscscscccscscccsssssssscscsccsscscssscsscscsccccscssccsssccs"
inkscape:connector-curvature="0"
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/user/owncloud/core/img/logo.png"
id="path7625"
d="m 14.488658,7.6997589 c -2.381798,0 -4.30607,1.92427 -4.30607,4.3060701 0,0.98178 0.32692,1.88539 0.878102,2.60897 1.195708,-1.38395 2.960465,-2.2628 4.93087,-2.2628 0.964013,0 1.878155,0.21467 2.70185,0.59103 0.06669,-0.3016 0.101318,-0.61527 0.101318,-0.9372 0,-2.3818001 -1.92427,-4.3060701 -4.30607,-4.3060701 z m -5.6232205,1.99261 c -1.240375,0 -2.2374675,1.0055301 -2.2374675,2.2459101 0,0.4016 0.10361,0.78106 0.28707,1.10607 0.74849,-0.42223 1.61383,-0.66702 2.5329825,-0.66702 0.088705,0 0.1741425,0.004 0.2617425,0.008 -0.00993,-0.1253 -0.016875,-0.25124 -0.016875,-0.3795 0,-0.69087 0.15005,-1.34819 0.41372,-1.94196 C 9.7516025,9.8258189 9.3262675,9.6923689 8.86545,9.6923689 z M 19.487078,11.237489 c -0.09164,0 -0.179965,0.0113 -0.270185,0.0169 0.03903,0.24606 0.06755,0.49451 0.06755,0.75145 0,0.39985 -0.05085,0.78569 -0.143535,1.15673 1.08665,0.60136 1.989072,1.50116 2.583642,2.59208 0.616705,-0.32106 1.30466,-0.52521 2.03483,-0.57414 -0.18818,-2.20687 -2.016472,-3.94301 -4.272297,-3.94301 z m -3.495518,1.60422 c -3.33285,0 -6.0284975,2.69542 -6.0284975,6.0285 0,3.33272 2.6955105,6.0285 6.0284975,6.0285 3.33299,0 6.0285,-2.69579 6.0285,-6.0285 0,-3.33307 -2.695647,-6.0285 -6.0285,-6.0285 z m -6.5435375,0.0253 c -2.58566,0 -4.6775725,2.09191 -4.6775725,4.67757 0,1.52213 0.7252325,2.8696 1.8490775,3.72349 0.47379,-0.91381 1.425375,-1.53668 2.5245375,-1.53668 0.132845,0 0.260355,0.0161 0.38839,0.0338 -0.040192,-0.29242 -0.0591,-0.59159 -0.0591,-0.89499 0,-1.4506 0.47218,-2.79202 1.274933,-3.87546 -0.48052,-0.60129 -0.8244005,-1.32376 -0.970978,-2.11082 -0.1086325,-0.008 -0.218725,-0.0169 -0.3292875,-0.0169 z m 14.6575255,2.78628 c -0.785125,0 -1.520585,0.20045 -2.169923,0.54037 0.368715,0.81673 0.574143,1.72291 0.574143,2.67652 0,1.78555 -0.71789,3.406849 -1.88285,4.584699 0.85582,0.95013 2.097512,1.54512 3.47863,1.54512 2.58566,0 4.677575,-2.091919 4.677575,-4.677579 0,-2.585661 -2.091915,-4.66913 -4.677575,-4.66913 z M 4.3145118,16.269679 C 1.9326443,16.269679 0,18.185439 0,20.567309 c 0,2.38187 1.9326443,4.31451 4.3145118,4.31451 0.9065732,0 1.7463732,-0.282451 2.4401082,-0.75989 -0.286665,-0.44545 -0.4559375,-0.978001 -0.4559375,-1.54512 0,-0.294361 0.043432,-0.57714 0.1266475,-0.84433 -1.29874,-0.93858 -2.1445912,-2.46595 -2.1445912,-4.18787 0,-0.4375 0.057653,-0.86054 0.1604237,-1.26649 -0.042658,-0.001 -0.083686,-0.008 -0.1266507,-0.008 z m 25.3213812,3.69816 c -0.127065,0 -0.250018,0.0145 -0.371505,0.0338 0.0067,0.1074 0.0084,0.21176 0.0084,0.32084 0,1.37337 -0.541883,2.61988 -1.41847,3.54618 0.43125,0.50149 1.064697,0.819 1.781532,0.819 1.30572,0 2.364118,-1.04996 2.364118,-2.35568 0,-1.30572 -1.058398,-2.36411 -2.364118,-2.36411 z m -20.491828,0.25329 c -1.3056525,0 -2.3556725,1.05002 -2.3556725,2.35568 0,1.30565 1.05002,2.36411 2.3556725,2.36411 1.0008,0 1.850283,-0.62448 2.195253,-1.5029 -0.84174,-0.8573 -1.446688,-1.951 -1.7139855,-3.16623 C 9.468915,20.239449 9.31015,20.221129 9.144065,20.221129 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.2;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.8;color:#000000;fill:url(#linearGradient7623);fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 14.488658,6.699758 c -2.381798,0 -4.30607,1.92427 -4.30607,4.306071 0,0.98178 0.32692,1.88539 0.878102,2.60897 1.195708,-1.38395 2.960465,-2.2628 4.93087,-2.2628 0.964013,0 1.878155,0.21467 2.70185,0.59103 0.06669,-0.3016 0.101318,-0.61527 0.101318,-0.9372 0,-2.381801 -1.92427,-4.306071 -4.30607,-4.306071 z m -5.6232205,1.99261 c -1.240375,0 -2.2374675,1.00554 -2.2374675,2.245911 0,0.4016 0.10361,0.78106 0.28707,1.10607 0.74849,-0.42223 1.61383,-0.66702 2.5329825,-0.66702 0.088705,0 0.1741425,0.004 0.2617425,0.008 -0.00993,-0.1253 -0.016875,-0.25124 -0.016875,-0.3795 0,-0.69086 0.15005,-1.348191 0.41372,-1.941961 -0.3550075,-0.23805 -0.7803425,-0.3715 -1.24116,-0.3715 z m 10.6216405,1.545121 c -0.09164,0 -0.179965,0.0113 -0.270185,0.0169 0.03903,0.24606 0.06755,0.49452 0.06755,0.75145 0,0.39985 -0.05085,0.78569 -0.143535,1.15673 1.08665,0.60137 1.989072,1.50116 2.583642,2.59208 0.616705,-0.32106 1.30466,-0.5252 2.03483,-0.57414 -0.18818,-2.20687 -2.016472,-3.94301 -4.272297,-3.94301 z m -3.495518,1.60422 c -3.33285,0 -6.0284975,2.69542 -6.0284975,6.0285 0,3.33272 2.6955105,6.0285 6.0284975,6.0285 3.33299,0 6.0285,-2.69579 6.0285,-6.0285 0,-3.33307 -2.695647,-6.0285 -6.0285,-6.0285 z m -6.5435375,0.0253 c -2.58566,0 -4.6775725,2.09191 -4.6775725,4.67758 0,1.52212 0.7252325,2.86959 1.8490775,3.72348 0.47379,-0.913811 1.425375,-1.53668 2.5245375,-1.53668 0.132845,0 0.260355,0.0161 0.38839,0.0338 -0.040192,-0.29242 -0.0591,-0.59159 -0.0591,-0.89499 0,-1.4506 0.47218,-2.792019 1.274933,-3.875459 -0.48052,-0.60129 -0.8244005,-1.32376 -0.970978,-2.11082 -0.1086325,-0.008 -0.218725,-0.0169 -0.3292875,-0.0169 z m 14.6575255,2.78628 c -0.785125,0 -1.520585,0.20045 -2.169923,0.54037 0.368715,0.81673 0.574143,1.72291 0.574143,2.67652 0,1.78555 -0.71789,3.406849 -1.88285,4.584699 0.85582,0.95013 2.097512,1.54512 3.47863,1.54512 2.58566,0 4.677575,-2.091919 4.677575,-4.677579 0,-2.585661 -2.091915,-4.66913 -4.677575,-4.66913 z M 4.3145118,15.269679 C 1.9326443,15.269679 0,17.185439 0,19.567309 c 0,2.38187 1.9326443,4.31451 4.3145118,4.31451 0.9065732,0 1.7463732,-0.282451 2.4401082,-0.75989 -0.286665,-0.44545 -0.4559375,-0.978001 -0.4559375,-1.54512 0,-0.294361 0.043432,-0.57714 0.1266475,-0.84433 -1.29874,-0.93858 -2.1445912,-2.46595 -2.1445912,-4.18786 0,-0.43751 0.057653,-0.86055 0.1604237,-1.2665 -0.042658,-10e-4 -0.083686,-0.008 -0.1266507,-0.008 z m 25.3213812,3.69816 c -0.127065,0 -0.250018,0.0145 -0.371505,0.0338 0.0067,0.1074 0.0084,0.21176 0.0084,0.32084 0,1.37337 -0.541883,2.61988 -1.41847,3.54618 0.43125,0.50149 1.064697,0.819 1.781532,0.819 1.30572,0 2.364118,-1.04996 2.364118,-2.35568 0,-1.30572 -1.058398,-2.36411 -2.364118,-2.36411 z m -20.491828,0.25329 c -1.3056525,0 -2.3556725,1.05002 -2.3556725,2.35568 0,1.30565 1.05002,2.36411 2.3556725,2.36411 1.0008,0 1.850283,-0.62448 2.195253,-1.5029 -0.84174,-0.8573 -1.446688,-1.951 -1.7139855,-3.16623 C 9.468915,19.239449 9.31015,19.221129 9.144065,19.221129 z"
id="circle238"
inkscape:export-filename="/home/user/owncloud/core/img/logo.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sscscsscscscscccscscccsssssssscscsccsscscssscsscscsccccscssccsssccs" />
</svg>

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 117 KiB

BIN
resources/warning-16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

View File

@@ -16,7 +16,7 @@ mirall/createanowncloudpage.ui
mirall/owncloudftpaccesspage.ui
mirall/owncloudwizardresultpage.ui
mirall/owncloudcredentialspage.ui
mirall/sslerrorsdialog.ui
mirall/sslerrordialog.ui
mirall/proxydialog.ui
)
@@ -61,6 +61,7 @@ set(libsync_SRCS
mirall/unisonfolder.cpp
mirall/networklocation.cpp
mirall/mirallconfigfile.cpp
mirall/credentialstore.cpp
mirall/csyncfolder.cpp
mirall/owncloudfolder.cpp
mirall/csyncthread.cpp
@@ -68,6 +69,7 @@ set(libsync_SRCS
mirall/theme.cpp
mirall/owncloudtheme.cpp
mirall/miralltheme.cpp
mirall/owncloudinfo.cpp
)
set(libsync_HEADERS
mirall/folderman.h
@@ -78,6 +80,8 @@ set(libsync_HEADERS
mirall/csyncfolder.h
mirall/owncloudfolder.h
mirall/csyncthread.h
mirall/owncloudinfo.h
mirall/credentialstore.h
)
IF( INOTIFY_FOUND )
@@ -109,7 +113,6 @@ set(mirall_SRCS
mirall/statusdialog.cpp
mirall/owncloudwizard.cpp
mirall/owncloudsetupwizard.cpp
mirall/owncloudinfo.cpp
mirall/updatedetector.cpp
mirall/occinfo.cpp
mirall/sslerrordialog.cpp
@@ -120,7 +123,6 @@ set(mirall_SRCS
set(mirall_HEADERS
mirall/application.h
mirall/folderwizard.h
mirall/owncloudinfo.h
mirall/owncloudsetupwizard.h
mirall/owncloudwizard.h
mirall/statusdialog.h
@@ -173,9 +175,9 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
# we may not add MACOSX_BUNDLE here, if not building one
# add_executable(owncloud main.cpp ${final_src})
add_executable(owncloud WIN32 main.cpp ${final_src})
set_target_properties( owncloud PROPERTIES COMPILE_DEFINITIONS OWNCLOUD_CLIENT)
# add_executable( ${APPLICATION_EXECUTABLE} main.cpp ${final_src})
add_executable( ${APPLICATION_EXECUTABLE} WIN32 main.cpp ${final_src})
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES COMPILE_DEFINITIONS OWNCLOUD_CLIENT)
# mirall is not built for the bundle
add_executable( mirall WIN32 main.cpp ${final_src})
@@ -199,25 +201,29 @@ else()
set(MACOSX_BUNDLE_ICON_FILE "ownCloud.icns")
# we must add MACOSX_BUNDLE only if building a bundle
add_executable(owncloud WIN32 MACOSX_BUNDLE main.cpp ${final_src})
set_target_properties( owncloud PROPERTIES COMPILE_DEFINITIONS OWNCLOUD_CLIENT)
add_executable( ${APPLICATION_EXECUTABLE} WIN32 MACOSX_BUNDLE main.cpp ${final_src})
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES COMPILE_DEFINITIONS OWNCLOUD_CLIENT)
#FIXME: hardcoded path
install(FILES /usr/local/lib/csync-0/csync_owncloud.so DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Plugins)
if ( EXISTS ${CSYNC_BINARY_DIR}/modules/ocsync_owncloud.so )
install(FILES ${CSYNC_BINARY_DIR}/modules/ocsync_owncloud.so DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Plugins)
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)
list(APPEND dirs "/usr/local/lib")
endif()
set_target_properties( owncloud PROPERTIES
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}
)
target_link_libraries(owncloud ${QT_LIBRARIES} )
target_link_libraries(owncloud owncloudsync)
target_link_libraries(owncloud ${CSYNC_LIBRARY})
target_link_libraries( ${APPLICATION_EXECUTABLE} ${QT_LIBRARIES} )
target_link_libraries( ${APPLICATION_EXECUTABLE} owncloudsync )
target_link_libraries( ${APPLICATION_EXECUTABLE} ${CSYNC_LIBRARY} )
install(TARGETS owncloud
install(TARGETS ${APPLICATION_EXECUTABLE}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
@@ -228,7 +234,7 @@ install(TARGETS owncloud
# 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)
install_qt4_executable(${OWNCLOUD_OSX_BUNDLE} "" "${OWNCLOUD_OSX_BUNDLE}/Contents/Plugins/csync_owncloud.so" ${dirs})
install_qt4_executable(${OWNCLOUD_OSX_BUNDLE} "" "${OWNCLOUD_OSX_BUNDLE}/Contents/Plugins/ocsync_owncloud.so" ${dirs})
endif()
find_program(KRAZY2_EXECUTABLE krazy2)

View File

@@ -21,12 +21,15 @@ int main(int argc, char **argv)
Mirall::Application app(argc, argv);
app.initialize();
qint64 pid = -1;
// if the application is already running, notify it.
if( app.isRunning() ) {
if( app.sendMessage( QLatin1String("A message to the master"), 5000, pid ))
return 0;
QStringList args = app.arguments();
if ( args.size() > 1 && ! app.giveHelp() ) {
QString msg = args.join( QLatin1String("|") );
if( ! app.sendMessage( msg ) )
return -1;
}
return 0;
}
// if help requested, show on command line and exit.
if( ! app.giveHelp() )

View File

@@ -25,15 +25,13 @@
#include "mirall/statusdialog.h"
#include "mirall/owncloudsetupwizard.h"
#include "mirall/owncloudinfo.h"
#include "mirall/sslerrordialog.h"
#include "mirall/theme.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/updatedetector.h"
#include "mirall/proxydialog.h"
#include "mirall/miralltheme.h"
#include "mirall/owncloudtheme.h"
#include "config.h"
#include "mirall/version.h"
#include "mirall/credentialstore.h"
#ifdef WITH_CSYNC
#include "mirall/csyncfolder.h"
@@ -71,26 +69,25 @@ void csyncLogCatcher(const char *msg)
Application::Application(int &argc, char **argv) :
SharedTools::QtSingleApplication(argc, argv),
_tray(0),
_sslErrorDialog(0),
#if QT_VERSION >= 0x040700
_networkMgr(new QNetworkConfigurationManager(this)),
#endif
_contextMenu(0),
_theme(Theme::instance()),
_updateDetector(0),
_helpOnly(false)
_showLogWindow(false),
_logFlush(false),
_helpOnly(false),
_logBrowser(0)
{
#ifdef OWNCLOUD_CLIENT
_theme = new ownCloudTheme();
#else
_theme = new mirallTheme();
#endif
setApplicationName( _theme->appName() );
setWindowIcon( _theme->applicationIcon() );
if( arguments().contains(QLatin1String("--help"))) {
showHelp();
}
parseOptions(arguments());
setupLogBrowser();
//no need to waste time;
if ( _helpOnly ) return;
processEvents();
QTranslator *qtTranslator = new QTranslator(this);
@@ -99,19 +96,25 @@ Application::Application(int &argc, char **argv) :
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_") + QLocale::system().name(), QLatin1String("/usr/share/mirall/i18n/"));
mirallTranslator->load(QLatin1String("mirall_") + locale, QLatin1String("/usr/share/mirall/i18n/"));
#endif
#ifdef Q_OS_MAC
mirallTranslator->load(QLatin1String("mirall_") + QLocale::system().name(), applicationDirPath()+QLatin1String("/../translations") ); // path defaults to app dir.
mirallTranslator->load(QLatin1String("mirall_") + locale, applicationDirPath()+QLatin1String("/../translations") ); // path defaults to app dir.
#endif
#ifdef Q_OS_WIN32
mirallTranslator->load(QLatin1String("mirall_") + QLocale::system().name(), applicationDirPath());
mirallTranslator->load(QLatin1String("mirall_") + locale, applicationDirPath());
#endif
installTranslator(mirallTranslator);
connect( this, SIGNAL(messageReceived(QString)), SLOT(slotParseOptions(QString)));
// create folder manager for sync folder management
_folderMan = new FolderMan(this);
connect( _folderMan, SIGNAL(folderSyncStateChange(QString)),
@@ -124,7 +127,7 @@ Application::Application(int &argc, char **argv) :
setQuitOnLastWindowClosed(false);
_folderWizard = new FolderWizard( 0, _theme );
_folderWizard = new FolderWizard;
_owncloudSetupWizard = new OwncloudSetupWizard( _folderMan, _theme, this );
connect( _owncloudSetupWizard, SIGNAL(ownCloudWizardDone(int)), SLOT(slotStartFolderSetup(int)));
@@ -166,11 +169,15 @@ Application::Application(int &argc, char **argv) :
QTimer::singleShot( 3000, this, SLOT( slotStartUpdateDetector() ));
}
connect( ownCloudInfo::instance(), SIGNAL(sslFailed(QNetworkReply*, QList<QSslError>)),
this,SLOT(slotSSLFailed(QNetworkReply*, QList<QSslError>)));
qDebug() << "Network Location: " << NetworkLocation::currentLocation().encoded();
}
Application::~Application()
{
delete _tray; // needed, see ctor
qDebug() << "* Mirall shutdown";
}
@@ -191,19 +198,9 @@ void Application::slotStartFolderSetup( int result )
connect( ownCloudInfo::instance(),SIGNAL(noOwncloudFound(QNetworkReply*)),
SLOT(slotNoOwnCloudFound(QNetworkReply*)));
connect( ownCloudInfo::instance(),SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
this,SLOT(slotAuthCheck(QString,QNetworkReply*)));
ownCloudInfo::instance()->checkInstallation();
} else {
QMessageBox::warning(0, tr("No ownCloud Configuration"),
tr("<p>No server connection has been configured for this ownCloud client.</p>"
"<p>Please right click on the ownCloud system tray icon and select <i>Configure</i> "
"to connect this client to an ownCloud server.</p>"));
// It was evaluated to open the config dialog from here directly but decided
// against because the user does not know why. The popup gives a better user
// guidance, even if its a click more.
_owncloudSetupWizard->startWizard(true); // with intro
}
} else {
qDebug() << "Setup Wizard was canceled. No reparsing of config.";
@@ -224,13 +221,13 @@ void Application::slotOwnCloudFound( const QString& url, const QString& versionS
this, SLOT(slotNoOwnCloudFound(QNetworkReply*)));
if( version.startsWith("4.0") ) {
QMessageBox::warning(0, tr("ownCloud Server Mismatch"),
QMessageBox::warning(0, tr("%1 Server Mismatch").arg(_theme->appName()),
tr("<p>The configured server for this client is too old.</p>"
"<p>Please update to the latest ownCloud server and restart the client.</p>"));
"<p>Please update to the latest %1 server and restart the client.</p>").arg(_theme->appName()));
return;
}
QTimer::singleShot( 0, this, SLOT( slotCheckAuthentication() ));
QTimer::singleShot( 0, this, SLOT( slotFetchCredentials() ));
}
void Application::slotNoOwnCloudFound( QNetworkReply* reply )
@@ -240,12 +237,12 @@ void Application::slotNoOwnCloudFound( QNetworkReply* reply )
if( reply ) {
QString url( reply->url().toString() );
url.remove( QLatin1String("/status.php") );
msg = tr("<p>The ownCloud at %1 could not be reached.</p>").arg( url );
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>");
QMessageBox::warning(0, tr("ownCloud Connection Failed"), msg );
QMessageBox::warning(0, tr("%1 Connection Failed").arg(_theme->appName()), msg );
_actionAddFolder->setEnabled( false );
// Disconnect.
@@ -261,8 +258,48 @@ void Application::slotNoOwnCloudFound( QNetworkReply* reply )
setupContextMenu();
}
void Application::slotFetchCredentials()
{
connect( CredentialStore::instance(), SIGNAL(fetchCredentialsFinished(bool)),
this, SLOT(slotCredentialsFetched(bool)) );
CredentialStore::instance()->fetchCredentials();
if( CredentialStore::instance()->state() == CredentialStore::TooManyAttempts ) {
QString trayMessage = tr("Too many user attempts to enter password.");
_tray->showMessage(tr("Credentials"), trayMessage);
_actionOpenStatus->setEnabled( false );
_actionAddFolder->setEnabled( false );
}
}
void Application::slotCredentialsFetched(bool ok)
{
qDebug() << "Credentials successfully fetched: " << ok;
if( ! ok ) {
QString trayMessage;
trayMessage = tr("Error: Could not retrieve the password!");
if( CredentialStore::instance()->state() == CredentialStore::UserCanceled ) {
trayMessage = tr("Password dialog was canceled!");
}
if( !trayMessage.isEmpty() ) {
_tray->showMessage(tr("Credentials"), trayMessage);
}
qDebug() << "Could not fetch credentials";
_actionAddFolder->setEnabled( false );
_actionOpenStatus->setEnabled( false );
} else {
// Credential fetched ok.
QTimer::singleShot( 0, this, SLOT( slotCheckAuthentication() ));
}
disconnect( CredentialStore::instance(), SIGNAL(fetchCredentialsFinished(bool)) );
}
void Application::slotCheckAuthentication()
{
connect( ownCloudInfo::instance(),SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
this,SLOT(slotAuthCheck(QString,QNetworkReply*)));
qDebug() << "# checking for authentication settings.";
ownCloudInfo::instance()->getRequest(QLatin1String("/"), true ); // this call needs to be authenticated.
// simply GET the webdav root, will fail if credentials are wrong.
@@ -271,20 +308,31 @@ void Application::slotCheckAuthentication()
void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
{
bool ok = true;
if( reply->error() == QNetworkReply::AuthenticationRequiredError ) { // returned if the user is wrong.
qDebug() << "******** Password is wrong!";
QMessageBox::warning(0, tr("No ownCloud Connection"),
tr("<p>Your ownCloud credentials are not correct.</p>"
"<p>Please correct them by starting the configuration dialog from the tray!</p>"));
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appName()),
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()));
_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 ownCloud Connection"),
tr("<p>Your ownCloud user name or password is not correct.</p>"
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appName()),
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 );
} else {
ok = false;
}
// disconnect from ownCloud Info signals
disconnect( ownCloudInfo::instance(),SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
this,SLOT(slotAuthCheck(QString,QNetworkReply*)));
if( ok ) {
qDebug() << "######## Credentials are ok!";
int cnt = _folderMan->setupFolders();
if( cnt ) {
@@ -293,22 +341,58 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
processEvents();
if( _tray )
_tray->showMessage(tr("ownCloud Sync Started"), tr("Sync started for %1 configured sync folder(s).").arg(cnt));
_tray->showMessage(tr("%1 Sync Started").arg(_theme->appName()),
tr("Sync started for %1 configured sync folder(s).").arg(cnt));
_statusDialog->setFolderList( _folderMan->map() );
computeOverallSyncStatus();
}
_actionAddFolder->setEnabled( true );
setupContextMenu();
} else {
slotFetchCredentials();
}
}
void Application::slotSSLFailed( QNetworkReply *reply, QList<QSslError> errors )
{
qDebug() << "SSL-Warnings happened for url " << reply->url().toString();
if( ownCloudInfo::instance()->certsUntrusted() ) {
// User decided once to untrust. Honor this decision.
qDebug() << "Untrusted by user decision, returning.";
return;
}
// disconnect from ownCloud Info signals
disconnect( ownCloudInfo::instance(),SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
this,SLOT(slotAuthCheck(QString,QNetworkReply*)));
setupContextMenu();
QString configHandle = ownCloudInfo::instance()->configHandle(reply);
// make the ssl dialog aware of the custom config. It loads known certs.
if( ! _sslErrorDialog ) {
_sslErrorDialog = new SslErrorDialog;
}
_sslErrorDialog->setCustomConfigHandle( configHandle );
if( _sslErrorDialog->setErrorList( errors ) ) {
// all ssl certs are known and accepted. We can ignore the problems right away.
qDebug() << "Certs are already known and trusted, Warnings are not valid.";
reply->ignoreSslErrors();
} else {
if( _sslErrorDialog->exec() == QDialog::Accepted ) {
if( _sslErrorDialog->trustConnection() ) {
reply->ignoreSslErrors();
} else {
// User does not want to trust.
ownCloudInfo::instance()->setCertsUntrusted(true);
}
} else {
ownCloudInfo::instance()->setCertsUntrusted(true);
}
}
}
void Application::setupActions()
{
_actionOpenoC = new QAction(tr("Open ownCloud..."), this);
_actionOpenoC = new QAction(tr("Open %1 in browser...").arg(_theme->appName()), this);
QObject::connect(_actionOpenoC, SIGNAL(triggered(bool)), SLOT(slotOpenOwnCloud()));
_actionOpenStatus = new QAction(tr("Open status..."), this);
QObject::connect(_actionOpenStatus, SIGNAL(triggered(bool)), SLOT(slotOpenStatus()));
@@ -318,13 +402,17 @@ void Application::setupActions()
QObject::connect(_actionConfigure, SIGNAL(triggered(bool)), SLOT(slotConfigure()));
_actionConfigureProxy = new QAction(tr("Configure proxy..."), this);
QObject::connect(_actionConfigureProxy, SIGNAL(triggered(bool)), SLOT(slotConfigureProxy()));
_actionAbout = new QAction(tr("About..."), this);
QObject::connect(_actionAbout, SIGNAL(triggered(bool)), SLOT(slotAbout()));
_actionQuit = new QAction(tr("Quit"), this);
QObject::connect(_actionQuit, SIGNAL(triggered(bool)), SLOT(quit()));
}
void Application::setupSystemTray()
{
_tray = new QSystemTrayIcon(this);
// Setting a parent heres will crash on X11 since by the time qapp runs
// its childrens dtors, the X11->screen variable queried for is gone -> crash
_tray = new QSystemTrayIcon;
_tray->setIcon( _theme->applicationIcon() ); // load the grey icon
connect(_tray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
@@ -337,10 +425,19 @@ void Application::setupSystemTray()
void Application::setupContextMenu()
{
bool isConfigured = ownCloudInfo::instance()->isConfigured();
_actionOpenStatus->setEnabled(isConfigured);
_actionOpenoC->setEnabled(isConfigured);
_actionAddFolder->setEnabled(isConfigured);
if( _contextMenu ) {
_contextMenu->clear();
} else {
_contextMenu = new QMenu();
// this must be called only once after creating the context menu, or
// it will trigger a bug in Ubuntu's SNI bridge patch (11.10, 12.04).
_tray->setContextMenu(_contextMenu);
}
_contextMenu->setTitle(_theme->appName() );
_contextMenu->addAction(_actionOpenStatus);
@@ -348,58 +445,78 @@ void Application::setupContextMenu()
_contextMenu->addSeparator();
if (!_folderMan->map().isEmpty())
_contextMenu->addAction(tr("Managed Folders:"))->setDisabled(true);
int folderCnt = _folderMan->map().size();
// add open actions for all sync folders to the tray menu
if( _theme->singleSyncFolder() ) {
if( folderCnt == 0 ) {
// if there is no folder configured yet, show the add action.
_contextMenu->addAction(_actionAddFolder);
} else {
// there should be exactly one folder. No sync-folder add action will be shown.
QStringList li = _folderMan->map().keys();
if( li.size() == 1 ) {
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);
action->setIcon( _theme->trayFolderIcon( folder->backend()) );
// here all folders should be added
foreach (Folder *folder, _folderMan->map() ) {
QAction *action = new QAction( folder->alias(), this );
action->setIcon( _theme->trayFolderIcon( folder->backend()) );
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
_folderOpenActionMapper->setMapping( action, folder->alias() );
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
_folderOpenActionMapper->setMapping( action, folder->alias() );
_contextMenu->addAction(action);
}
}
}
} else {
// show a grouping with more than one folder.
if ( folderCnt ) {
_contextMenu->addAction(tr("Managed Folders:"))->setDisabled(true);
}
foreach (Folder *folder, _folderMan->map() ) {
QAction *action = new QAction( folder->alias(), this );
action->setIcon( _theme->trayFolderIcon( folder->backend()) );
_contextMenu->addAction(action);
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
_folderOpenActionMapper->setMapping( action, folder->alias() );
_contextMenu->addAction(action);
}
_contextMenu->addAction(_actionAddFolder);
}
_contextMenu->addAction(_actionAddFolder);
_contextMenu->addSeparator();
_contextMenu->addAction(_actionConfigure);
_contextMenu->addAction(_actionConfigureProxy);
_contextMenu->addSeparator();
_contextMenu->addAction(_actionAbout);
_contextMenu->addSeparator();
_contextMenu->addAction(_actionQuit);
_tray->setContextMenu(_contextMenu);
}
void Application::setupLogBrowser()
{
// init the log browser.
_logBrowser = new LogBrowser;
qInstallMsgHandler( mirallLogCatcher );
csync_set_log_callback( csyncLogCatcher );
// might be called from second instance
if (!_logBrowser) {
// init the log browser.
_logBrowser = new LogBrowser;
qInstallMsgHandler( mirallLogCatcher );
csync_set_log_callback( csyncLogCatcher );
// ## TODO: allow new log name maybe?
if (!_logFile.isEmpty()) {
qDebug() << "Logging into logfile: " << _logFile << " with flush " << _logFlush;
_logBrowser->setLogFile( _logFile, _logFlush );
}
}
if( arguments().contains(QLatin1String("--logwindow"))
|| arguments().contains(QLatin1String("-l"))) {
if (_showLogWindow)
slotOpenLogBrowser();
}
// check for command line option for a log file.
int lf = arguments().indexOf(QLatin1String("--logfile"));
if( lf > -1 && lf+1 < arguments().count() ) {
QString logfile = arguments().at( lf+1 );
bool flush = false;
if( arguments().contains(QLatin1String("--logflush"))) flush = true;
qDebug() << "Logging into logfile: " << logfile << " with flush " << flush;
_logBrowser->setLogFile( logfile, flush );
}
qDebug() << QString::fromLatin1( "################## %1 %2 %3 ").arg(_theme->appName())
.arg( QLocale::system().name() )
.arg(_theme->version());
}
void Application::setupProxy()
@@ -410,18 +527,22 @@ void Application::setupProxy()
switch(proxy) {
case QNetworkProxy::NoProxy: {
QNetworkProxy proxy;
proxy.setType(QNetworkProxy::NoProxy);
QNetworkProxy::setApplicationProxy(proxy);
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
break;
}
case QNetworkProxy::DefaultProxy: {
QNetworkProxyFactory::setUseSystemConfiguration(true);
break;
}
case QNetworkProxy::Socks5Proxy: {
proxy = QNetworkProxy::HttpProxy;
cfg.setProxyType(proxy);
// fall through
}
case QNetworkProxy::HttpProxy:{
QNetworkProxy proxy;
proxy.setType(QNetworkProxy::Socks5Proxy);
proxy.setType(QNetworkProxy::HttpProxy);
proxy.setHostName(cfg.proxyHostName());
proxy.setPort(cfg.proxyPort());
proxy.setUser(cfg.proxyUser());
@@ -466,12 +587,16 @@ void Application::slotOpenOwnCloud()
void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
{
// A click on the tray icon should only open the status window on Win and
// Linux, not on Mac. They want a menu entry.
// A click on the tray icon should only open the status window on Win and
// Linux, not on Mac. They want a menu entry.
// If the user canceled login, rather open the login window.
if( CredentialStore::instance()->state() == CredentialStore::UserCanceled ) {
slotFetchCredentials();
}
#if defined Q_WS_WIN || defined Q_WS_X11
if( reason == QSystemTrayIcon::Trigger ) {
slotOpenStatus();
}
if( reason == QSystemTrayIcon::Trigger && _actionOpenStatus->isEnabled() ) {
slotOpenStatus();
}
#endif
}
@@ -505,10 +630,11 @@ void Application::slotAddFolder()
targetPath = _folderWizard->field(QLatin1String("targetURLFolder")).toString();
onlyOnline = _folderWizard->field(QLatin1String("onlyOnline?")).toBool();
onlyThisLAN = _folderWizard->field(QLatin1String("onlyThisLAN?")).toBool();
} else if( _folderWizard->field(QLatin1String("OC?")).toBool()) {
} else if( _folderWizard->field(QLatin1String("OC?")).toBool() ||
Theme::instance()->singleSyncFolder()) {
// setup a ownCloud folder
backend = QLatin1String("owncloud");
targetPath = _folderWizard->field(QLatin1String("targetOCFolder")).toString();
targetPath = _folderWizard->field(QLatin1String("targetOCFolder")).toString(); //empty in single folder mode
} else {
qWarning() << "* Folder not local and note remote?";
goodData = false;
@@ -519,6 +645,7 @@ void Application::slotAddFolder()
Folder *f = _folderMan->setupFolderFromConfigFile( alias );
if( f ) {
_statusDialog->slotAddFolder( f );
_statusDialog->buttonsSetEnabled();
setupContextMenu();
}
}
@@ -546,7 +673,7 @@ void Application::slotOpenStatus()
if( !cfgFile.exists() ) {
qDebug() << "No configured folders yet, start the Owncloud integration dialog.";
_owncloudSetupWizard->startWizard();
_owncloudSetupWizard->startWizard(true); // with intro
} else {
qDebug() << "#============# Status dialog starting #=============#";
raiseWidget = _statusDialog;
@@ -576,6 +703,14 @@ void Application::slotOpenLogBrowser()
_logBrowser->raise();
}
void Application::slotAbout()
{
QMessageBox::about(0, tr("About %1").arg(_theme->appName()),
tr("%1 client, version %2\n\nCopyright 2012, the ownCloud developers.")
.arg(_theme->appName())
.arg(MIRALL_STRINGIFY(MIRALL_VERSION)));
}
/*
* the folder is to be removed. The slot is called from a signal emitted by
* the status dialog, which removes the folder from its list by itself.
@@ -678,42 +813,54 @@ void Application::slotInfoFolder( const QString& alias )
void Application::slotEnableFolder(const QString& alias, const bool enable)
{
qDebug() << "Application: enable folder with alias " << alias;
qDebug() << "Application: enable folder with alias " << alias;
bool terminate = false;
_folderMan->slotEnableFolder( alias, enable );
// this sets the folder status to disabled but does not interrupt it.
Folder *f = _folderMan->folder( alias );
if( f && !enable ) {
// check if a sync is still running and if so, ask if we should terminate.
if( f->isBusy() ) { // its still running
int reply = QMessageBox::question( 0, tr("Sync Running"),
tr("The syncing operation is running.<br/>Do you want to terminate it?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes );
if ( reply == QMessageBox::Yes )
terminate = true;
else
return; // do nothing
}
}
// this sets the folder status to disabled but does not interrupt it.
Folder *f = _folderMan->folder( alias );
if( f && !enable ) {
// check if a sync is still running and if so, ask if we should terminate.
if( f->isBusy() ) { // its still running
QMessageBox::StandardButton b = QMessageBox::question( 0, tr("Sync Running"),
tr("The syncing operation is running.<br/>Do you want to terminate it?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes );
if( b == QMessageBox::Yes ) {
_folderMan->terminateSyncProcess( alias );
}
}
}
// message box can return at any time while the thread keeps running,
// so better check again after the user has responded.
if ( f->isBusy() && terminate )
_folderMan->terminateSyncProcess( alias );
_statusDialog->slotUpdateFolderState( f );
_folderMan->slotEnableFolder( alias, enable );
_statusDialog->slotUpdateFolderState( f );
}
void Application::slotConfigure()
{
_folderMan->disableFoldersWithRestore();
_owncloudSetupWizard->startWizard();
_owncloudSetupWizard->startWizard(false);
_folderMan->restoreEnabledFolders();
}
void Application::slotConfigureProxy()
{
ProxyDialog* dlg = new ProxyDialog();
if (dlg->exec() == QDialog::Accepted)
ProxyDialog dlg;
if (dlg.exec() == QDialog::Accepted)
{
setupProxy();
}
dlg->deleteLater();
}
void Application::slotParseOptions(const QString &opts)
{
QStringList options = opts.split(QLatin1Char('|'));
parseOptions(options);
setupLogBrowser();
}
void Application::slotSyncStateChange( const QString& alias )
@@ -729,6 +876,31 @@ void Application::slotSyncStateChange( const QString& alias )
qDebug() << "Sync state changed for folder " << alias << ": " << result.statusString();
}
void Application::parseOptions(const QStringList &options)
{
QStringListIterator it(options);
// skip file name;
if (it.hasNext()) it.next();
while (it.hasNext()) {
QString option = it.next();
if (option == QLatin1String("--help")) {
showHelp();
} else if (option == QLatin1String("--logwindow") ||
option == QLatin1String("-l")) {
_showLogWindow = true;
} else if (option == QLatin1String("--logfile")) {
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
_logFile = it.next();
} else {
showHelp();
}
} else if (option == QLatin1String("--logflush")) {
_logFlush = true;
}
}
}
void Application::computeOverallSyncStatus()
{
@@ -744,47 +916,47 @@ void Application::computeOverallSyncStatus()
SyncResult::Status syncStatus = folderResult.status();
if( ! folderResult.localRunOnly() ) { // skip local runs, use the last message.
if( syncedFolder->syncEnabled() ) {
switch( syncStatus ) {
case SyncResult::Undefined:
if ( overallResult.status() != SyncResult::Error ) {
overallResult.setStatus(SyncResult::Error);
}
folderMessage = tr( "Undefined State." );
break;
case SyncResult::NotYetStarted:
folderMessage = tr( "Waits to start syncing." );
overallResult.setStatus( SyncResult::NotYetStarted );
break;
case SyncResult::SyncRunning:
folderMessage = tr( "Sync is running." );
overallResult.setStatus( SyncResult::SyncRunning );
break;
case SyncResult::Success:
if( overallResult.status() == SyncResult::Undefined ) {
folderMessage = tr( "Last Sync was successful." );
overallResult.setStatus( SyncResult::Success );
}
break;
case SyncResult::Error:
overallResult.setStatus( SyncResult::Error );
folderMessage = tr( "Syncing Error." );
break;
case SyncResult::SetupError:
if ( overallResult.status() != SyncResult::Error ) {
overallResult.setStatus( SyncResult::SetupError );
}
folderMessage = tr( "Setup Error." );
break;
default:
folderMessage = tr( "Undefined Error State." );
overallResult.setStatus( SyncResult::Error );
switch( syncStatus ) {
case SyncResult::Undefined:
if ( overallResult.status() != SyncResult::Error ) {
overallResult.setStatus(SyncResult::Error);
}
} else {
folderMessage = tr( "Undefined State." );
break;
case SyncResult::NotYetStarted:
folderMessage = tr( "Waits to start syncing." );
overallResult.setStatus( SyncResult::NotYetStarted );
break;
case SyncResult::SyncRunning:
folderMessage = tr( "Sync is running." );
overallResult.setStatus( SyncResult::SyncRunning );
break;
case SyncResult::Success:
if( overallResult.status() == SyncResult::Undefined ) {
folderMessage = tr( "Last Sync was successful." );
overallResult.setStatus( SyncResult::Success );
}
break;
case SyncResult::Error:
overallResult.setStatus( SyncResult::Error );
folderMessage = tr( "Syncing Error." );
break;
case SyncResult::SetupError:
if ( overallResult.status() != SyncResult::Error ) {
overallResult.setStatus( SyncResult::SetupError );
}
folderMessage = tr( "Setup Error." );
break;
default:
folderMessage = tr( "Undefined Error State." );
overallResult.setStatus( SyncResult::Error );
}
if( !syncedFolder->syncEnabled() ) {
// sync is disabled.
folderMessage = tr( "Sync is paused." );
folderMessage += tr( " (Sync is paused)" );
}
}
qDebug() << "Folder in overallStatus Message: " << syncedFolder << " with name " << syncedFolder->alias();
QString msg = QString::fromLatin1("Folder %1: %2").arg(syncedFolder->alias()).arg(folderMessage);
if( msg != _overallStatusStrings[syncedFolder->alias()] ) {
@@ -817,7 +989,8 @@ void Application::showHelp()
std::cout << " --logfile <filename> : write log output to file <filename>." << std::endl;
std::cout << " --flushlog : flush the log file after every write." << std::endl;
std::cout << std::endl;
std::cout << "For more information, see http://www.owncloud.org" << std::endl;
if (_theme->appName() == QLatin1String("ownCloud"))
std::cout << "For more information, see http://www.owncloud.org" << std::endl;
_helpOnly = true;
}

View File

@@ -18,6 +18,7 @@
#include <QApplication>
#include <QSystemTrayIcon>
#include <QNetworkReply>
#include <QSslError>
#include "qtsingleapplication.h"
@@ -40,6 +41,7 @@ class FolderWizard;
class StatusDialog;
class OwncloudSetupWizard;
class ownCloudInfo;
class SslErrorDialog;
class UpdateDetector;
class Application : public SharedTools::QtSingleApplication
@@ -61,10 +63,12 @@ protected slots:
void slotInfoFolder( const QString& );
void slotConfigure();
void slotConfigureProxy();
void slotParseOptions( const QString& );
void slotSyncStateChange( const QString& );
protected:
void parseOptions(const QStringList& );
void setupActions();
void setupSystemTray();
void setupContextMenu();
@@ -78,13 +82,16 @@ protected slots:
void slotTrayClicked( QSystemTrayIcon::ActivationReason );
void slotFolderOpenAction(const QString & );
void slotOpenOwnCloud();
void slotStartFolderSetup(int result = 1); // defaulting to Accepted
void slotStartFolderSetup(int result = QDialog::Accepted); // defaulting to Accepted
void slotOwnCloudFound( const QString&, const QString&, const QString&, const QString& );
void slotNoOwnCloudFound( QNetworkReply* );
void slotCheckAuthentication();
void slotAuthCheck( const QString& ,QNetworkReply* );
void slotOpenLogBrowser();
void slotAbout();
void slotSSLFailed( QNetworkReply *reply, QList<QSslError> errors );
void slotFetchCredentials();
void slotCredentialsFetched( bool );
void slotStartUpdateDetector();
private:
@@ -98,6 +105,7 @@ private:
QAction *_actionConfigure;
QAction *_actionOpenoC;
QAction *_actionConfigureProxy;
QAction *_actionAbout;
#if QT_VERSION >= 0x040700
QNetworkConfigurationManager *_networkMgr;
@@ -105,6 +113,7 @@ private:
FolderWizard *_folderWizard;
OwncloudSetupWizard *_owncloudSetupWizard;
SslErrorDialog *_sslErrorDialog;
// tray's menu
QMenu *_contextMenu;
@@ -116,6 +125,9 @@ private:
UpdateDetector *_updateDetector;
QMap<QString, QString> _overallStatusStrings;
LogBrowser *_logBrowser;
QString _logFile;
bool _showLogWindow;
bool _logFlush;
bool _helpOnly;
};

View File

@@ -0,0 +1,154 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <QtGui>
#include "mirall/credentialstore.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/theme.h"
namespace Mirall {
CredentialStore *CredentialStore::_instance=0;
CredentialStore::CredState CredentialStore::_state = NotFetched;
QString CredentialStore::_passwd = QString::null;
QString CredentialStore::_user = QString::null;
int CredentialStore::_tries = 0;
CredentialStore::CredentialStore(QObject *parent) :
QObject(parent)
{
}
CredentialStore *CredentialStore::instance()
{
if( !CredentialStore::_instance ) CredentialStore::_instance = new CredentialStore;
return CredentialStore::_instance;
}
QString CredentialStore::password( const QString& ) const
{
return _passwd;
}
QString CredentialStore::user( const QString& ) const
{
return _user;
}
CredentialStore::CredState CredentialStore::state()
{
return _state;
}
void CredentialStore::fetchCredentials()
{
_state = Fetching;
MirallConfigFile cfgFile;
MirallConfigFile::CredentialType t;
if( _tries++ == 3 ) {
qDebug() << "Too many attempts to enter password!";
_state = TooManyAttempts;
return;
}
t = cfgFile.credentialType();
bool ok = false;
QString pwd;
_state = Fetching;
_user = cfgFile.ownCloudUser();
switch( t ) {
case MirallConfigFile::User: {
/* Ask the user for the password */
/* Fixme: Move user interaction out here. */
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;
}
break;
}
case MirallConfigFile::Settings: {
/* Read from config file. */
pwd = cfgFile.ownCloudPasswd();
ok = true;
break;
}
case MirallConfigFile::KeyChain: {
/* Qt Keychain is not yet implemented. */
#ifdef HAVE_QTKEYCHAIN
if( !_user.isEmpty() ) {
ReadPasswordJoei b job( QLatin1String(Theme::instance()->appName()) );
job.setAutoDelete( false );
job.setKey( _user );
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), this,
SLOT(slotKeyChainFinished(QKeyChain::Job*)));
job.start();
}
#else
qDebug() << "QtKeyChain: Not yet implemented!";
#endif
break;
}
default: {
break;
}
}
if( ok ) {
_passwd = pwd;
_state = Ok;
}
if( !ok && _state == Fetching ) {
_state = Error;
}
emit( fetchCredentialsFinished(ok) );
}
#ifdef HAVE_QTKEYCHAIN
void CredentialsStore::slotKeyChainFinished(QKeyChain::Job* job)
{
if( job ) {
if( job->error() ) {
qDebug() << "Error mit keychain: " << job->errorString();
} else {
_passwd = job.textData();
}
}
}
#endif
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& user, const QString& pwd )
{
_passwd = pwd;
_user = user;
_state = Ok;
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 CREDENTIALSTORE_H
#define CREDENTIALSTORE_H
#include <QObject>
namespace Mirall {
/*
* This object holds the credential information of the ownCloud connection. It
* is implemented as a singleton.
* At startup of the client, at first the fetchCredentials() method must be called
* which tries to get credentials from one of the supported backends. To determine
* which backend should be used, MirallConfigFile::credentialType() is called as
* the backend is configured in the config file.
*
* The fetchCredentials() call changes the internal state of the credential store
* to one of
* Ok: There are credentials. Note that it's unknown if they are correct!!
* UserCanceled: The fetching involved user interaction and the user canceled
* the operation. No valid credentials are there.
* TooManyAttempts: The user tried to often to enter a password.
* Fetching: The fetching is not yet finished.
* Error: A general error happened.
* After fetching has finished, signal fetchCredentialsFinished(bool) is emitted.
* The result can be retrieved with state() and password() and user() methods.
*/
class CredentialStore : public QObject
{
Q_OBJECT
public:
enum CredState { NotFetched = 0, Ok, UserCanceled, Fetching, Error, TooManyAttempts };
QString password( const QString& connection = QString::null ) const;
QString user( const QString& connection = QString::null ) const;
/**
* @brief state
* @return the state of the Credentialstore.
*/
CredState state();
/**
* @brief fetchCredentials - start to retrieve user credentials.
*
* This method must be called first to retrieve the credentials.
* At the end, this method emits the fetchKeyChainFinished() signal.
*/
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.
*/
static CredentialStore *instance();
/**
* @brief setCredentials - sets the user credentials.
*
* This function is called from the setup wizard to set the credentials
* int this store. The function also sets the state to ok.
* @param user - the user name
* @param password - the password.
*/
void setCredentials( const QString&, const QString& );
signals:
/**
* @brief fetchCredentialsFinished
*
* emitted as soon as the fetching of the credentials has finished.
* If the parameter is true, there is a password and user. This does
* however, not say if the credentials are valid log in data.
* If false, the user pressed cancel.
*/
void fetchCredentialsFinished(bool);
private slots:
#ifdef HAVE_QTKEYCHAIN
void slotKeyChainFinished(QKeyChain::Job* job);
#endif
private:
explicit CredentialStore(QObject *parent = 0);
static CredentialStore *_instance;
static CredState _state;
static QString _passwd;
static QString _user;
static int _tries;
};
}
#endif // CREDENTIALSTORE_H

View File

@@ -15,6 +15,7 @@
#include "mirall/csyncthread.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/theme.h"
#include <QDebug>
#include <QDir>
@@ -25,23 +26,17 @@
#include <QTime>
#include <QApplication>
namespace Mirall {
/* static variables to hold the credentials */
QString CSyncThread::_user;
QString CSyncThread::_passwd;
QString CSyncThread::_proxyType;
QString CSyncThread::_proxyPwd;
QString CSyncThread::_proxyPort;
QString CSyncThread::_proxyHost;
QString CSyncThread::_proxyUser;
QNetworkProxy CSyncThread::_proxy;
QString CSyncThread::_csyncConfigDir; // to be able to remove the lock file.
QMutex CSyncThread::_mutex;
struct proxyInfo_s {
char *proxyType;
char *proxyHost;
@@ -51,75 +46,107 @@ struct proxyInfo_s {
};
typedef proxyInfo_s ProxyInfo;
int CSyncThread::checkPermissions( TREE_WALK_FILE* file, void *data )
{
WalkStats *wStats = static_cast<WalkStats*>(data);
walkStats_s::walkStats_s() {
errorType = 0;
if( !wStats ) {
qDebug() << "WalkStats is zero - must not be!";
return -1;
}
eval = 0;
removed = 0;
renamed = 0;
newFiles = 0;
conflicts = 0;
ignores = 0;
sync = 0;
error = 0;
wStats->seenFiles++;
dirPermErrors = 0;
switch(file->instruction) {
case CSYNC_INSTRUCTION_NONE:
seenFiles = 0;
break;
case CSYNC_INSTRUCTION_EVAL:
wStats->eval++;
break;
case CSYNC_INSTRUCTION_REMOVE:
wStats->removed++;
break;
case CSYNC_INSTRUCTION_RENAME:
wStats->renamed++;
break;
case CSYNC_INSTRUCTION_NEW:
wStats->newFiles++;
break;
case CSYNC_INSTRUCTION_CONFLICT:
wStats->conflicts++;
break;
case CSYNC_INSTRUCTION_IGNORE:
wStats->ignores++;
break;
case CSYNC_INSTRUCTION_SYNC:
wStats->sync++;
break;
case CSYNC_INSTRUCTION_STAT_ERROR:
case CSYNC_INSTRUCTION_ERROR:
/* instructions for the propagator */
case CSYNC_INSTRUCTION_DELETED:
case CSYNC_INSTRUCTION_UPDATED:
wStats->error++;
wStats->errorType = WALK_ERROR_INSTRUCTIONS;
break;
default:
wStats->error++;
wStats->errorType = WALK_ERROR_WALK;
break;
}
}
if( file ) {
QString source = QString::fromUtf8(wStats->sourcePath);
source.append(QString::fromUtf8(file->path));
QFileInfo fi(source);
if( fi.isDir()) { // File type directory.
if( !(fi.isWritable() && fi.isExecutable()) ) {
wStats->dirPermErrors++;
wStats->errorType = WALK_ERROR_DIR_PERMS;
}
}
}
int CSyncThread::recordStats( TREE_WALK_FILE* file )
{
if( ! file ) return -1;
_mutex.lock();
// qDebug() << wStats->seenFiles << ". Path: " << file->path << ": uid= " << file->uid << " - type: " << file->type;
if( !( wStats->errorType == WALK_ERROR_NONE || wStats->errorType == WALK_ERROR_DIR_PERMS )) {
return -1;
}
return 0;
}
_walkStats.seenFiles++;
switch(file->instruction) {
case CSYNC_INSTRUCTION_NONE:
break;
case CSYNC_INSTRUCTION_EVAL:
_walkStats.eval++;
break;
case CSYNC_INSTRUCTION_REMOVE:
_walkStats.removed++;
break;
case CSYNC_INSTRUCTION_RENAME:
_walkStats.renamed++;
break;
case CSYNC_INSTRUCTION_NEW:
_walkStats.newFiles++;
break;
case CSYNC_INSTRUCTION_CONFLICT:
_walkStats.conflicts++;
break;
case CSYNC_INSTRUCTION_IGNORE:
_walkStats.ignores++;
break;
case CSYNC_INSTRUCTION_SYNC:
_walkStats.sync++;
break;
case CSYNC_INSTRUCTION_STAT_ERROR:
case CSYNC_INSTRUCTION_ERROR:
/* instructions for the propagator */
case CSYNC_INSTRUCTION_DELETED:
case CSYNC_INSTRUCTION_UPDATED:
_walkStats.error++;
_walkStats.errorType = WALK_ERROR_INSTRUCTIONS;
break;
default:
_walkStats.error++;
_walkStats.errorType = WALK_ERROR_WALK;
break;
}
int re = 0;
// qDebug() << _walkStats.seenFiles << ". Path: " << file->path << ": uid= " << file->uid << " - type: " << file->type;
if( !( _walkStats.errorType == WALK_ERROR_NONE || _walkStats.errorType == WALK_ERROR_DIR_PERMS )) {
re = -1;
}
_mutex.unlock();
return re;
}
int CSyncThread::treewalk( TREE_WALK_FILE* file, void *data )
{
int re = static_cast<CSyncThread*>(data)->recordStats( file );
if( re > -1 )
return static_cast<CSyncThread*>(data)->treewalkFile( file );
return -1;
}
int CSyncThread::treewalkFile( TREE_WALK_FILE *file )
{
if( ! file ) return -1;
SyncFileItem item;
item.file = QString::fromUtf8( file->path );
item.instruction = file->instruction;
QFileInfo fi( _source, item.file );
if( !(fi.isWritable() && fi.isExecutable()) ) {
_walkStats.dirPermErrors++;
}
_mutex.lock();
_syncedItems.append(item);
_mutex.unlock();
return 0;
}
CSyncThread::CSyncThread(const QString &source, const QString &target, bool localCheckOnly)
@@ -138,60 +165,49 @@ CSyncThread::~CSyncThread()
}
static char* proxyTypeToCStr(QNetworkProxy::ProxyType type)
{
switch (type) {
case QNetworkProxy::NoProxy:
return qstrdup("NoProxy");
case QNetworkProxy::DefaultProxy:
return qstrdup("DefaultProxy");
case QNetworkProxy::Socks5Proxy:
return qstrdup("Socks5Proxy");
case QNetworkProxy::HttpProxy:
return qstrdup("HttpProxy");
case QNetworkProxy::HttpCachingProxy:
return qstrdup("HttpCachingProxy");
case QNetworkProxy::FtpCachingProxy:
return qstrdup("FtpCachingProxy");
default:
return qstrdup("NoProxy");
}
}
void CSyncThread::startSync()
{
qDebug() << "starting to sync " << qApp->thread() << QThread::currentThread();
CSYNC *csync;
WalkStats *wStats = new WalkStats;
QTime walkTime;
wStats->sourcePath = 0;
wStats->errorType = 0;
wStats->eval = 0;
wStats->removed = 0;
wStats->renamed = 0;
wStats->newFiles = 0;
wStats->ignores = 0;
wStats->sync = 0;
wStats->seenFiles = 0;
wStats->conflicts = 0;
wStats->error = 0;
wStats->dirPermErrors = 0;
ProxyInfo proxyInfo;
proxyInfo.proxyHost = 0;
proxyInfo.proxyPort = 0;
proxyInfo.proxyPwd = 0;
proxyInfo.proxyType = 0;
proxyInfo.proxyUser = 0;
emit(started());
_mutex.lock();
if( !_proxyType.isEmpty() ) {
proxyInfo.proxyType = qstrdup( _proxyType.toAscii().constData() );
}
if( !_proxyHost.isEmpty() ) {
proxyInfo.proxyHost = qstrdup( _proxyHost.toAscii().constData() );
}
if( !_proxyPort.isEmpty() ) {
proxyInfo.proxyPort = qstrdup( _proxyPort.toAscii().constData() );
}
if( !_proxyUser.isEmpty() ) {
proxyInfo.proxyUser = qstrdup( _proxyUser.toAscii().constData() );
}
if( !_proxyPwd.isEmpty() ) {
proxyInfo.proxyPwd = qstrdup( _proxyPwd.toAscii().constData() );
}
emit(started());
proxyInfo.proxyType = proxyTypeToCStr( _proxy.type() );
proxyInfo.proxyHost = qstrdup( _proxy.hostName().toAscii().constData() );
proxyInfo.proxyPort = qstrdup( QByteArray::number( _proxy.port() ).constData() );
proxyInfo.proxyUser = qstrdup( _proxy.user().toAscii().constData() );
proxyInfo.proxyPwd = qstrdup( _proxy.password().toAscii().constData() );
if( csync_create(&csync,
_source.toUtf8().data(),
_target.toUtf8().data()) < 0 ) {
emit csyncError( tr("CSync create failed.") );
}
// FIXME: Check if we really need this stringcopy!
wStats->sourcePath = qstrdup( _source.toUtf8().constData() );
_csyncConfigDir = QString::fromUtf8( csync_get_config_dir( csync ));
_mutex.unlock();
@@ -208,6 +224,8 @@ void CSyncThread::startSync()
csync_add_exclude_list( csync, excludeList.toAscii() );
}
csync_set_config_dir( csync, cfg.configPath().toUtf8() );
QTime t;
t.start();
@@ -247,7 +265,7 @@ void CSyncThread::startSync()
emit wipeDb();
break;
case CSYNC_ERR_MODULE:
errStr = tr("<p>The ownCloud plugin for csync could not be loaded.<br/>Please verify the installation!</p>");
errStr = tr("<p>The %1 plugin for csync could not be loaded.<br/>Please verify the installation!</p>").arg(Theme::instance()->appName());
break;
case CSYNC_ERR_LOCAL_CREATE:
case CSYNC_ERR_LOCAL_STAT:
@@ -285,15 +303,15 @@ void CSyncThread::startSync()
}
qDebug() << "<<#### Update end ###########################################################";
csync_set_userdata(csync, wStats);
csync_set_userdata(csync, this);
walkTime.start();
if( csync_walk_local_tree(csync, &checkPermissions, 0) < 0 ) {
if( csync_walk_local_tree(csync, &treewalk, 0) < 0 ) {
qDebug() << "Error in treewalk.";
if( wStats->errorType == WALK_ERROR_WALK ) {
if( _walkStats.errorType == WALK_ERROR_WALK ) {
emit csyncError(tr("CSync encountered an error while examining the file system.\n"
"Syncing is not possible."));
} else if( wStats->errorType == WALK_ERROR_INSTRUCTIONS ) {
} else if( _walkStats.errorType == WALK_ERROR_INSTRUCTIONS ) {
emit csyncError(tr("CSync update generated a strange instruction.\n"
"Please write a bug report."));
}
@@ -301,15 +319,15 @@ void CSyncThread::startSync()
goto cleanup;
} else {
// only warn, do not stop the sync process.
if( wStats->errorType == WALK_ERROR_DIR_PERMS ) {
if( _walkStats.errorType == WALK_ERROR_DIR_PERMS ) {
emit csyncError(tr("The local filesystem has %1 write protected directories."
"That can hinder successful syncing.<p/>"
"Please make sure that all local directories are writeable.").arg(wStats->dirPermErrors));
"Please make sure that all local directories are writeable.").arg(_walkStats.dirPermErrors));
}
}
// emit the treewalk results. Do not touch the wStats after this.
emit treeWalkResult(wStats);
// emit the treewalk results.
emit treeWalkResult(_syncedItems, _walkStats);
_mutex.lock();
if( _localCheckOnly ) {
@@ -326,18 +344,18 @@ void CSyncThread::startSync()
goto cleanup;
}
if( csync_propagate(csync) < 0 ) {
emit csyncError(tr("CSync propagate failed."));
emit csyncError(tr("File exchange with ownCloud failed. Sync was stopped."));
goto cleanup;
}
}
cleanup:
csync_destroy(csync);
if( proxyInfo.proxyType ) delete( proxyInfo.proxyType );
if( proxyInfo.proxyHost ) delete( proxyInfo.proxyHost );
if( proxyInfo.proxyPort ) delete( proxyInfo.proxyPort );
if( proxyInfo.proxyUser ) delete( proxyInfo.proxyUser );
if( proxyInfo.proxyPwd ) delete( proxyInfo.proxyPwd );
if( proxyInfo.proxyType ) delete[] proxyInfo.proxyType;
if( proxyInfo.proxyHost ) delete[] proxyInfo.proxyHost;
if( proxyInfo.proxyPort ) delete[] proxyInfo.proxyPort;
if( proxyInfo.proxyUser ) delete[] proxyInfo.proxyUser;
if( proxyInfo.proxyPwd ) delete[] proxyInfo.proxyPwd ;
/*
* Attention: do not delete the wStat memory here. it is deleted in the
@@ -362,19 +380,12 @@ void CSyncThread::emitStateDb( CSYNC *csync )
}
}
void CSyncThread::setConnectionDetails( const QString& user, const QString& passwd,
const QString& proxyType, const QString& proxyHost,
int proxyPort , const QString& proxyUser, const QString& proxyPwd )
void CSyncThread::setConnectionDetails( const QString &user, const QString &passwd, const QNetworkProxy &proxy )
{
_mutex.lock();
_user = user;
_passwd = passwd;
_proxyType = proxyType;
_proxyHost = proxyHost;
_proxyPort = QString::number(proxyPort);
qDebug() << "Proxy-Port: " << _proxyPort;
_proxyUser = proxyUser;
_proxyPwd = proxyPwd;
_proxy = proxy;
_mutex.unlock();
}

View File

@@ -21,6 +21,7 @@
#include <QMutex>
#include <QThread>
#include <QString>
#include <QNetworkProxy>
#include <csync.h>
@@ -36,7 +37,8 @@ enum walkErrorTypes {
};
struct walkStats_s {
const char *sourcePath;
walkStats_s();
int errorType;
ulong eval;
@@ -55,6 +57,14 @@ struct walkStats_s {
typedef walkStats_s WalkStats;
struct syncFileItem_s {
QString file;
csync_instructions_e instruction;
};
typedef syncFileItem_s SyncFileItem;
typedef QVector<SyncFileItem> SyncFileItemVector;
class CSyncThread : public QObject
{
Q_OBJECT
@@ -62,15 +72,13 @@ public:
CSyncThread(const QString &source, const QString &target, bool = false);
~CSyncThread();
static void setConnectionDetails( const QString&, const QString&,
const QString&, const QString&, int,
const QString&, const QString& );
static void setConnectionDetails( const QString&, const QString&, const QNetworkProxy& );
static QString csyncConfigDir();
Q_INVOKABLE void startSync();
signals:
void treeWalkResult(WalkStats*);
void treeWalkResult(const SyncFileItemVector&, const WalkStats&);
void csyncError( const QString& );
void csyncStateDbFile( const QString& );
@@ -80,8 +88,10 @@ signals:
void started();
private:
static int checkPermissions( TREE_WALK_FILE* file, void *data);
static int treewalk( TREE_WALK_FILE* file, void *data );
int recordStats( TREE_WALK_FILE* file);
void emitStateDb( CSYNC *csync );
int treewalkFile( TREE_WALK_FILE* );
static int getauth(const char *prompt,
char *buf,
@@ -94,17 +104,16 @@ private:
static QMutex _mutex;
static QString _user;
static QString _passwd;
static QString _proxyType;
static QString _proxyHost;
static QString _proxyPort;
static QString _proxyUser;
static QString _proxyPwd;
static QNetworkProxy _proxy;
static QString _csyncConfigDir;
QString _source;
QString _target;
bool _localCheckOnly;
QVector <SyncFileItem> _syncedItems;
WalkStats _walkStats;
};
}

View File

@@ -70,18 +70,52 @@ Folder::Folder(const QString &alias, const QString &path, const QString& secondP
_online = true;
#endif
_pathWatcher = new QFileSystemWatcher(this);
_pathWatcher->addPath( _path );
connect(_pathWatcher, SIGNAL(directoryChanged(QString)),SLOT(slotLocalPathChanged(QString)));
_syncResult.setStatus( SyncResult::NotYetStarted );
// check if the local path exists
checkLocalPath();
}
Folder::~Folder()
{
}
void Folder::checkLocalPath()
{
QFileInfo fi(_path);
if( fi.isDir() && fi.isReadable() ) {
qDebug() << "Checked local path ok";
} else {
if( !fi.exists() ) {
// try to create the local dir
QDir d(_path);
if( d.mkpath(_path) ) {
qDebug() << "Successfully created the local dir " << _path;
}
}
// Check directory again
if( !fi.exists() ) {
_syncResult.setErrorString(tr("Local folder %1 does not exist.").arg(_path));
_syncResult.setStatus( SyncResult::SetupError );
} else if( !fi.isDir() ) {
_syncResult.setErrorString(tr("%1 should be a directory but is not.").arg(_path));
_syncResult.setStatus( SyncResult::SetupError );
} else if( !fi.isReadable() ) {
_syncResult.setErrorString(tr("%1 is not readable.").arg(_path));
_syncResult.setStatus( SyncResult::SetupError );
}
}
// if all is fine, connect a FileSystemWatcher
if( _syncResult.status() != SyncResult::SetupError ) {
_pathWatcher = new QFileSystemWatcher(this);
_pathWatcher->addPath( _path );
connect(_pathWatcher, SIGNAL(directoryChanged(QString)),
SLOT(slotLocalPathChanged(QString)));
}
}
QString Folder::alias() const
{
return _alias;
@@ -89,7 +123,11 @@ QString Folder::alias() const
QString Folder::path() const
{
return _path;
QString p(_path);
if( ! p.endsWith(QLatin1Char('/')) ) {
p.append(QLatin1Char('/'));
}
return p;
}
QString Folder::secondPath() const
@@ -104,7 +142,7 @@ QString Folder::nativePath() const
QString Folder::nativeSecondPath() const
{
return QDir::toNativeSeparators(_secondPath);
return secondPath();
}
bool Folder::syncEnabled() const
@@ -281,6 +319,16 @@ void Folder::slotLocalPathChanged( const QString& dir )
}
}
void Folder::setConfigFile( const QString& file )
{
_configFile = file;
}
QString Folder::configFile()
{
return _configFile;
}
void Folder::setBackend( const QString& b )
{
_backend = b;

View File

@@ -137,6 +137,12 @@ public:
*/
QString backend() const;
/**
* set the config file name.
*/
void setConfigFile( const QString& );
QString configFile();
/**
* This is called if the sync folder definition is removed. Do cleanups here.
*/
@@ -192,11 +198,14 @@ private:
*/
void evaluateSync(const QStringList &pathList);
virtual void checkLocalPath();
QString _path;
QString _secondPath;
QString _alias;
bool _onlyOnlineEnabled;
bool _onlyThisLANEnabled;
QString _configFile;
QFileSystemWatcher *_pathWatcher;

View File

@@ -19,6 +19,7 @@
#include "mirall/owncloudfolder.h"
#include "mirall/syncresult.h"
#include "mirall/inotify.h"
#include "mirall/theme.h"
#include <QDesktopServices>
#include <QtCore>
@@ -92,37 +93,106 @@ int FolderMan::setupKnownFolders()
return _folderMap.size();
}
#define SLASH_TAG QLatin1String("__SLASH__")
#define BSLASH_TAG QLatin1String("__BSLASH__")
#define QMARK_TAG QLatin1String("__QMARK__")
#define PERCENT_TAG QLatin1String("__PERCENT__")
#define STAR_TAG QLatin1String("__STAR__")
#define COLON_TAG QLatin1String("__COLON__")
#define PIPE_TAG QLatin1String("__PIPE__")
#define QUOTE_TAG QLatin1String("__QUOTE__")
#define LT_TAG QLatin1String("__LESS_THAN__")
#define GT_TAG QLatin1String("__GREATER_THAN__")
#define PAR_O_TAG QLatin1String("__PAR_OPEN__")
#define PAR_C_TAG QLatin1String("__PAR_CLOSE__")
QString FolderMan::escapeAlias( const QString& alias ) const
{
QString a(alias);
a.replace( QLatin1Char('/'), SLASH_TAG );
a.replace( QLatin1Char('\\'), BSLASH_TAG );
a.replace( QLatin1Char('?'), QMARK_TAG );
a.replace( QLatin1Char('%'), PERCENT_TAG );
a.replace( QLatin1Char('*'), STAR_TAG );
a.replace( QLatin1Char(':'), COLON_TAG );
a.replace( QLatin1Char('|'), PIPE_TAG );
a.replace( QLatin1Char('"'), QUOTE_TAG );
a.replace( QLatin1Char('<'), LT_TAG );
a.replace( QLatin1Char('>'), GT_TAG );
a.replace( QLatin1Char('['), PAR_O_TAG );
a.replace( QLatin1Char(']'), PAR_C_TAG );
return a;
}
QString FolderMan::unescapeAlias( const QString& alias ) const
{
QString a(alias);
a.replace( SLASH_TAG, QLatin1String("/") );
a.replace( BSLASH_TAG, QLatin1String("\\") );
a.replace( QMARK_TAG, QLatin1String("?") );
a.replace( PERCENT_TAG, QLatin1String("%") );
a.replace( STAR_TAG, QLatin1String("*") );
a.replace( COLON_TAG, QLatin1String(":") );
a.replace( PIPE_TAG, QLatin1String("|") );
a.replace( QUOTE_TAG, QLatin1String("\"") );
a.replace( LT_TAG, QLatin1String("<") );
a.replace( GT_TAG, QLatin1String(">") );
a.replace( PAR_O_TAG, QLatin1String("[") );
a.replace( PAR_C_TAG, QLatin1String("]") );
return a;
}
// filename is the name of the file only, it does not include
// the configuration directory path
Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
Folder *folder = 0L;
Folder *folder = 0;
qDebug() << " ` -> setting up:" << file;
QSettings settings( _folderConfigPath + QLatin1Char('/') + file, QSettings::IniFormat);
qDebug() << " -> file path: " << settings.fileName();
QString escapedAlias(file);
// check the unescaped variant (for the case the filename comes out
// of the directory listing. If the file is not existing, escape the
// file and try again.
QFileInfo cfgFile( _folderConfigPath, file);
settings.beginGroup( file ); // read the group with the same name as the file which is the folder alias
QString path = settings.value(QLatin1String("localpath")).toString();
if ( path.isNull() || !QFileInfo( path ).isDir() ) {
qWarning() << " `->" << path << "does not exist. Skipping folder" << file;
// _tray->showMessage(tr("Unknown folder"),
// tr("Folder %1 does not exist").arg(path.toString()),
// QSystemTrayIcon::Critical);
if( !cfgFile.exists() ) {
// try the escaped variant.
escapedAlias = escapeAlias(file);
cfgFile.setFile( _folderConfigPath, escapedAlias );
}
if( !cfgFile.isReadable() ) {
qDebug() << "Can not read folder definition for alias " << cfgFile.filePath();
return folder;
}
QSettings settings( cfgFile.filePath(), QSettings::IniFormat);
qDebug() << " -> file path: " << settings.fileName();
// Check if the filename is equal to the group setting. If not, use the group
// name as an alias.
QStringList groups = settings.childGroups();
if( ! groups.contains(escapedAlias) && groups.count() > 0 ) {
escapedAlias = groups.first();
}
settings.beginGroup( escapedAlias ); // read the group with the same name as the file which is the folder alias
QString path = settings.value(QLatin1String("localpath")).toString();
QString backend = settings.value(QLatin1String("backend")).toString();
QString targetPath = settings.value( QLatin1String("targetPath") ).toString();
QString connection = settings.value( QLatin1String("connection") ).toString();
// QString connection = settings.value( QLatin1String("connection") ).toString();
QString alias = unescapeAlias( escapedAlias );
if (!backend.isEmpty()) {
if (backend == QLatin1String("unison")) {
folder = new UnisonFolder(file, path, targetPath, this );
folder = new UnisonFolder(alias, path, targetPath, this );
} else if (backend == QLatin1String("csync")) {
#ifdef WITH_CSYNC
folder = new CSyncFolder(file, path, targetPath, this );
folder = new CSyncFolder(alias, path, targetPath, this );
#else
qCritical() << "* csync support not enabled!! ignoring:" << file;
#endif
@@ -140,7 +210,8 @@ Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
targetPath.remove(0,1);
}
folder = new ownCloudFolder( file, path, oCUrl + targetPath, this );
folder = new ownCloudFolder( alias, path, oCUrl + targetPath, this );
folder->setConfigFile(file);
#else
qCritical() << "* owncloud support not enabled!! ignoring:" << file;
#endif
@@ -149,21 +220,23 @@ Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
return NULL;
}
}
folder->setBackend( backend );
// folder->setOnlyOnlineEnabled(settings.value("folder/onlyOnline", false).toBool());
folder->setOnlyThisLANEnabled(settings.value(QLatin1String("folder/onlyThisLAN"), false).toBool());
_folderMap[file] = folder;
if( folder ) {
folder->setBackend( backend );
// folder->setOnlyOnlineEnabled(settings.value("folder/onlyOnline", false).toBool());
folder->setOnlyThisLANEnabled(settings.value(QLatin1String("folder/onlyThisLAN"), false).toBool());
qDebug() << "Adding folder to Folder Map " << folder;
/* Use a signal mapper to connect the signals to the alias */
connect(folder, SIGNAL(scheduleToSync(const QString&)), SLOT(slotScheduleSync(const QString&)));
connect(folder, SIGNAL(syncStateChange()), _folderChangeSignalMapper, SLOT(map()));
connect(folder, SIGNAL(syncStarted()), SLOT(slotFolderSyncStarted()));
connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult)));
_folderMap[alias] = folder;
_folderChangeSignalMapper->setMapping( folder, folder->alias() );
qDebug() << "Adding folder to Folder Map " << folder;
/* Use a signal mapper to connect the signals to the alias */
connect(folder, SIGNAL(scheduleToSync(const QString&)), SLOT(slotScheduleSync(const QString&)));
connect(folder, SIGNAL(syncStateChange()), _folderChangeSignalMapper, SLOT(map()));
connect(folder, SIGNAL(syncStarted()), SLOT(slotFolderSyncStarted()));
connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult)));
_folderChangeSignalMapper->setMapping( folder, folder->alias() );
}
return folder;
}
@@ -286,7 +359,7 @@ void FolderMan::slotFolderSyncStarted( )
*/
void FolderMan::slotFolderSyncFinished( const SyncResult& )
{
qDebug() << "<===================================== sync finsihed for " << _currentSyncFolder;
qDebug() << "<===================================== sync finished for " << _currentSyncFolder;
_currentSyncFolder.clear();
QTimer::singleShot(200, this, SLOT(slotScheduleFolderSync()));
@@ -305,14 +378,15 @@ void FolderMan::addFolderDefinition( const QString& backend, const QString& alia
const QString& sourceFolder, const QString& targetPath,
bool onlyThisLAN )
{
QString escapedAlias = escapeAlias(alias);
// Create a settings file named after the alias
QSettings settings( _folderConfigPath + QLatin1Char('/') + alias, QSettings::IniFormat);
QSettings settings( _folderConfigPath + QLatin1Char('/') + escapedAlias, QSettings::IniFormat);
settings.setValue(QString::fromLatin1("%1/localPath").arg(alias), sourceFolder );
settings.setValue(QString::fromLatin1("%1/targetPath").arg(alias), targetPath );
settings.setValue(QString::fromLatin1("%1/backend").arg(alias), backend );
settings.setValue(QString::fromLatin1("%1/connection").arg(alias), QLatin1String("ownCloud"));
settings.setValue(QString::fromLatin1("%1/onlyThisLAN").arg(alias), onlyThisLAN );
settings.setValue(QString::fromLatin1("%1/localPath").arg(escapedAlias), sourceFolder );
settings.setValue(QString::fromLatin1("%1/targetPath").arg(escapedAlias), targetPath );
settings.setValue(QString::fromLatin1("%1/backend").arg(escapedAlias), backend );
settings.setValue(QString::fromLatin1("%1/connection").arg(escapedAlias), Theme::instance()->appName());
settings.setValue(QString::fromLatin1("%1/onlyThisLAN").arg(escapedAlias), onlyThisLAN );
settings.sync();
}
@@ -341,19 +415,23 @@ void FolderMan::slotRemoveFolder( const QString& alias )
// remove a folder from the map. Should be sure n
void FolderMan::removeFolder( const QString& alias )
{
Folder *f = 0;
if( _folderMap.contains( alias )) {
qDebug() << "Removing " << alias;
Folder *f = _folderMap.take( alias );
f->wipe();
f->deleteLater();
qDebug() << "Removing " << alias;
f = _folderMap.take( alias );
f->wipe();
} else {
qDebug() << "!! Can not remove " << alias << ", not in folderMap.";
qDebug() << "!! Can not remove " << alias << ", not in folderMap.";
}
QFile file( _folderConfigPath + QLatin1Char('/') + alias );
if( file.exists() ) {
qDebug() << "Remove folder config file " << file.fileName();
file.remove();
if( f ) {
QFile file( _folderConfigPath + QLatin1Char('/') + f->configFile() );
if( file.exists() ) {
qDebug() << "Remove folder config file " << file.fileName();
file.remove();
}
f->deleteLater();
}
}

View File

@@ -27,7 +27,6 @@ class QSignalMapper;
namespace Mirall {
class SyncResult;
class OwncloudSetup;
class FolderMan : public QObject
{
@@ -103,13 +102,17 @@ private:
// and create the folders
int setupKnownFolders();
// Escaping of the alias which is used in QSettings AND the file
// system, thus need to be escaped.
QString escapeAlias( const QString& ) const;
QString unescapeAlias( const QString& ) const;
void removeFolder( const QString& );
FolderWatcher *_configFolderWatcher;
Folder::Map _folderMap;
QHash<QString, bool> _folderEnabledMap;
QString _folderConfigPath;
OwncloudSetup *_ownCloudSetup;
QSignalMapper *_folderChangeSignalMapper;
QString _currentSyncFolder;
QStringList _scheduleQueue;

View File

@@ -36,9 +36,9 @@ FolderWizardSourcePage::FolderWizardSourcePage()
{
_ui.setupUi(this);
registerField(QLatin1String("sourceFolder*"), _ui.localFolderLineEdit);
_ui.localFolderLineEdit->setText( QString::fromLatin1( "%1/%2").arg( QDir::homePath() ).arg(QLatin1String("ownCloud") ) );
_ui.localFolderLineEdit->setText( QString::fromLatin1( "%1/%2").arg( QDir::homePath() ).arg(Theme::instance()->appName() ) );
registerField(QLatin1String("alias*"), _ui.aliasLineEdit);
_ui.aliasLineEdit->setText( QString::fromLatin1("ownCloud") );
_ui.aliasLineEdit->setText( Theme::instance()->appName() );
_ui.warnLabel->hide();
#if QT_VERSION >= 0x040700
@@ -208,7 +208,8 @@ void FolderWizardTargetPage::slotDirCheckReply(const QString &url, QNetworkReply
if( _dirChecked ) {
showWarn();
} else {
showWarn( tr("The folder is not available on your ownCloud.<br/>Click to let mirall create it."), true );
showWarn( tr("The folder is not available on your %1.<br/>Click to create it." )
.arg( Theme::instance()->appName() ), true );
}
emit completeChanged();
@@ -233,10 +234,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 on ownCloud was successfully created."), false );
showWarn( tr("Folder was successfully created on %1.").arg( Theme::instance()->appName() ), false );
slotTimerFires();
} else {
showWarn( tr("Failed to create the folder on ownCloud.<br/>Please check manually."), false );
showWarn( tr("Failed to create the folder on %1.<br/>Please check manually.").arg( Theme::instance()->appName() ), false );
}
}
@@ -311,7 +312,8 @@ void FolderWizardTargetPage::slotOwnCloudFound( const QString& url, const QStrin
if( infoStr.isEmpty() ) {
} else {
_ui.OCLabel->setText( tr("to your <a href=\"%1\">ownCloud</a> (version %2)").arg(url).arg(infoStr));
_ui.OCLabel->setText( tr("to your <a href=\"%1\">%2</a> (version %3)").arg(url)
.arg(Theme::instance()->appName()).arg(infoStr));
_ui.OCFolderLineEdit->setEnabled( true );
_ui.OCRadioBtn->setEnabled( true );
qDebug() << "ownCloud found on " << url << " with version: " << infoStr;
@@ -321,8 +323,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 ownCloud found!") );
showWarn( tr("Your ownCloud could not be reached:<br/><tt>%1</tt>").arg(error->errorString()));
_ui.OCLabel->setText( tr("no configured %1 found!").arg(Theme::instance()->appName()) );
showWarn( tr("%1 could not be reached:<br/><tt>%2</tt>")
.arg(Theme::instance()->appName()).arg(error->errorString()));
_ui.OCRadioBtn->setEnabled( false );
_ui.OCFolderLineEdit->setEnabled( false );
}
@@ -450,18 +453,17 @@ bool FolderWizardOwncloudPage::isComplete() const
* Folder wizard itself
*/
FolderWizard::FolderWizard( QWidget *parent, Theme *theme )
FolderWizard::FolderWizard( QWidget *parent )
: QWizard(parent),
_folderWizardSourcePage(0)
{
_folderWizardSourcePage = new FolderWizardSourcePage();
setPage(Page_Source, _folderWizardSourcePage );
setPage(Page_Target, new FolderWizardTargetPage());
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 ? theme->appName()
: QLatin1String("Mirall") ) );
setWindowTitle( tr( "%1 Folder Wizard" ).arg( Theme::instance()->appName() ) );
#ifdef Q_WS_MAC
setWizardStyle( QWizard::ModernStyle );
#endif

View File

@@ -136,8 +136,6 @@ private:
/**
*
*/
class Theme;
class FolderWizard : public QWizard
{
Q_OBJECT
@@ -150,7 +148,7 @@ public:
Page_Owncloud
};
FolderWizard(QWidget *parent = 0L, Theme *theme = 0);
FolderWizard(QWidget *parent = 0);
void setFolderMap( Folder::Map* );
private:

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>454</width>
<height>397</height>
<width>520</width>
<height>360</height>
</rect>
</property>
<property name="windowTitle">
@@ -66,6 +66,16 @@
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../mirall.qrc">:/mirall/resources/owncloud-icon-48.png</pixmap>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="OCLabel">
<property name="font">
@@ -86,24 +96,18 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Folder on ownCloud:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="OCFolderLineEdit"/>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../mirall.qrc">:/mirall/resources/mirall-48.png</pixmap>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Folder on ownCloud:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="OCFolderLineEdit"/>
</item>
</layout>
</item>
</layout>
</widget>

View File

@@ -12,9 +12,12 @@
* for more details.
*/
#include "config.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/owncloudtheme.h"
#include "mirall/miralltheme.h"
#include "mirall/credentialstore.h"
#include <QtCore>
#include <QtGui>
@@ -23,14 +26,10 @@
#define DEFAULT_LOCAL_POLL_INTERVAL 10000 // default local poll time in milliseconds
#define DEFAULT_POLL_TIMER_EXEED 10
#define OC_ORGANIZATION QLatin1String("ownCloud")
#define OC_APPLICATION QLatin1String("ownCloudClient")
#define CA_CERTS_KEY QLatin1String("CaCertificates")
namespace Mirall {
QString MirallConfigFile::_passwd;
QString MirallConfigFile::_oCVersion;
bool MirallConfigFile::_askedUser = false;
@@ -48,27 +47,33 @@ QString MirallConfigFile::configPath() const
QString MirallConfigFile::excludeFile() const
{
const QString exclFile(QLatin1String("exclude.lst"));
QString dir = configPath();
dir += exclFile;
// prefer sync-exclude.lst, but if it does not exist, check for
// exclude.lst for compatibility reasonsin the user writeable
// directories.
const QString exclFile("sync-exclude.lst");
QFileInfo fi( dir );
if( fi.isReadable() ) {
return dir;
QFileInfo fi;
fi.setFile( configPath(), exclFile );
if( ! fi.isReadable() ) {
fi.setFile( configPath(), QLatin1String("exclude.lst") );
}
// Check alternative places...
if( ! fi.isReadable() ) {
#ifdef Q_OS_WIN32
fi.setFile( QApplication::applicationDirPath(), exclFile );
fi.setFile( QApplication::applicationDirPath(), exclFile );
#endif
#ifdef Q_OS_LINUX
fi.setFile( QString("/etc"), exclFile );
fi.setFile( QString("/etc/%1").arg(Theme::instance()->appName()), exclFile );
#endif
#ifdef Q_OS_MAC
// exec path is inside the bundle
fi.setFile( QApplication::applicationDirPath(),
QLatin1String("../Resources/") + exclFile );
// exec path is inside the bundle
fi.setFile( QApplication::applicationDirPath(),
QLatin1String("../Resources/") + exclFile );
#endif
}
if( fi.isReadable() ) {
qDebug() << " ==> returning exclude file path: " << fi.absoluteFilePath();
return fi.absoluteFilePath();
@@ -79,15 +84,10 @@ QString MirallConfigFile::excludeFile() const
QString MirallConfigFile::configFile() const
{
#ifdef OWNCLOUD_CLIENT
ownCloudTheme theme;
#else
mirallTheme theme;
#endif
if( qApp->applicationName().isEmpty() ) {
qApp->setApplicationName( theme.appName() );
qApp->setApplicationName( Theme::instance()->appName() );
}
QString dir = configPath() + theme.configFileName();
QString dir = configPath() + Theme::instance()->configFileName();
if( !_customHandle.isEmpty() ) {
dir.append( QLatin1Char('_'));
dir.append( _customHandle );
@@ -104,7 +104,7 @@ bool MirallConfigFile::exists()
QString MirallConfigFile::defaultConnection() const
{
return QLatin1String("ownCloud");
return Theme::instance()->appName();
}
bool MirallConfigFile::connectionExists( const QString& conn )
@@ -151,10 +151,12 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
settings.setValue( QLatin1String("nostoredpassword"), QVariant(skipPwd) );
settings.sync();
// check the perms, only read-write for the owner.
QFile::setPermissions( file, QFile::ReadOwner|QFile::WriteOwner );
// inform the credential store about the password change.
CredentialStore::instance()->setCredentials( user, pwd );
}
// set the url, called from redirect handling.
@@ -313,6 +315,24 @@ int MirallConfigFile::pollTimerExceedFactor( const QString& connection ) const
return pte;
}
MirallConfigFile::CredentialType MirallConfigFile::credentialType() const
{
QString con; /* ( connection ); */
/* if( connection.isEmpty() ) */ con = defaultConnection();
CredentialType ct = Settings;
QSettings settings( configFile(), QSettings::IniFormat );
settings.setIniCodec( "UTF-8" );
settings.beginGroup( con );
bool skipPwd = settings.value( QLatin1String("nostoredpassword"), false ).toBool();
if( skipPwd ) {
ct = User;
}
return ct;
}
QString MirallConfigFile::ownCloudPasswd( const QString& connection ) const
{
QString con( connection );
@@ -324,38 +344,22 @@ QString MirallConfigFile::ownCloudPasswd( const QString& connection ) const
QString pwd;
bool skipPwd = settings.value( QLatin1String("nostoredpassword"), false ).toBool();
if( skipPwd ) {
if( ! _askedUser ) {
bool ok;
QString text = QInputDialog::getText(0, QApplication::translate("MirallConfigFile","ownCloud Password Required"),
QApplication::translate("MirallConfigFile","Please enter your ownCloud password:"),
QLineEdit::Password,
QString::null, &ok);
if( ok && !text.isEmpty() ) { // empty password is not allowed on ownCloud
_passwd = text;
_askedUser = true;
}
}
pwd = _passwd;
} else {
QByteArray pwdba = settings.value(QLatin1String("passwd")).toByteArray();
if( pwdba.isEmpty() ) {
// check the password entry, cleartext from before
// read it and convert to base64, delete the cleartext entry.
QString p = settings.value(QLatin1String("password")).toString();
QByteArray pwdba = settings.value(QLatin1String("passwd")).toByteArray();
if( pwdba.isEmpty() ) {
// check the password entry, cleartext from before
// read it and convert to base64, delete the cleartext entry.
QString p = settings.value(QLatin1String("password")).toString();
if( ! p.isEmpty() ) {
// its there, save base64-encoded and delete.
if( ! p.isEmpty() ) {
// its there, save base64-encoded and delete.
pwdba = p.toUtf8();
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
settings.remove( QLatin1String("password") );
settings.sync();
}
pwdba = p.toUtf8();
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
settings.remove( QLatin1String("password") );
settings.sync();
}
pwd = QString::fromUtf8( QByteArray::fromBase64(pwdba) );
}
pwd = QString::fromUtf8( QByteArray::fromBase64(pwdba) );
return pwd;
}
@@ -395,15 +399,6 @@ int MirallConfigFile::maxLogLines() const
return logLines;
}
QByteArray MirallConfigFile::basicAuthHeader() const
{
QString concatenated = ownCloudUser() + QLatin1Char(':') + ownCloudPasswd();
const QString b(QLatin1String("Basic "));
QByteArray data = b.toLocal8Bit() + concatenated.toLocal8Bit().toBase64();
return data;
}
// remove a custom config file.
void MirallConfigFile::cleanupCustomConfig()
{
@@ -468,15 +463,22 @@ QVariant MirallConfigFile::customMedia( customMediaType type )
}
if( !key.isEmpty() ) {
#ifdef Q_OS_WIN32
const QString customFile("custom.ini");
QFileInfo fi;
fi.setFile( QApplication::applicationDirPath(), QLatin1String("ownCloudClient.ini"));
qDebug() << "Custom Config file: " << fi.absoluteFilePath();
QSettings settings( fi.absoluteFilePath(), QSettings::IniFormat );
#else
QSettings settings( QSettings::IniFormat, QSettings::SystemScope, OC_ORGANIZATION, OC_APPLICATION );
#ifdef Q_OS_WIN32
fi.setFile( QApplication::applicationDirPath(), customFile );
#endif
#ifdef Q_OS_MAC
// exec path is inside the bundle
fi.setFile( QApplication::applicationDirPath(),
QLatin1String("../Resources/") + customFile );
#endif
#ifdef Q_OS_LINUX
fi.setFile( QString("/etc/%1").arg(Theme::instance()->appName()), customFile );
#endif
QSettings settings( fi.absoluteFilePath(), QSettings::IniFormat );
QString cfg = settings.fileName();
qDebug() << "Trying to read config ini file at " << cfg;

View File

@@ -24,6 +24,9 @@ namespace Mirall {
class MirallConfigFile
{
/* let only CredentialStore read the password from the file. All other classes
* should work with CredentialStore to get the credentials. */
friend class CredentialStore;
public:
MirallConfigFile( const QString& appendix = QString() );
@@ -35,6 +38,12 @@ public:
oCSetupResultTop // ownCloud connect result page
};
enum CredentialType {
User = 0,
Settings,
KeyChain
};
QString configPath() const;
QString configFile() const;
QString excludeFile() const;
@@ -60,9 +69,7 @@ public:
QByteArray caCerts();
void setCaCerts( const QByteArray& );
QString ownCloudUser( const QString& connection = QString() ) const;
QString ownCloudPasswd( const QString& connection = QString() ) const;
CredentialType credentialType() const;
QString ownCloudVersion() const;
void setOwnCloudVersion( const QString& );
@@ -79,8 +86,6 @@ public:
int remotePollInterval( const QString& connection = QString() ) const;
int pollTimerExceedFactor( const QString& connection = QString() ) const;
QByteArray basicAuthHeader() const;
// Custom Config: accept the custom config to become the main one.
void acceptCustomConfig();
// Custom Config: remove the custom config file.
@@ -99,12 +104,15 @@ public:
QString proxyUser() const;
QString proxyPassword() const;
protected:
QString ownCloudPasswd( const QString& connection = QString() ) const;
QString ownCloudUser( const QString& connection = QString() ) const;
private:
QVariant getValue(const QString& param, const QString& group) const;
private:
static QString _passwd;
static bool _askedUser;
static QString _oCVersion;
QString _customHandle;

View File

@@ -15,6 +15,8 @@
#include "mirall/owncloudfolder.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/owncloudinfo.h"
#include "mirall/credentialstore.h"
#include <csync.h>
@@ -27,6 +29,8 @@
#include <QTextStream>
#include <QTimer>
#include <QNetworkProxy>
#include <QNetworkAccessManager>
#include <QNetworkProxyFactory>
namespace Mirall {
@@ -99,6 +103,15 @@ QString ownCloudFolder::secondPath() const
return re;
}
QString ownCloudFolder::nativeSecondPath() const
{
// TODO: fold into secondPath() after 1.1.0 release
QString path = secondPath();
if (!path.startsWith(QLatin1Char('/')) || path.isEmpty())
path.prepend(QLatin1Char('/'));
return path;
}
void ownCloudFolder::startSync()
{
startSync( QStringList() );
@@ -149,36 +162,23 @@ void ownCloudFolder::startSync(const QStringList &pathList)
_csync = new CSyncThread( path(), url.toString(), _localCheckOnly );
_csync->moveToThread(_thread);
// Proxy settings. Proceed them as strings to csync thread.
int intProxy = cfgFile.proxyType();
QString proxyType;
QList<QNetworkProxy> proxies = QNetworkProxyFactory::proxyForQuery(QUrl(cfgFile.ownCloudUrl()));
// We set at least one in Application
Q_ASSERT(proxies.count() > 0);
QNetworkProxy proxy = proxies.first();
if( intProxy == QNetworkProxy::NoProxy )
proxyType = QLatin1String("NoProxy");
else if( intProxy == QNetworkProxy::DefaultProxy )
proxyType = QLatin1String("DefaultProxy");
else if( intProxy == QNetworkProxy::Socks5Proxy )
proxyType = QLatin1String("Socks5Proxy");
else if( intProxy == QNetworkProxy::HttpProxy )
proxyType = QLatin1String("HttpProxy");
else if( intProxy == QNetworkProxy::HttpCachingProxy )
proxyType = QLatin1String("HttpCachingProxy");
else if( intProxy == QNetworkProxy::FtpCachingProxy )
proxyType = QLatin1String("FtpCachingProxy");
else proxyType = QLatin1String("NoProxy");
_csync->setConnectionDetails( cfgFile.ownCloudUser(), cfgFile.ownCloudPasswd(), proxyType,
cfgFile.proxyHostName(), cfgFile.proxyPort(), cfgFile.proxyUser(),
cfgFile.proxyPassword() );
_csync->setConnectionDetails( CredentialStore::instance()->user(),
CredentialStore::instance()->password(),
proxy );
connect(_csync, SIGNAL(started()), SLOT(slotCSyncStarted()), Qt::QueuedConnection);
connect(_csync, SIGNAL(finished()), SLOT(slotCSyncFinished()), Qt::QueuedConnection);
connect(_csync, SIGNAL(csyncError(const QString)), SLOT(slotCSyncError(const QString)), Qt::QueuedConnection);
connect(_csync, SIGNAL(csyncStateDbFile(QString)), SLOT(slotCsyncStateDbFile(QString)), Qt::QueuedConnection);
connect(_csync, SIGNAL(wipeDb()),SLOT(slotWipeDb()), Qt::QueuedConnection);
connect( _csync, SIGNAL(treeWalkResult(WalkStats*)),
this, SLOT(slotThreadTreeWalkResult(WalkStats*)), Qt::QueuedConnection);
qRegisterMetaType<SyncFileItemVector>("SyncFileItemVector");
qRegisterMetaType<WalkStats>("WalkStats");
connect( _csync, SIGNAL(treeWalkResult(SyncFileItemVector,WalkStats)),
this, SLOT(slotThreadTreeWalkResult(SyncFileItemVector, WalkStats)), Qt::QueuedConnection);
_thread->start();
QMetaObject::invokeMethod(_csync, "startSync", Qt::QueuedConnection);
@@ -190,27 +190,28 @@ void ownCloudFolder::slotCSyncStarted()
emit syncStarted();
}
void ownCloudFolder::slotThreadTreeWalkResult( WalkStats *wStats )
void ownCloudFolder::slotThreadTreeWalkResult(const SyncFileItemVector& items, const WalkStats& wStats )
{
qDebug() << "Seen files: " << wStats->seenFiles;
_items = items;
qDebug() << "Seen files: " << wStats.seenFiles;
/* check if there are happend changes in the file system */
qDebug() << "New files: " << wStats->newFiles;
qDebug() << "Updated files: " << wStats->eval;
qDebug() << "Walked files: " << wStats->seenFiles;
qDebug() << "Eval files: " << wStats->eval;
qDebug() << "Removed files: " << wStats->removed;
qDebug() << "Renamed files: " << wStats->renamed;
qDebug() << "New files: " << wStats.newFiles;
qDebug() << "Updated files: " << wStats.eval;
qDebug() << "Walked files: " << wStats.seenFiles;
qDebug() << "Eval files: " << wStats.eval;
qDebug() << "Removed files: " << wStats.removed;
qDebug() << "Renamed files: " << wStats.renamed;
if( ! _localCheckOnly ) _lastSeenFiles = 0;
_localFileChanges = false;
#ifndef USE_INOTIFY
if( _lastSeenFiles > 0 && _lastSeenFiles != wStats->seenFiles ) {
qDebug() << "*** last seen files different from currently seen number " << _lastSeenFiles << "<>" << wStats->seenFiles << " => full Sync needed";
if( _lastSeenFiles > 0 && _lastSeenFiles != wStats.seenFiles ) {
qDebug() << "*** last seen files different from currently seen number " << _lastSeenFiles << "<>" << wStats.seenFiles << " => full Sync needed";
_localFileChanges = true;
}
if( (wStats->newFiles + wStats->eval + wStats->removed + wStats->renamed) > 0 ) {
if( (wStats.newFiles + wStats.eval + wStats.removed + wStats.renamed) > 0 ) {
qDebug() << "*** Local changes, lets do a full sync!" ;
_localFileChanges = true;
}
@@ -218,14 +219,8 @@ void ownCloudFolder::slotThreadTreeWalkResult( WalkStats *wStats )
qDebug() << " *** No local changes, finalize, pollTimerCounter is "<< _pollTimerCnt ;
}
#endif
_lastSeenFiles = wStats->seenFiles;
_lastSeenFiles = wStats.seenFiles;
/*
* Attention: This is deleted here, outside of the thread, because the thread can
* faster die than this routine has read out the memory.
*/
delete wStats->sourcePath;
delete wStats;
}
void ownCloudFolder::slotCSyncError(const QString& err)
@@ -234,12 +229,6 @@ void ownCloudFolder::slotCSyncError(const QString& err)
_csyncError = true;
}
void ownCloudFolder::slotCsyncStateDbFile( const QString& file )
{
qDebug() << "Got csync statedb file: " << file;
_csyncStateDbFile = file;
}
void ownCloudFolder::slotCSyncFinished()
{
qDebug() << "-> CSync Finished slot with error " << _csyncError;
@@ -271,7 +260,10 @@ 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
delete _thread;
_csync = 0;
_thread = 0;
@@ -301,7 +293,6 @@ void ownCloudFolder::slotLocalPathChanged( const QString& dir )
qDebug() << "XXXXXXX The sync folder root was removed!!";
if( _thread && _thread->isRunning() ) {
qDebug() << "CSync currently running, set wipe flag!!";
slotWipeDb();
} else {
qDebug() << "CSync not running, wipe it now!!";
wipe();
@@ -312,39 +303,81 @@ void ownCloudFolder::slotLocalPathChanged( const QString& dir )
}
}
// an error condition in csyncthread requires to get rid of the database to avoid deletion
// of files.
void ownCloudFolder::slotWipeDb()
{
qDebug() << "Wiping of the csync database is required!";
_wipeDb = true;
}
// This removes the csync File database if the sync folder definition is removed
// permanentely. This is needed to provide a clean startup again in case another
// local folder is synced to the same ownCloud.
// See http://bugs.owncloud.org/thebuggenie/owncloud/issues/oc-788
void ownCloudFolder::wipe()
{
if( !_csyncStateDbFile.isEmpty() ) {
QFile file(_csyncStateDbFile);
if( file.exists() ) {
if( !file.remove()) {
qDebug() << "WRN: Failed to remove existing csync StateDB " << _csyncStateDbFile;
} else {
qDebug() << "wipe: Removed csync StateDB " << _csyncStateDbFile;
}
QString stateDbFile = path()+QLatin1String(".csync_journal.db");
QFile file(stateDbFile);
if( file.exists() ) {
if( !file.remove()) {
qDebug() << "WRN: Failed to remove existing csync StateDB " << stateDbFile;
} else {
qDebug() << "WRN: statedb is empty, can not remove.";
qDebug() << "wipe: Removed csync StateDB " << stateDbFile;
}
// Check if the tmp database file also exists
QString ctmpName = _csyncStateDbFile + QLatin1String(".ctmp");
QFile ctmpFile( ctmpName );
if( ctmpFile.exists() ) {
ctmpFile.remove();
}
_wipeDb = false;
} else {
qDebug() << "WRN: statedb is empty, can not remove.";
}
// Check if the tmp database file also exists
QString ctmpName = path() + QLatin1String(".csync_journal.db.ctmp");
QFile ctmpFile( ctmpName );
if( ctmpFile.exists() ) {
ctmpFile.remove();
}
_wipeDb = false;
}
SyncFileStatus ownCloudFolder::fileStatus( const QString& file )
{
if( file.isEmpty() ) return STATUS_NONE;
QFileInfo fi( path(), file );
foreach( const SyncFileItem item, _items ) {
qDebug() << "FileStatus compare: " << item.file << " <> " << fi.absoluteFilePath();
if( item.file == fi.absoluteFilePath() ) {
switch( item.instruction ) {
case CSYNC_INSTRUCTION_NONE:
return STATUS_NONE;
break;
case CSYNC_INSTRUCTION_EVAL:
return STATUS_EVAL;
break;
case CSYNC_INSTRUCTION_RENAME:
return STATUS_RENAME;
break;
case CSYNC_INSTRUCTION_NEW:
return STATUS_NEW;
break;
case CSYNC_INSTRUCTION_CONFLICT:
return STATUS_CONFLICT;
break;
case CSYNC_INSTRUCTION_IGNORE:
return STATUS_IGNORE;
break;
case CSYNC_INSTRUCTION_SYNC:
case CSYNC_INSTRUCTION_UPDATED:
return STATUS_SYNC;
break;
case CSYNC_INSTRUCTION_STAT_ERROR:
return STATUS_STAT_ERROR;
break;
case CSYNC_INSTRUCTION_ERROR:
return STATUS_ERROR;
break;
case CSYNC_INSTRUCTION_DELETED:
case CSYNC_INSTRUCTION_REMOVE:
return STATUS_REMOVE;
break;
default:
break;
}
}
}
return STATUS_NEW;
}
} // ns

View File

@@ -26,6 +26,21 @@ class QProcess;
namespace Mirall {
enum SyncFileStatus_s {
STATUS_NONE,
STATUS_EVAL,
STATUS_REMOVE,
STATUS_RENAME,
STATUS_NEW,
STATUS_CONFLICT,
STATUS_IGNORE,
STATUS_SYNC,
STATUS_STAT_ERROR,
STATUS_ERROR,
STATUS_UPDATED
};
typedef SyncFileStatus_s SyncFileStatus;
class ownCloudFolder : public Folder
{
Q_OBJECT
@@ -35,11 +50,14 @@ public:
const QString &secondPath, QObject *parent = 0L);
virtual ~ownCloudFolder();
QString secondPath() const;
QString nativeSecondPath() const;
virtual bool isBusy() const;
virtual void startSync(const QStringList &pathList);
virtual void wipe();
SyncFileStatus fileStatus( const QString& );
public slots:
void startSync();
void slotTerminateSync();
@@ -51,9 +69,7 @@ private slots:
void slotCSyncStarted();
void slotCSyncError(const QString& );
void slotCSyncFinished();
void slotThreadTreeWalkResult( WalkStats* );
void slotCsyncStateDbFile(const QString&);
void slotWipeDb();
void slotThreadTreeWalkResult(const SyncFileItemVector &, const WalkStats& );
void slotPollTimerRemoteCheck();
@@ -69,7 +85,7 @@ private:
bool _csyncError;
bool _wipeDb;
ulong _lastSeenFiles;
QString _csyncStateDbFile;
QVector<SyncFileItem> _items;
};
}

View File

@@ -15,7 +15,8 @@
#include "mirall/owncloudinfo.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/version.h"
#include "mirall/sslerrordialog.h"
#include "mirall/theme.h"
#include "mirall/credentialstore.h"
#include <QtCore>
#include <QtGui>
@@ -46,13 +47,10 @@ ownCloudInfo* ownCloudInfo::instance()
return _instance;
}
ownCloudInfo::ownCloudInfo( const QString& connectionName, QObject *parent ) :
QObject(parent), _sslErrorDialog(0)
ownCloudInfo::ownCloudInfo() :
QObject(0)
{
if( connectionName.isEmpty() )
_connection = QLatin1String( "ownCloud");
else
_connection = connectionName;
_connection = Theme::instance()->appName();
_manager = new QNetworkAccessManager( this );
@@ -62,7 +60,7 @@ ownCloudInfo::ownCloudInfo( const QString& connectionName, QObject *parent ) :
QSslSocket::addDefaultCaCertificates(QSslCertificate::fromData(certs));
connect( _manager, SIGNAL( sslErrors(QNetworkReply*, QList<QSslError>)),
this, SLOT(slotSSLFailed(QNetworkReply*, QList<QSslError>)) );
this, SIGNAL(sslFailed(QNetworkReply*, QList<QSslError>)) );
connect( _manager, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)),
this, SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));
@@ -72,7 +70,6 @@ ownCloudInfo::ownCloudInfo( const QString& connectionName, QObject *parent ) :
ownCloudInfo::~ownCloudInfo()
{
delete _sslErrorDialog;
}
void ownCloudInfo::setCustomConfigHandle( const QString& handle )
@@ -90,6 +87,7 @@ bool ownCloudInfo::isConfigured()
void ownCloudInfo::checkInstallation()
{
/* No authentication required for this. */
getRequest( QLatin1String("status.php"), false );
}
@@ -132,23 +130,24 @@ void ownCloudInfo::mkdirRequest( const QString& dir )
if (url.scheme() == "https")
conMode = QHttp::ConnectionModeHttps;
QHttp* qhttp = new QHttp(url.host(), conMode, 0, this);
qhttp->setUser( cfgFile.ownCloudUser( _connection ), cfgFile.ownCloudPasswd( _connection ));
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)));
connect(qhttp, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), this, SLOT(qhttpResponseHeaderReceived(QHttpResponseHeader)));
//connect(qhttp, SIGNAL(authenticationRequired(QString,quint16,QAuthenticator*)), this, SLOT(qhttpAuthenticationRequired(QString,quint16,QAuthenticator*)));
QHttpRequestHeader header("MKCOL", url.path(), 1,1); /* header */
header.setValue("Host", url.host() );
QHttpRequestHeader header("MKCOL", QString(url.encodedPath()), 1,1); /* header */
header.setValue("Host", QString(url.encodedHost()));
header.setValue("User-Agent", QString("mirall-%1").arg(MIRALL_STRINGIFY(MIRALL_VERSION)).toAscii() );
header.setValue("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
header.setValue("Accept-Language", "it,de-de;q=0.8,it-it;q=0.6,en-us;q=0.4,en;q=0.2");
header.setValue("Connection", "keep-alive");
header.setContentType("application/x-www-form-urlencoded"); //important
header.setContentLength(0);
header.setValue("Authorization", cfgFile.basicAuthHeader());
header.setValue("Authorization", CredentialStore::instance()->basicAuthHeader());
int david = qhttp->request(header,0,0);
//////////////// connect(davinfo, SIGNAL(dataSendProgress(int,int)), this, SLOT(SendStatus(int, int)));
@@ -243,8 +242,8 @@ 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( cfgFile.ownCloudUser( _connection ) );
auth->setPassword( cfgFile.ownCloudPasswd( _connection ));
auth->setUser( CredentialStore::instance()->user() ); //_connection ) );
auth->setPassword( CredentialStore::instance()->password() ); // _connection ));
} else {
qDebug() << "WRN: attempt to authenticate to different url - attempt " <<_authAttempts;
}
@@ -255,53 +254,15 @@ void ownCloudInfo::slotAuthentication( QNetworkReply *reply, QAuthenticator *aut
}
void ownCloudInfo::slotSSLFailed( QNetworkReply *reply, QList<QSslError> errors )
QString ownCloudInfo::configHandle(QNetworkReply *reply)
{
qDebug() << "SSL-Warnings happened for url " << reply->url().toString();
QString configHandle;
// an empty config handle is ok for the default config.
if( _configHandleMap.contains(reply) ) {
configHandle = _configHandleMap[reply];
qDebug() << "SSL: Have a custom config handle: " << configHandle;
}
if( !configHandle.isEmpty() ) {
qDebug() << "Custom config handle: " << configHandle;
}
if( _certsUntrusted ) {
// User decided once to untrust. Honor this decision.
qDebug() << "Untrusted by user decision, returning.";
return;
}
if( _sslErrorDialog == 0 ) {
_sslErrorDialog = new SslErrorDialog;
}
// make the ssl dialog aware of the custom config. It loads known certs.
_sslErrorDialog->setCustomConfigHandle( configHandle );
if( _sslErrorDialog->setErrorList( errors ) ) {
// all ssl certs are known and accepted. We can ignore the problems right away.
qDebug() << "Certs are already known and trusted, Warnings are not valid.";
reply->ignoreSslErrors();
} else {
if( _sslErrorDialog->exec() == QDialog::Accepted ) {
if( _sslErrorDialog->trustConnection() ) {
reply->ignoreSslErrors();
} else {
// User does not want to trust.
_certsUntrusted = true;
}
} else {
_certsUntrusted = true;
}
}
return configHandle;
}
QUrl ownCloudInfo::redirectUrl(const QUrl& possibleRedirectUrl,
const QUrl& oldRedirectUrl) const {
QUrl redirectUrl;
@@ -446,6 +407,16 @@ void ownCloudInfo::resetSSLUntrust()
_certsUntrusted = false;
}
void ownCloudInfo::setCertsUntrusted(bool donttrust)
{
_certsUntrusted = donttrust;
}
bool ownCloudInfo::certsUntrusted()
{
return _certsUntrusted;
}
void ownCloudInfo::slotError( QNetworkReply::NetworkError err)
{
qDebug() << "ownCloudInfo Network Error: " << err;
@@ -461,7 +432,7 @@ 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"), cfgFile.basicAuthHeader() );
req.setRawHeader( QByteArray("Authorization"), CredentialStore::instance()->basicAuthHeader() );
if (size) {
req.setHeader( QNetworkRequest::ContentLengthHeader, size);
@@ -482,6 +453,5 @@ QNetworkReply* ownCloudInfo::davRequest(const QString& reqVerb, QNetworkRequest
}
}
#endif
}

View File

@@ -27,8 +27,6 @@
namespace Mirall
{
class SslErrorDialog;
class ownCloudInfo : public QObject
{
Q_OBJECT
@@ -60,6 +58,16 @@ public:
*/
void resetSSLUntrust();
/**
* Set wether or not to trust errorneus SSL certificates
*/
void setCertsUntrusted(bool donttrust);
/**
* Do we trust the certificate?.
*/
bool certsUntrusted();
/**
* Create a collection via owncloud. Provide a relative path.
*/
@@ -70,6 +78,11 @@ public:
*/
void setCustomConfigHandle( const QString& );
/**
* Accessor to the config handle.
*/
QString configHandle(QNetworkReply *reply = 0);
signals:
// result signal with url- and version string.
void ownCloudInfoFound( const QString&, const QString&, const QString&, const QString& );
@@ -77,6 +90,7 @@ signals:
void ownCloudDirExists( const QString&, QNetworkReply* );
void webdavColCreated( QNetworkReply::NetworkError );
void sslFailed( QNetworkReply *reply, QList<QSslError> errors );
public slots:
@@ -84,7 +98,6 @@ protected slots:
void slotReplyFinished( );
void slotError( QNetworkReply::NetworkError );
void slotAuthentication( QNetworkReply*, QAuthenticator *);
void slotSSLFailed( QNetworkReply *reply, QList<QSslError> errors );
#if QT46_IMPL
void qhttpRequestFinished(int id, bool success );
@@ -96,7 +109,7 @@ protected slots:
#endif
private:
explicit ownCloudInfo( const QString& = QString(), QObject *parent = 0);
explicit ownCloudInfo();
QUrl redirectUrl(const QUrl&, const QUrl& ) const;
@@ -116,7 +129,6 @@ private:
QUrl _urlRedirectedTo;
QHash<QNetworkReply*, QString> _directories;
QHash<QNetworkReply*, QString> _configHandleMap;
SslErrorDialog *_sslErrorDialog;
bool _certsUntrusted;
int _authAttempts;
};

View File

@@ -7,33 +7,14 @@
<x>0</x>
<y>0</y>
<width>480</width>
<height>271</height>
<height>278</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0" colspan="2">
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<pointsize>14</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Create the ownCloud Connection</string>
</property>
</widget>
</widget>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="serverAddressLabel">
<property name="text">
<string>Server &amp;address:</string>
@@ -43,25 +24,20 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="protocolLabel">
<property name="text">
<string>https://</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leUrl">
<property name="toolTip">
<string>Enter the url of the ownCloud you want to connect to (without http or https).</string>
</property>
</widget>
</item>
</layout>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="topLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -141,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>
@@ -156,7 +132,32 @@
</item>
</layout>
</item>
<item row="6" column="1">
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="protocolLabel">
<property name="text">
<string>https://</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leUrl">
<property name="toolTip">
<string>Enter the url of the ownCloud you want to connect to (without http or https).</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="bottomLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -169,28 +170,16 @@
</property>
</spacer>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="topLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="bottomLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>leUrl</tabstop>
<tabstop>cbSecureConnect</tabstop>
<tabstop>cbConnectOC</tabstop>
<tabstop>leUsername</tabstop>
<tabstop>lePassword</tabstop>
<tabstop>cbNoPasswordStore</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -96,7 +96,8 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
// Now write the resulting folder definition if folder names are set.
if( !( _localFolder.isEmpty() || _remoteFolder.isEmpty() ) ) { // both variables are set.
if( _folderMan ) {
_folderMan->addFolderDefinition( QLatin1String("owncloud"), QLatin1String("ownCloud"), _localFolder, _remoteFolder, false );
_folderMan->addFolderDefinition( QLatin1String("owncloud"), Theme::instance()->appName(),
_localFolder, _remoteFolder, false );
_ocWizard->appendToResultWidget(tr("<font color=\"green\"><b>Local sync folder %1 successfully created!</b></font>").arg(_localFolder));
} else {
qDebug() << "WRN: Folderman is zero in Setup Wizzard.";
@@ -126,7 +127,8 @@ void OwncloudSetupWizard::slotConnectToOCUrl( const QString& url )
{
qDebug() << "Connect to url: " << url;
_ocWizard->setField(QLatin1String("OCUrl"), url );
_ocWizard->appendToResultWidget(tr("Trying to connect to ownCloud at %1...").arg(url ));
_ocWizard->appendToResultWidget(tr("Trying to connect to %1 at %2...")
.arg( Theme::instance()->appName() ).arg(url) );
testOwnCloudConnect();
}
@@ -138,7 +140,7 @@ void OwncloudSetupWizard::testOwnCloudConnect()
MirallConfigFile cfgFile( _configHandle );
cfgFile.writeOwncloudConfig( QLatin1String("ownCloud"),
cfgFile.writeOwncloudConfig( Theme::instance()->appName(),
_ocWizard->field(QLatin1String("OCUrl")).toString(),
_ocWizard->field(QLatin1String("OCUser")).toString(),
_ocWizard->field(QLatin1String("OCPasswd")).toString(),
@@ -146,11 +148,12 @@ void OwncloudSetupWizard::testOwnCloudConnect()
_ocWizard->field(QLatin1String("PwdNoLocalStore")).toBool() );
// now start ownCloudInfo to check the connection.
ownCloudInfo::instance()->setCustomConfigHandle( _configHandle );
if( ownCloudInfo::instance()->isConfigured() ) {
ownCloudInfo* info = ownCloudInfo::instance();
info->setCustomConfigHandle( _configHandle );
if( info->isConfigured() ) {
// reset the SSL Untrust flag to let the SSL dialog appear again.
ownCloudInfo::instance()->resetSSLUntrust();
ownCloudInfo::instance()->checkInstallation();
info->resetSSLUntrust();
info->checkInstallation();
} else {
qDebug() << " ownCloud seems not to be configured, can not start test connect.";
}
@@ -158,7 +161,8 @@ 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: ownCloud version %2 (%3)</font><br/><br/>").arg( url ).arg(infoString).arg(version));
_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));
// enable the finish button.
_ocWizard->button( QWizard::FinishButton )->setEnabled( true );
@@ -169,7 +173,8 @@ void OwncloudSetupWizard::slotOwnCloudFound( const QString& url, const QString&
void OwncloudSetupWizard::slotNoOwnCloudFound( QNetworkReply *err )
{
_ocWizard->appendToResultWidget(tr("<font color=\"red\">Failed to connect to ownCloud!</font>") );
_ocWizard->appendToResultWidget(tr("<font color=\"red\">Failed to connect to %1!</font>")
.arg(Theme::instance()->appName()));
_ocWizard->appendToResultWidget(tr("Error: <tt>%1</tt>").arg(err->errorString()) );
// remove the config file again
@@ -306,19 +311,19 @@ void OwncloudSetupWizard::slotProcessFinished( int res, QProcess::ExitStatus )
qDebug() << "exit code: " << res;
if( res ) {
_ocWizard->appendToResultWidget( tr("<font color=\"red\">Installation of ownCloud failed!</font>") );
_ocWizard->appendToResultWidget( tr("<font color=\"red\">Installation of %1 failed!</font>").arg(Theme::instance()->appName()));
_ocWizard->showOCUrlLabel( false );
emit ownCloudSetupFinished( false );
} else {
// Successful installation. Write the config.
_ocWizard->appendToResultWidget( tr("<font color=\"green\">Installation of ownCloud succeeded!</font>") );
_ocWizard->appendToResultWidget( tr("<font color=\"green\">Installation of %1 succeeded!</font>").arg(Theme::instance()->appName()));
_ocWizard->showOCUrlLabel( true );
testOwnCloudConnect();
}
}
void OwncloudSetupWizard::startWizard()
void OwncloudSetupWizard::startWizard(bool intro)
{
// create the ocInfo object
connect(ownCloudInfo::instance(),SIGNAL(ownCloudInfoFound(QString,QString,QString,QString)),SLOT(slotOwnCloudFound(QString,QString,QString,QString)));
@@ -331,6 +336,12 @@ void OwncloudSetupWizard::startWizard()
if( !url.isEmpty() ) {
_ocWizard->setOCUrl( url );
}
#ifdef OWNCLOUD_CLIENT
if (intro)
_ocWizard->setStartId(OwncloudWizard::Page_oCWelcome);
else
_ocWizard->setStartId(OwncloudWizard::Page_oCSetup);
#endif
_ocWizard->restart();
_ocWizard->show();
}
@@ -353,7 +364,7 @@ bool OwncloudSetupWizard::checkOwncloudAdmin( const QString& bin )
void OwncloudSetupWizard::setupLocalSyncFolder()
{
_localFolder = QDir::homePath() + QLatin1String("/ownCloud");
_localFolder = QDir::homePath() + QDir::separator() + Theme::instance()->defaultClientFolder();
if( ! _folderMan ) return;
@@ -379,8 +390,8 @@ void OwncloudSetupWizard::setupLocalSyncFolder()
}
if( localFolderOk ) {
_remoteFolder = QLatin1String("clientsync"); // FIXME: Themeable
if( createRemoteFolder( _remoteFolder ) ) {
_remoteFolder = Theme::instance()->defaultServerFolder();
if( !_remoteFolder.isEmpty() && createRemoteFolder( _remoteFolder ) ) {
// the creation started successfully, does not mean it will work
qDebug() << "Creation of remote folder started successfully.";
} else {
@@ -413,7 +424,7 @@ void OwncloudSetupWizard::slotCreateRemoteFolderFinished( QNetworkReply::Network
} else if( error == 202 ) {
_ocWizard->appendToResultWidget( tr("The remote folder %1 already exists. Connecting it for syncing.").arg(_remoteFolder));
} else if( error > 202 && error < 300 ) {
_ocWizard->appendToResultWidget( tr("The folder creation resulted in HTTP error code %d").arg((int)error) );
_ocWizard->appendToResultWidget( tr("The folder creation resulted in HTTP error code %1").arg((int)error) );
} else if( error == QNetworkReply::OperationCanceledError ) {
_ocWizard->appendToResultWidget( tr("<p><font color=\"red\">Remote folder creation failed probably because the provided credentials are wrong.</font>"
"<br/>Please go back and check your credentials.</p>"));
@@ -439,12 +450,14 @@ void OwncloudSetupWizard::finalizeSetup( bool success )
}
_ocWizard->appendToResultWidget( QLatin1String(" "));
_ocWizard->appendToResultWidget( QLatin1String("<p><font color=\"green\"><b>")
+ tr("Congratulations, your ownCloud can be connected!")
+ tr("Succesfully connected to %1!")
.arg(Theme::instance()->appName())
+ QLatin1String("</b></font></p>"));
_ocWizard->appendToResultWidget( tr("Press Finish to permanently accept this connection."));
} else {
_ocWizard->appendToResultWidget(QLatin1String("<p><font color=\"red\">")
+ tr("An ownCloud connection could not be established. Please check again.")
+ tr("Connection to %1 could not be established. Please check again.")
.arg(Theme::instance()->appName())
+ QLatin1String("</font></p>"));
}
}

View File

@@ -38,7 +38,10 @@ public:
~OwncloudSetupWizard();
void startWizard( );
/**
* @intro wether or not to show the intro wizard page
*/
void startWizard(bool intro = false);
void installServer();

View File

@@ -33,7 +33,7 @@ QString ownCloudTheme::appName() const
* because the value is used by QDesktopServices to find the config
* file. Be aware.
*/
return QApplication::translate("appname", "ownCloud");
return QLatin1String("ownCloud");
}
QString ownCloudTheme::configFileName() const
@@ -51,7 +51,7 @@ QIcon ownCloudTheme::folderIcon( const QString& backend ) const
QString name;
if( backend == QLatin1String("owncloud")) {
name = QLatin1String( "owncloud-icon-framed" );
name = QLatin1String( "owncloud-framed" );
}
if( backend == QLatin1String("unison" )) {
name = QLatin1String( "folder-sync" );
@@ -79,25 +79,25 @@ QIcon ownCloudTheme::syncStateIcon( SyncResult::Status status ) const
switch( status ) {
case SyncResult::Undefined:
statusIcon = QLatin1String("owncloud-icon-error");
statusIcon = QLatin1String("owncloud-error");
break;
case SyncResult::NotYetStarted:
statusIcon = QLatin1String("owncloud-icon");
break;
case SyncResult::SyncRunning:
statusIcon = QLatin1String("owncloud-icon-sync");
statusIcon = QLatin1String("owncloud-sync");
break;
case SyncResult::Success:
statusIcon = QLatin1String("owncloud-icon-sync-ok");
statusIcon = QLatin1String("owncloud-sync-ok");
break;
case SyncResult::Error:
statusIcon = QLatin1String("owncloud-icon-error");
statusIcon = QLatin1String("owncloud-error");
break;
case SyncResult::SetupError:
statusIcon = QLatin1String("owncloud-icon-error");
statusIcon = QLatin1String("owncloud-error");
break;
default:
statusIcon = QLatin1String("owncloud-icon-error");
statusIcon = QLatin1String("owncloud-error");
}
return themeIcon( statusIcon );
@@ -106,7 +106,7 @@ QIcon ownCloudTheme::syncStateIcon( SyncResult::Status status ) const
QIcon ownCloudTheme::folderDisabledIcon( ) const
{
// Fixme: Do we really want the dialog-canel from theme here?
return themeIcon( QLatin1String("owncloud-icon-error") );
return themeIcon( QLatin1String("owncloud-error") );
}
QIcon ownCloudTheme::applicationIcon( ) const

View File

@@ -14,6 +14,7 @@
*/
#include "mirall/owncloudwizard.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/theme.h"
#include <QDebug>
#include <QDesktopServices>
@@ -54,10 +55,29 @@ void setupCustomMedia( QVariant variant, QLabel *label )
// ======================================================================
OwncloudWelcomePage::OwncloudWelcomePage()
{
setTitle(tr("Welcome to %1").arg(Theme::instance()->appName()));
QVBoxLayout *lay = new QVBoxLayout(this);
QLabel *content = new QLabel;
lay->addWidget(content, 100, Qt::AlignTop);
content->setAlignment(Qt::AlignTop);
content->setTextFormat(Qt::RichText);
content->setWordWrap(true);
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 hosting provider.</p>")
.arg(Theme::instance()->appName()));
}
OwncloudSetupPage::OwncloudSetupPage()
{
_ui.setupUi(this);
setTitle(tr("Create the %1 Connection").arg(Theme::instance()->appName()));
connect(_ui.leUrl, SIGNAL(textChanged(QString)), SLOT(handleNewOcUrl(QString)));
registerField( QLatin1String("OCUrl"), _ui.leUrl );
@@ -76,11 +96,6 @@ OwncloudSetupPage::OwncloudSetupPage()
_ui.cbConnectOC->hide();
setupCustomization();
#if QT_VERSION >= 0x040700
_ui.leUsername->setPlaceholderText(tr("john"));
_ui.lePassword->setPlaceholderText(tr("secret"));
#endif
}
OwncloudSetupPage::~OwncloudSetupPage()
@@ -152,17 +167,23 @@ void OwncloudSetupPage::slotSecureConChanged( int state )
void OwncloudSetupPage::handleNewOcUrl(const QString& ocUrl)
{
QUrl url(ocUrl);
QString urlMinusScheme = url.toString(QUrl::RemoveScheme);
// QUrl::RemoveScheme leaves the beginning slashes. Remove them
// if they're present.
if (urlMinusScheme.startsWith("//")) {
urlMinusScheme.remove(0, 2);
QString url = ocUrl;
int len = 0;
if (url.startsWith(QLatin1String("https://"))) {
_ui.cbSecureConnect->setChecked(true);
len = 8;
}
if (url.startsWith(QLatin1String("http://"))) {
_ui.cbSecureConnect->setChecked(false);
len = 7;
}
if( len ) {
int pos = _ui.leUrl->cursorPosition();
url.remove(0, len);
_ui.leUrl->setText(url);
_ui.leUrl->setCursorPosition(qMax(0, pos-len));
_ui.leUrl->setText(urlMinusScheme);
}
}
bool OwncloudSetupPage::isComplete() const
@@ -177,8 +198,6 @@ bool OwncloudSetupPage::isComplete() const
void OwncloudSetupPage::initializePage()
{
QString user = QString::fromLocal8Bit(qgetenv( "USER" ));
_ui.leUsername->setText( user );
}
int OwncloudSetupPage::nextId() const
@@ -258,11 +277,6 @@ OwncloudCredentialsPage::OwncloudCredentialsPage()
connect( _ui.OCPasswdEdit, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged()));
connect( _ui.cbPwdNoLocalStore, SIGNAL(stateChanged(int)), this, SLOT(slotPwdStoreChanged(int)));
#if QT_VERSION >= 0x040700
_ui.OCUserEdit->setPlaceholderText(tr("john"));
_ui.OCPasswdEdit->setPlaceholderText(tr("secret"));
#endif
}
OwncloudCredentialsPage::~OwncloudCredentialsPage()
@@ -285,8 +299,6 @@ bool OwncloudCredentialsPage::isComplete() const
void OwncloudCredentialsPage::initializePage()
{
QString user = QString::fromLocal8Bit(qgetenv( "USER" ));
_ui.OCUserEdit->setText( user );
}
int OwncloudCredentialsPage::nextId() const
@@ -307,8 +319,6 @@ OwncloudFTPAccessPage::OwncloudFTPAccessPage()
#if QT_VERSION >= 0x040700
_ui.ftpUrlEdit->setPlaceholderText(tr("ftp.mydomain.org"));
_ui.ftpUserEdit->setPlaceholderText(tr("john"));
_ui.ftpPasswdEdit->setPlaceholderText(tr("secret"));
#endif
}
@@ -431,7 +441,8 @@ 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 ownCloud</a> is now up and running!").arg(url) );
_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()));
_ui.ocLinkLabel->setOpenExternalLinks( true );
if( show ) {
@@ -463,6 +474,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
: QWizard(parent)
{
#ifdef OWNCLOUD_CLIENT
setPage(Page_oCWelcome, new OwncloudWelcomePage() );
setPage(Page_oCSetup, new OwncloudSetupPage() );
#else
setPage(Page_SelectType, new OwncloudWizardSelectTypePage() );
@@ -483,8 +495,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
QString OwncloudWizard::ocUrl() const
{
QString url = field("OCUrl").toString();
QString url = field("OCUrl").toString().simplified();
if( field("secureConnect").toBool() ) {
url.prepend(QLatin1String("https://"));
} else {

View File

@@ -57,6 +57,7 @@ class OwncloudWizard: public QWizard
public:
enum {
Page_oCWelcome,
Page_oCSetup,
Page_SelectType,
Page_Create_OC,
@@ -93,6 +94,20 @@ private:
QString _oCUrl;
};
/**
* page for first launch only
*/
class OwncloudWelcomePage: public QWizardPage
{
Q_OBJECT
public:
OwncloudWelcomePage();
virtual int nextId() const { return OwncloudWizard::Page_oCSetup; }
};
/**
* page to ask for the type of Owncloud to connect to
*/

View File

@@ -39,7 +39,7 @@ Mirall::ProxyDialog::ProxyDialog( QWidget* parent )
noProxyRadioButton->setChecked(true);
if (cfgFile.proxyType() == QNetworkProxy::DefaultProxy)
systemProxyRadioButton->setChecked(true);
if (cfgFile.proxyType() == QNetworkProxy::Socks5Proxy)
if (cfgFile.proxyType() == QNetworkProxy::HttpProxy)
{
manualProxyRadioButton->setChecked(true);
hostLineEdit->setText(cfgFile.proxyHostName());
@@ -71,12 +71,12 @@ void Mirall::ProxyDialog::saveSettings()
{
QString user = userLineEdit->text();
QString pass = passwordLineEdit->text();
cfgFile.setProxyType(QNetworkProxy::Socks5Proxy, hostLineEdit->text(),
cfgFile.setProxyType(QNetworkProxy::HttpProxy, hostLineEdit->text(),
portSpinBox->value(), user, pass);
}
else
{
cfgFile.setProxyType(QNetworkProxy::Socks5Proxy, hostLineEdit->text(),
cfgFile.setProxyType(QNetworkProxy::HttpProxy, hostLineEdit->text(),
portSpinBox->value(), QString::null, QString::null);
}
}

View File

@@ -23,7 +23,7 @@
</font>
</property>
<property name="text">
<string>Configure Proxies to access your ownCloud</string>
<string>Configure Proxies</string>
</property>
<property name="buddy">
<cstring>manualSettings</cstring>

View File

@@ -26,11 +26,18 @@ SslErrorDialog::SslErrorDialog(QWidget *parent) :
{
setupUi( this );
setWindowTitle( tr("SSL Connection") );
QPushButton *okButton = _dialogButtonBox->button( QDialogButtonBox::Ok );
QPushButton *okButton =
_dialogButtonBox->button( QDialogButtonBox::Ok );
QPushButton *cancelButton =
_dialogButtonBox->button( QDialogButtonBox::Cancel );
okButton->setEnabled(false);
connect(_cbTrustConnect, SIGNAL(clicked(bool)),
okButton, SLOT(setEnabled(bool)));
if( okButton ) {
okButton->setDefault(true);
connect( okButton, SIGNAL(clicked()),SLOT(accept()));
connect( cancelButton, SIGNAL(clicked()),SLOT(reject()));
}
}
@@ -51,6 +58,7 @@ QString SslErrorDialog::styleSheet() const
"#ca_error p { margin-top: 2px; margin-bottom:2px; }"
"#ccert { margin-left: 5px; }"
"#issuer { margin-left: 5px; }"
"tt { font-size: small; }"
);
return style;
@@ -118,6 +126,18 @@ bool SslErrorDialog::setErrorList( QList<QSslError> errors )
return false;
}
static QByteArray formatHash(const QByteArray &fmhash)
{
QByteArray hash;
int steps = fmhash.length()/2;
for (int i = 0; i < steps; i++) {
hash.append(fmhash[i]);
hash.append(fmhash[i+1]);
hash.append(' ');
}
return hash;
}
QString SslErrorDialog::certDiv( QSslCertificate cert ) const
{
QString msg;
@@ -126,23 +146,36 @@ QString SslErrorDialog::certDiv( QSslCertificate cert ) const
msg += QL("<div id=\"ccert\">");
QStringList li;
li << tr("Organization: %1").arg( cert.subjectInfo( QSslCertificate::Organization) );
li << tr("Unit: %1").arg( cert.subjectInfo( QSslCertificate::OrganizationalUnitName) );
li << tr("Country: %1").arg(cert.subjectInfo( QSslCertificate::CountryName));
QString org = Qt::escape(cert.subjectInfo( QSslCertificate::Organization));
QString unit = Qt::escape(cert.subjectInfo( QSslCertificate::OrganizationalUnitName));
QString country = Qt::escape(cert.subjectInfo( QSslCertificate::CountryName));
if (unit.isEmpty()) unit = tr("&lt;not specified&gt;");
if (org.isEmpty()) org = tr("&lt;not specified&gt;");
if (country.isEmpty()) country = tr("&lt;not specified&gt;");
li << tr("Organization: %1").arg(org);
li << tr("Unit: %1").arg(unit);
li << tr("Country: %1").arg(country);
msg += QL("<p>") + li.join(QL("<br/>")) + QL("</p>");
msg += QL("<p>");
QString md5sum = QString::fromAscii(formatHash(cert.digest(QCryptographicHash::Md5).toHex()));
QString sha1sum = QString::fromAscii(formatHash(cert.digest(QCryptographicHash::Sha1).toHex()));
msg += tr("Fingerprint (MD5): <tt>%1</tt>").arg(md5sum) + QL("<br/>");
msg += tr("Fingerprint (SHA1): <tt>%1</tt>").arg(sha1sum) + QL("<br/>");
msg += QL("<br/>");
msg += tr("Effective Date: %1").arg( cert.effectiveDate().toString()) + QL("<br/>");
msg += tr("Expiry Date: %1").arg( cert.expiryDate().toString()) + QL("</p>");
msg += QL("</div>" );
msg += QL("<h3>") + tr("Issuer: %1").arg( cert.issuerInfo( QSslCertificate::CommonName )) + QL("</h3>");
msg += QL("<h3>") + tr("Issuer: %1").arg(Qt::escape(cert.issuerInfo( QSslCertificate::CommonName))) + QL("</h3>");
msg += QL("<div id=\"issuer\">");
li.clear();
li << tr("Organization: %1").arg( cert.issuerInfo( QSslCertificate::Organization) );
li << tr("Unit: %1").arg( cert.issuerInfo( QSslCertificate::OrganizationalUnitName) );
li << tr("Country: %1").arg(cert.issuerInfo( QSslCertificate::CountryName));
li << tr("Organization: %1").arg(Qt::escape(cert.issuerInfo( QSslCertificate::Organization)));
li << tr("Unit: %1").arg(Qt::escape(cert.issuerInfo( QSslCertificate::OrganizationalUnitName)));
li << tr("Country: %1").arg(Qt::escape(cert.issuerInfo( QSslCertificate::CountryName)));
msg += QL("<p>") + li.join(QL("<br/>")) + QL("</p>");
msg += QL("</div>" );
msg += QL("</div>" );

View File

@@ -19,7 +19,7 @@
#include <QSslCertificate>
#include <QList>
#include "ui_sslerrorsdialog.h"
#include "ui_sslerrordialog.h"
class QSslError;
@@ -27,7 +27,7 @@ class QSslError;
namespace Mirall
{
class SslErrorDialog : public QDialog, public Ui::sslErrorsDialog
class SslErrorDialog : public QDialog, public Ui::sslErrorDialog
{
Q_OBJECT
public:

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>sslErrorsDialog</class>
<widget class="QWidget" name="sslErrorsDialog">
<class>sslErrorDialog</class>
<widget class="QWidget" name="sslErrorDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>593</width>
<height>547</height>
<width>640</width>
<height>560</height>
</rect>
</property>
<property name="windowTitle">
@@ -22,14 +22,14 @@
</font>
</property>
<property name="text">
<string>Check if you want to continue via SSL and trust the shown certificates.</string>
<string>Trust this certificate anyway</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QDialogButtonBox" name="_dialogButtonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>

View File

@@ -16,6 +16,8 @@
#include "mirall/folder.h"
#include "mirall/theme.h"
#include "mirall/owncloudinfo.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/credentialstore.h"
#include <QtCore>
#include <QtGui>
@@ -71,20 +73,29 @@ QSize FolderViewDelegate::sizeHint(const QStyleOptionViewItem & option ,
QFontMetrics fm(font);
QFontMetrics aliasFm(aliasFont);
int margin = aliasFm.height()/2;
w = 8 + fm.boundingRect( p ).width();
// calc height
int h = aliasFm.height()/2; // margin to top
int h = margin; // margin to top
h += aliasFm.height(); // alias
h += fm.height()/2; // between alias and local path
h += fm.height(); // local path
h += fm.height()/2; // between local and remote path
h += fm.height(); // remote path
h += aliasFm.height()/2; // bottom margin
h += margin; // bottom margin
int minHeight = 48 + fm.height()/2 + fm.height()/2; // icon + margins
int minHeight = 48 + margin + margin; // icon + margins
if( h < minHeight ) h = minHeight;
// add some space to show an error condition.
if( ! qvariant_cast<QString>(index.data(FolderErrorMsg)).isEmpty() ) {
h += margin+fm.height();
}
return QSize( w, h );
}
@@ -97,18 +108,23 @@ void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
QFont aliasFont = QApplication::font();
QFont subFont = QApplication::font();
QFont errorFont = subFont;
//font.setPixelSize(font.weight()+);
aliasFont.setBold(true);
aliasFont.setPointSize( subFont.pointSize()+2 );
QFontMetrics subFm( subFont );
QFontMetrics aliasFm( aliasFont );
int margin = aliasFm.height()/2;
QIcon folderIcon = qvariant_cast<QIcon>(index.data(FolderIconRole));
QIcon statusIcon = qvariant_cast<QIcon>(index.data(FolderStatusIcon));
QString aliasText = qvariant_cast<QString>(index.data(FolderAliasRole));
QString pathText = qvariant_cast<QString>(index.data(FolderPathRole));
QString remotePath = qvariant_cast<QString>(index.data(FolderSecondPathRole));
QString errorText = qvariant_cast<QString>(index.data(FolderErrorMsg));
// QString statusText = qvariant_cast<QString>(index.data(FolderStatus));
bool syncEnabled = index.data(FolderSyncEnabled).toBool();
// QString syncStatus = syncEnabled? tr( "Enabled" ) : tr( "Disabled" );
@@ -118,16 +134,22 @@ void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
QRect aliasRect = option.rect;
QRect iconRect = option.rect;
iconRect.setRight( iconsize.width()+30 );
iconRect.setTop( iconRect.top() + (iconRect.height()-iconsize.height())/2);
aliasRect.setLeft(iconRect.right());
iconRect.setLeft( margin );
iconRect.setWidth( 48 );
iconRect.setTop( iconRect.top() + margin ); // (iconRect.height()-iconsize.height())/2);
QRect statusRect = iconRect;
statusRect.setLeft( option.rect.right() - margin - 48 );
statusRect.setRight( option.rect.right() - margin );
aliasRect.setLeft(iconRect.right()+margin);
aliasRect.setTop(aliasRect.top() + aliasFm.height()/2 );
aliasRect.setBottom(aliasRect.top()+subFm.height());
// local directory box
QRect localPathRect = aliasRect;
localPathRect.setTop(aliasRect.bottom() + subFm.height() / 2);
localPathRect.setTop(aliasRect.bottom() + margin / 3);
localPathRect.setBottom(localPathRect.top()+subFm.height());
// remote directory box
@@ -135,14 +157,16 @@ void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
remotePathRect.setTop( localPathRect.bottom() + subFm.height()/2 );
remotePathRect.setBottom( remotePathRect.top() + subFm.height());
iconRect.setBottom(remotePathRect.bottom());
//painter->drawPixmap(QPoint(iconRect.right()/2,iconRect.top()/2),icon.pixmap(iconsize.width(),iconsize.height()));
if( syncEnabled ) {
painter->drawPixmap(QPoint(iconRect.left()+15,iconRect.top()), folderIcon.pixmap(iconsize.width(),iconsize.height()));
painter->drawPixmap(QPoint(iconRect.left(),iconRect.top()), folderIcon.pixmap(iconsize.width(),iconsize.height()));
} else {
painter->drawPixmap(QPoint(iconRect.left()+15,iconRect.top()), folderIcon.pixmap(iconsize.width(),iconsize.height(), QIcon::Disabled ));
painter->drawPixmap(QPoint(iconRect.left(),iconRect.top()), folderIcon.pixmap(iconsize.width(),iconsize.height(), QIcon::Disabled ));
}
painter->drawPixmap(QPoint(option.rect.right() - 4 - 48, option.rect.top() + (option.rect.height()-48)/2 ), statusIcon.pixmap(48,48));
painter->drawPixmap(QPoint(statusRect.left(), statusRect.top()), statusIcon.pixmap(48,48));
painter->setFont(aliasFont);
painter->drawText(aliasRect, aliasText);
@@ -151,6 +175,30 @@ void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
painter->drawText(localPathRect.left(),localPathRect.top()+17, pathText);
painter->drawText(remotePathRect, tr("Remote path: %1").arg(remotePath));
// paint an error overlay if there is an error string
if( !errorText.isEmpty() ) {
QRect errorRect = localPathRect;
errorRect.setLeft( iconRect.left());
errorRect.setTop( iconRect.bottom()+subFm.height()/2 );
errorRect.setHeight(subFm.height()+margin);
errorRect.setRight( statusRect.right() );
painter->setBrush( QColor(0xbb, 0x4d, 0x4d) );
painter->setPen( QColor(0xaa, 0xaa, 0xaa));
painter->drawRoundedRect( errorRect, 4, 4 );
QIcon warnIcon(":/mirall/resources/warning-16");
painter->drawPixmap( QPoint(errorRect.left()+2, errorRect.top()+2), warnIcon.pixmap(QSize(16,16)));
painter->setPen( Qt::white );
painter->setFont(errorFont);
QRect errorTextRect = errorRect;
errorTextRect.setLeft( errorTextRect.left()+margin/2 +16);
errorTextRect.setTop( errorTextRect.top()+margin/2 );
painter->drawText(errorTextRect, errorText);
}
// painter->drawText(lastSyncRect, tr("Last Sync: %1").arg( statusText ));
// painter->drawText(statusRect, tr("Sync Status: %1").arg( syncStatus ));
painter->restore();
@@ -169,7 +217,7 @@ StatusDialog::StatusDialog( Theme *theme, QWidget *parent) :
QDialog(parent),
_theme( theme )
{
setupUi( this );
setupUi( this );
setWindowTitle( QString::fromLatin1( "%1 %2" ).arg(_theme->appName(), _theme->version() ) );
_model = new FolderStatusModel();
@@ -197,14 +245,8 @@ StatusDialog::StatusDialog( Theme *theme, QWidget *parent) :
_ButtonInfo->setEnabled(false);
_ButtonAdd->setEnabled(true);
#if defined Q_WS_X11
connect(_folderList, SIGNAL(activated(QModelIndex)), SLOT(slotFolderActivated(QModelIndex)));
connect( _folderList,SIGNAL(doubleClicked(QModelIndex)),SLOT(slotDoubleClicked(QModelIndex)));
#endif
#if defined Q_WS_WIN || defined Q_WS_MAC
connect(_folderList, SIGNAL(clicked(QModelIndex)), SLOT(slotFolderActivated(QModelIndex)));
connect( _folderList,SIGNAL(doubleClicked(QModelIndex)),SLOT(slotDoubleClicked(QModelIndex)));
#endif
connect(_folderList, SIGNAL(doubleClicked(QModelIndex)),SLOT(slotDoubleClicked(QModelIndex)));
_ocUrlLabel->setWordWrap( true );
}
@@ -250,6 +292,11 @@ void StatusDialog::setFolderList( Folder::Map folders )
slotAddFolder( f );
}
QModelIndex idx = _model->index(0, 0);
if (idx.isValid())
_folderList->setCurrentIndex(idx);
buttonsSetEnabled();
}
void StatusDialog::slotAddFolder( Folder *folder )
@@ -261,6 +308,30 @@ void StatusDialog::slotAddFolder( Folder *folder )
_model->appendRow( item );
}
void StatusDialog::buttonsSetEnabled()
{
bool haveFolders = _folderList->model()->rowCount() > 0;
_ButtonRemove->setEnabled(false);
if( _theme->singleSyncFolder() ) {
// only one folder synced folder allowed.
_ButtonAdd->setVisible(!haveFolders);
} else {
_ButtonAdd->setVisible(true);
_ButtonAdd->setEnabled(true);
}
QModelIndex selected = _folderList->currentIndex();
bool isSelected = selected.isValid();
_ButtonEnable->setEnabled(isSelected);
_ButtonRemove->setEnabled(isSelected);
_ButtonFetch->setEnabled(isSelected);
_ButtonInfo->setEnabled(isSelected);
_ButtonPush->setEnabled(isSelected);
}
void StatusDialog::slotUpdateFolderState( Folder *folder )
{
QStandardItem *item = 0;
@@ -330,6 +401,7 @@ void StatusDialog::slotRemoveSelectedFolder()
if( selected.isValid() ) {
_model->removeRow( selected.row() );
}
buttonsSetEnabled();
}
void StatusDialog::slotFetchFolder()
@@ -398,12 +470,12 @@ void StatusDialog::slotCheckConnection()
connect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotOCInfoFail(QNetworkReply*)));
_ocUrlLabel->setText( tr("Checking ownCloud connection..."));
_ocUrlLabel->setText( tr("Checking %1 connection...").arg(Theme::instance()->appName()));
qDebug() << "Check status.php from statusdialog.";
ownCloudInfo::instance()->checkInstallation();
} else {
// ownCloud is not yet configured.
_ocUrlLabel->setText( tr("No ownCloud connection configured."));
_ocUrlLabel->setText( tr("No %1 connection configured.").arg(Theme::instance()->appName()));
_ButtonAdd->setEnabled( false);
}
}
@@ -424,9 +496,11 @@ void StatusDialog::slotOCInfo( const QString& url, const QString& versionStr, co
qDebug() << "#-------# oC found on " << url;
/* enable the open button */
MirallConfigFile cfg;
_ocUrlLabel->setOpenExternalLinks(true);
_ocUrlLabel->setText( tr("Connected to <a href=\"%1\">%2</a>, ownCloud %3").arg(url).arg(url).arg(versionStr) );
_ocUrlLabel->setToolTip( tr("Version: %1").arg(version));
_ocUrlLabel->setText( tr("Connected to <a href=\"%1\">%1</a> as <i>%2</i>.")
.arg(url).arg( CredentialStore::instance()->user()) );
_ocUrlLabel->setToolTip( tr("Version: %1 (%2)").arg(versionStr).arg(version));
_ButtonAdd->setEnabled(true);
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),
@@ -442,7 +516,7 @@ void StatusDialog::slotOCInfoFail( QNetworkReply *reply)
QString errStr = tr("unknown problem.");
if( reply ) errStr = reply->errorString();
_ocUrlLabel->setText( tr("<p>Failed to connect to ownCloud: <tt>%1</tt></p>").arg(errStr) );
_ocUrlLabel->setText( tr("<p>Failed to connect to %1: <tt>%2</tt></p>").arg(Theme::instance()->appName()).arg(errStr) );
_ButtonAdd->setEnabled( false);
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),

View File

@@ -69,6 +69,7 @@ public:
~StatusDialog();
void setFolderList( Folder::Map );
void buttonsSetEnabled();
signals:
void removeFolderAlias( const QString& );

View File

@@ -18,11 +18,19 @@
#include <QtCore>
#include <QtGui>
#include "mirall/miralltheme.h"
#include "mirall/owncloudtheme.h"
#include "config.h"
namespace Mirall {
Theme::Theme()
{
Theme* Theme::_instance = 0;
Theme* Theme::instance() {
if (!_instance)
_instance = new THEME_CLASS;
return _instance;
}
QString Theme::statusHeaderText( SyncResult::Status status ) const
@@ -56,7 +64,7 @@ QString Theme::statusHeaderText( SyncResult::Status status ) const
QString Theme::version() const
{
return QString::fromLocal8Bit( MIRALL_STRINGIFY( MIRALL_VERSION ))+QLatin1String("beta1");
return QString::fromLocal8Bit( MIRALL_STRINGIFY( MIRALL_VERSION ));
}
QIcon Theme::trayFolderIcon( const QString& backend ) const
@@ -87,5 +95,29 @@ QIcon Theme::themeIcon( const QString& name ) const
return icon;
}
// if this option return true, the client only supports one folder to sync.
// The Add-Button is removed accoringly.
bool Theme::singleSyncFolder() const {
return false;
}
/**
* The default folder (without path) on the server at setup time.
*/
QString Theme::defaultServerFolder() const
{
return QLatin1String("clientsync");
}
/**
* The default folder (without path) on the client side at setup time.
*/
QString Theme::defaultClientFolder() const
{
return appName();
}
} // end namespace mirall

View File

@@ -30,7 +30,7 @@ class SyncResult;
class Theme
{
public:
Theme();
static Theme* instance();
virtual QString appName() const = 0;
@@ -59,10 +59,36 @@ public:
virtual QString statusHeaderText( SyncResult::Status ) const;
virtual QString version() const;
/**
* Characteristics: bool if more than one sync folder is allowed
*/
virtual bool singleSyncFolder() const;
/**
* The default folder name without path on the server at setup time.
*/
virtual QString defaultServerFolder() const;
/**
* The default folder name without path on the client side at setup time.
*/
virtual QString defaultClientFolder() const;
/**
* Override to encforce a particular locale, i.e. "de" or "pt_BR"
*/
virtual QString enforcedLocale() const { return QString::null; }
protected:
QIcon themeIcon(const QString& name) const;
Theme() {}
private:
Theme(Theme const&);
Theme& operator=(Theme const&);
static Theme* _instance;
};

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