summaryrefslogtreecommitdiffstats
path: root/kresources/scalix
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch)
tree67208f7c145782a7e90b123b982ca78d88cc2c87 /kresources/scalix
downloadtdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz
tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kresources/scalix')
-rw-r--r--kresources/scalix/Makefile.am4
-rw-r--r--kresources/scalix/README9
-rw-r--r--kresources/scalix/kabc/Makefile.am27
-rw-r--r--kresources/scalix/kabc/contact.cpp377
-rw-r--r--kresources/scalix/kabc/contact.h37
-rw-r--r--kresources/scalix/kabc/resourcescalix.cpp628
-rw-r--r--kresources/scalix/kabc/resourcescalix.h170
-rw-r--r--kresources/scalix/kabc/resourcescalix_plugin.cpp53
-rw-r--r--kresources/scalix/kabc/scalix.desktop30
-rw-r--r--kresources/scalix/kcal/Makefile.am27
-rw-r--r--kresources/scalix/kcal/resourcescalix.cpp885
-rw-r--r--kresources/scalix/kcal/resourcescalix.h221
-rw-r--r--kresources/scalix/kcal/resourcescalix_plugin.cpp50
-rw-r--r--kresources/scalix/kcal/scalix.desktop31
-rw-r--r--kresources/scalix/kioslave/Makefile.am17
-rw-r--r--kresources/scalix/kioslave/scalix.cpp225
-rw-r--r--kresources/scalix/kioslave/scalix.h51
-rw-r--r--kresources/scalix/kioslave/scalix.protocol8
-rw-r--r--kresources/scalix/kioslave/scalixs.protocol8
-rw-r--r--kresources/scalix/knotes/Makefile.am28
-rw-r--r--kresources/scalix/knotes/resourcescalix.cpp425
-rw-r--r--kresources/scalix/knotes/resourcescalix.h127
-rw-r--r--kresources/scalix/knotes/resourcescalix_plugin.cpp50
-rw-r--r--kresources/scalix/knotes/scalix.desktop30
-rw-r--r--kresources/scalix/scalixadmin/Makefile.am15
-rw-r--r--kresources/scalix/scalixadmin/delegatedialog.cpp105
-rw-r--r--kresources/scalix/scalixadmin/delegatedialog.h53
-rw-r--r--kresources/scalix/scalixadmin/delegatemanager.cpp49
-rw-r--r--kresources/scalix/scalixadmin/delegatemanager.h49
-rw-r--r--kresources/scalix/scalixadmin/delegatepage.cpp170
-rw-r--r--kresources/scalix/scalixadmin/delegatepage.h60
-rw-r--r--kresources/scalix/scalixadmin/delegateview.cpp74
-rw-r--r--kresources/scalix/scalixadmin/delegateview.h48
-rw-r--r--kresources/scalix/scalixadmin/jobs.cpp306
-rw-r--r--kresources/scalix/scalixadmin/jobs.h202
-rw-r--r--kresources/scalix/scalixadmin/ldapdialog.cpp43
-rw-r--r--kresources/scalix/scalixadmin/ldapdialog.h39
-rw-r--r--kresources/scalix/scalixadmin/ldapview.cpp99
-rw-r--r--kresources/scalix/scalixadmin/ldapview.h51
-rw-r--r--kresources/scalix/scalixadmin/main.cpp53
-rw-r--r--kresources/scalix/scalixadmin/mainwindow.cpp59
-rw-r--r--kresources/scalix/scalixadmin/mainwindow.h32
-rw-r--r--kresources/scalix/scalixadmin/otherusermanager.cpp51
-rw-r--r--kresources/scalix/scalixadmin/otherusermanager.h47
-rw-r--r--kresources/scalix/scalixadmin/otheruserpage.cpp173
-rw-r--r--kresources/scalix/scalixadmin/otheruserpage.h60
-rw-r--r--kresources/scalix/scalixadmin/otheruserview.cpp71
-rw-r--r--kresources/scalix/scalixadmin/otheruserview.h44
-rw-r--r--kresources/scalix/scalixadmin/outofofficepage.cpp125
-rw-r--r--kresources/scalix/scalixadmin/outofofficepage.h57
-rw-r--r--kresources/scalix/scalixadmin/passwordpage.cpp190
-rw-r--r--kresources/scalix/scalixadmin/passwordpage.h55
-rw-r--r--kresources/scalix/scalixadmin/settings.cpp136
-rw-r--r--kresources/scalix/scalixadmin/settings.h56
-rw-r--r--kresources/scalix/shared/Makefile.am17
-rw-r--r--kresources/scalix/shared/kmailconnection.cpp281
-rw-r--r--kresources/scalix/shared/kmailconnection.h117
-rw-r--r--kresources/scalix/shared/resourcescalixbase.cpp179
-rw-r--r--kresources/scalix/shared/resourcescalixbase.h180
-rw-r--r--kresources/scalix/shared/scalixbase.cpp446
-rw-r--r--kresources/scalix/shared/scalixbase.h176
-rw-r--r--kresources/scalix/shared/subresource.cpp116
-rw-r--r--kresources/scalix/shared/subresource.h110
-rw-r--r--kresources/scalix/uninstall.desktop2
64 files changed, 7714 insertions, 0 deletions
diff --git a/kresources/scalix/Makefile.am b/kresources/scalix/Makefile.am
new file mode 100644
index 000000000..1a58c7ec9
--- /dev/null
+++ b/kresources/scalix/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS = shared kabc kcal kioslave knotes scalixadmin
+
+messages: rc.cpp
+ $(XGETTEXT) shared/*.cpp kabc/*.cpp kcal/*.cpp knotes/*.cpp -o $(podir)/kres_scalix.pot
diff --git a/kresources/scalix/README b/kresources/scalix/README
new file mode 100644
index 000000000..34a00e9ad
--- /dev/null
+++ b/kresources/scalix/README
@@ -0,0 +1,9 @@
+The Scalix Resource is based on the code of the Kolab resource as both
+groupware servers use a similar storage concept (storing pim items as
+email attachments on an IMAP server).
+
+However the Scalix Resource has several modifications, e.g. the XML storage
+type was removed and freebusy handling is done via a separated KIO slave.
+
+If you have any problems, questions or suggestions contact me under
+ Tobias Koenig <[email protected]>
diff --git a/kresources/scalix/kabc/Makefile.am b/kresources/scalix/kabc/Makefile.am
new file mode 100644
index 000000000..a9fbf2021
--- /dev/null
+++ b/kresources/scalix/kabc/Makefile.am
@@ -0,0 +1,27 @@
+METASOURCES = AUTO
+
+INCLUDES = -I$(top_srcdir)/kresources/scalix/shared -I$(top_srcdir) $(all_includes)
+
+# The scalix wizard links to this library too
+lib_LTLIBRARIES = libkabcscalix.la
+
+libkabcscalix_la_SOURCES = resourcescalix.cpp contact.cpp
+libkabcscalix_la_LDFLAGS = $(all_libraries) -no-undefined
+libkabcscalix_la_LIBADD = \
+ $(top_builddir)/kresources/scalix/shared/libresourcescalixshared.la \
+ -lkresources -lkabc
+
+kde_module_LTLIBRARIES = kabc_scalix.la
+
+noinst_HEADERS = resourcescalix.h
+
+kabc_scalix_la_SOURCES = resourcescalix_plugin.cpp
+kabc_scalix_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined
+kabc_scalix_la_LIBADD = libkabcscalix.la
+
+servicedir = $(kde_servicesdir)/kresources/kabc
+service_DATA = scalix.desktop
+
+install-data-local: $(srcdir)/../uninstall.desktop
+ $(mkinstalldirs) $(DESTDIR)$(servicedir)
+ $(INSTALL_DATA) $(srcdir)/../uninstall.desktop $(DESTDIR)$(servicedir)/imap.desktop
diff --git a/kresources/scalix/kabc/contact.cpp b/kresources/scalix/kabc/contact.cpp
new file mode 100644
index 000000000..156ae01af
--- /dev/null
+++ b/kresources/scalix/kabc/contact.cpp
@@ -0,0 +1,377 @@
+/*
+ * This file is part of the scalix resource.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qdom.h>
+
+#include <libkdepim/distributionlist.h>
+#include <kstaticdeleter.h>
+
+#include "contact.h"
+
+using namespace Scalix;
+
+static QMap<QString, QString> *s_distListMap = 0;
+static KStaticDeleter< QMap<QString, QString> > sd;
+
+static QString custom( const QString &name, const KABC::Addressee &addr, const QString &defaultValue = QString() )
+{
+ const QString value = addr.custom( "Scalix", name );
+ if ( value.isEmpty() )
+ return defaultValue;
+ else
+ return value;
+}
+
+static void setCustom( const QString &name, const QString &value, KABC::Addressee &addr )
+{
+ addr.insertCustom( "Scalix", name, value );
+}
+
+QString Contact::toXml( const KABC::Addressee &addr )
+{
+ /**
+ * Handle distribution lists.
+ */
+ if ( KPIM::DistributionList::isDistributionList( addr ) ) {
+ if ( s_distListMap )
+ return (*s_distListMap)[ addr.uid() ];
+ else
+ return QString();
+ }
+
+ /**
+ * Handle normal contacts.
+ */
+ QString xml;
+ xml += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+ xml += "<contact>\n";
+
+ xml += "<direct_ref>" + addr.uid() + "</direct_ref>\n";
+ xml += "<sensitivity>" + custom( "sensitivity", addr, "0" ) + "</sensitivity>\n";
+
+ xml += "<message_class>IPM.Contact</message_class>\n";
+ xml += "<is_recurring>" + custom( "is_recurring", addr, "false" ) + "</is_recurring>\n";
+ xml += "<reminder_set>" + custom( "reminder_set", addr, "false" ) + "</reminder_set>\n";
+ xml += "<send_rich_info>" + custom( "send_rich_info", addr, "false" ) + "</send_rich_info>\n";
+ xml += "<subject>" + addr.formattedName() + "</subject>\n";
+ xml += "<last_modification_time>" + addr.revision().toString( Qt::ISODate ) + "</last_modification_time>\n";
+
+ xml += "<display_name_prefix>" + addr.prefix() + "</display_name_prefix>\n";
+ xml += "<first_name>" + addr.givenName() + "</first_name>\n";
+ xml += "<middle_name>" + addr.additionalName() + "</middle_name>\n";
+ xml += "<last_name>" + addr.familyName() + "</last_name>\n";
+ xml += "<suffix>" + addr.suffix() + "</suffix>\n";
+ xml += "<display_name>" + addr.assembledName() + "</display_name>\n";
+ xml += "<file_as>" + addr.formattedName() + "</file_as>\n";
+ xml += "<nickname>" + addr.nickName() + "</nickname>\n";
+
+ xml += "<web_page_address>" + addr.url().url() + "</web_page_address>\n";
+ xml += "<company_name>" + addr.organization() + "</company_name>\n";
+ xml += "<job_title>" + addr.title() + "</job_title>\n";
+
+ QStringList emails = addr.emails();
+ for ( uint i = 0; i < 3; ++i ) {
+ QString type, address, comment, display;
+
+ if ( i < emails.count() ) {
+ type = "SMTP";
+ address = emails[ i ];
+
+ /**
+ * If the contact was created by kontact use the email address as
+ * display name and the formatted name as comment, otherwise we use
+ * the values from the server.
+ */
+ if ( custom( "comes_from_scalix", addr ) != "true" ) {
+ comment = addr.formattedName();
+ display = emails[ i ];
+ } else {
+ comment = custom( QString( "email%1_address_with_comment" ).arg( i + 1 ), addr );
+ display = custom( QString( "email%1_display_name" ).arg( i + 1 ), addr );
+ }
+ }
+
+ xml += QString( "<email%1_address_type>" ).arg( i + 1 ) + type +
+ QString( "</email%1_address_type>" ).arg( i + 1 ) +"\n";
+ xml += QString( "<email%1_address>" ).arg( i + 1 ) + address +
+ QString( "</email%1_address>" ).arg( i + 1 ) +"\n";
+ xml += QString( "<email%1_address_with_comment>" ).arg( i + 1 ) + comment +
+ QString( "</email%1_address_with_comment>" ).arg( i + 1 ) + "\n";
+ xml += QString( "<email%1_display_name>" ).arg( i + 1 ) + display +
+ QString( "</email%1_display_name>" ).arg( i + 1 ) + "\n";
+ }
+
+ KABC::PhoneNumber phone = addr.phoneNumber( KABC::PhoneNumber::Home );
+ xml += "<home_phone_number>" + phone.number() + "</home_phone_number>\n";
+
+ phone = addr.phoneNumber( KABC::PhoneNumber::Work );
+ xml += "<work_phone_number>" + phone.number() + "</work_phone_number>\n";
+
+ phone = addr.phoneNumber( KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax );
+ xml += "<work_fax_number>" + phone.number() + "</work_fax_number>\n";
+
+ phone = addr.phoneNumber( KABC::PhoneNumber::Cell );
+ xml += "<mobile_phone_number>" + phone.number() + "</mobile_phone_number>\n";
+
+ const KABC::Address workAddress = addr.address( KABC::Address::Work );
+ xml += "<work_address_street>" + workAddress.street() + "</work_address_street>\n";
+ xml += "<work_address_zip>" + workAddress.postalCode() + "</work_address_zip>\n";
+ xml += "<work_address_city>" + workAddress.locality() + "</work_address_city>\n";
+ xml += "<work_address_state>" + workAddress.region() + "</work_address_state>\n";
+ xml += "<work_address_country>" + workAddress.country() + "</work_address_country>\n";
+
+ const KABC::Address homeAddress = addr.address( KABC::Address::Home );
+ xml += "<home_address_street>" + homeAddress.street() + "</home_address_street>\n";
+ xml += "<home_address_zip>" + homeAddress.postalCode() + "</home_address_zip>\n";
+ xml += "<home_address_city>" + homeAddress.locality() + "</home_address_city>\n";
+ xml += "<home_address_state>" + homeAddress.region() + "</home_address_state>\n";
+ xml += "<home_address_country>" + homeAddress.country() + "</home_address_country>\n";
+
+ const KABC::Address otherAddress = addr.address( KABC::Address::Dom );
+ xml += "<other_address_street>" + otherAddress.street() + "</other_address_street>\n";
+ xml += "<other_address_zip>" + otherAddress.postalCode() + "</other_address_zip>\n";
+ xml += "<other_address_city>" + otherAddress.locality() + "</other_address_city>\n";
+ xml += "<other_address_state>" + otherAddress.region() + "</other_address_state>\n";
+ xml += "<other_address_country>" + otherAddress.country() + "</other_address_country>\n";
+
+ if ( homeAddress.type() & KABC::Address::Pref )
+ xml += "<selected_mailing_address>1</selected_mailing_address>\n";
+ else if ( workAddress.type() & KABC::Address::Pref )
+ xml += "<selected_mailing_address>2</selected_mailing_address>\n";
+ else if ( otherAddress.type() & KABC::Address::Pref )
+ xml += "<selected_mailing_address>3</selected_mailing_address>\n";
+
+ xml += "<im_address>" + addr.custom( "KADDRESSBOOK", "X-IMAddress" ) + "</im_address>\n";
+ xml += "<manager>" + addr.custom( "KADDRESSBOOK", "X-ManagersName" ) + "</manager>\n";
+ xml += "<department>" + addr.custom( "KADDRESSBOOK", "X-Department" ) + "</department>\n";
+ xml += "<assistant>" + addr.custom( "KADDRESSBOOK", "X-AssistantsName" ) + "</assistant>\n";
+ xml += "<profession>" + addr.custom( "KADDRESSBOOK", "X-Profession" ) + "</profession>\n";
+ xml += "<office_location>" + addr.custom( "KADDRESSBOOK", "X-Office" ) + "</office_location>\n";
+ xml += "<spouse>" + addr.custom( "KADDRESSBOOK", "X-SpousesName" ) + "</spouse>\n";
+
+ xml += "<bday>" + addr.birthday().toString( Qt::ISODate ) + "</bday>\n";
+ xml += "<anniversary>" + addr.custom( "KADDRESSBOOK", "X-Anniversary" ) + "</anniversary>\n";
+
+ xml += "<mapi_charset>" + custom( "mapi_charset", addr, "UTF8" ) + "</mapi_charset>";
+
+ xml += "</contact>\n";
+
+ return xml;
+}
+
+KABC::Addressee Contact::fromXml( const QString &xml )
+{
+ QDomDocument document;
+
+ QString errorMsg;
+ int errorLine, errorColumn;
+ if ( !document.setContent( xml, true, &errorMsg, &errorLine, &errorColumn ) ) {
+ qDebug( "Error parsing XML in Scalix::Contact::fromXml: %s (%d,%d)", errorMsg.latin1(), errorLine, errorColumn );
+ return KABC::Addressee();
+ }
+
+ QDomElement contactElement = document.documentElement();
+ if ( contactElement.tagName() != "contact" ) {
+ if ( contactElement.tagName() == "distlist" ) {
+ const QDomNodeList names = contactElement.elementsByTagName( "display_name" );
+ const QString listName = ( names.count() == 1 ? names.item( 0 ).toElement().text() : "Scalix Dummy List" );
+
+ /**
+ * As we can't provide distribution list functionality we store the entry
+ * here and return it on save.
+ */
+ KPIM::DistributionList list;
+ list.setName( listName );
+
+ if ( !s_distListMap )
+ sd.setObject( s_distListMap, new QMap<QString, QString>() );
+
+ s_distListMap->insert( list.uid(), xml );
+
+ return list;
+ } else {
+ qDebug( "Error interpreting XML in Scalix::Contact::fromXml: no 'contact' or 'distlist' tag found" );
+ return KABC::Addressee();
+ }
+ }
+
+ QString emails[ 3 ];
+ KABC::Address homeAddress( KABC::Address::Home );
+ KABC::Address workAddress( KABC::Address::Work );
+ KABC::Address otherAddress( KABC::Address::Dom );
+
+ KABC::Addressee addr;
+ setCustom( "comes_from_scalix", "true", addr );
+
+ QDomNode node = contactElement.firstChild();
+ while ( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if ( !element.isNull() ) {
+ if ( element.tagName() == "direct_ref" )
+ addr.setUid( element.text() );
+ else if ( element.tagName() == "sensitivity" )
+ setCustom( "sensitivity", element.text(), addr );
+ else if ( element.tagName() == "is_recurring" )
+ setCustom( "is_recurring", element.text(), addr );
+ else if ( element.tagName() == "reminder_set" )
+ setCustom( "reminder_set", element.text(), addr );
+ else if ( element.tagName() == "send_rich_info" )
+ setCustom( "send_rich_info", element.text(), addr );
+ else if ( element.tagName() == "last_modification_time" )
+ addr.setRevision( QDateTime::fromString( element.text(), Qt::ISODate ) );
+
+ // name
+ else if ( element.tagName() == "display_name_prefix" )
+ addr.setPrefix( element.text() );
+ else if ( element.tagName() == "first_name" )
+ addr.setGivenName( element.text() );
+ else if ( element.tagName() == "middle_name" )
+ addr.setAdditionalName( element.text() );
+ else if ( element.tagName() == "last_name" )
+ addr.setFamilyName( element.text() );
+ else if ( element.tagName() == "suffix" )
+ addr.setSuffix( element.text() );
+ else if ( element.tagName() == "file_as" )
+ addr.setFormattedName( element.text() );
+ else if ( element.tagName() == "nickname" )
+ addr.setNickName( element.text() );
+
+ // job
+ else if ( element.tagName() == "web_page_address" )
+ addr.setUrl( element.text() );
+ else if ( element.tagName() == "company_name" )
+ addr.setOrganization( element.text() );
+ else if ( element.tagName() == "job_title" )
+ addr.setTitle( element.text() );
+
+ // emails
+ else if ( element.tagName().startsWith( "email" ) ) {
+ if ( element.tagName() == "email1_address" )
+ emails[ 0 ] = element.text();
+ else if ( element.tagName() == "email2_address" )
+ emails[ 1 ] = element.text();
+ else if ( element.tagName() == "email3_address" )
+ emails[ 2 ] = element.text();
+ else
+ setCustom( element.tagName(), element.text(), addr );
+ }
+
+ // phone numbers
+ else if ( element.tagName() == "home_phone_number" )
+ addr.insertPhoneNumber( KABC::PhoneNumber( element.text(), KABC::PhoneNumber::Home ) );
+ else if ( element.tagName() == "work_phone_number" )
+ addr.insertPhoneNumber( KABC::PhoneNumber( element.text(), KABC::PhoneNumber::Work ) );
+ else if ( element.tagName() == "work_fax_number" )
+ addr.insertPhoneNumber( KABC::PhoneNumber( element.text(), KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax ) );
+ else if ( element.tagName() == "mobile_phone_number" )
+ addr.insertPhoneNumber( KABC::PhoneNumber( element.text(), KABC::PhoneNumber::Cell ) );
+
+ // address (work)
+ else if ( element.tagName() == "work_address_street" )
+ workAddress.setStreet( element.text() );
+ else if ( element.tagName() == "work_address_zip" )
+ workAddress.setPostalCode( element.text() );
+ else if ( element.tagName() == "work_address_city" )
+ workAddress.setLocality( element.text() );
+ else if ( element.tagName() == "work_address_state" )
+ workAddress.setRegion( element.text() );
+ else if ( element.tagName() == "work_address_country" )
+ workAddress.setCountry( element.text() );
+
+ // address (home)
+ else if ( element.tagName() == "home_address_street" )
+ homeAddress.setStreet( element.text() );
+ else if ( element.tagName() == "home_address_zip" )
+ homeAddress.setPostalCode( element.text() );
+ else if ( element.tagName() == "home_address_city" )
+ homeAddress.setLocality( element.text() );
+ else if ( element.tagName() == "home_address_state" )
+ homeAddress.setRegion( element.text() );
+ else if ( element.tagName() == "home_address_country" )
+ homeAddress.setCountry( element.text() );
+
+ // address (other)
+ else if ( element.tagName() == "other_address_street" )
+ otherAddress.setStreet( element.text() );
+ else if ( element.tagName() == "other_address_zip" )
+ otherAddress.setPostalCode( element.text() );
+ else if ( element.tagName() == "other_address_city" )
+ otherAddress.setLocality( element.text() );
+ else if ( element.tagName() == "other_address_state" )
+ otherAddress.setRegion( element.text() );
+ else if ( element.tagName() == "other_address_country" )
+ otherAddress.setCountry( element.text() );
+
+ else if ( element.tagName() == "selected_mailing_address" )
+ switch ( element.text().toInt() ) {
+ case 1:
+ homeAddress.setType( homeAddress.type() | KABC::Address::Pref );
+ break;
+ case 2:
+ workAddress.setType( workAddress.type() | KABC::Address::Pref );
+ break;
+ case 3:
+ otherAddress.setType( otherAddress.type() | KABC::Address::Pref );
+ break;
+ default:
+ Q_ASSERT( !"Unknown selected_mailing_address enum" );
+ break;
+ }
+
+ // misc
+ else if ( element.tagName() == "im_address" )
+ addr.insertCustom( "KADDRESSBOOK", "X-IMAddress", element.text() );
+ else if ( element.tagName() == "manager" )
+ addr.insertCustom( "KADDRESSBOOK", "X-ManagersName", element.text() );
+ else if ( element.tagName() == "department" )
+ addr.insertCustom( "KADDRESSBOOK", "X-Department", element.text() );
+ else if ( element.tagName() == "assistant" )
+ addr.insertCustom( "KADDRESSBOOK", "X-AssistantsName", element.text() );
+ else if ( element.tagName() == "profession" )
+ addr.insertCustom( "KADDRESSBOOK", "X-Profession", element.text() );
+ else if ( element.tagName() == "office_location" )
+ addr.insertCustom( "KADDRESSBOOK", "X-Office", element.text() );
+ else if ( element.tagName() == "spouse" )
+ addr.insertCustom( "KADDRESSBOOK", "X-SpousesName", element.text() );
+
+ else if ( element.tagName() == "bday" )
+ addr.setBirthday( QDateTime::fromString( element.text(), Qt::ISODate ) );
+ else if ( element.tagName() == "anniversary" )
+ addr.insertCustom( "KADDRESSBOOK", "X-Anniversary", element.text() );
+ else
+ setCustom( element.tagName(), element.text(), addr );
+ }
+
+ node = node.nextSibling();
+ }
+
+ for ( int i = 0; i < 3; ++i )
+ if ( !emails[ i ].isEmpty() )
+ addr.insertEmail( emails[ i ] );
+
+ if ( !homeAddress.isEmpty() )
+ addr.insertAddress( homeAddress );
+ if ( !workAddress.isEmpty() )
+ addr.insertAddress( workAddress );
+ if ( !otherAddress.isEmpty() )
+ addr.insertAddress( otherAddress );
+
+ return addr;
+}
diff --git a/kresources/scalix/kabc/contact.h b/kresources/scalix/kabc/contact.h
new file mode 100644
index 000000000..d73765ede
--- /dev/null
+++ b/kresources/scalix/kabc/contact.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the scalix resource.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SCALIX_CONTACT_H
+#define SCALIX_CONTACT_H
+
+#include <kabc/addressee.h>
+
+namespace Scalix {
+
+class Contact
+{
+ public:
+ static QString toXml( const KABC::Addressee &addr );
+ static KABC::Addressee fromXml( const QString &xml );
+};
+
+}
+
+#endif
diff --git a/kresources/scalix/kabc/resourcescalix.cpp b/kresources/scalix/kabc/resourcescalix.cpp
new file mode 100644
index 000000000..6cbf10832
--- /dev/null
+++ b/kresources/scalix/kabc/resourcescalix.cpp
@@ -0,0 +1,628 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2002 - 2004 Klar�lvdalens Datakonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "resourcescalix.h"
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <ktempfile.h>
+#include <kio/observer.h>
+#include <kio/uiserver_stub.h>
+#include <kmainwindow.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+
+#include <qobject.h>
+#include <qtimer.h>
+#include <qstring.h>
+#include <qfile.h>
+#include <qapplication.h>
+
+#include <assert.h>
+
+#include "contact.h"
+
+using namespace Scalix;
+
+class ScalixFactory : public KRES::PluginFactoryBase
+{
+ public:
+ KRES::Resource *resource( const KConfig *config )
+ {
+ return new KABC::ResourceScalix( config );
+ }
+
+ KRES::ConfigWidget *configWidget( QWidget* )
+ {
+ return 0;
+ }
+};
+
+K_EXPORT_COMPONENT_FACTORY(kabc_scalix,ScalixFactory)
+
+static const char* s_kmailContentsType = "Contact";
+static const char* s_attachmentMimeTypeContact = "application/x-vnd.kolab.contact";
+static const char* s_attachmentMimeTypeDistList = "application/x-vnd.kolab.contact.distlist";
+static const char* s_inlineMimeType = "application/scalix-properties";
+
+KABC::ResourceScalix::ResourceScalix( const KConfig *config )
+ : KPIM::ResourceABC( config ),
+ Scalix::ResourceScalixBase( "ResourceScalix-KABC" ),
+ mCachedSubresource( QString::null ), mLocked( false )
+{
+ setType( "scalix" );
+}
+
+KABC::ResourceScalix::~ResourceScalix()
+{
+ // The resource is deleted on exit (StdAddressBook's KStaticDeleter),
+ // and it wasn't closed before that, so close here to save the config.
+ if ( isOpen() ) {
+ close();
+ }
+}
+
+void KABC::ResourceScalix::loadSubResourceConfig( KConfig& config,
+ const QString& name,
+ const QString& label,
+ bool writable )
+{
+ KConfigGroup group( &config, name );
+ bool active = group.readBoolEntry( "Active", true );
+ int completionWeight = group.readNumEntry( "CompletionWeight", 80 );
+ mSubResources.insert( name, Scalix::SubResource( active, writable, label,
+ completionWeight ) );
+}
+
+bool KABC::ResourceScalix::doOpen()
+{
+ KConfig config( configFile() );
+
+ // Read the calendar entries
+ QValueList<KMailICalIface::SubResource> subResources;
+ if ( !kmailSubresources( subResources, s_kmailContentsType ) )
+ return false;
+ mSubResources.clear();
+ QValueList<KMailICalIface::SubResource>::ConstIterator it;
+ for ( it = subResources.begin(); it != subResources.end(); ++it ) {
+ loadSubResourceConfig( config, (*it).location, (*it).label, (*it).writable );
+ }
+
+ return true;
+}
+
+void KABC::ResourceScalix::doClose()
+{
+ KConfig config( configFile() );
+
+ Scalix::ResourceMap::ConstIterator it;
+ for ( it = mSubResources.begin(); it != mSubResources.end(); ++it ) {
+ config.setGroup( it.key() );
+ config.writeEntry( "Active", it.data().active() );
+ config.writeEntry( "CompletionWeight", it.data().completionWeight() );
+ }
+}
+
+KABC::Ticket * KABC::ResourceScalix::requestSaveTicket()
+{
+ if ( !addressBook() ) {
+ kdError() << "no addressbook" << endl;
+ return 0;
+ }
+ mLocked = true;
+
+ return createTicket( this );
+}
+
+void KABC::ResourceScalix::releaseSaveTicket( Ticket* ticket )
+{
+ mLocked = false;
+ mCachedSubresource = QString::null;
+ delete ticket;
+}
+
+QString KABC::ResourceScalix::loadContact( const QString& contactData,
+ const QString& subResource,
+ Q_UINT32 sernum,
+ KMailICalIface::StorageFormat )
+{
+ KABC::Addressee addr = Contact::fromXml( contactData );
+
+ addr.setResource( this );
+ addr.setChanged( false );
+ KABC::Resource::insertAddressee( addr ); // same as mAddrMap.insert( addr.uid(), addr );
+ mUidMap[ addr.uid() ] = StorageReference( subResource, sernum );
+ kdDebug(5650) << "Loaded contact uid=" << addr.uid() << " sernum=" << sernum << " fullName=" << addr.name() << endl;
+ return addr.uid();
+}
+
+bool KABC::ResourceScalix::loadSubResource( const QString& subResource )
+{
+ bool scalixcontacts = loadSubResourceHelper( subResource, s_attachmentMimeTypeContact, KMailICalIface::StorageXML );
+ bool scalixdistlists = loadSubResourceHelper( subResource, s_attachmentMimeTypeDistList, KMailICalIface::StorageXML );
+ bool vcardstyle = loadSubResourceHelper( subResource, s_inlineMimeType, KMailICalIface::StorageIcalVcard );
+ return scalixcontacts && scalixdistlists && vcardstyle;
+}
+
+bool KABC::ResourceScalix::loadSubResourceHelper( const QString& subResource,
+ const char* mimetype,
+ KMailICalIface::StorageFormat format )
+{
+ int count = 0;
+ if ( !kmailIncidencesCount( count, mimetype, subResource ) ) {
+ kdError() << "Communication problem in KABC::ResourceScalix::loadSubResourceHelper()\n";
+ return false;
+ }
+ if ( !count )
+ return true;
+
+ // Read that many contacts at a time.
+ // If this number is too small we lose time in kmail.
+ // If it's too big the progressbar is jumpy.
+ const int nbMessages = 200;
+
+ (void)Observer::self(); // ensure kio_uiserver is running
+ UIServer_stub uiserver( "kio_uiserver", "UIServer" );
+ int progressId = 0;
+ if ( count > 200 ) {
+ progressId = uiserver.newJob( kapp->dcopClient()->appId(), true );
+ uiserver.totalFiles( progressId, count );
+ uiserver.infoMessage( progressId, i18n( "Loading contacts..." ) );
+ uiserver.transferring( progressId, "Contacts" );
+ }
+
+ for ( int startIndex = 0; startIndex < count; startIndex += nbMessages ) {
+ QMap<Q_UINT32, QString> lst;
+
+ if ( !kmailIncidences( lst, mimetype, subResource, startIndex, nbMessages ) ) {
+ kdError() << "Communication problem in ResourceScalix::load()\n";
+ if ( progressId )
+ uiserver.jobFinished( progressId );
+ return false;
+ }
+
+ for( QMap<Q_UINT32, QString>::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
+ loadContact( it.data(), subResource, it.key(), format );
+ }
+ if ( progressId ) {
+ uiserver.processedFiles( progressId, startIndex );
+ uiserver.percent( progressId, 100 * startIndex / count );
+ }
+ }
+
+ kdDebug(5650) << "Contacts scalix resource: got " << count << " contacts in " << subResource << endl;
+
+ if ( progressId )
+ uiserver.jobFinished( progressId );
+ return true;
+}
+
+bool KABC::ResourceScalix::load()
+{
+ mUidMap.clear();
+ mAddrMap.clear();
+
+ bool rc = true;
+ Scalix::ResourceMap::ConstIterator itR;
+ for ( itR = mSubResources.begin(); itR != mSubResources.end(); ++itR ) {
+ if ( !itR.data().active() )
+ // This resource is disabled
+ continue;
+
+ rc &= loadSubResource( itR.key() );
+ }
+
+ return rc;
+}
+
+bool KABC::ResourceScalix::save( Ticket* )
+{
+ bool rc = true;
+
+ for( ConstIterator it = begin(); it != end(); ++it )
+ if( (*it).changed() ) {
+ rc &= kmailUpdateAddressee( *it );
+ }
+
+ if ( !rc )
+ kdDebug(5650) << k_funcinfo << " failed." << endl;
+ return rc;
+}
+
+namespace Scalix {
+struct AttachmentList {
+ QStringList attachmentURLs;
+ QStringList attachmentNames;
+ QStringList attachmentMimeTypes;
+ QStringList deletedAttachments;
+ QValueList<KTempFile *> tempFiles;
+
+ void addAttachment( const QString& url, const QString& name, const QString& mimetype ) {
+ attachmentURLs.append( url );
+ attachmentNames.append( name );
+ attachmentMimeTypes.append( mimetype );
+ }
+
+ void updatePictureAttachment( const QImage& image, const QString& name );
+ void updateAttachment( const QByteArray& data, const QString& name, const char* mimetype );
+};
+} // namespace
+
+void AttachmentList::updatePictureAttachment( const QImage& image, const QString& name )
+{
+ assert( !name.isEmpty() );
+ if ( !image.isNull() ) {
+ KTempFile* tempFile = new KTempFile;
+ image.save( tempFile->file(), "PNG" );
+ tempFile->close();
+ KURL url;
+ url.setPath( tempFile->name() );
+ kdDebug(5650) << "picture saved to " << url.path() << endl;
+ addAttachment( url.url(), name, "image/png" );
+ } else {
+ deletedAttachments.append( name );
+ }
+}
+
+void AttachmentList::updateAttachment( const QByteArray& data, const QString& name, const char* mimetype )
+{
+ assert( !name.isEmpty() );
+ if ( !data.isNull() ) {
+ KTempFile* tempFile = new KTempFile;
+ tempFile->file()->writeBlock( data );
+ tempFile->close();
+ KURL url;
+ url.setPath( tempFile->name() );
+ kdDebug(5650) << "data saved to " << url.path() << endl;
+ addAttachment( url.url(), name, mimetype );
+ } else {
+ deletedAttachments.append( name );
+ }
+}
+
+bool KABC::ResourceScalix::kmailUpdateAddressee( const Addressee& addr )
+{
+ const QString uid = addr.uid();
+ QString subResource;
+ Q_UINT32 sernum;
+ if ( mUidMap.find( uid ) != mUidMap.end() ) {
+ subResource = mUidMap[ uid ].resource();
+ if ( !subresourceWritable( subResource ) ) {
+ kdWarning() << "Wow! Something tried to update a non-writable addressee! Fix this caller: " << kdBacktrace() << endl;
+ return false;
+ }
+ sernum = mUidMap[ uid ].serialNumber();
+ } else {
+ if ( !mCachedSubresource.isNull() ) {
+ subResource = mCachedSubresource;
+ } else {
+ subResource = findWritableResource( mSubResources );
+ // We were locked, remember the subresource we are working with until
+ // we are unlocked
+ if ( mLocked )
+ mCachedSubresource = subResource;
+ }
+ if ( subResource.isEmpty() )
+ return false;
+ sernum = 0;
+ }
+
+ AttachmentList att;
+ QString subject = addr.formattedName();
+
+ QString mimetype = s_inlineMimeType;
+
+ QString data = Contact::toXml( addr );
+
+ CustomHeaderMap customHeaders;
+ customHeaders.insert( "X-Scalix-Class", "IPM.Contact" );
+
+ bool rc = kmailUpdate( subResource, sernum, data, mimetype, subject,
+ customHeaders,
+ att.attachmentURLs, att.attachmentMimeTypes, att.attachmentNames,
+ att.deletedAttachments );
+ if ( !rc )
+ kdDebug(5650) << "kmailUpdate returned false!" << endl;
+ if ( rc ) {
+ kdDebug(5650) << "kmailUpdate returned, now sernum=" << sernum << " for uid=" << uid << endl;
+ mUidMap[ uid ] = StorageReference( subResource, sernum );
+ // This is ugly, but it's faster than doing
+ // mAddrMap.find(addr.uid()), which would give the same :-(
+ // Reason for this: The Changed attribute of Addressee should
+ // be mutable
+ const_cast<Addressee&>(addr).setChanged( false );
+ }
+
+ for( QValueList<KTempFile *>::Iterator it = att.tempFiles.begin(); it != att.tempFiles.end(); ++it ) {
+ (*it)->setAutoDelete( true );
+ delete (*it);
+ }
+ return rc;
+}
+
+void KABC::ResourceScalix::insertAddressee( const Addressee& addr )
+{
+ const QString uid = addr.uid();
+ //kdDebug(5650) << k_funcinfo << uid << endl;
+ bool ok = false;
+ if ( mUidMap.contains( uid ) ) {
+ mUidsPendingUpdate.append( uid );
+ } else {
+ mUidsPendingAdding.append( uid );
+ }
+
+ ok = kmailUpdateAddressee( addr );
+
+ if ( ok )
+ Resource::insertAddressee( addr );
+}
+
+void KABC::ResourceScalix::removeAddressee( const Addressee& addr )
+{
+ const QString uid = addr.uid();
+ if ( mUidMap.find( uid ) == mUidMap.end() ) return;
+ //kdDebug(5650) << k_funcinfo << uid << endl;
+ const QString resource = mUidMap[ uid ].resource();
+ if ( !subresourceWritable( resource ) ) {
+ kdWarning() << "Wow! Something tried to delete a non-writable addressee! Fix this caller: " << kdBacktrace() << endl;
+ return;
+ }
+ /* The user told us to delete, tell KMail */
+ kmailDeleteIncidence( resource,
+ mUidMap[ uid ].serialNumber() );
+ mUidsPendingDeletion.append( uid );
+ mUidMap.remove( uid );
+
+ Resource::removeAddressee( addr );
+}
+
+/*
+ * These are the DCOP slots that KMail call to notify when something
+ * changed.
+ */
+bool KABC::ResourceScalix::fromKMailAddIncidence( const QString& type,
+ const QString& subResource,
+ Q_UINT32 sernum,
+ int format,
+ const QString& contactXML )
+{
+ // Check if this is a contact
+ if( type != s_kmailContentsType || !subresourceActive( subResource ) )
+ return false;
+
+ // Load contact to find the UID
+ const QString uid = loadContact( contactXML, subResource, sernum,
+ ( KMailICalIface::StorageFormat )format );
+
+ //kdDebug(5650) << k_funcinfo << uid << endl;
+
+ // Emit "addressbook changed" if this comes from kmail and not from the GUI
+ if ( !mUidsPendingAdding.contains( uid )
+ && !mUidsPendingUpdate.contains( uid ) ) {
+ addressBook()->emitAddressBookChanged();
+ } else {
+ mUidsPendingAdding.remove( uid );
+ mUidsPendingUpdate.remove( uid );
+ }
+
+ return true;
+}
+
+void KABC::ResourceScalix::fromKMailDelIncidence( const QString& type,
+ const QString& subResource,
+ const QString& uid )
+{
+ // Check if this is a contact
+ if( type != s_kmailContentsType || !subresourceActive( subResource ) )
+ return;
+
+ //kdDebug(5650) << k_funcinfo << uid << endl;
+
+ // Can't be in both, by contract
+ if ( mUidsPendingDeletion.contains( uid ) ) {
+ mUidsPendingDeletion.remove( uid );
+ } else if ( mUidsPendingUpdate.contains( uid ) ) {
+ // It's good to know if was deleted, but we are waiting on a new one to
+ // replace it, so let's just sit tight.
+ } else {
+ // We didn't trigger this, so KMail did, remove the reference to the uid
+ mAddrMap.remove( uid );
+ mUidMap.remove( uid );
+ addressBook()->emitAddressBookChanged();
+ }
+}
+
+void KABC::ResourceScalix::fromKMailRefresh( const QString& type,
+ const QString& /*subResource*/ )
+{
+ // Check if this is a contact
+ if( type != s_kmailContentsType ) return;
+
+ //kdDebug(5650) << k_funcinfo << endl;
+
+ load(); // ### should call loadSubResource(subResource) probably
+ addressBook()->emitAddressBookChanged();
+}
+
+void KABC::ResourceScalix::fromKMailAddSubresource( const QString& type,
+ const QString& subResource,
+ const QString& label,
+ bool writable )
+{
+ if( type != s_kmailContentsType ) return;
+
+ if ( mSubResources.contains( subResource ) )
+ // Already registered
+ return;
+
+ KConfig config( configFile() );
+ config.setGroup( "Contact" );
+ loadSubResourceConfig( config, subResource, label, writable );
+ loadSubResource( subResource );
+ addressBook()->emitAddressBookChanged();
+ emit signalSubresourceAdded( this, type, subResource );
+}
+
+void KABC::ResourceScalix::fromKMailDelSubresource( const QString& type,
+ const QString& subResource )
+{
+ if( type != s_kmailContentsType ) return;
+
+ if ( !mSubResources.contains( subResource ) )
+ // Not registered
+ return;
+
+ // Ok, it's our job, and we have it here
+ mSubResources.erase( subResource );
+
+ KConfig config( configFile() );
+ config.deleteGroup( subResource );
+ config.sync();
+
+ // Make a list of all uids to remove
+ Scalix::UidMap::ConstIterator mapIt;
+ QStringList uids;
+ for ( mapIt = mUidMap.begin(); mapIt != mUidMap.end(); ++mapIt )
+ if ( mapIt.data().resource() == subResource )
+ // We have a match
+ uids << mapIt.key();
+
+ // Finally delete all the incidences
+ if ( !uids.isEmpty() ) {
+ QStringList::ConstIterator it;
+ for ( it = uids.begin(); it != uids.end(); ++it ) {
+ mAddrMap.remove( *it );
+ mUidMap.remove( *it );
+ }
+
+ addressBook()->emitAddressBookChanged();
+ }
+
+ emit signalSubresourceRemoved( this, type, subResource );
+}
+
+
+
+void KABC::ResourceScalix::fromKMailAsyncLoadResult( const QMap<Q_UINT32, QString>& map,
+ const QString& /* type */,
+ const QString& folder )
+{
+ // FIXME
+ KMailICalIface::StorageFormat format = KMailICalIface::StorageXML;
+ for( QMap<Q_UINT32, QString>::ConstIterator it = map.begin(); it != map.end(); ++it ) {
+ loadContact( it.data(), folder, it.key(), format );
+ }
+ if ( !addressBook() ){
+ kdDebug(5650) << "asyncLoadResult() : addressBook() returning NULL pointer.\n";
+ }else
+ addressBook()->emitAddressBookChanged();
+}
+
+QStringList KABC::ResourceScalix::subresources() const
+{
+ return mSubResources.keys();
+}
+
+bool KABC::ResourceScalix::subresourceActive( const QString& subresource ) const
+{
+ if ( mSubResources.contains( subresource ) ) {
+ return mSubResources[ subresource ].active();
+ }
+
+ // Safe default bet:
+ kdDebug(5650) << "subresourceActive( " << subresource << " ): Safe bet\n";
+
+ return true;
+}
+
+bool KABC::ResourceScalix::subresourceWritable( const QString& subresource ) const
+{
+ if ( mSubResources.contains( subresource ) ) {
+ return mSubResources[ subresource ].writable();
+ }
+ return false; //better a safe default
+}
+
+int KABC::ResourceScalix::subresourceCompletionWeight( const QString& subresource ) const
+{
+ if ( mSubResources.contains( subresource ) ) {
+ return mSubResources[ subresource ].completionWeight();
+ }
+
+ kdDebug(5650) << "subresourceCompletionWeight( " << subresource << " ): not found, using default\n";
+
+ return 80;
+}
+
+QString KABC::ResourceScalix::subresourceLabel( const QString& subresource ) const
+{
+ if ( mSubResources.contains( subresource ) ) {
+ return mSubResources[ subresource ].label();
+ }
+
+ kdDebug(5650) << "subresourceLabel( " << subresource << " ): not found!\n";
+ return QString::null;
+}
+
+void KABC::ResourceScalix::setSubresourceCompletionWeight( const QString& subresource, int completionWeight )
+{
+ if ( mSubResources.contains( subresource ) ) {
+ mSubResources[ subresource ].setCompletionWeight( completionWeight );
+ } else {
+ kdDebug(5650) << "setSubresourceCompletionWeight: subresource " << subresource << " not found" << endl;
+ }
+}
+
+QMap<QString, QString> KABC::ResourceScalix::uidToResourceMap() const
+{
+ // TODO: Couldn't this be made simpler?
+ QMap<QString, QString> map;
+ Scalix::UidMap::ConstIterator mapIt;
+ for ( mapIt = mUidMap.begin(); mapIt != mUidMap.end(); ++mapIt )
+ map[ mapIt.key() ] = mapIt.data().resource();
+ return map;
+}
+
+void KABC::ResourceScalix::setSubresourceActive( const QString &subresource, bool active )
+{
+ if ( mSubResources.contains( subresource ) ) {
+ mSubResources[ subresource ].setActive( active );
+ load();
+ } else {
+ kdDebug(5650) << "setSubresourceCompletionWeight: subresource " << subresource << " not found" << endl;
+ }
+}
+
+#include "resourcescalix.moc"
diff --git a/kresources/scalix/kabc/resourcescalix.h b/kresources/scalix/kabc/resourcescalix.h
new file mode 100644
index 000000000..10d3d8aa5
--- /dev/null
+++ b/kresources/scalix/kabc/resourcescalix.h
@@ -0,0 +1,170 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2002 - 2004 Klar�lvdalens Datakonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef KABC_RESOURCESCALIX_H
+#define KABC_RESOURCESCALIX_H
+
+#include <libkdepim/resourceabc.h>
+#include <dcopobject.h>
+#include "../shared/resourcescalixbase.h"
+#include "../shared/subresource.h"
+#include <kmail/kmailicalIface.h>
+#include <kdepimmacros.h>
+
+namespace KABC {
+
+ class FormatPlugin;
+
+/**
+ * This class implements a KAddressBook resource that keeps its
+ * addresses in an Scalix folder in KMail (or other conforming email
+ * clients).
+ */
+class KDE_EXPORT ResourceScalix : public KPIM::ResourceABC,
+ public Scalix::ResourceScalixBase
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor
+ */
+ ResourceScalix( const KConfig* );
+
+ /**
+ * Destructor.
+ */
+ virtual ~ResourceScalix();
+
+ /**
+ * Open the contacts list
+ */
+ virtual bool doOpen();
+
+ /**
+ * Request a ticket, you have to pass through save() to
+ * allow locking.
+ */
+ virtual Ticket *requestSaveTicket();
+
+ /**
+ Releases the ticket previousely requested with requestSaveTicket().
+ The resource has to remove its locks in this function.
+ */
+ virtual void releaseSaveTicket( Ticket* );
+
+ /**
+ * Load all addressees to the addressbook
+ */
+ virtual bool load();
+
+ /**
+ * Save all addressees to the addressbook.
+ *
+ * @param ticket The ticket you get by requestSaveTicket()
+ */
+ virtual bool save( Ticket *ticket );
+
+ /**
+ Insert an addressee into the resource.
+ */
+ virtual void insertAddressee( const Addressee& );
+
+ /**
+ * Removes a addressee from resource. This method is mainly
+ * used by record-based resources like LDAP or SQL.
+ */
+ virtual void removeAddressee( const Addressee& addr );
+
+ // Listen to KMail changes in the amount of sub resources
+ void fromKMailAddSubresource( const QString& type, const QString& id,
+ const QString& label, bool writable );
+ void fromKMailDelSubresource( const QString& type, const QString& id );
+
+ bool fromKMailAddIncidence( const QString& type, const QString& resource,
+ Q_UINT32 sernum, int format, const QString& contact );
+ void fromKMailDelIncidence( const QString& type, const QString& resource,
+ const QString& contact );
+ void fromKMailRefresh( const QString& type, const QString& resource );
+
+ void fromKMailAsyncLoadResult( const QMap<Q_UINT32, QString>& map,
+ const QString& type,
+ const QString& folder );
+
+ /// Return the list of subresources.
+ QStringList subresources() const;
+
+ /// Is this subresource active?
+ bool subresourceActive( const QString& ) const;
+ /// Is this subresource writabel?
+ bool subresourceWritable( const QString& ) const;
+
+ virtual void setSubresourceActive( const QString &, bool );
+
+ /// Completion weight for a given subresource
+ virtual int subresourceCompletionWeight( const QString& ) const;
+
+ /// Label for a given subresource
+ virtual QString subresourceLabel( const QString& ) const;
+
+ /// Set completion weight for a given subresource
+ virtual void setSubresourceCompletionWeight( const QString&, int );
+
+ /// Give the uidmap. Used for ordered searching
+ QMap<QString, QString> uidToResourceMap() const;
+
+protected:
+ bool kmailUpdateAddressee( const Addressee& );
+
+ void doClose();
+
+ void loadSubResourceConfig( KConfig& config, const QString& name,
+ const QString& label, bool writable );
+ bool loadSubResource( const QString& subResource );
+ bool loadSubResourceHelper( const QString& subResource, const char* mimetype, KMailICalIface::StorageFormat format );
+ QString loadContact( const QString& contactData, const QString& subResource,
+ Q_UINT32 sernum, const KMailICalIface::StorageFormat format );
+
+ QString configFile() const {
+ return Scalix::ResourceScalixBase::configFile( "kabc" );
+ }
+
+ // The list of subresources
+ Scalix::ResourceMap mSubResources;
+ QString mCachedSubresource;
+ bool mLocked;
+};
+
+}
+
+#endif // KABC_RESOURCESCALIX_H
diff --git a/kresources/scalix/kabc/resourcescalix_plugin.cpp b/kresources/scalix/kabc/resourcescalix_plugin.cpp
new file mode 100644
index 000000000..95bc28beb
--- /dev/null
+++ b/kresources/scalix/kabc/resourcescalix_plugin.cpp
@@ -0,0 +1,53 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2002 - 2004 Klar�lvdalens Datakonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "resourcescalix.h"
+
+using namespace Scalix;
+
+class ScalixFactory : public KRES::PluginFactoryBase
+{
+ public:
+ KRES::Resource *resource( const KConfig *config )
+ {
+ return new KABC::ResourceScalix( config );
+ }
+
+ KRES::ConfigWidget *configWidget( QWidget* )
+ {
+ return 0;
+ }
+};
+
+K_EXPORT_COMPONENT_FACTORY(kabc_scalix,ScalixFactory)
+
diff --git a/kresources/scalix/kabc/scalix.desktop b/kresources/scalix/kabc/scalix.desktop
new file mode 100644
index 000000000..b91af2470
--- /dev/null
+++ b/kresources/scalix/kabc/scalix.desktop
@@ -0,0 +1,30 @@
+[Desktop Entry]
+Name=Addressbook on Scalix Server via KMail
+Name[bg]=Адресник на сървъра Scalix през KMail
+Name[ca]=Llibreta d'adreces en un servidor Scalix mitjançant el KMail
+Name[da]=Adressebog på Scalix-server via KMail
+Name[de]=Adressbuch auf einem Scalix-Server via KMail
+Name[el]=Βιβλίο διευθύνσεων σε εξυπηρετητή Scalix μέσω του KMail
+Name[es]=Libreta de direcciones en servidor Scalix por medio de KMail
+Name[et]=Aadressiraamat Scalix-serveris (KMaili vahendusel)
+Name[fr]=Carnet d'adresses sur serveur Scalix via KMail
+Name[is]=Vistfangaskrá á Scalix-þjóni gegnum KMail
+Name[it]=Rubrica indirizzi su server Scalix via KMail
+Name[ja]=KMail 経由 Scalix サーバのアドレス帳
+Name[km]=សៀវភៅ​អាសយដ្ឋាន​នៅ​លើ​ម៉ាស៊ីន​បម្រើ Scalix តាម​រយៈ KMail
+Name[nds]=Adressbook op Scalix-Server över KMail
+Name[nl]=Adresboek op Scalix-server via KMail
+Name[pl]=Książka adresowa na serwerze Scalix za pośrednictwem KMaila
+Name[ru]=Адресная книга на сервере Scalix через KMail
+Name[sk]=Adresár na Scalix serveri pomocou KMail
+Name[sr]=Адресар на Scalix серверу преко KMail-а
+Name[sr@Latn]=Adresar na Scalix serveru preko KMail-a
+Name[sv]=Adressbok på Scalix-server via Kmail
+Name[tr]=KMail Aracılığı ile Scalix Sunucusunda Adres Defteri
+Name[zh_CN]=通过 KMail 访问 Scalix 服务器上的地址簿
+Name[zh_TW]=透過 KMail 取得 Scalix 伺服器上的通訊錄
+X-KDE-Library=kabc_scalix
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=contact
+X-KDE-ResourceType=scalix
diff --git a/kresources/scalix/kcal/Makefile.am b/kresources/scalix/kcal/Makefile.am
new file mode 100644
index 000000000..060c5c00c
--- /dev/null
+++ b/kresources/scalix/kcal/Makefile.am
@@ -0,0 +1,27 @@
+METASOURCES = AUTO
+
+INCLUDES = -I$(top_srcdir)/kresources/scalix/shared -I$(top_srcdir) \
+ -I$(top_builddir)/libkdepim $(all_includes)
+
+# The scalix wizard links to this library too
+lib_LTLIBRARIES = libkcalscalix.la
+
+libkcalscalix_la_SOURCES = resourcescalix.cpp
+libkcalscalix_la_LDFLAGS = $(all_libraries) -no-undefined
+libkcalscalix_la_LIBADD = $(top_builddir)/libkcal/libkcal.la \
+ $(top_builddir)/kresources/scalix/shared/libresourcescalixshared.la \
+ -lkresources
+
+kde_module_LTLIBRARIES = kcal_scalix.la
+
+kcal_scalix_la_SOURCES = resourcescalix_plugin.cpp
+kcal_scalix_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined
+kcal_scalix_la_LIBADD = libkcalscalix.la
+
+servicedir = $(kde_servicesdir)/kresources/kcal
+service_DATA = scalix.desktop
+
+install-data-local: $(srcdir)/../uninstall.desktop
+ $(mkinstalldirs) $(DESTDIR)$(servicedir)
+ $(INSTALL_DATA) $(srcdir)/../uninstall.desktop $(DESTDIR)$(servicedir)/imap.desktop
+
diff --git a/kresources/scalix/kcal/resourcescalix.cpp b/kresources/scalix/kcal/resourcescalix.cpp
new file mode 100644
index 000000000..9a8beeb9e
--- /dev/null
+++ b/kresources/scalix/kcal/resourcescalix.cpp
@@ -0,0 +1,885 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+ 2004 Till Adam <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "resourcescalix.h"
+
+#include <kio/observer.h>
+#include <kio/uiserver_stub.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <libkcal/icalformat.h>
+#include <libkdepim/kincidencechooser.h>
+#include <kabc/locknull.h>
+#include <kmainwindow.h>
+#include <klocale.h>
+
+#include <qobject.h>
+#include <qtimer.h>
+#include <qapplication.h>
+
+#include <assert.h>
+
+using namespace KCal;
+using namespace Scalix;
+
+static const char* kmailCalendarContentsType = "Calendar";
+static const char* kmailTodoContentsType = "Task";
+static const char* kmailJournalContentsType = "Journal";
+static const char* eventAttachmentMimeType = "application/x-vnd.kolab.event";
+static const char* todoAttachmentMimeType = "application/x-vnd.kolab.task";
+static const char* journalAttachmentMimeType = "application/x-vnd.kolab.journal";
+static const char* incidenceInlineMimeType = "text/calendar";
+
+
+ResourceScalix::ResourceScalix( const KConfig *config )
+ : ResourceCalendar( config ), ResourceScalixBase( "ResourceScalix-libkcal" ),
+ mCalendar( QString::fromLatin1("UTC") ), mOpen( false )
+{
+ setType( "scalix" );
+ connect( &mResourceChangedTimer, SIGNAL( timeout() ),
+ this, SLOT( slotEmitResourceChanged() ) );
+}
+
+ResourceScalix::~ResourceScalix()
+{
+ // The resource is deleted on exit (StdAddressBook's KStaticDeleter),
+ // and it wasn't closed before that, so close here to save the config.
+ if ( mOpen ) {
+ close();
+ }
+}
+
+void ResourceScalix::loadSubResourceConfig( KConfig& config,
+ const QString& name,
+ const QString& label,
+ bool writable,
+ ResourceMap& subResource )
+{
+ KConfigGroup group( &config, name );
+ bool active = group.readBoolEntry( "Active", true );
+ subResource.insert( name, Scalix::SubResource( active, writable, label ) );
+}
+
+bool ResourceScalix::openResource( KConfig& config, const char* contentType,
+ ResourceMap& map )
+{
+ // Read the subresource entries from KMail
+ QValueList<KMailICalIface::SubResource> subResources;
+ if ( !kmailSubresources( subResources, contentType ) )
+ return false;
+ map.clear();
+ QValueList<KMailICalIface::SubResource>::ConstIterator it;
+ for ( it = subResources.begin(); it != subResources.end(); ++it )
+ loadSubResourceConfig( config, (*it).location, (*it).label, (*it).writable, map );
+ return true;
+}
+
+bool ResourceScalix::doOpen()
+{
+ if ( mOpen )
+ // Already open
+ return true;
+ mOpen = true;
+
+ KConfig config( configFile() );
+ config.setGroup( "General" );
+ mProgressDialogIncidenceLimit = config.readNumEntry("ProgressDialogIncidenceLimit", 200);
+
+ return openResource( config, kmailCalendarContentsType, mEventSubResources )
+ && openResource( config, kmailTodoContentsType, mTodoSubResources )
+ && openResource( config, kmailJournalContentsType, mJournalSubResources );
+}
+
+static void closeResource( KConfig& config, ResourceMap& map )
+{
+ ResourceMap::ConstIterator it;
+ for ( it = map.begin(); it != map.end(); ++it ) {
+ config.setGroup( it.key() );
+ config.writeEntry( "Active", it.data().active() );
+ }
+}
+
+void ResourceScalix::doClose()
+{
+ if ( !mOpen )
+ // Not open
+ return;
+ mOpen = false;
+
+ KConfig config( configFile() );
+ closeResource( config, mEventSubResources );
+ closeResource( config, mTodoSubResources );
+ closeResource( config, mJournalSubResources );
+}
+
+bool ResourceScalix::loadSubResource( const QString& subResource,
+ const char* mimetype )
+{
+ int count = 0;
+ if ( !kmailIncidencesCount( count, mimetype, subResource ) ) {
+ kdError(5650) << "Communication problem in ResourceScalix::load()\n";
+ return false;
+ }
+
+ if ( !count )
+ return true;
+
+ const int nbMessages = 200; // read 200 mails at a time (see kabc resource)
+
+ const QString labelTxt = !strcmp(mimetype, "application/x-vnd.kolab.task") ? i18n( "Loading tasks..." )
+ : !strcmp(mimetype, "application/x-vnd.kolab.journal") ? i18n( "Loading journals..." )
+ : i18n( "Loading events..." );
+ const bool useProgress = qApp && qApp->type() != QApplication::Tty && count > mProgressDialogIncidenceLimit;
+ if ( useProgress )
+ (void)::Observer::self(); // ensure kio_uiserver is running
+ UIServer_stub uiserver( "kio_uiserver", "UIServer" );
+ int progressId = 0;
+ if ( useProgress ) {
+ progressId = uiserver.newJob( kapp->dcopClient()->appId(), true );
+ uiserver.totalFiles( progressId, count );
+ uiserver.infoMessage( progressId, labelTxt );
+ uiserver.transferring( progressId, labelTxt );
+ }
+
+ for ( int startIndex = 0; startIndex < count; startIndex += nbMessages ) {
+ QMap<Q_UINT32, QString> lst;
+ if ( !kmailIncidences( lst, mimetype, subResource, startIndex, nbMessages ) ) {
+ kdError(5650) << "Communication problem in ResourceScalix::load()\n";
+ if ( progressId )
+ uiserver.jobFinished( progressId );
+ return false;
+ }
+
+ { // for RAII scoping below
+ TemporarySilencer t( this );
+ for( QMap<Q_UINT32, QString>::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
+ addIncidence( mimetype, it.data(), subResource, it.key() );
+ }
+ }
+ if ( progressId ) {
+ uiserver.processedFiles( progressId, startIndex );
+ uiserver.percent( progressId, 100 * startIndex / count );
+ }
+ }
+
+ if ( progressId )
+ uiserver.jobFinished( progressId );
+ return true;
+}
+
+bool ResourceScalix::doLoad()
+{
+ mUidMap.clear();
+
+ return loadAllEvents() & loadAllTodos() & loadAllJournals();
+}
+
+bool ResourceScalix::doLoadAll( ResourceMap& map, const char* mimetype )
+{
+ bool rc = true;
+ for ( ResourceMap::ConstIterator it = map.begin(); it != map.end(); ++it ) {
+ if ( !it.data().active() )
+ // This resource is disabled
+ continue;
+
+ rc &= loadSubResource( it.key(), mimetype );
+ }
+ return rc;
+}
+
+bool ResourceScalix::loadAllEvents()
+{
+ removeIncidences( "Event" );
+ mCalendar.deleteAllEvents();
+ return doLoadAll( mEventSubResources, incidenceInlineMimeType );
+}
+
+bool ResourceScalix::loadAllTodos()
+{
+ removeIncidences( "Todo" );
+ mCalendar.deleteAllTodos();
+ return doLoadAll( mTodoSubResources, incidenceInlineMimeType );
+}
+
+bool ResourceScalix::loadAllJournals()
+{
+ removeIncidences( "Journal" );
+ mCalendar.deleteAllJournals();
+ return doLoadAll( mJournalSubResources, incidenceInlineMimeType );
+}
+
+void ResourceScalix::removeIncidences( const QCString& incidenceType )
+{
+ Scalix::UidMap::Iterator mapIt = mUidMap.begin();
+ while ( mapIt != mUidMap.end() )
+ {
+ Scalix::UidMap::Iterator it = mapIt++;
+ // Check the type of this uid: event, todo or journal.
+ // Need to look up in mCalendar for that. Given the implementation of incidence(uid),
+ // better call event(uid), todo(uid) etc. directly.
+
+ // A faster but hackish way would probably be to check the type of the resource,
+ // like mEventSubResources.find( it.data().resource() ) != mEventSubResources.end() ?
+ const QString& uid = it.key();
+ if ( incidenceType == "Event" && mCalendar.event( uid ) )
+ mUidMap.remove( it );
+ else if ( incidenceType == "Todo" && mCalendar.todo( uid ) )
+ mUidMap.remove( it );
+ else if ( incidenceType == "Journal" && mCalendar.journal( uid ) )
+ mUidMap.remove( it );
+ }
+}
+
+bool ResourceScalix::doSave()
+{
+ return true;
+}
+
+void ResourceScalix::incidenceUpdated( KCal::IncidenceBase* incidencebase )
+{
+ if ( incidencebase->isReadOnly() ) return; // Should not happen (TM)
+ incidencebase->setSyncStatus( KCal::Event::SYNCMOD );
+ incidencebase->setLastModified( QDateTime::currentDateTime() );
+ // we should probably update the revision number here,
+ // or internally in the Event itself when certain things change.
+ // need to verify with ical documentation.
+
+ const QString uid = incidencebase->uid();
+
+ if ( mUidsPendingUpdate.contains( uid ) || mUidsPendingAdding.contains( uid ) ) {
+ /* We are currently processing this event ( removing and readding or
+ * adding it ). If so, ignore this update. Keep the last of these around
+ * and process once we hear back from KMail on this event. */
+ mPendingUpdates.replace( uid, incidencebase );
+ return;
+ }
+
+ QString subResource;
+ Q_UINT32 sernum = 0;
+ if ( mUidMap.contains( uid ) ) {
+ subResource = mUidMap[ uid ].resource();
+ sernum = mUidMap[ uid ].serialNumber();
+ mUidsPendingUpdate.append( uid );
+ }
+ sendKMailUpdate( incidencebase, subResource, sernum );
+}
+
+void ResourceScalix::resolveConflict( KCal::Incidence* inc, const QString& subresource, Q_UINT32 sernum )
+{
+ if ( ! inc )
+ return;
+ if ( ! mResolveConflict ) {
+ // we should do no conflict resolution
+ delete inc;
+ return;
+ }
+ Incidence* local = mCalendar.incidence( inc->uid() );
+ Incidence* localIncidence = 0;
+ Incidence* addedIncidence = 0;
+ if ( local ) {
+ KIncidenceChooser* ch = new KIncidenceChooser();
+ ch->setIncidence( local ,inc );
+ if ( KIncidenceChooser::chooseMode == KIncidenceChooser::ask ) {
+ connect ( this, SIGNAL( useGlobalMode() ), ch, SLOT ( useGlobalMode() ) );
+ if ( ch->exec() )
+ if ( KIncidenceChooser::chooseMode != KIncidenceChooser::ask )
+ emit useGlobalMode() ;
+ }
+ Incidence* result = ch->getIncidence();
+ delete ch;
+ if ( result == local ) {
+ localIncidence = local->clone();
+ delete inc;
+ } else if ( result == inc ) {
+ addedIncidence = inc;
+ } else if ( result == 0 ) { // take both
+ localIncidence = local->clone();
+ localIncidence->recreate();
+ localIncidence->setSummary( i18n("Copy of: %1").arg(localIncidence->summary()) );
+ addedIncidence = inc;
+ }
+ bool silent = mSilent;
+ mSilent = false;
+ deleteIncidence( local ); // remove local from kmail
+ kmailDeleteIncidence( subresource, sernum );// remove new from kmail
+ if ( localIncidence ) {
+ addIncidence( localIncidence, subresource, 0 );
+ mUidsPendingAdding.remove( localIncidence->uid() ); // we do want to inform KOrg also
+ }
+ if ( addedIncidence ) {
+ addIncidence( addedIncidence, subresource, 0 );
+ mUidsPendingAdding.remove( addedIncidence->uid() ); // we do want to inform KOrg also
+ }
+ mSilent = silent;
+ }
+}
+void ResourceScalix::addIncidence( const char* mimetype, const QString& data,
+ const QString& subResource, Q_UINT32 sernum )
+{
+ // This uses pointer comparison, so it only works if we use the static
+ // objects defined in the top of the file
+ Incidence *inc = mFormat.fromString( data );
+ addIncidence( inc, subResource, sernum );
+}
+
+
+bool ResourceScalix::sendKMailUpdate( KCal::IncidenceBase* incidencebase, const QString& subresource,
+ Q_UINT32 sernum )
+{
+ const QString& type = incidencebase->type();
+ const char* mimetype = 0;
+ QString data;
+ if ( type == "Event" ) {
+ mimetype = incidenceInlineMimeType;
+ data = mFormat.createScheduleMessage( static_cast<KCal::Event *>(incidencebase),
+ Scheduler::Publish );
+ } else if ( type == "Todo" ) {
+ mimetype = incidenceInlineMimeType;
+ data = mFormat.createScheduleMessage( static_cast<KCal::Todo *>(incidencebase),
+ Scheduler::Publish );
+ } else if ( type == "Journal" ) {
+ mimetype = incidenceInlineMimeType;
+ data = mFormat.createScheduleMessage( static_cast<KCal::Journal *>(incidencebase),
+ Scheduler::Publish );
+ } else {
+ kdWarning(5006) << "Can't happen: unhandled type=" << type << endl;
+ }
+
+// kdDebug() << k_funcinfo << "Data string:\n" << data << endl;
+
+ KCal::Incidence* incidence = static_cast<KCal::Incidence *>( incidencebase );
+ CustomHeaderMap customHeaders;
+
+ if ( type == "Event" )
+ customHeaders.insert( "X-Scalix-Class", "IPM.Appointment" );
+ else if ( type == "Todo" )
+ customHeaders.insert( "X-Scalix-Class", "IPM.Task" );
+
+ QString subject = incidence->summary();
+
+ // behold, sernum is an in-parameter
+ const bool rc = kmailUpdate( subresource, sernum, data, mimetype, subject, customHeaders );
+ // update the serial number
+ if ( mUidMap.contains( incidencebase->uid() ) ) {
+ mUidMap[ incidencebase->uid() ].setSerialNumber( sernum );
+ }
+ return rc;
+}
+
+bool ResourceScalix::addIncidence( KCal::Incidence* incidence, const QString& _subresource,
+ Q_UINT32 sernum )
+{
+ Q_ASSERT( incidence );
+ if ( !incidence ) return false;
+ const QString &uid = incidence->uid();
+ QString subResource = _subresource;
+
+ Scalix::ResourceMap *map = &mEventSubResources; // don't use a ref here!
+
+ const QString& type = incidence->type();
+ if ( type == "Event" )
+ map = &mEventSubResources;
+ else if ( type == "Todo" )
+ map = &mTodoSubResources;
+ else if ( type == "Journal" )
+ map = &mJournalSubResources;
+ else
+ kdWarning() << "unknown type " << type << endl;
+
+ if ( !mSilent ) { /* We got this one from the user, tell KMail. */
+ // Find out if this event was previously stored in KMail
+ bool newIncidence = _subresource.isEmpty();
+ if ( newIncidence ) {
+ subResource = findWritableResource( *map );
+ }
+
+ if ( subResource.isEmpty() )
+ return false;
+
+ mNewIncidencesMap.insert( uid, subResource );
+
+ if ( !sendKMailUpdate( incidence, subResource, sernum ) ) {
+ kdError(5650) << "Communication problem in ResourceScalix::addIncidence()\n";
+ return false;
+ } else {
+ // KMail is doing it's best to add the event now, put a sticker on it,
+ // so we know it's one of our transient ones
+ mUidsPendingAdding.append( uid );
+
+ /* Add to the cache immediately if this is a new event coming from
+ * KOrganizer. It relies on the incidence being in the calendar when
+ * addIncidence returns. */
+ if ( newIncidence ) {
+ mCalendar.addIncidence( incidence );
+ incidence->registerObserver( this );
+ }
+ }
+ } else { /* KMail told us */
+ bool ourOwnUpdate = false;
+ /* Check if we updated this one, which means kmail deleted and added it.
+ * We know the new state, so lets just not do much at all. The old incidence
+ * in the calendar remains valid, but the serial number changed, so we need to
+ * update that */
+ if ( ourOwnUpdate = mUidsPendingUpdate.contains( uid ) ) {
+ mUidsPendingUpdate.remove( uid );
+ mUidMap.remove( uid );
+ mUidMap[ uid ] = StorageReference( subResource, sernum );
+ } else {
+ /* This is a real add, from KMail, we didn't trigger this ourselves.
+ * If this uid already exists in this folder, do conflict resolution,
+ * unless the folder is read-only, in which case the user should not be
+ * offered a means of putting mails in a folder she'll later be unable to
+ * upload. Skip the incidence, in this case. */
+ if ( mUidMap.contains( uid )
+ && ( mUidMap[ uid ].resource() == subResource ) ) {
+ if ( (*map)[ subResource ].writable() ) {
+ resolveConflict( incidence, subResource, sernum );
+ } else {
+ kdWarning( 5650 ) << "Duplicate event in a read-only folder detected! "
+ "Please inform the owner of the folder. " << endl;
+ }
+ return true;
+ }
+ /* Add to the cache if the add didn't come from KOrganizer, in which case
+ * we've already added it, and listen to updates from KOrganizer for it. */
+ if ( !mUidsPendingAdding.contains( uid ) ) {
+ mCalendar.addIncidence( incidence );
+ incidence->registerObserver( this );
+ }
+ if ( !subResource.isEmpty() && sernum != 0 ) {
+ mUidMap[ uid ] = StorageReference( subResource, sernum );
+ incidence->setReadOnly( !(*map)[ subResource ].writable() );
+ }
+ }
+ /* Check if there are updates for this uid pending and if so process them. */
+ if ( KCal::IncidenceBase *update = mPendingUpdates.find( uid ) ) {
+ mSilent = false; // we do want to tell KMail
+ mPendingUpdates.remove( uid );
+ incidenceUpdated( update );
+ } else {
+ /* If the uid was added by KMail, KOrganizer needs to be told, so
+ * schedule emitting of the resourceChanged signal. */
+ if ( !mUidsPendingAdding.contains( uid ) ) {
+ if ( !ourOwnUpdate ) mResourceChangedTimer.changeInterval( 100 );
+ } else {
+ mUidsPendingAdding.remove( uid );
+ }
+ }
+
+ mNewIncidencesMap.remove( uid );
+ }
+ return true;
+}
+
+
+bool ResourceScalix::addEvent( KCal::Event* event )
+{
+ if ( mUidMap.contains( event->uid() ) )
+ return true; //noop
+ else
+ return addIncidence( event, QString::null, 0 );
+}
+
+bool ResourceScalix::deleteIncidence( KCal::Incidence* incidence )
+{
+ if ( incidence->isReadOnly() ) return false;
+
+ const QString uid = incidence->uid();
+ if( !mUidMap.contains( uid ) ) return false; // Odd
+ /* The user told us to delete, tell KMail */
+ if ( !mSilent ) {
+ kmailDeleteIncidence( mUidMap[ uid ].resource(),
+ mUidMap[ uid ].serialNumber() );
+ mUidsPendingDeletion.append( uid );
+ incidence->unRegisterObserver( this );
+ mCalendar.deleteIncidence( incidence );
+ mUidMap.remove( uid );
+ } else {
+ assert( false ); // If this still happens, something is very wrong
+ }
+ return true;
+}
+
+bool ResourceScalix::deleteEvent( KCal::Event* event )
+{
+ return deleteIncidence( event );
+}
+
+KCal::Event* ResourceScalix::event( const QString& uid )
+{
+ return mCalendar.event(uid);
+}
+
+KCal::Event::List ResourceScalix::rawEvents( EventSortField sortField, SortDirection sortDirection )
+{
+ return mCalendar.rawEvents( sortField, sortDirection );
+}
+
+KCal::Event::List ResourceScalix::rawEventsForDate( const QDate& date,
+ EventSortField sortField,
+ SortDirection sortDirection )
+{
+ return mCalendar.rawEventsForDate( date, sortField, sortDirection );
+}
+
+KCal::Event::List ResourceScalix::rawEventsForDate( const QDateTime& qdt )
+{
+ return mCalendar.rawEventsForDate( qdt );
+}
+
+KCal::Event::List ResourceScalix::rawEvents( const QDate& start,
+ const QDate& end,
+ bool inclusive )
+{
+ return mCalendar.rawEvents( start, end, inclusive );
+}
+
+bool ResourceScalix::addTodo( KCal::Todo* todo )
+{
+ if ( mUidMap.contains( todo->uid() ) )
+ return true; //noop
+ else
+ return addIncidence( todo, QString::null, 0 );
+}
+
+bool ResourceScalix::deleteTodo( KCal::Todo* todo )
+{
+ return deleteIncidence( todo );
+}
+
+KCal::Todo* ResourceScalix::todo( const QString& uid )
+{
+ return mCalendar.todo( uid );
+}
+
+KCal::Todo::List ResourceScalix::rawTodos( TodoSortField sortField, SortDirection sortDirection )
+{
+ return mCalendar.rawTodos( sortField, sortDirection );
+}
+
+KCal::Todo::List ResourceScalix::rawTodosForDate( const QDate& date )
+{
+ return mCalendar.rawTodosForDate( date );
+}
+
+bool ResourceScalix::addJournal( KCal::Journal* journal )
+{
+ if ( mUidMap.contains( journal->uid() ) )
+ return true; //noop
+ else
+ return addIncidence( journal, QString::null, 0 );
+}
+
+bool ResourceScalix::deleteJournal( KCal::Journal* journal )
+{
+ return deleteIncidence( journal );
+}
+
+KCal::Journal* ResourceScalix::journal( const QString& uid )
+{
+ return mCalendar.journal(uid);
+}
+
+KCal::Journal::List ResourceScalix::rawJournals( JournalSortField sortField, SortDirection sortDirection )
+{
+ return mCalendar.rawJournals( sortField, sortDirection );
+}
+
+KCal::Journal::List ResourceScalix::rawJournalsForDate( const QDate &date )
+{
+ return mCalendar.rawJournalsForDate( date );
+}
+
+KCal::Alarm::List ResourceScalix::alarms( const QDateTime& from,
+ const QDateTime& to )
+{
+ return mCalendar.alarms( from, to );
+}
+
+KCal::Alarm::List ResourceScalix::alarmsTo( const QDateTime& to )
+{
+ return mCalendar.alarmsTo(to);
+}
+
+void ResourceScalix::setTimeZoneId( const QString& tzid )
+{
+ mCalendar.setTimeZoneId( tzid );
+ mFormat.setTimeZone( mCalendar.timeZoneId(), !mCalendar.isLocalTime() );
+}
+
+bool ResourceScalix::fromKMailAddIncidence( const QString& type,
+ const QString& subResource,
+ Q_UINT32 sernum,
+ int /*format*/,
+ const QString& data )
+{
+ bool rc = true;
+ TemporarySilencer t( this ); // RAII
+ if ( type != kmailCalendarContentsType && type != kmailTodoContentsType
+ && type != kmailJournalContentsType )
+ // Not ours
+ return false;
+ if ( !subresourceActive( subResource ) ) return true;
+
+ Incidence *inc = mFormat.fromString( data );
+ if ( !inc )
+ rc = false;
+ else
+ addIncidence( inc, subResource, sernum );
+
+ return rc;
+}
+
+void ResourceScalix::fromKMailDelIncidence( const QString& type,
+ const QString& subResource,
+ const QString& uid )
+{
+ if ( type != kmailCalendarContentsType && type != kmailTodoContentsType
+ && type != kmailJournalContentsType )
+ // Not ours
+ return;
+ if ( !subresourceActive( subResource ) ) return;
+
+ // Can't be in both, by contract
+ if ( mUidsPendingDeletion.contains( uid ) ) {
+ mUidsPendingDeletion.remove( uid );
+ } else if ( mUidsPendingUpdate.contains( uid ) ) {
+ // It's good to know if was deleted, but we are waiting on a new one to
+ // replace it, so let's just sit tight.
+ } else {
+ // We didn't trigger this, so KMail did, remove the reference to the uid
+ KCal::Incidence* incidence = mCalendar.incidence( uid );
+ if( incidence ) {
+ incidence->unRegisterObserver( this );
+ mCalendar.deleteIncidence( incidence );
+ }
+ mUidMap.remove( uid );
+ mResourceChangedTimer.changeInterval( 100 );
+ }
+}
+
+void ResourceScalix::fromKMailRefresh( const QString& type,
+ const QString& /*subResource*/ )
+{
+ // TODO: Only load the specified subResource
+ if ( type == "Calendar" )
+ loadAllEvents();
+ else if ( type == "Task" )
+ loadAllTodos();
+ else if ( type == "Journal" )
+ loadAllJournals();
+ else
+ kdWarning(5006) << "KCal Scalix resource: fromKMailRefresh: unknown type " << type << endl;
+ mResourceChangedTimer.changeInterval( 100 );
+}
+
+void ResourceScalix::fromKMailAddSubresource( const QString& type,
+ const QString& subResource,
+ const QString& label,
+ bool writable )
+{
+ ResourceMap* map = 0;
+ const char* mimetype = 0;
+ if ( type == kmailCalendarContentsType ) {
+ map = &mEventSubResources;
+ mimetype = eventAttachmentMimeType;
+ } else if ( type == kmailTodoContentsType ) {
+ map = &mTodoSubResources;
+ mimetype = todoAttachmentMimeType;
+ } else if ( type == kmailJournalContentsType ) {
+ map = &mJournalSubResources;
+ mimetype = journalAttachmentMimeType;
+ } else
+ // Not ours
+ return;
+
+ if ( map->contains( subResource ) )
+ // Already registered
+ return;
+
+ KConfig config( configFile() );
+ config.setGroup( subResource );
+
+ bool active = config.readBoolEntry( subResource, true );
+ (*map)[ subResource ] = Scalix::SubResource( active, writable, label );
+ loadSubResource( subResource, mimetype );
+ emit signalSubresourceAdded( this, type, subResource, label );
+}
+
+void ResourceScalix::fromKMailDelSubresource( const QString& type,
+ const QString& subResource )
+{
+ ResourceMap* map = subResourceMap( type );
+ if ( !map ) // not ours
+ return;
+ if ( map->contains( subResource ) )
+ map->erase( subResource );
+ else
+ // Not registered
+ return;
+
+ // Delete from the config file
+ KConfig config( configFile() );
+ config.deleteGroup( subResource );
+ config.sync();
+
+ // Make a list of all uids to remove
+ Scalix::UidMap::ConstIterator mapIt;
+ QStringList uids;
+ for ( mapIt = mUidMap.begin(); mapIt != mUidMap.end(); ++mapIt )
+ if ( mapIt.data().resource() == subResource )
+ // We have a match
+ uids << mapIt.key();
+
+ // Finally delete all the incidences
+ if ( !uids.isEmpty() ) {
+ TemporarySilencer t( this );
+ QStringList::ConstIterator it;
+ for ( it = uids.begin(); it != uids.end(); ++it ) {
+ KCal::Incidence* incidence = mCalendar.incidence( *it );
+ if( incidence )
+ mCalendar.deleteIncidence( incidence );
+ mUidMap.remove( *it );
+ }
+ }
+
+ emit signalSubresourceRemoved( this, type, subResource );
+}
+
+QStringList ResourceScalix::subresources() const
+{
+ // Workaround: The ResourceView in KOrganizer wants to know this
+ // before it opens the resource :-( Make sure we are open
+ const_cast<ResourceScalix*>( this )->doOpen();
+ return ( mEventSubResources.keys()
+ + mTodoSubResources.keys()
+ + mJournalSubResources.keys() );
+}
+
+const QString
+ResourceScalix::labelForSubresource( const QString& subresource ) const
+{
+ if ( mEventSubResources.contains( subresource ) )
+ return mEventSubResources[ subresource ].label();
+ if ( mTodoSubResources.contains( subresource ) )
+ return mTodoSubResources[ subresource ].label();
+ if ( mJournalSubResources.contains( subresource ) )
+ return mJournalSubResources[ subresource ].label();
+ return subresource;
+}
+
+QString ResourceScalix::subresourceIdentifier( Incidence *incidence )
+{
+ QString uid = incidence->uid();
+ if ( mUidMap.contains( uid ) )
+ return mUidMap[ uid ].resource();
+ else
+ if ( mNewIncidencesMap.contains( uid ) )
+ return mNewIncidencesMap[ uid ];
+ else
+ return QString();
+}
+
+void ResourceScalix::fromKMailAsyncLoadResult( const QMap<Q_UINT32, QString>& map,
+ const QString& type,
+ const QString& folder )
+{
+ TemporarySilencer t( this );
+ for( QMap<Q_UINT32, QString>::ConstIterator it = map.begin(); it != map.end(); ++it )
+ addIncidence( type.latin1(), it.data(), folder, it.key() );
+}
+
+bool ResourceScalix::subresourceActive( const QString& subresource ) const
+{
+ // Workaround: The ResourceView in KOrganizer wants to know this
+ // before it opens the resource :-( Make sure we are open
+ const_cast<ResourceScalix*>( this )->doOpen();
+
+ if ( mEventSubResources.contains( subresource ) )
+ return mEventSubResources[ subresource ].active();
+ if ( mTodoSubResources.contains( subresource ) )
+ return mTodoSubResources[ subresource ].active();
+ if ( mJournalSubResources.contains( subresource ) )
+ return mJournalSubResources[ subresource ].active();
+
+ // Safe default bet:
+ kdDebug(5650) << "subresourceActive( " << subresource << " ): Safe bet\n";
+
+ return true;
+}
+
+void ResourceScalix::setSubresourceActive( const QString &subresource, bool v )
+{
+ ResourceMap *map = 0;
+
+ if ( mEventSubResources.contains( subresource ) )
+ map = &mEventSubResources;
+ if ( mTodoSubResources.contains( subresource ) )
+ map = &mTodoSubResources;
+ if ( mJournalSubResources.contains( subresource ) )
+ map = &mJournalSubResources;
+
+ if ( map && ( ( *map )[ subresource ].active() != v ) ) {
+ ( *map )[ subresource ].setActive( v );
+ doLoad(); // refresh the mCalendar cache
+ mResourceChangedTimer.changeInterval( 100 );
+ }
+}
+
+void ResourceScalix::slotEmitResourceChanged()
+{
+ kdDebug(5650) << "KCal Scalix resource: emitting resource changed " << endl;
+ mResourceChangedTimer.stop();
+ emit resourceChanged( this );
+}
+
+KABC::Lock* ResourceScalix::lock()
+{
+ return new KABC::LockNull( true );
+}
+
+
+Scalix::ResourceMap* ResourceScalix::subResourceMap( const QString& contentsType )
+{
+ if ( contentsType == kmailCalendarContentsType ) {
+ return &mEventSubResources;
+ } else if ( contentsType == kmailTodoContentsType ) {
+ return &mTodoSubResources;
+ } else if ( contentsType == kmailJournalContentsType ) {
+ return &mJournalSubResources;
+ }
+ // Not ours
+ return 0;
+}
+
+#include "resourcescalix.moc"
diff --git a/kresources/scalix/kcal/resourcescalix.h b/kresources/scalix/kcal/resourcescalix.h
new file mode 100644
index 000000000..0c845a6ce
--- /dev/null
+++ b/kresources/scalix/kcal/resourcescalix.h
@@ -0,0 +1,221 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+ 2004 Till Adam <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef KCAL_RESOURCESCALIX_H
+#define KCAL_RESOURCESCALIX_H
+
+#include <qtimer.h>
+
+#include <kdepimmacros.h>
+#include <libkcal/calendarlocal.h>
+#include <libkcal/icalformat.h>
+#include <libkcal/resourcecalendar.h>
+#include "../shared/resourcescalixbase.h"
+
+namespace KCal {
+
+struct TemporarySilencer;
+
+class KDE_EXPORT ResourceScalix : public KCal::ResourceCalendar,
+ public KCal::IncidenceBase::Observer,
+ public Scalix::ResourceScalixBase
+{
+ Q_OBJECT
+ friend struct TemporarySilencer;
+
+public:
+ ResourceScalix( const KConfig* );
+ virtual ~ResourceScalix();
+
+ /// Load resource data.
+ bool doLoad();
+
+ /// Save resource data.
+ bool doSave();
+
+ /// Open the notes resource.
+ bool doOpen();
+ /// Close the notes resource.
+ void doClose();
+
+ // The libkcal functions. See the resource for descriptions
+ bool addEvent( KCal::Event* anEvent );
+ bool deleteEvent( KCal::Event* );
+ KCal::Event* event( const QString &UniqueStr );
+ KCal::Event::List rawEvents( EventSortField sortField = EventSortUnsorted, SortDirection sortDirection = SortDirectionAscending );
+ KCal::Event::List rawEventsForDate(
+ const QDate& date,
+ EventSortField sortField=EventSortUnsorted,
+ SortDirection sortDirection=SortDirectionAscending );
+ KCal::Event::List rawEventsForDate( const QDateTime& qdt );
+ KCal::Event::List rawEvents( const QDate& start, const QDate& end,
+ bool inclusive = false );
+
+ bool addTodo( KCal::Todo* todo );
+ bool deleteTodo( KCal::Todo* );
+ KCal::Todo* todo( const QString& uid );
+ KCal::Todo::List rawTodos( TodoSortField sortField = TodoSortUnsorted, SortDirection sortDirection = SortDirectionAscending );
+ KCal::Todo::List rawTodosForDate( const QDate& date );
+
+ bool addJournal( KCal::Journal* );
+ bool deleteJournal( KCal::Journal* );
+ KCal::Journal* journal( const QString& uid );
+ KCal::Journal::List rawJournals( JournalSortField sortField = JournalSortUnsorted, SortDirection sortDirection = SortDirectionAscending );
+ KCal::Journal::List rawJournalsForDate( const QDate &date );
+
+ KCal::Alarm::List alarms( const QDateTime& from, const QDateTime& to );
+ KCal::Alarm::List alarmsTo( const QDateTime& to );
+
+ void setTimeZoneId( const QString& tzid );
+
+ bool deleteIncidence( KCal::Incidence* i );
+
+ /// The ResourceScalixBase methods called by KMail
+ bool fromKMailAddIncidence( const QString& type, const QString& subResource,
+ Q_UINT32 sernum, int format, const QString& data );
+ void fromKMailDelIncidence( const QString& type, const QString& subResource,
+ const QString& uid );
+ void fromKMailRefresh( const QString& type, const QString& subResource );
+
+ /// Listen to KMail changes in the amount of sub resources
+ void fromKMailAddSubresource( const QString& type, const QString& subResource,
+ const QString& label, bool writable );
+ void fromKMailDelSubresource( const QString& type, const QString& subResource );
+
+ void fromKMailAsyncLoadResult( const QMap<Q_UINT32, QString>& map,
+ const QString& type,
+ const QString& folder );
+
+ /** Return the list of subresources. */
+ QStringList subresources() const;
+
+ /** Is this subresource active? */
+ bool subresourceActive( const QString& ) const;
+ /** (De)activate the subresource */
+ virtual void setSubresourceActive( const QString &, bool );
+
+ /** What is the label for this subresource? */
+ virtual const QString labelForSubresource( const QString& resource ) const;
+
+ virtual QString subresourceIdentifier( Incidence *incidence );
+
+ KABC::Lock* lock();
+
+signals:
+ void useGlobalMode();
+protected slots:
+ void slotEmitResourceChanged();
+
+private:
+ void removeIncidences( const QCString& incidenceType );
+ void resolveConflict( KCal::Incidence*, const QString& subresource, Q_UINT32 sernum );
+
+ void addIncidence( const char* mimetype, const QString& xml,
+ const QString& subResource, Q_UINT32 sernum );
+
+ bool addIncidence( KCal::Incidence* i, const QString& subresource,
+ Q_UINT32 sernum );
+/*
+ void addEvent( const QString& xml, const QString& subresource,
+ Q_UINT32 sernum );
+ void addTodo( const QString& xml, const QString& subresource,
+ Q_UINT32 sernum );
+ void addJournal( const QString& xml, const QString& subresource,
+ Q_UINT32 sernum );
+*/
+
+ bool loadAllEvents();
+ bool loadAllTodos();
+ bool loadAllJournals();
+
+ bool doLoadAll( Scalix::ResourceMap& map, const char* mimetype );
+
+ /// Reimplemented from IncidenceBase::Observer to know when an incidence was changed
+ void incidenceUpdated( KCal::IncidenceBase* );
+
+ bool openResource( KConfig& config, const char* contentType,
+ Scalix::ResourceMap& map );
+ void loadSubResourceConfig( KConfig& config, const QString& name,
+ const QString& label, bool writable,
+ Scalix::ResourceMap& subResource );
+ bool loadSubResource( const QString& subResource, const char* mimetype );
+
+ QString configFile() const {
+ return ResourceScalixBase::configFile( "kcal" );
+ }
+
+ Scalix::ResourceMap* subResourceMap( const QString& contentsType );
+
+ bool sendKMailUpdate( KCal::IncidenceBase* incidence, const QString& _subresource,
+ Q_UINT32 sernum );
+
+
+ KCal::CalendarLocal mCalendar;
+
+ // The list of subresources
+ Scalix::ResourceMap mEventSubResources, mTodoSubResources, mJournalSubResources;
+
+ bool mOpen; // If the resource is open, this is true
+ QDict<KCal::IncidenceBase> mPendingUpdates;
+ QTimer mResourceChangedTimer;
+ ICalFormat mFormat;
+
+ /**
+ This map contains the association between a new added incidence
+ and the subresource it belongs to.
+ That's needed to return the correct mapping in subresourceIdentifier().
+
+ We can't trust on mUidMap here, because it contains only non-pending uids.
+ */
+ QMap<QString, QString> mNewIncidencesMap;
+ int mProgressDialogIncidenceLimit;
+};
+
+struct TemporarySilencer {
+ TemporarySilencer( ResourceScalix *_resource )
+ {
+ resource = _resource;
+ oldValue = resource->mSilent;
+ resource->mSilent = true;
+ }
+ ~TemporarySilencer()
+ {
+ resource->mSilent = oldValue;
+ }
+ ResourceScalix *resource;
+ bool oldValue;
+};
+
+}
+
+#endif // KCAL_RESOURCESCALIX_H
diff --git a/kresources/scalix/kcal/resourcescalix_plugin.cpp b/kresources/scalix/kcal/resourcescalix_plugin.cpp
new file mode 100644
index 000000000..53ac6705f
--- /dev/null
+++ b/kresources/scalix/kcal/resourcescalix_plugin.cpp
@@ -0,0 +1,50 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2002 - 2004 Klar�lvdalens Datakonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "resourcescalix.h"
+
+class ScalixFactory : public KRES::PluginFactoryBase
+{
+public:
+ KRES::Resource *resource( const KConfig *config )
+ {
+ return new KCal::ResourceScalix( config );
+ }
+
+ KRES::ConfigWidget *configWidget( QWidget* )
+ {
+ return 0;
+ }
+};
+
+K_EXPORT_COMPONENT_FACTORY(kcal_scalix,ScalixFactory)
diff --git a/kresources/scalix/kcal/scalix.desktop b/kresources/scalix/kcal/scalix.desktop
new file mode 100644
index 000000000..1c468cca4
--- /dev/null
+++ b/kresources/scalix/kcal/scalix.desktop
@@ -0,0 +1,31 @@
+[Desktop Entry]
+Name=Calendar on Scalix Server via KMail
+Name[bg]=Календар на сървъра Scalix през KMail
+Name[ca]=Calendari en un servidor Scalix mitjançant el KMail
+Name[da]=Kalender på Scalix-server via KMail
+Name[de]=Kalender auf einem Scalix-Server via KMail
+Name[el]=Ημερολόγιο σε εξυπηρετητή Scalix μέσω του KMail
+Name[es]=Calendario en servidor Scalix por medio de KMail
+Name[et]=Kalender Scalix-serveris (KMaili vahendusel)
+Name[fr]=Agenda sur serveur Scalix via KMail
+Name[is]=Dagatal á Scalix-þjóni gegnum KMail
+Name[it]=Calendario su server Scalix via KMail
+Name[ja]=KMail 経由 Scalix サーバのカレンダー
+Name[km]=ប្រតិទិន​នៅ​លើ​ម៉ាស៊ីន​បម្រើ Scalix តាម​រយៈ KMail
+Name[nds]=Kalenner op Scalix-Server över KMail
+Name[nl]=Agenda op Scalix-server via KMail
+Name[pl]=Kalendarz na serwerze Scalix za pośrednictwem KMaila
+Name[pt_BR]=Calendário em Servidor Scalix via KMail
+Name[ru]=Календарь на сервере Scalix через KMail
+Name[sk]=Kalendár na Scalix serveri pomocou KMail
+Name[sr]=Календар на Scalix серверу преко KMail-а
+Name[sr@Latn]=Kalendar na Scalix serveru preko KMail-a
+Name[sv]=Kalender på Scalix-server via Kmail
+Name[tr]=KMail Aracılığı ile Scalix Sunucusunda Takvim
+Name[zh_CN]=通过 KMail 访问 Scalix 服务器上的日历
+Name[zh_TW]=透過 KMail 取得 Scalix 伺服器上的行事曆
+X-KDE-Library=kcal_scalix
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=calendar
+X-KDE-ResourceType=scalix
diff --git a/kresources/scalix/kioslave/Makefile.am b/kresources/scalix/kioslave/Makefile.am
new file mode 100644
index 000000000..8396c4985
--- /dev/null
+++ b/kresources/scalix/kioslave/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES = -I$(top_srcdir) -I$(top_builddir)/libkdepim $(all_includes)
+
+noinst_HEADERS = scalix.h
+
+METASOURCES = AUTO
+
+kdelnkdir = $(kde_servicesdir)
+kdelnk_DATA = scalix.protocol scalixs.protocol
+
+kde_module_LTLIBRARIES = kio_scalix.la
+
+kio_scalix_la_SOURCES = scalix.cpp
+kio_scalix_la_LIBADD = $(top_builddir)/libkcal/libkcal.la $(top_builddir)/libkdepim/libkdepim.la $(LIB_KIO)
+kio_scalix_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kio_scalix.pot
diff --git a/kresources/scalix/kioslave/scalix.cpp b/kresources/scalix/kioslave/scalix.cpp
new file mode 100644
index 000000000..199bd0980
--- /dev/null
+++ b/kresources/scalix/kioslave/scalix.cpp
@@ -0,0 +1,225 @@
+/*
+ This file is part of KDE.
+
+ Copyright (C) 2007 Trolltech ASA. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <qapplication.h>
+#include <qeventloop.h>
+
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kdebug.h>
+#include <kdeversion.h>
+#include <kio/global.h>
+#include <klocale.h>
+
+#include <kdepimmacros.h>
+
+#include <stdlib.h>
+
+#include "scalix.h"
+
+extern "C" {
+ KDE_EXPORT int kdemain( int argc, char **argv );
+}
+
+static const KCmdLineOptions options[] =
+{
+ { "+protocol", I18N_NOOP( "Protocol name" ), 0 },
+ { "+pool", I18N_NOOP( "Socket name" ), 0 },
+ { "+app", I18N_NOOP( "Socket name" ), 0 },
+ KCmdLineLastOption
+};
+
+int kdemain( int argc, char **argv )
+{
+ putenv( strdup( "SESSION_MANAGER=" ) );
+ KApplication::disableAutoDcopRegistration();
+
+ KCmdLineArgs::init( argc, argv, "kio_scalix", 0, 0, 0, 0 );
+ KCmdLineArgs::addCmdLineOptions( options );
+ KApplication app( false, false );
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ Scalix slave( args->arg( 0 ), args->arg( 1 ), args->arg( 2 ) );
+ slave.dispatchLoop();
+
+ return 0;
+}
+
+Scalix::Scalix( const QCString &protocol, const QCString &pool, const QCString &app )
+ : SlaveBase( protocol, pool, app )
+{
+}
+
+void Scalix::get( const KURL &url )
+{
+ mimeType( "text/plain" );
+
+ QString path = url.path();
+
+ if ( path.contains( "/freebusy/" ) ) {
+ retrieveFreeBusy( url );
+ } else {
+ error( KIO::ERR_SLAVE_DEFINED, i18n( "Unknown path. Known path is '/freebusy/'" ) );
+ }
+}
+
+void Scalix::put( const KURL& url, int, bool, bool )
+{
+ QString path = url.path();
+
+ if ( path.contains( "/freebusy/" ) ) {
+ publishFreeBusy( url );
+ } else {
+ error( KIO::ERR_SLAVE_DEFINED, i18n( "Unknown path. Known path is '/freebusy/'" ) );
+ }
+}
+
+void Scalix::retrieveFreeBusy( const KURL &url )
+{
+ /**
+ * The url is of the following form:
+ * scalix://user:password@host/freebusy/[email protected]
+ */
+
+ // Extract user@domain (e.g. everything between '/freebusy/' and '.ifb')
+ const QString requestUser = url.path().mid( 10, url.path().length() - 14 );
+
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+
+ const QString argument = QString( "BEGIN:VFREEBUSY\nATTENDEE:MAILTO:%1\nEND:VFREEBUSY" ).arg( requestUser );
+ const QString command = QString( "X-GET-ICAL-FREEBUSY {%1}" ).arg( argument.length() );
+
+ stream << (int) 'X' << 'E' << command << argument;
+
+ QString imapUrl = QString( "imap://%1@%3/" ).arg( url.pass().isEmpty() ?
+ url.user() : url.user() + ":" + url.pass() )
+ .arg( url.host() );
+
+ mFreeBusyData = QString();
+
+ KIO::SimpleJob *job = KIO::special( imapUrl, packedArgs, false );
+ connect( job, SIGNAL( infoMessage( KIO::Job*, const QString& ) ),
+ this, SLOT( slotInfoMessage( KIO::Job*, const QString& ) ) );
+ connect( job, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( slotRetrieveResult( KIO::Job* ) ) );
+
+ qApp->eventLoop()->enterLoop();
+}
+
+void Scalix::publishFreeBusy( const KURL &url )
+{
+ /**
+ * The url is of the following form:
+ * scalix://user:password@host/freebusy/path/to/calendar/user@domain
+ */
+ QString requestUser, calendar;
+ QString path = url.path();
+
+ // extract user name
+ int lastSlash = path.findRev( '/' );
+ if ( lastSlash != -1 )
+ requestUser = path.mid( lastSlash + 1 );
+
+ // extract calendar name
+ int secondSlash = path.find( '/', 1 );
+ if ( secondSlash != -1 )
+ calendar = path.mid( secondSlash + 1, lastSlash - secondSlash - 1 );
+
+ if ( requestUser.isEmpty() || calendar.isEmpty() ) {
+ error( KIO::ERR_SLAVE_DEFINED, i18n( "No user or calendar given!" ) );
+ return;
+ };
+
+ // read freebusy information
+ QByteArray data;
+ while ( true ) {
+ dataReq();
+
+ QByteArray buffer;
+ const int newSize = readData(buffer);
+ if ( newSize < 0 ) {
+ // read error: network in unknown state so disconnect
+ error( KIO::ERR_COULD_NOT_READ, i18n("KIO data supply error.") );
+ return;
+ }
+
+ if ( newSize == 0 )
+ break;
+
+ unsigned int oldSize = data.size();
+ data.resize( oldSize + buffer.size() );
+ memcpy( data.data() + oldSize, buffer.data(), buffer.size() );
+ }
+
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+
+ const QString argument = QString::fromUtf8( data );
+ const QString command = QString( "X-PUT-ICAL-FREEBUSY Calendar {%1}" ).arg( argument.length() );
+
+ stream << (int) 'X' << 'E' << command << argument;
+
+ QString imapUrl = QString( "imap://%1@%3/" ).arg( url.pass().isEmpty() ?
+ url.user() : url.user() + ":" + url.pass() )
+ .arg( url.host() );
+
+ KIO::SimpleJob *job = KIO::special( imapUrl, packedArgs, false );
+ connect( job, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( slotPublishResult( KIO::Job* ) ) );
+
+ qApp->eventLoop()->enterLoop();
+}
+
+void Scalix::slotInfoMessage( KIO::Job *job, const QString &data )
+{
+ if ( job->error() ) {
+ // error is handled in slotResult
+ return;
+ }
+
+ mFreeBusyData = data;
+}
+
+
+void Scalix::slotRetrieveResult( KIO::Job *job )
+{
+ if ( job->error() ) {
+ error( KIO::ERR_SLAVE_DEFINED, job->errorString() );
+ } else {
+ data( mFreeBusyData.utf8() );
+ finished();
+ }
+
+ qApp->eventLoop()->exitLoop();
+}
+
+void Scalix::slotPublishResult( KIO::Job *job )
+{
+ if ( job->error() ) {
+ error( KIO::ERR_SLAVE_DEFINED, job->errorString() );
+ } else {
+ finished();
+ }
+
+ qApp->eventLoop()->exitLoop();
+}
+
+#include "scalix.moc"
diff --git a/kresources/scalix/kioslave/scalix.h b/kresources/scalix/kioslave/scalix.h
new file mode 100644
index 000000000..3697c49d7
--- /dev/null
+++ b/kresources/scalix/kioslave/scalix.h
@@ -0,0 +1,51 @@
+/*
+ This file is part of KDE.
+
+ Copyright (C) 2007 Trolltech ASA. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SCALIX_H
+#define SCALIX_H
+
+#include <kio/job.h>
+#include <kio/slavebase.h>
+
+#include <qobject.h>
+
+class Scalix : public QObject, public KIO::SlaveBase
+{
+ Q_OBJECT
+
+ public:
+ Scalix( const QCString &protocol, const QCString &pool, const QCString &app );
+
+ void get( const KURL &url );
+ void put( const KURL &url, int permissions, bool overwrite, bool resume );
+
+ private slots:
+ void slotRetrieveResult( KIO::Job* );
+ void slotPublishResult( KIO::Job* );
+ void slotInfoMessage( KIO::Job*, const QString& );
+
+ private:
+ void retrieveFreeBusy( const KURL& );
+ void publishFreeBusy( const KURL& );
+
+ QString mFreeBusyData;
+};
+
+#endif
diff --git a/kresources/scalix/kioslave/scalix.protocol b/kresources/scalix/kioslave/scalix.protocol
new file mode 100644
index 000000000..a527d77dd
--- /dev/null
+++ b/kresources/scalix/kioslave/scalix.protocol
@@ -0,0 +1,8 @@
+[Protocol]
+DocPath=kioslave/scalix.html
+exec=kio_scalix
+input=none
+output=filesystem
+protocol=scalix
+reading=true
+writing=true
diff --git a/kresources/scalix/kioslave/scalixs.protocol b/kresources/scalix/kioslave/scalixs.protocol
new file mode 100644
index 000000000..fd13db6ad
--- /dev/null
+++ b/kresources/scalix/kioslave/scalixs.protocol
@@ -0,0 +1,8 @@
+[Protocol]
+DocPath=kioslave/scalix.html
+exec=kio_scalix
+input=none
+output=filesystem
+protocol=scalixs
+reading=true
+writing=true
diff --git a/kresources/scalix/knotes/Makefile.am b/kresources/scalix/knotes/Makefile.am
new file mode 100644
index 000000000..42a1c2302
--- /dev/null
+++ b/kresources/scalix/knotes/Makefile.am
@@ -0,0 +1,28 @@
+METASOURCES = AUTO
+
+INCLUDES = -I$(top_srcdir)/kresources/scalix/shared \
+ -I$(top_srcdir) -I$(top_srcdir)/knotes -I$(top_builddir)/libkdepim $(all_includes)
+
+# The scalix wizard links to this library too
+lib_LTLIBRARIES = libknotesscalix.la
+
+libknotesscalix_la_SOURCES = resourcescalix.cpp
+libknotesscalix_la_LDFLAGS = $(all_libraries) -no-undefined
+libknotesscalix_la_LIBADD = \
+ $(top_builddir)/kresources/scalix/shared/libresourcescalixshared.la \
+ $(top_builddir)/knotes/libknotesresources.la \
+ $(top_builddir)/libkcal/libkcal.la \
+ -lkresources -lkdeprint
+
+kde_module_LTLIBRARIES = knotes_scalix.la
+
+knotes_scalix_la_SOURCES = resourcescalix_plugin.cpp
+knotes_scalix_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined
+knotes_scalix_la_LIBADD = libknotesscalix.la
+
+servicedir = $(kde_servicesdir)/kresources/knotes
+service_DATA = scalix.desktop
+
+install-data-local: $(srcdir)/../uninstall.desktop
+ $(mkinstalldirs) $(DESTDIR)$(servicedir)
+ $(INSTALL_DATA) $(srcdir)/../uninstall.desktop $(DESTDIR)$(servicedir)/scalix.desktop
diff --git a/kresources/scalix/knotes/resourcescalix.cpp b/kresources/scalix/knotes/resourcescalix.cpp
new file mode 100644
index 000000000..e43a9a912
--- /dev/null
+++ b/kresources/scalix/knotes/resourcescalix.cpp
@@ -0,0 +1,425 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+ Copyright (c) 2004 Till Adam <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "resourcescalix.h"
+
+#include <knotes/resourcemanager.h>
+
+#include <libkcal/icalformat.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+
+using namespace Scalix;
+
+static const char* configGroupName = "Note";
+static const char* kmailContentsType = "Note";
+static const char* attachmentMimeType = "application/x-vnd.kolab.note";
+static const char* inlineMimeType = "text/calendar";
+
+ResourceScalix::ResourceScalix( const KConfig *config )
+ : ResourceNotes( config ), ResourceScalixBase( "ResourceScalix-KNotes" ),
+ mCalendar( QString::fromLatin1("UTC") )
+{
+ setType( "scalix" );
+}
+
+ResourceScalix::~ResourceScalix()
+{
+}
+
+bool ResourceScalix::doOpen()
+{
+ KConfig config( configFile() );
+ config.setGroup( configGroupName );
+
+ // Get the list of Notes folders from KMail
+ QValueList<KMailICalIface::SubResource> subResources;
+ if ( !kmailSubresources( subResources, kmailContentsType ) )
+ return false;
+
+ // Make the resource map from the folder list
+ QValueList<KMailICalIface::SubResource>::ConstIterator it;
+ mSubResources.clear();
+ for ( it = subResources.begin(); it != subResources.end(); ++it ) {
+ const QString subResource = (*it).location;
+ const bool active = config.readBoolEntry( subResource, true );
+ mSubResources[ subResource ] = Scalix::SubResource( active, (*it).writable, (*it).label );
+ }
+
+ return true;
+}
+
+void ResourceScalix::doClose()
+{
+ KConfig config( configFile() );
+ config.setGroup( configGroupName );
+ Scalix::ResourceMap::ConstIterator it;
+ for ( it = mSubResources.begin(); it != mSubResources.end(); ++it )
+ config.writeEntry( it.key(), it.data().active() );
+}
+
+bool ResourceScalix::loadSubResource( const QString& subResource,
+ const QString &mimetype )
+{
+ // Get the list of journals
+ int count = 0;
+ if ( !kmailIncidencesCount( count, mimetype, subResource ) ) {
+ kdError() << "Communication problem in ResourceScalix::load()\n";
+ return false;
+ }
+
+ QMap<Q_UINT32, QString> lst;
+ if( !kmailIncidences( lst, mimetype, subResource, 0, count ) ) {
+ kdError(5500) << "Communication problem in "
+ << "ResourceScalix::getIncidenceList()\n";
+ return false;
+ }
+
+ kdDebug(5500) << "Notes scalix resource: got " << lst.count() << " notes in " << subResource << endl;
+
+ // Populate with the new entries
+ const bool silent = mSilent;
+ mSilent = true;
+ QMap<Q_UINT32, QString>::Iterator it;
+ for ( it = lst.begin(); it != lst.end(); ++it ) {
+ KCal::Journal* journal = addNote( it.data(), subResource, it.key(), mimetype );
+ if ( !journal )
+ kdDebug(5500) << "loading note " << it.key() << " failed" << endl;
+ else
+ manager()->registerNote( this, journal );
+ }
+ mSilent = silent;
+
+ return true;
+}
+
+bool ResourceScalix::load()
+{
+ // We get a fresh list of events, so clean out the old ones
+ mCalendar.deleteAllEvents();
+ mUidMap.clear();
+
+ bool rc = true;
+ Scalix::ResourceMap::ConstIterator itR;
+ for ( itR = mSubResources.begin(); itR != mSubResources.end(); ++itR ) {
+ if ( !itR.data().active() )
+ // This subResource is disabled
+ continue;
+
+ QString mimetype = inlineMimeType;
+ rc &= loadSubResource( itR.key(), mimetype );
+ mimetype = attachmentMimeType;
+ rc &= loadSubResource( itR.key(), mimetype );
+ }
+
+ return rc;
+}
+
+bool ResourceScalix::save()
+{
+ // Nothing to do here, we save everything in incidenceUpdated()
+ return true;
+}
+
+bool ResourceScalix::addNote( KCal::Journal* journal )
+{
+ return addNote( journal, QString::null, 0 );
+}
+
+KCal::Journal* ResourceScalix::addNote( const QString& data, const QString& subresource,
+ Q_UINT32 sernum, const QString& )
+{
+ KCal::Journal* journal = 0;
+ // FIXME: This does not take into account the time zone!
+ KCal::ICalFormat formatter;
+ journal = static_cast<KCal::Journal*>( formatter.fromString( data ) );
+
+ Q_ASSERT( journal );
+ if( journal && !mUidMap.contains( journal->uid() ) )
+ if ( addNote( journal, subresource, sernum ) )
+ return journal;
+ else
+ delete journal;
+ return 0;
+}
+
+bool ResourceScalix::addNote( KCal::Journal* journal,
+ const QString& subresource, Q_UINT32 sernum )
+{
+ kdDebug(5500) << "ResourceScalix::addNote( KCal::Journal*, '" << subresource << "', " << sernum << " )\n";
+
+ journal->registerObserver( this );
+
+ // Find out if this note was previously stored in KMail
+ bool newNote = subresource.isEmpty();
+ mCalendar.addJournal( journal );
+
+ QString resource =
+ newNote ? findWritableResource( mSubResources ) : subresource;
+ if ( resource.isEmpty() ) // canceled
+ return false;
+
+ if ( !mSilent ) {
+ KCal::ICalFormat formatter;
+ const QString xml = formatter.toString( journal );
+ kdDebug(5500) << k_funcinfo << "XML string:\n" << xml << endl;
+
+ if( !kmailUpdate( resource, sernum, xml, attachmentMimeType, journal->uid() ) ) {
+ kdError(5500) << "Communication problem in ResourceScalix::addNote()\n";
+ return false;
+ }
+ }
+
+ if ( !resource.isEmpty() && sernum != 0 ) {
+ mUidMap[ journal->uid() ] = StorageReference( resource, sernum );
+ return true;
+ }
+
+ return false;
+}
+
+bool ResourceScalix::deleteNote( KCal::Journal* journal )
+{
+ const QString uid = journal->uid();
+ if ( !mUidMap.contains( uid ) )
+ // Odd
+ return false;
+
+ if ( !mSilent ) {
+ kmailDeleteIncidence( mUidMap[ uid ].resource(),
+ mUidMap[ uid ].serialNumber() );
+ }
+ mUidMap.remove( uid );
+ manager()->deleteNote( journal );
+ mCalendar.deleteJournal( journal );
+ return true;
+}
+
+KCal::Alarm::List ResourceScalix::alarms( const QDateTime& from, const QDateTime& to )
+{
+ KCal::Alarm::List alarms;
+ KCal::Journal::List notes = mCalendar.journals();
+ KCal::Journal::List::ConstIterator note;
+ for ( note = notes.begin(); note != notes.end(); ++note )
+ {
+ QDateTime preTime = from.addSecs( -1 );
+ KCal::Alarm::List::ConstIterator it;
+ for( it = (*note)->alarms().begin(); it != (*note)->alarms().end(); ++it )
+ {
+ if ( (*it)->enabled() )
+ {
+ QDateTime dt = (*it)->nextRepetition( preTime );
+ if ( dt.isValid() && dt <= to )
+ alarms.append( *it );
+ }
+ }
+ }
+
+ return alarms;
+}
+
+void ResourceScalix::incidenceUpdated( KCal::IncidenceBase* i )
+{
+ QString subResource;
+ Q_UINT32 sernum;
+ if ( mUidMap.contains( i->uid() ) ) {
+ subResource = mUidMap[ i->uid() ].resource();
+ sernum = mUidMap[ i->uid() ].serialNumber();
+ } else { // can this happen?
+ subResource = findWritableResource( mSubResources );
+ if ( subResource.isEmpty() ) // canceled
+ return;
+ sernum = 0;
+ }
+
+ KCal::Journal* journal = dynamic_cast<KCal::Journal*>( i );
+ KCal::ICalFormat formatter;
+ const QString xml = formatter.toString( journal );
+ if( !xml.isEmpty() && kmailUpdate( subResource, sernum, xml, attachmentMimeType, journal->uid() ) )
+ mUidMap[ i->uid() ] = StorageReference( subResource, sernum );
+}
+
+/*
+ * These are the DCOP slots that KMail call to notify when something
+ * changed.
+ */
+bool ResourceScalix::fromKMailAddIncidence( const QString& type,
+ const QString& subResource,
+ Q_UINT32 sernum,
+ int,
+ const QString& note )
+{
+ // Check if this is a note
+ if( type != kmailContentsType ) return false;
+
+ const bool silent = mSilent;
+ mSilent = true;
+ QString mimetype = inlineMimeType;
+ KCal::Journal* journal = addNote( note, subResource, sernum, mimetype );
+ if ( journal )
+ manager()->registerNote( this, journal );
+ mSilent = silent;
+ return true;
+}
+
+void ResourceScalix::fromKMailDelIncidence( const QString& type,
+ const QString& /*subResource*/,
+ const QString& uid )
+{
+ // Check if this is a note
+ if( type != kmailContentsType ) return;
+
+ kdDebug(5500) << "ResourceScalix::fromKMailDelIncidence( " << type << ", " << uid
+ << " )" << endl;
+
+ const bool silent = mSilent;
+ mSilent = true;
+ KCal::Journal* j = mCalendar.journal( uid );
+ if( j )
+ deleteNote( j );
+ mSilent = silent;
+}
+
+void ResourceScalix::fromKMailRefresh( const QString& type,
+ const QString& /*subResource*/ )
+{
+ if ( type == kmailContentsType )
+ load(); // ### should call loadSubResource(subResource) probably
+}
+
+void ResourceScalix::fromKMailAddSubresource( const QString& type,
+ const QString& subResource,
+ const QString& mimetype,
+ bool writable )
+{
+ if ( type != kmailContentsType )
+ // Not ours
+ return;
+
+ if ( mSubResources.contains( subResource ) )
+ // Already registered
+ return;
+
+ KConfig config( configFile() );
+ config.setGroup( configGroupName );
+
+ bool active = config.readBoolEntry( subResource, true );
+ mSubResources[ subResource ] = Scalix::SubResource( active, writable, subResource );
+ loadSubResource( subResource, mimetype );
+ emit signalSubresourceAdded( this, type, subResource );
+}
+
+void ResourceScalix::fromKMailDelSubresource( const QString& type,
+ const QString& subResource )
+{
+ if ( type != configGroupName )
+ // Not ours
+ return;
+
+ if ( !mSubResources.contains( subResource ) )
+ // Not registered
+ return;
+
+ // Ok, it's our job, and we have it here
+ mSubResources.erase( subResource );
+
+ KConfig config( configFile() );
+ config.setGroup( configGroupName );
+ config.deleteEntry( subResource );
+ config.sync();
+
+ // Make a list of all uids to remove
+ Scalix::UidMap::ConstIterator mapIt;
+ QStringList uids;
+ for ( mapIt = mUidMap.begin(); mapIt != mUidMap.end(); ++mapIt )
+ if ( mapIt.data().resource() == subResource )
+ // We have a match
+ uids << mapIt.key();
+
+ // Finally delete all the incidences
+ if ( !uids.isEmpty() ) {
+ const bool silent = mSilent;
+ mSilent = true;
+ QStringList::ConstIterator it;
+ for ( it = uids.begin(); it != uids.end(); ++it ) {
+ KCal::Journal* j = mCalendar.journal( *it );
+ if( j )
+ deleteNote( j );
+ }
+ mSilent = silent;
+ }
+
+ emit signalSubresourceRemoved( this, type, subResource );
+}
+
+void ResourceScalix::fromKMailAsyncLoadResult( const QMap<Q_UINT32, QString>& map,
+ const QString& type,
+ const QString& folder )
+{
+ // We are only interested in notes
+ if ( ( type != attachmentMimeType ) && ( type != inlineMimeType ) ) return;
+ // Populate with the new entries
+ const bool silent = mSilent;
+ mSilent = true;
+ QString mimetype = inlineMimeType;
+ for( QMap<Q_UINT32, QString>::ConstIterator it = map.begin(); it != map.end(); ++it ) {
+ KCal::Journal* journal = addNote( it.data(), folder, it.key(), mimetype );
+ if ( !journal )
+ kdDebug(5500) << "loading note " << it.key() << " failed" << endl;
+ else
+ manager()->registerNote( this, journal );
+ }
+ mSilent = silent;
+}
+
+
+QStringList ResourceScalix::subresources() const
+{
+ return mSubResources.keys();
+}
+
+bool ResourceScalix::subresourceActive( const QString& res ) const
+{
+ if ( mSubResources.contains( res ) ) {
+ return mSubResources[ res ].active();
+ }
+
+ // Safe default bet:
+ kdDebug(5650) << "subresourceActive( " << res << " ): Safe bet\n";
+
+ return true;
+}
+
+
+#include "resourcescalix.moc"
diff --git a/kresources/scalix/knotes/resourcescalix.h b/kresources/scalix/knotes/resourcescalix.h
new file mode 100644
index 000000000..a26bd1973
--- /dev/null
+++ b/kresources/scalix/knotes/resourcescalix.h
@@ -0,0 +1,127 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef KNOTES_RESOURCESCALIX_H
+#define KNOTES_RESOURCESCALIX_H
+
+#include <resourcenotes.h>
+#include <libkcal/incidencebase.h>
+#include <libkcal/calendarlocal.h>
+#include "../shared/resourcescalixbase.h"
+#include "../shared/subresource.h"
+#include <kdepimmacros.h>
+
+
+namespace Scalix {
+
+/**
+ * This class implements a KNotes resource that keeps its
+ * addresses in an IMAP folder in KMail (or other conforming email
+ * clients).
+ */
+class KDE_EXPORT ResourceScalix : public ResourceNotes,
+ public KCal::IncidenceBase::Observer,
+ public ResourceScalixBase
+{
+ Q_OBJECT
+
+public:
+ ResourceScalix( const KConfig* );
+ virtual ~ResourceScalix();
+
+ /// Load resource data.
+ bool load();
+
+ /// Save resource data.
+ bool save();
+
+ /// Open the notes resource.
+ bool doOpen();
+ /// Close the notes resource.
+ void doClose();
+
+ bool addNote( KCal::Journal* );
+
+ bool deleteNote( KCal::Journal* );
+
+ KCal::Alarm::List alarms( const QDateTime& from, const QDateTime& to );
+
+ /// Reimplemented from IncidenceBase::Observer to know when a note was changed
+ void incidenceUpdated( KCal::IncidenceBase* );
+
+ /// The ResourceScalixBase methods called by KMail
+ bool fromKMailAddIncidence( const QString& type, const QString& resource,
+ Q_UINT32 sernum, int format, const QString& note );
+ void fromKMailDelIncidence( const QString& type, const QString& resource,
+ const QString& uid );
+ void fromKMailRefresh( const QString& type, const QString& resource );
+
+ /// Listen to KMail changes in the amount of sub resources
+ void fromKMailAddSubresource( const QString& type, const QString& resource,
+ const QString& label, bool writable );
+ void fromKMailDelSubresource( const QString& type, const QString& resource );
+
+ void fromKMailAsyncLoadResult( const QMap<Q_UINT32, QString>& map,
+ const QString& type,
+ const QString& folder );
+
+ /** Return the list of subresources. */
+ QStringList subresources() const;
+
+ /** Is this subresource active? */
+ bool subresourceActive( const QString& ) const;
+
+signals:
+ void signalSubresourceAdded( Resource*, const QString&, const QString& );
+ void signalSubresourceRemoved( Resource*, const QString&, const QString& );
+
+private:
+ bool addNote( KCal::Journal* journal, const QString& resource,
+ Q_UINT32 sernum );
+ KCal::Journal* addNote( const QString& data, const QString& subresource,
+ Q_UINT32 sernum, const QString &mimetype );
+
+ bool loadSubResource( const QString& resource, const QString& mimetype );
+
+ QString configFile() const {
+ return ResourceScalixBase::configFile( "knotes" );
+ }
+
+ KCal::CalendarLocal mCalendar;
+
+ // The list of subresources
+ Scalix::ResourceMap mSubResources;
+};
+
+}
+
+#endif // KNOTES_RESOURCESCALIX_H
diff --git a/kresources/scalix/knotes/resourcescalix_plugin.cpp b/kresources/scalix/knotes/resourcescalix_plugin.cpp
new file mode 100644
index 000000000..a83bbd746
--- /dev/null
+++ b/kresources/scalix/knotes/resourcescalix_plugin.cpp
@@ -0,0 +1,50 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2002 - 2004 Klar�lvdalens Datakonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "resourcescalix.h"
+
+class ScalixFactory : public KRES::PluginFactoryBase
+{
+public:
+ KRES::Resource *resource( const KConfig *config )
+ {
+ return new Scalix::ResourceScalix( config );
+ }
+
+ KRES::ConfigWidget *configWidget( QWidget* )
+ {
+ return 0;
+ }
+};
+
+K_EXPORT_COMPONENT_FACTORY( knotes_scalix, ScalixFactory() )
diff --git a/kresources/scalix/knotes/scalix.desktop b/kresources/scalix/knotes/scalix.desktop
new file mode 100644
index 000000000..a573bee8c
--- /dev/null
+++ b/kresources/scalix/knotes/scalix.desktop
@@ -0,0 +1,30 @@
+[Desktop Entry]
+Name=Notes on Scalix Server via KMail
+Name[bg]=Бележки на сървъра Scalix през KMail
+Name[ca]=Notes en un servidor Scalix mitjançant el KMail
+Name[da]=Noter på Scalix-server via KMail
+Name[de]=Notizen auf einem Scalix-Server via KMail
+Name[el]=Σημειώσεις σε εξυπηρετητή Scalix μέσω του KMail
+Name[es]=Notas en servidor Scalix por medio de KMail
+Name[et]=Kalender Scalix-serveris (KMaili vahendusel)
+Name[fr]=Notes sur serveur Scalix via KMail
+Name[is]=Minnismiðar á Scalix-þjóni gegnum KMail
+Name[it]=Note su server Scalix via KMail
+Name[ja]=KMail 経由 Scalix サーバのメモ
+Name[km]=ចំណាំ​នៅលើ​ម៉ាស៊ីន​បម្រើ Scalix តាមរយៈ KMail
+Name[nds]=Notizen op Scalix-Server över KMail
+Name[nl]=Notities op Scalix-server via KMail
+Name[pl]=Notatki na serwerze Scalix za pośrednictwem KMaila
+Name[ru]=Заметки на сервере Scalix через KMail
+Name[sk]=Poznámky na Scalix serveri pomocou KMail
+Name[sr]=Белешке на Scalix серверу преко KMail-а
+Name[sr@Latn]=Beleške na Scalix serveru preko KMail-a
+Name[sv]=Anteckningar på Scalix-server via Kmail
+Name[tr]=KMail Aracılığı ile Scalix Sunucusunda Takvim
+Name[zh_CN]=通过 KMail 访问 Scalix 服务器上的日历
+Name[zh_TW]=透過 KMail 取得 Scalix 伺服器上的便條
+X-KDE-Library=knotes_scalix
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=notes
+X-KDE-ResourceType=scalix
diff --git a/kresources/scalix/scalixadmin/Makefile.am b/kresources/scalix/scalixadmin/Makefile.am
new file mode 100644
index 000000000..7402ef281
--- /dev/null
+++ b/kresources/scalix/scalixadmin/Makefile.am
@@ -0,0 +1,15 @@
+bin_PROGRAMS = scalixadmin
+
+INCLUDES = $(all_includes)
+
+scalixadmin_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+scalixadmin_LDADD = $(LIB_KABC)
+scalixadmin_SOURCES = main.cpp mainwindow.cpp passwordpage.cpp settings.cpp jobs.cpp \
+ otherusermanager.cpp otheruserview.cpp otheruserpage.cpp ldapview.cpp ldapdialog.cpp \
+ delegatemanager.cpp delegateview.cpp delegatepage.cpp delegatedialog.cpp \
+ outofofficepage.cpp
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/scalixadmin.pot
diff --git a/kresources/scalix/scalixadmin/delegatedialog.cpp b/kresources/scalix/scalixadmin/delegatedialog.cpp
new file mode 100644
index 000000000..3dc0412a4
--- /dev/null
+++ b/kresources/scalix/scalixadmin/delegatedialog.cpp
@@ -0,0 +1,105 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qtoolbutton.h>
+
+#include <klocale.h>
+
+#include "jobs.h"
+#include "ldapdialog.h"
+
+#include "delegatedialog.h"
+
+DelegateDialog::DelegateDialog( QWidget *parent )
+ : KDialogBase( parent, "", true, "", Ok | Cancel, Ok, true )
+{
+ QWidget *page = new QWidget( this );
+ QGridLayout *layout = new QGridLayout( page, 5, 3, 11, 6 );
+
+ QLabel *label = new QLabel( i18n( "User:" ), page );
+ layout->addWidget( label, 0, 0 );
+
+ mEmail = new QLineEdit( page );
+ layout->addWidget( mEmail, 0, 1 );
+
+ QToolButton *emailSelector = new QToolButton( page );
+ emailSelector->setUsesTextLabel( true );
+ emailSelector->setTextLabel( i18n( "..." ) );
+ layout->addWidget( emailSelector, 0, 2 );
+
+ QValueList<Scalix::DelegateTypes> types;
+ types << Scalix::SendOnBehalfOf;
+ types << Scalix::SeePrivate;
+ types << Scalix::GetMeetings;
+ types << Scalix::InsteadOfMe;
+
+ int row = 1;
+ for ( uint i = 0; i < types.count(); ++i ) {
+ QCheckBox *box = new QCheckBox( Scalix::Delegate::rightsAsString( types[ i ] ), page );
+ layout->addMultiCellWidget( box, row, row, 1, 2 );
+
+ mRights.insert( types[ i ], box );
+ row++;
+ }
+
+ connect( emailSelector, SIGNAL( clicked() ), SLOT( selectEmail() ) );
+
+ setMainWidget( page );
+}
+
+void DelegateDialog::setDelegate( const Scalix::Delegate &delegate )
+{
+ mEmail->setText( delegate.email() );
+
+ QMap<int, QCheckBox*>::Iterator it;
+ for ( it = mRights.begin(); it != mRights.end(); ++it )
+ it.data()->setChecked( delegate.rights() & it.key() );
+}
+
+Scalix::Delegate DelegateDialog::delegate() const
+{
+ int rights = 0;
+
+ QMap<int, QCheckBox*>::ConstIterator it;
+ for ( it = mRights.begin(); it != mRights.end(); ++it )
+ if ( it.data()->isChecked() )
+ rights |= it.key();
+
+ return Scalix::Delegate( mEmail->text(), rights );
+}
+
+void DelegateDialog::selectEmail()
+{
+ LdapDialog dlg( this );
+ if ( !dlg.exec() )
+ return;
+
+ const QString email = dlg.selectedUser();
+ if ( email.isEmpty() )
+ return;
+
+ mEmail->setText( email );
+}
+
+#include "delegatedialog.moc"
diff --git a/kresources/scalix/scalixadmin/delegatedialog.h b/kresources/scalix/scalixadmin/delegatedialog.h
new file mode 100644
index 000000000..b5503a4f3
--- /dev/null
+++ b/kresources/scalix/scalixadmin/delegatedialog.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DELEGATEDIALOG_H
+#define DELEGATEDIALOG_H
+
+#include <qmap.h>
+
+#include <kdialogbase.h>
+
+class QCheckBox;
+class QLineEdit;
+
+namespace Scalix {
+class Delegate;
+}
+
+class DelegateDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ DelegateDialog( QWidget *parent = 0 );
+
+ void setDelegate( const Scalix::Delegate &delegate );
+ Scalix::Delegate delegate() const;
+
+ private slots:
+ void selectEmail();
+
+ private:
+ QLineEdit *mEmail;
+ QMap<int, QCheckBox*> mRights;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/delegatemanager.cpp b/kresources/scalix/scalixadmin/delegatemanager.cpp
new file mode 100644
index 000000000..686370d77
--- /dev/null
+++ b/kresources/scalix/scalixadmin/delegatemanager.cpp
@@ -0,0 +1,49 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "delegatemanager.h"
+
+DelegateManager::DelegateManager()
+{
+}
+
+DelegateManager::~DelegateManager()
+{
+}
+
+void DelegateManager::addDelegate( const Scalix::Delegate &delegate )
+{
+ mDelegates.append( delegate );
+ emit changed();
+}
+
+void DelegateManager::clear()
+{
+ mDelegates.clear();
+
+ emit changed();
+}
+
+Scalix::Delegate::List DelegateManager::delegates() const
+{
+ return mDelegates;
+}
+
+#include "delegatemanager.moc"
diff --git a/kresources/scalix/scalixadmin/delegatemanager.h b/kresources/scalix/scalixadmin/delegatemanager.h
new file mode 100644
index 000000000..f27b79a1b
--- /dev/null
+++ b/kresources/scalix/scalixadmin/delegatemanager.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DELEGATEMANAGER_H
+#define DELEGATEMANAGER_H
+
+#include <qobject.h>
+#include <qstringlist.h>
+
+#include "jobs.h"
+
+class DelegateManager : public QObject
+{
+ Q_OBJECT
+
+ public:
+ DelegateManager();
+ ~DelegateManager();
+
+ void addDelegate( const Scalix::Delegate &delegate );
+ void clear();
+
+ Scalix::Delegate::List delegates() const;
+
+ signals:
+ void changed();
+
+ private:
+ Scalix::Delegate::List mDelegates;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/delegatepage.cpp b/kresources/scalix/scalixadmin/delegatepage.cpp
new file mode 100644
index 000000000..f9a9b8e7a
--- /dev/null
+++ b/kresources/scalix/scalixadmin/delegatepage.cpp
@@ -0,0 +1,170 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include <unistd.h>
+
+#include "delegatedialog.h"
+#include "delegateview.h"
+#include "jobs.h"
+#include "settings.h"
+
+#include "delegatepage.h"
+
+DelegatePage::DelegatePage( QWidget *parent )
+ : QWidget( parent )
+{
+ QGridLayout *layout = new QGridLayout( this, 2, 3, 11, 6 );
+
+ mView = new DelegateView( &mManager, this );
+ layout->addMultiCellWidget( mView, 0, 0, 0, 2 );
+
+ mAddButton = new QPushButton( i18n( "Add Delegate..." ), this );
+ layout->addWidget( mAddButton, 1, 0 );
+
+ mEditButton = new QPushButton( i18n( "Edit Delegate..." ), this );
+ mEditButton->setEnabled( false );
+ layout->addWidget( mEditButton, 1, 1 );
+
+ mRemoveButton = new QPushButton( i18n( "Remove Delegate" ), this );
+ mRemoveButton->setEnabled( false );
+ layout->addWidget( mRemoveButton, 1, 2 );
+
+ connect( mView, SIGNAL( selectionChanged() ), SLOT( selectionChanged() ) );
+ connect( mAddButton, SIGNAL( clicked() ), SLOT( addDelegate() ) );
+ connect( mEditButton, SIGNAL( clicked() ), SLOT( editDelegate() ) );
+ connect( mRemoveButton, SIGNAL( clicked() ), SLOT( removeDelegate() ) );
+
+ loadAllDelegates();
+}
+
+DelegatePage::~DelegatePage()
+{
+}
+
+void DelegatePage::loadAllDelegates()
+{
+ Scalix::GetDelegatesJob *job = Scalix::getDelegates( Settings::self()->globalSlave(),
+ Settings::self()->accountUrl() );
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( allDelegates( KIO::Job* ) ) );
+}
+
+void DelegatePage::addDelegate()
+{
+ DelegateDialog dlg( this );
+ dlg.setCaption( i18n( "Add Delegate" ) );
+
+ if ( !dlg.exec() )
+ return;
+
+ const Scalix::Delegate delegate = dlg.delegate();
+
+ if ( !delegate.isValid() )
+ return;
+
+ Scalix::SetDelegateJob *job = Scalix::setDelegate( Settings::self()->globalSlave(),
+ Settings::self()->accountUrl(),
+ delegate.email(), delegate.rights() );
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( delegateAdded( KIO::Job* ) ) );
+}
+
+void DelegatePage::editDelegate()
+{
+ const Scalix::Delegate oldDelegate = mView->selectedDelegate();
+ if ( !oldDelegate.isValid() )
+ return;
+
+ DelegateDialog dlg( this );
+ dlg.setCaption( i18n( "Edit Delegate" ) );
+
+ dlg.setDelegate( oldDelegate );
+
+ if ( !dlg.exec() )
+ return;
+
+ const Scalix::Delegate delegate = dlg.delegate();
+
+ if ( !delegate.isValid() )
+ return;
+
+ Scalix::SetDelegateJob *job = Scalix::setDelegate( Settings::self()->globalSlave(),
+ Settings::self()->accountUrl(),
+ delegate.email(), delegate.rights() );
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( delegateAdded( KIO::Job* ) ) );
+}
+
+void DelegatePage::removeDelegate()
+{
+ const Scalix::Delegate delegate = mView->selectedDelegate();
+ if ( !delegate.isValid() )
+ return;
+
+ Scalix::DeleteDelegateJob *job = Scalix::deleteDelegate( Settings::self()->globalSlave(),
+ Settings::self()->accountUrl(), delegate.email() );
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( delegateRemoved( KIO::Job* ) ) );
+}
+
+void DelegatePage::allDelegates( KIO::Job *job )
+{
+ if ( job->error() )
+ KMessageBox::error( this, job->errorString() );
+
+ Scalix::GetDelegatesJob *delegateJob = static_cast<Scalix::GetDelegatesJob*>( job );
+
+ mManager.clear();
+
+ const Scalix::Delegate::List delegates = delegateJob->delegates();
+ for ( uint i = 0; i < delegates.count(); ++i )
+ mManager.addDelegate( delegates[ i ] );
+
+ selectionChanged();
+}
+
+void DelegatePage::delegateAdded( KIO::Job *job )
+{
+ if ( job->error() )
+ KMessageBox::error( this, job->errorString() );
+ else
+ loadAllDelegates(); // update the GUI
+}
+
+void DelegatePage::delegateRemoved( KIO::Job *job )
+{
+ if ( job->error() )
+ KMessageBox::error( this, job->errorString() );
+ else
+ loadAllDelegates(); // update the GUI
+}
+
+void DelegatePage::selectionChanged()
+{
+ bool state = ( mView->selectedItem() != 0 );
+
+ mEditButton->setEnabled( state );
+ mRemoveButton->setEnabled( state );
+}
+
+#include "delegatepage.moc"
diff --git a/kresources/scalix/scalixadmin/delegatepage.h b/kresources/scalix/scalixadmin/delegatepage.h
new file mode 100644
index 000000000..243c0f0d3
--- /dev/null
+++ b/kresources/scalix/scalixadmin/delegatepage.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DELEGATEPAGE_H
+#define DELEGATEPAGE_H
+
+#include <qwidget.h>
+
+#include "delegatemanager.h"
+
+class QPushButton;
+class DelegateView;
+
+class DelegatePage : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ DelegatePage( QWidget *parent = 0 );
+ ~DelegatePage();
+
+ private slots:
+ void loadAllDelegates();
+ void addDelegate();
+ void editDelegate();
+ void removeDelegate();
+
+ void delegateAdded( KIO::Job* );
+ void delegateRemoved( KIO::Job* );
+ void allDelegates( KIO::Job* );
+
+ void selectionChanged();
+
+ private:
+ QPushButton *mAddButton;
+ QPushButton *mEditButton;
+ QPushButton *mRemoveButton;
+
+ DelegateManager mManager;
+ DelegateView *mView;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/delegateview.cpp b/kresources/scalix/scalixadmin/delegateview.cpp
new file mode 100644
index 000000000..9ea16cf1a
--- /dev/null
+++ b/kresources/scalix/scalixadmin/delegateview.cpp
@@ -0,0 +1,74 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <klocale.h>
+
+#include "delegatemanager.h"
+
+#include "delegateview.h"
+
+class DelegateItem : public QListViewItem
+{
+ public:
+ DelegateItem( QListView *parent, const Scalix::Delegate &delegate )
+ : QListViewItem( parent ), mDelegate( delegate )
+ {
+ setText( 0, mDelegate.email() );
+ setText( 1, Scalix::Delegate::rightsAsString( mDelegate.rights() ) );
+ }
+
+ Scalix::Delegate delegate() const { return mDelegate; }
+
+ private:
+ Scalix::Delegate mDelegate;
+};
+
+DelegateView::DelegateView( DelegateManager *manager, QWidget *parent )
+ : KListView( parent ), mManager( manager )
+{
+ addColumn( i18n( "Delegate" ) );
+ addColumn( i18n( "Rights" ) );
+ setFullWidth( true );
+ setAllColumnsShowFocus( true );
+
+ connect( mManager, SIGNAL( changed() ), SLOT( delegateChanged() ) );
+
+ delegateChanged();
+}
+
+Scalix::Delegate DelegateView::selectedDelegate() const
+{
+ DelegateItem *item = dynamic_cast<DelegateItem*>( selectedItem() );
+ if ( item )
+ return item->delegate();
+
+ return Scalix::Delegate();
+}
+
+void DelegateView::delegateChanged()
+{
+ clear();
+
+ const Scalix::Delegate::List delegates = mManager->delegates();
+ for ( uint i = 0; i < delegates.count(); ++i )
+ new DelegateItem( this, delegates[ i ] );
+}
+
+#include "delegateview.moc"
diff --git a/kresources/scalix/scalixadmin/delegateview.h b/kresources/scalix/scalixadmin/delegateview.h
new file mode 100644
index 000000000..61725be29
--- /dev/null
+++ b/kresources/scalix/scalixadmin/delegateview.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DELEGATEVIEW_H
+#define DELEGATEVIEW_H
+
+#include <klistview.h>
+
+namespace Scalix {
+class Delegate;
+}
+
+class DelegateManager;
+
+class DelegateView : public KListView
+{
+ Q_OBJECT
+
+ public:
+ DelegateView( DelegateManager *manager, QWidget *parent = 0 );
+
+ Scalix::Delegate selectedDelegate() const;
+
+ private slots:
+ void delegateChanged();
+
+ private:
+ DelegateManager *mManager;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/jobs.cpp b/kresources/scalix/scalixadmin/jobs.cpp
new file mode 100644
index 000000000..c463463d2
--- /dev/null
+++ b/kresources/scalix/scalixadmin/jobs.cpp
@@ -0,0 +1,306 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kio/scheduler.h>
+#include <klocale.h>
+
+#include "jobs.h"
+
+using namespace Scalix;
+
+Delegate::Delegate()
+ : mRights( -1 )
+{
+}
+
+Delegate::Delegate( const QString &email, int rights )
+ : mEmail( email ), mRights( rights )
+{
+}
+
+bool Delegate::isValid() const
+{
+ return ( !mEmail.isEmpty() && mRights != -1 );
+}
+
+QString Delegate::email() const
+{
+ return mEmail;
+}
+
+int Delegate::rights() const
+{
+ return mRights;
+}
+
+QString Delegate::rightsAsString( int rights )
+{
+ QStringList rightNames;
+
+ if ( rights & SendOnBehalfOf )
+ rightNames.append( i18n( "Send on behalf of" ) );
+ if ( rights & SeePrivate )
+ rightNames.append( i18n( "See private" ) );
+ if ( rights & GetMeetings )
+ rightNames.append( i18n( "Get meetings" ) );
+ if ( rights & InsteadOfMe )
+ rightNames.append( i18n( "Instead of me" ) );
+
+ return rightNames.join( ", " );
+}
+
+
+SetPasswordJob* Scalix::setPassword( KIO::Slave* slave, const KURL& url,
+ const QString &oldPassword, const QString& newPassword )
+{
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)'X' << (int)'N'
+ << QString( "X-SCALIX-PASSWORD" ) << QString( "%1 %2" ).arg( oldPassword ).arg( newPassword );
+
+ SetPasswordJob* job = new SetPasswordJob( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave( slave, job );
+ return job;
+}
+
+SetDelegateJob* Scalix::setDelegate( KIO::Slave* slave, const KURL& url, const QString& email, int params )
+{
+ QStringList types;
+ if ( params & SendOnBehalfOf )
+ types.append( "SOBO" );
+ if ( params & SeePrivate )
+ types.append( "SEEPRIVATE" );
+ if ( params & GetMeetings )
+ types.append( "GETMEETINGS" );
+ if ( params & InsteadOfMe )
+ types.append( "INSTEADOFME" );
+
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)'X' << (int)'N'
+ << QString( "X-SET-DELEGATE" ) << QString( "%1 %2" ).arg( email ).arg( types.join( " " ) );
+
+ SetDelegateJob* job = new SetDelegateJob( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave( slave, job );
+ return job;
+}
+
+DeleteDelegateJob* Scalix::deleteDelegate( KIO::Slave* slave, const KURL& url, const QString& email )
+{
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)'X' << (int)'N'
+ << QString( "X-DELETE-DELEGATE" ) << email;
+
+ DeleteDelegateJob* job = new DeleteDelegateJob( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave( slave, job );
+ return job;
+}
+
+GetDelegatesJob* Scalix::getDelegates( KIO::Slave* slave, const KURL& url )
+{
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)'X' << (int)'N' << QString( "X-GET-DELEGATES" ) << QString();
+
+ GetDelegatesJob* job = new GetDelegatesJob( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave( slave, job );
+ return job;
+}
+
+AddOtherUserJob* Scalix::addOtherUser( KIO::Slave* slave, const KURL& url, const QString& email )
+{
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)'X' << (int)'N'
+ << QString( "X-ADD-OTHER-USER" ) << email;
+
+ AddOtherUserJob* job = new AddOtherUserJob( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave( slave, job );
+ return job;
+}
+
+DeleteOtherUserJob* Scalix::deleteOtherUser( KIO::Slave* slave, const KURL& url, const QString& email )
+{
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)'X' << (int)'N'
+ << QString( "X-DELETE-OTHER-USER" ) << email;
+
+ DeleteOtherUserJob* job = new DeleteOtherUserJob( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave( slave, job );
+ return job;
+}
+
+GetOtherUsersJob* Scalix::getOtherUsers( KIO::Slave* slave, const KURL& url )
+{
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)'X' << (int)'N'
+ << QString( "X-GET-OTHER-USERS" ) << QString();
+
+ GetOtherUsersJob* job = new GetOtherUsersJob( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave( slave, job );
+ return job;
+}
+
+SetOutOfOfficeJob* Scalix::setOutOfOffice( KIO::Slave* slave, const KURL& url, bool enabled, const QString& msg )
+{
+ const QString argument = msg;
+ const QString command = QString( "X-SET-OUT-OF-OFFICE %1 %2 {%3}" ).arg( enabled ? "ENABLED" : "DISABLED" )
+ .arg( "UTF-8" )
+ .arg( msg.utf8().length() );
+
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int) 'X' << (int)'E' << command << argument;
+
+ SetOutOfOfficeJob* job = new SetOutOfOfficeJob( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave( slave, job );
+ return job;
+}
+
+GetOutOfOfficeJob* Scalix::getOutOfOffice( KIO::Slave* slave, const KURL& url )
+{
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)'X' << (int)'N'
+ << QString( "X-GET-OUT-OF-OFFICE" ) << QString();
+
+ GetOutOfOfficeJob* job = new GetOutOfOfficeJob( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave( slave, job );
+ return job;
+}
+
+SetPasswordJob::SetPasswordJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo )
+ : KIO::SimpleJob( url, KIO::CMD_SPECIAL, packedArgs, showProgressInfo )
+{
+}
+
+SetDelegateJob::SetDelegateJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo )
+ : KIO::SimpleJob( url, KIO::CMD_SPECIAL, packedArgs, showProgressInfo )
+{
+}
+
+DeleteDelegateJob::DeleteDelegateJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo )
+ : KIO::SimpleJob( url, KIO::CMD_SPECIAL, packedArgs, showProgressInfo )
+{
+}
+
+GetDelegatesJob::GetDelegatesJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo )
+ : KIO::SimpleJob( url, KIO::CMD_SPECIAL, packedArgs, showProgressInfo )
+{
+ connect( this, SIGNAL( infoMessage( KIO::Job*, const QString& ) ),
+ this, SLOT( slotInfoMessage( KIO::Job*, const QString& ) ) );
+}
+
+Delegate::List GetDelegatesJob::delegates() const
+{
+ return mDelegates;
+}
+
+void GetDelegatesJob::slotInfoMessage( KIO::Job*, const QString &data )
+{
+ /**
+ * The passed data have the following form:
+ *
+ * "[email protected]:right1,right2,right4 [email protected]:right3,right5"
+ */
+ QStringList delegates = QStringList::split( ' ', data );
+ for ( uint i = 0; i < delegates.count(); ++i ) {
+ QStringList delegate = QStringList::split( ':', delegates[ i ] );
+
+ const QString email = delegate[ 0 ];
+ int rights = 0;
+
+ QStringList rightsList = QStringList::split( ',', delegate[ 1 ] );
+ for ( uint j = 0; j < rightsList.count(); ++j ) {
+ if ( rightsList[ j ] == "SOBO" )
+ rights |= SendOnBehalfOf;
+ else if ( rightsList[ j ] == "SEEPRIVATE" )
+ rights |= SeePrivate;
+ else if ( rightsList[ j ] == "GETMEETINGS" )
+ rights |= GetMeetings;
+ else if ( rightsList[ j ] == "INSTEADOFME" )
+ rights |= InsteadOfMe;
+ }
+
+ mDelegates.append( Delegate( email, rights ) );
+ }
+}
+
+AddOtherUserJob::AddOtherUserJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo )
+ : KIO::SimpleJob( url, KIO::CMD_SPECIAL, packedArgs, showProgressInfo )
+{
+}
+
+DeleteOtherUserJob::DeleteOtherUserJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo )
+ : KIO::SimpleJob( url, KIO::CMD_SPECIAL, packedArgs, showProgressInfo )
+{
+}
+
+GetOtherUsersJob::GetOtherUsersJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo )
+ : KIO::SimpleJob( url, KIO::CMD_SPECIAL, packedArgs, showProgressInfo )
+{
+ connect( this, SIGNAL( infoMessage( KIO::Job*, const QString& ) ),
+ this, SLOT( slotInfoMessage( KIO::Job*, const QString& ) ) );
+}
+
+QStringList GetOtherUsersJob::otherUsers() const
+{
+ return mOtherUsers;
+}
+
+void GetOtherUsersJob::slotInfoMessage( KIO::Job*, const QString &data )
+{
+ mOtherUsers = QStringList::split( ' ', data );
+}
+
+SetOutOfOfficeJob::SetOutOfOfficeJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo )
+ : KIO::SimpleJob( url, KIO::CMD_SPECIAL, packedArgs, showProgressInfo )
+{
+}
+
+GetOutOfOfficeJob::GetOutOfOfficeJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo )
+ : KIO::SimpleJob( url, KIO::CMD_SPECIAL, packedArgs, showProgressInfo )
+{
+ connect( this, SIGNAL( infoMessage( KIO::Job*, const QString& ) ),
+ this, SLOT( slotInfoMessage( KIO::Job*, const QString& ) ) );
+}
+
+bool GetOutOfOfficeJob::enabled() const
+{
+ return mEnabled;
+}
+
+QString GetOutOfOfficeJob::message() const
+{
+ return mMessage;
+}
+
+void GetOutOfOfficeJob::slotInfoMessage( KIO::Job*, const QString &data )
+{
+ const QStringList fields = QStringList::split( '^', data );
+
+ mEnabled = ( fields[ 0 ] == "ENABLED" );
+ mMessage = fields[ 1 ];
+}
+
+#include "jobs.moc"
diff --git a/kresources/scalix/scalixadmin/jobs.h b/kresources/scalix/scalixadmin/jobs.h
new file mode 100644
index 000000000..3b5a1b81f
--- /dev/null
+++ b/kresources/scalix/scalixadmin/jobs.h
@@ -0,0 +1,202 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kio/job.h>
+
+#ifndef JOBS_H
+#define JOBS_H
+
+namespace Scalix {
+
+ enum DelegateTypes
+ {
+ SendOnBehalfOf = 1,
+ SeePrivate = 2,
+ GetMeetings = 4,
+ InsteadOfMe = 8
+ };
+
+ class SetPasswordJob;
+ class SetDelegateJob;
+ class DeleteDelegateJob;
+ class GetDelegatesJob;
+ class AddOtherUserJob;
+ class DeleteOtherUserJob;
+ class GetOtherUsersJob;
+ class SetOutOfOfficeJob;
+ class GetOutOfOfficeJob;
+
+ class Delegate
+ {
+ public:
+ typedef QValueList<Delegate> List;
+
+ Delegate();
+ Delegate( const QString &email, int rights );
+
+ bool isValid() const;
+
+ QString email() const;
+ int rights() const;
+
+ static QString rightsAsString( int rights );
+
+ private:
+ QString mEmail;
+ int mRights;
+ };
+
+ /**
+ * Sets/Changes the password of the user encoded in @p url.
+ */
+ SetPasswordJob* setPassword( KIO::Slave* slave, const KURL& url, const QString& oldPassword, const QString& newPassword );
+
+ /**
+ * Adds a delegate represented by @p email with the given @p params for the user encoded in @p url.
+ */
+ SetDelegateJob* setDelegate( KIO::Slave* slave, const KURL& url, const QString& email, int params );
+
+ /**
+ * Deletes the delegate represented by @p email for the user encoded in @p url.
+ */
+ DeleteDelegateJob* deleteDelegate( KIO::Slave* slave, const KURL& url, const QString& email );
+
+ /**
+ * Retrieves the delegates for the user encoded in @p url.
+ */
+ GetDelegatesJob* getDelegates( KIO::Slave* slave, const KURL& url );
+
+ /**
+ * Adds the mailbox of another user represented by @p email to the users 'Other Users' namespace.
+ */
+ AddOtherUserJob* addOtherUser( KIO::Slave* slave, const KURL& url, const QString& email );
+
+ /**
+ * Deletes the mailbox of another user represented by @p email from the users 'Other Users' namespace.
+ */
+ DeleteOtherUserJob* deleteOtherUser( KIO::Slave* slave, const KURL& url, const QString& email );
+
+ /**
+ * Retrieves the list of all other users.
+ */
+ GetOtherUsersJob* getOtherUsers( KIO::Slave* slave, const KURL& url );
+
+ /**
+ * Sets the out-of-office data.
+ *
+ * @param enabled Whether the out-of-office functionality is enabled.
+ * @param msg The out-of-office message.
+ */
+ SetOutOfOfficeJob* setOutOfOffice( KIO::Slave* slave, const KURL& url, bool enabled, const QString& msg );
+
+ /**
+ * Retrieves the out-of-office data.
+ */
+ GetOutOfOfficeJob* getOutOfOffice( KIO::Slave* slave, const KURL& url );
+
+
+ class SetPasswordJob : public KIO::SimpleJob
+ {
+ public:
+ SetPasswordJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo );
+ };
+
+ class SetDelegateJob : public KIO::SimpleJob
+ {
+ public:
+ SetDelegateJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo );
+ };
+
+ class DeleteDelegateJob : public KIO::SimpleJob
+ {
+ public:
+ DeleteDelegateJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo );
+ };
+
+ class GetDelegatesJob : public KIO::SimpleJob
+ {
+ Q_OBJECT
+
+ public:
+ GetDelegatesJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo );
+
+ Delegate::List delegates() const;
+
+ private slots:
+ void slotInfoMessage( KIO::Job*, const QString& );
+
+ private:
+ Delegate::List mDelegates;
+ };
+
+ class AddOtherUserJob : public KIO::SimpleJob
+ {
+ public:
+ AddOtherUserJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo );
+ };
+
+ class DeleteOtherUserJob : public KIO::SimpleJob
+ {
+ public:
+ DeleteOtherUserJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo );
+ };
+
+ class GetOtherUsersJob : public KIO::SimpleJob
+ {
+ Q_OBJECT
+
+ public:
+ GetOtherUsersJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo );
+
+ QStringList otherUsers() const;
+
+ private slots:
+ void slotInfoMessage( KIO::Job*, const QString& );
+
+ private:
+ QStringList mOtherUsers;
+ };
+
+ class SetOutOfOfficeJob : public KIO::SimpleJob
+ {
+ public:
+ SetOutOfOfficeJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo );
+ };
+
+ class GetOutOfOfficeJob : public KIO::SimpleJob
+ {
+ Q_OBJECT
+
+ public:
+ GetOutOfOfficeJob( const KURL& url, const QByteArray &packedArgs, bool showProgressInfo );
+
+ bool enabled() const;
+ QString message() const;
+
+ private slots:
+ void slotInfoMessage( KIO::Job*, const QString& );
+
+ private:
+ bool mEnabled;
+ QString mMessage;
+ };
+}
+
+#endif
diff --git a/kresources/scalix/scalixadmin/ldapdialog.cpp b/kresources/scalix/scalixadmin/ldapdialog.cpp
new file mode 100644
index 000000000..be624f131
--- /dev/null
+++ b/kresources/scalix/scalixadmin/ldapdialog.cpp
@@ -0,0 +1,43 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <klocale.h>
+
+#include "ldapview.h"
+
+#include "ldapdialog.h"
+
+LdapDialog::LdapDialog( QWidget *parent )
+ : KDialogBase( parent, "", true, "", Ok | Cancel, Ok, true )
+{
+ setCaption( i18n( "User Account Selection" ) );
+
+ mView = new LdapView( this );
+ setMainWidget( mView );
+
+ mView->setQuery( "cn=*" );
+
+ resize( 400, 250 );
+}
+
+QString LdapDialog::selectedUser() const
+{
+ return mView->selectedUser();
+}
diff --git a/kresources/scalix/scalixadmin/ldapdialog.h b/kresources/scalix/scalixadmin/ldapdialog.h
new file mode 100644
index 000000000..6b326f550
--- /dev/null
+++ b/kresources/scalix/scalixadmin/ldapdialog.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef LDAPDIALOG_H
+#define LDAPDIALOG_H
+
+#include <kdialogbase.h>
+
+class LdapView;
+
+class LdapDialog : public KDialogBase
+{
+ public:
+ LdapDialog( QWidget *parent = 0 );
+
+ QString selectedUser() const;
+
+
+ private:
+ LdapView *mView;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/ldapview.cpp b/kresources/scalix/scalixadmin/ldapview.cpp
new file mode 100644
index 000000000..660f1944a
--- /dev/null
+++ b/kresources/scalix/scalixadmin/ldapview.cpp
@@ -0,0 +1,99 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kabc/ldapclient.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include "settings.h"
+
+#include "ldapview.h"
+
+class LdapItem : public QListViewItem
+{
+ public:
+ LdapItem( QListView *parent, const QString &text, const QString &email )
+ : QListViewItem( parent )
+ {
+ setText( 0, text );
+ setText( 1, email );
+ }
+};
+
+
+LdapView::LdapView( QWidget *parent )
+ : KListView( parent )
+{
+ addColumn( i18n( "User" ) );
+ setFullWidth( true );
+
+ mClient = new KABC::LdapClient;
+
+ mClient->setHost( Settings::self()->ldapHost() );
+ mClient->setPort( Settings::self()->ldapPort() );
+ mClient->setBase( Settings::self()->ldapBase() );
+ mClient->setBindDN( Settings::self()->ldapBindDn() );
+ mClient->setPwdBindDN( Settings::self()->ldapPassword() );
+
+ QStringList attrs;
+ attrs << "surname" << "mail";
+ mClient->setAttrs( attrs );
+
+ connect( mClient, SIGNAL( result( const KABC::LdapObject& ) ),
+ this, SLOT( entryAdded( const KABC::LdapObject& ) ) );
+ connect( mClient, SIGNAL( error( const QString& ) ),
+ this, SLOT( error( const QString& ) ) );
+}
+
+LdapView::~LdapView()
+{
+ mClient->cancelQuery();
+ delete mClient;
+}
+
+QString LdapView::selectedUser() const
+{
+ QListViewItem *item = selectedItem();
+ if ( !item )
+ return QString();
+ else
+ return item->text( 1 );
+}
+
+void LdapView::setQuery( const QString &query )
+{
+ clear();
+ mClient->startQuery( query );
+}
+
+void LdapView::entryAdded( const KABC::LdapObject &obj )
+{
+ const QString text = QString( "%1 (%2)" ).arg( obj.attrs[ "surname" ].first() )
+ .arg( obj.attrs[ "mail" ].first() );
+
+ new LdapItem( this, text, obj.attrs[ "mail" ].first() );
+}
+
+void LdapView::error( const QString &msg )
+{
+ KMessageBox::error( this, msg );
+}
+
+#include "ldapview.moc"
diff --git a/kresources/scalix/scalixadmin/ldapview.h b/kresources/scalix/scalixadmin/ldapview.h
new file mode 100644
index 000000000..0acb3602c
--- /dev/null
+++ b/kresources/scalix/scalixadmin/ldapview.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef LDAPVIEW_H
+#define LDAPVIEW_H
+
+#include <klistview.h>
+
+namespace KABC {
+class LdapClient;
+class LdapObject;
+}
+
+class LdapView : public KListView
+{
+ Q_OBJECT
+
+ public:
+ LdapView( QWidget *parent = 0 );
+ ~LdapView();
+
+ QString selectedUser() const;
+
+ public slots:
+ void setQuery( const QString &query );
+
+ private slots:
+ void entryAdded( const KABC::LdapObject& );
+ void error( const QString& );
+
+ private:
+ KABC::LdapClient *mClient;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/main.cpp b/kresources/scalix/scalixadmin/main.cpp
new file mode 100644
index 000000000..d27399210
--- /dev/null
+++ b/kresources/scalix/scalixadmin/main.cpp
@@ -0,0 +1,53 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+
+#include "mainwindow.h"
+
+static const char description[] = I18N_NOOP("Configuration Tool for Scalix Groupware Konnector");
+
+static KCmdLineOptions options[] =
+{
+ KCmdLineLastOption
+};
+
+int main( int argc, char **argv )
+{
+ KAboutData aboutData( "scalixadmin", I18N_NOOP("ScalixAdmin"), "1.0", description,
+ KAboutData::License_GPL, "(c) 2007, Tobias Koenig" );
+ aboutData.addAuthor( "Tobias Koenig",0, "[email protected]" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KApplication app;
+
+ KGlobal::locale()->insertCatalogue( "scalixadmin" );
+
+ MainWindow *window = new MainWindow;
+ window->show();
+
+ app.setMainWidget( window );
+
+ return app.exec();
+}
diff --git a/kresources/scalix/scalixadmin/mainwindow.cpp b/kresources/scalix/scalixadmin/mainwindow.cpp
new file mode 100644
index 000000000..e6cac550d
--- /dev/null
+++ b/kresources/scalix/scalixadmin/mainwindow.cpp
@@ -0,0 +1,59 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qvbox.h>
+
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kjanuswidget.h>
+#include <klocale.h>
+
+#include "delegatepage.h"
+#include "otheruserpage.h"
+#include "outofofficepage.h"
+#include "passwordpage.h"
+
+#include "mainwindow.h"
+
+MainWindow::MainWindow()
+ : KMainWindow( 0 )
+{
+ KJanusWidget *wdg = new KJanusWidget( this, "", KJanusWidget::IconList );
+
+ QPixmap icon = KGlobal::iconLoader()->loadIcon( "folder_yellow", KIcon::Desktop );
+ QVBox *page = wdg->addVBoxPage( i18n( "Other Accounts" ), i18n( "Register other accounts" ), icon );
+ new OtherUserPage( page );
+
+ icon = KGlobal::iconLoader()->loadIcon( "edu_languages", KIcon::Desktop );
+ page = wdg->addVBoxPage( i18n( "Delegates" ), i18n( "Setup delegates for my account" ), icon );
+ new DelegatePage( page );
+
+ icon = KGlobal::iconLoader()->loadIcon( "kontact_summary_green", KIcon::Desktop );
+ page = wdg->addVBoxPage( i18n( "Out of Office..." ), i18n( "Setup Out of Office Message" ), icon );
+ new OutOfOfficePage( page );
+
+ icon = KGlobal::iconLoader()->loadIcon( "password", KIcon::Desktop );
+ page = wdg->addVBoxPage( i18n( "Password" ), i18n( "Change the password" ), icon );
+ new PasswordPage( page );
+
+ setCentralWidget( wdg );
+
+ resize( 540, 450 );
+}
diff --git a/kresources/scalix/scalixadmin/mainwindow.h b/kresources/scalix/scalixadmin/mainwindow.h
new file mode 100644
index 000000000..38c955980
--- /dev/null
+++ b/kresources/scalix/scalixadmin/mainwindow.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <kmainwindow.h>
+
+class MainWindow : public KMainWindow
+{
+ public:
+ MainWindow();
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/otherusermanager.cpp b/kresources/scalix/scalixadmin/otherusermanager.cpp
new file mode 100644
index 000000000..b5b3d3ccf
--- /dev/null
+++ b/kresources/scalix/scalixadmin/otherusermanager.cpp
@@ -0,0 +1,51 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "otherusermanager.h"
+
+OtherUserManager::OtherUserManager()
+{
+}
+
+OtherUserManager::~OtherUserManager()
+{
+}
+
+void OtherUserManager::addOtherUser( const QString &email )
+{
+ if ( !mOtherUsers.contains( email ) ) {
+ mOtherUsers.append( email );
+ emit changed();
+ }
+}
+
+void OtherUserManager::clear()
+{
+ mOtherUsers.clear();
+
+ emit changed();
+}
+
+QStringList OtherUserManager::otherUsers() const
+{
+ return mOtherUsers;
+}
+
+#include "otherusermanager.moc"
diff --git a/kresources/scalix/scalixadmin/otherusermanager.h b/kresources/scalix/scalixadmin/otherusermanager.h
new file mode 100644
index 000000000..6f7f9ac77
--- /dev/null
+++ b/kresources/scalix/scalixadmin/otherusermanager.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef OTHERUSERMANAGER_H
+#define OTHERUSERMANAGER_H
+
+#include <qobject.h>
+#include <qstringlist.h>
+
+class OtherUserManager : public QObject
+{
+ Q_OBJECT
+
+ public:
+ OtherUserManager();
+ ~OtherUserManager();
+
+ void addOtherUser( const QString &email );
+ void clear();
+
+ QStringList otherUsers() const;
+
+ signals:
+ void changed();
+
+ private:
+ QStringList mOtherUsers;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/otheruserpage.cpp b/kresources/scalix/scalixadmin/otheruserpage.cpp
new file mode 100644
index 000000000..ae12290c7
--- /dev/null
+++ b/kresources/scalix/scalixadmin/otheruserpage.cpp
@@ -0,0 +1,173 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qapplication.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+
+#include <dcopref.h>
+#include <kdcopservicestarter.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include <unistd.h>
+
+#include "jobs.h"
+#include "ldapdialog.h"
+#include "otheruserview.h"
+#include "settings.h"
+
+#include "otheruserpage.h"
+
+OtherUserPage::OtherUserPage( QWidget *parent )
+ : QWidget( parent )
+{
+ QGridLayout *layout = new QGridLayout( this, 2, 2, 11, 6 );
+
+ mView = new OtherUserView( &mManager, this );
+ layout->addMultiCellWidget( mView, 0, 0, 0, 1 );
+
+ mAddButton = new QPushButton( i18n( "Add Account..." ), this );
+ layout->addWidget( mAddButton, 1, 0 );
+
+ mDeleteButton = new QPushButton( i18n( "Remove Account" ), this );
+ mDeleteButton->setEnabled( false );
+ layout->addWidget( mDeleteButton, 1, 1 );
+
+ connect( mView, SIGNAL( selectionChanged() ), SLOT( selectionChanged() ) );
+ connect( mAddButton, SIGNAL( clicked() ), SLOT( addUser() ) );
+ connect( mDeleteButton, SIGNAL( clicked() ), SLOT( removeUser() ) );
+
+ loadAllUsers();
+}
+
+OtherUserPage::~OtherUserPage()
+{
+}
+
+void OtherUserPage::loadAllUsers()
+{
+ Scalix::GetOtherUsersJob *job = Scalix::getOtherUsers( Settings::self()->globalSlave(),
+ Settings::self()->accountUrl() );
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( allUsers( KIO::Job* ) ) );
+}
+
+void OtherUserPage::addUser()
+{
+ LdapDialog dlg( this );
+ if ( !dlg.exec() )
+ return;
+
+ const QString email = dlg.selectedUser();
+ if ( email.isEmpty() )
+ return;
+
+ Scalix::AddOtherUserJob *job = Scalix::addOtherUser( Settings::self()->globalSlave(),
+ Settings::self()->accountUrl(), email );
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( userAdded( KIO::Job* ) ) );
+}
+
+void OtherUserPage::removeUser()
+{
+ const QString email = mView->selectedUser();
+ if ( email.isEmpty() )
+ return;
+
+ Scalix::DeleteOtherUserJob *job = Scalix::deleteOtherUser( Settings::self()->globalSlave(),
+ Settings::self()->accountUrl(), email );
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( userRemoved( KIO::Job* ) ) );
+}
+
+void OtherUserPage::allUsers( KIO::Job *job )
+{
+ if ( job->error() )
+ KMessageBox::error( this, job->errorString() );
+
+ Scalix::GetOtherUsersJob *userJob = static_cast<Scalix::GetOtherUsersJob*>( job );
+
+ mManager.clear();
+
+ const QStringList users = userJob->otherUsers();
+ for ( uint i = 0; i < users.count(); ++i )
+ mManager.addOtherUser( users[ i ] );
+
+ selectionChanged();
+}
+
+void OtherUserPage::userAdded( KIO::Job *job )
+{
+ if ( job->error() )
+ KMessageBox::error( this, job->errorString() );
+ else
+ loadAllUsers(); // update the GUI
+
+ updateKmail();
+}
+
+void OtherUserPage::userRemoved( KIO::Job *job )
+{
+ if ( job->error() )
+ KMessageBox::error( this, job->errorString() );
+ else
+ loadAllUsers(); // update the GUI
+
+ updateKmail();
+}
+
+void OtherUserPage::selectionChanged()
+{
+ mDeleteButton->setEnabled( mView->selectedItem() != 0 );
+}
+
+void OtherUserPage::updateKmail()
+{
+ QMessageBox *msg = new QMessageBox( qApp->mainWidget() );
+ msg->setText( i18n( "Updating account..." ) );
+ msg->show();
+ qApp->processEvents();
+ sleep( 1 );
+ qApp->processEvents();
+
+ QString error;
+ QCString dcopService;
+ int result = KDCOPServiceStarter::self()->
+ findServiceFor( "DCOP/ResourceBackend/IMAP", QString::null,
+ QString::null, &error, &dcopService );
+ if ( result != 0 ) {
+ KMessageBox::error( 0, i18n( "Unable to start KMail to trigger account update with Scalix server" ) );
+ delete msg;
+ return;
+ }
+
+ DCOPRef ref( dcopService, "KMailIface" );
+
+ // loop until dcop iface is set up correctly
+ QStringList list;
+ while ( list.isEmpty() ) {
+ ref.call( "accounts()" ).get( list );
+ }
+
+ ref.call( "checkAccount(QString)", i18n( "Scalix Server" ) );
+
+ delete msg;
+}
+
+#include "otheruserpage.moc"
diff --git a/kresources/scalix/scalixadmin/otheruserpage.h b/kresources/scalix/scalixadmin/otheruserpage.h
new file mode 100644
index 000000000..f847a05d3
--- /dev/null
+++ b/kresources/scalix/scalixadmin/otheruserpage.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef OTHERUSERPAGE_H
+#define OTHERUSERPAGE_H
+
+#include <qwidget.h>
+
+#include "otherusermanager.h"
+
+class QPushButton;
+class OtherUserView;
+
+class OtherUserPage : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ OtherUserPage( QWidget *parent = 0 );
+ ~OtherUserPage();
+
+ private slots:
+ void loadAllUsers();
+ void addUser();
+ void removeUser();
+
+ void userAdded( KIO::Job* );
+ void userRemoved( KIO::Job* );
+ void allUsers( KIO::Job* );
+
+ void selectionChanged();
+
+ private:
+ void updateKmail();
+
+ QPushButton *mAddButton;
+ QPushButton *mDeleteButton;
+
+ OtherUserManager mManager;
+ OtherUserView *mView;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/otheruserview.cpp b/kresources/scalix/scalixadmin/otheruserview.cpp
new file mode 100644
index 000000000..70bc9e3d5
--- /dev/null
+++ b/kresources/scalix/scalixadmin/otheruserview.cpp
@@ -0,0 +1,71 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <klocale.h>
+
+#include "otherusermanager.h"
+
+#include "otheruserview.h"
+
+class OtherUserItem : public QListViewItem
+{
+ public:
+ OtherUserItem( QListView *parent, const QString &user )
+ : QListViewItem( parent ), mUser( user )
+ {
+ setText( 0, mUser );
+ }
+
+ QString user() const { return mUser; }
+
+ private:
+ QString mUser;
+};
+
+OtherUserView::OtherUserView( OtherUserManager *manager, QWidget *parent )
+ : KListView( parent ), mManager( manager )
+{
+ addColumn( i18n( "Registered Accounts" ) );
+ setFullWidth( true );
+
+ connect( mManager, SIGNAL( changed() ), SLOT( userChanged() ) );
+
+ userChanged();
+}
+
+QString OtherUserView::selectedUser() const
+{
+ OtherUserItem *item = dynamic_cast<OtherUserItem*>( selectedItem() );
+ if ( item )
+ return item->user();
+
+ return QString();
+}
+
+void OtherUserView::userChanged()
+{
+ clear();
+
+ QStringList users = mManager->otherUsers();
+ for ( uint i = 0; i < users.count(); ++i )
+ new OtherUserItem( this, users[ i ] );
+}
+
+#include "otheruserview.moc"
diff --git a/kresources/scalix/scalixadmin/otheruserview.h b/kresources/scalix/scalixadmin/otheruserview.h
new file mode 100644
index 000000000..6eacc93c9
--- /dev/null
+++ b/kresources/scalix/scalixadmin/otheruserview.h
@@ -0,0 +1,44 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef OTHERUSERVIEW_H
+#define OTHERUSERVIEW_H
+
+#include <klistview.h>
+
+class OtherUserManager;
+
+class OtherUserView : public KListView
+{
+ Q_OBJECT
+
+ public:
+ OtherUserView( OtherUserManager *manager, QWidget *parent = 0 );
+
+ QString selectedUser() const;
+
+ private slots:
+ void userChanged();
+
+ private:
+ OtherUserManager *mManager;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/outofofficepage.cpp b/kresources/scalix/scalixadmin/outofofficepage.cpp
new file mode 100644
index 000000000..0b8d3f803
--- /dev/null
+++ b/kresources/scalix/scalixadmin/outofofficepage.cpp
@@ -0,0 +1,125 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qbuttongroup.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qtextedit.h>
+
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include "jobs.h"
+#include "settings.h"
+
+#include "outofofficepage.h"
+
+OutOfOfficePage::OutOfOfficePage( QWidget *parent )
+ : QWidget( parent )
+{
+ QGridLayout *layout = new QGridLayout( this, 4, 2, 11, 6 );
+
+ QButtonGroup *group = new QButtonGroup( 1, Qt::Vertical, this );
+
+ mDisabled = new QRadioButton( i18n( "I am in the office" ), group );
+ mDisabled->setChecked( true );
+ mEnabled = new QRadioButton( i18n( "I am out of the office" ), group );
+
+ mLabel = new QLabel( i18n( "Auto-reply once to each sender with the following text:" ), this );
+ mMessage = new QTextEdit( this );
+ mSaveButton = new QPushButton( i18n( "Save" ), this );
+
+ layout->addMultiCellWidget( group, 0, 0, 0, 1 );
+ layout->addMultiCellWidget( mLabel, 1, 1, 0, 1 );
+ layout->addMultiCellWidget( mMessage, 2, 2, 0, 1 );
+ layout->addWidget( mSaveButton, 3, 1 );
+
+ statusChanged();
+
+ connect( mEnabled, SIGNAL( toggled( bool ) ), this, SLOT( statusChanged() ) );
+ connect( mEnabled, SIGNAL( toggled( bool ) ), this, SLOT( changed() ) );
+ connect( mSaveButton, SIGNAL( clicked() ), this, SLOT( store() ) );
+ connect( mMessage, SIGNAL( textChanged() ), this, SLOT( changed() ) );
+
+ load();
+}
+
+OutOfOfficePage::~OutOfOfficePage()
+{
+}
+
+void OutOfOfficePage::load()
+{
+ Scalix::GetOutOfOfficeJob *job = Scalix::getOutOfOffice( Settings::self()->globalSlave(),
+ Settings::self()->accountUrl() );
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( loaded( KIO::Job* ) ) );
+}
+
+void OutOfOfficePage::loaded( KIO::Job* job )
+{
+ if ( job->error() ) {
+ KMessageBox::error( this, job->errorString() );
+ return;
+ }
+
+ Scalix::GetOutOfOfficeJob *outOfOfficeJob = static_cast<Scalix::GetOutOfOfficeJob*>( job );
+
+ mEnabled->setChecked( outOfOfficeJob->enabled() );
+ mMessage->setText( outOfOfficeJob->message() );
+
+ statusChanged();
+
+ mSaveButton->setEnabled( false );
+}
+
+void OutOfOfficePage::store()
+{
+ Scalix::SetOutOfOfficeJob *job = Scalix::setOutOfOffice( Settings::self()->globalSlave(),
+ Settings::self()->accountUrl(),
+ mEnabled->isChecked(),
+ mMessage->text() );
+
+ connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( stored( KIO::Job* ) ) );
+
+ mSaveButton->setEnabled( false );
+}
+
+void OutOfOfficePage::stored( KIO::Job* job )
+{
+ if ( job->error() )
+ KMessageBox::error( this, job->errorString() );
+}
+
+void OutOfOfficePage::statusChanged()
+{
+ bool state = mEnabled->isChecked();
+
+ mLabel->setEnabled( state );
+ mMessage->setEnabled( state );
+}
+
+void OutOfOfficePage::changed()
+{
+ mSaveButton->setEnabled( true );
+}
+
+#include "outofofficepage.moc"
diff --git a/kresources/scalix/scalixadmin/outofofficepage.h b/kresources/scalix/scalixadmin/outofofficepage.h
new file mode 100644
index 000000000..cc5b2591a
--- /dev/null
+++ b/kresources/scalix/scalixadmin/outofofficepage.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef OUTOFOFFICEPAGE_H
+#define OUTOFOFFICEPAGE_H
+
+#include <qwidget.h>
+
+class QLabel;
+class QPushButton;
+class QRadioButton;
+class QTextEdit;
+
+class OutOfOfficePage : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ OutOfOfficePage( QWidget *parent = 0 );
+ ~OutOfOfficePage();
+
+ private slots:
+ void load();
+ void loaded( KIO::Job* );
+ void store();
+ void stored( KIO::Job* );
+ void statusChanged();
+ void changed();
+
+ private:
+ QRadioButton *mEnabled;
+ QRadioButton *mDisabled;
+ QLabel *mLabel;
+ QTextEdit *mMessage;
+ QPushButton *mSaveButton;
+
+ bool mChanged;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/passwordpage.cpp b/kresources/scalix/scalixadmin/passwordpage.cpp
new file mode 100644
index 000000000..7d4182348
--- /dev/null
+++ b/kresources/scalix/scalixadmin/passwordpage.cpp
@@ -0,0 +1,190 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kstringhandler.h>
+#include <kwallet.h>
+
+#include "jobs.h"
+#include "settings.h"
+
+#include "passwordpage.h"
+
+PasswordPage::PasswordPage( QWidget *parent )
+ : QWidget( parent ), mJob( 0 )
+{
+ QGridLayout *layout = new QGridLayout( this, 2, 3, 11, 6 );
+
+ QLabel *label = new QLabel( i18n( "New password:" ), this );
+ layout->addWidget( label, 0, 0 );
+
+ mPassword = new QLineEdit( this );
+ mPassword->setEchoMode( QLineEdit::Password );
+ label->setBuddy( mPassword );
+ layout->addWidget( mPassword, 0, 1 );
+
+ label = new QLabel( i18n( "Retype new password:" ), this );
+ layout->addWidget( label, 1, 0 );
+
+ mPasswordRetype = new QLineEdit( this );
+ mPasswordRetype->setEchoMode( QLineEdit::Password );
+ label->setBuddy( mPasswordRetype );
+ layout->addWidget( mPasswordRetype, 1, 1 );
+
+ mButton = new QPushButton( i18n( "Change" ), this );
+ mButton->setEnabled( false );
+ layout->addWidget( mButton, 2, 1 );
+
+ layout->setRowSpacing( 3, 1 );
+
+ connect( mPassword, SIGNAL( textChanged( const QString& ) ), this, SLOT( textChanged() ) );
+ connect( mPasswordRetype, SIGNAL( textChanged( const QString& ) ), this, SLOT( textChanged() ) );
+ connect( mButton, SIGNAL( clicked() ), this, SLOT( buttonClicked() ) );
+}
+
+void PasswordPage::buttonClicked()
+{
+ if ( !mJob ) {
+ if ( mPassword->text() != mPasswordRetype->text() ) {
+ KMessageBox::error( this, i18n( "The two passwords differ!" ) );
+ return;
+ }
+
+ mJob = Scalix::setPassword( Settings::self()->globalSlave(), Settings::self()->accountUrl(),
+ Settings::self()->accountPassword(), mPassword->text() );
+ connect( mJob, SIGNAL( result( KIO::Job* ) ), this, SLOT( finished( KIO::Job* ) ) );
+
+ updateState( true );
+ } else {
+ mJob->kill();
+ mJob = 0;
+
+ updateState( false );
+ }
+}
+
+void PasswordPage::updateState( bool isWorking )
+{
+ if ( isWorking ) {
+ mPassword->setEnabled( false );
+ mPasswordRetype->setEnabled( false );
+ mButton->setText( i18n( "Stop" ) );
+ } else {
+ mPassword->setEnabled( true );
+ mPasswordRetype->setEnabled( true );
+ mButton->setText( i18n( "Change" ) );
+ }
+}
+
+void PasswordPage::textChanged()
+{
+ mButton->setEnabled( !mPassword->text().isEmpty() &&
+ !mPasswordRetype->text().isEmpty() );
+}
+
+void PasswordPage::finished( KIO::Job* job )
+{
+ mJob = 0;
+
+ updateState( false );
+
+ if ( job->error() ) {
+ KMessageBox::error( this, i18n( "Unable to change the password" ) + "\n" + job->errorString() );
+ return;
+ }
+
+ // Update configuration files to the new password as well
+
+ const QString newPassword = mPassword->text();
+
+ { // ScalixAdmin config
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "Account" );
+ group.writeEntry( "pass", KStringHandler::obscure( newPassword ) );
+ }
+
+ { // ScalixWizard config
+ KConfig config( "scalixrc" );
+ KConfigGroup group( &config, "General" );
+ group.writeEntry( "Password", KStringHandler::obscure( newPassword ) );
+ }
+
+ { // KMail config
+ KConfig config( "kmailrc" );
+
+ // Try to find account group for Scalix
+ QString scalixAccount;
+ const QStringList groupList = config.groupList();
+ for ( uint i = 0; i < groupList.count(); ++i ) {
+ if ( groupList[ i ].startsWith( "Account " ) ) {
+ KConfigGroup group( &config, groupList[ i ] );
+ if ( group.hasKey( "groupwareType" ) && group.readNumEntry( "groupwareType" ) == 2 ) {
+ scalixAccount = groupList[ i ];
+ break;
+ }
+ }
+ }
+
+ if ( scalixAccount.isEmpty() ) {
+ qWarning( "No Scalix Groupware Account found in kmailrc!" );
+ return;
+ }
+
+ const int accountId = scalixAccount.mid( 8 ).toInt();
+
+ KConfigGroup group( &config, scalixAccount );
+
+ // Save only if the user choose it before
+ bool storePassword = group.readBoolEntry( "store-passwd", false );
+ if ( storePassword ) {
+ // First try to store in KWallet
+ if ( KWallet::Wallet::isEnabled() ) {
+ WId window = 0;
+ if ( qApp->activeWindow() )
+ window = qApp->activeWindow()->winId();
+
+ KWallet::Wallet *wallet = KWallet::Wallet::openWallet( KWallet::Wallet::NetworkWallet(), window );
+ if ( wallet ) {
+ if ( !wallet->hasFolder( "kmail" ) )
+ wallet->createFolder( "kmail" );
+ wallet->setFolder( "kmail" );
+ wallet->writePassword( "account-" + QString::number( accountId ), newPassword );
+ }
+ } else {
+ group.writeEntry( "pass", KStringHandler::obscure( newPassword ) );
+ }
+
+ KConfigGroup fileGroup( &config, QString( "Folder-%1" ).arg( group.readNumEntry( "Folder" ) ) );
+ fileGroup.writeEntry( "pass", KStringHandler::obscure( newPassword ) );
+ }
+ }
+
+ KMessageBox::information( this, i18n( "Password was changed successfully" ) );
+}
+
+#include "passwordpage.moc"
diff --git a/kresources/scalix/scalixadmin/passwordpage.h b/kresources/scalix/scalixadmin/passwordpage.h
new file mode 100644
index 000000000..a397be416
--- /dev/null
+++ b/kresources/scalix/scalixadmin/passwordpage.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PASSWORDPAGE_H
+#define PASSWORDPAGE_H
+
+#include <qwidget.h>
+
+class QLineEdit;
+class QPushButton;
+
+namespace KIO {
+class Job;
+}
+
+class PasswordPage : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ PasswordPage( QWidget *parent = 0 );
+
+ private slots:
+ void buttonClicked();
+ void finished( KIO::Job* );
+ void textChanged();
+
+ private:
+ void updateState( bool );
+
+ QLineEdit *mPassword;
+ QLineEdit *mPasswordRetype;
+ QPushButton *mButton;
+
+ KIO::Job *mJob;
+};
+
+#endif
diff --git a/kresources/scalix/scalixadmin/settings.cpp b/kresources/scalix/scalixadmin/settings.cpp
new file mode 100644
index 000000000..2f6b49bad
--- /dev/null
+++ b/kresources/scalix/scalixadmin/settings.cpp
@@ -0,0 +1,136 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kconfig.h>
+#include <kio/scheduler.h>
+#include <kstringhandler.h>
+
+#include "settings.h"
+
+Settings* Settings::mSelf = 0;
+
+Settings::Settings()
+{
+ mSlave = KIO::Scheduler::getConnectedSlave( accountUrl(),
+ accountData() );
+}
+
+Settings::~Settings()
+{
+}
+
+Settings* Settings::self()
+{
+ if ( !mSelf )
+ mSelf = new Settings;
+
+ return mSelf;
+}
+
+KIO::MetaData Settings::accountData() const
+{
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "Account" );
+
+ KIO::MetaData data;
+ data.insert( "auth", group.readEntry( "auth" ) );
+ data.insert( "tls", group.readBoolEntry( "use-tls" ) ? "on" : "off" );
+
+ return data;
+}
+
+KURL Settings::accountUrl() const
+{
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "Account" );
+
+ KURL url;
+ url.setProtocol( group.readBoolEntry( "use-ssl" ) ? "imaps" : "imap" );
+ url.setUser( group.readEntry( "user" ) );
+ url.setPass( KStringHandler::obscure( group.readEntry( "pass" ) ) );
+ url.setHost( group.readEntry( "host" ) );
+ url.setPort( group.readNumEntry( "port" ) );
+
+ return url;
+}
+
+QString Settings::accountPassword() const
+{
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "Account" );
+
+ return KStringHandler::obscure( group.readEntry( "pass" ) );
+}
+
+KIO::Slave* Settings::globalSlave() const
+{
+ return mSlave;
+}
+
+QString Settings::rulesWizardUrl() const
+{
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "Misc" );
+
+ QString url = group.readEntry( "rulesWizardUrl" );
+ if ( url.isEmpty() ) {
+ KConfigGroup group( &config, "Account" );
+ url = QString( "http://%1/Scalix/rw/?username=%2" ).arg( group.readEntry( "host" ) )
+ .arg( group.readEntry( "user" ) );
+ }
+
+ return url;
+}
+
+QString Settings::ldapHost() const
+{
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "LDAP" );
+ return group.readEntry( "host" );
+}
+
+QString Settings::ldapPort() const
+{
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "LDAP" );
+ return group.readEntry( "port" );
+}
+
+QString Settings::ldapBase() const
+{
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "LDAP" );
+ return group.readEntry( "base" );
+}
+
+QString Settings::ldapBindDn() const
+{
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "LDAP" );
+ return group.readEntry( "bindDn" );
+}
+
+QString Settings::ldapPassword() const
+{
+ KConfig config( "scalixadminrc" );
+ KConfigGroup group( &config, "LDAP" );
+ return group.readEntry( "password" );
+}
+
diff --git a/kresources/scalix/scalixadmin/settings.h b/kresources/scalix/scalixadmin/settings.h
new file mode 100644
index 000000000..17ed9a2c9
--- /dev/null
+++ b/kresources/scalix/scalixadmin/settings.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of ScalixAdmin.
+ *
+ * Copyright (C) 2007 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <kurl.h>
+#include <kio/global.h>
+#include <kio/slave.h>
+
+class Settings
+{
+ public:
+ ~Settings();
+
+ static Settings* self();
+
+ KIO::MetaData accountData() const;
+ KURL accountUrl() const;
+ QString accountPassword() const;
+
+ KIO::Slave *globalSlave() const;
+
+ QString rulesWizardUrl() const;
+
+ QString ldapHost() const;
+ QString ldapPort() const;
+ QString ldapBase() const;
+ QString ldapBindDn() const;
+ QString ldapPassword() const;
+
+ private:
+ Settings();
+ KIO::Slave *mSlave;
+
+ static Settings* mSelf;
+};
+
+#endif
diff --git a/kresources/scalix/shared/Makefile.am b/kresources/scalix/shared/Makefile.am
new file mode 100644
index 000000000..4aaa9304e
--- /dev/null
+++ b/kresources/scalix/shared/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/kresources/lib $(all_includes)
+
+noinst_HEADERS = resourcescalixbase.h scalixbase.h subresource.h
+
+noinst_LTLIBRARIES = libresourcescalixshared.la
+
+libresourcescalixshared_la_SOURCES = \
+ resourcescalixbase.cpp kmailconnection.cpp scalixbase.cpp \
+ subresource.cpp \
+ kmailconnection.skel kmailicalIface.stub
+libresourcescalixshared_la_METASOURCES = AUTO
+libresourcescalixshared_la_LIBADD = $(top_builddir)/libkcal/libkcal.la $(top_builddir)/libkdepim/libkdepim.la ../../lib/libkgroupwaredav.la
+libresourcescalixshared_la_LDFLAGS = -no-undefined
+
+kmailicalIface_DCOPIDLNG = true
+
+kmailicalIface_DIR = $(top_srcdir)/kmail
diff --git a/kresources/scalix/shared/kmailconnection.cpp b/kresources/scalix/shared/kmailconnection.cpp
new file mode 100644
index 000000000..af32cd74b
--- /dev/null
+++ b/kresources/scalix/shared/kmailconnection.cpp
@@ -0,0 +1,281 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "kmailconnection.h"
+#include "resourcescalixbase.h"
+
+#include <kdebug.h>
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <kdcopservicestarter.h>
+#include <klocale.h>
+
+#include "kmailicalIface_stub.h"
+
+
+using namespace Scalix;
+
+
+KMailConnection::KMailConnection( ResourceScalixBase* resource,
+ const QCString& objId )
+ : DCOPObject( objId ), mResource( resource ), mKMailIcalIfaceStub( 0 )
+{
+ // Make the connection to KMail ready
+ mDCOPClient = new DCOPClient();
+ mDCOPClient->attach();
+ mDCOPClient->registerAs( objId, true );
+
+ kapp->dcopClient()->setNotifications( true );
+ connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString& ) ),
+ this, SLOT( unregisteredFromDCOP( const QCString& ) ) );
+}
+
+KMailConnection::~KMailConnection()
+{
+ kapp->dcopClient()->setNotifications( false );
+ delete mKMailIcalIfaceStub;
+ mKMailIcalIfaceStub = 0;
+ delete mDCOPClient;
+ mDCOPClient = 0;
+}
+
+static const QCString dcopObjectId = "KMailICalIface";
+bool KMailConnection::connectToKMail()
+{
+ if ( !mKMailIcalIfaceStub ) {
+ QString error;
+ QCString dcopService;
+ int result = KDCOPServiceStarter::self()->
+ findServiceFor( "DCOP/ResourceBackend/IMAP", QString::null,
+ QString::null, &error, &dcopService );
+ if ( result != 0 ) {
+ kdError(5650) << "Couldn't connect to the IMAP resource backend\n";
+ // TODO: You might want to show "error" (if not empty) here,
+ // using e.g. KMessageBox
+ return false;
+ }
+
+ mKMailIcalIfaceStub = new KMailICalIface_stub( kapp->dcopClient(),
+ dcopService, dcopObjectId );
+
+ // Attach to the KMail signals
+ if ( !connectKMailSignal( "incidenceAdded(QString,QString,Q_UINT32,int,QString)",
+ "fromKMailAddIncidence(QString,QString,Q_UINT32,int,QString)" ) )
+ kdError(5650) << "DCOP connection to incidenceAdded failed" << endl;
+ if ( !connectKMailSignal( "incidenceDeleted(QString,QString,QString)",
+ "fromKMailDelIncidence(QString,QString,QString)" ) )
+ kdError(5650) << "DCOP connection to incidenceDeleted failed" << endl;
+ if ( !connectKMailSignal( "signalRefresh(QString,QString)",
+ "fromKMailRefresh(QString,QString)" ) )
+ kdError(5650) << "DCOP connection to signalRefresh failed" << endl;
+ if ( !connectKMailSignal( "subresourceAdded( QString, QString, QString )",
+ "fromKMailAddSubresource( QString, QString, QString )" ) )
+ kdError(5650) << "DCOP connection to subresourceAdded failed" << endl;
+ if ( !connectKMailSignal( "subresourceDeleted(QString,QString)",
+ "fromKMailDelSubresource(QString,QString)" ) )
+ kdError(5650) << "DCOP connection to subresourceDeleted failed" << endl;
+ if ( !connectKMailSignal( "asyncLoadResult(QMap<Q_UINT32, QString>, QString, QString)",
+ "fromKMailAsyncLoadResult(QMap<Q_UINT32, QString>, QString, QString)" ) )
+ kdError(5650) << "DCOP connection to asyncLoadResult failed" << endl;
+ }
+
+ return ( mKMailIcalIfaceStub != 0 );
+}
+
+bool KMailConnection::fromKMailAddIncidence( const QString& type,
+ const QString& folder,
+ Q_UINT32 sernum,
+ int format,
+ const QString& data )
+{
+ if ( format != KMailICalIface::StorageXML
+ && format != KMailICalIface::StorageIcalVcard )
+ return false;
+// kdDebug(5650) << "KMailConnection::fromKMailAddIncidence( " << type << ", "
+// << folder << " ). iCal:\n" << ical << endl;
+ return mResource->fromKMailAddIncidence( type, folder, sernum, format, data );
+}
+
+void KMailConnection::fromKMailDelIncidence( const QString& type,
+ const QString& folder,
+ const QString& xml )
+{
+// kdDebug(5650) << "KMailConnection::fromKMailDelIncidence( " << type << ", "
+// << folder << ", " << uid << " )\n";
+ mResource->fromKMailDelIncidence( type, folder, xml );
+}
+
+void KMailConnection::fromKMailRefresh( const QString& type, const QString& folder )
+{
+// kdDebug(5650) << "KMailConnection::fromKMailRefresh( " << type << ", "
+// << folder << " )\n";
+ mResource->fromKMailRefresh( type, folder );
+}
+
+void KMailConnection::fromKMailAddSubresource( const QString& type,
+ const QString& resource,
+ const QString& label )
+{
+// kdDebug(5650) << "KMailConnection::fromKMailAddSubresource( " << type << ", "
+// << resource << " )\n";
+ bool writable = true;
+
+ // TODO: This should be told by KMail right away
+ if ( connectToKMail() )
+ writable = mKMailIcalIfaceStub->isWritableFolder( type, resource );
+
+ mResource->fromKMailAddSubresource( type, resource, label, writable );
+}
+
+void KMailConnection::fromKMailDelSubresource( const QString& type,
+ const QString& resource )
+{
+// kdDebug(5650) << "KMailConnection::fromKMailDelSubresource( " << type << ", "
+// << resource << " )\n";
+ mResource->fromKMailDelSubresource( type, resource );
+}
+
+void KMailConnection::fromKMailAsyncLoadResult( const QMap<Q_UINT32, QString>& map,
+ const QString& type,
+ const QString& folder )
+{
+ mResource->fromKMailAsyncLoadResult( map, type, folder );
+}
+
+bool KMailConnection::connectKMailSignal( const QCString& signal,
+ const QCString& method )
+{
+ return connectDCOPSignal( "kmail", dcopObjectId, signal, method, false )
+ && connectDCOPSignal( "kontact", dcopObjectId, signal, method, false );
+}
+
+bool KMailConnection::kmailSubresources( QValueList<KMailICalIface::SubResource>& lst,
+ const QString& contentsType )
+{
+ if ( !connectToKMail() )
+ return false;
+
+ lst = mKMailIcalIfaceStub->subresourcesKolab( contentsType );
+ return mKMailIcalIfaceStub->ok();
+}
+
+bool KMailConnection::kmailIncidencesCount( int& count,
+ const QString& mimetype,
+ const QString& resource )
+{
+ if ( !connectToKMail() )
+ return false;
+
+ count = mKMailIcalIfaceStub->incidencesKolabCount( mimetype, resource );
+ return mKMailIcalIfaceStub->ok();
+}
+
+bool KMailConnection::kmailIncidences( QMap<Q_UINT32, QString>& lst,
+ const QString& mimetype,
+ const QString& resource,
+ int startIndex,
+ int nbMessages )
+{
+ if ( !connectToKMail() )
+ return false;
+
+ lst = mKMailIcalIfaceStub->incidencesKolab( mimetype, resource, startIndex, nbMessages );
+ return mKMailIcalIfaceStub->ok();
+}
+
+
+bool KMailConnection::kmailGetAttachment( KURL& url,
+ const QString& resource,
+ Q_UINT32 sernum,
+ const QString& filename )
+{
+ if ( !connectToKMail() )
+ return false;
+
+ url = mKMailIcalIfaceStub->getAttachment( resource, sernum, filename );
+ return mKMailIcalIfaceStub->ok();
+}
+
+bool KMailConnection::kmailDeleteIncidence( const QString& resource,
+ Q_UINT32 sernum )
+{
+ return connectToKMail()
+ && mKMailIcalIfaceStub->deleteIncidenceKolab( resource, sernum )
+ && mKMailIcalIfaceStub->ok();
+}
+
+bool KMailConnection::kmailUpdate( const QString& resource,
+ Q_UINT32& sernum,
+ const QString& subject,
+ const QString& plainTextBody,
+ const QMap<QCString, QString>& customHeaders,
+ const QStringList& attachmentURLs,
+ const QStringList& attachmentMimetypes,
+ const QStringList& attachmentNames,
+ const QStringList& deletedAttachments )
+{
+ //kdDebug(5006) << kdBacktrace() << endl;
+ if ( connectToKMail() ) {
+ sernum = mKMailIcalIfaceStub->update( resource, sernum, subject, plainTextBody, customHeaders,
+ attachmentURLs, attachmentMimetypes, attachmentNames,
+ deletedAttachments );
+ return sernum && mKMailIcalIfaceStub->ok();
+ } else
+ return false;
+}
+
+bool KMailConnection::kmailStorageFormat( KMailICalIface::StorageFormat& type,
+ const QString& folder )
+{
+ bool ok = connectToKMail();
+ type = mKMailIcalIfaceStub->storageFormat( folder );
+ return ok && mKMailIcalIfaceStub->ok();
+}
+
+
+bool KMailConnection::kmailTriggerSync( const QString &contentsType )
+{
+ bool ok = connectToKMail();
+ return ok && mKMailIcalIfaceStub->triggerSync( contentsType );
+}
+
+void KMailConnection::unregisteredFromDCOP( const QCString& appId )
+{
+ if ( mKMailIcalIfaceStub && mKMailIcalIfaceStub->app() == appId ) {
+ // Delete the stub so that the next time we need to talk to kmail,
+ // we'll know that we need to start a new one.
+ delete mKMailIcalIfaceStub;
+ mKMailIcalIfaceStub = 0;
+ }
+}
+
+#include "kmailconnection.moc"
diff --git a/kresources/scalix/shared/kmailconnection.h b/kresources/scalix/shared/kmailconnection.h
new file mode 100644
index 000000000..ea57857a8
--- /dev/null
+++ b/kresources/scalix/shared/kmailconnection.h
@@ -0,0 +1,117 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef KMAILCONNECTION_H
+#define KMAILCONNECTION_H
+
+#include <dcopobject.h>
+#include <kmail/kmailicalIface.h>
+
+class KURL;
+class DCOPClient;
+class KMailICalIface_stub;
+
+namespace Scalix {
+
+class ResourceScalixBase;
+
+/**
+ This class provides the kmail connectivity for IMAP resources.
+*/
+class KMailConnection : public QObject, public DCOPObject {
+ Q_OBJECT
+ K_DCOP
+
+ // These are the methods called by KMail when the resource changes
+k_dcop:
+ bool fromKMailAddIncidence( const QString& type, const QString& resource,
+ Q_UINT32 sernum, int format, const QString& xml );
+ void fromKMailDelIncidence( const QString& type, const QString& resource,
+ const QString& xml );
+ void fromKMailRefresh( const QString& type, const QString& resource );
+ void fromKMailAddSubresource( const QString& type, const QString& resource, const QString& label );
+ void fromKMailDelSubresource( const QString& type, const QString& resource );
+ void fromKMailAsyncLoadResult( const QMap<Q_UINT32, QString>& map, const QString& type,
+ const QString& folder );
+
+public:
+ KMailConnection( ResourceScalixBase* resource, const QCString& objId );
+ virtual ~KMailConnection();
+
+ /**
+ * Do the connection to KMail.
+ */
+ bool connectToKMail();
+
+ // Call the DCOP methods
+ bool kmailSubresources( QValueList<KMailICalIface::SubResource>& lst,
+ const QString& contentsType );
+ bool kmailIncidencesCount( int& count,
+ const QString& mimetype,
+ const QString& resource );
+ bool kmailIncidences( QMap<Q_UINT32, QString>& lst, const QString& mimetype,
+ const QString& resource,
+ int startIndex,
+ int nbMessages );
+
+ bool kmailGetAttachment( KURL& url, const QString& resource, Q_UINT32 sernum,
+ const QString& filename );
+ bool kmailDeleteIncidence( const QString& resource, Q_UINT32 sernum );
+ bool kmailUpdate( const QString& resource,
+ Q_UINT32& sernum,
+ const QString& subject,
+ const QString& plainTextBody,
+ const QMap<QCString, QString>& customHeaders,
+ const QStringList& attachmentURLs,
+ const QStringList& attachmentMimetypes,
+ const QStringList& attachmentNames,
+ const QStringList& deletedAttachments );
+
+ bool kmailStorageFormat( KMailICalIface::StorageFormat& type, const QString& folder);
+
+ bool kmailTriggerSync( const QString& contentsType );
+
+private slots:
+ virtual void unregisteredFromDCOP( const QCString& );
+
+private:
+ /** Connect a signal from KMail to a local slot. */
+ bool connectKMailSignal( const QCString&, const QCString& );
+
+ ResourceScalixBase* mResource;
+ DCOPClient* mDCOPClient;
+ KMailICalIface_stub* mKMailIcalIfaceStub;
+};
+
+}
+
+#endif // KMAILCONNECTION_H
diff --git a/kresources/scalix/shared/resourcescalixbase.cpp b/kresources/scalix/shared/resourcescalixbase.cpp
new file mode 100644
index 000000000..e91e58787
--- /dev/null
+++ b/kresources/scalix/shared/resourcescalixbase.cpp
@@ -0,0 +1,179 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "resourcescalixbase.h"
+#include "kmailconnection.h"
+
+#include <folderselectdialog.h>
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kinputdialog.h>
+#include <kurl.h>
+#include <ktempfile.h>
+#include <kmessagebox.h>
+#include <qtextstream.h>
+#include <kdebug.h>
+
+using namespace Scalix;
+
+static unsigned int uniquifier = 0;
+
+ResourceScalixBase::ResourceScalixBase( const QCString& objId )
+ : mSilent( false )
+{
+ KGlobal::locale()->insertCatalogue( "kres_scalix" );
+ KGlobal::locale()->insertCatalogue( "libkcal" );
+ QString uniqueObjId = QString( objId ) + QString::number( uniquifier++ );
+ mConnection = new KMailConnection( this, uniqueObjId.utf8() );
+}
+
+ResourceScalixBase::~ResourceScalixBase()
+{
+ delete mConnection;
+}
+
+
+bool ResourceScalixBase::kmailSubresources( QValueList<KMailICalIface::SubResource>& lst,
+ const QString& contentsType ) const
+{
+ return mConnection->kmailSubresources( lst, contentsType );
+}
+
+bool ResourceScalixBase::kmailTriggerSync( const QString& contentsType ) const
+{
+ return mConnection->kmailTriggerSync( contentsType );
+}
+
+
+bool ResourceScalixBase::kmailIncidencesCount( int &count,
+ const QString& mimetype,
+ const QString& resource ) const
+{
+ return mConnection->kmailIncidencesCount( count, mimetype, resource );
+}
+
+bool ResourceScalixBase::kmailIncidences( QMap<Q_UINT32, QString>& lst,
+ const QString& mimetype,
+ const QString& resource,
+ int startIndex,
+ int nbMessages ) const
+{
+ return mConnection->kmailIncidences( lst, mimetype, resource, startIndex, nbMessages );
+}
+
+bool ResourceScalixBase::kmailGetAttachment( KURL& url, const QString& resource,
+ Q_UINT32 sernum,
+ const QString& filename ) const
+{
+ return mConnection->kmailGetAttachment( url, resource, sernum, filename );
+}
+
+bool ResourceScalixBase::kmailDeleteIncidence( const QString& resource,
+ Q_UINT32 sernum )
+{
+ return mSilent || mConnection->kmailDeleteIncidence( resource, sernum );
+}
+
+bool ResourceScalixBase::kmailUpdate( const QString& resource,
+ Q_UINT32& sernum,
+ const QString& xml,
+ const QString& mimetype,
+ const QString& subject,
+ const CustomHeaderMap& _customHeaders,
+ const QStringList& _attachmentURLs,
+ const QStringList& _attachmentMimetypes,
+ const QStringList& _attachmentNames,
+ const QStringList& deletedAttachments )
+{
+ if ( mSilent )
+ return true;
+
+ QString subj = subject;
+ if ( subj.isEmpty() )
+ subj = i18n("Internal kolab data: Do not delete this mail.");
+
+ // ical style, simply put the data inline
+ return mConnection->kmailUpdate( resource, sernum, subj, xml, _customHeaders,
+ _attachmentURLs, _attachmentMimetypes, _attachmentNames, deletedAttachments );
+}
+
+QString ResourceScalixBase::configFile( const QString& type ) const
+{
+ return locateLocal( "config",
+ QString( "kresources/scalix/%1rc" ).arg( type ) );
+}
+
+bool ResourceScalixBase::connectToKMail() const
+{
+ return mConnection->connectToKMail();
+}
+
+QString ResourceScalixBase::findWritableResource( const ResourceMap& resources )
+{
+ // I have to use the label (shown in the dialog) as key here. But given how the
+ // label is made up, it should be unique. If it's not, well the dialog would suck anyway...
+ QMap<QString, QString> possible;
+ QStringList labels;
+ ResourceMap::ConstIterator it;
+ for ( it = resources.begin(); it != resources.end(); ++it ) {
+ if ( it.data().writable() && it.data().active() ) {
+ // Writable and active possibility
+ possible[ it.data().label() ] = it.key();
+ }
+ }
+
+ if ( possible.isEmpty() ) { // None found!!
+ kdWarning(5650) << "No writable resource found!" << endl;
+ KMessageBox::error( 0, i18n( "No writable resource was found, saving will not be possible. Reconfigure KMail first." ) );
+ return QString::null;
+ }
+ if ( possible.count() == 1 )
+ // Just one found
+ return possible.begin().data(); // yes this is the subresource key, i.e. location
+
+ // Several found, ask the user
+ QString chosenLabel = KPIM::FolderSelectDialog::getItem( i18n( "Select Resource Folder" ),
+ i18n( "You have more than one writable resource folder. "
+ "Please select the one you want to write to." ),
+ possible.keys() );
+ if ( chosenLabel.isEmpty() ) // cancelled
+ return QString::null;
+ return possible[chosenLabel];
+}
+
+KMailICalIface::StorageFormat ResourceScalixBase::kmailStorageFormat( const QString &folder ) const
+{
+ KMailICalIface::StorageFormat format = (KMailICalIface::StorageFormat) 3;
+ mConnection->kmailStorageFormat( format, folder );
+ return format;
+}
diff --git a/kresources/scalix/shared/resourcescalixbase.h b/kresources/scalix/shared/resourcescalixbase.h
new file mode 100644
index 000000000..3c32c1dfd
--- /dev/null
+++ b/kresources/scalix/shared/resourcescalixbase.h
@@ -0,0 +1,180 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef RESOURCESCALIXBASE_H
+#define RESOURCESCALIXBASE_H
+
+#include <qstring.h>
+#include <qmap.h>
+#include <qstringlist.h>
+
+#include "subresource.h"
+#include <kmail/kmailicalIface.h>
+
+class QCString;
+class KURL;
+
+namespace Scalix {
+
+class KMailConnection;
+
+/**
+ This class provides the kmail connectivity for IMAP resources.
+
+ The main methods are:
+
+ fromKMail...() : calls made _by_ KMail to add/delete data representation in the resource.
+
+ kmail...() : calls _into_ KMail made by the resource.
+
+ e.g. fromKMailAddIncidence() is called by KMail
+ when a new iCard is there after an IMAP sync.
+
+ By calling fromKMailAddIncidence() KMail notifies
+ the resource about the new incidence, so in the
+ addressbook a new address will appear like magic.
+
+ e.g. kmailAddIncidence() is called by the resource when
+ iCard must be stored by KMail because the user has added
+ an address in the addressbook.
+
+ By calling kmailAddIncidence() the resource causes
+ KMail to store the new address in the (IMAP) folder.
+*/
+class ResourceScalixBase {
+public:
+ ResourceScalixBase( const QCString& objId );
+ virtual ~ResourceScalixBase();
+
+ // These are the methods called by KMail when the resource changes
+ virtual bool fromKMailAddIncidence( const QString& type,
+ const QString& resource,
+ Q_UINT32 sernum,
+ int format,
+ const QString& data ) = 0;
+ virtual void fromKMailDelIncidence( const QString& type,
+ const QString& resource,
+ const QString& xml ) = 0;
+ virtual void fromKMailRefresh( const QString& type,
+ const QString& resource ) = 0;
+ virtual void fromKMailAddSubresource( const QString& type,
+ const QString& resource,
+ const QString& label,
+ bool writable ) = 0;
+ virtual void fromKMailDelSubresource( const QString& type,
+ const QString& resource ) = 0;
+
+ virtual void fromKMailAsyncLoadResult( const QMap<Q_UINT32, QString>& map,
+ const QString& type,
+ const QString& folder ) = 0;
+protected:
+ /// Do the connection to KMail.
+ bool connectToKMail() const;
+
+ // These are the KMail dcop function connections. The docs here say
+ // "Get", which here means that the first argument is the return arg
+
+ /// List all folders with a certain contentsType. Returns a QMap with
+ /// resourcename/writable pairs
+ bool kmailSubresources( QValueList<KMailICalIface::SubResource>& lst,
+ const QString& contentsType ) const;
+
+ /// Get the number of messages in this folder.
+ /// Used to iterate over kmailIncidences by chunks
+ bool kmailIncidencesCount( int& count, const QString& mimetype,
+ const QString& resource ) const;
+
+ /// Get the mimetype attachments from a chunk of messages from this folder.
+ /// Returns a QMap with serialNumber/attachment pairs.
+ bool kmailIncidences( QMap<Q_UINT32, QString>& lst, const QString& mimetype,
+ const QString& resource,
+ int startIndex,
+ int nbMessages ) const;
+
+ bool kmailTriggerSync( const QString& contentType ) const;
+
+public: // for Contact
+ /// Get an attachment from a mail. Returns a URL to it. This can
+ /// be called by the resource after obtaining the incidence.
+ /// The resource must delete the temp file.
+ bool kmailGetAttachment( KURL& url, const QString& resource,
+ Q_UINT32 sernum,
+ const QString& filename ) const;
+
+protected:
+ /// Delete an incidence.
+ bool kmailDeleteIncidence( const QString& resource, Q_UINT32 sernum );
+
+ KMailICalIface::StorageFormat kmailStorageFormat( const QString& folder ) const;
+
+ typedef QMap<QCString, QString> CustomHeaderMap;
+
+ /// Update an incidence. The list of attachments are URLs.
+ /// The parameter sernum is updated with the right KMail serial number
+ bool kmailUpdate( const QString& resource, Q_UINT32& sernum,
+ const QString& xml,
+ const QString& mimetype,
+ const QString& subject,
+ const CustomHeaderMap& customHeaders = CustomHeaderMap(),
+ const QStringList& attachmentURLs = QStringList(),
+ const QStringList& attachmentMimetypes = QStringList(),
+ const QStringList& attachmentNames = QStringList(),
+ const QStringList& deletedAttachments = QStringList() );
+
+ /// Get the full path of the config file.
+ QString configFile( const QString& type ) const;
+
+ /// If only one of these is writable, return that. Otherwise return null.
+ QString findWritableResource( const ResourceMap& resources );
+
+ bool mSilent;
+
+ /**
+ * This is used to store a mapping from the XML UID to the KMail
+ * serial number of the mail it's stored in. That provides a quick way
+ * to access the storage in KMail.
+ */
+ UidMap mUidMap;
+
+ /// This is used to distinguish operations triggered by the user,
+ /// from operations triggered by KMail
+ QStringList mUidsPendingAdding;
+ QStringList mUidsPendingDeletion;
+ QStringList mUidsPendingUpdate;
+
+private:
+ mutable KMailConnection* mConnection;
+};
+
+}
+
+#endif // RESOURCEKOLABBASE_H
diff --git a/kresources/scalix/shared/scalixbase.cpp b/kresources/scalix/shared/scalixbase.cpp
new file mode 100644
index 000000000..ab38500e2
--- /dev/null
+++ b/kresources/scalix/shared/scalixbase.cpp
@@ -0,0 +1,446 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "scalixbase.h"
+
+#include <kabc/addressee.h>
+#include <libkcal/journal.h>
+#include <libkdepim/kpimprefs.h>
+#include <kdebug.h>
+#include <qfile.h>
+
+using namespace Scalix;
+
+
+ScalixBase::ScalixBase( const QString& tz )
+ : mCreationDate( QDateTime::currentDateTime() ),
+ mLastModified( QDateTime::currentDateTime() ),
+ mSensitivity( Public ), mTimeZoneId( tz ),
+ mHasPilotSyncId( false ), mHasPilotSyncStatus( false )
+{
+}
+
+ScalixBase::~ScalixBase()
+{
+}
+
+void ScalixBase::setFields( const KCal::Incidence* incidence )
+{
+ // So far unhandled KCal::IncidenceBase fields:
+ // mPilotID, mSyncStatus, mFloats
+
+ setUid( incidence->uid() );
+ setBody( incidence->description() );
+ setCategories( incidence->categoriesStr() );
+ setCreationDate( localToUTC( incidence->created() ) );
+ setLastModified( localToUTC( incidence->lastModified() ) );
+ setSensitivity( static_cast<Sensitivity>( incidence->secrecy() ) );
+ // TODO: Attachments
+}
+
+void ScalixBase::saveTo( KCal::Incidence* incidence ) const
+{
+ incidence->setUid( uid() );
+ incidence->setDescription( body() );
+ incidence->setCategories( categories() );
+ incidence->setCreated( utcToLocal( creationDate() ) );
+ incidence->setLastModified( utcToLocal( lastModified() ) );
+ incidence->setSecrecy( sensitivity() );
+ // TODO: Attachments
+}
+
+void ScalixBase::setFields( const KABC::Addressee* addressee )
+{
+ // An addressee does not have a creation date, so somehow we should
+ // make one, if this is a new entry
+
+ setUid( addressee->uid() );
+ setBody( addressee->note() );
+ setCategories( addressee->categories().join( "," ) );
+
+ // Set creation-time and last-modification-time
+ const QString creationString = addressee->custom( "KOLAB", "CreationDate" );
+ kdDebug(5006) << "Creation time string: " << creationString << endl;
+ QDateTime creationDate;
+ if ( creationString.isEmpty() ) {
+ creationDate = QDateTime::currentDateTime();
+ kdDebug(5006) << "Creation date set to current time\n";
+ }
+ else {
+ creationDate = stringToDateTime( creationString );
+ kdDebug(5006) << "Creation date loaded\n";
+ }
+ QDateTime modified = addressee->revision();
+ if ( !modified.isValid() )
+ modified = QDateTime::currentDateTime();
+ setLastModified( modified );
+ if ( modified < creationDate ) {
+ // It's not possible that the modification date is earlier than creation
+ creationDate = modified;
+ kdDebug(5006) << "Creation date set to modification date\n";
+ }
+ setCreationDate( creationDate );
+ const QString newCreationDate = dateTimeToString( creationDate );
+ if ( creationString != newCreationDate ) {
+ // We modified the creation date, so store it for future reference
+ const_cast<KABC::Addressee*>( addressee )
+ ->insertCustom( "KOLAB", "CreationDate", newCreationDate );
+ kdDebug(5006) << "Creation date modified. New one: " << newCreationDate << endl;
+ }
+
+ switch( addressee->secrecy().type() ) {
+ case KABC::Secrecy::Private:
+ setSensitivity( Private );
+ break;
+ case KABC::Secrecy::Confidential:
+ setSensitivity( Confidential );
+ break;
+ default:
+ setSensitivity( Public );
+ }
+
+ // TODO: Attachments
+}
+
+void ScalixBase::saveTo( KABC::Addressee* addressee ) const
+{
+ addressee->setUid( uid() );
+ addressee->setNote( body() );
+ addressee->setCategories( QStringList::split( ',', categories() ) );
+ addressee->setRevision( lastModified() );
+ addressee->insertCustom( "KOLAB", "CreationDate",
+ dateTimeToString( creationDate() ) );
+
+ switch( sensitivity() ) {
+ case Private:
+ addressee->setSecrecy( KABC::Secrecy( KABC::Secrecy::Private ) );
+ break;
+ case Confidential:
+ addressee->setSecrecy( KABC::Secrecy( KABC::Secrecy::Confidential ) );
+ break;
+ default:
+ addressee->setSecrecy( KABC::Secrecy( KABC::Secrecy::Public ) );
+ break;
+ }
+
+ // TODO: Attachments
+}
+
+void ScalixBase::setUid( const QString& uid )
+{
+ mUid = uid;
+}
+
+QString ScalixBase::uid() const
+{
+ return mUid;
+}
+
+void ScalixBase::setBody( const QString& body )
+{
+ mBody = body;
+}
+
+QString ScalixBase::body() const
+{
+ return mBody;
+}
+
+void ScalixBase::setCategories( const QString& categories )
+{
+ mCategories = categories;
+}
+
+QString ScalixBase::categories() const
+{
+ return mCategories;
+}
+
+void ScalixBase::setCreationDate( const QDateTime& date )
+{
+ mCreationDate = date;
+}
+
+QDateTime ScalixBase::creationDate() const
+{
+ return mCreationDate;
+}
+
+void ScalixBase::setLastModified( const QDateTime& date )
+{
+ mLastModified = date;
+}
+
+QDateTime ScalixBase::lastModified() const
+{
+ return mLastModified;
+}
+
+void ScalixBase::setSensitivity( Sensitivity sensitivity )
+{
+ mSensitivity = sensitivity;
+}
+
+ScalixBase::Sensitivity ScalixBase::sensitivity() const
+{
+ return mSensitivity;
+}
+
+void ScalixBase::setPilotSyncId( unsigned long id )
+{
+ mHasPilotSyncId = true;
+ mPilotSyncId = id;
+}
+
+bool ScalixBase::hasPilotSyncId() const
+{
+ return mHasPilotSyncId;
+}
+
+unsigned long ScalixBase::pilotSyncId() const
+{
+ return mPilotSyncId;
+}
+
+void ScalixBase::setPilotSyncStatus( int status )
+{
+ mHasPilotSyncStatus = true;
+ mPilotSyncStatus = status;
+}
+
+bool ScalixBase::hasPilotSyncStatus() const
+{
+ return mHasPilotSyncStatus;
+}
+
+int ScalixBase::pilotSyncStatus() const
+{
+ return mPilotSyncStatus;
+}
+
+bool ScalixBase::loadEmailAttribute( QDomElement& element, Email& email )
+{
+ for ( QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ if ( n.isComment() )
+ continue;
+ if ( n.isElement() ) {
+ QDomElement e = n.toElement();
+ QString tagName = e.tagName();
+
+ if ( tagName == "display-name" )
+ email.displayName = e.text();
+ else if ( tagName == "smtp-address" )
+ email.smtpAddress = e.text();
+ else
+ // TODO: Unhandled tag - save for later storage
+ kdDebug() << "Warning: Unhandled tag " << e.tagName() << endl;
+ } else
+ kdDebug() << "Node is not a comment or an element???" << endl;
+ }
+
+ return true;
+}
+
+void ScalixBase::saveEmailAttribute( QDomElement& element, const Email& email,
+ const QString& tagName ) const
+{
+ QDomElement e = element.ownerDocument().createElement( tagName );
+ element.appendChild( e );
+ writeString( e, "display-name", email.displayName );
+ writeString( e, "smtp-address", email.smtpAddress );
+}
+
+bool ScalixBase::loadAttribute( QDomElement& element )
+{
+ QString tagName = element.tagName();
+
+ if ( tagName == "uid" )
+ setUid( element.text() );
+ else if ( tagName == "body" )
+ setBody( element.text() );
+ else if ( tagName == "categories" )
+ setCategories( element.text() );
+ else if ( tagName == "creation-date" )
+ setCreationDate( stringToDateTime( element.text() ) );
+ else if ( tagName == "last-modification-date" )
+ setLastModified( stringToDateTime( element.text() ) );
+ else if ( tagName == "sensitivity" )
+ setSensitivity( stringToSensitivity( element.text() ) );
+ else if ( tagName == "product-id" )
+ return true; // ignore this field
+ else if ( tagName == "pilot-sync-id" )
+ setPilotSyncId( element.text().toULong() );
+ else if ( tagName == "pilot-sync-status" )
+ setPilotSyncStatus( element.text().toInt() );
+ else
+ return false;
+
+ // Handled here
+ return true;
+}
+
+bool ScalixBase::saveAttributes( QDomElement& element ) const
+{
+ writeString( element, "product-id", productID() );
+ writeString( element, "uid", uid() );
+ writeString( element, "body", body() );
+ writeString( element, "categories", categories() );
+ writeString( element, "creation-date", dateTimeToString( creationDate() ) );
+ writeString( element, "last-modification-date",
+ dateTimeToString( lastModified() ) );
+ writeString( element, "sensitivity", sensitivityToString( sensitivity() ) );
+ if ( hasPilotSyncId() )
+ writeString( element, "pilot-sync-id", QString::number( pilotSyncId() ) );
+ if ( hasPilotSyncStatus() )
+ writeString( element, "pilot-sync-status", QString::number( pilotSyncStatus() ) );
+ return true;
+}
+
+bool ScalixBase::load( const QString& xml )
+{
+ QString errorMsg;
+ int errorLine, errorColumn;
+ QDomDocument document;
+ bool ok = document.setContent( xml, &errorMsg, &errorLine, &errorColumn );
+
+ if ( !ok ) {
+ qWarning( "Error loading document: %s, line %d, column %d",
+ errorMsg.latin1(), errorLine, errorColumn );
+ return false;
+ }
+
+ // XML file loaded into tree. Now parse it
+ return loadXML( document );
+}
+
+bool ScalixBase::load( QFile& xml )
+{
+ QString errorMsg;
+ int errorLine, errorColumn;
+ QDomDocument document;
+ bool ok = document.setContent( &xml, &errorMsg, &errorLine, &errorColumn );
+
+ if ( !ok ) {
+ qWarning( "Error loading document: %s, line %d, column %d",
+ errorMsg.latin1(), errorLine, errorColumn );
+ return false;
+ }
+
+ // XML file loaded into tree. Now parse it
+ return loadXML( document );
+}
+
+QDomDocument ScalixBase::domTree()
+{
+ QDomDocument document;
+
+ QString p = "version=\"1.0\" encoding=\"UTF-8\"";
+ document.appendChild(document.createProcessingInstruction( "xml", p ) );
+
+ return document;
+}
+
+
+QString ScalixBase::dateTimeToString( const QDateTime& time )
+{
+ return time.toString( Qt::ISODate ) + 'Z';
+}
+
+QString ScalixBase::dateToString( const QDate& date )
+{
+ return date.toString( Qt::ISODate );
+}
+
+QDateTime ScalixBase::stringToDateTime( const QString& _date )
+{
+ QString date( _date );
+ if ( date.endsWith( "Z" ) )
+ date.truncate( date.length() - 1 );
+ return QDateTime::fromString( date, Qt::ISODate );
+}
+
+QDate ScalixBase::stringToDate( const QString& date )
+{
+ return QDate::fromString( date, Qt::ISODate );
+}
+
+QString ScalixBase::sensitivityToString( Sensitivity s )
+{
+ switch( s ) {
+ case Private: return "private";
+ case Confidential: return "confidential";
+ case Public: return "public";
+ }
+
+ return "What what what???";
+}
+
+ScalixBase::Sensitivity ScalixBase::stringToSensitivity( const QString& s )
+{
+ if ( s == "private" )
+ return Private;
+ if ( s == "confidential" )
+ return Confidential;
+ return Public;
+}
+
+QString ScalixBase::colorToString( const QColor& color )
+{
+ // Color is in the format "#RRGGBB"
+ return color.name();
+}
+
+QColor ScalixBase::stringToColor( const QString& s )
+{
+ return QColor( s );
+}
+
+void ScalixBase::writeString( QDomElement& element, const QString& tag,
+ const QString& tagString )
+{
+ if ( !tagString.isEmpty() ) {
+ QDomElement e = element.ownerDocument().createElement( tag );
+ QDomText t = element.ownerDocument().createTextNode( tagString );
+ e.appendChild( t );
+ element.appendChild( e );
+ }
+}
+
+QDateTime ScalixBase::localToUTC( const QDateTime& time ) const
+{
+ return KPimPrefs::localTimeToUtc( time, mTimeZoneId );
+}
+
+QDateTime ScalixBase::utcToLocal( const QDateTime& time ) const
+{
+ return KPimPrefs::utcToLocalTime( time, mTimeZoneId );
+}
diff --git a/kresources/scalix/shared/scalixbase.h b/kresources/scalix/shared/scalixbase.h
new file mode 100644
index 000000000..efed7e27a
--- /dev/null
+++ b/kresources/scalix/shared/scalixbase.h
@@ -0,0 +1,176 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Bo Thorsen <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef SCALIXBASE_H
+#define SCALIXBASE_H
+
+#include <qdom.h>
+#include <qdatetime.h>
+#include <qcolor.h>
+
+class QFile;
+
+namespace KCal {
+ class Incidence;
+}
+
+namespace KABC {
+ class Addressee;
+}
+
+namespace Scalix {
+
+class ScalixBase {
+public:
+ struct Email {
+ public:
+ Email( const QString& name = QString::null,
+ const QString& email = QString::null )
+ : displayName( name ), smtpAddress( email )
+ {
+ }
+
+ QString displayName;
+ QString smtpAddress;
+ };
+
+ enum Sensitivity { Public = 0, Private = 1, Confidential = 2 };
+
+ explicit ScalixBase( const QString& timezone = QString::null );
+ virtual ~ScalixBase();
+
+ // Return a string identifying this type
+ virtual QString type() const = 0;
+
+ virtual void setUid( const QString& uid );
+ virtual QString uid() const;
+
+ virtual void setBody( const QString& body );
+ virtual QString body() const;
+
+ virtual void setCategories( const QString& categories );
+ virtual QString categories() const;
+
+ virtual void setCreationDate( const QDateTime& date );
+ virtual QDateTime creationDate() const;
+
+ virtual void setLastModified( const QDateTime& date );
+ virtual QDateTime lastModified() const;
+
+ virtual void setSensitivity( Sensitivity sensitivity );
+ virtual Sensitivity sensitivity() const;
+
+ virtual void setPilotSyncId( unsigned long id );
+ virtual bool hasPilotSyncId() const;
+ virtual unsigned long pilotSyncId() const;
+
+ virtual void setPilotSyncStatus( int status );
+ virtual bool hasPilotSyncStatus() const;
+ virtual int pilotSyncStatus() const;
+
+ // String - Date conversion methods
+ static QString dateTimeToString( const QDateTime& time );
+ static QString dateToString( const QDate& date );
+ static QDateTime stringToDateTime( const QString& time );
+ static QDate stringToDate( const QString& date );
+
+ // String - Sensitivity conversion methods
+ static QString sensitivityToString( Sensitivity );
+ static Sensitivity stringToSensitivity( const QString& );
+
+ // String - Color conversion methods
+ static QString colorToString( const QColor& );
+ static QColor stringToColor( const QString& );
+
+ // Load this object by reading the XML file
+ bool load( const QString& xml );
+ bool load( QFile& xml );
+
+ // Load this QDomDocument
+ virtual bool loadXML( const QDomDocument& xml ) = 0;
+
+ // Serialize this object to an XML string
+ virtual QString saveXML() const = 0;
+
+protected:
+ /// Read all known fields from this ical incidence
+ void setFields( const KCal::Incidence* );
+
+ /// Save all known fields into this ical incidence
+ void saveTo( KCal::Incidence* ) const;
+
+ /// Read all known fields from this contact
+ void setFields( const KABC::Addressee* );
+
+ /// Save all known fields into this contact
+ void saveTo( KABC::Addressee* ) const;
+
+ // This just makes the initial dom tree with version and doctype
+ static QDomDocument domTree();
+
+ bool loadEmailAttribute( QDomElement& element, Email& email );
+
+ void saveEmailAttribute( QDomElement& element, const Email& email,
+ const QString& tagName = "email" ) const;
+
+ // Load the attributes of this class
+ virtual bool loadAttribute( QDomElement& );
+
+ // Save the attributes of this class
+ virtual bool saveAttributes( QDomElement& ) const;
+
+ // Return the product ID
+ virtual QString productID() const = 0;
+
+ // Write a string tag
+ static void writeString( QDomElement&, const QString&, const QString& );
+
+ QDateTime localToUTC( const QDateTime& time ) const;
+ QDateTime utcToLocal( const QDateTime& time ) const;
+
+ QString mUid;
+ QString mBody;
+ QString mCategories;
+ QDateTime mCreationDate;
+ QDateTime mLastModified;
+ Sensitivity mSensitivity;
+ QString mTimeZoneId;
+
+ // KPilot synchronization stuff
+ bool mHasPilotSyncId, mHasPilotSyncStatus;
+ unsigned long mPilotSyncId;
+ int mPilotSyncStatus;
+};
+
+}
+
+#endif // SCALIXBASE_H
diff --git a/kresources/scalix/shared/subresource.cpp b/kresources/scalix/shared/subresource.cpp
new file mode 100644
index 000000000..6653e0f06
--- /dev/null
+++ b/kresources/scalix/shared/subresource.cpp
@@ -0,0 +1,116 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Klar�lvdalens Datakonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "subresource.h"
+
+using namespace Scalix;
+
+SubResource::SubResource( bool active, bool writable, const QString& label,
+ int completionWeight )
+ : mActive( active ), mWritable( writable ), mLabel( label ),
+ mCompletionWeight( completionWeight )
+{
+}
+
+SubResource::~SubResource()
+{
+}
+
+void SubResource::setActive( bool active )
+{
+ mActive = active;
+}
+
+bool SubResource::active() const
+{
+ return mActive;
+}
+
+void SubResource::setWritable( bool writable )
+{
+ mWritable = writable;
+}
+
+bool SubResource::writable() const
+{
+ return mWritable;
+}
+
+void SubResource::setLabel( const QString& label )
+{
+ mLabel = label;
+}
+
+QString SubResource::label() const
+{
+ return mLabel;
+}
+
+void SubResource::setCompletionWeight( int completionWeight )
+{
+ mCompletionWeight = completionWeight;
+}
+
+int SubResource::completionWeight() const
+{
+ return mCompletionWeight;
+}
+
+StorageReference::StorageReference( const QString& resource, Q_UINT32 sernum )
+ : mResource( resource ), mSerialNumber( sernum )
+{
+}
+
+StorageReference::~StorageReference()
+{
+}
+
+void StorageReference::setResource( const QString& resource )
+{
+ mResource = resource;
+}
+
+QString StorageReference::resource() const
+{
+ return mResource;
+}
+
+void StorageReference::setSerialNumber( Q_UINT32 serialNumber )
+{
+ mSerialNumber = serialNumber;
+}
+
+Q_UINT32 StorageReference::serialNumber() const
+{
+ return mSerialNumber;
+}
diff --git a/kresources/scalix/shared/subresource.h b/kresources/scalix/shared/subresource.h
new file mode 100644
index 000000000..3cfc4429e
--- /dev/null
+++ b/kresources/scalix/shared/subresource.h
@@ -0,0 +1,110 @@
+/*
+ This file is part of the scalix resource - based on the kolab resource.
+
+ Copyright (c) 2004 Klar�lvdalens Datakonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef SUBRESOURCE_H
+#define SUBRESOURCE_H
+
+#include <qstring.h>
+#include <qmap.h>
+
+
+namespace Scalix {
+
+/**
+ * This class is used to store in a map from resource id to this, providing
+ * a lookup of the subresource settings.
+ */
+class SubResource {
+public:
+ // This is just for QMap
+ SubResource() {}
+
+ SubResource( bool active, bool writable, const QString& label,
+ int completionWeight = 100 );
+ virtual ~SubResource();
+
+ virtual void setActive( bool active );
+ virtual bool active() const;
+
+ virtual void setWritable( bool writable );
+ virtual bool writable() const;
+
+ virtual void setLabel( const QString& label );
+ virtual QString label() const;
+
+ virtual void setCompletionWeight( int completionWeight );
+ virtual int completionWeight() const;
+
+private:
+ bool mActive; // Controlled by the applications
+ bool mWritable; // Set if the KMail folder is writable
+ QString mLabel; // The GUI name of this resource
+
+ // This is just for the abc plugin. But as long as only this is here,
+ // it's just as cheap to have it in here as making a d-pointer that
+ // subclasses could add to. If more are added, then we should refactor
+ // to a d-pointer instead.
+ int mCompletionWeight;
+};
+
+typedef QMap<QString, SubResource> ResourceMap;
+
+/**
+ * This class is used to store a mapping from the XML UID to the KMail
+ * serial number of the mail it's stored in and the resource. That provides
+ * a quick way to access the storage in KMail.
+ */
+class StorageReference {
+public:
+ // Just for QMap
+ StorageReference() {}
+
+ StorageReference( const QString& resource, Q_UINT32 sernum );
+ virtual ~StorageReference();
+
+ virtual void setResource( const QString& resource );
+ virtual QString resource() const;
+
+ virtual void setSerialNumber( Q_UINT32 serialNumber );
+ virtual Q_UINT32 serialNumber() const;
+
+private:
+ QString mResource;
+ Q_UINT32 mSerialNumber;
+};
+
+typedef QMap<QString, StorageReference> UidMap;
+
+}
+
+#endif // SUBRESOURCE_H
diff --git a/kresources/scalix/uninstall.desktop b/kresources/scalix/uninstall.desktop
new file mode 100644
index 000000000..e1e3e1732
--- /dev/null
+++ b/kresources/scalix/uninstall.desktop
@@ -0,0 +1,2 @@
+[Desktop Entry]
+Hidden=true