Compare commits

..
125 Commits
Author SHA1 Message Date
Hivert Quentin 1f7e5d2b2c fix(sql): use proper sql adaptor for usr source 2026-03-24 15:26:37 +01:00
Hivert Quentin f322fa2721 chore(release): 5.12.6 2026-03-19 13:49:13 +01:00
Hivert Quentin 623f083cd9 fix(totp): new user can properly use totp 2026-03-19 13:30:28 +01:00
Hivert Quentin 7f7e1ad496 chore(release): 5.12.5 2026-03-03 12:49:33 +01:00
Hivert Quentin 4f92da4971 chore(js/css): update generated files 2026-03-03 01:01:16 -05:00
Hivert Quentin 1fdb4d3026 i18n(pt): Add Greek (partial) 2026-03-02 15:01:52 +01:00
Hivert Quentin fbd056cc29 i18n(pt): Update Portuguese translations 2026-03-02 11:49:55 +01:00
Hivert Quentin 39b820a549 i18n(pt_BR): Update BrazilianPortuguese translations 2026-03-02 11:49:55 +01:00
Hivert Quentin 1be58da745 i18n(ru): Update Russian translations 2026-03-02 11:49:55 +01:00
Hivert Quentin 6ce884b3e7 i18n(es_ES): Update SpanishSpain translations 2026-03-02 11:49:55 +01:00
Hivert Quentin 4a587fe000 i18n(ca): Update Catalan translations 2026-03-02 11:49:54 +01:00
Hivert Quentin d993227b36 i18n(th): Update Thai translations 2026-03-02 11:49:54 +01:00
Hivert Quentin 54e65233d9 chore(js/css): update generated files 2026-03-02 09:15:14 +00:00
Hivert Quentin 2c2dbe4c61 chore(js/css): update generated files 2026-02-26 01:00:41 -05:00
Hivert Quentin d7e51655fb fix(minsearch): fix instance of minsearch 2026-02-25 17:33:05 +01:00
Hivert Quentin 83d4c522f8 fix(vulnerability): properly change the totp code after disabling it 2026-02-25 15:23:57 +01:00
Hivert Quentin e821b20f87 fix(vulnerability): prevent javascript njection with hint query 2026-02-24 17:06:04 +01:00
Hivert Quentin dba92852f1 chore(js/css): update generated files 2026-02-06 01:00:40 -05:00
Hivert Quentin af984f58c0 fix(Mail): correctly update quota when refreshing 2026-02-05 10:51:41 +01:00
Hivert Quentin 71d865b86a fix(identity): fix signatrue when changing identity 2026-02-05 08:48:28 +01:00
Hivert Quentin 3abbc31ed4 chore(js/css): update generated files 2026-01-30 01:00:38 -05:00
Hivert Quentin 389e8e64c4 fix(ui): prevent UI to search for users with empty string 2026-01-29 15:58:00 +01:00
Hivert Quentin b46bf8b8dd chore(js/css): update generated files 2026-01-22 01:00:37 -05:00
Hivert Quentin 7a09408ef8 chore(js/css): update generated files 2025-12-31 01:00:38 -05:00
Hivert Quentin 95efe73e69 fix(encryptedUrl): fix cache key data and expect uncrypted name for freebusy 2025-12-22 17:28:49 +01:00
Hivert Quentin eb77a8e048 chore(js/css): update generated files 2025-12-17 01:00:34 -05:00
Hivert Quentin 7876013a4c fix(event): also add jitsi url in the location as outlook doesn't support attach url 2025-12-16 10:50:34 +01:00
Hivert Quentin e9b3f2a43d fix(vulnerability): prevent xss with events, tasks and contacts categories 2025-12-16 10:25:49 +01:00
vrubim 47239ba0fd add remaining traslations for catalan and spanish 2025-12-12 10:27:17 +01:00
Hivert Quentin 6f916008e9 fix(login): prevent user search for login keyword 2025-12-09 11:05:52 +01:00
Hivert Quentin 16ab99e7cf fix(vulnerability): prevent sogo to execute scripts pass in theme query 2025-11-26 13:22:38 +01:00
Hivert Quentin bd0547fb73 chore(js/css): update generated files 2025-11-25 01:00:34 -05:00
Hivert Quentin 03fa91dc22 fix(mail): use the correct replyTo when set to a non*default identity 2025-11-24 15:44:21 +01:00
Hivert Quentin e2b8494a9c fix(trad): typo in a transation key 2025-10-16 17:03:30 +02:00
Hivert Quentin d69f55c265 fix(tool): ranem-user properly change data in c_defaults and c_settings 2025-10-16 11:32:39 +02:00
Hivert Quentin f8638a3f4e fix(db): increase some column size 2025-10-15 17:07:37 +02:00
Hivert Quentin f18e3a05c3 chore(realease): 5.12.4 2025-10-06 09:52:02 +02:00
Hivert Quentin 6425a62e1a i18n(cy): Update Welsh translations 2025-10-06 09:47:41 +02:00
Hivert Quentin 5021376daf i18n(uk): Update Ukrainian translations 2025-10-06 09:47:41 +02:00
Hivert Quentin 8c38c9ce03 i18n(tr_TR): Update TurkishTurkey translations 2025-10-06 09:47:41 +02:00
Hivert Quentin f86a32d0a1 i18n(th): Update Thai translations 2025-10-06 09:47:41 +02:00
Hivert Quentin 2ebb63767e i18n(sv): Update Swedish translations 2025-10-06 09:47:41 +02:00
Hivert Quentin c755ab3b4e i18n(es_ES): Update SpanishSpain translations 2025-10-06 09:47:41 +02:00
Hivert Quentin 07e9d34865 i18n(es_AR): Update SpanishArgentina translations 2025-10-06 09:47:40 +02:00
Hivert Quentin 645be8fcc5 i18n(sl_SI): Update Slovenian translations 2025-10-06 09:47:39 +02:00
Hivert Quentin 0f24c17516 i18n(sk): Update Slovak translations 2025-10-06 09:47:39 +02:00
Hivert Quentin c675dbfaa7 i18n(sr@latin): Update SerbianLatin translations 2025-10-06 09:47:39 +02:00
Hivert Quentin dd367b0e94 i18n(sr): Update Serbian translations 2025-10-06 09:47:39 +02:00
Hivert Quentin 1a80fd6284 i18n(ru): Update Russian translations 2025-10-06 09:47:39 +02:00
Hivert Quentin ec4d7807d9 i18n(ro_RO): Update Romanian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 972ffcc0c6 i18n(pt): Update Portuguese translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 3a442f1b3d i18n(nn_NO): Update NorwegianNynorsk translations 2025-10-06 09:47:38 +02:00
Hivert Quentin eab6d9f249 i18n(nb_NO): Update NorwegianBokmal translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 3dc9b90992 i18n(sr_ME@latin): Update Montenegrin translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 798bed54e2 i18n(mk_MK): Update Macedonian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 2b455fe587 i18n(lt): Update Lithuanian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin ad7dc8f45e i18n(lv): Update Latvian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin ed9121175a i18n(ko): Update Korean translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 6514fbb8f1 i18n(kk): Update Kazakh translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 9a295c5944 i18n(ja): Update Japanese translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 1bb74c7522 i18n(it): Update Italian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 56e4929ca7 i18n(id_ID): Update Indonesian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 401e2f51cd i18n(is): Update Icelandic translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 799e8c21af i18n(hu): Update Hungarian translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 070705acfa i18n(he): Update Hebrew translations 2025-10-06 09:47:38 +02:00
Hivert Quentin 95e19379f6 i18n(de): Update German translations 2025-10-06 09:47:38 +02:00
Hivert Quentin f017fef4b2 i18n(gl): Update Galician translations 2025-10-06 09:47:38 +02:00
Hivert Quentin a914fd4151 i18n(fr): Update French translations 2025-10-06 09:47:38 +02:00
Hivert Quentin c0c506f910 i18n(fi): Update Finnish translations 2025-10-06 09:47:38 +02:00
Hivert Quentin b42882b564 i18n(nl): Update Dutch translations 2025-10-06 09:47:38 +02:00
Hivert Quentin ae293ec3ce i18n(da_DK): Update Danish translations 2025-10-06 09:47:38 +02:00
Hivert Quentin e662f10389 i18n(hr_HR): Update Croatian translations 2025-10-06 09:47:37 +02:00
Hivert Quentin c7a519ca12 i18n(zh_TW): Update ChineseTaiwan translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 22ab0b3c75 i18n(zh_CN): Update ChineseChina translations 2025-10-06 09:47:37 +02:00
Hivert Quentin b77129e2e7 i18n(ca): Update Catalan translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 4585293d99 i18n(bg_BG): Update Bulgarian translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 9d277c3f15 i18n(pt_BR): Update BrazilianPortuguese translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 4461122697 i18n(bs_BA): Update Bosnian translations 2025-10-06 09:47:37 +02:00
Hivert Quentin b96e531f66 i18n(eu): Update Basque translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 6c3e66142f i18n(ar): Update Arabic translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 16fcb46c4b i18n(pl): Update Polish translations 2025-10-06 09:47:37 +02:00
Hivert Quentin f252e0e2c2 i18n(cs): Update Czech translations 2025-10-06 09:47:37 +02:00
Hivert Quentin 09d87b2d23 chore(UI): update theme-default 2025-10-06 09:33:17 +02:00
Hivert Quentin 9e20190fad fix(login): Only remember the login if the auth was successful 2025-10-02 13:37:56 +02:00
Hivert Quentin 981748754a fix(mailer): don't add mailto: to string starting with @ 2025-09-24 09:18:08 +02:00
Hivert Quentin 8d8ef5fd67 chore(js/css): update generated files 2025-09-23 01:00:35 -04:00
Hivert Quentin 666c979eea fix(mailer): correctly show interline for p element 2025-09-22 09:57:12 +02:00
Hivert Quentin 1d59c616ac chore(js/css): update generated files 2025-09-20 01:00:35 -04:00
Hivert Quentin a7f7950d91 fix(eas): use proper imap mech for EAS request when using openid 2025-09-19 16:47:16 +02:00
Hivert Quentin 5d616600df feat(mail): Add a setting to show the attachments above the mail body 2025-09-19 15:30:45 +02:00
Hivert Quentin a077512e34 fix(ui): add css class for login page 2025-09-19 09:50:15 +02:00
Hivert Quentin 23c8648169 fix(label): missing trad 2025-09-17 13:48:39 +02:00
Hivert Quentin 9fad7e6f9c chore(packaging): prepare debian 13 2025-09-16 16:11:23 +02:00
Hivert Quentin 0fb3db0608 fix(label): ensure the translation kept is not null 2025-09-16 16:09:01 +02:00
Hivert Quentin a7651e56c5 fix(task): fix reminder for tasks 2025-09-15 17:21:47 +02:00
Emily Kooistra 481a9bf1de perf(calendar): don't allocate and copy all children for each time we call _filterComponent:
Improving the filtering of the calender objects, keeping a global static of the array of tags
that are allowed. And using removeChildren to prevent the need of a full copy while we iterate
over it.
2025-09-15 15:43:05 +02:00
Emily Kooistra f48f27c812 perf(core): store translations in a globally static NSMutableDictionary
fetching public ICS files without this patch result in continual opening
and closing of the "Localizable.strings" to create a NSDictionary,
looking up one key and closing it again. By caching it in a static
variable this greatly improves the performance.
2025-09-15 15:43:05 +02:00
Hivert Quentin 86d94ab8fe fix(log): remove the ics from the log line 2025-08-27 10:19:42 +02:00
Hivert Quentin aba41a06b4 chore(js/css): update generated files 2025-08-21 01:00:36 -04:00
Hivert Quentin ed7a136e0f fix(password): Correctly check the secret question answer when hitting enter instead of the button next 2025-08-20 14:04:31 +02:00
Patrick Ben Koetter d99f020f82 chore(doc): Modernized Headings for easier editing (#370) 2025-08-08 10:45:12 +02:00
Hivert Quentin 244d1388eb fix(calendar): fetch our own iana timezone instead of trusting VTIMEZONE 2025-08-01 11:56:06 +02:00
Hivert Quentin dfcbbba514 chore(build): remove unnecessary import 2025-07-29 13:50:52 +02:00
Hivert Quentin 7bee193413 fix(mail): preoperly generates the message-id header value 2025-07-28 17:40:14 +02:00
Hivert Quentin 4ef79e219c fix(openid): correcly type userTokenInterval 2025-07-28 16:08:17 +02:00
Hivert Quentin 736d7589b1 fix(ldap): fetch the correct user source when creating an event with an attendee 2025-07-28 13:52:15 +02:00
Hivert Quentin 4d8cca10f6 fix(kdap): don't try to fetch for a nobody user 2025-07-28 13:28:30 +02:00
Hivert Quentin c8dd5535b3 fix(sieveà: Sieve use the correct imap auth mechanism 2025-07-24 15:03:30 +02:00
Hivert Quentin 42f620e562 fix(curl): properly close curl connection 2025-07-24 14:46:45 +02:00
Hivert Quentin 3662846900 chore(js/css): update generated files 2025-07-22 01:00:32 -04:00
Hivert Quentin b9f6b90740 Revert "fix(view): automatically refresh view only if a number is set."
This reverts commit 55dbae6bee.
2025-07-21 13:11:30 +02:00
Hivert Quentin b69ef6d7a5 chore(release): 5.12.3 2025-07-12 09:44:17 +02:00
Hivert Quentin 3ab86776e2 fix(calendar): fix recurrent event last date
Fix a bug introduces by #8766b7c
2025-07-08 15:26:09 +02:00
Hivert Quentin 7fa0daea43 chore(js/css): update generated files 2025-07-08 01:00:38 -04:00
Hivert Quentin 55dbae6bee fix(view): automatically refresh view only if a number is set. 2025-07-07 15:39:59 +02:00
Hivert Quentin d48befd151 chore(js/css): update generated files 2025-07-04 01:00:36 -04:00
Hivert Quentin f5f8f112cd chore(language): Add Thai language 2025-07-03 16:59:56 +02:00
Hivert Quentin 08bc6aff3f chore(language): Add Korean language 2025-07-03 09:35:50 +02:00
Hivert Quentin 8290cf2859 chore(doc): add doc por api 2025-06-25 14:16:17 +02:00
Hivert Quentin 8f03432a55 chore(release): 5.12.2 2025-06-25 09:34:32 +02:00
Hivert Quentin 9649ae345f i18n(pt): Update Portuguese translations 2025-06-25 08:52:35 +02:00
Hivert Quentin e9c03d3cf7 i18n(tr_TR): Update TurkishTurkey translations 2025-06-25 08:52:35 +02:00
Hivert Quentin 031e117cba i18n(nl): Update Dutch translations 2025-06-25 08:52:34 +02:00
Hivert Quentin dabad1d0cf fix(api): add handler for internal error 2025-06-24 10:20:12 +02:00
Hivert Quentin c1b6388260 chore(packaging): fix rhel packaging 2025-06-24 09:30:28 +02:00
271 changed files with 11176 additions and 874 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
[main]
host = https://www.transifex.com
lang_map = fr: French, pt_BR: BrazilianPortuguese, ru: Russian, sk: Slovak, es_AR: SpanishArgentina, fi: Finnish, id_ID: Indonesian, lt: Lithuanian, tr_TR: TurkishTurkey, zh_TW: ChineseTaiwan, ar: Arabic, cs: Czech, nn_NO: NorwegianNynorsk, sl_SI: Slovenian, uk: Ukrainian, zh_CN: ChineseChina, sv: Swedish, bg_BG: Bulgarian, cy: Welsh, is: Icelandic, sr: Serbian, lv: Latvian, pl: Polish, ro_RO: Romanian, bs_BA: Bosnian,ca: Catalan, he: Hebrew, kk: Kazakh, pt: Portuguese, es_ES: SpanishSpain, eu: Basque, hu: Hungarian, ja: Japanese, mk_MK: Macedonian, nb_NO: NorwegianBokmal, nl: Dutch, sr@latin: SerbianLatin, da_DK: Danish, de: German, hr_HR: Croatian, it: Italian, sr_ME@latin: Montenegrin, gl_ES: Galician
lang_map = fr: French, pt_BR: BrazilianPortuguese, ru: Russian, sk: Slovak, es_AR: SpanishArgentina, fi: Finnish, id_ID: Indonesian, lt: Lithuanian, tr_TR: TurkishTurkey, zh_TW: ChineseTaiwan, ar: Arabic, cs: Czech, nn_NO: NorwegianNynorsk, sl_SI: Slovenian, uk: Ukrainian, zh_CN: ChineseChina, sv: Swedish, bg_BG: Bulgarian, cy: Welsh, is: Icelandic, sr: Serbian, lv: Latvian, pl: Polish, ro_RO: Romanian, bs_BA: Bosnian,ca: Catalan, he: Hebrew, kk: Kazakh, pt: Portuguese, es_ES: SpanishSpain, eu: Basque, hu: Hungarian, ja: Japanese, mk_MK: Macedonian, nb_NO: NorwegianBokmal, nl: Dutch, sr@latin: SerbianLatin, da_DK: Danish, de: German, hr_HR: Croatian, it: Italian, sr_ME@latin: Montenegrin, gl_ES: Galician, ko: Korean, th: Thai, el: Greek
[o:alinto:p:sogo:r:soobjects-appointments]
source_file = SoObjects/Appointments/English.lproj/Localizable.strings
+13 -13
View File
@@ -371,20 +371,20 @@ void handle_api_terminate(int signum)
}
//Execute action
// NS_DURING
// {
NS_DURING
{
ret = [classAction action: context withParam: paramInjected];
// }
// NS_HANDLER
// {
// error = [NSString stringWithFormat: @"Internal error during: %@", action];
// [self errorWithFormat: error];
// [self _sendAPIErrorResponse: theResponse withMessage: error withStatus: 500];
// RELEASE(context);
// RELEASE(pool);
// return nil;
// }
// NS_ENDHANDLER;
}
NS_HANDLER
{
error = [NSString stringWithFormat: @"Internal error during: %@", action];
[self errorWithFormat: error];
[self _sendAPIErrorResponse: theResponse withMessage: error withStatus: 500];
RELEASE(context);
RELEASE(pool);
return nil;
}
NS_ENDHANDLER;
//Make the response
+1 -1
View File
@@ -1627,7 +1627,7 @@ struct GlobalObjectId {
[map setObject: dateReceived forKey: @"date"];
messageId = [NSString generateMessageID];
messageId = [NSString generateMessageID: [identity objectForKey: @"email"]];
[map setObject: messageId forKey: @"message-id"];
attachmentKeys = [self fetchFileAttachmentKeys];
+150
View File
@@ -2,6 +2,156 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [5.12.6](https://github.com/Alinto/sogo/compare/SOGo-5.12.6...SOGo-5.12.6) (2026-03-19)
### Bug Fixes
* **totp:** new user can properly use totp ([623f08](https://github.com/Alinto/sogo/commit/623f083cd94842766c6d9430cf3bdad8fc4d5dbc))
### [5.12.5](https://github.com/Alinto/sogo/compare/SOGo-5.12.4...SOGo-5.12.5) (2026-03-03)
### Bug Fixes
* **db:** increase some column size ([f8638a3](https://github.com/Alinto/sogo/commit/f8638a3f4edd3487901c119b079dea2a3746cd7c))
* **encryptedUrl:** fix cache key data and expect uncrypted name for freebusy ([95efe73](https://github.com/Alinto/sogo/commit/95efe73e69abaae7fb8c1bdd0fe7ac660d59d7a4))
* **event:** also add jitsi url in the location as outlook doesn't support attach url ([7876013](https://github.com/Alinto/sogo/commit/7876013a4c1b0c7a1ac7153f2c61ff5f3de39632))
* **identity:** fix signatrue when changing identity ([71d865b](https://github.com/Alinto/sogo/commit/71d865b86a7c11dc6aa8612999ae515f14a3bdf2))
* **login:** prevent user search for login keyword ([6f91600](https://github.com/Alinto/sogo/commit/6f916008e9e30bceaf5942e0c8645006d07d3aec))
* **Mail:** correctly update quota when refreshing ([af984f5](https://github.com/Alinto/sogo/commit/af984f58c043cb7ddc8597f119c8a5b9737612b2))
* **mail:** use the correct replyTo when set to a non*default identity ([03fa91d](https://github.com/Alinto/sogo/commit/03fa91dc22b268ce230f78e7386234ca84814f27))
* **minsearch:** fix instance of minsearch ([d7e5165](https://github.com/Alinto/sogo/commit/d7e51655fb0a543cff68a9fbc10ceb67540e4bec))
* **tool:** rename-user properly change data in c_defaults and c_settings ([d69f55c](https://github.com/Alinto/sogo/commit/d69f55c265e0e5873032d5e14e49636ed6c36631))
* **trad:** typo in a transation key ([e2b8494](https://github.com/Alinto/sogo/commit/e2b8494a9cde046a8aad71808353366c328e0230))
* **ui:** prevent UI to search for users with empty string ([389e8e6](https://github.com/Alinto/sogo/commit/389e8e64c4933edbcc1f756f422594e70d70c903))
* **vulnerability:** prevent javascript njection with hint query ([e821b20](https://github.com/Alinto/sogo/commit/e821b20f87d1a9757f1d0aff7d1e31703f97054b))
* **vulnerability:** prevent sogo to execute scripts pass in theme query ([16ab99e](https://github.com/Alinto/sogo/commit/16ab99e7cf8db2c30b211f0d5e338d7f9e3a9efb))
* **vulnerability:** prevent xss with events, tasks and contacts categories ([e9b3f2a](https://github.com/Alinto/sogo/commit/e9b3f2a43d7557e8416f6749df4ab4f9128af2d1))
* **vulnerability:** properly change the totp code after disabling it ([83d4c52](https://github.com/Alinto/sogo/commit/83d4c522f87cfde0ba543837d9b24c3479083ec2))
### Localization
* **ca:** Update Catalan translations ([4a587fe](https://github.com/Alinto/sogo/commit/4a587fe00044bfce55186a7f75af64b5256399d7))
* **es_ES:** Update SpanishSpain translations ([6ce884b](https://github.com/Alinto/sogo/commit/6ce884b3e71cc08c1e3eedb722be00ade6d1263f))
* **pt_BR:** Update BrazilianPortuguese translations ([39b820a](https://github.com/Alinto/sogo/commit/39b820a5490eadbbadc6872f0814c23b7a6d4a13))
* **pt:** Add Greek (partial) ([1fdb4d3](https://github.com/Alinto/sogo/commit/1fdb4d30261f5d69d83eef7d8615ef62ddd94a7e))
* **pt:** Update Portuguese translations ([fbd056c](https://github.com/Alinto/sogo/commit/fbd056cc293a7c53f0ff0de4dd8a50a0d998291f))
* **ru:** Update Russian translations ([1be58da](https://github.com/Alinto/sogo/commit/1be58da745b875aeb12096ac8fb8c51c6df99068))
* **th:** Update Thai translations ([d993227](https://github.com/Alinto/sogo/commit/d993227b36b6fbddebf113a5b544aa3bebf01bcc))
## [5.12.4](https://github.com/Alinto/sogo/compare/SOGo-5.12.3...SOGo-5.13.0) (2025-10-06)
### Enhancements
* **mail:** Add a setting to show the attachments above the mail body ([5d61660](https://github.com/Alinto/sogo/commit/5d616600dfa6258e4eebcb5c065e393ebfae8f3a))
### Bug Fixes
* **calendar:** fetch our own iana timezone instead of trusting VTIMEZONE ([244d138](https://github.com/Alinto/sogo/commit/244d1388eb00c060c5302e5bfd997fd397820bc0))
* **curl:** properly close curl connection ([42f620e](https://github.com/Alinto/sogo/commit/42f620e56201e17391532507c02ae370f117c574))
* **eas:** use proper imap mech for EAS request when using openid ([a7f7950](https://github.com/Alinto/sogo/commit/a7f7950d91c83acd75c0b0d55dec74ab85d38d6c))
* **ldap:** don't try to fetch for a nobody user ([4d8cca1](https://github.com/Alinto/sogo/commit/4d8cca10f63aff9499b71d61d59d6f81570eb659))
* **label:** ensure the translation kept is not null ([0fb3db0](https://github.com/Alinto/sogo/commit/0fb3db060871a14e2abd8c6963ccd812cbacf200))
* **label:** missing trad ([23c8648](https://github.com/Alinto/sogo/commit/23c8648169b4893aaafa2e369259d94d56c76831))
* **ldap:** fetch the correct user source when creating an event with an attendee ([736d758](https://github.com/Alinto/sogo/commit/736d7589b16be4ebcf9fc6931a79187888c3b444))
* **login:** Only remember the login if the auth was successful ([9e20190](https://github.com/Alinto/sogo/commit/9e20190fad1a437f7e1307f0adcfe19a8d45184c))
* **log:** remove the ics from the log line ([86d94ab](https://github.com/Alinto/sogo/commit/86d94ab8fefaf3aa5ba99e13c28a0b24036d94ff))
* **mailer:** correctly show interline for p element ([666c979](https://github.com/Alinto/sogo/commit/666c979eeae6d51a6bc09684ebbab57ed9ce4b91))
* **mailer:** don't add mailto: to string starting with @ ([9817487](https://github.com/Alinto/sogo/commit/981748754a4857bab66a6fb94cdc5da4265ce003))
* **mail:** preoperly generates the message-id header value ([7bee193](https://github.com/Alinto/sogo/commit/7bee193413935ca03e4936a15791fbbb534493ec))
* **openid:** correcly type userTokenInterval ([4ef79e2](https://github.com/Alinto/sogo/commit/4ef79e219c289697eec0c2d100c8af1a5d0889b6))
* **password:** Correctly check the secret question answer when hitting enter instead of the button next ([ed7a136](https://github.com/Alinto/sogo/commit/ed7a136e0f2c5ecd35033aef6d0561d9fcf2ccdc))
* **task:** fix reminder for tasks ([a7651e5](https://github.com/Alinto/sogo/commit/a7651e56c53a4dc33892d86f404a132a2b8af83a))
* **ui:** add css class for login page ([a077512](https://github.com/Alinto/sogo/commit/a077512e34bf42933457b92613b348ff2e06642a))
* **calendar:** don't allocate and copy all children for each time we call _filterComponent: ([481a9bf](https://github.com/Alinto/sogo/commit/481a9bf1de1da8e07b5ed4c1786aac89d19ca6c3))
* **core:** store translations in a globally static NSMutableDictionary ([f48f27c](https://github.com/Alinto/sogo/commit/f48f27c812466ce806ab60b43ebe5a2bfc97ed0a))
### Localization
* **ar:** Update Arabic translations ([6c3e661](https://github.com/Alinto/sogo/commit/6c3e66142f50c68ee9b1435e5d6961573e7445d4))
* **bg_BG:** Update Bulgarian translations ([4585293](https://github.com/Alinto/sogo/commit/4585293d999152e6c7b54f00f73f925051a4ed64))
* **bs_BA:** Update Bosnian translations ([4461122](https://github.com/Alinto/sogo/commit/446112269705ae1565a21d3e39e4665c172fc3d4))
* **ca:** Update Catalan translations ([b77129e](https://github.com/Alinto/sogo/commit/b77129e2e7608f163eeeb1c4ed7e35fb5558c3cb))
* **cs:** Update Czech translations ([f252e0e](https://github.com/Alinto/sogo/commit/f252e0e2c271118cceb2979a828f5220350ba57f))
* **cy:** Update Welsh translations ([6425a62](https://github.com/Alinto/sogo/commit/6425a62e1ab8900dc83df5ca165eb92718856886))
* **da_DK:** Update Danish translations ([ae293ec](https://github.com/Alinto/sogo/commit/ae293ec3ce7488530199e82bd7bde50b2d506a43))
* **de:** Update German translations ([95e1937](https://github.com/Alinto/sogo/commit/95e19379f6fa698f54a09d7b7bcb4cfe16b4c358))
* **es_AR:** Update SpanishArgentina translations ([07e9d34](https://github.com/Alinto/sogo/commit/07e9d34865e57fa64f8db1b7ed4a5a67a0c1f234))
* **es_ES:** Update SpanishSpain translations ([c755ab3](https://github.com/Alinto/sogo/commit/c755ab3b4ea5ecad2c98d396d6bca6d873d0f1de))
* **eu:** Update Basque translations ([b96e531](https://github.com/Alinto/sogo/commit/b96e531f662a41802bd83e54e4a8055987d36164))
* **fi:** Update Finnish translations ([c0c506f](https://github.com/Alinto/sogo/commit/c0c506f9103b12ed5a39b340c4bccac500a2f6a8))
* **fr:** Update French translations ([a914fd4](https://github.com/Alinto/sogo/commit/a914fd4151e5565d4f168819c2664dc460587dec))
* **gl:** Update Galician translations ([f017fef](https://github.com/Alinto/sogo/commit/f017fef4b2a86f210f36bd5e62afe37c7bba3a18))
* **he:** Update Hebrew translations ([070705a](https://github.com/Alinto/sogo/commit/070705acfaa65ad435c1d2fa659e4b1f333b59a8))
* **hr_HR:** Update Croatian translations ([e662f10](https://github.com/Alinto/sogo/commit/e662f10389795e281abd283775f0d168a519e25d))
* **hu:** Update Hungarian translations ([799e8c2](https://github.com/Alinto/sogo/commit/799e8c21af79b2a8beb082a9d56a238aee30ae4a))
* **id_ID:** Update Indonesian translations ([56e4929](https://github.com/Alinto/sogo/commit/56e4929ca78c105dde470a6d26749b1328fad47f))
* **is:** Update Icelandic translations ([401e2f5](https://github.com/Alinto/sogo/commit/401e2f51cd3a69afa72fb76ffeb8fc91a5779cca))
* **it:** Update Italian translations ([1bb74c7](https://github.com/Alinto/sogo/commit/1bb74c75227f858d680035a5eccd7c5ef954f869))
* **ja:** Update Japanese translations ([9a295c5](https://github.com/Alinto/sogo/commit/9a295c5944886df95b941f716fc5e6b4c62525b7))
* **kk:** Update Kazakh translations ([6514fbb](https://github.com/Alinto/sogo/commit/6514fbb8f1c2745dd44be49c72da88937fcf107f))
* **ko:** Update Korean translations ([ed91211](https://github.com/Alinto/sogo/commit/ed9121175aa6164a73987a247cebe47e53676529))
* **lt:** Update Lithuanian translations ([2b455fe](https://github.com/Alinto/sogo/commit/2b455fe587f96700c4398538b995680251660ac1))
* **lv:** Update Latvian translations ([ad7dc8f](https://github.com/Alinto/sogo/commit/ad7dc8f45ee316c4d39ebf5fa71207947b4be2f8))
* **mk_MK:** Update Macedonian translations ([798bed5](https://github.com/Alinto/sogo/commit/798bed54e2eb0f76f26dc6c6c423285c565b9888))
* **nb_NO:** Update NorwegianBokmal translations ([eab6d9f](https://github.com/Alinto/sogo/commit/eab6d9f2492eccc2397c3ad49ab284223cb8771c))
* **nl:** Update Dutch translations ([b42882b](https://github.com/Alinto/sogo/commit/b42882b564ad9aa1b510b00d06da21688d959785))
* **nn_NO:** Update NorwegianNynorsk translations ([3a442f1](https://github.com/Alinto/sogo/commit/3a442f1b3d38350a5544f0fb62718f45b70c37ad))
* **pl:** Update Polish translations ([16fcb46](https://github.com/Alinto/sogo/commit/16fcb46c4be26497d12be712c5bacf0f0056a5b3))
* **pt_BR:** Update BrazilianPortuguese translations ([9d277c3](https://github.com/Alinto/sogo/commit/9d277c3f157e21183648609e5bee429559e87a63))
* **pt:** Update Portuguese translations ([972ffcc](https://github.com/Alinto/sogo/commit/972ffcc0c6f4f67da5557da28b6c5af87d632b96))
* **ro_RO:** Update Romanian translations ([ec4d780](https://github.com/Alinto/sogo/commit/ec4d7807d994836218c6ba9c5979283623a520d4))
* **ru:** Update Russian translations ([1a80fd6](https://github.com/Alinto/sogo/commit/1a80fd6284750cc9997e6cbbafcdf86765032405))
* **sk:** Update Slovak translations ([0f24c17](https://github.com/Alinto/sogo/commit/0f24c175163e2a000d6cace4d9302cae384f3b49))
* **sl_SI:** Update Slovenian translations ([645be8f](https://github.com/Alinto/sogo/commit/645be8fcc53cd2729dad9906e66a8f630cffaf52))
* **sr_ME@latin:** Update Montenegrin translations ([3dc9b90](https://github.com/Alinto/sogo/commit/3dc9b9099223940ec4a4f660d499ac450398d6cc))
* **sr@latin:** Update SerbianLatin translations ([c675dbf](https://github.com/Alinto/sogo/commit/c675dbfaa70755abf4300462f538dfa878c7c969))
* **sr:** Update Serbian translations ([dd367b0](https://github.com/Alinto/sogo/commit/dd367b0e94b74dccfc862d9ca07906cc16234965))
* **sv:** Update Swedish translations ([2ebb637](https://github.com/Alinto/sogo/commit/2ebb63767e53c39bc982d9959dabacfdce8b9b19))
* **th:** Update Thai translations ([f86a32d](https://github.com/Alinto/sogo/commit/f86a32d0a148b8465a01f098855dc58470c1a689))
* **tr_TR:** Update TurkishTurkey translations ([8c38c9c](https://github.com/Alinto/sogo/commit/8c38c9ce038e902d4b79f2093448ffec2c1f1d55))
* **uk:** Update Ukrainian translations ([5021376](https://github.com/Alinto/sogo/commit/5021376daf92c95a69afa2a2d99cf559f858d478))
* **zh_CN:** Update ChineseChina translations ([22ab0b3](https://github.com/Alinto/sogo/commit/22ab0b3c751f7c20c234c1824552aaa4c661f983))
* **zh_TW:** Update ChineseTaiwan translations ([c7a519c](https://github.com/Alinto/sogo/commit/c7a519ca124121e259a00473e6163cbd93e16aa4))
### [5.12.3](https://github.com/Alinto/sogo/compare/SOGo-5.12.2...SOGo-5.12.3) (2025-07-12)
### Bug Fixes
* **calendar:** fix recurrent event last date ([3ab8677](https://github.com/Alinto/sogo/commit/3ab86776e2ea826e043e3a0519097538853d82e3)), closes [#8766b7](https://bugs.sogo.nu/view.php?id=8766b7)
* **view:** automatically refresh view only if a number is set. ([55dbae6](https://github.com/Alinto/sogo/commit/55dbae6bee9bdd1aa00333320ba076617cbfb0fc))
## [5.12.2](https://github.com/Alinto/sogo/compare/SOGo-5.12.1...SOGo-5.12.2) (2025-06-25)
### Features
* **api:** add endpoint for caldav/cardav url ([51f1521](https://github.com/Alinto/sogo/commit/51f1521dba2d0ca8bdbadffadb16db26b975f668))
* **openid:** swicth to libcurl for http request ([a782424](https://github.com/Alinto/sogo/commit/a782424a30cfe8e9c6f2769a45bcdd3498679237))
### Bug Fixes
* **api:** add handler for internal error ([dabad1d](https://github.com/Alinto/sogo/commit/dabad1d0cf46263d78558d79d2af9fff528a9a89))
* **calendar:** properly evalute last occurance freebusy ([8766b7c](https://github.com/Alinto/sogo/commit/8766b7c6b32aedf37d7f8f350e461931b253a4fb))
* **openid:** add state in connection flow ([085fc4a](https://github.com/Alinto/sogo/commit/085fc4a9eb7d1e2a0f7b48baa1f09a8ba0d515e1))
* **openid:** allow expires_in param to be null ([9954c36](https://github.com/Alinto/sogo/commit/9954c3607bfda55424f5ac532a1075407235f345))
* **openid:** make end_session_endpoint optional ([c5fb348](https://github.com/Alinto/sogo/commit/c5fb3482e22f1bfc935213e8ed7208becd9bd1f4))
* **password:** put correct regex for special char ([e36d0d2](https://github.com/Alinto/sogo/commit/e36d0d219baed8c7d57af0069fadb8d1bf7df072))
* **session:** allow password/token to be longer than userkey ([516606b](https://github.com/Alinto/sogo/commit/516606baff5674c25da1e76f532ca2a9d7818ec0))
* **sieve:** add requirements for notify when doing a filter ([f53d7b7](https://github.com/Alinto/sogo/commit/f53d7b73db3d87a17a253bf98ee09a80052b3fd8))
* **view:** don't hide the option mailcomposer in small screen ([8a90773](https://github.com/Alinto/sogo/commit/8a907737de336f873047ecdc7d5c8ac07ae9e45b))
### Localization
* **nl:** Update Dutch translations ([031e117](https://github.com/Alinto/sogo/commit/031e117cbacf9d41caff43be19e639dee81b84dc))
* **pt:** Update Portuguese translations ([9649ae3](https://github.com/Alinto/sogo/commit/9649ae345f334d390860b0db70db8c3b621f513e))
* **tr_TR:** Update TurkishTurkey translations ([e9c03d3](https://github.com/Alinto/sogo/commit/e9c03d3cf7e668866ac757f72d87cdc4709c9d33))
## [5.12.1](https://github.com/Alinto/sogo/compare/SOGo-5.12.0...SOGo-5.12.1) (2025-04-30)
+264 -130
View File
@@ -1,5 +1,4 @@
Installation and Configuration Guide
====================================
= Installation and Configuration Guide
////
This file is part of the SOGo project.
@@ -10,8 +9,8 @@ Installation and Configuration Guide
////
include::includes/global-attributes.asciidoc[]
About this Guide
----------------
== About this Guide
This guide will walk you through the installation and configuration of
the SOGo solution. It also covers the installation and configuration of
@@ -23,8 +22,8 @@ The instructions are based on version {release_version} of SOGo.
The latest version of this guide is available
at https://www.sogo.nu/support.html#/documentation.
Introduction
------------
== Introduction
SOGo is a free and modern scalable groupware server. It offers shared
calendars, address books, and emails through your favourite Web browser
@@ -48,8 +47,8 @@ device, or Outlook 2013/2016
SOGo is developed by a community of developers located mainly in North
America and Europe. More information can be found at https://sogo.nu/
Architecture and Compatibility
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Architecture and Compatibility
image::images/architecture.png[System Architecture, 400, 964]
@@ -61,11 +60,11 @@ protocol are also supported.
To install and configure the Outlook CalDav Synchronizer, please refer
to the _Outlook Connector Configuration Guide_.
System Requirements
-------------------
Assumptions
~~~~~~~~~~~
== System Requirements
=== Assumptions
SOGo reuses many components in an infrastructure. Thus, it requires the
following:
@@ -104,8 +103,8 @@ components, together with version numbers:
More recent versions of the software mentioned above can also be used.
Minimum Hardware Requirements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Minimum Hardware Requirements
The following table provides hardware recommendations for the server,
desktops and mobile devices:
@@ -157,8 +156,8 @@ Linux
Microsoft ActiveSync.
|=======================================================================
Operating System Requirements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Operating System Requirements
The following operating systems are currently supported by SOGo:
@@ -182,16 +181,16 @@ directly to the SOGo website at https://sogo.nu/faq/installation.html.
Note that once the SOGo packages are installed under Debian and Ubuntu,
this guide can be followed in order to fully configure SOGo.
Installation
------------
== Installation
This section will guide you through the installation of SOGo together
with its dependencies. The steps described here apply to an RPM-based
installation for a Red Hat or CentOS 7 distribution. Most of these steps
should apply to all supported operating systems.
Software Downloads
~~~~~~~~~~~~~~~~~~
=== Software Downloads
**In order to access the community build, go to https://www.sogo.nu/download.html[SOGo website]
and select "Development (nightly builds)" at the bottom of the page.**
@@ -255,8 +254,8 @@ sed -i '/enabled=1/a exclude=gnustep* ytnef*' /etc/yum.repos.d/epel.repo
For more information on EPEL, visit http://fedoraproject.org/wiki/EPEL/.
Software Installation
~~~~~~~~~~~~~~~~~~~~~
=== Software Installation
Once the yum configuration file has been created, you are now ready to
install SOGo and its dependencies. To do so, proceed with the following
@@ -276,8 +275,8 @@ for Oracle. The installation command will thus look like this:
Once completed, SOGo will be fully installed on your server. You are now
ready to configure it.
Configuration
-------------
== Configuration
In this section, you'll learn how to configure SOGo to use your existing
LDAP, SMTP and database servers. As previously mentioned, we assume that
@@ -285,8 +284,8 @@ those components run on the same server on which SOGo is being
installed. If this is not the case, please adjust the configuration
parameters to reflect those changes.
GNUstep Environment Overview
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== GNUstep Environment Overview
SOGo makes use of the GNUstep environment. GNUstep is a free software
implementation of the OpenStep specification which provides many
@@ -319,8 +318,8 @@ wrapped within curly brackets `{ [configuration] }`. If SOGo refuses to
start due to syntax errors in its configuration file, `plparse` is helpful
for finding these, as it indicates the line containing the problem.
Preferences Hierarchy
~~~~~~~~~~~~~~~~~~~~~
=== Preferences Hierarchy
SOGo supports domain names segregation, meaning that you can separate
multiple groups of users within one installation of SOGo. A user
@@ -350,8 +349,8 @@ following abbreviations in the tables of this document:
Remember that the hierarchy paradigm allow the default value of a
parameter to be defined at a parent level.
General Preferences
~~~~~~~~~~~~~~~~~~~
=== General Preferences
The following table describes the general parameters that can be set:
@@ -879,8 +878,8 @@ Obiously, if your users can connect without specifying a domain, let this parame
[[Secret-for-sensitive-data]]
Secret for sensitive data
~~~~~~~~~~~~~~~~~~~~~~~~~
=== Secret for sensitive data
_Since 5.10_
@@ -974,8 +973,7 @@ sogo-tool user-preferences unset default <user> AuxiliaryMailAccounts
user being the full mail address or just the username if domainless. After that, the user will have to set its auxiliary accounts again.
Authentication using LDAP
~~~~~~~~~~~~~~~~~~~~~~~~~
=== Authentication using LDAP
SOGo can use a LDAP server to authenticate users and, if desired, to
provide global address books. SOGo can also use an SQL backend for this
@@ -1385,8 +1383,8 @@ Defaults to `NO` when unset.
|=======================================================================
LDAP Attributes Indexing
~~~~~~~~~~~~~~~~~~~~~~~~
=== LDAP Attributes Indexing
To ensure proper performance of the SOGo application, the following LDAP
attributes must be fully indexed:
@@ -1402,8 +1400,8 @@ attributes must be fully indexed:
Please refer to the documentation of the software you use in order to
index those attributes.
LDAP Attributes Mapping
~~~~~~~~~~~~~~~~~~~~~~~
=== LDAP Attributes Mapping
Some LDAP attributes are mapped to contacts attributes in the SOGo UI.
The table below list most of them. It is possible to override these by
@@ -1463,8 +1461,8 @@ mapping = {
|Photo |photo
|===
Authenticating using C.A.S.
~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Authenticating using C.A.S.
SOGo natively supports C.A.S. authentication. For activating C.A.S.
authentication you need first to make sure that the
@@ -1567,8 +1565,8 @@ expected by pam_cas, otherwise it will fail to authenticate incoming
connection properly.
Authenticating using OPENID
~~~~~~~~~~~~~~~~~~~~~~~~~~~
[[openid-section]]
=== Authenticating using OPENID
SOGo natively supports OPENID authentication. For activating OpenId authentication you need first to make sure that
_SOGoAuthenticationType_ is set to `openid`,
@@ -1641,8 +1639,8 @@ the session will stays in the table and be useless. That's why a new sogo-tool c
You can put it in a cron to do that periodicly. +
See _<<sogo-tool-clean-openid-sessions,sogo-tool clean-openid-sessions>>_.
Authenticating using SAML2
~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Authenticating using SAML2
SOGo natively supports SAML2 authentication. Please refer to the documentation of your identity
provider and the SAML2 configuration keys that are listed above for proper setup. Once a SOGo
@@ -1675,8 +1673,7 @@ _NGImap4AuthMechanism_ is configured to use the `SAML` mechanism. If you
make use of the CrudeSAML PAM plugin, this value may be left empty.
Database Configuration
~~~~~~~~~~~~~~~~~~~~~~
=== Database Configuration
SOGo requires a relational database system in order to store
appointments, tasks and contacts information. It also uses the database
@@ -1923,10 +1920,9 @@ calendar.
Ensure the computer used for the test has emoji fonts installed.
[[Authentication-using-SQL]]
Authentication using SQL
~~~~~~~~~~~~~~~~~~~~~~~~
[[Authentication-using-SQL]]
=== Authentication using SQL
SOGo can use a SQL-based database server for authentication. The
configuration is very similar to LDAP-based authentication.
@@ -2163,8 +2159,8 @@ or username@domain.tld
Note that groups are currently not supported for SQL-based
authentication sources.
SMTP Server Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~
=== SMTP Server Configuration
SOGo makes use of a SMTP server to send emails from the Web interface,
iMIP/iTIP messages and various notifications.
@@ -2223,8 +2219,8 @@ Possible values are:
Defaults to `NO` when unset.
|=======================================================================
IMAP Server Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~
=== IMAP Server Configuration
SOGo requires an IMAP server in order to let users consult their email
messages, manage their folders and more.
@@ -2392,8 +2388,8 @@ permissions for the individual user.
The default prefix is `$`. 
|=======================================================================
Web Interface Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Web Interface Configuration
The following additional parameters only affect the Web interface
behaviour of SOGo.
@@ -2900,8 +2896,8 @@ SOGoMailJunkSettings = {
sent by SOGo. Defaults to `NO` when unset.
|=======================================================================
SOGo Configuration Summary
~~~~~~~~~~~~~~~~~~~~~~~~~~
=== SOGo Configuration Summary
The complete SOGo configuration file `/etc/sogo/sogo.conf` should look
like this:
@@ -2949,10 +2945,9 @@ like this:
}
----
[[multi-domains-configuration]]
Multi-domains Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~
[[multi-domains-configuration]]
=== Multi-domains Configuration
If you want your installation to isolate two groups of users, you must
define a distinct authentication source for each _domain_. Your domain keys
@@ -3048,8 +3043,8 @@ Defaults to an empty array, which means domains are isolated from each
other.
|=======================================================================
Apache Configuration
~~~~~~~~~~~~~~~~~~~~
=== Apache Configuration
The SOGo configuration for Apache is located in
`/etc/httpd/conf.d/SOGo.conf`.
@@ -3078,8 +3073,8 @@ The default configuration will use `mod_proxy` and `mod_headers` to
relay requests to the `sogod` parent process. This is suitable for small
to medium deployments.
Starting Services
~~~~~~~~~~~~~~~~~
=== Starting Services
Once SOGo if fully installed and configured, start the services using
the following command:
@@ -3095,8 +3090,8 @@ modules and configuration files were added:
Finally, you should also make sure that the `memcached` service is
started and that it is also automatically started at boot time.
_Cronjob_ — EMail reminders
~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== _Cronjob_ — EMail reminders
SOGo allows you to set email-based reminders for events and tasks. To
enable this, you must enable the `SOGoEnableEMailAlarms` preference and
@@ -3123,8 +3118,8 @@ SOGoSMTPMasterUserUsername = "foo";
SOGoSMTPMasterUserPassword = "bar";
```
_Cronjob_ — Vacation messages activation and expiration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== _Cronjob_ — Vacation messages activation and expiration
When vacation messages are enabled (see the parameter
_SOGoVacationEnabled_), users can set an activation or expiration date
@@ -3145,8 +3140,8 @@ The _cronjob_ should look like this:
0 0 * * * sogo /usr/sbin/sogo-tool update-autoreply -p /etc/sogo/sieve.creds
----
_Password_ — Force user password change at login
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== _Password_ — Force user password change at login
The following commands force user to change his password at login :
@@ -3160,11 +3155,11 @@ Disable :
/usr/sbin/sogo-tool user-preferences unset settings [USER] ForceResetPassword
----
Managing User Accounts
----------------------
Creating the SOGo Administrative Account
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
== Managing User Accounts
=== Creating the SOGo Administrative Account
First, create the SOGo administrative account in your LDAP server. The
following LDIF file (`sogo.ldif`) can be used as an example:
@@ -3191,8 +3186,8 @@ administrative account using the following command:
ldappasswd -h 127.0.0.1 -x -w qwerty -D cn=Manager,dc=acme,dc=com uid=sogo,ou=users,dc=acme,dc=com -s qwerty
Creating a User Account
~~~~~~~~~~~~~~~~~~~~~~~
=== Creating a User Account
SOGo uses LDAP directories to authenticate users. Use the following LDIF
file (`jdoe.ldif`) as an example to create a SOGo user account:
@@ -3225,8 +3220,8 @@ easier. These GUI utilities can make use of templates to create and
pre-configure typical user accounts or any standardized LDAP record,
along with the correct object classes, fields and default values.
Microsoft Enterprise ActiveSync
-------------------------------
=== Microsoft Enterprise ActiveSync
SOGo supports the Microsoft ActiveSync protocol.
@@ -3362,8 +3357,8 @@ and send an email to iplicreq@microsoft.com
Alinto provides this software for free, but is not responsible for
anything related to its usage.
Microsoft Enterprise ActiveSync Tuning
--------------------------------------
== Microsoft Enterprise ActiveSync Tuning
First of all, it is important to know that most EAS devices will keep
HTTP connections open to SOGo (and thus, Apache) for a long time. This
@@ -3438,8 +3433,8 @@ SOGoMaximumSyncInterval = 3540;
SOGoInternalSyncInterval = 60;
----
S/MIME Support in SOGo
----------------------
== S/MIME Support in SOGo
SOGo supports S/MIME email signing and encryption. When receiving
S/MIME signed emails, SOGo automatically extracts the PKCS (Public-Key
@@ -3457,11 +3452,10 @@ please have a look at Actalis:
https://www.actalis.it/products/certificates-for-secure-electronic-mail.aspx
Using SOGo
----------
== Using SOGo
SOGo Web Interface
~~~~~~~~~~~~~~~~~~
=== SOGo Web Interface
To acces the SOGo Web Interface, point your Web browser, which is
running from the same server where SOGo was installed, to the following
@@ -3470,8 +3464,8 @@ URL: http://127.0.0.1/SOGo.
Log in using the "jdoe" user and the "qwerty" password. The underlying
database tables will automatically be created by SOGo.
Mozilla Thunderbird and Lightning
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Mozilla Thunderbird and Lightning
Alternatively, you can access SOGo with a GroupDAV and a CalDAV client.
A typical well-integrated setup is to use Mozilla Thunderbird and
@@ -3513,8 +3507,8 @@ To access your personal calendar:
`http://127.0.0.1/SOGo/dav/jdoe/Calendar/personal/`
* Click on Continue.
Apple Calendar (macOS, iOS, iPadOS)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== Apple Calendar (macOS, iOS, iPadOS)
Apple Calendar on macOS, iOS, and iPadOS can also be used
as a client application for SOGo.
@@ -3532,8 +3526,8 @@ You have to add the profile to your device :
* Go to Settings / Profiles / Click on + / Continue
* Type your SOGo account password and click on install
Apple AddressBook
~~~~~~~~~~~~~~~~~
=== Apple AddressBook
Since Mac OS X 10.6 (Snow Leopard), Apple AddressBook can be configured
to use SOGo.
@@ -3581,8 +3575,8 @@ You have to add the profile to your device :
* Go to Settings / Profiles / Click on + / Continue
* Type your SOGo account password and click on install
Microsoft ActiveSync
~~~~~~~~~~~~~~~~~~~~
=== Microsoft ActiveSync
You can synchronize contacts, emails, events and tasks from SOGo with
any mobile devices that support Microsoft ActiveSync. Microsoft Outlook
@@ -3591,8 +3585,9 @@ any mobile devices that support Microsoft ActiveSync. Microsoft Outlook
The Microsoft ActiveSync server URL is generally something
like: `http://127.0.0.1/Microsoft-Server-ActiveSync`.
Using sogo-tool
---------------
== Using sogo-tool
The command _sogo-tool_ allows to do some operations on database and sieve filter. It is included with
the sogo package on Debian/Ubuntu but must be installed manually on RHEl/CentOS:
@@ -3601,8 +3596,8 @@ the sogo package on Debian/Ubuntu but must be installed manually on RHEl/CentOS:
*_WARNING_: Use sogo-tool with full awareness of what you are doing. This is an admin tool that can cause loss of data
or completely make the webmail unusable by a user.*
sogo-tool backup/restore
~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool backup/restore
The backup tool saves the information of a user into a file. The information saved are its preferences, its events and its contacts.
@@ -3683,8 +3678,8 @@ sogo-tool restore -F "Contacts/personal" tmp/backup user1
sogo-tool restore -F "Calendar/60C8-65323D80-7-4D9F7D80" tmp/backup user1
----
sogo-tool checkup
~~~~~~~~~~~~~~~~~
=== sogo-tool checkup
Check the events and contacts data's integrity of a user
@@ -3715,8 +3710,8 @@ sogo-tool checkup -d user1
[[sogo-tool-clean-openid-sessions]]
sogo-tool clean-openid-sessions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool clean-openid-sessions
Obviously only usefull if you have set SOGo with openId authentication.
Will clean all expired openId sessions from the database.
@@ -3728,8 +3723,8 @@ Example:
sogo-tool clean-openid-sessions
----
sogo-tool cleanup
~~~~~~~~~~~~~~~~~
=== sogo-tool cleanup
Will purge all user's deleted events and contacts which the deletion is older than a number of days.
@@ -3753,8 +3748,7 @@ Purged 5 records from folder /Users/user2/Calendar/personal
----
sogo-tool create-folder
~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool create-folder
Create a folder (Calendar or Address Book) for a user.
@@ -3771,8 +3765,7 @@ sogo-tool create-folder user2 Calendar Pro_Calendar
----
sogo-tool dump-defaults
~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool dump-defaults
Output all current defaults value of GNUstep and SOGo (sogo.conf)
@@ -3789,8 +3782,8 @@ sogo-tool dump-defaults all
sogo-tool dump-defaults -f /tmp/foo/conf.xml
----
sogo-tool expire-sessions
~~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool expire-sessions
Expires user sessions from database without activity for specified number of minutes. When a user log in to sogo for
the first time, sogo will create a entry in database's table OCSSessionsFolderURL with the user's information. Sogo will
@@ -3809,8 +3802,8 @@ sogo-tool expire-sessions 160 #Will remove session which last activity is ol
sogo-tool expire-sessions 0 #Will remove session which last activity is older than 0 minutes.
----
sogo-tool manage-acl
~~~~~~~~~~~~~~~~~~~~
=== sogo-tool manage-acl
Manage access-control list (ACL) of a user for folders (Calendar and Address Book).
@@ -3881,8 +3874,8 @@ Example:
sogo-tool manage-acl unsubscribe sogo-tests1 Contacts/5E1D-653FC400-1-1A330C40 sogo-tests2
----
sogo-tool manage-eas
~~~~~~~~~~~~~~~~~~~~
=== sogo-tool manage-eas
Manage EAS folders
@@ -3912,8 +3905,8 @@ sogo-tool manage-eas mergevcard janedow androidc316986417 YES
sogo-tool manage-eas mergevevent janedow androidc316986417 YES
----
sogo-tool remove
~~~~~~~~~~~~~~~~
=== sogo-tool remove
Remove all folders (Calendar and Address Book) and Preference settings of a user. The personal Calendar and Address Book
will stay but be emptied of all entries. The Preferences will go back to defaults values as for a new user.
@@ -3937,8 +3930,8 @@ Deleting /Users/user2/Contacts/B087-65363400-7-374DA380
Deleting /Users/user2/Contacts/personal
----
sogo-tool remove-doubles
~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool remove-doubles
remove duplicate contacts from the specified user addressbook
@@ -3963,8 +3956,8 @@ sogo-tool remove-doubles user1 personal
sogo-tool remove-doubles user2 489-65376E80-1-2D2BA000
----
sogo-tool rename-user
~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool rename-user
Update records pertaining to a user after a change of user id. Will change all folders path, subscriptions from others users,
all mention of user id in database.
@@ -3982,8 +3975,8 @@ Example:
sogo-tool rename-user old_username new_username
----
sogo-tool truncate-calendar
~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool truncate-calendar
Remove old calendar entries from the specified user calendar.
@@ -4013,8 +4006,7 @@ Removing 1 records...
Removed 1 records.
----
sogo-tool update-autoreply
~~~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool update-autoreply
_This command is only useful if your sieve server doesn't have the capabilities *date* or *relational*_
In that case this command will check vacation's setting of all the users. If vacation is enabled/disabled,
@@ -4034,8 +4026,7 @@ Example:
[[sogo-tool-update-secret]]
sogo-tool update-secret
~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool update-secret
_New in 5.10_
@@ -4061,8 +4052,7 @@ If your data are already encrypted with 'oldSecret' but you want to decrypt them
sogo-tool update-secret -o oldSecret
----
sogo-tool user-preferences
~~~~~~~~~~~~~~~~~~~~~~~~~~
=== sogo-tool user-preferences
Get, set or unset user defaults / settings in the database.
@@ -4121,9 +4111,153 @@ sogo-tool user-preferences set defaults user1 Forward -f /path/filename -p cred
----
== API REST
Upgrading
---------
Starting from 5.12.2, an API with two endpoints is available.
All response will be on json format. In case of errors, the message will be:
```json
{"error" : "message"}
```
with an explicit message
=== API server url
_<scheme>_://_<domain>_/SOGo/SOGoAPI/_<action>_
• *scheme* : https or http
• *domain* : domain or ip:port of SOGo's server
• *action* : name of the action. No action does the Version action described below.
=== Authentication
Somes actions needs to be authenticated. There is two ways to do so:
* *Basic auth*
Add a header *Auhtorization* with value:
'Basic <credentials>'
*credentials* is the sitrng '<uid>:<password>' base64 encoded.
* *OpenID*
**Only works if you configure sogo to use openid. See <<openid-section, the related section>>**
Add a header *Auhtorization* with value:
'Bearer <access_token>'
*acces_token* is from the https://connect2id.com/products/server/docs/api/token#url[openid protocol]. It has to be fetch with the scope `openid`.
=== Action - Version
* *URL*: <scheme>://<domain>/SOGo/SOGoAPI/Version
* *Authentication needed*: NO
* *HTTP method allowed*: GET
* *Description*: Return the current version of sogo
* *Answer structure*:
```json
{
"major":5,
"patch":1,
"minor":12
}
```
=== Action - UserFolder
* *URL*: <scheme>://<domain>/SOGo/SOGoAPI/UserFolder
* *Authentication needed*: YES
* *HTTP method allowed*: GET
* *Description*: Return the caldav and cardav links of the authenticated user, plus their names.
* *Answer structure*:
```json
{
"calendar":[
{
"name":"DidyShared",
"url":"http://127.0.0.1/SOGo/dav/sogo-tests1@example.org/Calendar/12509-67F67D00-1-3105AF40"
},
{
"name":"LocalDidy",
"url":"http://127.0.0.1/SOGo/dav/sogo-tests1@example.org/Calendar/1BC38-67B60000-1-6E4B6880"
},
{
"name":"Personal Calendar",
"url":"http://127.0.0.1/SOGo/dav/sogo-tests1@example.org/Calendar/personal"
}
],
"username":"sogo-tests1@example.org",
"contact":[
{
"name":"Personal Address Book",
"url":"http://127.0.0.1/SOGo/dav/sogo-tests1@example.org/Contacts/personal"
}
]
}
```
* *Note*:
The Answer has 3 primary keys:
** *username*: uid of the user.
** *calendar*: array of calendar's folder info.
** *contact*: array of calendar's folder info.
A folder info is a dict with:
** *name*: Name of the folder.
** *url*: Dav link of the folder.
=== Errors and messages
Complete http response is `{“error:” : <message>}`.
*<action>* is the one used for the request: `<scheme>://<domain>/SOGo/SOGoAPI/<action>`
[%header,cols="1,3,3"]
|===
|Status |Message |Description
|400
|No backend API found for action: <action>
|The requested action doesn't exist
|500
|Can't alloc and init class: <classAction>
|The requested action exist but failed to be instantiated. <classAction> is the class's name
|400
|Method <method> not allowed for action <action>
|Http method not allowed. <methos> is the one used (GET, PUT, POST...)
|400
|Missing param <param> for action <action>
|Required param for action not found. <param> is the name of the missing parameter.
|401
|No authorization header found for <action>
|No Authorization header found
|401
|Authorization method incorrect: <auth> for action <action>
|Value of Authorization's header doesn't start with Basic or Bearer. <auth> is the full value.
|401
|User wrong login or not found for action <action>
|Fail to authenticate the user. Various causes possible: wrong login, wrong password, expired token...
|500
|Internal error during: <action>
|Internal error during the action
|===
To have more logs you can add `SOGoAPIDebugEnabled = YES;` to your sogo.conf.
== Upgrading
This section describes what needs to be done when upgrading to the
current version of SOGo from the previous release.
@@ -12,8 +12,8 @@
////
Additional Information
----------------------
== Additional Information
For more information, please consult the online FAQs (Frequently Asked
Questions) :
@@ -12,8 +12,7 @@
////
Commercial Support and Contact Information
------------------------------------------
== Commercial Support and Contact Information
For any questions or comments, do not hesitate to contact us by writing
an email to contact@sogo.nu.
+1 -1
View File
@@ -380,7 +380,7 @@ static BOOL debugLeaks;
request = [_ctx request];
login = [SOGoUser getDecryptedUsernameIfNeeded: _key request: request];
if([login isEqualToString: @"changeLanguage"])
if([login isEqualToString: @"changeLanguage"] || [login isEqualToString: @"login"])
user = nil;
else
{
+12 -12
View File
@@ -214,10 +214,10 @@
{
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_user_session VARCHAR(4096) NOT NULL,"
@" c_old_session VARCHAR(4096) NULL,"
@" c_user_session TEXT NOT NULL,"
@" c_old_session TEXT NULL,"
@" c_session_started INT4 NOT NULL,"
@" c_refresh_token VARCHAR(4096) NULL,"
@" c_refresh_token TEXT NULL,"
@" c_access_token_expires_in INT4 NULL,"
@" c_refresh_token_expires_in INT4 NULL)");
@@ -274,7 +274,7 @@
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_id VARCHAR(255) PRIMARY KEY,"
@" c_value VARCHAR(4096) NOT NULL,"
@" c_value TEXT NOT NULL,"
@" c_creationdate INT4 NOT NULL,"
@" c_lastseen INT4 NOT NULL)");
@@ -375,10 +375,10 @@
{
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_user_session VARCHAR(4096) NOT NULL,"
@" c_old_session VARCHAR(4096) NULL,"
@" c_user_session TEXT NOT NULL,"
@" c_old_session TEXT NULL,"
@" c_session_started INT4 NOT NULL,"
@" c_refresh_token VARCHAR(4096) NULL,"
@" c_refresh_token TEXT NULL,"
@" c_access_token_expires_in INT4 NULL,"
@" c_refresh_token_expires_in INT4 NULL)");
@@ -435,7 +435,7 @@
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_id VARCHAR(255) PRIMARY KEY,"
@" c_value VARCHAR(4096) NOT NULL,"
@" c_value TEXT NOT NULL,"
@" c_creationdate INT NOT NULL,"
@" c_lastseen INT NOT NULL)");
@@ -536,10 +536,10 @@
{
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_user_session VARCHAR2(4096) NOT NULL,"
@" c_old_session VARCHAR2(4096) NULL,"
@" c_user_session VARCHAR2(8192) NOT NULL,"
@" c_old_session VARCHAR2(8192) NULL,"
@" c_session_started INTEGER NOT NULL,"
@" c_refresh_token VARCHAR2(4096) NULL,"
@" c_refresh_token VARCHAR2(8192) NULL,"
@" c_access_token_expires_in INTEGER NULL,"
@" c_refresh_token_expires_in INTEGER NULL)");
@@ -595,7 +595,7 @@
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_id VARCHAR2(255) PRIMARY KEY,"
@" c_value VARCHAR2(4096) NOT NULL,"
@" c_value VARCHAR2(8192) NOT NULL,"
@" c_creationdate INTEGER NOT NULL,"
@" c_lastseen INTEGER NOT NULL)");
@@ -93,11 +93,13 @@
if (until)
{
lastStartDate = until;
lastEndDate = until;
}
else
{
repeatCount = [rrule repeatCount];
if (dayMask == nil)
{
// If there's no day mask, we can compute the date of the last
// occurrence of the recurrent rule.
lastStartDate = [firStart dateByAddingYears: 0 months: 0
@@ -106,6 +108,7 @@
lastEndDate = [firEnd dateByAddingYears: 0 months: 0
days: (interval
* (repeatCount - 1))];
}
}
if (lastStartDate != nil && lastEndDate != nil)
+7 -2
View File
@@ -86,8 +86,13 @@
tzId = [self value: 0 ofAttribute: @"tzid"];
if ([tzId length])
{
calendar = (iCalCalendar *) [self searchParentOfClass: [iCalCalendar class]];
timeZone = [calendar timeZoneWithId: tzId];
//Hack, get timezone inf from sogo and not from the event VTIMEZONE as it can be incorrect/incomplete
timeZone = [iCalTimeZone timeZoneForName: tzId];
if(!timeZone)
{
calendar = (iCalCalendar *) [self searchParentOfClass: [iCalCalendar class]];
timeZone = [calendar timeZoneWithId: tzId];
}
//if (!timeZone)
//[self logWithFormat: @"timezone '%@' not found in calendar", tzId];
}
@@ -230,10 +230,11 @@ static inline unsigned iCalDoWForNSDoW (int dow)
else
{
untilStart = [rrule untilDate];
untilEnd = [rrule untilDate];
}
}
if (untilStart != nil)
if (untilStart != nil && untilEnd != nil)
{
if ([untilEnd compare: rStart] == NSOrderedAscending)
// Range starts after last occurrence
@@ -102,11 +102,15 @@
lastEndDate = nil;
until = [rrule untilDate];
if (until)
{
lastStartDate = until;
lastEndDate = until;
}
else
{
repeatCount = [rrule repeatCount];
if (dayMask == nil)
{
// When there's no BYxxx mask, we can find the date of the last
// occurrence.
lastStartDate = [firStart dateByAddingYears: 0 months: 0
@@ -115,6 +119,7 @@
lastEndDate = [firEnd dateByAddingYears: 0 months: 0
days: (interval
* (repeatCount - 1) * 7)];
}
}
if (lastStartDate != nil && lastEndDate != nil)
@@ -80,10 +80,12 @@
if (until)
{
lastStartDate = until;
lastEndDate = until;
}
if (repeatCount > 0)
{
if (lastStartDate == nil && ![rrule hasByMask])
{
// When there's no BYxxx mask, we can find the date of the last
// occurrence.
lastStartDate = [firStart dateByAddingYears: (interval * (repeatCount - 1))
@@ -92,6 +94,7 @@
lastEndDate = [firEnd dateByAddingYears: (interval * (repeatCount - 1))
months: 0
days: 0];
}
referenceDate = firStart;
}
+4 -4
View File
@@ -142,7 +142,7 @@ CREATE TABLE sogo_quick_contact (
CREATE TABLE sogo_sessions_folder (
c_id varchar(255) NOT NULL,
c_value varchar(4096) NOT NULL,
c_value text NOT NULL,
c_creationdate int(11) NOT NULL,
c_lastseen int(11) NOT NULL,
PRIMARY KEY (c_id)
@@ -166,10 +166,10 @@ CREATE TABLE sogo_admin (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE sogo_opend_id (
c_user_session varchar(4096) NOT NULL,
c_old_session varchar(4096) DEFAULT '',
c_user_session text NOT NULL,
c_old_session text DEFAULT '',
c_session_started int(11) NOT NULL,
c_refresh_token varchar(4096) DEFAULT '',
c_refresh_token text DEFAULT '',
c_access_token_expires_in int(11) DEFAULT '',
c_refresh_token_expires_in int(11) DEFAULT NULL,
PRIMARY KEY (c_user_session)
@@ -0,0 +1,82 @@
"Inviting the following persons is prohibited:" = "Inviting the following persons is prohibited:";
"Personal Calendar" = "Personal Calendar";
vevent_class0 = "(Public event)";
vevent_class1 = "(Private event)";
vevent_class2 = "(Confidential event)";
vtodo_class0 = "(Public task)";
vtodo_class1 = "(Private task)";
vtodo_class2 = "(Confidential task)";
/* Receipts */
"The event \"%{Summary}\" was created" = "The event \"%{Summary}\" was created";
"The event \"%{Summary}\" was deleted" = "The event \"%{Summary}\" was deleted";
"The event \"%{Summary}\" was updated" = "The event \"%{Summary}\" was updated";
"The task \"%{Summary}\" was created" = "The task \"%{Summary}\" was created";
"The task \"%{Summary}\" was deleted" = "The task \"%{Summary}\" was deleted";
"The task \"%{Summary}\" was updated" = "The task \"%{Summary}\" was updated";
"The following attendees(s) were notified" = "The following attendee(s) were notified";
"The following attendees(s) were added" = "The following attendee(s) were added";
"The following attendees(s) were removed" = "The following attendee(s) were removed";
/* IMIP messages */
"calendar_label" = "Calendar";
"startDate_label" = "Start";
"endDate_label" = "End";
"time_label" = "Time";
"to_label" = "to";
"due_label" = "Due Date";
"location_label" = "Location";
"summary_label" = "Summary";
"comment_label" = "Comment";
"organizer_label" = "Organizer";
"attendee_label" = "Attendee";
/* Invitation */
"Event Invitation: \"%{Summary}\"" = "Event Invitation: \"%{Summary}\"";
"(sent by %{SentBy}) " = "(sent by %{SentBy}) ";
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}";
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}";
/* Deletion */
"Event Cancelled: \"%{Summary}\"" = "Event Cancelled: \"%{Summary}\"";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
= "%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
= "%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}";
/* Update */
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
= "The appointment \"%{Summary}\" for the %{OldStartDate} has changed";
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
= "The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed";
"The following parameters have changed in the \"%{Summary}\" meeting:"
= "The following parameters have changed in the \"%{Summary}\" meeting:";
"Please accept or decline those changes."
= "Please accept or decline those changes.";
/* Reply */
"Accepted invitation: \"%{Summary}\"" = "Accepted invitation: \"%{Summary}\"";
"Declined invitation: \"%{Summary}\"" = "Declined invitation: \"%{Summary}\"";
"Delegated invitation: \"%{Summary}\"" = "Delegated invitation: \"%{Summary}\"";
"Not yet decided on invitation: \"%{Summary}\"" = "Not yet decided on invitation: \"%{Summary}\"";
"%{Attendee} %{SentByText}has accepted your event invitation."
= "%{Attendee} %{SentByText}has accepted your event invitation.";
"%{Attendee} %{SentByText}has declined your event invitation."
= "%{Attendee} %{SentByText}has declined your event invitation.";
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
= "%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}.";
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
= "%{Attendee} %{SentByText}has not yet decided upon your event invitation.";
/* Reminder */
"Reminder: \"%{Summary}\" - %{StartDate}" = "Reminder: \"%{Summary}\" - %{StartDate}";
/* Resources */
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Cannot access resource: \"%{Cn} %{SystemEmail}\"";
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}.";
/* Participation role */
"Your participation is required to this event" = "Your participation is required to this event";
"Your participation is optional to this event" = "Your participation is optional to this event";
"Your participation is not required to this event" = "Your participation is not required to this event";
@@ -0,0 +1,82 @@
"Inviting the following persons is prohibited:" = "다음 사람들을 초대하는 것은 금지되어 있습니다:";
"Personal Calendar" = "개인 캘린더";
vevent_class0 = "(공개 이벤트)";
vevent_class1 = "(비공개 이벤트)";
vevent_class2 = "(기밀 이벤트)";
vtodo_class0 = "(공개 할 일)";
vtodo_class1 = "(비공개 할 일)";
vtodo_class2 = "(기밀 할 일)";
/* Receipts */
"The event \"%{Summary}\" was created" = "이벤트 \"%{Summary}\"가 생성되었습니다";
"The event \"%{Summary}\" was deleted" = "이벤트 \"%{Summary}\"가 삭제되었습니다";
"The event \"%{Summary}\" was updated" = "이벤트 \"%{Summary}\"가 업데이트되었습니다";
"The task \"%{Summary}\" was created" = "할 일 \"%{Summary}\"이 생성되었습니다";
"The task \"%{Summary}\" was deleted" = "할 일 \"%{Summary}\"이 삭제되었습니다";
"The task \"%{Summary}\" was updated" = "할 일 \"%{Summary}\"이 업데이트되었습니다";
"The following attendees(s) were notified" = "다음 참석자에게 알림이 전송되었습니다";
"The following attendees(s) were added" = "다음 참석자가 추가되었습니다";
"The following attendees(s) were removed" = "다음 참석자가 제거되었습니다";
/* IMIP messages */
"calendar_label" = "캘린더";
"startDate_label" = "시작";
"endDate_label" = "종료";
"time_label" = "시간";
"to_label" = "까지";
"due_label" = "마감일";
"location_label" = "장소";
"summary_label" = "요약";
"comment_label" = "설명";
"organizer_label" = "주최자";
"attendee_label" = "참석자";
/* Invitation */
"Event Invitation: \"%{Summary}\"" = "이벤트 초대: \"%{Summary}\"";
"(sent by %{SentBy}) " = "(%{SentBy}님이 보냄) ";
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}님이 %{Summary}에 초대했습니다.\n\n시작: %{StartDate}\n종료: %{EndDate}\n설명: %{Description}";
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}님이 %{Summary}에 초대했습니다.\n\n시작: %{StartDate} %{StartTime}\n종료: %{EndDate} %{EndTime}\n설명: %{Description}";
/* Deletion */
"Event Cancelled: \"%{Summary}\"" = "이벤트 취소됨: \"%{Summary}\"";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
= "%{Organizer} %{SentByText}님이 이 이벤트를 취소했습니다: %{Summary}.\n\n시작: %{StartDate}\n종료: %{EndDate}\n설명: %{Description}";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
= "%{Organizer} %{SentByText}님이 이 이벤트를 취소했습니다: %{Summary}.\n\n시작: %{StartDate} %{StartTime}\n종료: %{EndDate} %{EndTime}\n설명: %{Description}";
/* Update */
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
= "%{OldStartDate}에 예정된 약속 \"%{Summary}\"이 변경되었습니다";
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
= "%{OldStartDate} %{OldStartTime}에 예정된 약속 \"%{Summary}\"이 변경되었습니다";
"The following parameters have changed in the \"%{Summary}\" meeting:"
= "모임 \"%{Summary}\"에서 다음 매개변수가 변경되었습니다:";
"Please accept or decline those changes."
= "이 변경 사항을 수락하거나 거절하십시오.";
/* Reply */
"Accepted invitation: \"%{Summary}\"" = "초대 수락: \"%{Summary}\"";
"Declined invitation: \"%{Summary}\"" = "초대 거절: \"%{Summary}\"";
"Delegated invitation: \"%{Summary}\"" = "초대 위임: \"%{Summary}\"";
"Not yet decided on invitation: \"%{Summary}\"" = "초대에 대해 아직 결정하지 않음: \"%{Summary}\"";
"%{Attendee} %{SentByText}has accepted your event invitation."
= "%{Attendee} %{SentByText}님이 귀하의 이벤트 초대를 수락했습니다.";
"%{Attendee} %{SentByText}has declined your event invitation."
= "%{Attendee} %{SentByText}님이 귀하의 이벤트 초대를 거절했습니다.";
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
= "%{Attendee} %{SentByText}님이 %{Delegate}에게 초대를 위임했습니다.";
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
= "%{Attendee} %{SentByText}님이 귀하의 이벤트 초대에 대해 아직 결정하지 않았습니다.";
/* Reminder */
"Reminder: \"%{Summary}\" - %{StartDate}" = "알림: \"%{Summary}\" - %{StartDate}";
/* Resources */
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "리소스에 접근할 수 없습니다: \"%{Cn} %{SystemEmail}\"";
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "리소스 \"%{Cn} %{SystemEmail}\"에 대한 최대 동시 예약 수(%{NumberOfSimultaneousBookings})에 도달했습니다. 충돌하는 이벤트는 \"%{EventTitle}\"이며, %{StartDate}에 시작합니다.";
/* Participation role */
"Your participation is required to this event" = "이 이벤트에 귀하의 참여가 필수입니다";
"Your participation is optional to this event" = "이 이벤트에 귀하의 참여는 선택 사항입니다";
"Your participation is not required to this event" = "이 이벤트에 귀하의 참여는 필요하지 않습니다";
@@ -1133,8 +1133,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
recordIndex = [self _indexOfRecordMatchingDate: recurrenceId inArray: ma];
if ([dateRange doesIntersectWithDateRange: recurrenceIdRange] && recordIndex == -1) {
[self warnWithFormat:
@"missing exception record for recurrence-id %@ (uid %@), ma = %@, dr = %@, rir = %@",
recurrenceId, [component uid], ma, dateRange, recurrenceIdRange];
@"missing exception record for recurrence-id %@ (uid %@), dr = %@, rir = %@",
recurrenceId, [component uid], dateRange, recurrenceIdRange];
}
if ([dateRange doesIntersectWithDateRange: recurrenceIdRange] && recordIndex != -1)
{
+15 -10
View File
@@ -65,6 +65,9 @@
#import "iCalRepeatableEntityObject+SOGo.h"
#import "SOGoCalendarComponent.h"
static NSArray *allowed_tags = nil;
@implementation SOGoCalendarComponent
+ (SOGoWebDAVAclManager *) webdavAclManager
@@ -210,7 +213,6 @@
SOGoUser *calendarOwner;
NSEnumerator *children;
CardElement *element;
NSArray *tags;
int classification;
@@ -231,22 +233,25 @@
summary = [self labelForKey: [NSString stringWithFormat: @"%@_class%d",
type, classification]
inContext: context];
tags = [NSArray arrayWithObjects: @"DTSTAMP", @"DTSTART", @"DTEND", @"DUE", @"EXDATE", @"EXRULE", @"RRULE", @"RECURRENCE-ID", nil];
if(!allowed_tags)
allowed_tags = [[NSArray arrayWithObjects: @"DTSTAMP", @"DTSTART", @"DTEND", @"DUE", @"EXDATE", @"EXRULE", @"RRULE", @"RECURRENCE-ID", nil] retain];
uid = [[component uid] asCryptedPassUsingScheme: @"ssha256"
withSalt: [[settings userPublicSalt] dataUsingEncoding: NSASCIIStringEncoding]
andEncoding: encHex
keyPath: nil];
children = [[[[component children] copy] autorelease] objectEnumerator];
children = [[component children] objectEnumerator];
NSMutableArray *to_remove = [NSMutableArray arrayWithCapacity: 8];
while ((element = [children nextObject]))
{
tag = [element tag];
if (![tags containsObject: [tag uppercaseString]])
[component removeChild: element];
if (![allowed_tags containsObject: [tag uppercaseString]])
[to_remove addObject: element];
}
[component removeChildren: to_remove];
[component setSummary: summary];
[component setUid: uid];
}
@@ -885,7 +890,7 @@
mailDate = [[NSCalendarDate date] rfc822DateString];
[headerMap setObject: mailDate forKey: @"date"];
[headerMap setObject: subject forKey: @"subject"];
[headerMap setObject: [NSString generateMessageID] forKey: @"message-id"];
[headerMap setObject: [NSString generateMessageID: senderEmail] forKey: @"message-id"];
if ([msgType length] > 0)
[headerMap setObject: msgType forKey: @"x-sogo-message-type"];
msg = [NGMimeMessage messageWithHeader: headerMap];
@@ -974,7 +979,7 @@
[headerMap setObject: mailDate forKey: @"date"];
[headerMap setObject: [[p getSubject] asQPSubjectString: @"UTF-8"]
forKey: @"subject"];
[headerMap setObject: [NSString generateMessageID] forKey: @"message-id"];
[headerMap setObject: [NSString generateMessageID: [[attendee mailAddress] pureEMailAddress]] forKey: @"message-id"];
[headerMap setObject: @"1.0" forKey: @"MIME-Version"];
if (textOnly)
@@ -1163,7 +1168,7 @@
mailDate = [[NSCalendarDate date] rfc822DateString];
[headerMap setObject: mailDate forKey: @"date"];
[headerMap setObject: [page getSubject] forKey: @"subject"];
[headerMap setObject: [NSString generateMessageID] forKey: @"message-id"];
[headerMap setObject: [NSString generateMessageID: senderEmail] forKey: @"message-id"];
[headerMap setObject: @"1.0" forKey: @"MIME-Version"];
[headerMap setObject: @"text/html; charset=utf-8"
forKey: @"content-type"];
@@ -0,0 +1,82 @@
"Inviting the following persons is prohibited:" = " ไม่เชิญบุคคลต่อไปนี้:";
"Personal Calendar" = "ปฏิทินส่วนตัว";
vevent_class0 = "(กิจกรรมสาธารณะ)";
vevent_class1 = "(กิจกรรมส่วนตัว)";
vevent_class2 = "(กิจกรรมลับ)";
vtodo_class0 = "(งานสาธารณะ)";
vtodo_class1 = "(งานส่วนตัว)";
vtodo_class2 = "(งานลับ)";
/* Receipts */
"The event \"%{Summary}\" was created" = "กิจกรรม \"%{Summary}\" ถุกสร้างขึ้น";
"The event \"%{Summary}\" was deleted" = "กิจกรรม \"%{Summary}\" ถูกลบ";
"The event \"%{Summary}\" was updated" = "กิจกรรม \"%{Summary}\" ถูกอัพเดต";
"The task \"%{Summary}\" was created" = "งาน \"%{Summary}\" ถูกสร้างขี้น";
"The task \"%{Summary}\" was deleted" = "งาน \"%{Summary}\" ถูกลบ";
"The task \"%{Summary}\" was updated" = "งาน \"%{Summary}\" ถูกอัพเดต";
"The following attendees(s) were notified" = "ผู้เข้าร่วมต่อไปนี้ได้รับการแจ้งแล้ว";
"The following attendees(s) were added" = "ผู้เข้าร่วมต่อไปนี้ถูกเพิ่มเข้ามา";
"The following attendees(s) were removed" = "ผู้เข้าร่วมต่อไปนี้ถูกลบออก";
/* IMIP messages */
"calendar_label" = "ปฏิทิน";
"startDate_label" = "เริ่ม";
"endDate_label" = "สิ้นสุด";
"time_label" = "เวลา";
"to_label" = "ถึง";
"due_label" = "วันครบกำหนด";
"location_label" = "สถานที่";
"summary_label" = "สรุป";
"comment_label" = "ความคิดเห็น";
"organizer_label" = "ผู้จัดงาน";
"attendee_label" = "ผู้เข้าร่วม";
/* Invitation */
"Event Invitation: \"%{Summary}\"" = "คำเชิญร่วมกิจกรรม : \"%{Summary}\"";
"(sent by %{SentBy}) " = "(ส่งโดย %{SentBy}) ";
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}ได้ทําการเชิญคุณไป %{Summary}.\n\nเริ่ม: %{StartDate}\nสิ้นสุด: %{EndDate}\nคำอธิบาย: %{Description}";
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}ได้ทําการเชิญคุณไป %{Summary}.\n\nเริ่ม: %{StartDate} เวลา %{StartTime}\nสิ้นสุด: %{EndDate} เวลา %{EndTime}\nคำอธิบาย: %{Description}";
/* Deletion */
"Event Cancelled: \"%{Summary}\"" = "กิจกรรมถูกยกเลิกแล้ว: \"%{Summary}\"";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
= "%{Organizer} %{SentByText}:ได้ยกเลิกกิจกรรม %{Summary}.\n\nเริ่ม: %{StartDate}\nสิ้นสุด: %{EndDate}\nคำอธิบาย: %{Description}";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
= "%{Organizer} %{SentByText}hasได้ยกเลิกกิจกรรม: %{Summary}.\n\nเริ่ม: %{StartDate} เวลา %{StartTime}\nสิ้นสุด: %{EndDate} เวลา %{EndTime}\nคำอธิบาย: %{Description}";
/* Update */
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
= "นัดหมาย \"%{Summary}\" สำหรับวันที่ %{OldStartDate} มีการเปลี่ยนแปลง";
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
= "นัดหมาย \"%{Summary}\" สำหรับวันที่ %{OldStartDate} เวลา %{OldStartTime} มีการเปลี่ยนแปลง";
"The following parameters have changed in the \"%{Summary}\" meeting:"
= "มีการเปลี่ยนแปลงใน \"%{Summary}\" :";
"Please accept or decline those changes."
= "กรุณาตอบรับหรือปฏิเสธการเปลี่ยนแปลงเหล่านั้น";
/* Reply */
"Accepted invitation: \"%{Summary}\"" = "ตอบรับคำเชิญ: \"%{Summary}\"";
"Declined invitation: \"%{Summary}\"" = "ปฏิเสธคำเชิญ: \"%{Summary}\"";
"Delegated invitation: \"%{Summary}\"" = "ลบคำเชิญ: \"%{Summary}\"";
"Not yet decided on invitation: \"%{Summary}\"" = "ยังไม่ตัดสินใจเกี่ยวกับคำเชิญ: \"%{Summary}\"";
"%{Attendee} %{SentByText}has accepted your event invitation."
= "%{Attendee} %{SentByText} ได้ตอบรับคำเชิญกิจกรรมของคุณแล้ว";
"%{Attendee} %{SentByText}has declined your event invitation."
= "%{Attendee} %{SentByText} ได้ตอบปฏิเสธคำเชิญกิจกรรมของคุณแล้ว";
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
= "%{Attendee} %{SentByText}ได้มอบหมายการเชิญให้ %{Delegate}.";
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
= "%{Attendee} %{SentByText}ยังไม่ได้ตัดสินใจเกี่ยวกับคำเชิญงานของคุณ";
/* Reminder */
"Reminder: \"%{Summary}\" - %{StartDate}" = "สิ่งเตือนความจำ: \"%{Summary}\" - %{StartDate}";
/* Resources */
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "ไม่สามารถเข้าถึงทรัพยากรได้: \"%{Cn} %{SystemEmail}\"";
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "จำนวนการจองสูงสุดพร้อมกัน (%{NumberOfSimultaneousBookings}) ขอใช้ทรัพยากร \"%{Cn} %{SystemEmail}\". งานที่ขัดแย้งกัน \"%{EventTitle}\", and starts on %{StartDate}.";
/* Participation role */
"Your participation is required to this event" = "การเข้าร่วมของคุณจำเป็นสำหรับกิจกรรมนี้";
"Your participation is optional to this event" = " การเข้าร่วมกิจกรรมนี้ไม่จำเป็น";
"Your participation is not required to this event" = " การเข้าร่วมของคุณไม่จำเป็นสำหรับกิจกรรมนี้";
+10
View File
@@ -107,6 +107,7 @@
BOOL isAllDayStartDate, isAllDayDueDate;
NSCalendarDate *startDate, *dueDate, *completedDate;
NSInteger percent;
NSString *owner;
SOGoUserDefaults *ud;
iCalDateTime *todoStartDate, *todoDueDate;
iCalTimeZone *tz;
@@ -230,6 +231,15 @@
}
else
[self setPercentComplete: @""];
//To make an ics conforme with outlook live (bouh), valarm must be the last element of vevent
//Try to set it here
o = [data objectForKey: @"alarm"];
if ([o isKindOfClass: [NSDictionary class]])
{
owner = [data objectForKey: @"owner"];
[self _setAlarm: o forOwner: owner];
}
}
- (NSMutableDictionary *) quickRecordFromContent: (NSString *) theContent
@@ -0,0 +1,2 @@
"Personal Address Book" = "Personal Address Book";
"Collected Address Book" = "Collected Address Book";
@@ -0,0 +1,2 @@
"Personal Address Book" = "개인 주소록";
"Collected Address Book" = "받은/보낸 주소록";
@@ -0,0 +1,2 @@
"Personal Address Book" = "สมุดที่อยู่ส่วนตัว";
"Collected Address Book" = "สมุดที่อยู่ที่เก็บรวบรวม";
+4
View File
@@ -94,6 +94,8 @@ Mailer_RESOURCE_FILES += \
SOGoMailJapaneseReply.wo \
SOGoMailKazakhForward.wo \
SOGoMailKazakhReply.wo \
SOGoMailKoreanForward.wo \
SOGoMailKoreanReply.wo \
SOGoMailLatvianForward.wo \
SOGoMailLatvianReply.wo \
SOGoMailLithuanianForward.wo \
@@ -128,6 +130,8 @@ Mailer_RESOURCE_FILES += \
SOGoMailSpanishArgentinaReply.wo \
SOGoMailSwedishForward.wo \
SOGoMailSwedishReply.wo \
SOGoMailThaiForward.wo \
SOGoMailThaiReply.wo \
SOGoMailTurkishTurkeyForward.wo \
SOGoMailTurkishTurkeyReply.wo \
SOGoMailUkrainianForward.wo \
@@ -0,0 +1,5 @@
"OtherUsersFolderName" = "Other Users";
"SharedFoldersName" = "Shared Folders";
"Report: Marked messages as junk" = "Report: Marked messages as junk";
"Report: Marked messages as not junk" = "Report: Marked messages as not junk";
@@ -0,0 +1,5 @@
"OtherUsersFolderName" = "다른 사용자";
"SharedFoldersName" = "공유 폴더";
"Report: Marked messages as junk" = "보고서: 스팸으로 표시된 메시지";
"Report: Marked messages as not junk" = "보고서: 스팸이 아닌 것으로 표시된 메시지";
+1 -1
View File
@@ -25,7 +25,7 @@
@interface NSString (SOGoExtension)
+ (NSString *) generateMessageID;
+ (NSString *) generateMessageID: (NSString *) mailOrDomain;
- (NSString *) htmlToText;
- (NSString *) htmlByExtractingImages: (NSMutableArray *) theImages;
- (NSString *) stringByConvertingCRLNToHTML;
+17 -5
View File
@@ -560,15 +560,27 @@
@implementation NSString (SOGoExtension)
+ (NSString *) generateMessageID
+ (NSString *) generateMessageID: (NSString *) mailOrDomain
{
NSMutableString *messageID;
NSString *pGUID;
NSString *_domain;
NSRange r;
messageID = [NSMutableString string];
[messageID appendFormat: @"<%@", [SOGoObject globallyUniqueObjectId]];
pGUID = [[NSProcessInfo processInfo] globallyUniqueString];
[messageID appendFormat: @"@%u>", (unsigned int)[pGUID hash]];
[messageID appendFormat: @"<%@", [SOGoObject mailUniqueMessageId]];
if(mailOrDomain)
{
r = [mailOrDomain rangeOfString: @"@" options: NSBackwardsSearch];
if (r.location != NSNotFound)
{
//Its the full email not a domain
_domain = [mailOrDomain substringFromIndex: (r.location + r.length)];
}
else
_domain = mailOrDomain;
[messageID appendFormat: @"@%@>", _domain];
}
return [messageID lowercaseString];
}
+1 -1
View File
@@ -222,7 +222,7 @@ static NSString *userAgent = nil;
messageID = [headers objectForKey: @"message-id"];
if (!messageID)
{
messageID = [NSString generateMessageID];
messageID = [NSString generateMessageID: [[newHeaders objectForKey: @"from"] pureEMailAddress]];
[headers setObject: messageID forKey: @"message-id"];
}
+4
View File
@@ -142,6 +142,10 @@
else
imapAuthMech = nil;
//If ActiveSync, force the plain mech
if([[[[self context] request] requestHandlerKey] isEqualToString:@"Microsoft-Server-ActiveSync"])
imapAuthMech = @"plain";
return [NGImap4ConnectionManager defaultConnectionManager: imapAuthMech];
}
+9
View File
@@ -91,6 +91,9 @@
@interface SOGoMailGermanForward : SOGoMailForward
@end
@interface SOGoMailGreekForward : SOGoMailForward
@end
@interface SOGoMailHebrewForward : SOGoMailForward
@end
@@ -112,6 +115,9 @@
@interface SOGoMailKazakhForward : SOGoMailForward
@end
@interface SOGoMailKoreanForward : SOGoMailForward
@end
@interface SOGoMailLatvianForward : SOGoMailForward
@end
@@ -163,6 +169,9 @@
@interface SOGoMailSwedishForward : SOGoMailForward
@end
@interface SOGoMailThaiForward : SOGoMailForward
@end
@interface SOGoMailTurkishTurkeyForward : SOGoMailForward
@end
+9
View File
@@ -345,6 +345,9 @@
@implementation SOGoMailGermanForward
@end
@implementation SOGoMailGreekForward
@end
@implementation SOGoMailHebrewForward
@end
@@ -366,6 +369,9 @@
@implementation SOGoMailKazakhForward
@end
@implementation SOGoMailKoreanForward
@end
@implementation SOGoMailLatvianForward
@end
@@ -417,6 +423,9 @@
@implementation SOGoMailSwedishForward
@end
@implementation SOGoMailThaiForward
@end
@implementation SOGoMailTurkishTurkeyForward
@end
@@ -0,0 +1,15 @@
<#newLine/><#newLine
/><#signaturePlacementOnTop><#signature/><#newLine/><#newLine/></#signaturePlacementOnTop
>-------- Αρχικό Μήνυμα --------<#newLine
/>Θέμα: <#subject/><#newLine
/>Ημερομηνία: <#date/><#newLine
/>Από: <#from/><#newLine
/><#hasReplyTo>Απάντηση-Προς: <#replyTo/><#newLine/></#hasReplyTo
><#hasOrganization>Οργανισμός: <#organization/><#newLine/></#hasOrganization
>Προς: <#to/><#newLine
/><#hasCc>Κοιν.: <#cc/><#newLine/></#hasCc
><#hasNewsGroups>Ομάδες ειδήσεων: <#newsgroups/><#newLine/></#hasNewsGroups
><#hasReferences>Αναφορές: <#references/><#newLine/></#hasReferences
><#newLine/><#newLine
/><#messageBody
/><#signaturePlacementOnBottom><#newLine/><#newLine/><#signature/></#signaturePlacementOnBottom>
@@ -0,0 +1,88 @@
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}
@@ -0,0 +1,18 @@
<#replyPlacementOnTop><#newLine/><#newLine/></#replyPlacementOnTop
><#signaturePlacementOnTop><#signature/><#newLine/><#newLine/></#signaturePlacementOnTop
><#outlookMode
>-------- Αρχικό Μήνυμα --------<#newLine
/>Θέμα: <#subject/><#newLine
/>Ημερομηνία: <#date/><#newLine
/>Από: <#from/><#newLine
/><#hasReplyTo>Απάντηση-Προς: <#replyTo/><#newLine/></#hasReplyTo
><#hasOrganization>Οργανισμός: <#organization/><#newLine/></#hasOrganization
>Προς: <#to/><#newLine
/><#hasCc>Κοιν.: <#cc/><#newLine/></#hasCc
><#hasNewsGroups>Ομάδες ειδήσεων: <#newsgroups/><#newLine/></#hasNewsGroups
><#hasReferences>Αναφορές: <#references/><#newLine/></#hasReferences
></#outlookMode
><#standardMode>Στις <#date/>, ο/η <#from/> έγραψε:</#standardMode
><#newLine/><#newLine/><#messageBody
/><#replyPlacementOnBottom><#newLine/><#newLine/></#replyPlacementOnBottom
><#signaturePlacementOnBottom><#newLine/><#signature/></#signaturePlacementOnBottom>
@@ -0,0 +1,106 @@
outlookMode: WOConditional {
condition = outlookMode;
}
standardMode: WOConditional {
condition = outlookMode;
negate = YES;
}
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}
replyPlacementOnTop: WOConditional {
condition = replyPlacementOnTop;
}
replyPlacementOnBottom: WOConditional {
condition = replyPlacementOnTop;
negate = YES;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}
@@ -0,0 +1,15 @@
<#newLine/><#newLine
/><#signaturePlacementOnTop><#signature/><#newLine/><#newLine/></#signaturePlacementOnTop
>-------- 원본 메시지 --------<#newLine
/>제목: <#subject/><#newLine
/>날짜: <#date/><#newLine
/>보낸 사람: <#from/><#newLine
/><#hasReplyTo>회신: <#replyTo/><#newLine/></#hasReplyTo>
<#hasOrganization>조직: <#organization/><#newLine/></#hasOrganization>
받는 사람: <#to/>
<#hasCc>참조: <#cc/><#newLine/></#hasCc>
<#hasNewsGroups>뉴스그룹: <#newsgroups/><#newLine/></#hasNewsGroups>
<#hasReferences>참조: <#references/><#newLine/></#hasReferences>
<#newLine/><#newLine
/><#messageBody
/><#signaturePlacementOnBottom><#newLine/><#newLine/><#signature/></#signaturePlacementOnBottom>
@@ -0,0 +1,88 @@
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}
@@ -0,0 +1,20 @@
<#replyPlacementOnTop><#newLine/><#newLine/></#replyPlacementOnTop>
<#signaturePlacementOnTop><#signature/><#newLine/><#newLine/></#signaturePlacementOnTop>
<#outlookMode>
-------- 원본 메시지 --------
제목: <#subject/><#newLine/>
날짜: <#date/><#newLine/>
보낸 사람: <#from/><#newLine/>
<#hasReplyTo>회신: <#replyTo/><#newLine/></#hasReplyTo>
<#hasOrganization>조직: <#organization/><#newLine/></#hasOrganization>
받는 사람: <#to/><#newLine/>
<#hasCc>참조: <#cc/><#newLine/></#hasCc>
<#hasNewsGroups>뉴스그룹: <#newsgroups/><#newLine/></#hasNewsGroups>
<#hasReferences>참조: <#references/><#newLine/></#hasReferences>
</#outlookMode>
<#standardMode>
<#date/>에 <#from/>(이)가 작성했습니다:
</#standardMode>
<#newLine/><#newLine/><#messageBody/>
<#replyPlacementOnBottom><#newLine/><#newLine/></#replyPlacementOnBottom>
<#signaturePlacementOnBottom><#newLine/><#signature/></#signaturePlacementOnBottom>
@@ -0,0 +1,106 @@
outlookMode: WOConditional {
condition = outlookMode;
}
standardMode: WOConditional {
condition = outlookMode;
negate = YES;
}
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}
replyPlacementOnTop: WOConditional {
condition = replyPlacementOnTop;
}
replyPlacementOnBottom: WOConditional {
condition = replyPlacementOnTop;
negate = YES;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}
+6
View File
@@ -108,6 +108,9 @@
@interface SOGoMailJapaneseReply : SOGoMailReply
@end
@interface SOGoMailKoreanReply : SOGoMailReply
@end
@interface SOGoMailKazakhReply : SOGoMailReply
@end
@@ -162,6 +165,9 @@
@interface SOGoMailSwedishReply : SOGoMailReply
@end
@interface SOGoMailThaiReply : SOGoMailReply
@end
@interface SOGoMailTurkishTurkeyReply : SOGoMailReply
@end
+6
View File
@@ -167,6 +167,9 @@
@implementation SOGoMailKazakhReply
@end
@implementation SOGoMailKoreanReply
@end
@implementation SOGoMailLatvianReply
@end
@@ -218,6 +221,9 @@
@implementation SOGoMailSwedishReply
@end
@implementation SOGoMailThaiReply
@end
@implementation SOGoMailTurkishTurkeyReply
@end
@@ -0,0 +1,15 @@
<#newLine/><#newLine
/><#signaturePlacementOnTop><#signature/><#newLine/><#newLine/></#signaturePlacementOnTop
>-------- ข้อความต้นทาง --------<#newLine
/>หัวข้อ: <#subject/><#newLine
/>วันที่: <#date/><#newLine
/>จาก: <#from/><#newLine
/><#hasReplyTo>ตอบกลับ: <#replyTo/><#newLine/></#hasReplyTo
><#hasOrganization>องค์กร: <#organization/><#newLine/></#hasOrganization
>ถึง: <#to/><#newLine
/><#hasCc>สำเนา: <#cc/><#newLine/></#hasCc
><#hasNewsGroups>กลุ่มข่าว: <#newsgroups/><#newLine/></#hasNewsGroups
><#hasReferences>การอ้างถึง: <#references/><#newLine/></#hasReferences
><#newLine/><#newLine
/><#messageBody
/><#signaturePlacementOnBottom><#newLine/><#newLine/><#signature/></#signaturePlacementOnBottom>
@@ -0,0 +1,88 @@
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}
@@ -0,0 +1,18 @@
<#replyPlacementOnTop><#newLine/><#newLine/></#replyPlacementOnTop
><#signaturePlacementOnTop><#signature/><#newLine/><#newLine/></#signaturePlacementOnTop
><#outlookMode
>-------- ข้อความต้นทาง --------<#newLine
/>หัวข้อ: <#subject/><#newLine
/>วันที่: <#date/><#newLine
/>จาก: <#from/><#newLine
/><#hasReplyTo>ตอบกลับ: <#replyTo/><#newLine/></#hasReplyTo
><#hasOrganization>องค์กร: <#organization/><#newLine/></#hasOrganization
>ถึง: <#to/><#newLine
/><#hasCc>สำเนา: <#cc/><#newLine/></#hasCc
><#hasNewsGroups>กลุ่มข่าว: <#newsgroups/><#newLine/></#hasNewsGroups
><#hasReferences>การอ้างถึง: <#references/><#newLine/></#hasReferences
></#outlookMode
><#standardMode>บน <#date/>, <#from/> ขียน:</#standardMode
><#newLine/><#newLine/><#messageBody
/><#replyPlacementOnBottom><#newLine/><#newLine/></#replyPlacementOnBottom
><#signaturePlacementOnBottom><#newLine/><#signature/></#signaturePlacementOnBottom>
@@ -0,0 +1,106 @@
outlookMode: WOConditional {
condition = outlookMode;
}
standardMode: WOConditional {
condition = outlookMode;
negate = YES;
}
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}
replyPlacementOnTop: WOConditional {
condition = replyPlacementOnTop;
}
replyPlacementOnBottom: WOConditional {
condition = replyPlacementOnTop;
negate = YES;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}
@@ -0,0 +1,5 @@
"OtherUsersFolderName" = "ผู้ใช้งานอื่นๆ";
"SharedFoldersName" = "โฟลเดอร์ที่แชร์";
"Report: Marked messages as junk" = "รายงาน: ทำเครื่องหมายข้อความเป็นขยะ";
"Report: Marked messages as not junk" = "รายงาน: ทำเครื่องหมายข้อความว่าไม่ใช่ขยะ";
+1
View File
@@ -27,6 +27,7 @@
@class NSArray;
@class NSString;
@class WOContext;
@class NSNull;
@interface NSObject (SOGoObjectUtilities)
+21 -9
View File
@@ -33,6 +33,9 @@
#import "NSObject+Utilities.h"
static NSMutableDictionary *translationCache = nil;
@implementation NSObject (SOGoObjectUtilities)
- (NSString *) jsonRepresentation
@@ -101,19 +104,28 @@
if (!bundle)
bundle = [NSBundle mainBundle];
languages = [[self _languagesForLabelsInContext: context] objectEnumerator];
if(!translationCache)
translationCache = [NSMutableDictionary new];
while (!label && (language = [languages nextObject]))
{
paths = [bundle pathsForResourcesOfType: @"strings"
inDirectory: [NSString stringWithFormat: @"%@.lproj",
language]
if (![translationCache objectForKey: language] || [[translationCache objectForKey: language] objectForKey: key] != [NSNull null]) {
paths = [bundle pathsForResourcesOfType: @"strings"
inDirectory: [NSString stringWithFormat: @"%@.lproj",
language]
forLocalization: language];
if ([paths count] > 0)
{
strings = [NSDictionary
dictionaryFromStringsFile: [paths objectAtIndex: 0]];
label = [strings objectForKey: key];
}
if ([paths count] > 0)
{
strings = [NSDictionary
dictionaryFromStringsFile: [paths objectAtIndex: 0]];
[translationCache setObject: strings forKey: language];
label = [strings objectForKey: key];
}
} else {
strings = [translationCache objectForKey: language];
label = [strings objectForKey: key];
}
}
if (!label)
label = key;
+3
View File
@@ -184,6 +184,9 @@ static int cssEscapingCount;
{
rangePtr->location += offset;
urlText = [selfCopy substringFromRange: *rangePtr];
//If we try to detect mail, check if the first char is @, meaning this is not an email
if([prefix isEqualToString: @"mailto:"] && [urlText characterAtIndex: 0] == '@')
continue;
newUrlText = [NSString stringWithFormat: @"<a rel=\"noopener\" href=\"%@%@\">%@</a>",
([urlText hasPrefix: prefix]? @"" : prefix),
urlText, urlText];
+1 -1
View File
@@ -289,7 +289,7 @@ static memcached_st *handle = NULL;
NSData *keyData, *valueData;
memcached_return error;
// [self logWithFormat: @"setValue: '%@' forKey: '%@'", value, key];
//[self logWithFormat: @"setValue: '%@' forKey: '%@'", value, key];
if (handle)
{
keyData = [key dataUsingEncoding: NSUTF8StringEncoding];
+4
View File
@@ -59,6 +59,7 @@
"French",
"Galician",
"German",
"Greek",
"Hebrew",
"Hungarian",
"Icelandic",
@@ -66,6 +67,7 @@
"Italian",
"Japanese",
"Kazakh",
"Korean",
"Latvian",
"Lithuanian",
"Macedonian",
@@ -84,6 +86,7 @@
"SpanishArgentina",
"SpanishSpain",
"Swedish",
"Thai",
"TurkishTurkey",
"Ukrainian",
"Welsh"
@@ -127,6 +130,7 @@
SOGoMailDisplayFullEmail = NO;
SOGoMailDisplayRemoteInlineImages = "never";
SOGoMailCertificateEnabled = YES;
SOGoMailDisplayAttachmentAbove = NO;
SOGoMailAutoMarkAsReadDelay = "0";
SOGoMailAutoSave = "5";
+3 -1
View File
@@ -462,7 +462,9 @@
- (int) searchMinimumWordLength
{
return [self integerForKey: @"SOGoSearchMinimumWordLength"];
int min = [self integerForKey: @"SOGoSearchMinimumWordLength"];
if(min<1) min=1;
return min;
}
- (BOOL) notifyOnPersonalModifications
+4
View File
@@ -48,6 +48,7 @@
@class NSException;
@class NSTimeZone;
@class NSURL;
@class NSUUID;
@class WOContext;
@class WORequest;
@@ -74,6 +75,9 @@
+ (NSString *) globallyUniqueObjectId;
- (NSString *) globallyUniqueObjectId;
+ (NSString *) mailUniqueMessageId;
- (NSString *) mailUniqueMessageId;
+ (id) objectWithName: (NSString *)_name inContainer:(id)_container;
- (id) initWithName: (NSString *) _name inContainer:(id)_container;
+17 -1
View File
@@ -21,7 +21,6 @@
#import <unistd.h>
#import <NGObjWeb/SoClass.h>
#import <NGObjWeb/SoObject+SoDAV.h>
#import <NGObjWeb/WOApplication.h>
@@ -111,11 +110,28 @@
pid, (int) f, sequence++, (int) rndm];
}
- (NSString *) globallyUniqueObjectId
{
return [[self class] globallyUniqueObjectId];
}
+ (NSString *) mailUniqueMessageId
{
/*
843F8180-4E33-7B0B-6F1B-9847CAD3E6EB
*/
return [[NSUUID UUID] UUIDString];
}
- (NSString *) mailUniqueMessageId
{
/*
843F8180-4E33-7B0B-6F1B-9847CAD3E6EB
*/
return [[self class] mailUniqueMessageId];
}
/* containment */
+ (id) objectWithName: (NSString *)_name inContainer:(id)_container
-1
View File
@@ -66,7 +66,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer);
NSString *openIdClient;
NSString *openIdClientSecret;
NSString *openIdEmailParam;
NSString *openIdHttpVersion;
BOOL openIdEnableRefreshToken;
BOOL sendDomainInfo;
+11 -7
View File
@@ -54,7 +54,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
return total;
}
@implementation SimpleOpenIdResponse
- (id)init {
@@ -152,7 +151,7 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
- (void) initializeWithConfig: (NSDictionary *) _config
{
SOGoSystemDefaults *sd;
id refreshTokenBool, domainInfo;
id refreshTokenBool, domainInfo, intForKey;
if([_config objectForKey: @"SOGoOpenIdConfigUrl"] &&
[_config objectForKey: @"SOGoOpenIdScope"] &&
@@ -164,7 +163,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
openIdClient = [_config objectForKey: @"SOGoOpenIdClient"];
openIdClientSecret = [_config objectForKey: @"SOGoOpenIdClientSecret"];
openIdEmailParam = [_config objectForKey: @"SOGoOpenIdEmailParam"];
openIdHttpVersion = [_config objectForKey: @"SOGoOpenIdHttpVersion"];
openIdEnableRefreshToken = NO;
refreshTokenBool = [_config objectForKey: @"SOGoOpenIdEnableRefreshToken"];
@@ -176,8 +174,12 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
if (domainInfo && [domainInfo respondsToSelector: @selector (boolValue)])
sendDomainInfo = [domainInfo boolValue];
userTokenInterval = [_config objectForKey: @"SOGoOpenIdTokenCheckInterval"];
intForKey = [_config objectForKey: @"SOGoOpenIdTokenCheckInterval"];
if (intForKey && [intForKey respondsToSelector: @selector (intValue)])
userTokenInterval = [intForKey intValue];
else
userTokenInterval = 0;
[self _loadSessionFromCache: forDomain];
if(cacheUpdateNeeded)
@@ -223,7 +225,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
openIdClient = [sd openIdClient];
openIdClientSecret = [sd openIdClientSecret];
openIdEmailParam = [sd openIdEmailParam];
openIdHttpVersion = [sd openIdHttpVersion];
openIdEnableRefreshToken = [sd openIdEnableRefreshToken];
userTokenInterval = [sd openIdTokenCheckInterval];
sendDomainInfo = [sd openIdSendDomainInfo];
@@ -352,16 +353,19 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
if(SOGoOpenIDDebugEnabled)
NSLog(@"OpenId perform request: response is: %@", response);
curl_easy_cleanup(curl);
return [response autorelease];
}
else if (status == 404)
{
[self errorWithFormat: @"OpenID endpoint not found (404): %@", endpoint];
curl_easy_cleanup(curl);
return nil;
}
else
{
[self errorWithFormat: @"OpenID server internal error during %@: %@", endpoint, response];
curl_easy_cleanup(curl);
return nil;
}
}
@@ -370,7 +374,7 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
[self errorWithFormat: @"CURL error while accessing %@ (%d): %@", endpoint, rc,
[NSString stringWithCString: strlen(error) ? error : curl_easy_strerror(rc)]];
}
curl_easy_cleanup (curl);
curl_easy_cleanup(curl);
}
else
{
+2 -2
View File
@@ -790,10 +790,10 @@ static NSString *sieveScriptName = @"sogo";
imapAuthMech = nil;
if([sd doesLoginTypeByDomain])
{
r = [theUsername rangeOfString: @"@"];
r = [authname rangeOfString: @"@"];
if (r.location != NSNotFound)
{
userDomain = [theUsername substringFromIndex: r.location+1];
userDomain = [authname substringFromIndex: r.location+1];
imapAuthMech = [sd getImapAuthMechForDomain: userDomain];
}
}
-1
View File
@@ -107,7 +107,6 @@ NSComparisonResult languageSort(id el1, id el2, void *context);
- (NSString *) openIdClient;
- (NSString *) openIdClientSecret;
- (NSString *) openIdEmailParam;
- (NSString *) openIdHttpVersion;
- (BOOL) openIdEnableRefreshToken;
- (BOOL) openIdLogoutEnabled: (NSString *) _domain;
- (int) openIdTokenCheckInterval;
-9
View File
@@ -784,15 +784,6 @@ NSComparisonResult languageSort(id el1, id el2, void *context)
return emailParam;
}
- (NSString *) openIdHttpVersion
{
NSString *httpVersion;
httpVersion = [self stringForKey: @"SOGoOpenIdHttpVersion"];
if(!httpVersion)
httpVersion = @"HTTP/1.1";
return httpVersion;
}
- (BOOL) openIdLogoutEnabled: (NSString *) _domain
{
if(_domain && [self doesLoginTypeByDomain])
+2 -1
View File
@@ -124,7 +124,8 @@
- (BOOL) isSuperUser;
- (BOOL) canAuthenticate;
- (NSString *) totpKey;
- (NSString *) totpKey: (bool) isCheck;
- (NSString *) oldtotpKey;
/* resource */
- (BOOL) isResource;
+135 -81
View File
@@ -47,7 +47,6 @@
#import "SOGoUser.h"
static const NSString *kEncryptedUserNamePrefix = @"uenc";
@implementation SoUser (SOGoExtension)
@@ -145,92 +144,91 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc";
realUID = nil;
domain = nil;
if ([newLogin isEqualToString: @"anonymous"]
|| [newLogin isEqualToString: @"freebusy"])
if ([newLogin isEqualToString: @"anonymous"] || [newLogin isEqualToString: @"freebusy"])
realUID = newLogin;
else
{
sd = [SOGoSystemDefaults sharedSystemDefaults];
if ([sd enableDomainBasedUID] || [[sd loginDomains] count] > 0)
{
sd = [SOGoSystemDefaults sharedSystemDefaults];
if ([sd enableDomainBasedUID] || [[sd loginDomains] count] > 0)
{
r = [newLogin rangeOfString: @"@" options: NSBackwardsSearch];
if (r.location != NSNotFound)
{
// The domain is probably appended to the username;
// make sure it is defined as a domain in the configuration.
domain = [newLogin substringFromIndex: (r.location + r.length)];
if ([[SOGoUserManager sharedUserManager] isDomainDefined: domain] &&
![sd enableDomainBasedUID])
newLogin = [newLogin substringToIndex: r.location];
r = [newLogin rangeOfString: @"@" options: NSBackwardsSearch];
if (r.location != NSNotFound)
{
// The domain is probably appended to the username;
// make sure it is defined as a domain in the configuration.
domain = [newLogin substringFromIndex: (r.location + r.length)];
if ([[SOGoUserManager sharedUserManager] isDomainDefined: domain] &&
![sd enableDomainBasedUID])
newLogin = [newLogin substringToIndex: r.location];
if (domain != nil && ![sd enableDomainBasedUID])
// Login domains are enabled (SOGoLoginDomains) but not
// domain-based UID (SOGoEnableDomainBasedUID).
// Drop the domain from the login name.
domain = nil;
}
}
newLogin = [newLogin stringByReplacingString: @"%40"
withString: @"@"];
if (b)
realUID = newLogin;
else
{
um = [SOGoUserManager sharedUserManager];
contactInfos = [um contactInfosForUserWithUIDorEmail: newLogin
inDomain: domain];
realUID = [contactInfos objectForKey: @"c_uid"];
if (domain == nil && [sd enableDomainBasedUID])
domain = [contactInfos objectForKey: @"c_domain"];
}
if ([realUID length] && [domain length])
{
// When the user is associated to a domain, the [SOGoUser login]
// method returns the combination login@domain while
// [SOGoUser loginInDomain] only returns the login.
r = [realUID rangeOfString: domain options: NSBackwardsSearch|NSCaseInsensitiveSearch];
// Do NOT strip @domain.com if SOGoEnableDomainBasedUID is enabled since
// the real login most likely is the email address.
if (r.location != NSNotFound && ![sd enableDomainBasedUID])
uid = [realUID substringToIndex: r.location-1];
// If we don't have the domain in the UID but SOGoEnableDomainBasedUID is
// enabled, let's add it internally so so it becomes unique across
// all potential domains.
else if (r.location == NSNotFound && [sd enableDomainBasedUID])
{
uid = [NSString stringWithString: realUID];
realUID = [NSString stringWithFormat: @"%@@%@", realUID, domain];
}
// We found the domain and SOGoEnableDomainBasedUID is enabled,
// we keep realUID.. This would happen for example if the user
// authenticates with foo@bar.com and the UIDFieldName is also foo@bar.com
else if ([sd enableDomainBasedUID])
uid = [NSString stringWithString: realUID];
}
if (domain != nil && ![sd enableDomainBasedUID])
// Login domains are enabled (SOGoLoginDomains) but not
// domain-based UID (SOGoEnableDomainBasedUID).
// Drop the domain from the login name.
domain = nil;
}
}
newLogin = [newLogin stringByReplacingString: @"%40"
withString: @"@"];
if (b)
realUID = newLogin;
else
{
um = [SOGoUserManager sharedUserManager];
contactInfos = [um contactInfosForUserWithUIDorEmail: newLogin
inDomain: domain];
realUID = [contactInfos objectForKey: @"c_uid"];
if (domain == nil && [sd enableDomainBasedUID])
domain = [contactInfos objectForKey: @"c_domain"];
}
if ([realUID length] && [domain length])
{
// When the user is associated to a domain, the [SOGoUser login]
// method returns the combination login@domain while
// [SOGoUser loginInDomain] only returns the login.
r = [realUID rangeOfString: domain options: NSBackwardsSearch|NSCaseInsensitiveSearch];
// Do NOT strip @domain.com if SOGoEnableDomainBasedUID is enabled since
// the real login most likely is the email address.
if (r.location != NSNotFound && ![sd enableDomainBasedUID])
uid = [realUID substringToIndex: r.location-1];
// If we don't have the domain in the UID but SOGoEnableDomainBasedUID is
// enabled, let's add it internally so so it becomes unique across
// all potential domains.
else if (r.location == NSNotFound && [sd enableDomainBasedUID])
{
uid = [NSString stringWithString: realUID];
realUID = [NSString stringWithFormat: @"%@@%@", realUID, domain];
}
// We found the domain and SOGoEnableDomainBasedUID is enabled,
// we keep realUID.. This would happen for example if the user
// authenticates with foo@bar.com and the UIDFieldName is also foo@bar.com
else if ([sd enableDomainBasedUID])
uid = [NSString stringWithString: realUID];
}
}
if ([realUID length])
{
if ((self = [super initWithLogin: realUID roles: newRoles]))
{
if ((self = [super initWithLogin: realUID roles: newRoles]))
{
allEmails = nil;
currentPassword = nil;
cn = nil;
ASSIGN (loginInDomain, (uid ? uid : realUID));
_defaults = nil;
_domainDefaults = nil;
_settings = nil;
mailAccounts = nil;
}
allEmails = nil;
currentPassword = nil;
cn = nil;
ASSIGN (loginInDomain, (uid ? uid : realUID));
_defaults = nil;
_domainDefaults = nil;
_settings = nil;
mailAccounts = nil;
}
}
else
{
[self release];
self = nil;
}
{
[self release];
self = nil;
}
return self;
}
@@ -265,6 +263,14 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc";
- (NSString *) loginInDomain
{
SOGoSystemDefaults *sd;
NSString *_domain, *realLoginInDomain;
NSRange r;
sd = [SOGoSystemDefaults sharedSystemDefaults];
if ([sd enableDomainBasedUID] || [[sd loginDomains] count] > 0)
{
return self->login;
}
return loginInDomain;
}
@@ -1292,7 +1298,7 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc";
return [authValue boolValue];
}
- (NSString *) totpKey
- (NSString *) totpKey: (bool) isCheck
{
#if defined(MFA_CONFIG)
NSString *key, *result;
@@ -1301,6 +1307,51 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc";
size_t s_len, secret_len;
//Until 5.12.4, SOGo had two problems with totp:
// * It was not renew after a user disable it/renable it.
// * The length was too small: 12 instead of the recommanded 20
if(![_defaults totpEnabled])
{
//Totp was not enabled
//Only renew if this is not a check (happen when the user enable it for the first time and save its preferences
//the saveAction will check the totp code but [_defaults totpEnabled] is still False )
key = [[self userSettings] userCurrentTotpKey: !isCheck];
}
else
{
//Totp currently enabled
key = [[self userSettings] userCurrentTotpKey: NO];
}
s = [key UTF8String];
s_len = strlen(s);
oath_init();
oath_base32_encode(s,s_len, &secret, &secret_len);
oath_done();
result = [[NSString alloc] initWithBytesNoCopy: secret
length: secret_len
encoding: NSASCIIStringEncoding
freeWhenDone: YES];
return [result autorelease];
#else
return nil;
#endif
}
- (NSString *) oldtotpKey
{
#if defined(MFA_CONFIG)
//Was used before 5.12.5, is to not make obsolete totp profile set before
NSString *key, *result;
const char *s;
char *secret;
size_t s_len, secret_len;
key = [[[self userSettings] userPrivateSalt] substringToIndex: 12];
s = [key UTF8String];
s_len = strlen(s);
@@ -1364,7 +1415,7 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc";
return username;
cache = [SOGoCache sharedCache];
cacheKey = [NSString stringWithFormat: @"%@_%@", kEncryptedUserNamePrefix, username];
cacheKey = [NSString stringWithFormat: @"encrypted_%@",username];
exception = nil;
tmp = nil;
@@ -1395,11 +1446,14 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc";
NSString *tmp, *cacheKey;
SOGoCache *cache;
if (![[SOGoSystemDefaults sharedSystemDefaults] isURLEncryptionEnabled] || [username isEqualToString: @"anonymous"] || [[request requestHandlerKey] isEqualToString:@"dav"])
if (![[SOGoSystemDefaults sharedSystemDefaults] isURLEncryptionEnabled] ||
[username isEqualToString: @"anonymous"] ||
[[request requestHandlerKey] isEqualToString:@"dav"] ||
[[request requestHandlerPath] hasSuffix: @"freebusy.ifb/ajaxRead"])
return username;
cache = [SOGoCache sharedCache];
cacheKey = [NSString stringWithFormat: @"%@_%@", kEncryptedUserNamePrefix, username];
cacheKey = [NSString stringWithFormat: @"decrypted_%@", username];
exception = nil;
tmp = nil;
+4 -2
View File
@@ -156,12 +156,14 @@ extern NSString *SOGoPasswordRecoverySecondaryEmail;
- (void) setMailComposeFontSize: (int) newValue;
- (int) mailComposeFontSize;
- (void) setMailDisplayFullEmail: (BOOL *) newValue;
- (BOOL *) mailDisplayFullEmail;
- (void) setMailDisplayFullEmail: (BOOL) newValue;
- (BOOL) mailDisplayFullEmail;
- (void) setMailDisplayRemoteInlineImages: (NSString *) newValue;
- (NSString *) mailDisplayRemoteInlineImages;
- (void) setMailDisplayAttachmentAbove: (BOOL) newValue;
- (BOOL) mailDisplayAttachmentAbove;
- (void) setMailAutoMarkAsReadDelay: (int) newValue;
- (int) mailAutoMarkAsReadDelay;
+12 -2
View File
@@ -634,12 +634,12 @@ NSString *SOGoPasswordRecoverySecondaryEmail = @"SecondaryEmail";
return [self integerForKey: @"SOGoMailComposeFontSize"];
}
- (void) setMailDisplayFullEmail: (BOOL *) newValue
- (void) setMailDisplayFullEmail: (BOOL) newValue
{
[self setBool: newValue forKey: @"SOGoMailDisplayFullEmail"];
}
- (BOOL *) mailDisplayFullEmail;
- (BOOL) mailDisplayFullEmail;
{
return [self boolForKey: @"SOGoMailDisplayFullEmail"];
}
@@ -654,6 +654,16 @@ NSString *SOGoPasswordRecoverySecondaryEmail = @"SecondaryEmail";
return [self stringForKey: @"SOGoMailDisplayRemoteInlineImages"];
}
- (void) setMailDisplayAttachmentAbove: (BOOL) newValue
{
[self setBool: newValue forKey: @"SOGoMailDisplayAttachmentAbove"];
}
- (BOOL) mailDisplayAttachmentAbove;
{
return [self boolForKey: @"SOGoMailDisplayAttachmentAbove"];
}
- (void) setMailAutoMarkAsReadDelay: (int) newValue
{
[self setInteger: newValue forKey: @"SOGoMailAutoMarkAsReadDelay"];
+2
View File
@@ -35,6 +35,8 @@
- (NSArray *) subscribedCalendars;
- (NSArray *) subscribedAddressBooks;
- (NSString *) userPrivateSalt;
- (NSString *) userCurrentTotpKey: (bool) renew;
- (void) setTotpKey: (NSString* ) newKey;
- (NSString *) userPublicSalt;
- (void)enableForceResetPassword;
- (void)disableForceResetPassword;
+36
View File
@@ -116,6 +116,42 @@ static Class SOGoUserProfileKlass = Nil;
return salt;
}
- (NSString *) userCurrentTotpKey: (bool) renew
{
NSMutableDictionary *values;
NSString *key;
key = [[self dictionaryForKey: @"General"] objectForKey: @"totpKey"];
if (!key || renew)
{
key = [[[[NSProcessInfo processInfo] globallyUniqueString] asSHA1String] substringToIndex: 20];
values = [self objectForKey: @"General"];
if (!values)
values = [NSMutableDictionary dictionary];
[values setObject: key forKey: @"totpKey"];
[self setObject: values forKey: @"General"];
[self synchronize];
}
return key;
}
- (void) setTotpKey: (NSString* ) newKey
{
NSMutableDictionary *values;
values = [self objectForKey: @"General"];
if (!values)
values = [NSMutableDictionary dictionary];
[values setObject: newKey forKey: @"totpKey"];
[self setObject: values forKey: @"General"];
[self synchronize];
}
- (void) enableForceResetPassword
{
[self setObject: [NSNumber numberWithInt:1] forKey: @"ForceResetPassword"];
+49 -21
View File
@@ -225,9 +225,16 @@
*/
- (NSString *) _encryptPassword: (NSString *) plainPassword
{
NSString *pass;
NSString *pass, *passwordScheme;
NSString* result;
// if ([_userPasswordAlgorithm caseInsensitiveCompare: @"none"] == NSOrderedSame ||
// [_userPasswordAlgorithm caseInsensitiveCompare: @"plain"] == NSOrderedSame ||
// [_userPasswordAlgorithm caseInsensitiveCompare: @"cleartext"] == NSOrderedSame)
// {
// pass = [pass stringByReplacingString: @"'" withString: @"''"];
// }
pass = [plainPassword asCryptedPassUsingScheme: _userPasswordAlgorithm
keyPath: _keyPath];
@@ -272,6 +279,7 @@
grace: (int *) _grace
disablepasswordPolicyCheck: (BOOL) _disablepasswordPolicyCheck
{
EOAdaptor *adaptor;
EOAdaptorChannel *channel;
EOQualifier *qualifier;
GCSChannelManager *cm;
@@ -281,11 +289,13 @@
rc = NO;
_login = [_login stringByReplacingString: @"'" withString: @"''"];
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: _viewURL];
if (channel)
{
EOAdaptorContext *adaptorCtx;
adaptorCtx = [channel adaptorContext];
adaptor = [adaptorCtx adaptor];
if (_loginFields)
{
NSMutableArray *qualifiers;
@@ -324,7 +334,8 @@
nil];
[qualifier autorelease];
}
[qualifier appendSQLToString: sql];
[qualifier appendSQLToString: sql
withAdaptor: adaptor];
ex = [channel evaluateExpressionX: sql];
if (!ex)
@@ -430,9 +441,11 @@
{
BOOL didChange, isOldPwdOk, isPolicyOk;
EOAdaptorChannel *channel;
EOAdaptor *adaptor;
EOQualifier *qualifier_login, *qualifier_pwd;
GCSChannelManager *cm;
NSException *ex;
NSString *sqlstr;
NSMutableString *sqlstr;
*perr = -1;
isOldPwdOk = NO;
@@ -455,16 +468,28 @@
return NO;
// Save new password
login = [login stringByReplacingString: @"'" withString: @"''"];
// login = [login stringByReplacingString: @"'" withString: @"''"];
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: _viewURL];
if (channel)
{
sqlstr = [NSString stringWithFormat: (@"UPDATE %@"
@" SET c_password = '%@'"
@" WHERE c_uid = '%@'"),
[_viewURL gcsTableName], encryptedPassword, login];
EOAdaptorContext *adaptorCtx;
adaptorCtx = [channel adaptorContext];
adaptor = [adaptorCtx adaptor];
sqlstr = [NSMutableString stringWithFormat: @"UPDATE %@ SET ",
[_viewURL gcsTableName]];
qualifier_pwd = [[EOKeyValueQualifier alloc] initWithKey: @"c_password"
operatorSelector: EOQualifierOperatorEqual
value: encryptedPassword];
[qualifier_pwd appendSQLToString: sqlstr
withAdaptor: adaptor];
[sqlstr appendString: @" WHERE "];
qualifier_login = [[EOKeyValueQualifier alloc] initWithKey: @"c_uid"
operatorSelector: EOQualifierOperatorEqual
value: login];
[qualifier_login appendSQLToString: sqlstr
withAdaptor: adaptor];
ex = [channel evaluateExpressionX: sqlstr];
if (!ex)
{
@@ -998,7 +1023,9 @@
inDomain: (NSString *)domain
limit: (int)limit
{
EOAdaptor *adaptor;
EOAdaptorChannel *channel;
EOQualifier *qualifier;
NSEnumerator *criteriaList;
NSMutableArray *fields, *results;
GCSChannelManager *cm;
@@ -1014,12 +1041,14 @@
channel = [cm acquireOpenChannelForURL: _viewURL];
if (channel)
{
EOAdaptorContext *adaptorCtx;
adaptorCtx = [channel adaptorContext];
adaptor = [adaptorCtx adaptor];
fields = [NSMutableArray array];
if ([filter length])
{
lowerFilter = [filter lowercaseString];
lowerFilter = [lowerFilter asSafeSQLLikeString];
filterFormat = [NSString stringWithFormat: @"LOWER(%%@) LIKE '%%%%%@%%%%'", lowerFilter];
filter = [[filter asSafeSQLString] stringByReplacingString: @"\%" withString: @"%%"];
filterFormat = [NSString stringWithFormat: @"(%%@ isCaseInsensitiveLike: '*%@*')", filter];
if (criteria)
criteriaList = [criteria objectEnumerator];
else
@@ -1044,7 +1073,9 @@
if ([fields count])
{
qs = [[[fields uniqueObjects] stringsWithFormat: filterFormat] componentsJoinedByString: @" OR "];
[sql appendString: qs];
qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
[qualifier appendSQLToString: sql
withAdaptor: adaptor];
}
else
[sql appendString: @"1 = 1"];
@@ -1108,7 +1139,7 @@
andSortOrdering: (EOSortOrdering *) ordering
inDomain: (NSString *) domain
{
static EOAdaptor *adaptor = nil;
EOAdaptor *adaptor;
NSException *ex;
NSMutableArray *results;
NSMutableString *sql;
@@ -1123,12 +1154,9 @@
channel = [cm acquireOpenChannelForURL: _viewURL];
if (channel)
{
if (!adaptor)
{
EOAdaptorContext *adaptorCtx;
adaptorCtx = [channel adaptorContext];
adaptor = [adaptorCtx adaptor];
}
EOAdaptorContext *adaptorCtx;
adaptorCtx = [channel adaptorContext];
adaptor = [adaptorCtx adaptor];
sql = [NSMutableString stringWithFormat: @"SELECT c_name FROM %@ WHERE (", [_viewURL gcsTableName]];
if (qualifier)
+19 -2
View File
@@ -172,6 +172,9 @@
EOAdaptorContext *ac;
EOAdaptorChannel *fc;
NSString *profileURL, *sql, *sqlFromUserID, *sqlToUserID;
NSString *old_c_default, *old_c_settings, *new_c_default, *new_c_settings;
NSArray *attrs;
NSDictionary *row;
NSException *sqlError;
SOGoSystemDefaults *sd;
@@ -188,9 +191,22 @@
[ac beginTransaction];
sql = [NSString stringWithFormat: @"UPDATE %@ SET c_uid = '%@'"
sql = [NSString stringWithFormat: @"SELECT c_defaults, c_settings FROM %@"
@" WHERE c_uid = '%@'",
[profileLocation gcsTableName], sqlToUserID, sqlFromUserID];
[profileLocation gcsTableName], sqlFromUserID];
sqlError = [fc evaluateExpressionX: sql];
attrs = [fc describeResults: NO];
while ((row = [fc fetchAttributes: attrs withZone: NULL]))
{
old_c_default = [row objectForKey: @"c_defaults"];
old_c_settings = [row objectForKey: @"c_settings"];
new_c_default = [old_c_default stringByReplacingOccurrencesOfString:fromUserID withString:toUserID];
new_c_settings = [old_c_settings stringByReplacingOccurrencesOfString:fromUserID withString:toUserID];
}
sql = [NSString stringWithFormat: @"UPDATE %@ SET c_uid = '%@', c_defaults = '%@', "
@"c_settings = '%@' WHERE c_uid = '%@'",
[profileLocation gcsTableName], sqlToUserID, new_c_default, new_c_settings, sqlFromUserID];
sqlError = [fc evaluateExpressionX: sql];
if (sqlError)
{
@@ -568,6 +584,7 @@
[self _updateForeignSubscriptionsFromUser: oldUserID toUser: newUserID];
[self _updateLocalACLsFromUser: oldUserID toUser: newUserID];
[self _updateForeignACLsFromUser: oldUserID toUser: newUserID];
[self _updateOldUserIDDefaultAndSettings: oldUserID toUser: newUserID];
rc = YES;
}
@@ -25,7 +25,7 @@
"No resource" = "Cap recurs";
"Any Authenticated User" = "Qualsevol usuari autenticat";
"Public Access" = "Accés públic";
"Save" = "Save";
"Clear" = "Clear";
"Message of the day" = "Message of the day";
"Message of the day has been saved" = "Message of the day has been saved";
"Save" = "Desar";
"Clear" = "Esborrar";
"Message of the day" = "Missatge del dia";
"Message of the day has been saved" = "El missatge del dia s'ha desat";
@@ -25,7 +25,7 @@
"No resource" = "Geen middelen";
"Any Authenticated User" = "Elke geauthenticeerde gebruiker";
"Public Access" = "Publieke toegang";
"Save" = "Save";
"Clear" = "Clear";
"Message of the day" = "Message of the day";
"Message of the day has been saved" = "Message of the day has been saved";
"Save" = "Opslaan";
"Clear" = "Leeg maken";
"Message of the day" = "Bericht van de dag";
"Message of the day has been saved" = "Bericht van de dag is opgeslagen";
@@ -0,0 +1,31 @@
/* this file is in UTF-8 format! */
"Help" = "Help";
"Close" = "Close";
"Modules" = "Modules";
/* Modules short names */
"ACLs" = "ACLs";
/* Modules titles */
"ACLs_title" = "Users folders ACLs management";
/* Modules descriptions */
"ACLs_description" = "<p>The Access Control Lists administration module allows to change the ACLs of each user's Calendars and Address books.</p><p>To modify the ACLs of a user's folder, type the name of the user in the search field at the top of the window and double-click on the desired folder.</p>";
"Name or Email" = "Name or Email";
"ACLs saved" = "ACLs saved";
/* Rights module: initial search message */
"Start a search to edit the rights" = "Start a search to edit the rights";
/* Rights module: Empty search result */
"No matching user" = "No matching user";
/* Rights module: no selection */
"No resource selected" = "No resource selected";
"Add User" = "Add User";
"Subscribe User" = "Subscribe User";
"Rights" = "Rights";
"Search Users" = "Search Users";
"users found" = "users found";
"No resource" = "No resource";
"Any Authenticated User" = "Any Authenticated User";
"Public Access" = "Public Access";
"Save" = "Save";
"Clear" = "Clear";
"Message of the day" = "Message of the day";
"Message of the day has been saved" = "Message of the day has been saved";
@@ -0,0 +1,31 @@
/* this file is in UTF-8 format! */
"Help" = "도움말";
"Close" = "닫기";
"Modules" = "모듈";
/* Modules short names */
"ACLs" = "ACL";
/* Modules titles */
"ACLs_title" = "사용자 폴더 ACL 관리";
/* Modules descriptions */
"ACLs_description" = "<p>접근 제어 목록(ACL) 관리 모듈은 각 사용자의 캘린더 및 주소록의 ACL을 변경할 수 있도록 합니다.</p><p>사용자 폴더의 ACL을 수정하려면 창 상단의 검색 필드에 사용자 이름을 입력하고 원하는 폴더를 두 번 클릭하십시오.</p>";
"Name or Email" = "이름 또는 이메일";
"ACLs saved" = "ACL 저장됨";
/* Rights module: initial search message */
"Start a search to edit the rights" = "권한을 편집하려면 검색을 시작하십시오";
/* Rights module: Empty search result */
"No matching user" = "일치하는 사용자 없음";
/* Rights module: no selection */
"No resource selected" = "선택된 리소스 없음";
"Add User" = "사용자 추가";
"Subscribe User" = "사용자 구독";
"Rights" = "권한";
"Search Users" = "사용자 검색";
"users found" = "사용자 발견";
"No resource" = "리소스 없음";
"Any Authenticated User" = "모든 인증된 사용자";
"Public Access" = "공개 접근";
"Save" = "저장";
"Clear" = "지우기";
"Message of the day" = "오늘의 메시지";
"Message of the day has been saved" = "오늘의 메시지가 저장되었습니다";
@@ -0,0 +1,31 @@
/* this file is in UTF-8 format! */
"Help" = "ช่วยเหลือ";
"Close" = "ปิด";
"Modules" = "โมดูล";
/* Modules short names */
"ACLs" = "ACLs";
/* Modules titles */
"ACLs_title" = "Users folders ACLs management";
/* Modules descriptions */
"ACLs_description" = "<p>โมดูลการจัดการรายการควบคุมการเข้าถึงช่วยให้สามารถเปลี่ยนแปลง ACLs ของปฏิทินและสมุดที่อยู่ของผู้ใช้แต่ละคนได้</p><p>ในการแก้ไข ACLs ของโฟลเดอร์ของผู้ใช้ ให้พิมพ์ชื่อผู้ใช้ในช่องค้นหาที่ด้านบนของหน้าต่างและดับเบิลคลิกที่โฟลเดอร์ที่ต้องการ</p>";
"Name or Email" = "ชื่อหรืออีเมล์";
"ACLs saved" = "ACLs บันทึกแล้ว";
/* Rights module: initial search message */
"Start a search to edit the rights" = "เริ่มการค้นหาเพื่อแก้ไขสิทธิ์";
/* Rights module: Empty search result */
"No matching user" = "ไม่พบผู้ใช้ที่ตรงกัน";
/* Rights module: no selection */
"No resource selected" = "ไม่ได้เลือกทรัพยากร";
"Add User" = "เพิ่มผู้ใช้";
"Subscribe User" = "สมัครสมาชิกผู้ใช้";
"Rights" = "สิทธิ์";
"Search Users" = "ค้นหาผู้ใช้";
"users found" = "ผู้ใช้พบ";
"No resource" = "ไม่มีทรัพยากร";
"Any Authenticated User" = "ผู้ใช้ที่ได้รับการยืนยันตัวตนใด ๆ";
"Public Access" = "การเข้าถึงสาธารณะ";
"Save" = "บันทึก";
"Clear" = "ชัดเจน";
"Message of the day" = "ข้อความของวันนี้";
"Message of the day has been saved" = "ข้อความของวันนี้ถูกบันทึกแล้ว";
+20 -20
View File
@@ -41,11 +41,11 @@
= "Qualsevol usuari amb un compte en el sistema tindrà accés a la seua llibreta d'adreces \"%{0}\". Està segur de voler donar accés a qualsevol usuari en el sistema? ";
"Give Access" = "Donar accés";
"Keep Private" = "Mantenir en privat";
"Expand" = "Expand";
"Reduce" = "Reduce";
"Expand" = "Expandir";
"Reduce" = "Reduir";
/* tooltip */
"Refresh" = "Refresh";
"Refresh" = "Actualitzar";
/* generic.js */
"Unable to subscribe to that folder!"
@@ -109,7 +109,7 @@
"Personal" = "Personal";
"To Do" = "Per fer";
"Later" = "Més tard";
"Forwarded" = "Forwarded";
"Forwarded" = "Reenviat";
"Return Receipt Sent" = "Justificant de recepció enviat";
"a2_Sunday" = "dg";
"a2_Monday" = "dl";
@@ -128,15 +128,15 @@
"S/MIME Certificate" = "Certificat S/MIME";
"Subject Name" = "Nom del subjecte";
"Issuer" = "Emissor";
"streetAddress" = "Street";
"stateOrProvinceName" = "State or Province";
"localityName" = "Locality";
"streetAddress" = "Carrer";
"stateOrProvinceName" = "Estat o Província";
"localityName" = "Localitat";
"countryName" = "País";
"organizationName" = "Organització";
"organizationalUnitName" = "Unitat organitzativa";
"commonName" = "Nom comú";
"surname" = "Surname";
"givenName" = "Given Name";
"surname" = "Cognoms";
"givenName" = "Nom de pila";
"emailAddress" = "Correu electrònic";
@@ -227,16 +227,16 @@
"Move forward" = "Avançar";
/* Password Recovery */
"passwordRecovery_Disabled" = "Disabled";
"passwordRecovery_SecretQuestion" = "Secret question";
"passwordRecovery_SecretQuestion1" = "What is the name of your first pet ?";
"passwordRecovery_SecretQuestion2" = "What was your first car ?";
"passwordRecovery_SecretQuestion3" = "What is your favorite movie ?";
"passwordRecovery_SecondaryEmail" = "Secondary E-mail";
"passwordRecovery_Disabled" = "Desactivat";
"passwordRecovery_SecretQuestion" = "Pregunta secreta";
"passwordRecovery_SecretQuestion1" = "Quin és el nom de la teva primera mascota?";
"passwordRecovery_SecretQuestion2" = "Quin va ser el teu primer cotxe?";
"passwordRecovery_SecretQuestion3" = "Quina és la teva pel·lícula preferida?";
"passwordRecovery_SecondaryEmail" = "Correu electrònic secundari";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum of %{0} lowercase letter";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum of %{0} uppercase letter";
"POLICY_MIN_DIGIT" = "Minimum of %{0} digit";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum of %{0} special symbols";
"POLICY_MIN_LENGTH" = "Minimum length of %{0} characters";
"POLICY_MIN_LOWERCASE_LETTER" = "Mínim de %{0} lletra minúscula";
"POLICY_MIN_UPPERCASE_LETTER" = "Mínim de %{0} lletra majúscula";
"POLICY_MIN_DIGIT" = "Mínim de %{0} dígit";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Mínim de %{0} símbols especials";
"POLICY_MIN_LENGTH" = "Longitud mínima de %{0} caràcters";
+5 -5
View File
@@ -235,8 +235,8 @@
"passwordRecovery_SecondaryEmail" = "Sekundární e-mail";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum of %{0} lowercase letter";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum of %{0} uppercase letter";
"POLICY_MIN_DIGIT" = "Minimum of %{0} digit";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum of %{0} special symbols";
"POLICY_MIN_LENGTH" = "Minimum length of %{0} characters";
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum je %{0} malých znaků";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum je %{0} velkých písmen";
"POLICY_MIN_DIGIT" = "Minimum je %{0} číslic";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum je %{0} speciálních znaků";
"POLICY_MIN_LENGTH" = "Minimální délka je %{0} znaků";
+14 -14
View File
@@ -45,7 +45,7 @@
"Reduce" = "Verminderen";
/* tooltip */
"Refresh" = "Refresh";
"Refresh" = "Vernieuwen";
/* generic.js */
"Unable to subscribe to that folder!"
@@ -109,7 +109,7 @@
"Personal" = "Persoonlijk";
"To Do" = "Te doen";
"Later" = "Later";
"Forwarded" = "Forwarded";
"Forwarded" = "Doorgestuurd";
"Return Receipt Sent" = "Ontvangstbewijs verzonden";
"a2_Sunday" = "Zo";
"a2_Monday" = "Ma";
@@ -122,7 +122,7 @@
"Add User" = "Gebruiker toevoegen";
"Loading" = "Laden";
"No such user." = "Geen dergelijke gebruiker";
"You cannot (un)subscribe to a folder that you own!" = "Kan niet aan- of afmelden van eigen map!";
"You cannot (un)subscribe to a folder that you own!" = "U kunt zich niet (af)melden voor een map waarvan u de eigenaar bent!";
/* SMIME Certificate field */
"S/MIME Certificate" = "S/MIME Certificaat";
@@ -227,16 +227,16 @@
"Move forward" = "Ga vooruit";
/* Password Recovery */
"passwordRecovery_Disabled" = "Disabled";
"passwordRecovery_SecretQuestion" = "Secret question";
"passwordRecovery_SecretQuestion1" = "What is the name of your first pet ?";
"passwordRecovery_SecretQuestion2" = "What was your first car ?";
"passwordRecovery_SecretQuestion3" = "What is your favorite movie ?";
"passwordRecovery_SecondaryEmail" = "Secondary E-mail";
"passwordRecovery_Disabled" = "Uitgezet";
"passwordRecovery_SecretQuestion" = "Geheime vraag";
"passwordRecovery_SecretQuestion1" = "Hoe heet je eerste huisdier?";
"passwordRecovery_SecretQuestion2" = "Wat was je eerste auto?";
"passwordRecovery_SecretQuestion3" = "Wat is je favoriete film?";
"passwordRecovery_SecondaryEmail" = "Secundair e-mailadres";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum of %{0} lowercase letter";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum of %{0} uppercase letter";
"POLICY_MIN_DIGIT" = "Minimum of %{0} digit";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum of %{0} special symbols";
"POLICY_MIN_LENGTH" = "Minimum length of %{0} characters";
"POLICY_MIN_LOWERCASE_LETTER" = "Minimaal %{0} kleine letter";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimaal %{0} hoofdletter";
"POLICY_MIN_DIGIT" = "Minimaal %{0} cijfer";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimaal %{0} speciale symbolen";
"POLICY_MIN_LENGTH" = "Minimale lengte van %{0} tekens";
+242
View File
@@ -0,0 +1,242 @@
/* this file is in UTF-8 format! */
/* toolbars */
"Save" = "Αποθήκευση";
"Close" = "Κλείσιμο";
"Edit User Rights" = "Επεξεργασία Δικαιωμάτων Χρήστη";
"Home" = "Αρχική";
"Calendar" = "Ημερολόγιο";
"Address Book" = "Επαφές";
"Mail" = "Αλληλογραφία";
"Preferences" = "Ρυθμίσεις";
"Administration" = "Διαχείριση";
"Disconnect" = "Αποσύνδεση";
"Toggle Menu" = "Εναλλαγή Μενού";
"Right Administration" = "Διαχείριση Δικαιωμάτων";
"Log Console (dev.)" = "Κονσόλα Καταγραφής (dev.)";
"User" = "Χρήστης";
"Vacation message is enabled" = "Το μήνυμα απουσίας είναι ενεργοποιημένο";
"Help" = "Βοήθεια";
"noJavascriptError" = "Το SOGo απαιτεί JavaScript για να λειτουργήσει. Βεβαιωθείτε ότι αυτή η επιλογή είναι διαθέσιμη και ενεργοποιημένη στις ρυθμίσεις του προγράμματος περιήγησής σας.";
"noJavascriptRetry" = "Επανάληψη";
"Owner" = "Ιδιοκτήτης";
"Publish the Free/Busy information" = "Δημοσίευση πληροφοριών Ελεύθερος/Απασχολημένος";
"Add..." = "Προσθήκη...";
"Remove" = "Αφαίρεση";
"Subscribe User" = "Εγγραφή Χρήστη";
"Any Authenticated User" = "Οποιοσδήποτε Πιστοποιημένος Χρήστης";
"Public Access" = "Δημόσια Πρόσβαση";
"Any user not listed above" = "Οποιοσδήποτε χρήστης δεν αναφέρεται παραπάνω";
"Anybody accessing this resource from the public area" = "Οποιοσδήποτε που έχει πρόσβαση σε αυτόν τον πόρο από τη δημόσια περιοχή";
"Sorry, the user rights can not be configured for that object." = "Λυπούμαστε, τα δικαιώματα χρήστη δεν μπορούν να ρυθμιστούν για αυτό το αντικείμενο.";
"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?"
= "Οποιοσδήποτε χρήστης με λογαριασμό σε αυτό το σύστημα θα μπορεί να έχει πρόσβαση στο γραμματοκιβώτιό σας \"%{0}\". Είστε βέβαιοι ότι τους εμπιστεύεστε όλους;";
"Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?"
= "Οποιοσδήποτε χρήστης με λογαριασμό σε αυτό το σύστημα θα μπορεί να έχει πρόσβαση στο ημερολόγιό σας \"%{0}\". Είστε βέβαιοι ότι τους εμπιστεύεστε όλους;";
"Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
= "Δυνητικά οποιοσδήποτε στο Διαδίκτυο θα μπορεί να έχει πρόσβαση στο ημερολόγιό σας \"%{0}\", ακόμα και αν δεν έχει λογαριασμό σε αυτό το σύστημα. Είναι αυτές οι πληροφορίες κατάλληλες για δημόσια δημοσίευση στο Διαδίκτυο;";
"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?"
= "Οποιοσδήποτε χρήστης με λογαριασμό σε αυτό το σύστημα θα μπορεί να έχει πρόσβαση στο βιβλίο διευθύνσεών σας \"%{0}\". Είστε βέβαιοι ότι τους εμπιστεύεστε όλους;";
"Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
= "Δυνητικά οποιοσδήποτε στο Διαδίκτυο θα μπορεί να έχει πρόσβαση στο βιβλίο διευθύνσεών σας \"%{0}\", ακόμα και αν δεν έχει λογαριασμό σε αυτό το σύστημα. Είναι αυτές οι πληροφορίες κατάλληλες για δημόσια δημοσίευση στο Διαδίκτυο;";
"Give Access" = "Παροχή Πρόσβασης";
"Keep Private" = "Διατήρηση Ιδιωτικότητας";
"Expand" = "Επέκταση";
"Reduce" = "Σύμπτυξη";
/* tooltip */
"Refresh" = "Ανανέωση";
/* generic.js */
"Unable to subscribe to that folder!"
= "Αδυναμία εγγραφής σε αυτόν τον φάκελο!";
"You cannot subscribe to a folder that you own!"
= "Δεν μπορείτε να εγγραφείτε σε φάκελο που σας ανήκει!";
"Unable to unsubscribe from that folder!"
= "Αδυναμία κατάργησης εγγραφής από αυτόν τον φάκελο!";
"You cannot unsubscribe from a folder that you own!"
= "Δεν μπορείτε να καταργήσετε την εγγραφή από φάκελο που σας ανήκει!";
"Unable to rename that folder!" = "Αδυναμία μετονομασίας αυτού του φακέλου!";
"You have already subscribed to that folder!"
= "Έχετε ήδη εγγραφεί σε αυτόν τον φάκελο!";
"The user rights cannot be edited for this object!"
= "Τα δικαιώματα χρήστη δεν μπορούν να επεξεργαστούν για αυτό το αντικείμενο!";
"A folder by that name already exists." = "Ένας φάκελος με αυτό το όνομα υπάρχει ήδη.";
"You cannot create a list in a shared address book."
= "Δεν μπορείτε να δημιουργήσετε λίστα σε κοινόχρηστο βιβλίο διευθύνσεων.";
"Warning" = "Προειδοποίηση";
"Can't contact server" = "Προέκυψε σφάλμα κατά την επικοινωνία με τον διακομιστή. Παρακαλούμε δοκιμάστε ξανά αργότερα.";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "Δεν σας επιτρέπεται η πρόσβαση σε αυτήν την ενότητα ή σε αυτό το σύστημα. Επικοινωνήστε με τον διαχειριστή του συστήματος.";
"You don't have the required privileges to perform the operation."
= "Δεν έχετε τα απαιτούμενα δικαιώματα για να εκτελέσετε αυτήν την ενέργεια.";
"noEmailForDelegation" = "Πρέπει να καθορίσετε τη διεύθυνση στην οποία θέλετε να αναθέσετε την πρόσκλησή σας.";
"delegate is organizer" = "Ο αντιπρόσωπος είναι ο διοργανωτής. Παρακαλούμε καθορίστε διαφορετικό αντιπρόσωπο.";
"delegate is a participant" = "Ο αντιπρόσωπος είναι ήδη συμμετέχων.";
"delegate is a group" = "Η καθορισμένη διεύθυνση αντιστοιχεί σε ομάδα. Μπορείτε να αναθέσετε μόνο σε μοναδικό άτομο.";
/* common buttons */
"OK" = "Εντάξει";
"Cancel" = "Άκυρο";
"Yes" = "Ναι";
"No" = "Όχι";
/* generic messages */
"Error" = "Σφάλμα";
"Success" = "Επιτυχία";
/* confirmation dialog box */
"Confirmation" = "Επιβεβαίωση";
/* alarms */
"Reminder" = "Υπενθύμιση";
"Start" = "Έναρξη";
"Due Date" = "Ημερομηνία Λήξης";
"Location" = "Τοποθεσία";
"Snooze" = "Αναβολή";
"Snooze for " = "Αναβολή για ";
"5 minutes" = "5 λεπτά";
"10 minutes" = "10 λεπτά";
"15 minutes" = "15 λεπτά";
"30 minutes" = "30 λεπτά";
"45 minutes" = "45 λεπτά";
"1 hour" = "1 ώρα";
"1 day" = "1 ημέρα";
/* mail labels */
"Important" = "Σημαντικό";
"Work" = "Εργασία";
"Personal" = "Προσωπικό";
"To Do" = "Προς Εκτέλεση";
"Later" = "Αργότερα";
"Forwarded" = "Προωθήθηκε";
"Return Receipt Sent" = "Απεστάλη Απόδειξη Παράδοσης";
"a2_Sunday" = "Κυ";
"a2_Monday" = "Δε";
"a2_Tuesday" = "Τρ";
"a2_Wednesday" = "Τε";
"a2_Thursday" = "Πέ";
"a2_Friday" = "Πα";
"a2_Saturday" = "Σά";
"Access Rights" = "Δικαιώματα Πρόσβασης";
"Add User" = "Προσθήκη Χρήστη";
"Loading" = "Φόρτωση";
"No such user." = "Δεν υπάρχει τέτοιος χρήστης.";
"You cannot (un)subscribe to a folder that you own!" = "Δεν μπορείτε να (απ)εγγραφείτε από φάκελο που σας ανήκει!";
/* SMIME Certificate field */
"S/MIME Certificate" = "Πιστοποιητικό S/MIME";
"Subject Name" = "Όνομα Υποκειμένου";
"Issuer" = "Εκδότης";
"streetAddress" = "Οδός";
"stateOrProvinceName" = "Πολιτεία ή Νομός";
"localityName" = "Πόλη";
"countryName" = "Χώρα";
"organizationName" = "Οργανισμός";
"organizationalUnitName" = "Μονάδα Οργανισμού";
"commonName" = "Κοινό Όνομα";
"surname" = "Επίθετο";
"givenName" = "Όνομα";
"emailAddress" = "Διεύθυνση Email";
/* Authentication username */
"Username" = "Όνομα Χρήστη";
/* Authentication password */
"Password" = "Κωδικός Πρόσβασης";
/* Authentication failed */
"Wrong username or password." = "Λανθασμένο όνομα χρήστη ή κωδικός πρόσβασης.";
/* Error message displayed bellow search field when the search string has less than the required number of characters */
"Enter at least %{minimumSearchLength} characters" = "Εισαγάγετε τουλάχιστον %{minimumSearchLength} χαρακτήρες";
/* Error message displayed when a file upload exceeds WOMaxUploadSize */
"File size upload limit reached" = "Ξεπεράστηκε το όριο μεγέθους αρχείου για μεταφόρτωση";
/* Generic server error */
"An error occured, please try again." = "Προέκυψε σφάλμα, παρακαλούμε δοκιμάστε ξανά.";
/* Open datepicker */
"Open Calendar" = "Άνοιγμα Ημερολογίου";
/* Toggle visibility (ex: mail account in left navigation menu) */
"Toggle visibility" = "Εναλλαγή ορατότητας";
"Keyboard Shortcuts" = "Συντομεύσεις Πληκτρολογίου";
/* Aria label for avatar button to select and unselect an item */
"Toggle item" = "Εναλλαγή στοιχείου";
/* Toggle multiple items at the same time (hotkeys cheatsheet) */
"Toggle range of items" = "Εναλλαγή εύρους στοιχείων";
/* Question mark shows list of hotkeys */
"Show or hide this help" = "Εμφάνιση ή απόκρυψη αυτής της βοήθειας";
/* Space key */
"key_space" = "διάστημα";
/* Delete key */
"key_delete" = "delete";
/* Shift and space key */
"key_shift+space" = "shift + διάστημα";
/* Up arrow key */
"key_up" = "↑";
/* Down arrow key */
"key_down" = "↓";
/* Left arrow key */
"key_left" = "←";
/* Right arrow key */
"key_right" = "→";
/* Shift and up arrow combo keys */
"key_shift+up" = "shift + ↑";
/* Shift and down arrow combo keys */
"key_shift+down" = "shift + ↓";
/* Backspace key */
"key_backspace" = "⌫";
/* Hotkey to start a search */
"hotkey_search" = "s";
/* Hotkey description to select next list item */
"View next item" = "Προβολή επόμενου στοιχείου";
/* Hotkey description to select previous list item */
"View previous item" = "Προβολή προηγούμενου στοιχείου";
/* Hotkey description to add next list item to selection */
"Add next item to selection" = "Προσθήκη επόμενου στοιχείου στην επιλογή";
/* Hotkey description to add previous list item to selection */
"Add previous item to selection" = "Προσθήκη προηγούμενου στοιχείου στην επιλογή";
/* Hotkey description to move backward in current view */
"Move backward" = "Μετακίνηση προς τα πίσω";
/* Hotkey description to move forward in current view */
"Move forward" = "Μετακίνηση προς τα εμπρός";
/* Password Recovery */
"passwordRecovery_Disabled" = "Απενεργοποιημένο";
"passwordRecovery_SecretQuestion" = "Μυστική ερώτηση";
"passwordRecovery_SecretQuestion1" = "Ποιο είναι το όνομα του πρώτου σας κατοικίδιου;";
"passwordRecovery_SecretQuestion2" = "Ποιο ήταν το πρώτο σας αυτοκίνητο;";
"passwordRecovery_SecretQuestion3" = "Ποια είναι η αγαπημένη σας ταινία;";
"passwordRecovery_SecondaryEmail" = "Δευτερεύον Email";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "Τουλάχιστον %{0} πεζός χαρακτήρας";
"POLICY_MIN_UPPERCASE_LETTER" = "Τουλάχιστον %{0} κεφαλαίος χαρακτήρας";
"POLICY_MIN_DIGIT" = "Τουλάχιστον %{0} ψηφίο";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Τουλάχιστον %{0} ειδικός χαρακτήρας";
"POLICY_MIN_LENGTH" = "Ελάχιστο μήκος %{0} χαρακτήρες";
+242
View File
@@ -0,0 +1,242 @@
/* this file is in UTF-8 format! */
/* toolbars */
"Save" = "저장";
"Close" = "닫기";
"Edit User Rights" = "사용자 권한 편집";
"Home" = "홈";
"Calendar" = "캘린더";
"Address Book" = "주소록";
"Mail" = "메일";
"Preferences" = "환경설정";
"Administration" = "관리";
"Disconnect" = "연결 끊기";
"Toggle Menu" = "메뉴 전환";
"Right Administration" = "권한 관리";
"Log Console (dev.)" = "로그 콘솔 (개발)";
"User" = "사용자";
"Vacation message is enabled" = "부재중 메시지 활성화됨";
"Help" = "도움말";
"noJavascriptError" = "SOGo를 실행하려면 Javascript가 필요합니다. 브라우저 환경설정에서 이 옵션이 사용 가능하고 활성화되어 있는지 확인하세요.";
"noJavascriptRetry" = "다시 시도";
"Owner" = "소유자";
"Publish the Free/Busy information" = "약속 가능/불가능 정보 게시";
"Add..." = "추가...";
"Remove" = "제거";
"Subscribe User" = "사용자 구독";
"Any Authenticated User" = "모든 인증된 사용자";
"Public Access" = "공개 접근";
"Any user not listed above" = "위에 나열되지 않은 모든 사용자";
"Anybody accessing this resource from the public area" = "공개 영역에서 이 리소스에 접근하는 모든 사람";
"Sorry, the user rights can not be configured for that object." = "죄송합니다, 해당 개체에 대한 사용자 권한은 설정할 수 없습니다.";
"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?"
= "이 시스템에 계정이 있는 모든 사용자가 귀하의 사서함 \"%{0}\"에 접근할 수 있습니다. 그들 모두를 신뢰하십니까?";
"Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?"
= "이 시스템에 계정이 있는 모든 사용자가 귀하의 캘린더 \"%{0}\"에 접근할 수 있습니다. 그들 모두를 신뢰하십니까?";
"Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
= "이 시스템에 계정이 없더라도 인터넷상의 누구나 귀하의 캘린더 \"%{0}\"에 접근할 수 있습니다. 이 정보는 공개 인터넷에 적합합니까?";
"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?"
= "이 시스템에 계정이 있는 모든 사용자가 귀하의 주소록 \"%{0}\"에 접근할 수 있습니다. 그들 모두를 신뢰하십니까?";
"Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
= "이 시스템에 계정이 없더라도 인터넷상의 누구나 귀하의 주소록 \"%{0}\"에 접근할 수 있습니다. 이 정보는 공개 인터넷에 적합합니까?";
"Give Access" = "접근 권한 부여";
"Keep Private" = "비공개 유지";
"Expand" = "확장";
"Reduce" = "축소";
/* tooltip */
"Refresh" = "새로고침";
/* generic.js */
"Unable to subscribe to that folder!"
= "해당 폴더를 구독할 수 없습니다!";
"You cannot subscribe to a folder that you own!"
= "소유하고 있는 폴더는 구독할 수 없습니다!";
"Unable to unsubscribe from that folder!"
= "해당 폴더 구독을 취소할 수 없습니다!";
"You cannot unsubscribe from a folder that you own!"
= "소유하고 있는 폴더는 구독을 취소할 수 없습니다!";
"Unable to rename that folder!" = "해당 폴더 이름을 바꿀 수 없습니다!";
"You have already subscribed to that folder!"
= "이미 해당 폴더를 구독했습니다!";
"The user rights cannot be edited for this object!"
= "이 개체에 대한 사용자 권한은 편집할 수 없습니다!";
"A folder by that name already exists." = "해당 이름의 폴더가 이미 존재합니다.";
"You cannot create a list in a shared address book."
= "공유 주소록에서는 목록을 생성할 수 없습니다.";
"Warning" = "경고";
"Can't contact server" = "서버와 통신하는 중 오류가 발생했습니다. 나중에 다시 시도해 주세요.";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "이 모듈 또는 이 시스템에 접근할 수 없습니다. 시스템 관리자에게 문의하십시오.";
"You don't have the required privileges to perform the operation."
= "이 작업을 수행하는 데 필요한 권한이 없습니다.";
"noEmailForDelegation" = "초대를 위임할 주소를 지정해야 합니다.";
"delegate is organizer" = "위임자가 주최자입니다. 다른 위임자를 지정하십시오.";
"delegate is a participant" = "위임자가 이미 참가자입니다.";
"delegate is a group" = "지정된 주소는 그룹에 해당합니다. 개별 사용자에게만 위임할 수 있습니다.";
/* common buttons */
"OK" = "확인";
"Cancel" = "취소";
"Yes" = "예";
"No" = "아니요";
/* generic messages */
"Error" = "오류";
"Success" = "성공";
/* confirmation dialog box */
"Confirmation" = "확인";
/* alarms */
"Reminder" = "알림";
"Start" = "시작";
"Due Date" = "마감일";
"Location" = "장소";
"Snooze" = "다시 알림";
"Snooze for " = "다시 알림 ";
"5 minutes" = "5분";
"10 minutes" = "10분";
"15 minutes" = "15분";
"30 minutes" = "30분";
"45 minutes" = "45분";
"1 hour" = "1시간";
"1 day" = "1일";
/* mail labels */
"Important" = "중요";
"Work" = "업무";
"Personal" = "개인";
"To Do" = "할 일";
"Later" = "나중에";
"Forwarded" = "전달됨";
"Return Receipt Sent" = "읽음 확인 전송됨";
"a2_Sunday" = "일";
"a2_Monday" = "월";
"a2_Tuesday" = "화";
"a2_Wednesday" = "수";
"a2_Thursday" = "목";
"a2_Friday" = "금";
"a2_Saturday" = "토";
"Access Rights" = "접근 권한";
"Add User" = "사용자 추가";
"Loading" = "로딩 중";
"No such user." = "해당 사용자가 없습니다.";
"You cannot (un)subscribe to a folder that you own!" = "소유하고 있는 폴더는 (구독/구독 취소)할 수 없습니다!";
/* SMIME Certificate field */
"S/MIME Certificate" = "S/MIME 인증서";
"Subject Name" = "주체 이름";
"Issuer" = "발급자";
"streetAddress" = "거리 주소";
"stateOrProvinceName" = "주 또는 시/도";
"localityName" = "지역";
"countryName" = "국가";
"organizationName" = "기관명";
"organizationalUnitName" = "조직 단위";
"commonName" = "일반 이름";
"surname" = "성";
"givenName" = "이름";
"emailAddress" = "이메일 주소";
/* Authentication username */
"Username" = "사용자명";
/* Authentication password */
"Password" = "비밀번호";
/* Authentication failed */
"Wrong username or password." = "잘못된 사용자명 또는 비밀번호입니다.";
/* Error message displayed bellow search field when the search string has less than the required number of characters */
"Enter at least %{minimumSearchLength} characters" = "최소 %{minimumSearchLength}자를 입력하세요";
/* Error message displayed when a file upload exceeds WOMaxUploadSize */
"File size upload limit reached" = "파일 크기 업로드 제한에 도달했습니다";
/* Generic server error */
"An error occured, please try again." = "An error occured, please try again.";
/* Open datepicker */
"Open Calendar" = "캘린더 열기";
/* Toggle visibility (ex: mail account in left navigation menu) */
"Toggle visibility" = "가시성 전환";
"Keyboard Shortcuts" = "키보드 단축키";
/* Aria label for avatar button to select and unselect an item */
"Toggle item" = "항목 전환";
/* Toggle multiple items at the same time (hotkeys cheatsheet) */
"Toggle range of items" = "항목 범위 전환";
/* Question mark shows list of hotkeys */
"Show or hide this help" = "이 도움말 표시 또는 숨기기";
/* Space key */
"key_space" = "스페이스";
/* Delete key */
"key_delete" = "삭제";
/* Shift and space key */
"key_shift+space" = "시프트 + 스페이스";
/* Up arrow key */
"key_up" = "↑";
/* Down arrow key */
"key_down" = "↓";
/* Left arrow key */
"key_left" = "←";
/* Right arrow key */
"key_right" = "→";
/* Shift and up arrow combo keys */
"key_shift+up" = "시프트 + ↑";
/* Shift and down arrow combo keys */
"key_shift+down" = "시프트 + ↓";
/* Backspace key */
"key_backspace" = "⌫";
/* Hotkey to start a search */
"hotkey_search" = "s";
/* Hotkey description to select next list item */
"View next item" = "다음 항목 보기";
/* Hotkey description to select previous list item */
"View previous item" = "이전 항목 보기";
/* Hotkey description to add next list item to selection */
"Add next item to selection" = "선택 항목에 다음 항목 추가";
/* Hotkey description to add previous list item to selection */
"Add previous item to selection" = "선택 항목에 이전 항목 추가";
/* Hotkey description to move backward in current view */
"Move backward" = "뒤로 이동";
/* Hotkey description to move forward in current view */
"Move forward" = "앞으로 이동";
/* Password Recovery */
"passwordRecovery_Disabled" = "비활성화됨";
"passwordRecovery_SecretQuestion" = "비밀 질문";
"passwordRecovery_SecretQuestion1" = "첫 번째 반려동물의 이름은 무엇인가요?";
"passwordRecovery_SecretQuestion2" = "첫 번째 자동차는 무엇이었나요?";
"passwordRecovery_SecretQuestion3" = "가장 좋아하는 영화는 무엇인가요?";
"passwordRecovery_SecondaryEmail" = "보조 이메일";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "최소 %{0}개의 소문자";
"POLICY_MIN_UPPERCASE_LETTER" = "최소 %{0}개의 대문자";
"POLICY_MIN_DIGIT" = "최소 %{0}개의 숫자";
"POLICY_MIN_SPECIAL_SYMBOLS" = "최소 %{0}개의 특수 기호";
"POLICY_MIN_LENGTH" = "최소 길이 %{0}자";
+5 -5
View File
@@ -235,8 +235,8 @@
"passwordRecovery_SecondaryEmail" = "Dodatkowy e-mail";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum of %{0} lowercase letter";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum of %{0} uppercase letter";
"POLICY_MIN_DIGIT" = "Minimum of %{0} digit";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum of %{0} special symbols";
"POLICY_MIN_LENGTH" = "Minimum length of %{0} characters";
"POLICY_MIN_LOWERCASE_LETTER" = "Co najmniej %{0} małych liter";
"POLICY_MIN_UPPERCASE_LETTER" = "Co najmniej %{0} dużych liter";
"POLICY_MIN_DIGIT" = "Co najmniej %{0} cyfr";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Co najmniej %{0} znaków specjalnych";
"POLICY_MIN_LENGTH" = "Długość co najmniej %{0} znaków";
@@ -235,8 +235,8 @@
"passwordRecovery_SecondaryEmail" = "Email secundario";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum of %{0} lowercase letter";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum of %{0} uppercase letter";
"POLICY_MIN_DIGIT" = "Minimum of %{0} digit";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum of %{0} special symbols";
"POLICY_MIN_LENGTH" = "Minimum length of %{0} characters";
"POLICY_MIN_LOWERCASE_LETTER" = "Mínimo de %{0} letra minúscula";
"POLICY_MIN_UPPERCASE_LETTER" = "Mínimo de %{0} letra mayúscula";
"POLICY_MIN_DIGIT" = "Mínimo de %{0} dígito";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Mínimo de %{0} símbolos especiales";
"POLICY_MIN_LENGTH" = "Longitud mínima de %{0} caracteres";
+242
View File
@@ -0,0 +1,242 @@
/* this file is in UTF-8 format! */
/* toolbars */
"Save" = "บันทึก";
"Close" = "ปิด";
"Edit User Rights" = "แก้ไขสิทธิผู้ใช้";
"Home" = "บ้าน";
"Calendar" = "ปฏิทิน";
"Address Book" = "สมุดที่อยู่";
"Mail" = "จดหมาย";
"Preferences" = "การตั้งค่าที่ต้องการ";
"Administration" = "การบริหาร";
"Disconnect" = "ตัดการเชื่อมต่อ";
"Toggle Menu" = "เปิด/ปิดเมนู";
"Right Administration" = "การบริหารจัดการสิทธิ์";
"Log Console (dev.)" = "คอนโซลบันทึก (dev.)";
"User" = "ผู้ใช้";
"Vacation message is enabled" = "ข้อความการพักผ่อนถูกเปิดใช้งาน";
"Help" = "ช่วยเหลือ";
"noJavascriptError" = "SOGo ต้องการ Javascript เพื่อให้ทำงาน โปรดตรวจสอบและเปิดใช้งานตัวเลือกนี้ภายในการตั้งค่าเบราว์เซอร์ของคุณ";
"noJavascriptRetry" = "ลองใหม่";
"Owner" = "เจ้าของ";
"Publish the Free/Busy information" = "เผยแพร่ข้อมูลว่างเสรี/ไม่ว่างเสรี";
"Add..." = "เพิ่ม...";
"Remove" = "ลบ";
"Subscribe User" = "สมัครสมาชิกผู้ใช้";
"Any Authenticated User" = "ผู้ใช้ที่ได้รับการยืนยันตัวตนใด ๆ";
"Public Access" = "การเข้าถึงสาธารณะ";
"Any user not listed above" = "ผู้ใช้ที่ไม่ได้ระบุไว้ในรายชื่อด้านบน";
"Anybody accessing this resource from the public area" = "ใครก็ตามที่เข้าถึงทรัพยากรนี้จากพื้นที่สาธารณะ";
"Sorry, the user rights can not be configured for that object." = "ขอโทษครับ ไม่สามารถกำหนดสิทธิ์ผู้ใช้สำหรับวัตถุดังกล่าวได้";
"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?"
= "ใครก็ตามที่มีบัญชีบนระบบนี้จะสามารถเข้าถึงกล่องจดหมายของคุณ \"%{0}\" ได้ คุณแน่ใจหรือว่าคุณไว้ใจพวกเขาทั้งหมด?";
"Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?"
= "ใครก็ตามที่มีบัญชีบนระบบนี้จะสามารถเข้าถึงปฏิทินของคุณ \"%{0}\" ได้ คุณแน่ใจหรือว่าคุณไว้ใจพวกเขาทั้งหมด?";
"Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
= "ใครก็ตามบนอินเทอร์เน็ตอาจสามารถเข้าถึงปฏิทินของคุณ \"%{0}\" ได้ แม้ว่าพวกเขาจะไม่มีบัญชีในระบบนี้เลย ข้อมูลนี้เหมาะสำหรับอินเทอร์เน็ตสาธารณะหรือไม่?";
"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?"
= "ใครก็ตามที่มีบัญชีบนระบบนี้จะสามารถเข้าถึงสมุดที่อยู่ของคุณ \"%{0}\" ได้ คุณแน่ใจหรือว่าคุณไว้ใจพวกเขาทั้งหมด?";
"Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
= "ใครก็ตามบนอินเทอร์เน็ตอาจสามารถเข้าถึงสมุดที่อยู่ของคุณ \"%{0}\" ได้ แม้ว่าพวกเขาจะไม่มีบัญชีในระบบนี้เลย ข้อมูลนี้เหมาะสำหรับอินเทอร์เน็ตสาธารณะหรือไม่?";
"Give Access" = "ให้สิทธิ์เข้าถึง";
"Keep Private" = "เก็บเป็นความลับ";
"Expand" = "ขยาย";
"Reduce" = "ลดลง";
/* tooltip */
"Refresh" = "รีเฟรช";
/* generic.js */
"Unable to subscribe to that folder!"
= "ไม่สามารถสมัครสมาชิกในโฟลเดอร์นั้นได้!";
"You cannot subscribe to a folder that you own!"
= "คุณไม่สามารถสมัครสมาชิกในโฟลเดอร์ที่คุณเป็นเจ้าของ!";
"Unable to unsubscribe from that folder!"
= "ไม่สามารถยกเลิกการสมัครสมาชิกจากโฟลเดอร์นั้นได้!";
"You cannot unsubscribe from a folder that you own!"
= "คุณไม่สามารถยกเลิกการสมัครสมาชิกในโฟลเดอร์ที่คุณเป็นเจ้าของ!";
"Unable to rename that folder!" = "ไม่สามารถเปลี่ยนชื่อโฟลเดอร์นั้นได้!";
"You have already subscribed to that folder!"
= "คุณได้สมัครสมาชิกในโฟลเดอร์นั้นแล้ว!";
"The user rights cannot be edited for this object!"
= "ไม่สามารถแก้ไขสิทธิ์ของผู้ใช้สำหรับวัตถุนี้ได้!";
"A folder by that name already exists." = "มีโฟลเดอร์ด้วยชื่อนั้นอยู่แล้ว";
"You cannot create a list in a shared address book."
= "คุณไม่สามารถสร้างรายการในสมุดที่อยู่ร่วมกันได้";
"Warning" = "คำเตือน";
"Can't contact server" = "เกิดข้อผิดพลาดขึ้นในขณะที่ติดต่อกับเซิร์ฟเวอร์ โปรดลองอีกครั้งในภายหลัง";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "คุณไม่ได้รับอนุญาตให้เข้าถึงโมดูลหรือระบบนี้ โปรดติดต่อผู้ดูแลระบบของคุณ";
"You don't have the required privileges to perform the operation."
= "คุณไม่มีสิทธิ์ที่จำเป็นในการดำเนินการ";
"noEmailForDelegation" = "คุณต้องระบุที่อยู่ที่คุณต้องการมอบหมายให้กับคำเชิญของคุณ";
"delegate is organizer" = "ผู้แทนเป็นผู้จัดงาน โปรดระบุผู้แทนอื่น";
"delegate is a participant" = "ผู้แทนถูกเข้าร่วมอยู่แล้ว.";
"delegate is a group" = "ที่อยู่ที่ระบุตรงกับกลุ่ม คุณสามารถมอบหมายให้กับบุคคลที่เป็นเอกลักษณ์เท่านั้น";
/* common buttons */
"OK" = "ตกลง";
"Cancel" = "ยกเลิก";
"Yes" = "ใช่";
"No" = "ไม่";
/* generic messages */
"Error" = "ข้อผิดพลาด";
"Success" = "สำเร็จ";
/* confirmation dialog box */
"Confirmation" = "ยืนยัน";
/* alarms */
"Reminder" = "เตือนความจำ";
"Start" = "เริ่ม";
"Due Date" = "วันครบกำหนด";
"Location" = "สถานที่";
"Snooze" = "หลับตา";
"Snooze for " = "Snooze for";
"5 minutes" = "5 นาที";
"10 minutes" = "10 นาที";
"15 minutes" = "15 นาที";
"30 minutes" = "30 นาที";
"45 minutes" = "45 นาที";
"1 hour" = "1 ชั่วโมง";
"1 day" = "1 วัน";
/* mail labels */
"Important" = "สำคัญ";
"Work" = "งาน";
"Personal" = "ส่วนตัว";
"To Do" = "ทำ";
"Later" = "หลังจากนั้น";
"Forwarded" = "ส่งต่อ";
"Return Receipt Sent" = "ใบตอบรับการส่งได้รับแล้ว";
"a2_Sunday" = "อา";
"a2_Monday" = "จ";
"a2_Tuesday" = "อ";
"a2_Wednesday" = "พ";
"a2_Thursday" = "พฤ";
"a2_Friday" = "ศ";
"a2_Saturday" = "ส";
"Access Rights" = "สิทธิ์การเข้าถึง";
"Add User" = "เพิ่มผู้ใช้";
"Loading" = "โหลด";
"No such user." = "ไม่มีผู้ใช้งานดังกล่าว";
"You cannot (un)subscribe to a folder that you own!" = "คุณไม่สามารถสมัครสมาชิกในโฟลเดอร์ที่คุณเป็นเจ้าของ!";
/* SMIME Certificate field */
"S/MIME Certificate" = "ใบรับรอง S/MIME";
"Subject Name" = "ชื่อเรื่อง";
"Issuer" = "ผู้ออก";
"streetAddress" = "ถนน";
"stateOrProvinceName" = "รัฐหรือจังหวัด";
"localityName" = "สถานที่";
"countryName" = "ประเทศ";
"organizationName" = "องค์กร";
"organizationalUnitName" = "หน่วยงานองค์กร";
"commonName" = "ชื่อทั่วไป";
"surname" = "นามสกุล";
"givenName" = "ชื่อจริง";
"emailAddress" = "ที่อยู่อีเมล์";
/* Authentication username */
"Username" = "ชื่อผู้ใช้";
/* Authentication password */
"Password" = "รหัสผ่าน";
/* Authentication failed */
"Wrong username or password." = "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง.";
/* Error message displayed bellow search field when the search string has less than the required number of characters */
"Enter at least %{minimumSearchLength} characters" = "ป้อนอย่างน้อย %{minimumSearchLength} ตัวอักษร";
/* Error message displayed when a file upload exceeds WOMaxUploadSize */
"File size upload limit reached" = "ขนาดไฟล์ที่อัปโหลดเกินขีดจำกัด";
/* Generic server error */
"An error occured, please try again." = "เกิดข้อผิดพลาด โปรดลองอีกครั้ง";
/* Open datepicker */
"Open Calendar" = "เปิดปฏิทิน";
/* Toggle visibility (ex: mail account in left navigation menu) */
"Toggle visibility" = "เปลี่ยนการมองเห็น";
"Keyboard Shortcuts" = "แป้นพิมพ์ลัด";
/* Aria label for avatar button to select and unselect an item */
"Toggle item" = "เปิด-ปิดรายการ";
/* Toggle multiple items at the same time (hotkeys cheatsheet) */
"Toggle range of items" = "เปลี่ยนสถานะของรายการ";
/* Question mark shows list of hotkeys */
"Show or hide this help" = "แสดงหรือซ่อนความช่วยเหลือนี้";
/* Space key */
"key_space" = "พื้นที่";
/* Delete key */
"key_delete" = "ลบ";
/* Shift and space key */
"key_shift+space" = "shift + space";
/* Up arrow key */
"key_up" = "↑";
/* Down arrow key */
"key_down" = "↓";
/* Left arrow key */
"key_left" = "←";
/* Right arrow key */
"key_right" = "→";
/* Shift and up arrow combo keys */
"key_shift+up" = "shift + ↑";
/* Shift and down arrow combo keys */
"key_shift+down" = "shift + ↓";
/* Backspace key */
"key_backspace" = "⌫";
/* Hotkey to start a search */
"hotkey_search" = "s";
/* Hotkey description to select next list item */
"View next item" = "ดูรายการถัดไป";
/* Hotkey description to select previous list item */
"View previous item" = "ดูรายการก่อนหน้า";
/* Hotkey description to add next list item to selection */
"Add next item to selection" = "เพิ่มรายการถัดไปในการเลือก";
/* Hotkey description to add previous list item to selection */
"Add previous item to selection" = "เพิ่มรายการก่อนหน้านี้ในการเลือก";
/* Hotkey description to move backward in current view */
"Move backward" = "ย้ายถอยหลัง";
/* Hotkey description to move forward in current view */
"Move forward" = "เคลื่อนไปข้างหน้า";
/* Password Recovery */
"passwordRecovery_Disabled" = "ปิดการใช้งาน";
"passwordRecovery_SecretQuestion" = "คำถามลับ";
"passwordRecovery_SecretQuestion1" = "ชื่อสัตว์เลี้ยงครั้งแรกของคุณคืออะไร?";
"passwordRecovery_SecretQuestion2" = "คุณมีรถคันแรกของคุณอยู่ที่ไหน?";
"passwordRecovery_SecretQuestion3" = "หนังเรื่องไหนเป็นหนังที่คุณชื่นชอบ?";
"passwordRecovery_SecondaryEmail" = "อีเมลสำรอง";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "อักษรตัวพิมพ์เล็กขั้นต่ำ %{0} ตัว";
"POLICY_MIN_UPPERCASE_LETTER" = "อักษรตัวตัวพิมพ์ใหญ่ขั้นต่ำ %{0} ตัว";
"POLICY_MIN_DIGIT" = "ตัวเลขขั้นต่ำ %{0} หลัก";
"POLICY_MIN_SPECIAL_SYMBOLS" = "สัญลักษณ์พิเศษขั้นต่ำ %{0} ตัว";
"POLICY_MIN_LENGTH" = "ความยาวขั้นต่ำ %{0} ตัว";
@@ -235,8 +235,8 @@
"passwordRecovery_SecondaryEmail" = "İkincil e-posta";
/* Password */
"POLICY_MIN_LOWERCASE_LETTER" = "Minimum of %{0} lowercase letter";
"POLICY_MIN_UPPERCASE_LETTER" = "Minimum of %{0} uppercase letter";
"POLICY_MIN_DIGIT" = "Minimum of %{0} digit";
"POLICY_MIN_SPECIAL_SYMBOLS" = "Minimum of %{0} special symbols";
"POLICY_MIN_LENGTH" = "Minimum length of %{0} characters";
"POLICY_MIN_LOWERCASE_LETTER" = "En az %{0} küçük harf";
"POLICY_MIN_UPPERCASE_LETTER" = "En az %{0} büyük harf";
"POLICY_MIN_DIGIT" = "En az %{0} rakam";
"POLICY_MIN_SPECIAL_SYMBOLS" = "En az %{0} özel simge";
"POLICY_MIN_LENGTH" = "En az %{0} karakter uzunluğunda";
@@ -193,11 +193,11 @@
"Work" = "Feina";
"Mobile" = "Mòbil";
"Pager" = "Cercapersones";
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
"Download iOS - MacOS configuration profile" = "Descarregar perfil de configuració iOS - MacOS";
/* categories */
"contacts_category_labels" = "Colleague, Competitor, Customer, Friend, Family, Business Partner, Provider, Press, VIP";
"New category" = "New category";
"contacts_category_labels" = "Col·lega, Competidor, Client, Amic, Família, Soci, Proveïdor, Premsa, VIP";
"New category" = "Nova categoria";
/* adresses */
"Title" = "Títol";
@@ -222,7 +222,7 @@
"New Addressbook..." = "Nova llibreta d'adreces";
"Subscribe to an Addressbook..." = "Subscribiure's a una llibreta...";
"Remove the selected Addressbook" = "Esborrar la llibreta seleccionada";
"Subscribe to a shared contact" = "Subscribe to a shared addressbook";
"Subscribe to a shared contact" = "Subscriure's a una llibreta compartida";
"Search User" = "Cerca usuari";
"Name of the Address Book" = "Nom de la llibreta";
"Are you sure you want to delete the selected address book?"
@@ -351,7 +351,7 @@
"Synchronization" = "Sincronització";
"Synchronize" = "Sincronitzar";
"Sucessfully subscribed to address book" = "S'ha subscrit correctament a la llibreta d'adreces";
"A similar card already exists. Would you like to save it anyway?" = "A similar card already exists. Would you like to save it anyway?";
"A similar card already exists. Would you like to save it anyway?" = "Ja existeix un contacte similar. Voleu desar-lo igualment?";
/* Aria label for scope of search on contacts */
"Search scope" = " Abast de la cerca ";
+1 -1
View File
@@ -193,7 +193,7 @@
"Work" = "Werk";
"Mobile" = "Mobiel";
"Pager" = "Pieper";
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuratieprofiel";
/* categories */
"contacts_category_labels" = "Collega, Concurrent, Klant, Vriend, Familie, Zakenpartner, Leverancier, Pers, VIP";
+366
View File
@@ -0,0 +1,366 @@
/* this file is in UTF-8 format! */
"Contact" = "Contact";
"Address" = "Address";
"Photos" = "Photos";
"Other" = "Other";
"Address Books" = "Address Books";
"Addressbook" = "Addressbook";
"Addresses" = "Addresses";
"Update" = "Update";
"Cancel" = "Cancel";
"Common" = "Common";
"Contact editor" = "Contact editor";
"Contact viewer" = "Contact viewer";
"Email" = "Email";
"Screen Name" = "Screen Name";
"Extended" = "Extended";
"Fax" = "Fax";
"Firstname" = "Firstname";
"Home" = "Home";
"HomePhone" = "HomePhone";
"Lastname" = "Lastname";
"Location" = "Location";
"Add a category" = "Add a category";
"MobilePhone" = "MobilePhone";
"Name" = "Name";
"OfficePhone" = "OfficePhone";
"Organization" = "Organization";
"Work Phone" = "Work Phone";
"Cell" = "Cell";
"Pager" = "Pager";
"Pref" = "Pref";
"Phone" = "Phone";
"Phones" = "Phones";
"Postal" = "Postal";
"Save" = "Save";
"Internet" = "Internet";
"Unit" = "Unit";
"delete" = "delete";
"edit" = "edit";
"invalidemailwarn" = "The specified email is invalid";
"new" = "new";
"Preferred Phone" = "Preferred Phone";
"Move To" = "Move To";
"Copy To" = "Copy To";
"Add to" = "Add to";
"To" = "To";
"Carbon Copy (Cc)" = "Carbon Copy (Cc)";
"Blind Carbon Copy (Bcc)" = "Blind Carbon Copy (Bcc)";
/* Search scope: name fields */
"name" = "Name";
/* Search scope: name fields */
"c_cn" = "Name";
/* Search scope: secondary email field */
"mozillanickname" = "Secondary email";
/* Search scope: screen name field */
"nsaimid" = "Screen name";
/* Search scope: mail fields */
"mail" = "Mail";
/* Search scope: mail fields */
"c_mail" = "Mail";
/* Search scope: telephone field */
"telephonenumber" = "Telephone";
/* Search scope: telephone field */
"homephone" = "Telephone";
/* Search scope: mobile field */
"mobile" = "Mobile";
/* Search scope: fax field */
"facsimiletelephonenumber" = "Fax";
/* Search scope: pager field */
"pager" = "Pager";
/* Search scope: categories field */
"c_categories" = "Categories";
/* Search scope: categories field */
"vcardcategories" = "Categories";
/* Search scope: title field */
"title" = "Title";
/* Search scope: organization field */
"c_o" = "Organization";
/* Search scope: organization field */
"o" = "Organization";
/* Search scope: department field */
"ou" = "Department";
/* Search scope: city field */
"l" = "City";
/* Search scope: country field */
"c" = "Country";
/* Search scope: home address field */
"mozillahomestreet" = "Home Address";
/* Search scope: state/province field */
"st" = "State/Province";
/* Search scope: home state/province field */
"mozillahomestate" = "Home State/Province";
/* Search scope: zip/postal code field */
"postalCode" = "Zip/Postal Code";
/* Search scope: home zip/postal code field */
"mozillahomepostalcode" = "Zip/Postal Code";
/* Search scope: home country field */
"mozillahomecountryname" = "Home Country";
/* Search scope: home web page field */
"mozillahomeurl" = "Home page";
/* Search scope: work web page field */
"mozillaworkurl" = "Web page";
/* Search scope: note field */
"description" = "Note";
/* Subheader of empty addressbook */
"No contact" = "No contact";
/* Subheader of system addressbook */
"Start a search to browse this address book" = "Start a search to browse this address book";
/* Number of contacts in addressbook; string is prefixed by number */
"contacts" = "contacts";
/* No contact matching search criteria */
"No matching contact" = "No matching contact";
/* Number of contacts matching search criteria; string is prefixed by number */
"matching contacts" = "matching contacts";
/* Number of selected contacts in list */
"selected" = "selected";
/* Empty right pane */
"No contact selected" = "No contact selected";
/* Tooltips */
"Create a new address book card" = "Create a new address book card";
"Create a new list" = "Create a new list";
"Edit the selected card" = "Edit the selected card";
"Send a mail message" = "Send a mail message";
"Delete selected card or address book" = "Delete selected card or address book";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Unknown";
"htmlMailFormat_FALSE" = "Plain Text";
"htmlMailFormat_TRUE" = "HTML";
"Name or Email" = "Name or Email";
"Category" = "Category";
"Personal Addressbook" = "Personal Addressbook";
"Search in Addressbook" = "Search in Addressbook";
"New Card" = "New Card";
"New List" = "New List";
"Edit" = "Edit";
"Properties" = "Properties";
"Sharing..." = "Sharing...";
"Write" = "Write";
"Delete" = "Delete";
"Instant Message" = "Instant Message";
"Add..." = "Add...";
"Remove" = "Remove";
"Please wait..." = "Please wait...";
"No possible subscription" = "No possible subscription";
"Preferred" = "Preferred";
"Display" = "Display";
"Display Name" = "Display Name";
"Additional Email" = "Additional Email";
"Phone Number" = "Phone Number";
"Prefers to receive messages formatted as" = "Prefers to receive messages formatted as";
"Categories" = "Categories";
"First" = "First";
"Last" = "Last";
"Nickname" = "Nickname";
"Telephone" = "Telephone";
"Work" = "Work";
"Mobile" = "Mobile";
"Pager" = "Pager";
"Download iOS - MacOS configuration profile" = "Download iOS - MacOS configuration profile";
/* categories */
"contacts_category_labels" = "Colleague, Competitor, Customer, Friend, Family, Business Partner, Provider, Press, VIP";
"New category" = "New category";
/* adresses */
"Title" = "Title";
"Service" = "Service";
"Company" = "Company";
"Department" = "Department";
"City" = "City ";
"State_Province" = "State/Province";
"ZIP_Postal Code" = "ZIP/Postal Code";
"Country" = "Country";
"Web Page" = "Web Page";
"Other Infos" = "Other Infos";
"Note" = "Note";
"Timezone" = "Timezone";
"Birthday" = "Birthday";
"Birthday (yyyy-mm-dd)" = "Birthday (yyyy-mm-dd)";
"Freebusy URL" = "Freebusy URL";
"Add as..." = "Add as...";
"Recipient" = "Recipient";
"Carbon Copy" = "Carbon Copy";
"Blind Carbon Copy" = "Blind Carbon Copy";
"New Addressbook..." = "New Addressbook...";
"Subscribe to an Addressbook..." = "Subscribe to an Addressbook...";
"Remove the selected Addressbook" = "Remove the selected Addressbook";
"Subscribe to a shared contact" = "Subscribe to a shared addressbook";
"Search User" = "Search User";
"Name of the Address Book" = "Name of the Address Book";
"Are you sure you want to delete the selected address book?"
= "Are you sure you want to delete the selected address book?";
"Are you sure you want to delete the addressbook \"%{0}\"?"
= "Are you sure you want to delete the addressbook \"%{0}\"?";
"You cannot remove nor unsubscribe from a public addressbook."
= "You cannot remove nor unsubscribe from a public addressbook.";
"You cannot remove nor unsubscribe from your personal addressbook."
= "You cannot remove nor unsubscribe from your personal addressbook.";
"Are you sure you want to delete the selected contacts?"
= "Are you sure you want to delete the selected contacts?";
"Are you sure you want to delete the card of %{0}?" = "Are you sure you want to delete the card of %{0}?";
"You cannot delete the card of \"%{0}\"."
= "You cannot delete the card of \"%{0}\".";
"You cannot subscribe to a folder that you own!"
= "You cannot subscribe to a folder that you own.";
"Unable to subscribe to that folder!"
= "Unable to subscribe to that folder.";
/* security */
"Security" = "Security";
"Uninstall" = "Uninstall";
"Error reading the card certificate." = "Error reading the card certificate.";
"No certificate associated to card." = "No certificate associated to card.";
/* acls */
"Access rights to" = "Access rights to";
"For user" = "For user";
"Any Authenticated User" = "Any Authenticated User";
"Public Access" = "Public Access";
"This person can add cards to this addressbook."
= "This person can add cards to this addressbook.";
"This person can edit the cards of this addressbook."
= "This person can edit the cards of this addressbook.";
"This person can list the content of this addressbook."
= "This person can list the content of this addressbook.";
"This person can read the cards of this addressbook."
= "This person can read the cards of this addressbook.";
"This person can erase cards from this addressbook."
= "This person can erase cards from this addressbook.";
"The selected contact has no email address."
= "The selected contact has no email address.";
"Please select a contact." = "Please select a contact.";
/* Messages for move and copy */
"%{0} card(s) copied" = "%{0} card(s) copied";
"%{0} card(s) moved" = "%{0} card(s) moved";
"SoAccessDeniedException" = "You cannot write to this address book.";
"Forbidden" = "Forbidden";
"Invalid Contact" = "The selected contact no longer exists.";
"Unknown Destination Folder" = "The chosen destination address book no longer exists.";
/* Lists */
"List details" = "List details";
"List name" = "List name";
"List nickname" = "List nickname";
"List description" = "List description";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";
"Lists can't be moved or copied." = "Lists can't be moved or copied.";
"Export" = "Export";
"Export Address Book..." = "Export Address Book...";
"View Raw Source" = "View Raw Source";
/* Import */
"Import Cards" = "Import Cards";
"Select a vCard or LDIF file." = "Select a vCard or LDIF file.";
"Upload" = "Upload";
"Uploading" = "Uploading";
"Done" = "Done";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"No card was imported." = "No card was imported.";
"A total of %{0} cards were imported in the addressbook." = "A total of %{0} cards were imported in the addressbook.";
"Reload" = "Reload";
/* Properties window */
"Address Book Name" = "Address Book Name";
"Links to this Address Book" = "Links to this Address Book";
"Authenticated User Access" = "Authenticated User Access";
"CardDAV URL" = "CardDAV URL";
"Options" = "Options";
"Rename" = "Rename";
"Subscriptions" = "Subscriptions";
"Global Addressbooks" = "Global Addressbooks";
"Search" = "Search";
"Sort" = "Sort";
"Descending Order" = "Descending Order";
"Back" = "Back";
"Select All" = "Select All";
"Copy contacts" = "Copy contacts";
"More messages options" = "More messages options";
"New Contact" = "New Contact";
"Close" = "Close";
"More contact options" = "More contact options";
"Organization Unit" = "Organization Unit";
"Add Organizational Unit" = "Add Organizational Unit";
"Type" = "Type";
"Email Address" = "Email Address";
"New Email Address" = "New Email Address";
"New Phone Number" = "New Phone Number";
"URL" = "URL";
"New URL" = "New URL";
"street" = "street";
"street (continued)" = "street (continued)";
"Postoffice" = "Postoffice";
"Region" = "Region";
"Postal Code" = "Postal Code";
"New Address" = "New Address";
"Reset" = "Reset";
"Description" = "Description";
"Add Member" = "Add Member";
"Subscribe" = "Subscribe";
"Add Birthday" = "Add Birthday";
"Import" = "Import";
"More options" = "More options";
"Role" = "Role";
"Add Screen Name" = "Add Screen Name";
"Custom 1" = "Custom 1";
"Custom 2" = "Custom 2";
"Custom 3" = "Custom 3";
"Custom 4" = "Custom 4";
"Custom Value" = "Custom Value";
"New Custom Value" = "New Custom Value";
"Synchronization" = "Synchronization";
"Synchronize" = "Synchronize";
"Sucessfully subscribed to address book" = "Successfully subscribed to address book";
"A similar card already exists. Would you like to save it anyway?" = "A similar card already exists. Would you like to save it anyway?";
/* Aria label for scope of search on contacts */
"Search scope" = "Search scope";
/* Aria label for avatar button to select and unselect a card */
"Toggle item" = "Toggle item";
/* Hotkey to create a new card */
"key_create_card" = "c";
/* Hotkey to create a new list */
"key_create_list" = "l";
@@ -0,0 +1,366 @@
/* this file is in UTF-8 format! */
"Contact" = "연락처";
"Address" = "주소";
"Photos" = "사진";
"Other" = "기타";
"Address Books" = "주소록";
"Addressbook" = "주소록";
"Addresses" = "주소";
"Update" = "업데이트";
"Cancel" = "취소";
"Common" = "공통";
"Contact editor" = "연락처 편집기";
"Contact viewer" = "연락처 뷰어";
"Email" = "이메일";
"Screen Name" = "스크린 이름";
"Extended" = "확장";
"Fax" = "팩스";
"Firstname" = "이름";
"Home" = "집";
"HomePhone" = "집 전화";
"Lastname" = "성";
"Location" = "위치";
"Add a category" = "카테고리 추가";
"MobilePhone" = "휴대폰";
"Name" = "이름";
"OfficePhone" = "회사 전화";
"Organization" = "기관";
"Work Phone" = "직장 전화";
"Cell" = "휴대폰";
"Pager" = "호출기";
"Pref" = "기본";
"Phone" = "전화";
"Phones" = "전화번호";
"Postal" = "우편";
"Save" = "저장";
"Internet" = "인터넷";
"Unit" = "단위";
"delete" = "삭제";
"edit" = "편집";
"invalidemailwarn" = "지정된 이메일이 유효하지 않습니다";
"new" = "새로 만들기";
"Preferred Phone" = "기본 전화번호";
"Move To" = "이동";
"Copy To" = "복사";
"Add to" = "추가";
"To" = "받는 사람";
"Carbon Copy (Cc)" = "참조 (Cc)";
"Blind Carbon Copy (Bcc)" = "숨은 참조 (Bcc)";
/* Search scope: name fields */
"name" = "이름";
/* Search scope: name fields */
"c_cn" = "이름";
/* Search scope: secondary email field */
"mozillanickname" = "보조 이메일";
/* Search scope: screen name field */
"nsaimid" = "스크린 이름";
/* Search scope: mail fields */
"mail" = "메일";
/* Search scope: mail fields */
"c_mail" = "메일";
/* Search scope: telephone field */
"telephonenumber" = "전화";
/* Search scope: telephone field */
"homephone" = "전화";
/* Search scope: mobile field */
"mobile" = "모바일";
/* Search scope: fax field */
"facsimiletelephonenumber" = "팩스";
/* Search scope: pager field */
"pager" = "호출기";
/* Search scope: categories field */
"c_categories" = "카테고리";
/* Search scope: categories field */
"vcardcategories" = "카테고리";
/* Search scope: title field */
"title" = "직함";
/* Search scope: organization field */
"c_o" = "기관";
/* Search scope: organization field */
"o" = "기관";
/* Search scope: department field */
"ou" = "부서";
/* Search scope: city field */
"l" = "도시";
/* Search scope: country field */
"c" = "국가";
/* Search scope: home address field */
"mozillahomestreet" = "집 주소";
/* Search scope: state/province field */
"st" = "주/도";
/* Search scope: home state/province field */
"mozillahomestate" = "집 주/도";
/* Search scope: zip/postal code field */
"postalCode" = "우편/우편번호";
/* Search scope: home zip/postal code field */
"mozillahomepostalcode" = "우편/우편번호";
/* Search scope: home country field */
"mozillahomecountryname" = "집 국가";
/* Search scope: home web page field */
"mozillahomeurl" = "홈페이지";
/* Search scope: work web page field */
"mozillaworkurl" = "웹 페이지";
/* Search scope: note field */
"description" = "메모";
/* Subheader of empty addressbook */
"No contact" = "연락처 없음";
/* Subheader of system addressbook */
"Start a search to browse this address book" = "이 주소록을 탐색하려면 검색을 시작하십시오";
/* Number of contacts in addressbook; string is prefixed by number */
"contacts" = "연락처";
/* No contact matching search criteria */
"No matching contact" = "일치하는 연락처 없음";
/* Number of contacts matching search criteria; string is prefixed by number */
"matching contacts" = "일치하는 연락처";
/* Number of selected contacts in list */
"selected" = "선택됨";
/* Empty right pane */
"No contact selected" = "선택된 연락처 없음";
/* Tooltips */
"Create a new address book card" = "새 주소록 카드 만들기";
"Create a new list" = "새 목록 만들기";
"Edit the selected card" = "선택한 카드 편집";
"Send a mail message" = "메일 메시지 보내기";
"Delete selected card or address book" = "선택한 카드 또는 주소록 삭제";
"Reload all contacts" = "모든 연락처 새로고침";
"htmlMailFormat_UNKNOWN" = "알 수 없음";
"htmlMailFormat_FALSE" = "일반 텍스트";
"htmlMailFormat_TRUE" = "HTML";
"Name or Email" = "이름 또는 이메일";
"Category" = "카테고리";
"Personal Addressbook" = "개인 주소록";
"Search in Addressbook" = "주소록 검색";
"New Card" = "새 카드";
"New List" = "새 목록";
"Edit" = "편집";
"Properties" = "속성";
"Sharing..." = "공유...";
"Write" = "쓰기";
"Delete" = "삭제";
"Instant Message" = "인스턴트 메시지";
"Add..." = "추가...";
"Remove" = "제거";
"Please wait..." = "기다려 주십시오...";
"No possible subscription" = "구독할 수 없음";
"Preferred" = "기본";
"Display" = "표시";
"Display Name" = "표시 이름";
"Additional Email" = "추가 이메일";
"Phone Number" = "전화번호";
"Prefers to receive messages formatted as" = "선호하는 메시지 형식";
"Categories" = "카테고리";
"First" = "이름";
"Last" = "성";
"Nickname" = "별명";
"Telephone" = "전화";
"Work" = "직장";
"Mobile" = "휴대폰";
"Pager" = "호출기";
"Download iOS - MacOS configuration profile" = "iOS - MacOS 구성 프로필 다운로드";
/* categories */
"contacts_category_labels" = "동료, 경쟁사, 고객, 친구, 가족, 비즈니스 파트너, 공급업체, 언론, VIP";
"New category" = "새 카테고리";
/* adresses */
"Title" = "직함";
"Service" = "서비스";
"Company" = "회사";
"Department" = "부서";
"City" = "도시";
"State_Province" = "주/도";
"ZIP_Postal Code" = "우편/우편번호";
"Country" = "국가";
"Web Page" = "웹 페이지";
"Other Infos" = "기타 정보";
"Note" = "메모";
"Timezone" = "시간대";
"Birthday" = "생일";
"Birthday (yyyy-mm-dd)" = "생일 (yyyy-mm-dd)";
"Freebusy URL" = "약속 가능/불가능 URL";
"Add as..." = "다음으로 추가...";
"Recipient" = "받는 사람";
"Carbon Copy" = "참조";
"Blind Carbon Copy" = "숨은 참조";
"New Addressbook..." = "새 주소록...";
"Subscribe to an Addressbook..." = "주소록 구독...";
"Remove the selected Addressbook" = "선택한 주소록 제거";
"Subscribe to a shared contact" = "공유 주소록 구독";
"Search User" = "사용자 검색";
"Name of the Address Book" = "주소록 이름";
"Are you sure you want to delete the selected address book?"
= "선택한 주소록을 삭제하시겠습니까?";
"Are you sure you want to delete the addressbook \"%{0}\"?"
= "주소록 \"%{0}\"을 삭제하시겠습니까?";
"You cannot remove nor unsubscribe from a public addressbook."
= "공개 주소록은 제거하거나 구독 취소할 수 없습니다.";
"You cannot remove nor unsubscribe from your personal addressbook."
= "개인 주소록은 제거하거나 구독 취소할 수 없습니다.";
"Are you sure you want to delete the selected contacts?"
= "선택한 연락처를 삭제하시겠습니까?";
"Are you sure you want to delete the card of %{0}?" = "%{0}의 카드를 삭제하시겠습니까?";
"You cannot delete the card of \"%{0}\"."
= "\"%{0}\"의 카드를 삭제할 수 없습니다.";
"You cannot subscribe to a folder that you own!"
= "소유하고 있는 폴더는 구독할 수 없습니다.";
"Unable to subscribe to that folder!"
= "해당 폴더를 구독할 수 없습니다.";
/* security */
"Security" = "보안";
"Uninstall" = "제거";
"Error reading the card certificate." = "카드 인증서 읽기 오류.";
"No certificate associated to card." = "카드와 연결된 인증서가 없습니다.";
/* acls */
"Access rights to" = "접근 권한 대상";
"For user" = "사용자";
"Any Authenticated User" = "모든 인증된 사용자";
"Public Access" = "공개 접근";
"This person can add cards to this addressbook."
= "이 사람은 이 주소록에 카드를 추가할 수 있습니다.";
"This person can edit the cards of this addressbook."
= "이 사람은 이 주소록의 카드를 편집할 수 있습니다.";
"This person can list the content of this addressbook."
= "이 사람은 이 주소록의 내용을 나열할 수 있습니다.";
"This person can read the cards of this addressbook."
= "이 사람은 이 주소록의 카드를 읽을 수 있습니다.";
"This person can erase cards from this addressbook."
= "이 사람은 이 주소록에서 카드를 지울 수 있습니다.";
"The selected contact has no email address."
= "선택한 연락처에 이메일 주소가 없습니다.";
"Please select a contact." = "연락처를 선택하십시오.";
/* Messages for move and copy */
"%{0} card(s) copied" = "%{0}개 카드 복사됨";
"%{0} card(s) moved" = "%{0}개 카드 이동됨";
"SoAccessDeniedException" = "이 주소록에 쓸 수 없습니다.";
"Forbidden" = "금지됨";
"Invalid Contact" = "선택한 연락처가 더 이상 존재하지 않습니다.";
"Unknown Destination Folder" = "선택한 대상 주소록이 더 이상 존재하지 않습니다.";
/* Lists */
"List details" = "목록 세부 정보";
"List name" = "목록 이름";
"List nickname" = "목록 별명";
"List description" = "목록 설명";
"Members" = "회원";
"Contacts" = "연락처";
"Add" = "추가";
"Lists can't be moved or copied." = "목록은 이동하거나 복사할 수 없습니다.";
"Export" = "내보내기";
"Export Address Book..." = "주소록 내보내기...";
"View Raw Source" = "원본 내용 보기";
/* Import */
"Import Cards" = "카드 가져오기";
"Select a vCard or LDIF file." = "vCard 또는 LDIF 파일을 선택하십시오.";
"Upload" = "업로드";
"Uploading" = "업로드 중";
"Done" = "완료";
"An error occured while importing contacts." = "연락처 가져오기 중 오류가 발생했습니다.";
"No card was imported." = "가져온 카드가 없습니다.";
"A total of %{0} cards were imported in the addressbook." = "총 %{0}개의 카드가 주소록으로 가져와졌습니다.";
"Reload" = "새로고침";
/* Properties window */
"Address Book Name" = "주소록 이름";
"Links to this Address Book" = "이 주소록 링크";
"Authenticated User Access" = "인증된 사용자 접근";
"CardDAV URL" = "CardDAV URL";
"Options" = "옵션";
"Rename" = "이름 변경";
"Subscriptions" = "구독";
"Global Addressbooks" = "전역 주소록";
"Search" = "검색";
"Sort" = "정렬";
"Descending Order" = "내림차순";
"Back" = "뒤로";
"Select All" = "모두 선택";
"Copy contacts" = "연락처 복사";
"More messages options" = "더 많은 메시지 옵션";
"New Contact" = "새 연락처";
"Close" = "닫기";
"More contact options" = "더 많은 연락처 옵션";
"Organization Unit" = "조직 단위";
"Add Organizational Unit" = "조직 단위 추가";
"Type" = "유형";
"Email Address" = "이메일 주소";
"New Email Address" = "새 이메일 주소";
"New Phone Number" = "새 전화번호";
"URL" = "URL";
"New URL" = "새 URL";
"street" = "거리";
"street (continued)" = "거리 (계속)";
"Postoffice" = "우체국";
"Region" = "지역";
"Postal Code" = "우편번호";
"New Address" = "새 주소";
"Reset" = "재설정";
"Description" = "설명";
"Add Member" = "멤버 추가";
"Subscribe" = "구독";
"Add Birthday" = "생일 추가";
"Import" = "가져오기";
"More options" = "더 많은 옵션";
"Role" = "역할";
"Add Screen Name" = "스크린 이름 추가";
"Custom 1" = "사용자 지정 1";
"Custom 2" = "사용자 지정 2";
"Custom 3" = "사용자 지정 3";
"Custom 4" = "사용자 지정 4";
"Custom Value" = "사용자 지정 값";
"New Custom Value" = "새 사용자 지정 값";
"Synchronization" = "동기화";
"Synchronize" = "동기화";
"Sucessfully subscribed to address book" = "주소록 구독 성공";
"A similar card already exists. Would you like to save it anyway?" = "유사한 카드가 이미 존재합니다. 그래도 저장하시겠습니까?";
/* Aria label for scope of search on contacts */
"Search scope" = "검색 범위";
/* Aria label for avatar button to select and unselect a card */
"Toggle item" = "항목 전환";
/* Hotkey to create a new card */
"key_create_card" = "c";
/* Hotkey to create a new list */
"key_create_list" = "l";
+366
View File
@@ -0,0 +1,366 @@
/* this file is in UTF-8 format! */
"Contact" = "ผู้ติดต่อ";
"Address" = "ที่อยู่";
"Photos" = "รูปภาพ";
"Other" = "อื่นๆ";
"Address Books" = "สมุดรายชื่อ";
"Addressbook" = "สมุดที่อยู่";
"Addresses" = "ที่อยู่";
"Update" = "อัปเดต";
"Cancel" = "ยกเลิก";
"Common" = "ทั่วไป";
"Contact editor" = "ติดต่อบรรณาธิการ";
"Contact viewer" = "ผู้ดูแลรายชื่อติดต่อ";
"Email" = "อีเมล";
"Screen Name" = "ชื่อหน้าจอ";
"Extended" = "ขยายออก";
"Fax" = "แฟกซ์";
"Firstname" = "ชื่อจริง";
"Home" = "บ้าน";
"HomePhone" = "โทรศัพท์บ้าน";
"Lastname" = "นามสกุล";
"Location" = "สถานที่";
"Add a category" = "เพิ่มหมวดหมู่";
"MobilePhone" = "โทรศัพท์มือถือ";
"Name" = "ชื่อ";
"OfficePhone" = "โทรศัพท์ในสำนักงาน";
"Organization" = "องค์กร";
"Work Phone" = "โทรศัพท์ที่ใช้ในการทำงาน";
"Cell" = "เซลล์";
"Pager" = "เพจเจอร์";
"Pref" = "การตั้งค่า";
"Phone" = "โทรศัพท์";
"Phones" = "โทรศัพท์";
"Postal" = "ไปรษณีย์";
"Save" = "บันทึก";
"Internet" = "อินเทอร์เน็ต";
"Unit" = "หน่วย";
"delete" = "ลบ";
"edit" = "แก้ไข";
"invalidemailwarn" = "ระบุอีเมลที่ระบุไม่ถูกต้อง";
"new" = "ใหม่";
"Preferred Phone" = "โทรศัพท์ที่ต้องการ";
"Move To" = "ย้ายไป";
"Copy To" = "คัดลอกไปยัง";
"Add to" = "เพิ่มเข้าไป";
"To" = "ถึง";
"Carbon Copy (Cc)" = "คัดลอกคาร์บอน (Cc)";
"Blind Carbon Copy (Bcc)" = "สำเนาบนซองที่มองไม่เห็น (Bcc)";
/* Search scope: name fields */
"name" = "ชื่อ";
/* Search scope: name fields */
"c_cn" = "ชื่อ";
/* Search scope: secondary email field */
"mozillanickname" = "อีเมลสำรอง";
/* Search scope: screen name field */
"nsaimid" = "ชื่อหน้าจอ";
/* Search scope: mail fields */
"mail" = "อีเมล";
/* Search scope: mail fields */
"c_mail" = "อีเมล";
/* Search scope: telephone field */
"telephonenumber" = "โทรศัพท์";
/* Search scope: telephone field */
"homephone" = "โทรศัพท์";
/* Search scope: mobile field */
"mobile" = "มือถือ";
/* Search scope: fax field */
"facsimiletelephonenumber" = "แฟกซ์";
/* Search scope: pager field */
"pager" = "เพจเจอร์";
/* Search scope: categories field */
"c_categories" = "หมวดหมู่";
/* Search scope: categories field */
"vcardcategories" = "หมวดหมู่";
/* Search scope: title field */
"title" = "หัวข้อ";
/* Search scope: organization field */
"c_o" = "องค์กร";
/* Search scope: organization field */
"o" = "องค์กร";
/* Search scope: department field */
"ou" = "แผนก";
/* Search scope: city field */
"l" = "เมือง";
/* Search scope: country field */
"c" = "ประเทศ";
/* Search scope: home address field */
"mozillahomestreet" = "ที่อยู่บ้าน";
/* Search scope: state/province field */
"st" = "รัฐ/จังหวัด";
/* Search scope: home state/province field */
"mozillahomestate" = "รัฐ/จังหวัดบ้าน";
/* Search scope: zip/postal code field */
"postalCode" = "รหัสไปรษณีย์";
/* Search scope: home zip/postal code field */
"mozillahomepostalcode" = "รหัสไปรษณีย์";
/* Search scope: home country field */
"mozillahomecountryname" = "ประเทศบ้าน";
/* Search scope: home web page field */
"mozillahomeurl" = "หน้าหลัก";
/* Search scope: work web page field */
"mozillaworkurl" = "หน้าเว็บ";
/* Search scope: note field */
"description" = "หมายเหตุ";
/* Subheader of empty addressbook */
"No contact" = "ไม่มีการติดต่อ";
/* Subheader of system addressbook */
"Start a search to browse this address book" = "เริ่มการค้นหาเพื่อเรียกดูสมุดที่อยู่นี้";
/* Number of contacts in addressbook; string is prefixed by number */
"contacts" = "ผู้ติดต่อ";
/* No contact matching search criteria */
"No matching contact" = "ไม่พบผู้ติดต่อที่ตรงกัน";
/* Number of contacts matching search criteria; string is prefixed by number */
"matching contacts" = "การจับคู่ผู้ติดต่อ";
/* Number of selected contacts in list */
"selected" = "เลือก";
/* Empty right pane */
"No contact selected" = "ไม่มีการเลือกติดต่อ";
/* Tooltips */
"Create a new address book card" = "สร้างบัตรสมุดที่อยู่ใหม่";
"Create a new list" = "สร้างรายการใหม่";
"Edit the selected card" = "แก้ไขการ์ดที่เลือก";
"Send a mail message" = "ส่งข้อความอีเมล์";
"Delete selected card or address book" = "ลบบัตรหรือสมุดที่อยู่ที่เลือก";
"Reload all contacts" = "โหลดข้อมูลทั้งหมดใหม่";
"htmlMailFormat_UNKNOWN" = "ไม่ทราบ";
"htmlMailFormat_FALSE" = "ข้อความธรรมดา";
"htmlMailFormat_TRUE" = "HTML";
"Name or Email" = "ชื่อหรืออีเมล์";
"Category" = "หมวดหมู่";
"Personal Addressbook" = "สมุดที่อยู่ส่วนตัว";
"Search in Addressbook" = "ค้นหาในสมุดที่อยู่";
"New Card" = "บัตรใหม่";
"New List" = "รายการใหม่";
"Edit" = "แก้ไข";
"Properties" = "คุณสมบัติ";
"Sharing..." = "แชร์...";
"Write" = "เขียน";
"Delete" = "ลบ";
"Instant Message" = "ข้อความสารบัญ: ข้อความทันที";
"Add..." = "เพิ่ม...";
"Remove" = "ลบ";
"Please wait..." = "กรุณารอสักครู่...";
"No possible subscription" = "ไม่มีการสมัครสมาชิกเป็นไปได้";
"Preferred" = "ต้องการ";
"Display" = "แสดงผล";
"Display Name" = "ชื่อที่แสดง";
"Additional Email" = "อีเมลเพิ่มเติม";
"Phone Number" = "หมายเลขโทรศัพท์";
"Prefers to receive messages formatted as" = "ต้องการรับข้อความที่จัดรูปแบบเป็น";
"Categories" = "หมวดหมู่";
"First" = "แรก";
"Last" = "สุดท้าย";
"Nickname" = "ชื่อเล่น";
"Telephone" = "โทรศัพท์";
"Work" = "งาน";
"Mobile" = "มือถือ";
"Pager" = "เพจเจอร์";
"Download iOS - MacOS configuration profile" = "ดาวน์โหลดโปรไฟล์การกำหนดค่า iOS - MacOS";
/* categories */
"contacts_category_labels" = "เพื่อนร่วมงาน, คู่แข่ง, ลูกค้า, เพื่อน, ครอบครัว, พันธมิตรทางธุรกิจ, ผู้ให้บริการ, สื่อ, บุคคลสำคัญ";
"New category" = "หมวดหมู่ใหม่";
/* adresses */
"Title" = "หัวข้อ";
"Service" = "บริการ";
"Company" = "บริษัท";
"Department" = "แผนก";
"City" = "เมือง";
"State_Province" = "รัฐ/จังหวัด";
"ZIP_Postal Code" = "รหัสไปรษณีย์";
"Country" = "ประเทศ";
"Web Page" = "หน้าเว็บ";
"Other Infos" = "อื่น ๆ ข้อมูล";
"Note" = "หมายเหตุ";
"Timezone" = "เขตเวลา";
"Birthday" = "วันเกิด";
"Birthday (yyyy-mm-dd)" = "วันเกิด (yyyy-mm-dd)";
"Freebusy URL" = "URL ที่สามารถใช้งานได้ฟรี";
"Add as..." = "เพิ่มเป็น...";
"Recipient" = "ผู้รับ";
"Carbon Copy" = "สำเนาคาร์บอน";
"Blind Carbon Copy" = "สำเนาบนซองอีเมล";
"New Addressbook..." = "สมุดที่อยู่ใหม่...";
"Subscribe to an Addressbook..." = "รับข้อมูลอัปเดตจากสมุดรายชื่อ...";
"Remove the selected Addressbook" = "ลบสมุดรายชื่อที่เลือก";
"Subscribe to a shared contact" = "สมัครสมาชิกสมุดรายชื่อที่ใช้ร่วมกัน";
"Search User" = "ค้นหาผู้ใช้";
"Name of the Address Book" = "ชื่อสมุดที่อยู่";
"Are you sure you want to delete the selected address book?"
= "คุณแน่ใจหรือว่าต้องการลบสมุดที่อยู่ที่เลือกไว้?";
"Are you sure you want to delete the addressbook \"%{0}\"?"
= "คุณแน่ใจหรือไม่ว่าต้องการลบสมุดที่อยู่ \"%{0}\"?";
"You cannot remove nor unsubscribe from a public addressbook."
= "คุณไม่สามารถลบหรือยกเลิกการสมัครสมาชิกจากสมุดที่อยู่สาธารณะได้";
"You cannot remove nor unsubscribe from your personal addressbook."
= "คุณไม่สามารถลบหรือยกเลิกการสมัครสมาชิกจากสมุดที่อยู่ส่วนตัวของคุณได้";
"Are you sure you want to delete the selected contacts?"
= "คุณแน่ใจหรือว่าต้องการลบรายชื่อที่เลือกไว้?";
"Are you sure you want to delete the card of %{0}?" = "คุณแน่ใจหรือไม่ว่าต้องการลบบัตรของ %{0}?";
"You cannot delete the card of \"%{0}\"."
= "คุณไม่สามารถลบบัตรของ \"%{0}\" ได้";
"You cannot subscribe to a folder that you own!"
= "คุณไม่สามารถสมัครสมาชิกในโฟลเดอร์ที่คุณเป็นเจ้าของ!";
"Unable to subscribe to that folder!"
= "ไม่สามารถสมัครสมาชิกในโฟลเดอร์นั้นได้.";
/* security */
"Security" = "ความปลอดภัย";
"Uninstall" = "ถอนการติดตั้ง";
"Error reading the card certificate." = "ข้อผิดพลาดในการอ่านใบรับรองของบัตร";
"No certificate associated to card." = "ไม่มีใบรับรองที่เกี่ยวข้องกับบัตร";
/* acls */
"Access rights to" = "สิทธิ์การเข้าถึง";
"For user" = "สำหรับผู้ใช้";
"Any Authenticated User" = "ผู้ใช้ที่ได้รับการยืนยันตัวตนใด ๆ";
"Public Access" = "การเข้าถึงสาธารณะ";
"This person can add cards to this addressbook."
= "บุคคลนี้สามารถเพิ่มบัตรเข้าสู่สมุดที่อยู่นี้ได้";
"This person can edit the cards of this addressbook."
= "บุคคลนี้สามารถแก้ไขบัตรของสมุดที่อยู่นี้ได้";
"This person can list the content of this addressbook."
= "บุคคลนี้สามารถรายการเนื้อหาของสมุดที่อยู่นี้ได้";
"This person can read the cards of this addressbook."
= "บุคคลนี้สามารถอ่านบัตรของสมุดที่อยู่นี้ได้.";
"This person can erase cards from this addressbook."
= "บุคคลนี้สามารถลบบัตรออกจากสมุดที่อยู่นี้ได้.";
"The selected contact has no email address."
= "ผู้ติดต่อที่เลือกไม่มีที่อยู่อีเมล์";
"Please select a contact." = "โปรดเลือกติดต่อ";
/* Messages for move and copy */
"%{0} card(s) copied" = "มีการคัดลอกบัตร %{0} ใบ";
"%{0} card(s) moved" = "มีการย้ายบัตร %{0} ใบ";
"SoAccessDeniedException" = "คุณไม่สามารถเขียนไปยังสมุดที่อยู่นี้ได้";
"Forbidden" = "เข้าถึงไม่ได้";
"Invalid Contact" = "คุณติดต่อที่เลือกไม่มีอยู่แล้ว";
"Unknown Destination Folder" = "ที่อยู่สมุดที่เลือกไว้ไม่มีอยู่แล้ว";
/* Lists */
"List details" = "รายละเอียดรายการ";
"List name" = "ชื่อรายการ";
"List nickname" = "รายชื่อเล่น";
"List description" = "รายละเอียดของรายการ";
"Members" = "สมาชิก";
"Contacts" = "ผู้ติดต่อ";
"Add" = "เพิ่ม";
"Lists can't be moved or copied." = "รายการไม่สามารถย้ายหรือคัดลอกได้";
"Export" = "ส่งออก";
"Export Address Book..." = "ส่งออกสมุดที่อยู่...";
"View Raw Source" = "ดูแหล่งที่มาแบบเรียลไทม์";
/* Import */
"Import Cards" = "นำเข้าการ์ด";
"Select a vCard or LDIF file." = "เลือกไฟล์ vCard หรือ LDIF";
"Upload" = "อัปโหลด";
"Uploading" = "กำลังอัปโหลด";
"Done" = "เสร็จแล้ว";
"An error occured while importing contacts." = "เกิดข้อผิดพลาดขณะนำเข้ารายชื่อผู้ติดต่อ";
"No card was imported." = "ไม่มีการนำเข้าบัตร";
"A total of %{0} cards were imported in the addressbook." = "จำนวนทั้งหมด %{0} บัตรถูกนำเข้าในสมุดที่อยู่";
"Reload" = "รีโหลด";
/* Properties window */
"Address Book Name" = "ชื่อสมุดที่อยู่";
"Links to this Address Book" = "ลิงค์ไปยังสมุดที่อยู่นี้";
"Authenticated User Access" = "การเข้าถึงผู้ใช้ที่ได้รับการรับรองแล้ว";
"CardDAV URL" = "CardDAV URL";
"Options" = "ตัวเลือก";
"Rename" = "เปลี่ยนชื่อ";
"Subscriptions" = "การสมัครสมาชิก";
"Global Addressbooks" = "สมุดที่อยู่อีเมลทั่วไป";
"Search" = "ค้นหา";
"Sort" = "เรียงลำดับ";
"Descending Order" = "ลำดับจากมากไปน้อย";
"Back" = "กลับ";
"Select All" = "เลือกทั้งหมด";
"Copy contacts" = "คัดลอกที่ติดต่อ";
"More messages options" = "ตัวเลือกข้อความเพิ่มเติม";
"New Contact" = "ติดต่อใหม่";
"Close" = "ปิด";
"More contact options" = "ตัวเลือกการติดต่อเพิ่มเติม";
"Organization Unit" = "หน่วยงานองค์กร";
"Add Organizational Unit" = "เพิ่มหน่วยงานองค์กร";
"Type" = "ประเภท";
"Email Address" = "ที่อยู่อีเมล์";
"New Email Address" = "ที่อยู่อีเมลใหม่";
"New Phone Number" = "หมายเลขโทรศัพท์ใหม่";
"URL" = "URL";
"New URL" = "New URL";
"street" = "ถนน";
"street (continued)" = "ถนน (ต่อไป)";
"Postoffice" = "ไปรษณีย์";
"Region" = "ภูมิภาค";
"Postal Code" = "รหัสไปรษณีย์";
"New Address" = "ที่อยู่ใหม่";
"Reset" = "รีเซ็ต";
"Description" = "คำอธิบาย";
"Add Member" = "เพิ่มสมาชิก";
"Subscribe" = "สมัครสมาชิก";
"Add Birthday" = "เพิ่มวันเกิด";
"Import" = "นำเข้า";
"More options" = "ตัวเลือกเพิ่มเติม";
"Role" = "บทบาท";
"Add Screen Name" = "เพิ่มชื่อหน้าจอ";
"Custom 1" = "กำหนดเอง 1";
"Custom 2" = "กำหนดเอง 2";
"Custom 3" = "กำหนดเอง 3";
"Custom 4" = "กำหนดเอง 4";
"Custom Value" = "ค่าที่กำหนดเอง";
"New Custom Value" = "ค่าที่กำหนดเองใหม่";
"Synchronization" = "การประสานข้อมูล";
"Synchronize" = "ซิงโครไนซ์";
"Sucessfully subscribed to address book" = "สมัครสมาชิกที่สมุดที่อยู่เรียบร้อยแล้ว";
"A similar card already exists. Would you like to save it anyway?" = "มีบัตรที่คล้ายกันอยู่แล้ว คุณต้องการบันทึกมันอยู่หรือไม่?";
/* Aria label for scope of search on contacts */
"Search scope" = "ขอบเขตการค้นหา";
/* Aria label for avatar button to select and unselect a card */
"Toggle item" = "เปิด-ปิดรายการ";
/* Hotkey to create a new card */
"key_create_card" = "c";
/* Hotkey to create a new list */
"key_create_list" = "l";
+1 -1
View File
@@ -485,7 +485,7 @@ static Class SOGoContactGCSEntryK = Nil;
co = [self clientObject];
card = [co vCard];
request = [context request];
params = [[request contentAsString] objectFromJSONString];
params = [[[request contentAsString] stringWithoutHTMLInjection: YES] objectFromJSONString];
forceSave = [[params objectForKey: @"ignoreDuplicate"] boolValue];
[self setAttributes: params];
+18 -10
View File
@@ -78,6 +78,14 @@
NSArray *cats, *newCats, *contactCategories;
ownerLogin = [[self clientObject] ownerInContext: context];
//if ownerLogin == @"nobody", meaning the current folder is not the personnal source of the user (it's the global address book)
//No need to fetch the user "nobody". Beware that if someone is really called nobody...
if([ownerLogin isEqualToString:@"nobody"])
{
cats = [self _languageContactsCategories];
return cats;
}
ud = [[SOGoUser userWithLogin: ownerLogin] userDefaults];
cats = [ud contactsCategories];
if (!cats)
@@ -85,16 +93,16 @@
contactCategories = [card categories];
if (contactCategories)
{
newCats = [cats mergedArrayWithArray: [contactCategories trimmedComponents]];
if ([newCats count] != [cats count])
{
cats = [newCats sortedArrayUsingSelector:
@selector (localizedCaseInsensitiveCompare:)];
[ud setContactsCategories: cats];
[ud synchronize];
}
}
{
newCats = [cats mergedArrayWithArray: [contactCategories trimmedComponents]];
if ([newCats count] != [cats count])
{
cats = [newCats sortedArrayUsingSelector:
@selector (localizedCaseInsensitiveCompare:)];
[ud setContactsCategories: cats];
[ud synchronize];
}
}
return cats;
}
+1 -1
View File
@@ -339,7 +339,7 @@
[list retain];
request = [context request];
params = [[request contentAsString] objectFromJSONString];
params = [[[request contentAsString] stringWithoutHTMLInjection: YES] objectFromJSONString];
o = [params objectForKey: @"refs"];
if (![o isKindOfClass: [NSArray class]])
@@ -47,4 +47,4 @@ reply_info = "Dit is een antwoord op een door u verstuurde uitnodiging.";
"OK" = "OK";
"Comment" = "Commentaar:";
"Description" = "Omschrijving";
"Location" = "Location";
"Location" = "Locatie";
@@ -0,0 +1,50 @@
ACCEPTED = "accepted";
COMPLETED = "completed";
DECLINED = "declined";
DELEGATED = "delegated";
"IN-PROCESS" = "in process";
"NEEDS-ACTION" = "needs action";
TENTATIVE = "tentative";
organized_by_you = "organized by you";
you_are_an_attendee = "you are an attendee";
add_info_text = "iMIP 'ADD' requests are not yet supported by SOGo.";
publish_info_text = "The sender informs you of the attached event.";
cancel_info_text = "Your invitation or the whole event was canceled.";
request_info_no_attendee = "is proposing a meeting to the attendees. You receive this mail as a notification, you are not scheduled as a participant.";
Appointment = "Appointment";
"Status Update" = "Status Update";
was = "was";
Organizer = "Organizer";
Time = "Time";
Attendees = "Attendees";
request_info = "invites you to participate in a meeting.";
"Add to calendar" = "Add to calendar";
"Delete from calendar" = "Delete from calendar";
"Update status" = "Update status";
Accept = "Accept";
Decline = "Decline";
Tentative = "Tentative";
"Delegate ..." = "Delegate ...";
"Delegated to" = "Delegated to";
"Update status in calendar" = "Update status in calendar";
"delegated from" = "delegated from";
reply_info_no_attendee = "You received a reply to a scheduling event but the sender of the reply is not a participant.";
reply_info = "This is a reply to an event invitation done by you.";
"to" = "to";
"Untitled" = "Untitled";
"Size" = "Size";
"Subject" = "Subject";
"From" = "From";
"Date" = "Date";
"To" = "To";
"Issuer" = "Issuer";
/* Tooltips */
"View Attachment" = "View Attachment";
"Save Attachment" = "Save Attachment";
"CC" = "CC";
"Cancel" = "Cancel";
"OK" = "OK";
"Comment" = "Comment";
"Description" = "Description";
"Location" = "Location";
@@ -0,0 +1,50 @@
ACCEPTED = "수락됨";
COMPLETED = "완료됨";
DECLINED = "거절됨";
DELEGATED = "위임됨";
"IN-PROCESS" = "진행 중";
"NEEDS-ACTION" = "조치 필요";
TENTATIVE = "미정";
organized_by_you = "귀하가 주최함";
you_are_an_attendee = "귀하는 참석자입니다";
add_info_text = "iMIP '추가' 요청은 아직 SOGo에서 지원되지 않습니다.";
publish_info_text = "보낸 사람이 첨부된 이벤트를 알려드립니다.";
cancel_info_text = "귀하의 초대 또는 전체 이벤트가 취소되었습니다.";
request_info_no_attendee = "참석자에게 회의를 제안합니다. 귀하는 알림으로 이 메일을 받으셨으며, 참가자로 예정되지 않았습니다.";
Appointment = "약속";
"Status Update" = "상태 업데이트";
was = "였습니다";
Organizer = "주최자";
Time = "시간";
Attendees = "참석자";
request_info = "회의에 귀하를 초대합니다.";
"Add to calendar" = "캘린더에 추가";
"Delete from calendar" = "캘린더에서 삭제";
"Update status" = "상태 업데이트";
Accept = "수락";
Decline = "거절";
Tentative = "미정";
"Delegate ..." = "위임...";
"Delegated to" = "위임 대상";
"Update status in calendar" = "캘린더에서 상태 업데이트";
"delegated from" = "위임됨";
reply_info_no_attendee = "일정 이벤트에 대한 회신을 받았지만 회신 보낸 사람은 참가자가 아닙니다.";
reply_info = "이것은 귀하가 보낸 이벤트 초대에 대한 회신입니다.";
"to" = "받는 사람";
"Untitled" = "제목 없음";
"Size" = "크기";
"Subject" = "제목";
"From" = "보낸 사람";
"Date" = "날짜";
"To" = "받는 사람";
"Issuer" = "발급자";
/* Tooltips */
"View Attachment" = "첨부 파일 보기";
"Save Attachment" = "첨부 파일 저장";
"CC" = "참조";
"Cancel" = "취소";
"OK" = "확인";
"Comment" = "설명";
"Description" = "설명";
"Location" = "장소";
@@ -47,4 +47,4 @@ reply_info = "To jest odpowiedź do utworzonego przez ciebie wydarzenia";
"OK" = "OK";
"Comment" = "Komentarz";
"Description" = "Opis";
"Location" = "Location";
"Location" = "Położenie";
@@ -0,0 +1,50 @@
ACCEPTED = "ยอมรับ";
COMPLETED = "เสร็จสิ้น";
DECLINED = "ปฏิเสธ";
DELEGATED = "มอบหมายงาน";
"IN-PROCESS" = "ในกระบวนการ";
"NEEDS-ACTION" = "ต้องการการดำเนินการ";
TENTATIVE = "ไม่สามารถแปลได้";
organized_by_you = "จัดระเบียบโดยคุณ";
you_are_an_attendee = "คุณเป็นผู้เข้าร่วม";
add_info_text = "iMIP 'ADD' ยังไม่ได้รับการสนับสนุนโดย SOGo.";
publish_info_text = "ผู้ส่งข้อมูลแจ้งให้คุณทราบเกี่ยวกับเหตุการณ์ที่แนบมา";
cancel_info_text = "คำเชิญของคุณหรืองานทั้งหมดถูกยกเลิก";
request_info_no_attendee = "เสนอการประชุมกับผู้เข้าร่วม คุณได้รับอีเมลนี้เป็นการแจ้งเตือน คุณไม่ได";
Appointment = "การนัดหมาย";
"Status Update" = "สถานะการอัปเดต";
was = "ก่อนหน้านี้";
Organizer = "ผู้จัดงาน";
Time = "เวลา";
Attendees = "ผู้เข้าร่วม";
request_info = "เชิญคุณมาร่วมประชุม";
"Add to calendar" = "เพิ่มลงในปฏิทิน";
"Delete from calendar" = "ลบจากปฏิทิน";
"Update status" = "อัปเดตสถานะ";
Accept = "ยอมรับ";
Decline = "ปฏิเสธ";
Tentative = "ไม่สามารถแปลได้";
"Delegate ..." = "มอบหมายงาน ...";
"Delegated to" = "มอบหมายงานให้";
"Update status in calendar" = "อัปเดตสถานะในปฏิทิน";
"delegated from" = "มอบหมายโดย";
reply_info_no_attendee = "คุณได้รับการตอบกลับเกี่ยวกับกิจกรรมการจัดตารางแต่ผู้ส่งการตอบกลับไม่ใช่ผู้เข้าร่วม";
reply_info = "นี่คือการตอบกลับเชิญเข้าร่วมกิจกรรมที่คุณทำ";
"to" = "ถึง";
"Untitled" = "ไม่มีชื่อ";
"Size" = "ขนาด";
"Subject" = "หัวข้อ";
"From" = "จาก";
"Date" = "วันที่";
"To" = "ถึง";
"Issuer" = "ผู้ออก";
/* Tooltips */
"View Attachment" = "ดูไฟล์แนบ";
"Save Attachment" = "บันทึกไฟล์แนบ";
"CC" = "CC";
"Cancel" = "ยกเลิก";
"OK" = "ตกลง";
"Comment" = "ความคิดเห็น";
"Description" = "คำอธิบาย";
"Location" = "ที่อยู่";
+55 -55
View File
@@ -3,7 +3,7 @@
/* Icon's label */
"Create" = "Redactar";
"Empty Trash" = "Buidar paperera";
"Empty Junk Folder" = "Empty Junk Folder";
"Empty Junk Folder" = "Buidar carpeta de correu brossa";
"Delete" = "Esborrar";
"Expunge" = "Compactar";
"Forward" = "Reenviar";
@@ -79,7 +79,7 @@
"Folder compacted" = "carpeta compactada";
/* Empty Junk Folder success message */
"Junk folder emptied" = "Junk folder emptied";
"Junk folder emptied" = "S'ha buidat la carpeta de correu brossa";
/* Empty Trash success message */
"Trash emptied" = "S'ha buidat la paperera";
@@ -88,7 +88,7 @@
"Access rights to" = "Drets d'accés a";
"For user" = "Per a l'usuari";
"Any Authenticated User" = "Qualsevol usuari autenticat";
"View this folder" = "View this folder";
"View this folder" = "Veure aquesta carpeta";
"Read mails from this folder" = "Llegir corrreu d'aquesta carpeta";
"Mark mails read and unread" = "Marcar correus com a llegits o no llegits";
"Modify the flags of the mails in this folder" = "Modificar les marques dels correus en aquesta carpeta";
@@ -143,23 +143,23 @@
"This mail is being sent from an unsecure network!" = "Aquest missatge s'envia des d'una xarxa no segura.";
"Address Book" = "Llibreta d'adreces";
"Search For" = "Cercar";
"Contains" = "Contains";
"Does not contains" = "Does not contains";
"Advanced search" = "Advanced search";
"Anytime" = "Anytime";
"Last 7 days" = "Last 7 days";
"Last 30 days" = "Last 30 days";
"Last 6 month" = "Last 6 month";
"Before" = "Before";
"After" = "After";
"Between" = "Between";
"and" = "and";
"With attachments" = "With attachments";
"In favorites" = "In favorites";
"Unseen only" = "Unseen only";
"Show more" = "Show more";
"Reset" = "Reset";
"Message size" = "Message size";
"Contains" = "Conté";
"Does not contains" = "No conté";
"Advanced search" = "Cerca avançada";
"Anytime" = "Qualsevol moment";
"Last 7 days" = "Últims 7 dies";
"Last 30 days" = "Últims 30 dies";
"Last 6 month" = "Últims 6 mesos";
"Before" = "Abans de";
"After" = "Després de";
"Between" = "Entre";
"and" = "i";
"With attachments" = "Amb adjunts";
"In favorites" = "Als preferits";
"Unseen only" = "Només no llegits";
"Show more" = "Mostrar més";
"Reset" = "Restablir";
"Message size" = "Mida del missatge";
/* Popup "show" */
"all" = "tot";
@@ -171,7 +171,7 @@
/* MailListView */
"Sender" = "Remitent";
"Subject or Sender" = "Assumpte o remitent";
"Subject or Recipient" = "Subject or Recipient";
"Subject or Recipient" = "Assumpte o destinatari";
"To or Cc" = "Per a o CC";
"Entire Message" = "Missatge complet";
"Date" = "Data";
@@ -191,13 +191,13 @@
"Untitled" = "Sense títol";
/* Filter option in messages list */
"Show unread messages only" = "Show unread messages only";
"Show unread messages only" = "Mostrar només missatges no llegits";
/* Filter option in messages list */
"Show flagged messages only" = "Show flagged messages only";
"Show flagged messages only" = "Mostrar només missatges marcats";
/* Aria label for icon of labels */
"Filtered by label" = "Filtered by label";
"Filtered by label" = "Filtrat per etiqueta";
/* Tree */
"SentFolderName" = "Enviats";
@@ -205,7 +205,7 @@
"InboxFolderName" = "Safata d'entrada";
"DraftsFolderName" = "Esborranys";
"JunkFolderName" = "Correu brossa";
"TemplatesFolderName" = "Templates";
"TemplatesFolderName" = "Plantilles";
"SieveFolderName" = "Filtres";
"Folders" = "Carpetes"; /* title line */
@@ -257,7 +257,7 @@
"Save As..." = "Desar com a...";
"Print Preview" = "Vista preliminar";
"View Message Source" = "Veure format original del missatge";
"View raw message" = "View raw message";
"View raw message" = "Veure missatge sense format";
/* Message view "more" menu: create an event from message */
"Convert To Event" = "Converteix a esdeveniment";
@@ -266,10 +266,10 @@
"Convert To Task" = "Converteix a tasca";
/* Message view "more" menu: download message as an eml file */
"Download message" = "Download message";
"Download message" = "Descarregar missatge";
/* Message view "more" menu: download message as a zip archive */
"Download message (zip)" = "Download message (zip)";
"Download message (zip)" = "Descarregar missatge (zip)";
/* Message view "more" menu: download all attachments as a zip archive */
"Download all attachments" = "Descarrega tots els adjunts";
@@ -317,16 +317,16 @@
"No certificate associated to account." = "No hi ha cap certificat associat al compte.";
/* Invalid S/MIME signature */
"Digital signature is not valid" = "Digital signature is not valid";
"Digital signature is not valid" = "La signatura digital no és vàlida";
/* Valid S/MIME signature */
"Message is signed" = "Message is signed";
"Message is signed" = "El missatge està signat";
/* Valid S/MIME signature but common name not found */
"Message is signed but the certificate doesn't match the sender email address" = "Message is signed but the certificate doesn't match the sender email address";
"Message is signed but the certificate doesn't match the sender email address" = "El missatge està signat però el certificat no coincideix amb l'adreça de correu del remitent";
/* Unknown error while validating message signature */
"Digital signature is not valid" = "Digital signature is not valid";
"Digital signature is not valid" = "La signatura digital no és vàlida";
"This Folder" = "Aquesta carpeta";
@@ -410,10 +410,10 @@
"Error while saving the draft" = "Error en guardar l'esborrany";
/* Error when emptying trash */
"Unable to empty the trash folder." = "Unable to empty the trash folder.";
"Unable to empty the trash folder." = "No s'ha pogut buidar la paperera.";
/* Error when emptying junk folder */
"Unable to empty the junk folder." = "Unable to empty the junk folder.";
"Unable to empty the junk folder." = "No s'ha pogut buidar la carpeta de correu brossa.";
/* Error when uploading a file attachment */
"Error while uploading the file \"%{0}\":" = "Error en carregar el fitxer \"%{0}\":";
@@ -429,9 +429,9 @@
"cannot send message: (smtp) all recipients discarded" = "No s'ha pogut enviar el missatge: tots els destinataris són incorrectes.";
"cannot send message (smtp) - recipients discarded" = "No s'ha pogut enviar el missatge. Les següents adreces són incorrectes";
"cannot send message: (smtp) error when connecting" = "No s'ha pogut enviar el missatge. Error al connectar amb el servidor SMTP.";
"cannot sign email without certificate" = "The message can't be signed because there's no certificate associated to the mail account.";
"cannot sign message because the certificate can't be read" = "The message can't be signed becasue the certificate associated to the mail account can't be read.";
"cannot sign message because the certificate doesn't include the specified sender address" = "The message can't be signed because the sender address is not included in the certificate associated to the mail account.";
"cannot sign email without certificate" = "El missatge no es pot signar perquè no hi ha cap certificat associat al compte de correu.";
"cannot sign message because the certificate can't be read" = "El missatge no es pot signar perquè no es pot llegir el certificat associat al compte de correu.";
"cannot sign message because the certificate doesn't include the specified sender address" = "El missatge no es pot signar perquè l'adreça del remitent no està inclosa al certificat associat al compte de correu.";
/* Contacts list in mail editor */
"Email" = "Correu electrònic";
@@ -452,7 +452,7 @@
"Set as Trash" = "Establir com a Paperera";
/* Set the folder as the one holding the Templates */
"Set as Templates" = "Set as Templates";
"Set as Templates" = "Establir com a Plantilles";
/* Set the folder as the one holding Junk mails */
"Set as Junk" = "Estableix com a correu brossa";
@@ -464,7 +464,7 @@
"Copy messages" = "Copiar els missatges";
"More messages options" = "Més opcions de missatges";
"Flag" = "Afegir estrella";
"Unflag" = "Unflag";
"Unflag" = "Treure estrella";
"Mark as Unread" = "Marca com a no llegit";
"Mark as Read" = "Marca com a llegit";
"Closing Window ..." = "Tancant la finestra ...";
@@ -478,10 +478,10 @@
"Your email has been sent" = "El teu email s'ha enviat";
"Folder compacted" = "carpeta compactada";
"More Options" = "More Options";
"More Options" = "Més opcions";
"New draft" = "New draft";
"Create new draft with this template" = "Create new draft with this template";
"New draft" = "Nou esborrany";
"Create new draft with this template" = "Crear nou esborrany amb aquesta plantilla";
/* Advanced search */
"Enter Subject" = "Introduïu l'Assumpte";
@@ -517,16 +517,16 @@
"hotkey_forward" = "f";
/* Email deletion */
"Clean folder" = "Clean folder";
"Clean mailbox" = "Clean mailbox";
"Delete permanently (do not use trash)" = "Delete permanently (do not use trash)";
"Apply to subfolders" = "Apply to subfolders";
"Delete e-mails older than" = "Delete e-mails older than";
"3 months" = "3 months";
"6 months" = "6 months";
"9 months" = "9 months";
"1 year" = "1 year";
"Custom" = "Custom";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "You are about to permanently delete some messages. Are you sure you want to proceed with this action?";
"Apply" = "Apply";
"%{0} message(s) deleted" = "%{0} message(s) deleted";
"Clean folder" = "Netejar carpeta";
"Clean mailbox" = "Netejar bústia";
"Delete permanently (do not use trash)" = "Esborrar permanentment (sense paperera)";
"Apply to subfolders" = "Aplicar a subcarpetes";
"Delete e-mails older than" = "Esborrar correus més antics de";
"3 months" = "3 mesos";
"6 months" = "6 mesos";
"9 months" = "9 mesos";
"1 year" = "1 any";
"Custom" = "Personalitzat";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "Esteu a punt d'esborrar permanentment alguns missatges. Esteu segur que voleu continuar amb aquesta acció?";
"Apply" = "Aplicar";
"%{0} message(s) deleted" = "%{0} missatge(s) esborrat(s)";
+14 -14
View File
@@ -171,7 +171,7 @@
/* MailListView */
"Sender" = "Odesílatel";
"Subject or Sender" = "Předmět nebo Odesílatel";
"Subject or Recipient" = "Subject or Recipient";
"Subject or Recipient" = "Předmět nebo Příjemce";
"To or Cc" = "Komu nebo Kopie";
"Entire Message" = "Celá zpráva";
"Date" = "Datum";
@@ -517,16 +517,16 @@
"hotkey_forward" = "f";
/* Email deletion */
"Clean folder" = "Clean folder";
"Clean mailbox" = "Clean mailbox";
"Delete permanently (do not use trash)" = "Delete permanently (do not use trash)";
"Apply to subfolders" = "Apply to subfolders";
"Delete e-mails older than" = "Delete e-mails older than";
"3 months" = "3 months";
"6 months" = "6 months";
"9 months" = "9 months";
"1 year" = "1 year";
"Custom" = "Custom";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "You are about to permanently delete some messages. Are you sure you want to proceed with this action?";
"Apply" = "Apply";
"%{0} message(s) deleted" = "%{0} message(s) deleted";
"Clean folder" = "Promazat složku";
"Clean mailbox" = "Promazat schránku";
"Delete permanently (do not use trash)" = "Smazat trvale (přeskočit Koš)";
"Apply to subfolders" = "Použít na podsložky";
"Delete e-mails older than" = "Smazat maily starší než";
"3 months" = "3 měsíce";
"6 months" = "6 měsíců";
"9 months" = "9 měsíců";
"1 year" = "1 rok";
"Custom" = "Vlastní...";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "Tǐmto navždy smažete zprávy. Chcete pokračovat?";
"Apply" = "Použít";
"%{0} message(s) deleted" = "%{0} zpráv smazáno";
+33 -33
View File
@@ -143,23 +143,23 @@
"This mail is being sent from an unsecure network!" = "Deze e-mail wordt verzonden vanaf een onveilig netwerk!";
"Address Book" = "Adresboek";
"Search For" = "Zoek naar";
"Contains" = "Contains";
"Does not contains" = "Does not contains";
"Advanced search" = "Advanced search";
"Anytime" = "Anytime";
"Last 7 days" = "Last 7 days";
"Last 30 days" = "Last 30 days";
"Last 6 month" = "Last 6 month";
"Before" = "Before";
"After" = "After";
"Between" = "Between";
"and" = "and";
"With attachments" = "With attachments";
"In favorites" = "In favorites";
"Unseen only" = "Unseen only";
"Show more" = "Show more";
"Contains" = "bevat";
"Does not contains" = "bevat niet";
"Advanced search" = "Geavanceerd zoeken";
"Anytime" = "Altijd";
"Last 7 days" = "Laatste 7 dagen";
"Last 30 days" = "Laatste 30 dagen";
"Last 6 month" = "Laatste 6 maanden";
"Before" = "Voor";
"After" = "Na";
"Between" = "Tussen";
"and" = "en";
"With attachments" = "Met bijlage";
"In favorites" = "In favorieten";
"Unseen only" = "Alleen ongelezen ";
"Show more" = "Meer weergeven";
"Reset" = "Reset";
"Message size" = "Message size";
"Message size" = "Berichtgrootte";
/* Popup "show" */
"all" = "alle";
@@ -171,7 +171,7 @@
/* MailListView */
"Sender" = "Afzender";
"Subject or Sender" = "Onderwerp of afzender";
"Subject or Recipient" = "Subject or Recipient";
"Subject or Recipient" = "Onderwerp of ontvanger";
"To or Cc" = "Ontvanger (Aan of Cc)";
"Entire Message" = "Volledig bericht";
"Date" = "Datum";
@@ -257,7 +257,7 @@
"Save As..." = "Opslaan als...";
"Print Preview" = "Afdrukvoorbeeld";
"View Message Source" = "Bron bekijken";
"View raw message" = "View raw message";
"View raw message" = "Bekijk onbewerkt bericht";
/* Message view "more" menu: create an event from message */
"Convert To Event" = "Omzetten naar afspraak";
@@ -464,7 +464,7 @@
"Copy messages" = "Kopieer berichten";
"More messages options" = "Meer berichtopties";
"Flag" = "Met vlag";
"Unflag" = "Unflag";
"Unflag" = "Vlag verwijderen";
"Mark as Unread" = "Als ongelezen markeren";
"Mark as Read" = "Markeren als gelezen";
"Closing Window ..." = "Venster sluiten ...";
@@ -478,7 +478,7 @@
"Your email has been sent" = "Uw email is verzonden";
"Folder compacted" = "Map gecomprimeerd";
"More Options" = "More Options";
"More Options" = "Meer opties";
"New draft" = "Nieuw concept";
"Create new draft with this template" = "Maak een nieuw concept met dit sjabloon";
@@ -517,16 +517,16 @@
"hotkey_forward" = "f";
/* Email deletion */
"Clean folder" = "Clean folder";
"Clean mailbox" = "Clean mailbox";
"Delete permanently (do not use trash)" = "Delete permanently (do not use trash)";
"Apply to subfolders" = "Apply to subfolders";
"Delete e-mails older than" = "Delete e-mails older than";
"3 months" = "3 months";
"6 months" = "6 months";
"9 months" = "9 months";
"1 year" = "1 year";
"Custom" = "Custom";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "You are about to permanently delete some messages. Are you sure you want to proceed with this action?";
"Apply" = "Apply";
"%{0} message(s) deleted" = "%{0} message(s) deleted";
"Clean folder" = "Map opschonen";
"Clean mailbox" = "Mailbox opschonen";
"Delete permanently (do not use trash)" = "Permanent verwijderen (niet in de prullenbak gebruiken)";
"Apply to subfolders" = "Toepassen op submappen";
"Delete e-mails older than" = "Verwijder e-mails die ouder zijn dan";
"3 months" = "3 maanden";
"6 months" = "6 maanden";
"9 months" = "9 maanden";
"1 year" = "1 jaar";
"Custom" = "Aangepast";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "U staat op het punt om enkele berichten definitief te verwijderen. Weet u zeker dat u hiermee wilt doorgaan?";
"Apply" = "Toepassen";
"%{0} message(s) deleted" = "%{0} bericht(en) verwijderd";
+532
View File
@@ -0,0 +1,532 @@
/* this file is in UTF-8 format! */
/* Icon's label */
"Create" = "Create";
"Empty Trash" = "Empty Trash";
"Empty Junk Folder" = "Empty Junk Folder";
"Delete" = "Delete";
"Expunge" = "Expunge";
"Forward" = "Forward";
"Get Mail" = "Get Mail";
"Junk" = "Junk";
"Not junk" = "Not junk";
"Reply" = "Reply";
"Reply All" = "Reply All";
"Print" = "Print";
"Stop" = "Stop";
"Write" = "Write";
"Search" = "Search";
"Send" = "Send";
"Contacts" = "Contacts";
"Attach" = "Attach";
"Save" = "Save";
"Options" = "Options";
"Close" = "Close";
"Size" = "Size";
/* Tooltips */
"Send this message now" = "Send this message now";
"Select a recipient from an Address Book" = "Select a recipient from an Address Book";
"Include an attachment" = "Include an attachment";
"Save this message" = "Save this message";
"Get new messages" = "Get new messages";
"Create a new message" = "Create a new message";
"Go to address book" = "Go to address book";
"Reply to the message" = "Reply to the message";
"Reply to sender and all recipients" = "Reply to sender and all recipients";
"Forward selected message" = "Forward selected message";
"Delete selected message or folder" = "Delete selected message or folder";
"Print this message" = "Print this message";
"Stop the current transfer" = "Stop the current transfer";
"Attachment" = "Attachment";
"Unread" = "Unread";
"Flagged" = "Flagged";
"Search multiple mailboxes" = "Search multiple mailboxes";
/* Main Frame */
"Home" = "Home";
"Calendar" = "Calendar";
"Addressbook" = "Address Book";
"Mail" = "Mail";
"Right Administration" = "Right Administration";
"Help" = "Help";
/* Mail account main windows */
"Welcome to the SOGo Mailer. Use the folder tree on the left to browse your mail accounts!" = "Welcome to the SOGo Mailer. Use the folder tree on the left to browse your mail accounts!";
"Read messages" = "Read messages";
/* Tooltip for fab button */
"Write a new message" = "Write a new message";
/* Tooltip for fab button */
"Write a message in new window" = "Write a message in new window";
"Share" = "Share";
"Account" = "Account";
"Shared Account" = "Shared Account";
/* A mailbox is selected, but no message (only shown on large screens) */
"No message selected" = "No message selected";
/* No mailbox is selected (usually resulting from an IMAP connection problem) */
"No mailbox selected" = "No mailbox selected";
"An error occured while communicating with the mail server" = "An error occured while communicating with the mail server";
/* Mailbox actions */
/* Compact Folder success message */
"Folder compacted" = "Folder compacted";
/* Empty Junk Folder success message */
"Junk folder emptied" = "Junk folder emptied";
/* Empty Trash success message */
"Trash emptied" = "Trash emptied";
/* acls */
"Access rights to" = "Access rights to";
"For user" = "For user";
"Any Authenticated User" = "Any Authenticated User";
"View this folder" = "View this folder";
"Read mails from this folder" = "Read mails from this folder";
"Mark mails read and unread" = "Mark mails read and unread";
"Modify the flags of the mails in this folder" = "Modify the flags of the mails in this folder";
"Insert, copy and move mails into this folder" = "Insert, copy and move mails into this folder";
"Post mails" = "Post mails";
"Add subfolders to this folder" = "Add subfolders to this folder";
"Remove this folder" = "Remove this folder";
"Erase mails from this folder" = "Erase mails from this folder";
"Expunge this folder" = "Expunge this folder";
"Export This Folder" = "Export This Folder";
"Modify the acl of this folder" = "Modify the acl of this folder";
"Saved Messages.zip" = "Saved Messages.zip";
"Update" = "Update";
"Cancel" = "Cancel";
/* Mail edition */
"From" = "From";
"Subject" = "Subject";
"To" = "To";
"Cc" = "Cc";
"Bcc" = "Bcc";
"Reply-To" = "Reply-To";
"Add address" = "Add address";
"Body" = "Body";
"Open" = "Open";
"Select All" = "Select All";
"Select Message" = "Select Message";
"Attach Web Page..." = "Attach Web Page...";
"file" = "file";
"files" = "files";
"Save all" = "Save all";
"to" = "To";
"cc" = "Cc";
"bcc" = "Bcc";
"Add a recipient" = "Add a recipient";
"Edit Draft..." = "Edit Draft...";
"Load Images" = "Load Images";
"Return Receipt" = "Return Receipt";
"Choose which identity to send this message from" = "Choose which identity to send this message from";
"The sender of this message has asked to be notified when you read this message. Do you with to notify the sender?" = "The sender of this message has asked to be notified when you read this message. Do you wish to notify the sender?";
"Return Receipt (displayed) - %@"= "Return Receipt (displayed) - %@";
"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents.";
"Security" = "Security";
"Sign" = "Sign";
"Encrypt" = "Encrypt";
"Priority" = "Priority";
"highest" = "Highest";
"high" = "High";
"normal" = "Normal";
"low" = "Low";
"lowest" = "Lowest";
"This mail is being sent from an unsecure network!" = "This mail is being sent from an unsecure network!";
"Address Book" = "Address Book";
"Search For" = "Search For";
"Contains" = "Contains";
"Does not contains" = "Does not contains";
"Advanced search" = "Advanced search";
"Anytime" = "Anytime";
"Last 7 days" = "Last 7 days";
"Last 30 days" = "Last 30 days";
"Last 6 month" = "Last 6 month";
"Before" = "Before";
"After" = "After";
"Between" = "Between";
"and" = "and";
"With attachments" = "With attachments";
"In favorites" = "In favorites";
"Unseen only" = "Unseen only";
"Show more" = "Show more";
"Reset" = "Reset";
"Message size" = "Message size";
/* Popup "show" */
"all" = "all";
"read" = "read";
"unread" = "unread";
"deleted" = "deleted";
"flagged" = "flagged";
/* MailListView */
"Sender" = "Sender";
"Subject or Sender" = "Subject or Sender";
"Subject or Recipient" = "Subject or Recipient";
"To or Cc" = "To or Cc";
"Entire Message" = "Entire Message";
"Date" = "Date";
"View" = "View";
"All" = "All";
"No message" = "No message";
"messages" = "messages";
"Yesterday" = "Yesterday";
"first" = "First";
"previous" = "Previous";
"next" = "Next";
"last" = "Last";
"msgnumber_to" = "to";
"msgnumber_of" = "of";
"Mark Unread" = "Mark Unread";
"Mark Read" = "Mark Read";
"Untitled" = "Untitled";
/* Filter option in messages list */
"Show unread messages only" = "Show unread messages only";
/* Filter option in messages list */
"Show flagged messages only" = "Show flagged messages only";
/* Aria label for icon of labels */
"Filtered by label" = "Filtered by label";
/* Tree */
"SentFolderName" = "Sent";
"TrashFolderName" = "Trash";
"InboxFolderName" = "Inbox";
"DraftsFolderName" = "Drafts";
"JunkFolderName" = "Junk";
"TemplatesFolderName" = "Templates";
"SieveFolderName" = "Filters";
"Folders" = "Folders"; /* title line */
/* MailMoveToPopUp */
"MoveTo" = "Move &hellip;";
/* Address Popup menu */
"Add to Address Book..." = "Add to Address Book...";
"Successfully created card" = "Successfully created card";
"Compose Mail To" = "Compose Mail To";
"Create Filter From Message..." = "Create Filter From Message...";
/* Image Popup menu */
"Save Image" = "Save Image";
"Save Attachment" = "Save Attachment";
/* Mailbox popup menus */
"Open in New Mail Window" = "Open in New Mail Window";
"Copy Folder Location" = "Copy Folder Location";
"Subscribe..." = "Subscribe...";
"Mark Folder Read" = "Mark Folder Read";
"New Folder..." = "New Folder...";
"Compact This Folder" = "Compact This Folder";
"Search Messages..." = "Search Messages...";
"Sharing..." = "Sharing...";
"New Subfolder..." = "New Subfolder...";
"Rename Folder..." = "Rename Folder...";
"Delete Folder" = "Delete Folder";
"Use This Folder For" = "Use This Folder For";
"Get Messages for Account" = "Get Messages for Account";
"Properties..." = "Properties...";
"Delegation..." = "Delegation...";
/* Use This Folder menu */
"Sent Messages" = "Sent Messages";
"Drafts" = "Drafts";
"Deleted Messages" = "Deleted Messages";
"Junk Messages" = "Junk Messages";
/* Message list popup menu */
"Open Message In New Window" = "Open Message In New Window";
"Reply to Sender Only" = "Reply to Sender Only";
"Reply to All" = "Reply to All";
"Edit As New..." = "Edit As New...";
"Move To" = "Move To";
"Copy To" = "Copy To";
"Label" = "Label";
"Mark" = "Mark";
"Save As..." = "Save As...";
"Print Preview" = "Print Preview";
"View Message Source" = "View Message Source";
"View raw message" = "View raw message";
/* Message view "more" menu: create an event from message */
"Convert To Event" = "Convert To Event";
/* Message view "more" menu: create a task from message */
"Convert To Task" = "Convert To Task";
/* Message view "more" menu: download message as an eml file */
"Download message" = "Download message";
/* Message view "more" menu: download message as a zip archive */
"Download message (zip)" = "Download message (zip)";
/* Message view "more" menu: download all attachments as a zip archive */
"Download all attachments" = "Download all attachments";
/* Filename prefix when downloading all attachments as a zip archive */
"attachments" = "attachments";
"Print..." = "Print...";
"Delete Message" = "Delete Message";
"Delete Selected Messages" = "Delete Selected Messages";
"Mark the selected messages as junk" = "Mark the selected messages as junk";
"Mark the selected messages as not junk" = "Mark the selected messages as not junk";
/* Text appended to the recipients list when there are too many recipients */
"and %{0} more..." = "and %{0} more...";
/* Button label to hide extended list of recipients */
"Hide" = "Hide";
/* Number of selected messages in list */
"selected" = "selected";
/* Date formatting from one time to another time */
"to_time" = "to";
/* Date formatting from one day to another day */
"to_date" = "to";
/* Encrypted message notification */
"This message is encrypted" = "This message is encrypted";
/* Encrypted message but no certificate */
"This message can't be decrypted. Please make sure you have uploaded your S/MIME certificate from the mail preferences module." = "This message can't be decrypted. Please make sure you have uploaded your S/MIME certificate from the mail preferences module.";
/* OpenSSL certificate error - unknown issuer */
"certificate verify error" = "Unable to verify message signature";
/* OpenSSL certificate error - digest failure */
"digest failure" = "The message has been modified";
/* OpenSSL reading error */
"Error reading the certificate. Please install a new certificate." = "Error reading the certificate. Please install a new certificate.";
/* Trying to access a non-existent certificate */
"No certificate associated to account." = "No certificate associated to account.";
/* Invalid S/MIME signature */
"Digital signature is not valid" = "Digital signature is not valid";
/* Valid S/MIME signature */
"Message is signed" = "Message is signed";
/* Valid S/MIME signature but common name not found */
"Message is signed but the certificate doesn't match the sender email address" = "Message is signed but the certificate doesn't match the sender email address";
/* Unknown error while validating message signature */
"Digital signature is not valid" = "Digital signature is not valid";
"This Folder" = "This Folder";
/* Label popup menu */
"None" = "None";
/* Mark popup menu */
"As Read" = "As Read";
"Thread As Read" = "Thread As Read";
"As Read By Date..." = "As Read By Date...";
"All Read" = "All Read";
"As Junk" = "As Junk";
"As Not Junk" = "As Not Junk";
"Run Junk Mail Controls" = "Run Junk Mail Controls";
"Search messages in" = "Search messages in";
"Search" = "Search";
"Search subfolders" = "Search subfolders";
"Match any of the following" = "Match any of the following";
"Match all of the following" = "Match all of the following";
"contains" = "contains";
"does not contain" = "does not contain";
"No matches found" = "No matches found";
"results found" = "results found";
"result found" = "result found";
"Please specify at least one filter" = "Please specify at least one filter";
/* Folder operations */
"Name" = "Name";
"Enter the new name of your folder"
="Enter the new name of your folder";
"Do you really want to move this folder into the trash ?"
= "Do you really want to move this folder into the trash ?";
"Operation failed" = "Operation failed";
"Quota" = "Quota:";
"quotasFormat" = "%{0}% used on %{1} MB";
"messageQuotasFormat" = "%{0}% of %{1} msgs";
"Unable to move/delete folder." = "Unable to move/delete folder.";
/* Alternative operation when folder cannot be deleted */
"The mailbox could not be moved to the trash folder. Would you like to delete it immediately?"
= "The mailbox could not be moved to the trash folder. Would you like to delete it immediately?";
/* Confirmation message when deleting multiple messages */
"Are you sure you want to delete the selected messages?" = "Are you sure you want to delete the selected messages?";
/* Notification on the number of messages successfuly copied */
"%{0} message(s) copied" = "%{0} message(s) copied";
/* Notification on the number of messages successfuly movied */
"%{0} message(s) moved" = "%{0} message(s) moved";
"Please select a message." = "Please select a message.";
"Please select a message to print." = "Please select a message to print.";
"Please select only one message to print." = "Please select only one message to print.";
"The message you have selected doesn't exist anymore." = "The message you have selected doesn't exist anymore.";
"The folder with name \"%{0}\" could not be created."
= "The folder with name \"%{0}\" could not be created.";
"This folder could not be renamed to \"%{0}\"."
= "This folder could not be renamed to \"%{0}\".";
"The folder could not be deleted."
= "The folder could not be deleted.";
"The trash could not be emptied."
= "The trash could not be emptied.";
"The folder functionality could not be changed."
= "The folder functionality could not be changed.";
"You need to choose a non-virtual folder!" = "You need to choose a non-virtual folder!";
"Moving a message into its own folder is impossible!"
= "Moving a message into its own folder is impossible!";
"Copying a message into its own folder is impossible!"
= "Copying a message into its own folder is impossible!";
/* Message operations */
"The messages could not be moved to the trash folder. Would you like to delete them immediately?"
= "The messages could not be moved to the trash folder. Would you like to delete them immediately?";
/* Message editing */
"Please specify a subject." = "Please specify a subject.";
"error_missingsubject" = "The message has no subject. Are you sure you want to send it?";
"error_missingrecipients" = "Please specify at least one recipient.";
"Send Anyway" = "Send Anyway";
"Error while saving the draft" = "Error while saving the draft";
/* Error when emptying trash */
"Unable to empty the trash folder." = "Unable to empty the trash folder.";
/* Error when emptying junk folder */
"Unable to empty the junk folder." = "Unable to empty the junk folder.";
/* Error when uploading a file attachment */
"Error while uploading the file \"%{0}\":" = "Error while uploading the file \"%{0}\":";
"There is an active file upload. Closing the window will interrupt it." = "There is an active file upload. Closing the window will interrupt it.";
"Message is too big" = "Message is too big";
/* Appears while sending the message */
"Sending" = "Sending";
/* Appears when the message is successfuly sent */
"Sent" = "Sent";
"cannot send message: (smtp) all recipients discarded" = "Cannot send message: all recipients are invalid.";
"cannot send message (smtp) - recipients discarded" = "Cannot send message. The following addresses are invalid";
"cannot send message: (smtp) error when connecting" = "Cannot send message: error when connecting to the SMTP server.";
"cannot sign email without certificate" = "The message can't be signed because there's no certificate associated to the mail account.";
"cannot sign message because the certificate can't be read" = "The message can't be signed becasue the certificate associated to the mail account can't be read.";
"cannot sign message because the certificate doesn't include the specified sender address" = "The message can't be signed because the sender address is not included in the certificate associated to the mail account.";
/* Contacts list in mail editor */
"Email" = "Email";
"More mail options" = "More mail options";
"Delegation" = "Delegation";
"Add User" = "Add User";
"Add a tag" = "Add a tag";
"reply" = "reply";
"Edit" = "Edit";
"Yes" = "Yes";
"No" = "No";
"Location" = "Location";
"Rename" = "Rename";
"Compact" = "Compact";
"Export" = "Export";
"Set as Drafts" = "Set as Drafts";
"Set as Sent" = "Set as Sent";
"Set as Trash" = "Set as Trash";
/* Set the folder as the one holding the Templates */
"Set as Templates" = "Set as Templates";
/* Set the folder as the one holding Junk mails */
"Set as Junk" = "Set as Junk";
"Sort" = "Sort";
"Order Received" = "Order Received";
"Descending Order" = "Descending Order";
"Back" = "Back";
"Copy messages" = "Copy messages";
"More messages options" = "More messages options";
"Flag" = "Flag";
"Unflag" = "Unflag";
"Mark as Unread" = "Mark as Unread";
"Mark as Read" = "Mark as Read";
"Closing Window ..." = "Closing Window ...";
"Tried to send too many mails. Please wait." = "Tried to send too many mails. Please wait.";
"View Mail" = "View Mail";
"This message contains external images." = "This message contains external images.";
"Expanded" = "Expanded";
"Add a Criteria" = "Add a Criteria";
"More search options" = "More search options";
"Your email has been saved" = "Your email has been saved";
"Your email has been sent" = "Your email has been sent";
"Folder compacted" = "Folder compacted";
"More Options" = "More Options";
"New draft" = "New draft";
"Create new draft with this template" = "Create new draft with this template";
/* Advanced search */
"Enter Subject" = "Enter Subject";
"Enter From" = "Enter From";
"Enter To" = "Enter To";
"Enter Cc" = "Enter Cc";
"Enter Body" = "Enter Body";
"match" = "match";
"does not match" = "does not match";
/* Aria label for scope of search on messages */
"Search scope" = "Search scope";
/* Subscriptions Dialog */
"Manage Subscriptions" = "Manage Subscriptions";
/* Label of filter input field in subscriptions dialog */
"Filter" = "Filter";
/* Hotkey to write a new message */
"hotkey_compose" = "w";
/* Hotkey to flag a message */
"hotkey_flag" = "*";
/* Hotkey to reply to a message */
"hotkey_reply" = "r";
/* Hotkey to reply to all recipients of a message */
"hotkey_replyall" = "a";
/* Hotkey to forward to a message */
"hotkey_forward" = "f";
/* Email deletion */
"Clean folder" = "Clean folder";
"Clean mailbox" = "Clean mailbox";
"Delete permanently (do not use trash)" = "Delete permanently (do not use trash)";
"Apply to subfolders" = "Apply to subfolders";
"Delete e-mails older than" = "Delete e-mails older than";
"3 months" = "3 months";
"6 months" = "6 months";
"9 months" = "9 months";
"1 year" = "1 year";
"Custom" = "Custom";
"You are about to permanently delete some messages. Are you sure you want to proceed with this action?" = "You are about to permanently delete some messages. Are you sure you want to proceed with this action?";
"Apply" = "Apply";
"%{0} message(s) deleted" = "%{0} message(s) deleted";
Loaded 100 of 271 files, more files were not shown because too many files have changed in this diff. Show more