From 57790838d90431dbbbc306527e1706c41c354eb8 Mon Sep 17 00:00:00 2001 From: Maniack Crudelis Date: Tue, 12 Apr 2016 13:15:39 +0200 Subject: [PATCH] Corrections --- app_radicale_fr.md | 116 +- conf/rights | 74 +- scripts/install | 3 +- scripts/upgrade | 3 +- sources/Notes ajouts | 15 + sources/ajouts_infcloud/interface.js | 7196 ++++++++++++++++++++++++++ 6 files changed, 7318 insertions(+), 89 deletions(-) create mode 100644 sources/Notes ajouts create mode 100644 sources/ajouts_infcloud/interface.js diff --git a/app_radicale_fr.md b/app_radicale_fr.md index 050a201..0239045 100644 --- a/app_radicale_fr.md +++ b/app_radicale_fr.md @@ -16,70 +16,88 @@ URL : https://domain.tld/path/user/calendar.ics/ Exemple : https://example.org/radicale/moi/calendar.ics/ -### ics et caldav indifféremment??? - ## Pour connecter un carnet d'adresses en particulier: URL : https://domain.tld/path/user/AddressBook.vcf/ Exemple : https://example.org/radicale/moi/AddressBook.vcf/ -## Créer un nouveau calendrier ou un nouveau carnet d'adresses +## Créer un nouveau calendrier ou un nouveau carnet d'adresses: Créer un nouveau calendrier ou un nouveau carnet d'adresses est très simple avec radicale, il suffit d'y accéder! Radicale créera tout nouveau calendrier ou carnet d'adresses inexistant si vous tentez d'y accéder. -Il suffit donc de se connecter (comme précédemment) à un calendrier ou un carnet d'adresses inexistant pour le créer. -Cela peux être fait simplement avec un navigateur, pour le voir apparaitre dans une collection déjà connectée à un client. +Il suffit donc de se connecter (comme précédemment) à un calendrier ou un carnet d'adresses inexistant pour le créer. +Cela peux être fait simplement avec un navigateur, pour le voir apparaître dans une collection déjà connectée à un client. + +## Accéder à un calendrier ou un carnet d'adresses d'un autre utilisateur: +Les adresses précédentes fonctionnent également pour accéder à des ressources n'appartenant pas à l'utilisateur authentifié. + +> Exemple: +> User1 peut se connecter à la collection de user2 +> https://example.org/radicale/user2/ +> Il lui suffira d'indiquer le login et mot de passe de user1. +> Ce sont les règles de partage (voir ci-dessous) qui permettront ou pas à user1 de voir le contenu de la collection de user2. +> Par défaut, aucun partage n'est autorisé. (A VÉRIFIER !!!) --- +## Configurer les droits d'accès et les partages de calendriers et de carnets d'adresses: +Par défaut, tout utilisateur à le droit de lecture et d'écriture sur ses propres calendriers et carnets d'adresses. +Il est toutefois possible d'affiner ces règles par défaut et d'autoriser des partages en autorisant des utilisateurs à accéder à des ressources ne leurs appartenant pas. +Les règles régissant ces droits doivent être inscrite dans le fichier */etc/radicale/rights* -Qu'est-ce que je voulais ajouter? -Les règles de partage et de droits! +Chaque règle se présente sous cette forme: +``` +# Commentaire précédant la règle et l'expliquant (optionnel évidemment): +[Nom de la règle] +user: utilisateur concerné +collection: calendrier, carnet ou collection concernée. +permission: permission, r (lecture), w (écriture) ou rw (lecture/écriture) +``` +Le fichier *rights* contient plusieurs exemples pouvant être exploités. +Pour valider les modifications apportées au fichier */etc/radicale/rights*, radicale doit être rechargé via le service uwsgi. +``` +sudo service uwsgi restart +``` -# This means all users starting with "admin" may read any collection -[admin] -user: ^admin.*$ -collection: .* -permission: r - -# This means all users may read and write any collection starting with public. -# We do so by just not testing against the user string. -[public] -user: .* -collection: ^public(/.+)?$ +## Partager des ressources: +Pour partager un calendrier ou un carnet d'adresses, il suffit d'écrire une règle le permettant. Le partage peut se faire avec un autre utilisateur. +``` +user: ^user1$ +collection: ^user2/shared2$ permission: rw - -# A little more complex: give read access to users from a domain for all -# collections of all the users (ie. user@domain.tld can read domain/\*). -# [domain-wide-access] -# user: ^.+@(.+)\..+$ -# collection: ^{0}/.+$ -# permission: r - -# Allow authenticated user to read all collections -[allow-everyone-read] -user: .+ -collection: .* +``` +Ou publiquement pour un utilisateur distant n'utilisant pas le même serveur. +``` +user: .* +collection: ^user2/shared2$ permission: r +``` +Dans les 2 cas, le partage ne fonctionnera qu'en utilisant l'adresse complète du calendrier ou de la collection. Autrement dit, les partages n'apparaissent pas dans la collection d'un utilisateur. +Cette limitation peut s'avérer bloquante pour des clients gérant une seule collection, tel que InfCloud. Pour ce cas particulier, une solution permet de contourner ce problème. -# Give write access to owners -[owner-write] -user: .+ -collection: ^%(login)s/.+$ -permission: w +### Partager des ressources directement dans la collection d'un utilisateur: +> Cette solution est fonctionnelle, mais reste du bidouillage... -# Partage public en lecture seule d'un agenda -#[public for readonly] -#user: .* -#collection: ^utilisateur/nom_calendrier* -#permission: r +Pour permettre à un partage d'apparaître directement dans la collection d'un utilisateur, il faut exploiter l'usage des fichiers sous Radicale. +En créant simplement un lien symbolique de la ressource à partager. +``` +ln -sr user2/shared.ics user1/user2_shared.ics +``` +La ressource partagée devient ainsi une ressource de la collection de user1, alors qu'elle reste physiquement dans la collection de user2. +En revanche, sans avoir recours à des règles pour chaque ressource de la collection de user1, la règle générale s'applique. user1 obtient donc le droit de lecture ET d'écriture par défaut sur la ressource partagé car elle fait partie de sa collection. -# Partage public en lecture/écriture d'un agenda -#[public for read/write] -#user: .* -#collection: ^utilisateur/nom_calendrier* -#permission: rw +--- -#[user1 can read and write user2/shared2] -#user: ^user1$ -#collection: ^user2/shared2$ -#permission: rw +## Rendre le log de Radicale plus loquace: +Par défaut, le log de Radicale est réglé sur INFO. Ce mode épargne le disque dur mais ne permet pas de débugger Radicale en cas de problème. +Pour passer Radicale en mode DEBUG, il faut éditer le fichier */etc/radicale/logging* et passer INFO à DEBUG dans les sections *[logger_root]* et *[handler_file]* puis recharger le service uwsgi. +Dés lors, le log affiche toutes les requêtes qui sont faite à Radicale ainsi que l'analyse du fichier *rights*. +Il est toutefois déconseillé de rester sur ce mode, car le log se rempli très rapidement. + +--- + +## Modifier la configuration de InfCloud: +La configuration de InfCloud se trouve dans le fichier *infcloud/config.js* +Pour prendre en compte une modification dans le fichier *config.js* (ou tout autre fichier de InfCloud) il faut recharger le cache avec le script fourni. +``` +sudo ./cache_update.sh +``` diff --git a/conf/rights b/conf/rights index e5968a1..5dc2e90 100644 --- a/conf/rights +++ b/conf/rights @@ -9,27 +9,6 @@ # Leading or ending slashes are trimmed from collection's path. - -# This means all users starting with "admin" may read any collection -[admin] -user: ^admin.*$ -collection: .* -permission: r - -# This means all users may read and write any collection starting with public. -# We do so by just not testing against the user string. -[public] -user: .* -collection: ^public(/.+)?$ -permission: rw - -# A little more complex: give read access to users from a domain for all -# collections of all the users (ie. user@domain.tld can read domain/\*). -# [domain-wide-access] -# user: ^.+@(.+)\..+$ -# collection: ^{0}/.+$ -# permission: r - # Allow authenticated user to read all collections [allow-everyone-read] user: .+ @@ -40,21 +19,44 @@ permission: r [owner-write] user: .+ collection: ^%(login)s/.+$ -permission: w +permission: rw -# Partage public en lecture seule d'un agenda -#[public for readonly] -#user: .* -#collection: ^utilisateur/nom_calendrier* -#permission: r -# Partage public en lecture/écriture d'un agenda -#[public for read/write] -#user: .* -#collection: ^utilisateur/nom_calendrier* -#permission: rw -#[user1 can read and write user2/shared2] -#user: ^user1$ -#collection: ^user2/shared2$ -#permission: rw +### EXAMPLES: + +## This means all users starting with "admin" may read any collection +# [admin] +# user: ^admin.*$ +# collection: .* +# permission: r + +## A little more complex: give read access to users from a domain for all +# collections of all the users (ie. user@domain.tld can read domain/\*). +# [domain-wide-access] +# user: ^.+@(.+)\..+$ +# collection: ^{0}/.+$ +# permission: r + +## This means all users may read and write any collection starting with public. +# [public] +# user: .* +# collection: ^public(/.+)?$ +# permission: rw + +## Partage public en lecture seule d'un agenda +# [public for readonly] +# user: .* +# collection: ^utilisateur/nom_calendrier* +# permission: r + +## Partage public en lecture/écriture d'un agenda +# [public for read/write] +# user: .* +# collection: ^utilisateur/nom_calendrier* +# permission: rw + +# [user1 can read and write user2/shared2] +# user: ^user1$ +# collection: ^user2/shared2$ +# permission: rw diff --git a/scripts/install b/scripts/install index 8c050b5..600c44e 100755 --- a/scripts/install +++ b/scripts/install @@ -142,8 +142,7 @@ sudo chown radicale: -R /opt/yunohost/$app sudo chown -R radicale: $final_path sudo mkdir /var/log/$app sudo touch /var/log/$app/$app.log -sudo chgrp radicale -R /var/log/$app -sudo chmod g+w -R /var/log/$app +sudo chown radicale -R /var/log/$app # Droit par défaut des dossiers de collections utilisateurs, tels qu'ils sont créés par radicale. sudo chmod 666 -R $final_path/default_collections sudo chmod 777 $final_path/default_collections $final_path/default_collections/USER diff --git a/scripts/upgrade b/scripts/upgrade index 15fb39c..96ae017 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -135,8 +135,7 @@ sudo chmod 644 /etc/$app/* sudo chown -R radicale: $final_path sudo mkdir -p /var/log/$app sudo touch /var/log/$app/$app.log -sudo chgrp radicale -R /var/log/$app -sudo chmod g+w -R /var/log/$app +sudo chown radicale -R /var/log/$app # Droit par défaut des dossiers de collections utilisateurs, tels qu'ils sont créés par radicale. sudo chmod 666 -R $final_path/default_collections sudo chmod 777 $final_path/default_collections $final_path/default_collections/USER diff --git a/sources/Notes ajouts b/sources/Notes ajouts new file mode 100644 index 0000000..9d1903f --- /dev/null +++ b/sources/Notes ajouts @@ -0,0 +1,15 @@ +Infos sur les fichiers modifiés dans le code source des logiciels: + +# Radicale: +Correction du commit https://github.com/Kozea/Radicale/commit/e807c3d35bea9cfcfcacac83b1b17d748ea15a39 + +Ce commit force l'arrêt de l'analyse du fichier rights à la première règle valide. + +Cette modification est faite aux lignes 112 à 116 du fichier regex.py + + +# InfCloud: +Le script cache_update.sh utilise l'éditeur de texte ed, qui n'est pas installé par défaut. La commande étant très simple, elle est remplacée par sed. + +Une erreur bloquante affecte CardDavMATE, après discussion avec le dévellopeur Ján Máté, il a trouvé la source du bug. Le fichier interface.js est corrigé en conséquence en attendant une nouvelle version. +Correction aux lignes 6922 à 6928. diff --git a/sources/ajouts_infcloud/interface.js b/sources/ajouts_infcloud/interface.js new file mode 100644 index 0000000..eb537c8 --- /dev/null +++ b/sources/ajouts_infcloud/interface.js @@ -0,0 +1,7196 @@ +/* +InfCloud - the open source CalDAV/CardDAV Web Client +Copyright (C) 2011-2015 + Jan Mate + Andrej Lezo + Matej Mihalik + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +function checkTimezone(timezone) +{ + if(timezone in timezones) + return timezone; + else if(timezone in timezones_alt) + return checkTimezone(timezones_alt[timezone]); + return null; +} +function CalDAVeditor_cleanup(repeatHash) +{ + if(typeof repeatHash!='undefined') + CalDAVcleanupRegexEnvironment(repeatHash); + else + CalDAVcleanupRegexEnvironment(); + + if(typeof repeatHash==='undefined' || repeatHash==='form') + { + /*************************** BAD HACKS SECTION ***************************/ + /* IE or FF */ + if($.browser.msie || $.browser.mozilla) + { + // ADD empty SVG to interface (we will replace it later) + $('').css('display', 'none').insertAfter($('#event_details_template, #todo_details_template').find('select')); + } + /*************************** END OF BAD HACKS SECTION ***************************/ + + /*************************** BAD HACKS SECTION ***************************/ + if($.browser.msie || $.browser.mozilla) + { + var newSVG=$(SVG_select).attr('data-type', 'select_icon').css({'pointer-events': 'none', 'z-index': '1', 'display': 'inline', 'margin-left': '-19px', 'vertical-align': 'top', 'background-color': '#ffffff'}); // background-color = stupid IE9 bug + $('#event_details_template, #todo_details_template').find('svg[data-type="select_icon"]').replaceWith($('
').append($(newSVG).clone()).html()); + } + /*************************** END OF BAD HACKS SECTION ***************************/ + } +} + +function animate_messageCalendar(messageSelector, messageTextSelector, duration, operation) +{ + if(operation==undefined) + operation='+='; + var height=$(messageTextSelector).height()+14; + var animation=500; + + $(messageSelector).animate({ + 'max-height': height+'px', + height: (operation==undefined ? '+=' : operation)+height+'px' + }, + animation, + function(){ + if(operation=='+=') + setTimeout(function(){animate_messageCalendar(messageSelector, messageTextSelector, 0, '-=');}, duration); + } + ); + return duration+2*animation; +} + +function show_editor_messageCalendar(inputPosition, inputSetClass, inputMessage, inputDuration, callback) +{ + var formShown=''; + + if($('#todo_details_template').css('display')!='none') + formShown='Todo'; + else + formShown='Event'; + + if(inputPosition==undefined || inputPosition=='in') + { + messageSelector='#'+formShown+'InMessage'; + messageTextSelector='#'+formShown+'InMessageText'; + } + else + { + messageSelector='#'+formShown+'Message'; + messageTextSelector='#'+formShown+'MessageText'; + } + + $(messageTextSelector).attr('class', inputSetClass); + $(messageTextSelector).text(inputMessage); + + var a=animate_messageCalendar(messageSelector, messageTextSelector, inputDuration); + + if(callback!=undefined) + callback(a); +} + +function show_editor_loader_messageCalendar(inputForm, inputSetClass, inputMessage, callback) +{ + var formShown=''; + + if(inputForm=='vtodo') + formShown='#todoLoader'; + else + formShown='#CAEvent'; + + messageSelector=formShown+' .saveLoader'; + messageTextSelector=formShown+' .saveLoaderInfo'; + + $(messageTextSelector).addClass(inputSetClass); + $(messageTextSelector).text(inputMessage); + setTimeout(function(){ + if(inputForm=='vtodo') + $(formShown).hide(); + else + $(messageSelector).hide(); + $(messageTextSelector).text(''); + $(messageTextSelector).removeClass(inputSetClass); + if(callback!=undefined) + callback(globalHideInfoMessageAfter); + }, globalHideInfoMessageAfter); + +} + +function items(etag, from, end, title, isall, uid, rid, ev_id, note, displayValue, alertTime, alertNote, untilDate, type, interval, after, repeatStart, repeatEnd, byMonthDay, repeatCount, realRepeatCount, vcalendar, location, alertTimeOut, timeZone, realStart ,realEnd, byDay, rec_id, wkst, classType, avail, hrefUrl,compareString,priority,status,ruleString) +{ + this.etag=etag; + this.id=uid; + this.start=from; + this.end=end; + this.title=title; + this.allDay=isall; + this.res_id=rid; + this.ev_id=ev_id; + this.note=note; + this.displayValue=displayValue; + this.alertTime=alertTime; + this.alertNote=alertNote; + this.untilDate=untilDate; + this.repeatStart=repeatStart; + this.repeatEnd=repeatEnd; + this.type=type; + this.interval=interval; + this.after=after; + this.byMonthDay=byMonthDay; + this.repeatCount=repeatCount; + this.realRepeatCount=realRepeatCount; + this.vcalendar=vcalendar; + this.location=location; + this.alertTimeOut=alertTimeOut; + this.timeZone=timeZone; + this.realStart=realStart; + this.realEnd=realEnd; + this.byDay=byDay; + this.rec_id=rec_id; + this.wkst=wkst; + this.classType=classType; + this.avail=avail; + this.hrefUrl=hrefUrl; + this.compareString=compareString; + this.priority=priority; + this.status=status; + this.searchvalue=title.toLowerCase().replace(vCalendar.pre['compressNewLineRex']).multiReplace(globalSearchTransformAlphabet); + this.ruleString=ruleString; +} + +function todoItems(from, to, untilDate, type, interval, after, wkst, repeatStart, repeatEnd, repeatCount, realRepeatCount, byDay, location, note, title, uid, vcalendar, etag, alertTime, alertNote, status, filterStatus, rec_id, repeatHash, percent, displayValue, res_id, compareString, timeZone, realStart, realEnd, alertTimeOut,classType, url, completedOn, sequence,priority,renderPriority, finalString,ruleString) +{ + this.start=from; + this.end=to; + this.untilDate=untilDate; + this.type=type; + this.interval=interval; + this.after=after; + this.wkst=wkst; + this.repeatStart=repeatStart; + this.repeatEnd=repeatEnd; + this.repeatCount=repeatCount; + this.realRepeatCount=realRepeatCount; + this.byDay=byDay; + this.location=location; + this.note=note; + this.title=title; + this.id=uid; + this.vcalendar=vcalendar; + this.etag=etag; + this.alertTime=alertTime; + this.alertNote=alertNote; + this.status=status; + this.filterStatus=filterStatus; + this.percent=percent; + this.displayValue=displayValue; + this.res_id=res_id; + this.compareString=compareString; + this.alertTimeOut=alertTimeOut; + this.timeZone=timeZone; + this.realStart=realStart; + this.realEnd=realEnd; + this.classType=classType; + this.url=url; + this.rec_id= rec_id; + this.repeatHash= repeatHash; + this.completedOn=completedOn; + this.sequence=sequence; + this.priority=priority; + this.renderPriority=renderPriority; + this.finalString=finalString; + this.searchvalue=title.toLowerCase().replace(vCalendar.pre['compressNewLineRex']).multiReplace(globalSearchTransformAlphabet); + this.ruleString=ruleString; +} + +function setLoadingLimit(forceLoad, allSyncMode) +{ + if(forceLoad) + { + if(globalSettings.eventstartpastlimit.value!=null && (allSyncMode || globalLimitLoading=='past')) + { + var pastDate = new Date(globalLoadedLimit.getTime()); + pastDate.setDate(pastDate.getDate()-7); + globalBeginPast = new Date(pastDate.getTime()); + } + if(globalSettings.eventstartfuturelimit.value!=null && (allSyncMode || globalLimitLoading=='future')) + { + var futureDate = new Date(globalToLoadedLimit.getTime()); + futureDate.setDate(futureDate.getDate()+14); + globalBeginFuture = new Date(futureDate.getTime()); + } + } +} + +function initSearchEngine() { + globalCalDAVQs=$('input[data-type="PH_CalDAVsearch"]').quicksearch(globalEventList.displayEventsArray,{ + delay: 500, + hide: function() { + this.hidden=true; + $('#SystemCalDavZAP').find('.event_item[data-id="'+this.id+'"]').each(function(){ + $(this).addClass('searchCalDAV_hide'); + if(this.tagName.toLowerCase()=='tr' && !$(this).siblings().addBack().not('.searchCalDAV_hide').length) + $(this).parent().prev().find('tr').addClass('searchCalDAV_hide'); + }); + }, + show: function() { + this.hidden=false; + $('#SystemCalDavZAP').find('.event_item[data-id="'+this.id+'"]').each(function(){ + $(this).removeClass('searchCalDAV_hide'); + if(this.tagName.toLowerCase()=='tr') + $(this).parent().prev().find('tr').removeClass('searchCalDAV_hide'); + }); + }, + prepareQuery: function(val) { + return val.multiReplace(globalSearchTransformAlphabet).toLowerCase().split(' '); + } + }); + + globalCalDAVTODOQs=$('input[data-type="PH_CalDAVTODOsearch"]').quicksearch(globalEventList.displayTodosArray,{ + delay: 500, + onAfter: function () { + if(!$('#TodoDisabler').is(':visible')) + $('#todoList').fullCalendar('selectEvent'); + }, + hide: function() { + this.hidden=true; + $('#SystemCalDavTODO').find('.event_item[data-id="'+this.id+'"]').addClass('searchCalDAV_hide'); + }, + show: function() { + this.hidden=false; + $('#SystemCalDavTODO').find('.event_item[data-id="'+this.id+'"]').removeClass('searchCalDAV_hide'); + }, + prepareQuery: function(val) { + return val.multiReplace(globalSearchTransformAlphabet).toLowerCase().split(' '); + } + }); +} + +//SORRY FOR THAT----------------------------------------------------------------------------------------------------- +function checkEventLoader(inputCounter, needRefresh) +{ + inputCounter.counter++; + if(inputCounter.counter==inputCounter.collectionLength) + { + if(inputCounter.listType=='vevent') + $('#ResourceCalDAVList [data-id="'+inputCounter.uid+'"]').removeClass('r_operate'); + else + $('#ResourceCalDAVTODOList [data-id="'+inputCounter.uid+'"]').removeClass('r_operate'); + + if((globalLimitTodoLoading=='' && globalLimitLoading=='') || ((inputCounter.listType=='vtodo' && globalSettings.todopastlimit.value==null) || (inputCounter.listType=='vevent' && globalSettings.eventstartpastlimit.value==null && globalSettings.eventstartfuturelimit.value==null))) + { + if(inputCounter.listType=='vevent') + globalAccountSettings[inputCounter.resourceIndex].calendarNo--; + else if(inputCounter.listType=='vtodo') + globalAccountSettings[inputCounter.resourceIndex].todoNo--; + + if(((globalAccountSettings[inputCounter.resourceIndex].calendarNo==0) && (globalAccountSettings[inputCounter.resourceIndex].todoNo==0) && globalCalDAVInitLoad) || (!globalCalDAVInitLoad)) + { + if(!globalCalDAVInitLoad&&inputCounter.typeList.indexOf('vevent')!=-1&&inputCounter.typeList.indexOf('vtodo')!=-1) + updateMainLoader(needRefresh,null,inputCounter.uid); + else + updateMainLoader(needRefresh,inputCounter.listType,inputCounter.uid); + } + } + else if((globalOnlyCalendarNumber>0 && globalOnlyCalendarNumberCount==globalOnlyCalendarNumber) || (globalTodoCalendarNumber>0 && globalOnlyTodoCalendarNumberCount==globalTodoCalendarNumber)) + updateMainLoader(needRefresh,inputCounter.listType,inputCounter.uid); + } +} + +function getResourceByCollection(calendarUID) +{ + var coll = globalResourceCalDAVList.getCollectionByUID(calendarUID); + var tmp=coll.accountUID.match(vCalendar.pre['accountUidParts']); + var resourceSettings=null; + + var resourceCalDAV_href=tmp[1]+tmp[3]+tmp[4]; + var resourceCalDAV_user=tmp[2]; + + for(var i=0;i0) + vCalendar.tplM['contentline_TRIGGER'].splice(data_id-1, 1); + + if(typeof vCalendar.tplM['contentline_VANOTE']!='undefined' && vCalendar.tplM['contentline_VANOTE']!='' && + vCalendar.tplM['contentline_VANOTE']!=null && vCalendar.tplM['contentline_VANOTE'].length>0) + vCalendar.tplM['contentline_VANOTE'].splice(data_id-1, 1); + + if(typeof vCalendar.tplM['contentline_ACTION']!='undefined' && vCalendar.tplM['contentline_ACTION']!='' && + vCalendar.tplM['contentline_ACTION']!=null && vCalendar.tplM['contentline_ACTION'].length>0) + vCalendar.tplM['contentline_ACTION'].splice(data_id-1, 1); + + if(typeof vCalendar.tplM['unprocessedVALARM']!='undefined' && vCalendar.tplM['unprocessedVALARM']!='' && + vCalendar.tplM['unprocessedVALARM']!=null && vCalendar.tplM['unprocessedVALARM'].length>0) + vCalendar.tplM['unprocessedVALARM'].splice(data_id-1, 1); +} + +function checkForTodo(data_id) +{ + var rh='form'; + if(typeof vCalendar.tplM['VTcontentline_TRIGGER'][rh]!='undefined' && vCalendar.tplM['VTcontentline_TRIGGER'][rh]!='' && + vCalendar.tplM['VTcontentline_TRIGGER'][rh]!=null && vCalendar.tplM['VTcontentline_TRIGGER'][rh].length>0) + vCalendar.tplM['VTcontentline_TRIGGER'][rh].splice(data_id-1, 1); + + if(typeof vCalendar.tplM['VTcontentline_VANOTE'][rh]!='undefined' && vCalendar.tplM['VTcontentline_VANOTE'][rh]!='' && + vCalendar.tplM['VTcontentline_VANOTE'][rh]!=null && vCalendar.tplM['VTcontentline_VANOTE'][rh].length>0) + vCalendar.tplM['VTcontentline_VANOTE'][rh].splice(data_id-1, 1); + + if(typeof vCalendar.tplM['VTcontentline_ACTION'][rh]!='undefined' && vCalendar.tplM['VTcontentline_ACTION'][rh]!='' && + vCalendar.tplM['VTcontentline_ACTION'][rh]!=null && vCalendar.tplM['VTcontentline_ACTION'][rh].length>0) + vCalendar.tplM['VTcontentline_ACTION'][rh].splice(data_id-1, 1); + + if(typeof vCalendar.tplM['VTunprocessedVALARM'[rh]]!='undefined' && vCalendar.tplM['VTunprocessedVALARM'][rh]!='' && + vCalendar.tplM['VTunprocessedVALARM'][rh] != null && vCalendar.tplM['VTunprocessedVALARM'][rh].length>0) + vCalendar.tplM['VTunprocessedVALARM'][rh].splice(data_id-1, 1); +} + +function div(op1, op2) +{ + var a=(op1/op2); + + var b=(op1%op2)/op2; + return a-b; +} + +function binarySearch(array, first, last, value) +{ + var mid=0; + value=value.getTime(); + while(first<=last) + { + mid=div((first+last), 2); + var date3=$.fullCalendar.parseDate(array[mid].sortStart); + date3=date3.getTime(); + + if(date3value) + last=mid-1; + else + break; + } + return mid; +} + +function parseISO8601(str) +{ + // we assume str is a UTC date ending in 'Z' + var err=0; + if(str.indexOf('T')!=-1) + { + var parts=str.split('T'); + + if(parts.length>1) + var dateParts=parts[0].split('-'); + else + return null; + + if(dateParts.length>1) + var timeParts=parts[1].split('Z'); + else + return null; + + var timeSubParts=timeParts[0].split(':'); + if(timeSubParts.length>1) + var timeSecParts=timeSubParts[2].split('.'); + else + return null; + + var timeHours=Number(timeSubParts[0]); + _date=new Date; + _date.setFullYear(Number(dateParts[0])); + _date.setMonth(Number(dateParts[1])-1); + _date.setDate(Number(dateParts[2])); + _date.setHours(Number(timeHours)); + _date.setMinutes(Number(timeSubParts[1])); + _date.setSeconds(Number(timeSecParts[0])); + if(timeSecParts[1]) + _date.setUTCMilliseconds(Number(timeSecParts[1])); + + // by using setUTC methods the date has already been converted to local time(?) + return _date; + } + else + { + var dateParts=str.split('-'); + + if(dateParts.length!=3) + return null; + + _date=new Date; + _date.setFullYear(Number(dateParts[0])); + _date.setMonth(Number(dateParts[1])-1); + _date.setDate(Number(dateParts[2])); + + return _date; + } +} + +function getValidRepeatDay(inputDate, RepeatDay) +{ + var newDate=''; + if(typeof RepeatDay=='string') + newDate=$.fullCalendar.parseDate(RepeatDay); + else + newDate = new Date(RepeatDay.getTime()); + + var monthNumber=inputDate.getMonth()+2; + var dayOfMonth=newDate.getDate(); + + if(monthNumber>12) + monthNumber=1; + + var lastDayInMonth=new Date(inputDate.getFullYear(), monthNumber, 0); + lastDayInMonth=lastDayInMonth.getDate(); + + if(lastDayInMonth0) + checkRec=isInRecurrenceArray(varDate,inputObj.stringUID,inputObj.recurrence_id_array, inputObj.tzName); + if(!inputObj.items.allDay) + { + var dateStart,dateEnd; + if(globalSettings.timezonesupport.value && inputObj.items.timeZone in timezones) + valOffsetFrom=getOffsetByTZ(inputObj.items.timeZone, varDate); + var realStart=new Date(varDate.getTime()); + dateStart=new Date(realStart.getTime()); + if(valOffsetFrom) + { + intOffset=(getLocalOffset(dateStart)*-1*1000)-valOffsetFrom.getSecondsFromOffset()*1000; + dateStart.setTime(dateStart.getTime()+intOffset); + } + if(inputObj.exDates.length>0) + if(inputObj.exDates.indexOf(dateStart.toString())!=-1) + checkRec=true; + + var realEnd=new Date(varEndDate.getTime()); + dateEnd=new Date(realEnd.getTime()); + if(intOffset) + dateEnd.setTime(dateEnd.getTime()+intOffset); + } + else + { + realStart=new Date(varDate.getTime()); + if(inputObj.exDates.length>0) + if(inputObj.exDates.indexOf(realStart.toString())!=-1) + checkRec=true; + dateStart=$.fullCalendar.formatDate(realStart,"yyyy-MM-dd'T'HH:mm:ss"); + realEnd=new Date(varEndDate.getTime()); + dateEnd =$.fullCalendar.formatDate(realEnd,"yyyy-MM-dd'T'HH:mm:ss"); + } + + var checkDateTime = new Date(inputObj.repeatStart.getTime()); + if(typeof dateStart=='string') + checkDateTime=$.fullCalendar.formatDate(inputObj.repeatStart,"yyyy-MM-dd'T'HH:mm:ss"); + if((inputObj.items.after!=='' && inputObj.items.realRepeatCount>(parseInt(inputObj.items.after,10))) || (typeof dateStart=='object' && (checkDateTime-dateStart)==0) || (typeof dateStart=='string' && checkDateTime==dateStart)) + { + checkRec=true; + inputObj.items.realRepeatCount--; + } + + if(!checkRec) + { + if(!inputObj.ignoreAlarms) + alertTimeOut=setAlertTimeouts(false,inputObj.alertTime, dateStart, dateEnd, {allDay:inputObj.items.allDay, title:inputObj.items.title},false, inputObj.items.id); + inputObj.items.repeatCount++; + var tmpObj=$.extend({},inputObj.items,{ + start:dateStart, + end:dateEnd, + realStart:realStart, + realEnd:realEnd, + repeatCount:inputObj.items.repeatCount, + realRepeatCount:inputObj.items.realRepeatCount, + alertTimeOut:alertTimeOut + }); + globalEventList.displayEventsArray[inputObj.items.res_id].splice(globalEventList.displayEventsArray[inputObj.items.res_id].length, 0, tmpObj); + lastGenDate = new Date(varDate.getTime()); + } + return true; + }); + + + if(typeof globalEventList.repeatable[inputObj.items.id] == 'undefined') + globalEventList.repeatable[inputObj.items.id]={ + lastGenDate:lastGenDate, + recurrence_id_array:inputObj.recurrence_id_array, + stringUID:inputObj.stringUID, + exDates:inputObj.exDates, + alertTime:inputObj.alertTime, + ignoreAlarms:inputObj.ignoreAlarms, + rule:rule, + items:inputObj.items + }; + else + globalEventList.repeatable[inputObj.items.id].lastGenDate=lastGenDate; +} + +function generateTodoRepeatInstances(inputObj) +{ + var rule=null; + var alertTimeOut=new Array(); + var firstDateSaved=false; + if(inputObj.repeatStart) + var resStart=new Date($.fullCalendar.parseDate(inputObj.items.realStart).getTime()); + else if(inputObj.repeatEnd) + var resStart=new Date($.fullCalendar.parseDate(inputObj.items.realEnd).getTime()); + + if(typeof inputObj.lastGenDate!='undefined') + var resStart=new Date(inputObj.lastGenDate.getTime()); + + var lastGenDate=new Date(resStart.getTime()); + if(typeof inputObj.rule == 'undefined') + { + var options = RRule.parseString(inputObj.items.ruleString); + options.dtstart = new Date(resStart.getTime()); + if(inputObj.untilDate!=='') + options.until = inputObj.untilDate; + rule = new RRule(options); + } + else + rule=inputObj.rule; + + var dates = new Array(); + dates = rule.between(resStart, new Date(inputObj.futureRLimit.getTime()), true); + + if(dates.length>0 && (dates[0]-resStart)!=0 || dates.length==0) + dates.splice(0,0,resStart); + + var futureLimitDate = new Date(inputObj.futureRLimit.getTime()); + futureLimitDate.setHours(resStart.getHours()); + futureLimitDate.setMinutes(resStart.getMinutes()); + futureLimitDate.setSeconds(resStart.getSeconds()); + + + var startCheck = new Date(dates[dates.length-1].getTime()); + + + var iterationEnd = dates.length; + if(globalSettings.appleremindersmode.value || (inputObj.repeatEnd=='' && inputObj.repeatStart!='')) + for(var i=0; i0) + { + var isBreak=false; + for(var j=0;j0) + { + varDate=new Date(dates[i-1].getTime()); + varDate.setMinutes(varDate.getMinutes()+1); + } + else if(typeof inputObj.previousRepeatStart!='undefined'&&inputObj.previousRepeatStart!=='') + varDate=new Date(inputObj.previousRepeatStart); + } + + if(varDate!=='') + { + if(globalSettings.timezonesupport.value && inputObj.items.timeZone in timezones) + valOffsetFrom=getOffsetByTZ(inputObj.items.timeZone, varDate); + var realStart=new Date(varDate.getTime()); + dateStart=new Date(varDate.getTime()); + if(valOffsetFrom && (typeof inputObj.previousRepeatStart=='undefined' || inputObj.previousRepeatStart=='')) + { + intOffset=(getLocalOffset(dateStart)*-1*1000)-valOffsetFrom.getSecondsFromOffset()*1000; + dateStart.setTime(dateStart.getTime()+intOffset); + } + + } + + if(varEndDate!=='') + { + + var realEnd=new Date(varEndDate.getTime()); + var dateEnd=new Date(varEndDate.getTime()); + if(intOffset) + dateEnd.setTime(dateEnd.getTime()+intOffset); + } + + if(inputObj.repeatStart!='') + { + checkCont=isInRecurrenceArray(realStart,inputObj.stringUID,inputObj.recurrence_id_array, inputObj.items.timeZone); + if(inputObj.exDates.length>0) + if(inputObj.exDates.indexOf(dateStart.toString())!=-1) + checkCont=true; + } + else + { + checkCont=isInRecurrenceArray(realEnd,inputObj.stringUID,inputObj.recurrence_id_array, inputObj.items.timeZone); + if(inputObj.exDates.length>0) + if(inputObj.exDates.indexOf(dateEnd.toString())!=-1) + checkCont=true; + } + + if(inputObj.items.after!=='' && !globalSettings.appleremindersmode.value && realRepeatCount>(parseInt(inputObj.items.after,10))) + { + checkCont=true; + realRepeatCount--; + } + + if(globalSettings.appleremindersmode.value && firstDateSaved && inputObj.todoArray.length==1) + { + globalAppleSupport.nextDates[inputObj.items.id] = new Date(dateEnd.getTime()); + break; + } + if(!checkCont) + { + if(!inputObj.ignoreAlarms) + alertTimeOut=setAlertTimeouts(true, inputObj.alertTime, (inputObj.repeatStart=='' ? dateEnd : dateStart), (inputObj.repeatEnd=='' ? dateStart : dateEnd), {title:inputObj.items.title, status:inputObj.items.status},!firstDateSaved,inputObj.items.id); + firstDateSaved = true; + repeatCount++; + var tmpObj=$.extend({},inputObj.items,{ + start:dateStart, + end:(inputObj.repeatEnd=='' && i==(dates.length-1) ? '' : dateEnd), + realStart:realStart, + realEnd:realEnd, + repeatCount:repeatCount, + realRepeatCount:realRepeatCount, + alertTimeOut:alertTimeOut + }); + + inputObj.preTodoArray.splice(inputObj.preTodoArray.length, 0, tmpObj); + if(inputObj.repeatStart!='') + lastGenDate = new Date(dateStart.getTime()); + else + lastGenDate = new Date(dateEnd.getTime()); + } + } + + if(typeof globalEventList.repeatableTodo[inputObj.items.id] == 'undefined') + globalEventList.repeatableTodo[inputObj.items.id]={ + todoArray:inputObj.todoArray, + lastGenDate:lastGenDate, + dayDifference:inputObj.dayDifference, + recurrence_id_array:inputObj.recurrence_id_array, + stringUID:inputObj.stringUID, + exDates:inputObj.exDates, + realRepeatCount:realRepeatCount, + repeatCount:repeatCount, + alertTime:inputObj.alertTime, + ignoreAlarms:inputObj.ignoreAlarms, + rule:rule, + items:inputObj.items + }; + else + { + globalEventList.repeatableTodo[inputObj.items.id].lastGenDate=lastGenDate; + globalEventList.repeatableTodo[inputObj.items.id].realRepeatCount=realRepeatCount; + globalEventList.repeatableTodo[inputObj.items.id].repeatCount=repeatCount; + } +} + +function loadRepeatEvents(inputRepeatEvent,prevLimit,toLimit) +{ + var repeatFromLine=new Date(prevLimit.getFullYear(), prevLimit.getMonth(), prevLimit.getDate(), 0, 0, 0); + generateRepeatInstances({ + untilDate:inputRepeatEvent.items.untilDate, + repeatStart:inputRepeatEvent.lastGenDate, + futureRLimit:toLimit, + stringUID:inputRepeatEvent.stringUID, + recurrence_id_array:inputRepeatEvent.recurrence_id_array, + exDates:inputRepeatEvent.exDates, + alertTime:inputRepeatEvent.alertTime, + ignoreAlarms:inputRepeatEvent.ignoreAlarms, + rule:inputRepeatEvent.rule, + items:inputRepeatEvent.items + }); +} + +function loadRepeatTodo(inputRepeatTodo,prevLimit) +{ + var preTodoArray=new Array(); + var previousRepeatStart = ''; + var repeatInstances = globalEventList.displayTodosArray[inputRepeatTodo.items.res_id].filter(function(elm){return elm.id==inputRepeatTodo.items.id && elm.type!=''}); + if(repeatInstances.length>0) + { + var index = globalEventList.displayTodosArray[inputRepeatTodo.items.res_id].indexOf(repeatInstances[repeatInstances.length-1]); + previousRepeatStart = repeatInstances[repeatInstances.length-1].start; + globalEventList.displayTodosArray[inputRepeatTodo.items.res_id].splice(index,1); + } + generateTodoRepeatInstances({ + loadRepeatTodo:true, + rule:inputRepeatTodo.rule, + realRepeatCount:--inputRepeatTodo.realRepeatCount, + repeatCount:--inputRepeatTodo.repeatCount, + dayDifference:inputRepeatTodo.dayDifference, + untilDate:inputRepeatTodo.items.untilDate, + repeatStart:inputRepeatTodo.items.repeatStart, + repeatEnd:inputRepeatTodo.items.repeatEnd, + futureRLimit:globalToLoadedLimitTodo, + stringUID:inputRepeatTodo.stringUID, + recurrence_id_array:inputRepeatTodo.recurrence_id_array, + exDates:inputRepeatTodo.exDates, + alertTime:inputRepeatTodo.alertTime, + ignoreAlarms:inputRepeatTodo.ignoreAlarms, + isChange:false, + lastGenDate:inputRepeatTodo.lastGenDate, + todoArray:inputRepeatTodo.todoArray, + preTodoArray:preTodoArray, + previousRepeatStart:previousRepeatStart, + items:inputRepeatTodo.items + }); + + $.merge(globalEventList.displayTodosArray[inputRepeatTodo.items.res_id],preTodoArray); +} + +function getPrevMonths(viewStart) +{ + + if(globalLimitLoading!='future' && globalLimitLoading!='past' && globalSettings.eventstartpastlimit.value!=null && viewStart < globalLoadedLimit) + { + globalLoadedLimit.setMonth(globalLoadedLimit.getMonth()-globalSettings.eventstartpastlimit.value-1); + globalOnlyCalendarNumberCount = 0 + $('#CalendarLoader').children('.loaderInfo').text(localization[globalInterfaceLanguage].calendarLoader).parent().css('display','block'); + globalLimitLoading='past'; + setCalendarNumber(false); + CalDAVnetLoadCollection(globalResourceCalDAVList.collections[0], true, false, 0, globalResourceCalDAVList.collections); + } +} + +function getNextMonths(viewEnd) +{ + if(globalLimitLoading!='future' && globalLimitLoading!='past' && viewEnd > globalToLoadedLimit) + { + var limitSet = (globalSettings.eventstartfuturelimit.value!=null); + var futureLimit = limitSet ? globalSettings.eventstartfuturelimit.value : 2; + var prevLimit = new Date(globalBeginFuture.getTime()); + globalToLoadedLimit.setMonth(globalToLoadedLimit.getMonth()+futureLimit+1); + var futureDate = new Date(globalToLoadedLimit.getTime()); + futureDate.setDate(futureDate.getDate()+14); + + if(limitSet) + { + globalOnlyCalendarNumberCount = 0; + $('#CalendarLoader').children('.loaderInfo').text(localization[globalInterfaceLanguage].calendarLoader).parent().css('display','block'); + globalLimitLoading='future'; + } + + for (var repeat in globalEventList.repeatable) + loadRepeatEvents(globalEventList.repeatable[repeat],prevLimit,futureDate); + + if(limitSet) + { + setCalendarNumber(false); + CalDAVnetLoadCollection(globalResourceCalDAVList.collections[0], true, false, 0, globalResourceCalDAVList.collections); + } + else + globalBeginFuture = new Date(futureDate.getTime()); + + refetchCalendarEvents(); + } +} + +function getPrevMonthsTodo(fromCalendar) +{ + if(globalLimitTodoLoading=='futureTODO' && globalLimitTodoLoading=='pastTODO') + return false; + var actualTodoMonth = new Date($('#todoList').fullCalendar('getView').start.getTime()); + actualTodoMonth.setDate(1); + + if(globalSettings.todopastlimit.value!=null && actualTodoMonth < globalLoadedLimitTodo) + { + if(typeof fromCalendar!='undefined' && fromCalendar!=null && fromCalendar) + globalLoadedLimitTodo = new Date(actualTodoMonth.getTime()); + else + globalLoadedLimitTodo.setMonth(globalLoadedLimitTodo.getMonth()-globalSettings.todopastlimit.value-1); + globalOnlyTodoCalendarNumberCount = 0; + $('#CalendarLoaderTODO').children('.loaderInfo').text(localization[globalInterfaceLanguage].calendarLoader).parent().css('display','block'); + globalLimitTodoLoading='pastTodo'; + setCalendarNumber(false); + CalDAVnetLoadCollection(globalResourceCalDAVList.TodoCollections[0], true, false, 0, globalResourceCalDAVList.TodoCollections); + } +} + +function getNextMonthsTodo(fromCalendar) +{ + if(globalLimitTodoLoading=='futureTODO' && globalLimitTodoLoading=='pastTODO') + return false; + //var limitSet = (!globalSettings.appleremindersmode.value && globalSettings.eventstartfuturelimit.value!=null) + var limitSet=false; + var futureLimit = limitSet ? globalSettings.eventstartfuturelimit.value : 2; + var actualTodoMonth = new Date($('#todoList').fullCalendar('getView').end.getTime()); + actualTodoMonth.setMonth(actualTodoMonth.getMonth()+1); + actualTodoMonth.setDate(1); + + if(actualTodoMonth > globalToLoadedLimitTodo) + { + var prevLimit = new Date(globalToLoadedLimitTodo.getTime()); + if(typeof fromCalendar!='undefined' && fromCalendar!=null && fromCalendar) + { + globalToLoadedLimitTodo = new Date(actualTodoMonth.getTime()) + globalToLoadedLimitTodo.setMonth(globalToLoadedLimitTodo.getMonth()+1); + } + else + globalToLoadedLimitTodo.setMonth(globalToLoadedLimitTodo.getMonth()+futureLimit+1); + + if(limitSet) + { + globalOnlyTodoCalendarNumberCount = 0; + $('#CalendarLoaderTODO').children('.loaderInfo').text(localization[globalInterfaceLanguage].calendarLoader).parent().css('display','block'); + globalLimitTodoLoading='futureTodo'; + } + + for(var repeat in globalEventList.repeatableTodo) + loadRepeatTodo(globalEventList.repeatableTodo[repeat],prevLimit); + + if(limitSet) + { + setCalendarNumber(false); + CalDAVnetLoadCollection(globalResourceCalDAVList.TodoCollections[0], true, false, 0, globalResourceCalDAVList.TodoCollections); + } + + refetchTodoEvents(); + } +} + +function showAlertEvents(inputUID, realDelay, alarmObject) +{ + if(maxAlarmValueCalendar
"); + } +} + +function showAlertTODO(inputUID, realDelay, alarmObject) +{ + if(globalSettings.ignorecompletedorcancelledalarms.value && (alarmObject.status=='COMPLETED' || alarmObject.status== 'CANCELLED')) + return false; + if(maxAlarmValueTodo"); + } +} + +function clearAlertEvents() +{ + $('#alertBoxContent').html(''); + $('#alertBox').css('visibility', 'hidden'); + $('#AlertDisabler').fadeOut(globalEditorFadeAnimation); +} + +function addAndEdit(isFormHidden, deleteMode) +{ + var inputUID=''; + if($('#uid').val()!='') + var coll = globalResourceCalDAVList.getEventCollectionByUID($('#uid').val().substring(0, $('#uid').val().lastIndexOf('/')+1)); + else + var coll = globalResourceCalDAVList.getEventCollectionByUID($('#event_calendar').val()); + var res = getAccount(coll.accountUID); + var tmp=res.href.match(vCalendar.pre['hrefRex']); + var origUID=tmp[1]+res.userAuth.userName+'@'+tmp[2]; + + if($('#etag').val()!='') + inputUID=$('#uid').val(); + else if($('#event_calendar').val()!='choose') + inputUID = $('#event_calendar').val()+''; + else + return false; + dataToVcalendar('EDIT',origUID, inputUID, $('#etag').val(), '', isFormHidden, deleteMode); +} + +function interResourceEdit(op, delUID,isFormHidden) +{ + var inputUID=''; + if($('#uid').val()!='') + var coll = globalResourceCalDAVList.getEventCollectionByUID($('#uid').val().substring(0, $('#uid').val().lastIndexOf('/')+1)); + else + var coll = globalResourceCalDAVList.getEventCollectionByUID($('#event_calendar').val()); + var res = getAccount(coll.accountUID); + var tmp=res.href.match(vCalendar.pre['hrefRex']); + var origUID=tmp[1]+res.userAuth.userName+'@'+tmp[2]; + + if(op != 'MOVE_IN') + $('#etag').val(''); + var srcUID=$('#uid').val().substring($('#uid').val().lastIndexOf('/')+1, $('#uid').val().length); + + inputUID=$('#event_calendar').val()+srcUID; + dataToVcalendar(op, origUID, inputUID, '', delUID,isFormHidden); +} + +function save(isFormHidden, deleteMode) +{ + $('#event_details_template').scrollTop(0); + if(!deleteMode) + { + if($('#event_details_template').find('img[data-type=invalidSmall]').filter(function(){return this.style.display != 'none'}).length>0) + { + show_editor_loader_messageCalendar('vevent', 'message_error', localization[globalInterfaceLanguage].txtErorInput); + return false; + } + var a=$.datepicker.parseDate(globalSettings.datepickerformat.value, $('#date_from').val()); + var a2=$.datepicker.parseDate(globalSettings.datepickerformat.value, $('#date_to').val()); + + var datetime_from=$.fullCalendar.formatDate(a, 'yyyy-MM-dd'); + var datetime_to=$.fullCalendar.formatDate(a2, 'yyyy-MM-dd'); + var time_from='00:00'; + var time_to='00:00'; + if(!$('#allday').prop('checked')) + { + if($('#time_from').val()!='' && $('#time_to').val()!='') + { + time_from=new Date(Date.parse("01/02/1990, "+$('#time_from').val())); + time_from=$.fullCalendar.formatDate(time_from, 'HH:mm'); + time_to=new Date(Date.parse("01/02/1990, "+$('#time_to').val())); + time_to=$.fullCalendar.formatDate(time_to, 'HH:mm'); + } + } + if($.fullCalendar.parseDate(datetime_from+'T'+time_from+'Z')>$.fullCalendar.parseDate(datetime_to+'T'+time_to+'Z')) + { + show_editor_loader_messageCalendar('vevent', 'message_error', localization[globalInterfaceLanguage].txtErrorDates); + return false; + } + } + + var calUID=$('#uid').val().substring(0, $('#uid').val().lastIndexOf('/')); + + var newUID=$('#event_calendar').val().substring(0, $('#event_calendar').val().length-1); + if($('#event_calendar').val()!='choose') + { + if($('#name').val()=='') + $('#name').val(localization[globalInterfaceLanguage].pholderNewEvent); + + if(newUID==calUID || ($('#etag').val()=='' && $('#event_calendar').val()!='choose')) + addAndEdit(isFormHidden, deleteMode); +// else if(calUID.substring(0, calUID.lastIndexOf('/'))==newUID.substring(0, newUID.lastIndexOf('/'))) +// { +// var delUID=$('#uid').val(); +// interResourceEdit('MOVE_IN',delUID, isFormHidden); +// } + else if(/*calUID.substring(0, calUID.lastIndexOf('/'))!=newUID.substring(0, newUID.lastIndexOf('/')) &&*/ $('#etag').val()!='') + { + var delUID=$('#uid').val(); + interResourceEdit('MOVE_OTHER',delUID, isFormHidden); + } + } + else + show_editor_loader_messageCalendar('vevent', 'message_error', localization[globalInterfaceLanguage].txtNotChoose); +} + +function deleteEvent() +{ + var delUID=$('#uid').val(); + + if(delUID!='') + deleteVcalendarFromCollection(delUID,'vevent'); +} + +function loadAdditionalCollections(collectionType) +{ + if(globalSettingsSaving!='') + return false; + globalSettingsSaving=collectionType; + var inSettings = $.extend({},globalSettings); + var rex = new RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@(.*)'); + var sel = ''; + var key = ''; + if(collectionType=='event') + { + key='loadedcalendarcollections'; + inSettings.loadedcalendarcollections = {value:new Array(), locked: globalSettings[key].locked}; + $('#ResourceCalDAVList').find('.unloadCheck').each(function(cin,cel) + { + if($(cel).prop('checked')) + { + var uidParts=$(cel).attr('data-id').match(rex); + inSettings.loadedcalendarcollections.value.splice(inSettings.loadedcalendarcollections.value.length , 0, uidParts[1]+uidParts[3]); + } + + }); + } + else if(collectionType=='todo') + { + sel='TODO'; + key='loadedtodocollections'; + inSettings.loadedtodocollections = {value : new Array(), locked: globalSettings[key].locked}; + $('#ResourceCalDAVTODOList').find('.unloadCheck').each(function(cin,cel) + { + if($(cel).prop('checked')) + { + var uidParts=$(cel).attr('data-id').match(rex); + inSettings.loadedtodocollections.value.splice(inSettings.loadedtodocollections.value.length , 0, uidParts[1]+uidParts[3]); + } + }); + } + + if($(inSettings[key].value).not(globalSettings[key].value).length > 0 || $(globalSettings[key].value).not(inSettings[key].value).length > 0) + { + $('#CalendarLoader'+sel).removeClass('loader_hidden'); + $('#ResourceCalDAV'+sel+'List').find('input[type="checkbox"]').prop('disabled',true); + var setC=0; + for(var i=0;i'); + headerClickElm.change(function(){ + loadResourceChBoxClick(this, '#ResourceCalDAV'+sel+'List', resHeader, resItem, resItem); + }); + $(this).addClass('load_mode').append(headerClickElm); + }); + // caldav_item display + resList.find('.resourceCalDAV'+sel+'_item').each(function(){ + if(typeof $(this).attr('data-id') != 'undefined') + { + var newInputElm = $(''); + newInputElm.change(function(){ + loadCollectionChBoxClick(this, '#ResourceCalDAV'+sel+'List', resHeader, resItem, resItem); + }); + $(this).addClass('load_mode').append(newInputElm); + if($(this).css('display')=='none') + $(this).addClass('unloaded'); + else + newInputElm.prop('checked',true); + newInputElm.trigger('change'); + } + }); + $('#showUnloadedCalendars'+sel).css('display','none'); + $('#resourceCalDAV'+sel+'_h').find('.resourceCalDAV'+sel+'_text').text(localization[globalInterfaceLanguage][locString]); + var origH = resList.find('.resourceCalDAV'+sel+'_header.unloaded').eq(0).css('height'); + var origC = resList.find('.resourceCalDAV'+sel+'_item.unloaded').eq(0).css('height'); + resList.find('.resourceCalDAV'+sel+'_header.unloaded').css({height:0,display:''}).animate({height:origH},300); + resList.find('.resourceCalDAV'+sel+'_item.unloaded').css({height:0,display:''}).animate({height:origC},300); + resList.animate({'top':49},300); +} + +function cancelUnloadedCollections(collectionType) +{ + var sel=null; + var loadedCollections=null; + if(collectionType=='event') + { + sel=''; + loadedCollections=globalSettings.loadedcalendarcollections.value; + } + else if(collectionType=='todo') + { + sel='TODO'; + loadedCollections=globalSettings.loadedtodocollections.value; + } + + $('#ResourceCalDAV'+sel+'List').children('.resourceCalDAV'+sel+'_item').each(function(){ + var isLoaded=false; + if(typeof globalCrossServerSettingsURL!='undefined'&&globalCrossServerSettingsURL!=null&globalCrossServerSettingsURL) + { + var uidParts=$(this).attr('data-id').match(RegExp('/([^/]+/[^/]+/)$')); + var tmpParts = uidParts[1].match('^(.*/)([^/]+)/$'); + var checkHref=decodeURIComponent(tmpParts[1])+tmpParts[2]+'/'; + var found=false; + for(var l=0;l1 ? '30' : '00') + } + else + offset='+'+(offset<10 ? '0' : '')+offset.toString().split('.')[0]+(offset.toString().split('.').length>1 ? '30' : '00') + + return offset; +} + +Date.prototype.stdTimezoneOffset=function() +{ + var jan=new Date(this.getFullYear(), 0, 1); + var jul=new Date(this.getFullYear(), 6, 1); + return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); +} + +Date.prototype.dst=function() +{ + return this.getTimezoneOffset()