summaryrefslogtreecommitdiffstats
path: root/kontact/src
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 /kontact/src
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 'kontact/src')
-rw-r--r--kontact/src/Kontact.desktop71
-rw-r--r--kontact/src/Makefile.am42
-rw-r--r--kontact/src/about/Makefile.am6
-rw-r--r--kontact/src/about/kontact.css30
-rw-r--r--kontact/src/about/main.html66
-rw-r--r--kontact/src/about/top-right-kontact.pngbin0 -> 17996 bytes
-rw-r--r--kontact/src/aboutdialog.cpp177
-rw-r--r--kontact/src/aboutdialog.h57
-rw-r--r--kontact/src/hi128-app-kontact.pngbin0 -> 20269 bytes
-rw-r--r--kontact/src/hi16-app-kontact.pngbin0 -> 960 bytes
-rw-r--r--kontact/src/hi22-app-kontact.pngbin0 -> 1528 bytes
-rw-r--r--kontact/src/hi32-app-kontact.pngbin0 -> 2611 bytes
-rw-r--r--kontact/src/hi48-app-kontact.pngbin0 -> 4805 bytes
-rw-r--r--kontact/src/hi64-app-kontact.pngbin0 -> 7186 bytes
-rw-r--r--kontact/src/iconsidepane.cpp612
-rw-r--r--kontact/src/iconsidepane.h193
-rw-r--r--kontact/src/kcmkontact.cpp152
-rw-r--r--kontact/src/kcmkontact.h69
-rw-r--r--kontact/src/kontact.kcfg32
-rw-r--r--kontact/src/kontact.setdlg646
-rw-r--r--kontact/src/kontactconfig.desktop53
-rw-r--r--kontact/src/kontactdcop.desktop18
-rw-r--r--kontact/src/kontactiface.h36
-rw-r--r--kontact/src/kontactui.rc48
-rw-r--r--kontact/src/main.cpp168
-rw-r--r--kontact/src/mainwindow.cpp1100
-rw-r--r--kontact/src/mainwindow.h168
-rw-r--r--kontact/src/prefs.kcfgc13
-rw-r--r--kontact/src/profiledialog.cpp267
-rw-r--r--kontact/src/profiledialog.h90
-rw-r--r--kontact/src/profilemanager.cpp340
-rw-r--r--kontact/src/profilemanager.h162
-rw-r--r--kontact/src/sidepanebase.cpp52
-rw-r--r--kontact/src/sidepanebase.h79
34 files changed, 4747 insertions, 0 deletions
diff --git a/kontact/src/Kontact.desktop b/kontact/src/Kontact.desktop
new file mode 100644
index 000000000..6cd9d0d3a
--- /dev/null
+++ b/kontact/src/Kontact.desktop
@@ -0,0 +1,71 @@
+[Desktop Entry]
+Name=Kontact
+Name[be]=Кантакт
+Name[hi]=कॉन्टेक्ट
+Name[mk]=Контакт
+Name[ne]=सम्पर्क गर्नुहोस्
+Name[sv]=Kontakt
+Name[ta]=தொடர்பு கொள்
+Name[zh_TW]=Kontact 個人資訊管理
+Exec=kontact
+Type=Application
+Icon=kontact
+GenericName=Personal Information Manager
+GenericName[af]=Personlike informasie bestuurder
+GenericName[ar]=منظم المعلومات الشخصي
+GenericName[be]=Кіраванне пэрсанальнай інфармацыяй
+GenericName[bg]=Лична информация
+GenericName[bs]=Upravitelj ličnim informacijama
+GenericName[ca]=Gestor d'informació personal
+GenericName[cs]=Správce osobních informací
+GenericName[cy]=Rheolydd Gwybodaeth Personol
+GenericName[da]=Personlig informationshåndtering
+GenericName[de]=Persönlicher Informationsmanager
+GenericName[el]=Προσωπικός διαχειριστής πληροφοριών
+GenericName[eo]=Persona Inform-Mastrumilo
+GenericName[es]=Gestor de información personal
+GenericName[et]=Personaalse info haldur
+GenericName[eu]=Informazio pertsonalaren kudeatzailea
+GenericName[fa]=مدیر اطلاعات شخصی
+GenericName[fi]=Henkilötietojen hallinta
+GenericName[fr]=Gestionnaire d'informations personnelles
+GenericName[gl]=Xestor de Información Persoal
+GenericName[he]=מנהל מידע אישי
+GenericName[hi]=निजी जानकारी प्रबंधक
+GenericName[hu]=Információkezelő
+GenericName[is]=Persónulegur upplýsingastjórnandi
+GenericName[it]=Gestione informazioni personali
+GenericName[ja]=個人情報マネージャ
+GenericName[ka]=პირადი ინფორმაციის მმართველი
+GenericName[kk]=Дербес Ақпарат Менеджері
+GenericName[km]=កម្មវិធី​គ្រប់គ្រង​ព័ត៌មាន​ផ្ទាល់​ខ្លួន
+GenericName[lt]=Asmeninės informacijos tvarkyklė
+GenericName[mk]=Менаџер на лични информации
+GenericName[ms]=Pengurus Makumat Peribadi
+GenericName[nb]=Personlig informasjonsbehandler
+GenericName[nds]=Pleger för persöönliche Informatschonen
+GenericName[ne]=व्यक्तिगत सूचना प्रबन्धक
+GenericName[nn]=Personleg informasjonshandtering
+GenericName[pl]=Program do zarządzania informacjami osobistymi
+GenericName[pt]=Gestor Pessoal de Informações
+GenericName[pt_BR]=Gerenciador de Informações Pessoais
+GenericName[ro]=Manager de informaţii personale
+GenericName[ru]=Персональный информационный менеджер
+GenericName[se]=Persuvnnalaš diehtogieđaheapmi
+GenericName[sk]=Osobný manažér informácii
+GenericName[sl]=Osebni upravitelj informacij
+GenericName[sr]=Менаџер личних информација
+GenericName[sr@Latn]=Menadžer ličnih informacija
+GenericName[sv]=Personlig informationshantering
+GenericName[ta]=அந்தரங்க தகவல் மேலாளர்
+GenericName[tg]=Мудири маълумоти шахсӣ
+GenericName[tr]=Kişisel Bilgi Yöneticisi
+GenericName[uk]=Менеджер особистої інформації
+GenericName[uz]=Shaxsiy maʼlumot boshqaruvchisi
+GenericName[uz@cyrillic]=Шахсий маълумот бошқарувчиси
+GenericName[zh_CN]=个人信息管理器
+GenericName[zh_TW]=個人資訊管理者
+Terminal=false
+X-KDE-StartupNotify=true
+Categories=Qt;KDE;Office;Network;Email;
+DocPath=kontact/index.html
diff --git a/kontact/src/Makefile.am b/kontact/src/Makefile.am
new file mode 100644
index 000000000..b30c5bc77
--- /dev/null
+++ b/kontact/src/Makefile.am
@@ -0,0 +1,42 @@
+SUBDIRS = about
+
+INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir) $(all_includes)
+
+lib_LTLIBRARIES = libkontact.la
+libkontact_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -version-info 1:0
+libkontact_la_LIBADD = $(LIB_KDECORE)
+libkontact_la_SOURCES = prefs.kcfgc
+
+bin_PROGRAMS = kontact
+
+kontact_METASOURCES = AUTO
+kontact_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+kontact_LDADD = $(top_builddir)/libkdepim/libkdepim.la \
+ $(top_builddir)/kontact/interfaces/libkpinterfaces.la libkontact.la \
+ $(LIB_KPARTS) $(LIB_KUTILS) $(LIB_KHTML)
+kontact_SOURCES = main.cpp mainwindow.cpp sidepanebase.cpp \
+ iconsidepane.cpp aboutdialog.cpp profilemanager.cpp profiledialog.cpp \
+ kontactiface.skel
+kontact_COMPILE_FIRST = prefs.h
+
+kde_module_LTLIBRARIES = kcm_kontact.la
+
+kcm_kontact_la_SOURCES = kcmkontact.cpp
+kcm_kontact_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
+kcm_kontact_la_LIBADD = libkontact.la $(top_builddir)/libkdepim/libkdepim.la
+kcm_kontact_la_COMPILE_FIRST = prefs.h
+
+
+rcdir = $(kde_datadir)/kontact
+rc_DATA = kontactui.rc
+
+xdg_apps_DATA = Kontact.desktop kontactdcop.desktop
+
+kde_kcfg_DATA = kontact.kcfg
+
+kde_services_DATA = kontactconfig.desktop
+
+kontactsetdlgdir = $(kde_datadir)/kontact
+kontactsetdlg_DATA = kontact.setdlg
+
+KDE_ICON = AUTO
diff --git a/kontact/src/about/Makefile.am b/kontact/src/about/Makefile.am
new file mode 100644
index 000000000..b2c7b7605
--- /dev/null
+++ b/kontact/src/about/Makefile.am
@@ -0,0 +1,6 @@
+about_DATA = \
+ top-right-kontact.png \
+ main.html \
+ kontact.css
+
+aboutdir = $(kde_datadir)/kontact/about
diff --git a/kontact/src/about/kontact.css b/kontact/src/about/kontact.css
new file mode 100644
index 000000000..18aa0ddcd
--- /dev/null
+++ b/kontact/src/about/kontact.css
@@ -0,0 +1,30 @@
+
+#headerR {
+ position: absolute;
+ right: 0px;
+ width: 430px;
+ height: 131px;
+ background-image: url(top-right-kontact.png);
+}
+
+#title {
+ right: 125px;
+}
+
+#tagline {
+ right: 125px;
+}
+
+#boxCenter {
+ background-image: url(box-center-kontact.png);
+ background-repeat: no-repeat;
+ background-color: #dfe7f3;
+ background-position: bottom right;
+}
+
+#subtext {
+ font-style: italic;
+}
+
+/* vim:set sw=2 et nocindent smartindent: */
+
diff --git a/kontact/src/about/main.html b/kontact/src/about/main.html
new file mode 100644
index 000000000..a36cc2537
--- /dev/null
+++ b/kontact/src/about/main.html
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1st August 2004), see www.w3.org" />
+
+ <style type="text/css">
+ /*<![CDATA[*/
+ @import "%1"; /* kde_infopage.css */
+ %1 /* maybe @import "kde_infopage_rtl.css"; */
+ @import "kontact.css";
+ body {font-size: %1px;}
+ /*]]>*/
+ </style>
+
+ <title>Kontact</title>
+</head>
+
+<body>
+ <div id="header">
+ <div id="headerL"/>
+ <div id="headerR"/>
+
+ <div id="title">
+ %2 <!-- Kontact -->
+ </div>
+
+ <div id="tagline">
+ %3 <!-- Catchphrase -->
+ </div>
+ </div>
+
+ <!-- the bar -->
+ <div id="bar">
+ <div id="barT"><div id="barTL"/><div id="barTR"/><div id="barTC"/></div>
+ <div id="barL">
+ <div id="barR">
+ <div id="barCenter" class="bar_text">
+ %4<!-- Kontact is ... -->
+ </div>
+ </div>
+ </div>
+ <div id="barB"><div id="barBL"/><div id="barBR"/><div id="barBC"/></div>
+ </div>
+
+ <!-- the main text box -->
+ <div id="box">
+ <div id="boxT"><div id="boxTL"/><div id="boxTR"/><div id="boxTC"/></div>
+ <div id="boxL">
+ <div id="boxR">
+ <div id="boxCenter">
+ <!--Welcome to Kontact-->
+ %5
+ </div>
+ </div>
+ </div>
+ <div id="boxB"><div id="boxBL"/><div id="boxBR"/><div id="boxBC"/></div>
+ </div>
+
+ <div id="footer"><div id="footerL"/><div id="footerR"/></div>
+</body>
+</html>
+<!-- vim:set sw=2 et nocindent smartindent: -->
diff --git a/kontact/src/about/top-right-kontact.png b/kontact/src/about/top-right-kontact.png
new file mode 100644
index 000000000..bf15f38b5
--- /dev/null
+++ b/kontact/src/about/top-right-kontact.png
Binary files differ
diff --git a/kontact/src/aboutdialog.cpp b/kontact/src/aboutdialog.cpp
new file mode 100644
index 000000000..d0a43721a
--- /dev/null
+++ b/kontact/src/aboutdialog.cpp
@@ -0,0 +1,177 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include "aboutdialog.h"
+
+#include "core.h"
+#include "plugin.h"
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kaboutdata.h>
+#include <kactivelabel.h>
+#include <ktextbrowser.h>
+
+#include <qlayout.h>
+#include <qlabel.h>
+
+#include <kdebug.h>
+
+using namespace Kontact;
+
+AboutDialog::AboutDialog( Kontact::Core *core, const char *name )
+ : KDialogBase( IconList, i18n("About Kontact"), Ok, Ok, core, name, false,
+ true ),
+ mCore( core )
+{
+ addAboutData( i18n( "Kontact Container" ), QString( "kontact" ),
+ KGlobal::instance()->aboutData() );
+
+ QValueList<Plugin*> plugins = mCore->pluginList();
+ QValueList<Plugin*>::ConstIterator end = plugins.end();
+ QValueList<Plugin*>::ConstIterator it = plugins.begin();
+ for ( ; it != end; ++it )
+ addAboutPlugin( *it );
+
+ addLicenseText( KGlobal::instance()->aboutData() );
+}
+
+void AboutDialog::addAboutPlugin( Kontact::Plugin *plugin )
+{
+ addAboutData( plugin->title(), plugin->icon(), plugin->aboutData() );
+}
+
+void AboutDialog::addAboutData( const QString &title, const QString &icon,
+ const KAboutData *about )
+{
+ QPixmap pixmap = KGlobal::iconLoader()->loadIcon( icon,
+ KIcon::Desktop, 48 );
+
+ QFrame *topFrame = addPage( title, QString::null, pixmap );
+
+ QBoxLayout *topLayout = new QVBoxLayout( topFrame );
+
+ if ( !about ) {
+ QLabel *label = new QLabel( i18n( "No about information available." ),
+ topFrame );
+ topLayout->addWidget( label );
+ } else {
+ QString text;
+
+ text += "<p><b>" + about->programName() + "</b><br>";
+
+ text += i18n( "Version %1</p>" ).arg( about->version() );
+
+ if ( !about->shortDescription().isEmpty() ) {
+ text += "<p>" + about->shortDescription() + "<br>" +
+ about->copyrightStatement() + "</p>";
+ }
+
+ QString home = about->homepage();
+ if ( !home.isEmpty() ) {
+ text += "<a href=\"" + home + "\">" + home + "</a><br>";
+ }
+
+ text.replace( "\n", "<br>" );
+
+ KActiveLabel *label = new KActiveLabel( text, topFrame );
+ label->setAlignment( AlignTop );
+ topLayout->addWidget( label );
+
+
+ QTextEdit *personView = new QTextEdit( topFrame );
+ personView->setReadOnly( true );
+ topLayout->addWidget( personView, 1 );
+
+ text = "";
+
+ const QValueList<KAboutPerson> authors = about->authors();
+ if ( !authors.isEmpty() ) {
+ text += i18n( "<p><b>Authors:</b></p>" );
+
+ QValueList<KAboutPerson>::ConstIterator it;
+ for ( it = authors.begin(); it != authors.end(); ++it ) {
+ text += formatPerson( (*it).name(), (*it).emailAddress() );
+ if ( !(*it).task().isEmpty() )
+ text += "<i>" + (*it).task() + "</i><br>";
+ }
+ }
+
+ const QValueList<KAboutPerson> credits = about->credits();
+ if ( !credits.isEmpty() ) {
+ text += i18n( "<p><b>Thanks to:</b></p>" );
+
+ QValueList<KAboutPerson>::ConstIterator it;
+ for ( it = credits.begin(); it != credits.end(); ++it ) {
+ text += formatPerson( (*it).name(), (*it).emailAddress() );
+ if ( !(*it).task().isEmpty() )
+ text += "<i>" + (*it).task() + "</i><br>";
+ }
+ }
+
+ const QValueList<KAboutTranslator> translators = about->translators();
+ if ( !translators.isEmpty() ) {
+ text += i18n("<p><b>Translators:</b></p>");
+
+ QValueList<KAboutTranslator>::ConstIterator it;
+ for ( it = translators.begin(); it != translators.end(); ++it ) {
+ text += formatPerson( (*it).name(), (*it).emailAddress() );
+ }
+ }
+
+ personView->setText( text );
+ }
+}
+
+QString AboutDialog::formatPerson( const QString &name, const QString &email )
+{
+ QString text = name;
+ if ( !email.isEmpty() ) {
+ text += " &lt;<a href=\"mailto:" + email + "\">" + email + "</a>&gt;";
+ }
+
+ text += "<br>";
+ return text;
+}
+
+void AboutDialog::addLicenseText( const KAboutData *about )
+{
+ if ( !about || about->license().isEmpty() )
+ return;
+
+ QPixmap pixmap = KGlobal::iconLoader()->loadIcon( "signature",
+ KIcon::Desktop, 48 );
+
+ QString title = i18n( "%1 License" ).arg( about->programName() );
+
+ QFrame *topFrame = addPage( title, QString::null, pixmap );
+ QBoxLayout *topLayout = new QVBoxLayout( topFrame );
+
+ KTextBrowser *textBrowser = new KTextBrowser( topFrame );
+ textBrowser->setText( QString( "<pre>%1</pre>" ).arg( about->license() ) );
+
+ topLayout->addWidget( textBrowser );
+}
+
+#include "aboutdialog.moc"
diff --git a/kontact/src/aboutdialog.h b/kontact/src/aboutdialog.h
new file mode 100644
index 000000000..9697c5274
--- /dev/null
+++ b/kontact/src/aboutdialog.h
@@ -0,0 +1,57 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+#ifndef KONTACT_ABOUTDIALOG_H
+#define KONTACT_ABOUTDIALOG_H
+
+#include <kdialogbase.h>
+class KAboutData;
+namespace Kontact {
+
+class Core;
+class Plugin;
+
+class AboutDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ AboutDialog( Kontact::Core *core, const char *name = 0 );
+
+ protected:
+ void addAboutPlugin( Kontact::Plugin *plugin );
+
+ void addAboutData( const QString &title, const QString &icon,
+ const KAboutData *about );
+
+ void addLicenseText( const KAboutData *about );
+
+ QString formatPerson( const QString &name, const QString &email );
+
+ private:
+ Core *mCore;
+};
+
+}
+
+#endif
diff --git a/kontact/src/hi128-app-kontact.png b/kontact/src/hi128-app-kontact.png
new file mode 100644
index 000000000..e8da426c5
--- /dev/null
+++ b/kontact/src/hi128-app-kontact.png
Binary files differ
diff --git a/kontact/src/hi16-app-kontact.png b/kontact/src/hi16-app-kontact.png
new file mode 100644
index 000000000..4d6e54d21
--- /dev/null
+++ b/kontact/src/hi16-app-kontact.png
Binary files differ
diff --git a/kontact/src/hi22-app-kontact.png b/kontact/src/hi22-app-kontact.png
new file mode 100644
index 000000000..af2614a26
--- /dev/null
+++ b/kontact/src/hi22-app-kontact.png
Binary files differ
diff --git a/kontact/src/hi32-app-kontact.png b/kontact/src/hi32-app-kontact.png
new file mode 100644
index 000000000..81d42536f
--- /dev/null
+++ b/kontact/src/hi32-app-kontact.png
Binary files differ
diff --git a/kontact/src/hi48-app-kontact.png b/kontact/src/hi48-app-kontact.png
new file mode 100644
index 000000000..c45ac6f8d
--- /dev/null
+++ b/kontact/src/hi48-app-kontact.png
Binary files differ
diff --git a/kontact/src/hi64-app-kontact.png b/kontact/src/hi64-app-kontact.png
new file mode 100644
index 000000000..7d2c409ed
--- /dev/null
+++ b/kontact/src/hi64-app-kontact.png
Binary files differ
diff --git a/kontact/src/iconsidepane.cpp b/kontact/src/iconsidepane.cpp
new file mode 100644
index 000000000..c7e9c84a0
--- /dev/null
+++ b/kontact/src/iconsidepane.cpp
@@ -0,0 +1,612 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include <qptrlist.h>
+#include <qwidgetstack.h>
+#include <qsignal.h>
+#include <qobjectlist.h>
+#include <qlabel.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include <qbitmap.h>
+#include <qfontmetrics.h>
+#include <qsignalmapper.h>
+#include <qstyle.h>
+#include <qframe.h>
+#include <qdrawutil.h>
+#include <qcursor.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+
+#include <kpopupmenu.h>
+#include <kapplication.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <sidebarextension.h>
+
+#include <kdebug.h>
+
+#include "mainwindow.h"
+
+#include "plugin.h"
+
+#include "prefs.h"
+#include "iconsidepane.h"
+
+namespace Kontact
+{
+
+//ugly wrapper class for adding an operator< to the Plugin class
+
+class PluginProxy
+{
+ public:
+ PluginProxy()
+ : mPlugin( 0 )
+ { }
+
+ PluginProxy( Plugin *plugin )
+ : mPlugin( plugin )
+ { }
+
+ PluginProxy & operator=( Plugin *plugin )
+ {
+ mPlugin = plugin;
+ return *this;
+ }
+
+ bool operator<( PluginProxy &rhs ) const
+ {
+ return mPlugin->weight() < rhs.mPlugin->weight();
+ }
+
+ Plugin *plugin() const
+ {
+ return mPlugin;
+ }
+
+ private:
+ Plugin *mPlugin;
+};
+
+} //namespace
+
+using namespace Kontact;
+
+EntryItem::EntryItem( Navigator *parent, Kontact::Plugin *plugin )
+ : QListBoxItem( parent ),
+ mPlugin( plugin ),
+ mHasHover( false ),
+ mPaintActive( false )
+{
+ reloadPixmap();
+ setCustomHighlighting( true );
+ setText( plugin->title() );
+}
+
+EntryItem::~EntryItem()
+{
+}
+
+void EntryItem::reloadPixmap()
+{
+ int size = (int)navigator()->viewMode();
+ if ( size != 0 )
+ mPixmap = KGlobal::iconLoader()->loadIcon( mPlugin->icon(),
+ KIcon::Desktop, size,
+ mPlugin->disabled() ?
+ KIcon::DisabledState
+ : KIcon::DefaultState);
+ else
+ mPixmap = QPixmap();
+}
+
+Navigator* EntryItem::navigator() const
+{
+ return static_cast<Navigator*>( listBox() );
+}
+
+int EntryItem::width( const QListBox *listbox ) const
+{
+ int w = 0;
+ if( navigator()->showIcons() ) {
+ w = navigator()->viewMode();
+ if ( navigator()->viewMode() == SmallIcons )
+ w += 4;
+ }
+ if( navigator()->showText() ) {
+ if ( navigator()->viewMode() == SmallIcons )
+ w += listbox->fontMetrics().width( text() );
+ else
+ w = QMAX( w, listbox->fontMetrics().width( text() ) );
+ }
+ return w + ( KDialog::marginHint() * 2 );
+}
+
+int EntryItem::height( const QListBox *listbox ) const
+{
+ int h = 0;
+ if ( navigator()->showIcons() )
+ h = (int)navigator()->viewMode() + 4;
+ if ( navigator()->showText() ) {
+ if ( navigator()->viewMode() == SmallIcons || !navigator()->showIcons() )
+ h = QMAX( h, listbox->fontMetrics().lineSpacing() ) + KDialog::spacingHint() * 2;
+ else
+ h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing() + 4;
+ }
+ return h;
+}
+
+void EntryItem::paint( QPainter *p )
+{
+ reloadPixmap();
+
+ QListBox *box = listBox();
+ bool iconAboveText = ( navigator()->viewMode() > SmallIcons )
+ && navigator()->showIcons();
+ int w = box->viewport()->width();
+ int y = iconAboveText ? 2 :
+ ( ( height( box ) - mPixmap.height() ) / 2 );
+
+ // draw selected
+ if ( isCurrent() || isSelected() || mHasHover || mPaintActive ) {
+ int h = height( box );
+
+ QBrush brush;
+ if ( isCurrent() || isSelected() || mPaintActive )
+ brush = box->colorGroup().brush( QColorGroup::Highlight );
+ else
+ brush = box->colorGroup().highlight().light( 115 );
+ p->fillRect( 1, 0, w - 2, h - 1, brush );
+ QPen pen = p->pen();
+ QPen oldPen = pen;
+ pen.setColor( box->colorGroup().mid() );
+ p->setPen( pen );
+
+ p->drawPoint( 1, 0 );
+ p->drawPoint( 1, h - 2 );
+ p->drawPoint( w - 2, 0 );
+ p->drawPoint( w - 2, h - 2 );
+
+ p->setPen( oldPen );
+ }
+
+ if ( !mPixmap.isNull() && navigator()->showIcons() ) {
+ int x = iconAboveText ? ( ( w - mPixmap.width() ) / 2 ) :
+ KDialog::marginHint();
+ p->drawPixmap( x, y, mPixmap );
+ }
+
+ QColor shadowColor = listBox()->colorGroup().background().dark(115);
+ if ( isCurrent() || isSelected() ) {
+ p->setPen( box->colorGroup().highlightedText() );
+ }
+
+ if ( !text().isEmpty() && navigator()->showText() ) {
+ QFontMetrics fm = p->fontMetrics();
+
+ int x = 0;
+ if ( iconAboveText ) {
+ x = ( w - fm.width( text() ) ) / 2;
+ y += fm.height() - fm.descent();
+ if ( navigator()->showIcons() )
+ y += mPixmap.height();
+ } else {
+ x = KDialog::marginHint() + 4;
+ if( navigator()->showIcons() ) {
+ x += mPixmap.width();
+ }
+
+ if ( !navigator()->showIcons() || mPixmap.height() < fm.height() )
+ y = height( box )/2 - fm.height()/2 + fm.ascent();
+ else
+ y += mPixmap.height()/2 - fm.height()/2 + fm.ascent();
+ }
+
+ if ( plugin()->disabled() ) {
+ p->setPen( box->palette().disabled().text( ) );
+ } else if ( isCurrent() || isSelected() || mHasHover ) {
+ p->setPen( box->colorGroup().highlight().dark(115) );
+ p->drawText( x + ( QApplication::reverseLayout() ? -1 : 1),
+ y + 1, text() );
+ p->setPen( box->colorGroup().highlightedText() );
+ }
+ else
+ p->setPen( box->colorGroup().text() );
+
+ p->drawText( x, y, text() );
+ }
+
+ // ensure that we don't have a stale flag around
+ if ( isCurrent() || isSelected() ) mHasHover = false;
+}
+
+void EntryItem::setHover( bool hasHover )
+{
+ mHasHover = hasHover;
+}
+
+void EntryItem::setPaintActive( bool paintActive )
+{
+ mPaintActive = paintActive;
+}
+
+Navigator::Navigator( SidePaneBase *parent, const char *name )
+ : KListBox( parent, name ), mSidePane( parent ),
+ mShowIcons( true ), mShowText( true )
+{
+ mMouseOn = 0;
+ mHighlightItem = 0;
+ mViewMode = sizeIntToEnum( Prefs::self()->sidePaneIconSize() );
+ mShowIcons = Prefs::self()->sidePaneShowIcons();
+ mShowText = Prefs::self()->sidePaneShowText();
+ setSelectionMode( KListBox::Single );
+ viewport()->setBackgroundMode( PaletteBackground );
+ setFrameStyle( QFrame::NoFrame );
+ setHScrollBarMode( QScrollView::AlwaysOff );
+ setAcceptDrops( true );
+
+ setFocusPolicy( NoFocus );
+
+ connect( this, SIGNAL( selectionChanged( QListBoxItem* ) ),
+ SLOT( slotExecuted( QListBoxItem* ) ) );
+ connect( this, SIGNAL( rightButtonPressed( QListBoxItem*, const QPoint& ) ),
+ SLOT( slotShowRMBMenu( QListBoxItem*, const QPoint& ) ) );
+ connect( this, SIGNAL( onItem( QListBoxItem * ) ),
+ SLOT( slotMouseOn( QListBoxItem * ) ) );
+ connect( this, SIGNAL( onViewport() ), SLOT( slotMouseOff() ) );
+
+ mMapper = new QSignalMapper( this );
+ connect( mMapper, SIGNAL( mapped( int ) ), SLOT( shortCutSelected( int ) ) );
+
+ QToolTip::remove( this );
+ if ( !mShowText )
+ new EntryItemToolTip( this );
+
+}
+
+QSize Navigator::sizeHint() const
+{
+ return QSize( 100, 100 );
+}
+
+void Navigator::highlightItem( EntryItem * item )
+{
+ mHighlightItem = item;
+
+ setPaintActiveItem( mHighlightItem, true );
+
+ QTimer::singleShot( 2000, this, SLOT( slotStopHighlight() ) );
+}
+
+void Navigator::slotStopHighlight()
+{
+ setPaintActiveItem( mHighlightItem, false );
+}
+
+void Navigator::setSelected( QListBoxItem *item, bool selected )
+{
+ // Reimplemented to avoid the immediate activation of
+ // the item. might turn out it doesn't work, we check that
+ // an confirm from MainWindow::selectPlugin()
+ if ( selected ) {
+ EntryItem *entry = static_cast<EntryItem*>( item );
+ emit pluginActivated( entry->plugin() );
+ }
+}
+
+void Navigator::updatePlugins( QValueList<Kontact::Plugin*> plugins_ )
+{
+ QValueList<Kontact::PluginProxy> plugins;
+ QValueList<Kontact::Plugin*>::ConstIterator end_ = plugins_.end();
+ QValueList<Kontact::Plugin*>::ConstIterator it_ = plugins_.begin();
+ for ( ; it_ != end_; ++it_ )
+ plugins += PluginProxy( *it_ );
+
+ clear();
+
+ mActions.setAutoDelete( true );
+ mActions.clear();
+ mActions.setAutoDelete( false );
+
+ int counter = 0;
+ int minWidth = 0;
+ qBubbleSort( plugins );
+ QValueList<Kontact::PluginProxy>::ConstIterator end = plugins.end();
+ QValueList<Kontact::PluginProxy>::ConstIterator it = plugins.begin();
+ for ( ; it != end; ++it ) {
+ Kontact::Plugin *plugin = ( *it ).plugin();
+ if ( !plugin->showInSideBar() )
+ continue;
+
+ EntryItem *item = new EntryItem( this, plugin );
+ item->setSelectable( !plugin->disabled() );
+
+ if ( item->width( this ) > minWidth )
+ minWidth = item->width( this );
+
+ QString name = QString( "CTRL+%1" ).arg( counter + 1 );
+ KAction *action = new KAction( plugin->title(), plugin->icon(), KShortcut( name ),
+ mMapper, SLOT( map() ),
+ mSidePane->actionCollection(), name.latin1() );
+ mActions.append( action );
+ mMapper->setMapping( action, counter );
+ counter++;
+ }
+
+ parentWidget()->setFixedWidth( minWidth );
+}
+
+void Navigator::dragEnterEvent( QDragEnterEvent *event )
+{
+ kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;
+
+ dragMoveEvent( event );
+}
+
+void Navigator::dragMoveEvent( QDragMoveEvent *event )
+{
+ kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;
+
+ kdDebug(5600) << " Format: " << event->format() << endl;
+
+ QListBoxItem *item = itemAt( event->pos() );
+
+ if ( !item ) {
+ event->accept( false );
+ return;
+ }
+
+ EntryItem *entry = static_cast<EntryItem*>( item );
+
+ kdDebug(5600) << " PLUGIN: " << entry->plugin()->identifier() << endl;
+
+ event->accept( entry->plugin()->canDecodeDrag( event ) );
+}
+
+void Navigator::dropEvent( QDropEvent *event )
+{
+ kdDebug(5600) << "Navigator::dropEvent()" << endl;
+
+ QListBoxItem *item = itemAt( event->pos() );
+
+ if ( !item ) {
+ return;
+ }
+
+ EntryItem *entry = static_cast<EntryItem*>( item );
+
+ kdDebug(5600) << " PLUGIN: " << entry->plugin()->identifier() << endl;
+
+ entry->plugin()->processDropEvent( event );
+}
+
+void Navigator::resizeEvent( QResizeEvent *event )
+{
+ QListBox::resizeEvent( event );
+ triggerUpdate( true );
+}
+
+void Navigator::enterEvent( QEvent *event )
+{
+ // work around Qt behaviour: onItem is not emmitted in enterEvent()
+ KListBox::enterEvent( event );
+ emit onItem( itemAt( mapFromGlobal( QCursor::pos() ) ) );
+}
+
+void Navigator::leaveEvent( QEvent *event )
+{
+ KListBox::leaveEvent( event );
+ slotMouseOn( 0 );
+ mMouseOn = 0;
+}
+
+void Navigator::slotExecuted( QListBoxItem *item )
+{
+ if ( !item )
+ return;
+
+ EntryItem *entry = static_cast<EntryItem*>( item );
+
+ emit pluginActivated( entry->plugin() );
+}
+
+IconViewMode Navigator::sizeIntToEnum(int size) const
+{
+ switch ( size ) {
+ case int(LargeIcons):
+ return LargeIcons;
+ break;
+ case int(NormalIcons):
+ return NormalIcons;
+ break;
+ case int(SmallIcons):
+ return SmallIcons;
+ break;
+ default:
+ // Stick with sane values
+ return NormalIcons;
+ kdDebug() << "View mode not implemented!" << endl;
+ break;
+ }
+}
+
+void Navigator::slotShowRMBMenu( QListBoxItem *, const QPoint &pos )
+{
+ KPopupMenu menu;
+ menu.insertTitle( i18n( "Icon Size" ) );
+ menu.insertItem( i18n( "Large" ), (int)LargeIcons );
+ menu.setItemEnabled( (int)LargeIcons, mShowIcons );
+ menu.insertItem( i18n( "Normal" ), (int)NormalIcons );
+ menu.setItemEnabled( (int)NormalIcons, mShowIcons );
+ menu.insertItem( i18n( "Small" ), (int)SmallIcons );
+ menu.setItemEnabled( (int)SmallIcons, mShowIcons );
+
+ menu.setItemChecked( (int)mViewMode, true );
+ menu.insertSeparator();
+
+ menu.insertItem( i18n( "Show Icons" ), (int)ShowIcons );
+ menu.setItemChecked( (int)ShowIcons, mShowIcons );
+ menu.setItemEnabled( (int)ShowIcons, mShowText );
+ menu.insertItem( i18n( "Show Text" ), (int)ShowText );
+ menu.setItemChecked( (int)ShowText, mShowText );
+ menu.setItemEnabled( (int)ShowText, mShowIcons );
+ int choice = menu.exec( pos );
+
+ if ( choice == -1 )
+ return;
+
+ if ( choice >= SmallIcons ) {
+ mViewMode = sizeIntToEnum( choice );
+ Prefs::self()->setSidePaneIconSize( choice );
+ } else {
+ // either icons or text were toggled
+ if ( choice == ShowIcons ) {
+ mShowIcons = !mShowIcons;
+ Prefs::self()->setSidePaneShowIcons( mShowIcons );
+ QToolTip::remove( this );
+ if ( !mShowText )
+ new EntryItemToolTip( this );
+ } else {
+ mShowText = !mShowText;
+ Prefs::self()->setSidePaneShowText( mShowText );
+ QToolTip::remove( this );
+ }
+ }
+ int maxWidth = 0;
+ QListBoxItem* it = 0;
+ for (int i = 0; (it = item(i)) != 0; ++i)
+ {
+ int width = it->width(this);
+ if (width > maxWidth)
+ maxWidth = width;
+ }
+ parentWidget()->setFixedWidth( maxWidth );
+
+ triggerUpdate( true );
+}
+
+void Navigator::shortCutSelected( int pos )
+{
+ setCurrentItem( pos );
+}
+
+void Navigator::setHoverItem( QListBoxItem* item, bool hover )
+{
+ static_cast<EntryItem*>( item )->setHover( hover );
+ updateItem( item );
+}
+
+void Navigator::setPaintActiveItem( QListBoxItem* item, bool paintActive )
+{
+ static_cast<EntryItem*>( item )->setPaintActive( paintActive );
+ updateItem( item );
+}
+
+void Navigator::slotMouseOn( QListBoxItem* newItem )
+{
+ QListBoxItem* oldItem = mMouseOn;
+ if ( oldItem == newItem ) return;
+
+ if ( oldItem && !oldItem->isCurrent() && !oldItem->isSelected() )
+ {
+ setHoverItem( oldItem, false );
+ }
+
+ if ( newItem && !newItem->isCurrent() && !newItem->isSelected() )
+ {
+ setHoverItem( newItem, true );
+ }
+ mMouseOn = newItem;
+}
+
+void Navigator::slotMouseOff()
+{
+ slotMouseOn( 0 );
+}
+
+IconSidePane::IconSidePane( Core *core, QWidget *parent, const char *name )
+ : SidePaneBase( core, parent, name )
+{
+ mNavigator = new Navigator( this );
+ connect( mNavigator, SIGNAL( pluginActivated( Kontact::Plugin* ) ),
+ SIGNAL( pluginSelected( Kontact::Plugin* ) ) );
+
+ setAcceptDrops( true );
+}
+
+IconSidePane::~IconSidePane()
+{
+}
+
+void IconSidePane::updatePlugins()
+{
+ mNavigator->updatePlugins( core()->pluginList() );
+}
+
+void IconSidePane::selectPlugin( Kontact::Plugin *plugin )
+{
+ bool blocked = signalsBlocked();
+ blockSignals( true );
+
+ for ( uint i = 0; i < mNavigator->count(); ++i ) {
+ EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
+ if ( item->plugin() == plugin ) {
+ mNavigator->setCurrentItem( i );
+ break;
+ }
+ }
+
+ blockSignals( blocked );
+}
+
+void IconSidePane::selectPlugin( const QString &name )
+{
+ bool blocked = signalsBlocked();
+ blockSignals( true );
+
+ for ( uint i = 0; i < mNavigator->count(); ++i ) {
+ EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
+ if ( item->plugin()->identifier() == name ) {
+ mNavigator->setCurrentItem( i );
+ break;
+ }
+ }
+
+ blockSignals( blocked );
+}
+
+void IconSidePane::indicateForegrunding( Kontact::Plugin *plugin )
+{
+ for ( uint i = 0; i < mNavigator->count(); ++i ) {
+ EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
+ if ( item->plugin() == plugin ) {
+ mNavigator->highlightItem( item );
+ break;
+ }
+ }
+
+
+}
+#include "iconsidepane.moc"
+
+// vim: sw=2 sts=2 et tw=80
diff --git a/kontact/src/iconsidepane.h b/kontact/src/iconsidepane.h
new file mode 100644
index 000000000..281d25aec
--- /dev/null
+++ b/kontact/src/iconsidepane.h
@@ -0,0 +1,193 @@
+/*
+ This file is part of the KDE Kontact.
+
+ Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef KONTACT_ICONSIDEPANEBASE_H
+#define KONTACT_ICONSIDEPANEBASE_H
+
+#include <qtooltip.h>
+
+#include <klistbox.h>
+
+#include "sidepanebase.h"
+#include "prefs.h"
+
+
+class QSignalMapper;
+
+namespace KParts { class Part; }
+
+namespace Kontact
+{
+
+class Core;
+class Plugin;
+class Navigator;
+
+enum IconViewMode { LargeIcons = 48, NormalIcons = 32, SmallIcons = 22, ShowText = 3, ShowIcons = 5 };
+
+
+/**
+ A QListBoxPixmap Square Box with an optional icon and a text
+ underneath.
+*/
+class EntryItem : public QListBoxItem
+{
+ public:
+ EntryItem( Navigator *, Kontact::Plugin * );
+ ~EntryItem();
+
+ Kontact::Plugin *plugin() const { return mPlugin; }
+
+ const QPixmap *pixmap() const { return &mPixmap; }
+
+ Navigator* navigator() const;
+
+ void setHover( bool );
+ void setPaintActive( bool );
+ bool paintActive() const { return mPaintActive; }
+ /**
+ returns the width of this item.
+ */
+ virtual int width( const QListBox * ) const;
+ /**
+ returns the height of this item.
+ */
+ virtual int height( const QListBox * ) const;
+
+ protected:
+ void reloadPixmap();
+
+ virtual void paint( QPainter *p );
+
+ private:
+ Kontact::Plugin *mPlugin;
+ QPixmap mPixmap;
+ bool mHasHover;
+ bool mPaintActive;
+};
+
+/**
+ * Tooltip that changes text depending on the item it is above.
+ * Compliments of "Practical Qt" by Dalheimer, Petersen et al.
+ */
+class EntryItemToolTip : public QToolTip
+{
+ public:
+ EntryItemToolTip( QListBox* parent )
+ : QToolTip( parent->viewport() ), mListBox( parent )
+ {}
+ protected:
+ void maybeTip( const QPoint& p ) {
+ // We only show tooltips when there are no texts shown
+ if ( Prefs::self()->sidePaneShowText() ) return;
+ if ( !mListBox ) return;
+ QListBoxItem* item = mListBox->itemAt( p );
+ if ( !item ) return;
+ const QRect itemRect = mListBox->itemRect( item );
+ if ( !itemRect.isValid() ) return;
+
+ const EntryItem *entryItem = static_cast<EntryItem*>( item );
+ QString tipStr = entryItem->text();
+ tip( itemRect, tipStr );
+ }
+ private:
+ QListBox* mListBox;
+};
+
+/**
+ Navigation pane showing all parts relevant to the user
+*/
+class Navigator : public KListBox
+{
+ Q_OBJECT
+ public:
+ Navigator( SidePaneBase *parent = 0, const char *name = 0 );
+
+ virtual void setSelected( QListBoxItem *, bool );
+
+ void updatePlugins( QValueList<Kontact::Plugin*> plugins );
+
+ QSize sizeHint() const;
+
+ void highlightItem( EntryItem* item );
+
+ IconViewMode viewMode() { return mViewMode; }
+ IconViewMode sizeIntToEnum(int size) const;
+ const QPtrList<KAction> & actions() { return mActions; }
+ bool showIcons() const { return mShowIcons; }
+ bool showText() const { return mShowText; }
+ signals:
+ void pluginActivated( Kontact::Plugin * );
+
+ protected:
+ void dragEnterEvent( QDragEnterEvent * );
+ void dragMoveEvent ( QDragMoveEvent * );
+ void dropEvent( QDropEvent * );
+ void resizeEvent( QResizeEvent * );
+ void enterEvent( QEvent* );
+ void leaveEvent( QEvent* );
+
+ void setHoverItem( QListBoxItem*, bool );
+ void setPaintActiveItem( QListBoxItem*, bool );
+
+ protected slots:
+ void slotExecuted( QListBoxItem * );
+ void slotMouseOn( QListBoxItem *item );
+ void slotMouseOff();
+ void slotShowRMBMenu( QListBoxItem *, const QPoint& );
+ void shortCutSelected( int );
+ void slotStopHighlight();
+
+ private:
+ SidePaneBase *mSidePane;
+ IconViewMode mViewMode;
+
+ QListBoxItem* mMouseOn;
+
+ EntryItem* mHighlightItem;
+
+ QSignalMapper *mMapper;
+ QPtrList<KAction> mActions;
+ bool mShowIcons;
+ bool mShowText;
+};
+
+class IconSidePane : public SidePaneBase
+{
+ Q_OBJECT
+ public:
+ IconSidePane( Core *core, QWidget *parent, const char *name = 0 );
+ ~IconSidePane();
+
+ virtual void indicateForegrunding( Kontact::Plugin* );
+
+ public slots:
+ virtual void updatePlugins();
+ virtual void selectPlugin( Kontact::Plugin* );
+ virtual void selectPlugin( const QString &name );
+ const QPtrList<KAction> & actions() { return mNavigator->actions(); }
+
+ private:
+ Navigator *mNavigator;
+};
+
+}
+
+#endif
diff --git a/kontact/src/kcmkontact.cpp b/kontact/src/kcmkontact.cpp
new file mode 100644
index 000000000..0c518d5c8
--- /dev/null
+++ b/kontact/src/kcmkontact.cpp
@@ -0,0 +1,152 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include "kcmkontact.h"
+#include "prefs.h"
+
+
+#include <kaboutdata.h>
+#include <kdebug.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <ktrader.h>
+
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+
+#include <kdepimmacros.h>
+
+extern "C"
+{
+ KDE_EXPORT KCModule *create_kontactconfig( QWidget *parent, const char * ) {
+ return new KcmKontact( parent, "kcmkontact" );
+ }
+}
+
+class PluginItem : public QListViewItem
+{
+ public:
+ PluginItem( QListView *parent, const KService::Ptr &ptr )
+ : QListViewItem( parent, ptr->name(), ptr->comment(), ptr->library() ),
+ mPtr( ptr )
+ {
+ }
+
+ KService::Ptr servicePtr() const
+ {
+ return mPtr;
+ }
+
+ private:
+ KService::Ptr mPtr;
+};
+
+KcmKontact::KcmKontact( QWidget *parent, const char *name )
+ : KPrefsModule( Kontact::Prefs::self(), parent, name )
+{
+ QBoxLayout *topLayout = new QVBoxLayout( this );
+ QBoxLayout *pluginStartupLayout = new QHBoxLayout( topLayout );
+ topLayout->addStretch();
+
+ KPrefsWidBool *forceStartupPlugin = addWidBool( Kontact::Prefs::self()->forceStartupPluginItem(), this );
+ pluginStartupLayout->addWidget( forceStartupPlugin->checkBox() );
+
+ PluginSelection *selection = new PluginSelection( Kontact::Prefs::self()->forcedStartupPluginItem(), this );
+ addWid( selection );
+
+ pluginStartupLayout->addWidget( selection->comboBox() );
+ selection->comboBox()->setEnabled( false );
+
+ connect( forceStartupPlugin->checkBox(), SIGNAL( toggled( bool ) ),
+ selection->comboBox(), SLOT( setEnabled( bool ) ) );
+ load();
+}
+
+const KAboutData* KcmKontact::aboutData() const
+{
+ KAboutData *about = new KAboutData( I18N_NOOP( "kontactconfig" ),
+ I18N_NOOP( "KDE Kontact" ),
+ 0, 0, KAboutData::License_GPL,
+ I18N_NOOP( "(c), 2003 Cornelius Schumacher" ) );
+
+ about->addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
+ about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" );
+
+ return about;
+}
+
+
+PluginSelection::PluginSelection( KConfigSkeleton::ItemString *item, QWidget *parent )
+{
+ mItem = item;
+ mPluginCombo = new QComboBox( parent );
+ connect( mPluginCombo, SIGNAL( activated( int ) ), SIGNAL( changed() ) );
+}
+
+PluginSelection::~PluginSelection()
+{
+}
+
+void PluginSelection::readConfig()
+{
+ const KTrader::OfferList offers = KTrader::self()->query(
+ QString::fromLatin1( "Kontact/Plugin" ),
+ QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );
+
+ int activeComponent = 0;
+ mPluginCombo->clear();
+ for ( KService::List::ConstIterator it = offers.begin(); it != offers.end(); ++it ) {
+ KService::Ptr service = *it;
+ // skip summary only plugins
+ QVariant var = service->property( "X-KDE-KontactPluginHasPart" );
+ if ( var.isValid() && var.toBool() == false )
+ continue;
+ mPluginCombo->insertItem( service->name() );
+ mPluginList.append( service );
+
+ if ( service->property("X-KDE-PluginInfo-Name").toString() == mItem->value() )
+ activeComponent = mPluginList.count() - 1;
+ }
+
+ mPluginCombo->setCurrentItem( activeComponent );
+}
+
+void PluginSelection::writeConfig()
+{
+ KService::Ptr ptr = *( mPluginList.at( mPluginCombo->currentItem() ) );
+ mItem->setValue( ptr->property("X-KDE-PluginInfo-Name").toString() );
+}
+
+QValueList<QWidget *> PluginSelection::widgets() const
+{
+ QValueList<QWidget *> widgets;
+ widgets.append( mPluginCombo );
+
+ return widgets;
+}
+
+#include "kcmkontact.moc"
diff --git a/kontact/src/kcmkontact.h b/kontact/src/kcmkontact.h
new file mode 100644
index 000000000..3b37f68f5
--- /dev/null
+++ b/kontact/src/kcmkontact.h
@@ -0,0 +1,69 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2003 Cornelius Scumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef KCMKONTACT_H
+#define KCMKONTACT_H
+
+#include <kprefsdialog.h>
+#include <kservice.h>
+#include "plugin.h"
+
+class QGroupBox;
+class QComboBox;
+class QListViewItem;
+
+class KAboutData;
+class KListView;
+
+class KcmKontact : public KPrefsModule
+{
+ Q_OBJECT
+
+ public:
+ KcmKontact( QWidget *parent = 0, const char *name = 0 );
+
+ virtual const KAboutData* aboutData() const;
+};
+
+class PluginSelection : public KPrefsWid
+{
+ Q_OBJECT
+
+ public:
+ PluginSelection( KConfigSkeleton::ItemString *item, QWidget *parent );
+ ~PluginSelection();
+
+ void readConfig();
+ void writeConfig();
+
+ QValueList<QWidget *> widgets() const;
+ QComboBox *comboBox() const { return mPluginCombo; }
+
+ private:
+ QComboBox *mPluginCombo;
+ QValueList<KService::Ptr> mPluginList;
+ KConfigSkeleton::ItemString *mItem;
+};
+
+#endif
diff --git a/kontact/src/kontact.kcfg b/kontact/src/kontact.kcfg
new file mode 100644
index 000000000..e8ae4eef1
--- /dev/null
+++ b/kontact/src/kontact.kcfg
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="kontactrc"/>
+
+ <group name="View">
+ <entry type="String" name="ActivePlugin">
+ <default>kontact_summaryplugin</default>
+ </entry>
+ <entry type="Bool" name="ForceStartupPlugin">
+ <default>false</default>
+ <label>Always start with specified component:</label>
+ <whatsthis>Usually Kontact will come up with the component used before shutdown. Check this box if you would like a specific component to come up on start instead.</whatsthis>
+ </entry>
+ <entry type="String" name="ForcedStartupPlugin">
+ </entry>
+
+ <entry type="IntList" name="SidePaneSplitter">
+ <default>1</default>
+ </entry>
+
+ <entry type="Int" name="SidePaneIconSize">
+ <default>32</default>
+ </entry>
+ <entry type="Bool" name="SidePaneShowIcons"><default>true</default></entry>
+ <entry type="Bool" name="SidePaneShowText"><default>true</default></entry>
+ <entry type="String" name="LastVersionSeen">
+ </entry>
+ </group>
+</kcfg>
diff --git a/kontact/src/kontact.setdlg b/kontact/src/kontact.setdlg
new file mode 100644
index 000000000..a90778a21
--- /dev/null
+++ b/kontact/src/kontact.setdlg
@@ -0,0 +1,646 @@
+[KontactSummary]
+Name=Summary View
+Name[bg]=Обобщение
+Name[ca]=Vista de resum
+Name[da]=Opsummeringsvisning
+Name[de]=Übersicht
+Name[el]=Προβολή σύνοψης
+Name[es]=Vista de resumen
+Name[et]=Kokkuvõttevaade
+Name[fr]=Vue résumée
+Name[is]=Yfirlitssýn
+Name[it]=Vista sommario
+Name[ja]=要約ビュー
+Name[km]=ទិដ្ឋភាព​សង្ខេប
+Name[nds]=Översicht
+Name[nl]=Overzichtsweergave
+Name[pl]=Podsumowanie
+Name[ru]=Просмотр сводок
+Name[sr]=Приказ сажетка
+Name[sr@Latn]=Prikaz sažetka
+Name[sv]=Översiktsvy
+Name[tr]=Özet Görünümü
+Name[zh_CN]=摘要视图
+Name[zh_TW]=摘要檢視
+Comment=Configuration of Kontact's <b>Summary View</b>. Some plugins provide <i>Summary View</i> items, choose the ones you would like to list.
+Comment[bg]=Настройване на <b>Обобщение</b> на Kontact. Някои приставки предлагат <i>обобщение</i>, изберете тези, които искате да използвате.
+Comment[ca]=Configuració de la <b>vista de resum</b> del Kontact. Alguns endollables proporcionen elements de <i>vista de resum</i>, trieu-ne els que voldríeu llistar.
+Comment[da]=Konfiguration af Kontacts <b>Opsummeringsvisning</b>. Nogle plugins giver <i>Opsummeringsvisning</i>-elementer, vælg dem du ønsker på listen.
+Comment[de]=Einrichtung der <b>Zusammenfassungsansicht</b> von Kontact. Einige Kontact-Module stellen Elemente für die <i>Zusammenfassungsansicht</i> zur Verfügung. Wählen Sie hier, welche Elemente angezeigt werden sollen.
+Comment[el]=Ρύθμιση της <b>Προβολής σύνοψης</b> του Kontact. Κάποια πρόσθετα παρέχουν αντικείμενα <i>Προβολή σύνοψης</i>· επιλέξτε αυτά που θέλετε να εμφανίζονται.
+Comment[es]=Configuración de Kontact <b>Vista de resumen</b>. Algunos complementos proveen elementos para la <i>Vista de resumen</i>, elija los que quiera listar.
+Comment[et]=Kontacti <b>kokkuvõttevaate</b> seadistamine. Mõned pluginad pakuvad <i>kokkuvõttevaate</i> elemente. Vali nimekirjas need, mida soovid näha.
+Comment[fr]=Configuration de Kontact <b> Vue résumée</b>. Certains modules fournissent des éléments de <i>Vue Résumée</i>, choisissez ceux que vous voulez voir listés.
+Comment[is]=Stillingar á <b>Yfirlitssýn</b>í Kontact. Sum íforrit koma með hluti í <i>Yfirlitssýn</i>, veldu þá sem þú vilt hafa á síðunni.
+Comment[it]=Configurazione della <b>vista sommario</b> di Kontact. Alcuni plugin forniscono elementi di <i>vista sommario</i>, scegli quelli che desideri vedere nell'elenco.
+Comment[ja]=Kontact の要約ビューの設定。要約ビューの項目を提供するプラグインがいくつかあります。要約ビューに表示させる項目を選択してください。
+Comment[km]=កា​រកំណត់​រចនាសម្ព័ន្ធ​របស់ Kontact <b>ទិដ្ឋភាព​សង្ខេប</b> ។ កម្មវិធី​ជំនួយ​មួយ​ចំនួនផ្ដល់​នូវ​ធាតុ<i>ទិដ្ឋភាព​សង្ខេប</i> ជ្រើស​ទិដ្ឋភាព​មួយ​ក្នុង​ចំណោម​ទិដ្ឋភាព​ទាំងនេះ​ដែល​អ្នក​ចង់​រាយ ។
+Comment[nds]=Kontact sien <b>Översicht</b> instellen. En Reeg Modulen stellt Indrääg för de <i>Översicht</i> praat. Hier kannst Du de utsöken, de Du hebben wullt.
+Comment[nl]=Configuratie van Kontacts <b>Overzichtsweergave</b>. Sommige plugins bieden ook items aan voor de <i>Overzichtweergave</i>, kies welke u wilt zien.
+Comment[pl]=Konfiguracja <b>Podsumowania</b> Kontaktu. Niektóre wtyczki zapewniają elementy <i>Widok podsumowania</i>, wybierz te które chcesz zobaczyć.
+Comment[ru]=Настройка показа сводок различных компонентов.
+Comment[sr]=Подешавање Kontact-овог <b>приказа сажетка</b>. Неки прикључци дају ставке <i>приказа сажетка</i>, изаберите оне које желите.
+Comment[sr@Latn]=Podešavanje Kontact-ovog <b>prikaza sažetka</b>. Neki priključci daju stavke <i>prikaza sažetka</i>, izaberite one koje želite.
+Comment[sv]=Inställning av Kontacts <b>översiktsvy</b>. Vissa insticksprogram tillhandahåller objekt för <i>översiktsvyn</i>. Välj de du skulle vilja visa.
+Comment[zh_CN]=Kontact <b>摘要视图</b>配置。有些插件提供了<i>摘要视图</i>项目,请选择您希望出现在列表中的项目。
+Comment[zh_TW]=設定 Kontact 的摘要檢視。有些外掛程式會提供「摘要檢視」的項目,您可以選取您要列出的項目。
+Weight=100
+Icon=kontact_summary
+
+[KMail]
+Name=E-Mail
+Name[bg]=Е-поща
+Name[ca]=Correu
+Name[da]=E-mail
+Name[el]=Αλληλογραφία
+Name[es]=Correo electrónico
+Name[et]=E-post
+Name[fr]=Courriel
+Name[is]=Tölvupóstur
+Name[it]=Posta elettronica
+Name[ja]=メール
+Name[km]=អ៊ីមែល
+Name[nds]=Nettpost
+Name[nl]=E-mail
+Name[pl]=E-mail
+Name[pt_BR]=E-mail
+Name[ru]=Электронная почта
+Name[sk]=Pošta
+Name[sr]=Е-пошта
+Name[sr@Latn]=E-pošta
+Name[sv]=E-post
+Name[tr]=E-Posta
+Name[zh_CN]=邮件
+Name[zh_TW]=電子郵件
+Comment=Configuration of Kontact's E-Mail Plugin <b>KMail</b>, includes a <i>Summary View Item</i> and represents a <i>Kontact Component</i>.
+Comment[bg]=Настройване на приставката за <b>KMail</b> в Kontact, включително обобщението и компонента.
+Comment[ca]=Configuració de l'endollable de correu <b>KMail</b> del Kontact, inclou un <i>element de vista de resum</i> i representa un <i>component del Kontact</i>.
+Comment[da]=Konfiguration af Kontacts e-mail-plugin <b>KMail</b>, inkluderer et <i>Opsummeringsvisnings-element</i> og repræsenterer en <i>Kontact-komponent</i>.
+Comment[de]=Einrichtung des E-Mail-Moduls <b>KMail</b> für Kontact. Die E-Mail-Komponente kann als <i>Kontact-Komponente<i> in die <i>Zusammenfassungsansicht</i> integriert werden.
+Comment[el]=Η ρύθμιση του προσθέτου αλληλογραφίας <b>KMail</b> του Kontact, περιέχει ένα <i>Αντικείμενο προβολής σύνοψης</i> και αντιπροσωπεύει ένα <i>Συστατικό του Kontact</i>.
+Comment[es]=Configuración del complemento de correo-e de Kontact <b>KMail</b>, incluye una <i>Vista de resumen</i> y representa un <i>Componente de Kontact</i>.
+Comment[et]=Kontacti e-posti plugina <b>KMaili</b> seadistamine, mis sisaldab <i>kokkuvõttevaate elementi</i>.
+Comment[fr]=Configuration du Module de Courriel de Kontact <b>KMail</b>, inclut un <i>Élément de Vue Résumée</i> et correspond à un <i>Composant de Kontact</i>.
+Comment[is]=Stillingar fyrir tölvupóstíforrit Kontact <b>KMail</b>, inniheldur <i>yfirlitssýnarhlut</i> sem stendur fyrir <i>Kontact einingu</i>.
+Comment[it]=Configurazione del plugin di posta elettronica <b>KMail</b> di Kontact, include una <i>vista sommario</i> e rappresenta un <i>componente Kontact</i>.
+Comment[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​របស់​កម្មវិធី​ជំនួយ​​អ៊ីមែល​របស់ Kontact​ <b>KMail</b> រួម​មាន<i>ធាតុ​ទិដ្ឋភាព​សង្ខេប</i> និង​បង្ហាញ <i>សមាសភាគ Kontact​</i> ។
+Comment[nds]=Kontact sien Nettpost-Moduul <b>KMail</b> instellen. Stellt en <i>Översicht-Indrag</i> praat un is en <i>Kontact-Komponent</i>.
+Comment[nl]=Instellingen voor Kontacts e-mailplugin <b>KMail</b>. Bevat een <i>Overzichtsweergaveplugin</i> en een <i>Kontact-component</i>.
+Comment[pl]=Konfiguracja wtyczki poczty Kontaktu <b>KMail</b>, zawiera <i>element Podsumowanie</i> i jest <i>Składnikiem Kontaktu</i>.
+Comment[ru]=Настройка модуля электронной почты <b>KMail</b> для показа в виде сводки.
+Comment[sr]=Подешавање Kontact-овог прикључка за е-пошту преко <b>KMail-</b>, укључујући <i>приказ сажетка</i>, и дат као <i>компонента Kontact-а</i>.
+Comment[sr@Latn]=Podešavanje Kontact-ovog priključka za e-poštu preko <b>KMail-</b>, uključujući <i>prikaz sažetka</i>, i dat kao <i>komponenta Kontact-a</i>.
+Comment[sv]=Inställning av Kontacts e-postinsticksprogram <b>Kmail</b>, omfattar ett objekt för <i>översiktsvyn</i> och representerar en <i>Kontactkomponent</i>.
+Comment[zh_CN]=Kontact <b>KMail</b> 电子邮件插件配置,其中包含一个<i>摘要视图项目,以 <i>Kontact 组件</i>形式呈现。
+Comment[zh_TW]=設定 Kontact 的電子郵件組件。
+Weight=200
+Icon=kontact_mail
+
+[KAB]
+Name=Contacts
+Name[af]=Kontakte
+Name[ar]=المراسلون
+Name[be]=Кантакты
+Name[bg]=Контакти
+Name[br]=Darempredoù
+Name[bs]=Kontakti
+Name[ca]=Contactes
+Name[cs]=Kontakty
+Name[cy]=Cysylltau
+Name[da]=Kontakter
+Name[de]=Kontakte
+Name[el]=Επαφές
+Name[eo]=Kontaktoj
+Name[es]=Contactos
+Name[et]=Kontaktid
+Name[eu]=Kontaktuak
+Name[fa]=تماسها
+Name[fi]=Yhteystiedot
+Name[fy]=Adressen
+Name[ga]=Teagmhálacha
+Name[gl]=Contactos
+Name[he]=אנשי קשר
+Name[hi]=सम्पर्कों
+Name[hu]=Névjegyek
+Name[is]=Tengiliðir
+Name[it]=Contatti
+Name[ja]=コンタクト
+Name[ka]=კონტაქტები
+Name[kk]=Контакттар
+Name[km]=ទំនាក់ទំនង
+Name[lt]=Kontaktai
+Name[mk]=Контакти
+Name[ms]=Orang hubungan
+Name[nds]=Kontakten
+Name[ne]=सम्पर्क
+Name[nl]=Adressen
+Name[nn]=Kontaktar
+Name[pa]=ਸੰਪਰਕ
+Name[pl]=Wizytówki
+Name[pt]=Contactos
+Name[pt_BR]=Contatos
+Name[ro]=Contacte
+Name[ru]=Контакты
+Name[rw]=Amaderesi
+Name[se]=Oktavuođat
+Name[sk]=Kontakty
+Name[sl]=Stiki
+Name[sr]=Контакти
+Name[sr@Latn]=Kontakti
+Name[sv]=Kontakter
+Name[ta]=தொடர்புகள்
+Name[tg]=Алоқот
+Name[th]=ที่อยู่ติดต่อ
+Name[tr]=Kişiler
+Name[uk]=Контакти
+Name[uz]=Aloqalar
+Name[uz@cyrillic]=Алоқалар
+Name[zh_CN]=联系人
+Name[zh_TW]=聯絡人
+Comment=Configuration of Kontact's Adress Book Plugin <b>KAdressbook</b> which represents a <i>Kontact Component</i>.
+Comment[bg]=Настройване на приставката за <b>KAdressbook</b> в Kontact, включително компонента.
+Comment[ca]=Configuració de l'endollable de la llibreta d'adreces <b>KAdressbook</b> del Kontact, que representa un <i>component del Kontact</i>.
+Comment[da]=Konfiguration af Kontacts adressebog-plugin <b>KAdressbook</b> som repræsenterer en <i>Kontact-komponent</i>.
+Comment[de]=Einrichtung des Adressbuch-Moduls für Kontact, welches eine <i>Kontact-Komponente</i> repräsentiert.
+Comment[el]=Ρύθμιση του πρόσθετου βιβλίου διευθύνσεων <b>KAdressbook</b> του Kontact που αντιπροσωπεύει ένα <i>Συστατικό του Kontact</i>.
+Comment[es]=Configuración del complemento de libreta de direcciones de Kontact <b> KAddressbok</b>, el cual representa un <i>Componente de Kontact</i>.
+Comment[et]=Kontacti aadressiraamatu plugina <b>KAdressbook</b> seaditamine.
+Comment[fr]=Configuration du Module de Carnet d'Adresses de Kontact <b> KAdressbook</b> qui correspond à un <i>Composant de Kontact</i>.
+Comment[is]=Stillingar fyrir vistfangaskráríforrit Kontact <b>KAdressbook</b>, inniheldur <i>yfirlitssýnarhlut</i> sem stendur fyrir <i>Kontact einingu</i>.
+Comment[it]=Configurazione del plugin rubrica di <b>KAddressbook</b> che rappresenta un <i>componente Kontact</i>.
+Comment[km]=កា​រកំណត់​រចនាសម្ព័ន្ធ​របស់​កម្មវិធី​ជំនួយ​សៀវភៅ​អាសយដ្ឋាន​របស់ Kontact <b>KAdressbook</b> ដែល​បង្ហាញ <i>សមាសភាគ Kontact​</i> ។
+Comment[nds]=Kontact sien Adressbook-Moduul <b>KAddressbook</b> instellende, dat en <i>Kontact-Komponent</i> is.
+Comment[nl]=Instellingen voor Kontacts adresboekplugin <b>KMail</b>. Bevat een <i>Kontact-component</i>.
+Comment[pl]=Konfiguracja wtyczki książki adresowej Kontaktu <b>KAddressBook</b>, która jest <i>Składnikiem Kontaktu</i>.
+Comment[ru]=Настройка модуля адресной книги <b>KAdressbook</b> для показа в виде сводки.
+Comment[sr]=Подешавање Kontact-овог прикључка за адресар преко <b>KAdressbook</b> у облику <i>компоненте Kontact-а</i>.
+Comment[sr@Latn]=Podešavanje Kontact-ovog priključka za adresar preko <b>KAdressbook</b> u obliku <i>komponente Kontact-a</i>.
+Comment[sv]=Inställning av Kontacts adressboksinsticksprogram <b>Kaddressbook</b>, som representerar en <i>Kontactkomponent</i>.
+Comment[zh_CN]=Kontact <b>KAdressbook</b> 地址簿插件配置,KAdressbook 以一个<i>Kontact 组件</i>形式呈现。
+Comment[zh_TW]=設定 Kontact 的通訊錄組件。
+Weight=300
+Icon=kontact_contacts
+
+[Special Dates]
+Name=Special Dates Summary
+Name[af]=Spesiale datums opsomming
+Name[ar]=موجز عن التواريخ المرموقة
+Name[bg]=Обобщение на специални случаи
+Name[ca]=Resum de dates especials
+Name[cs]=Souhrn speciálních datumů
+Name[da]=Opsummering af særlige datoer
+Name[de]=Übersicht über besondere Termine
+Name[el]=Σύνοψη σημαντικών ημερομηνιών
+Name[eo]=Resumo pri Specialaj Datoj
+Name[es]=Resumen de fechas especiales
+Name[et]=Tähtpäevade kokkuvõte
+Name[eu]=Data berezien laburpena
+Name[fa]=خلاصۀ تاریخهای ویژه
+Name[fi]=Erikoispäivien yhteenveto
+Name[fr]=Résumé des dates particulières
+Name[fy]=Oersicht foar spesjale datums
+Name[gl]=Resumo de Datas Especiais
+Name[he]=תקציר תאריכים מיוחדים
+Name[hu]=A fontos dátumok áttekintője
+Name[is]=Yfirlit sérstakra daga
+Name[it]=Sommario date speciali
+Name[ja]=特別な日の要約
+Name[ka]=განსაკუთრებულ თარიღთა დაიჯესტი
+Name[kk]=Ерекше күндер тұжырымы
+Name[km]=សង្ខេប​ថ្ងៃ​ពិសេស
+Name[lt]=Ypatingų dienų santrauka
+Name[mk]=Преглед на специјални датуми
+Name[ms]=Ringkasan Tarikh Khusus
+Name[nb]=Sammendrag av spesielle datoer
+Name[nds]=Översicht över besünner Daag
+Name[ne]=विशेष मिति सारांश
+Name[nl]=Overzicht voor speciale data
+Name[nn]=Samandrag for spesielle datoar
+Name[pl]=Podsumowanie dat specjalnych
+Name[pt]=Sumário de Datas Especiais
+Name[pt_BR]=Resumo de Datas Especiais
+Name[ru]=Сводка особых дат
+Name[sk]=Súhrn špeciálnych dátumov
+Name[sl]=Povzetek posebnih datumov
+Name[sr]=Сажетак посебних датума
+Name[sr@Latn]=Sažetak posebnih datuma
+Name[sv]=Översikt av speciella datum
+Name[ta]=விசேஷ செய்திகளின் சுருக்கம்
+Name[th]=สรุปวันพิเศษ
+Name[tr]=Özel Tarihler Özeti
+Name[uk]=Короткий підсумок особливих дат
+Name[zh_CN]=特殊日期摘要
+Name[zh_TW]=特殊日期摘要
+Comment=Special Dates Summary Component
+Comment[af]=Spesiale datums opsomming komponent
+Comment[bg]=Модул за обобщение на специалните случаи
+Comment[ca]=Component pel resum de dates especials
+Comment[cs]=Komponenta souhrnu speciálních příležitostí
+Comment[da]=Opsummeringskomponent for særlige datoer
+Comment[de]=Komponente für Übersicht über besondere Termine
+Comment[el]=Στοιχείο σύνοψης Σημαντικών Ημερομηνιών
+Comment[eo]=Specialdatresuma Komponanto
+Comment[es]=Componente de resumen de fechas especiales
+Comment[et]=Tähtpäevade kokkuvõtte komponent
+Comment[eu]=Data berezien laburpenaren osagaia
+Comment[fa]=مؤلفۀ خلاصۀ تاریخهای ویژه
+Comment[fi]=Erikoispäivien yhteenvedon komponentti
+Comment[fr]=Composant de résumé des dates particulières
+Comment[fy]=Komponint foar oersicht fan spesjale datums
+Comment[gl]=Compoñente de Resumo de Datas Especiais
+Comment[he]=רכיב תאריכים חשובים
+Comment[hu]=A fontos dátumok áttekintő komponense
+Comment[is]=Yfirlitshluti sérstakra daga
+Comment[it]=Componente sommario per le date speciali
+Comment[ja]=特別な日の要約コンポーネント
+Comment[ka]=განაკუთრებულ თარიღთა დაიჯესტის კომპონენტი
+Comment[kk]=Ерекше күндер тұжырымының компоненті
+Comment[km]=សមាសភាគ​សង្ខេប​នៃ​ថ្ងៃ​ពិសេស
+Comment[lt]=Ypatingų dienų santraukos komponentas
+Comment[mk]=Компонента за преглед на специјални датуми
+Comment[ms]=Komponen Ringkasan Tarikh Khusus
+Comment[nb]=Komponent for sammendrag av spesielle datoer
+Comment[nds]=Översichtkomponent för besünner Daag
+Comment[ne]=विशेष मिति सारांश अवयव
+Comment[nl]=Component voor overzicht van speciale data
+Comment[nn]=Komponent for samandrag for spesielle datoar
+Comment[pl]=Składnik podsumowania dat specjalnych
+Comment[pt]=Componente de Sumário de Datas Especiais
+Comment[pt_BR]=Componente de Datas Especiais
+Comment[ru]=Компонент сводки особых дат
+Comment[sk]=Komponent súhrnu špeciálnych dátumov
+Comment[sl]=Komponenta za povzetke posebnih datumov
+Comment[sr]=Компонента сажетка посебних датума
+Comment[sr@Latn]=Komponenta sažetka posebnih datuma
+Comment[sv]=Komponent för översikt av speciella datum
+Comment[ta]=விசேஷ தேதிகள் சுருக்கப் பகுதி
+Comment[tr]=Özel Tarihler Özeti Bileşeni
+Comment[uk]=Компонент короткого підсумку особливих дат
+Comment[zh_CN]=特殊日期摘要组件
+Comment[zh_TW]=特殊日期摘要元件
+Weight=310
+Icon=cookie
+
+[KOrganizer]
+Name=Calendar
+Name[af]=Kalender
+Name[ar]=التقويم
+Name[be]=Каляндар
+Name[bg]=Календар
+Name[br]=Deiziadur
+Name[bs]=Kalendar
+Name[ca]=Calendari
+Name[cs]=Kalendář
+Name[cy]=Calendr
+Name[da]=Kalender
+Name[de]=Kalender
+Name[el]=Ημερολόγιο
+Name[eo]=Kalendaro
+Name[es]=Calendario
+Name[et]=Kalender
+Name[eu]=Egutegia
+Name[fa]=تقویم
+Name[fi]=Kalenteri
+Name[fr]=Calendrier
+Name[fy]=Aginda
+Name[ga]=Féilire
+Name[gl]=Calendario
+Name[he]=לוח שנה
+Name[hi]=कैलेन्डर
+Name[hu]=Naptár
+Name[is]=Dagatal
+Name[it]=Calendario
+Name[ja]=カレンダー
+Name[ka]=კალენდარი
+Name[kk]=Күнтізбе
+Name[km]=ប្រតិទិន
+Name[lt]=Kalendorius
+Name[mk]=Календар
+Name[ms]=Kalendar
+Name[nb]=Kalender
+Name[nds]=Kalenner
+Name[ne]=क्यालेन्डर
+Name[nl]=Agenda
+Name[nn]=Kalender
+Name[pa]=ਕੈਲੰਡਰ
+Name[pl]=Kalendarz
+Name[pt]=Calendário
+Name[pt_BR]=Calendário
+Name[ru]=Календарь
+Name[se]=Kaleandar
+Name[sk]=Kalendár
+Name[sl]=Koledar
+Name[sr]=Календар
+Name[sr@Latn]=Kalendar
+Name[sv]=Kalender
+Name[ta]=நாள்காட்டி
+Name[tg]=Тақвим
+Name[th]=บันทึกประจำวัน
+Name[tr]=Takvim
+Name[uk]=Календар
+Name[uz]=Kalendar
+Name[uz@cyrillic]=Календар
+Name[zh_CN]=日历
+Name[zh_TW]=行事曆
+Comment=Configuration of Kontact's Calendar Plugin <b>KOrganizer</b>, includes a <i>Summary View Item</i> and represents a <i>Kontact Component</i>.
+Comment[bg]=Настройване на приставката за <b>KOrganizer</b> в Kontact, включително <i>обобщението</i> и <i>компонента</i>.
+Comment[ca]=Configuració de l'endollable de calendari <b>KOrganizer</b> del Kontact, inclou un <i>element de vista de resum</i> i representa un <i>component del Kontact</i>.
+Comment[da]=Konfiguration af Kontacts kalender-plugin <b>KOrganizer</b>, inkluderer et <i>Opsummeringsvisningselement</i> og repræsenterer en <i>Kontact-komponent</i>.
+Comment[de]=Einrichtung des Kalender-Moduls <b>KOrganizer</b> für Kontact, einschließlich der <i>Zusammenfassungsansicht</i>; repräsentiert eine <i>Kontact-Komponente</i>
+Comment[el]=Η ρύθμιση του προσθέτου ημερολογίου του <b>KOrganizer</b> του Kontact, περιέχει ένα <i>Αντικείμενο προβολής σύνοψης</i> και αντιπροσωπεύει ένα <i>Συστατικό του Kontact</i>.
+Comment[es]=Configuración del complemento de calendario de Kontact, <b> KOrganizer</b>, incluye una <i>Vista de resumen</i> y representa un <i>Componente de Kontact</i>.
+Comment[et]=Kontacti kalendriplugina <b>KOrganizeri</b> seadistamine, mis sisaldab <i>kokkuvõttevaate elementi</i>.
+Comment[fr]=Configuration du Module de Calendrier de Kontact <b>KOrganizer</b>, inclut un <i>Élément de Vue Résumée</i> et correspond à un <i>Composant de Kontact</i>.
+Comment[is]=Stillingar fyrir dagatalsíforrit Kontact <b>KOrganizer</b>, inniheldur <i>yfirlitssýnarhlut</i> sem stendur fyrir <i>Kontact einingu</i>.
+Comment[it]=Configurazione del plugin calendario <b>KOrganizer</b> di Kontact, include una <i>vista sommario</i> e rappresenta un <i>componente Kontact</i>.
+Comment[km]=កា​រកំណត់​រចនាសម្ព័ន្ធ​របស់​កម្មវិធី​ជំនួយ​ប្រតិទិន​របស់ Kontact <b>KOrganizer</b>រួម​មាន <i>ធាតុទិដ្ឋភាព​សង្ខេប</i> និង​បង្ហាញ <i>សមាសភាគ​ Kontact​</i>.
+Comment[nds]=Kontact sien Kalenner-Moduul <b>KOrganizer</b> instellen. Stellt en <i>Översicht-Indrag</i> praat un is en <i>Kontact-Komponent</i>.
+Comment[nl]=Instellingen voor Kontacts agendaplugin <b>KOrganizer</b>. Bevat een <i>Overzichtsweergaveplugin</i> en een <i>Kontact-component</i>.
+Comment[pl]=Konfiguracja wtyczki kalendarza Kontaktu <b>KOrganizer</b>, zawiera <i>element Podsumowanie</i> i jest <i>Składnikiem Kontaktu</i>.
+Comment[ru]=Настройка модуля календаря <b>KOrganizer</b> для показа в виде сводки.
+Comment[sr]=Подешавање Kontact-овог прикључка за календар преко <b>KOrganizer-а</b>, укључујући <i>приказ сажетка</i>, и дат као <i>компонента Kontact-а</i>.
+Comment[sr@Latn]=Podešavanje Kontact-ovog priključka za kalendar preko <b>KOrganizer-a</b>, uključujući <i>prikaz sažetka</i>, i dat kao <i>komponenta Kontact-a</i>.
+Comment[sv]=Inställning av Kontacts kalenderinsticksprogram <b>Korganizer</b>, omfattar ett objekt för <i>översiktsvyn</i> och representerar en <i>Kontactkomponent</i>.
+Comment[zh_CN]=Kontact 日历插件配置,<b>KOrganizer</b> 包含一个<i>摘要视图项目</i>,以 <i>Kontact 组件</i>形式呈现。
+Comment[zh_TW]=設定 Kontact 的行事曆組件。
+Weight=400
+Icon=kontact_date
+
+[KNode]
+Name=News
+Name[af]=Nuus
+Name[ar]=الأخبار
+Name[be]=Навіны
+Name[bg]=Новини
+Name[br]=Keleier
+Name[bs]=Usenet
+Name[ca]=Notícies
+Name[cs]=Novinky
+Name[cy]=Newyddion
+Name[da]=Nyheder
+Name[de]=Usenet
+Name[el]=Νέα
+Name[eo]=Novaĵoj
+Name[es]=Noticias
+Name[et]=Uudisegrupid
+Name[eu]=Berriak
+Name[fa]=اخبار
+Name[fi]=Uutiset
+Name[fr]=Nouvelles
+Name[fy]=Nijs
+Name[ga]=Nuacht
+Name[gl]=Novas
+Name[he]=חדשות
+Name[hi]=समाचार
+Name[hu]=Hírek
+Name[is]=Fréttir
+Name[ja]=ニュース
+Name[ka]=სიახლეები
+Name[kk]=Жаңалықтар
+Name[km]=ព័ត៌មាន
+Name[lt]=Naujienos
+Name[mk]=Вести
+Name[ms]=Berita
+Name[nb]=Njus
+Name[nds]=Narichten
+Name[ne]=समाचार
+Name[nl]=Nieuws
+Name[nn]=Nyheiter
+Name[pa]=ਖ਼ਬਰਾਂ
+Name[pl]=Listy dyskusyjne
+Name[pt]=Notícias
+Name[pt_BR]=Notícias
+Name[ro]=Ştiri
+Name[ru]=Новости
+Name[se]=Ođđasat
+Name[sk]=Diskusné skupiny
+Name[sl]=Novice
+Name[sr]=Вести
+Name[sr@Latn]=Vesti
+Name[sv]=Nyheter
+Name[ta]=செய்திகள்
+Name[tg]=Ахборот
+Name[th]=ข่าว
+Name[tr]=Haberler
+Name[uk]=Новини
+Name[uz]=Yangiliklar
+Name[uz@cyrillic]=Янгиликлар
+Name[zh_CN]=新闻
+Name[zh_TW]=新聞
+Comment=Configuration of Kontact's News Plugin <b>KNode</b> which represents a <i>Kontact Component</i>.
+Comment[bg]=Настройване на приставката за <b>KNode</b> в Kontact, включително компонента.
+Comment[ca]=Configuració de l'endollable de notícies <b>KNode</b> del Kontact, que representa un <i>component del Kontact</i>.
+Comment[da]=Konfiguration af Kontacts nyheds-plugin <b>KNode</b> som repræsenterer en <i>Kontact-komponent</i>.
+Comment[de]=Einrichtung des News-Moduls <b>KNode</b> für Kontact; repräsentiert eine <i>Kontact-Komponente</i>
+Comment[el]=Ρύθμιση του πρόσθετου νέων <b>KNode</b> του Kontact που αντιπροσωπεύει ένα <i>Συστατικό του Kontact</i>.
+Comment[es]=Configuración del complemento de noticias de Kontact <b>KNode</b> , el cual representa un <i>Componente de Kontact</i>.
+Comment[et]=Kontacti uudisteplugina <b>KNode</b> seadistamine.
+Comment[fr]=Configuration du Module de Nouvelles de Kontact <b>KNode</b> qui correspond à un <i>Composant de Kontact</i>.
+Comment[is]=Stillingar fyrir fréttastraumsíforrit Kontact <b>KNode</b>, inniheldur <i>yfirlitssýnarhlut</i> sem stendur fyrir <i>Kontact einingu</i>.
+Comment[it]=Configurazione del plugin notizie <b>KNode</b> di Kontact, che rappresenta un <i>componente Kontact</i>.
+Comment[km]=កា​រកំណត់​រចនាសម្ព័ន្ធ​របស់​កម្មវិធី​ជំនួយ​ព័ត៌មាន​របស់ Kontact <b>KNode</b> ដែល​បង្ហាញ <i>សមាភាគ​​របស់ Kontact​</i>​ ។
+Comment[nds]=Kontact sien Narichten-Moduul <b>KNode</b> instellen, dat en <i>Kontact-Komponent</i> is.
+Comment[nl]=Instellingen voor Kontacts nieuwsplugin <b>KNode</b>. Bevat een <i>Kontact-component</i>.
+Comment[pl]=Konfiguracja wtyczki wiadomości Kontaktu <b>KNode</b>, która jest <i>składnikiem Kontaktu</i>.
+Comment[ru]=Настройка модуля новостей <b>KNode</b> для показа в виде сводки.
+Comment[sr]=Подешавање Kontact-овог прикључка за вести преко <b>KNode-а</b> у облику <i>компненте Kontact-а</i>.
+Comment[sr@Latn]=Podešavanje Kontact-ovog priključka za vesti preko <b>KNode-a</b> u obliku <i>kompnente Kontact-a</i>.
+Comment[sv]=Inställning av Kontacts nyhetsinsticksprogram <b>Knode</b>, som representerar en <i>Kontactkomponent</i>.
+Comment[zh_CN]=Kontact 新闻组插件配置,<b>KNode</b> 以一个 <i>Kontact 组件</i>形式呈现。
+Comment[zh_TW]=設定 Kontact 的新聞組件。
+Weight=500
+Icon=kontact_news
+
+[KWeather]
+Name=Weather
+Name[af]=Weer
+Name[ar]=الطقس
+Name[be]=Надвор'е
+Name[bg]=Време
+Name[br]=Amzer
+Name[bs]=Vrijeme
+Name[ca]=Temps
+Name[cs]=Počasí
+Name[cy]=Tywydd
+Name[da]=Vejr
+Name[de]=Wetter
+Name[el]=Καιρός
+Name[eo]=Vetero
+Name[es]=Meteorología
+Name[et]=Ilm
+Name[eu]=Eguraldia
+Name[fa]=آب و هوا
+Name[fi]=Sää
+Name[fr]=Météo
+Name[fy]=It waar
+Name[ga]=Aimsir
+Name[gl]=O Tempo
+Name[he]=מזג אוויר
+Name[hi]=वेदर
+Name[hu]=Időjárás
+Name[is]=Veður
+Name[it]=Tempo meteorologico
+Name[ja]=気象情報
+Name[ka]=ამინდი
+Name[kk]=Ауа райы
+Name[km]=អាកាសធាតុ
+Name[lt]=Orų pranešėjas
+Name[mk]=Време
+Name[ms]=Cuaca
+Name[nb]=Været
+Name[nds]=Weder
+Name[ne]=मौसम
+Name[nl]=Het weer
+Name[nn]=Vêrmelding
+Name[pl]=Pogoda
+Name[pt]=Meteorologia
+Name[pt_BR]=Tempo
+Name[ro]=Vreme
+Name[ru]=Погода
+Name[se]=Dáldedieđáhus
+Name[sk]=Počasie
+Name[sl]=Vreme
+Name[sr]=Време
+Name[sr@Latn]=Vreme
+Name[sv]=Väder
+Name[ta]=வானிலை
+Name[tg]=Пешгӯии ҳаво
+Name[th]=รายงานอากาศ
+Name[tr]=Hava Durumu
+Name[uk]=Погода
+Name[uz]=Ob-havo
+Name[uz@cyrillic]=Об-ҳаво
+Name[zh_CN]=天气
+Name[zh_TW]=天氣
+Comment=Weather Information Component
+Comment[bg]=Информация за времето
+Comment[ca]=Component d'informació del temps
+Comment[da]=Komponent til vejrinformation
+Comment[de]=Komponente für Wetterinformationen
+Comment[el]=Συστατικό πληροφοριών καιρού
+Comment[es]=Componente de información meteorológica
+Comment[et]=Ilmateate komponent
+Comment[fr]=Composant d'Informations météorologiques
+Comment[is]=Eining fyrir veðurupplýsingar
+Comment[it]=Informazioni meteorologiche
+Comment[ja]=気象情報コンポーネント
+Comment[km]=សមាសភាគ​ព័ត៌មាន​អាកាសធាតុ
+Comment[nds]=Wederinformatschonen-Komponent
+Comment[nl]=Weerinformatiecomponent
+Comment[pl]=Składnik informacji o pogodzie
+Comment[ru]=Информация о погоде
+Comment[sk]=Informácie o počasí
+Comment[sr]=Компонента информација о времену
+Comment[sr@Latn]=Komponenta informacija o vremenu
+Comment[sv]=Komponent med väderrapport
+Comment[tr]=Hava Durumu Bilgisi Bileşeni
+Comment[zh_CN]=天气信息组件
+Comment[zh_TW]=天氣資訊組件
+Weight=1000
+Icon=kweather
+
+[NewsTicker]
+Name=News Ticker
+Name[af]=Nuus tikker
+Name[az]=Xəbər Gözləyici
+Name[br]=Kliker keleier
+Name[ca]=Teletip de notícies
+Name[cy]=Ticer Newyddion
+Name[da]=Nyhedstelegraf
+Name[de]=Newsticker
+Name[el]=Προβολέας ειδήσεων
+Name[eo]=Novaĵprezentilo
+Name[es]=Teletipo de noticias
+Name[et]=Uudistejälgija
+Name[eu]=Berri markatzailea
+Name[fa]=Ticker اخبار
+Name[fi]=Uutisnäytin
+Name[fr]=Téléscripteur de nouvelles
+Name[fy]=Nijs Tikker
+Name[gl]=Colector de Novas
+Name[he]=חדשות רצות
+Name[hi]=न्यूज टिकर
+Name[hr]=Ticker sa novostima
+Name[hu]=RSS hírmegjelenítő
+Name[id]=Ticker Berita
+Name[is]=Fréttastrimill
+Name[it]=Ticker notizie
+Name[ja]=ニュースティッカー
+Name[ka]=სიახლეთა ტიკერი
+Name[kk]=Жаңалық таспасы
+Name[km]=កម្មវិធី​ទទួល​ព័ត៌មាន
+Name[lt]=News pranešėjas
+Name[lv]=Ziņu Tikkers
+Name[ms]=Pengetik Berita
+Name[nb]=Nyhetstelegraf
+Name[nds]=Narichten-Ticker
+Name[ne]=न्यूज टिकर
+Name[nn]=Nyheitstelegraf
+Name[pl]=Wiadomości
+Name[pt]=Extractor de Notícias
+Name[pt_BR]=Animação de Notícias
+Name[ro]=Ştiri Internet
+Name[ru]=Новости
+Name[sk]=Sledovanie správ
+Name[sl]=Prikazovalnik novic
+Name[sr]=Откуцавач вести
+Name[sr@Latn]=Otkucavač vesti
+Name[sv]=Nyhetsövervakare
+Name[ta]=செய்திகள் குறிப்பான்
+Name[tg]=Ахборот
+Name[th]=ตั๋วข่าว
+Name[tr]=Haber İzleyici
+Name[uk]=Стрічка новин
+Name[ven]=Musengulusi wa Mafhungo
+Name[vi]=Trình kiểm tra news
+Name[xh]=Umchola-choli weendaba
+Name[zh_CN]=新闻点点通
+Name[zh_TW]=新聞顯示器
+Name[zu]=Umlungiseleli Wezindaba
+Comment=News Ticker Component
+Comment[af]=Nuus tikker komponent
+Comment[bg]=Компонент за новини
+Comment[ca]=Component de teletip de notícies
+Comment[cs]=Komponenta zdrojů novinek
+Comment[da]=Nyhedstelegraf-komponent
+Comment[de]=Newsticker-Komponente
+Comment[el]=Συστατικό προβολέα ειδήσεων
+Comment[eo]=Novaĵprezentila Komponanto
+Comment[es]=Componente de teletipo de noticias
+Comment[et]=Uudistejälgija komponent
+Comment[eu]=Berri markatzaile osagaia
+Comment[fa]=مؤلفۀ Ticker اخبار
+Comment[fi]=Uutiskomponentti
+Comment[fr]=Composant d'affichage de nouvelles
+Comment[fy]=Nijstikkerkomponint
+Comment[gl]=Compoñente de Fonte de Novas
+Comment[hu]=Hírmegjelenítő komponens
+Comment[is]=Fréttastrimilshluti
+Comment[it]=Ticker notizie
+Comment[ja]=ニュースティッカーコンポーネント
+Comment[ka]=სიახლეთა ტიკერის კომპონენტი
+Comment[kk]=Жаңалық таспасының компоненті
+Comment[km]=សមាសភាគ​កម្មវិធី​ទទួល​ព័ត៌មាន
+Comment[lt]=Naujienų pranešėjo komponentas
+Comment[ms]=Komponen Pengetik Berita
+Comment[nb]=Komponent for Nyhetstelegraf
+Comment[nds]=Narichtentelegraaf-Komponent
+Comment[ne]=समाचार टिकर अवयव
+Comment[nl]=Newstickercomponent
+Comment[nn]=Nyhendetelegrafkomponent
+Comment[pl]=Składnik paska wiadomości
+Comment[pt]=Componente de Fontes de Notícias
+Comment[pt_BR]=Componente Mostrador de Notícias
+Comment[ru]=Компонент ленты новостей
+Comment[sk]=Komponent zdrojov správ
+Comment[sl]=Komponenta prikazovalnika novic
+Comment[sr]=Компонента откуцавача вести
+Comment[sr@Latn]=Komponenta otkucavača vesti
+Comment[sv]=Nyhetskomponent
+Comment[ta]=செய்தி எடுக்கும் பகுதி
+Comment[tr]=Haber İzleyici Bileşeni
+Comment[uk]=Компонент смужки новин
+Comment[zh_CN]=新闻点点通组件
+Comment[zh_TW]=新聞顯示元件
+Weight=1100
+Icon=knode
diff --git a/kontact/src/kontactconfig.desktop b/kontact/src/kontactconfig.desktop
new file mode 100644
index 000000000..b057e72c4
--- /dev/null
+++ b/kontact/src/kontactconfig.desktop
@@ -0,0 +1,53 @@
+[Desktop Entry]
+Exec=kcmshell kontactconfig
+Icon=kontact
+Type=Service
+ServiceTypes=KCModule
+
+X-KDE-ModuleType=Library
+X-KDE-Library=kontact
+X-KDE-FactoryName=kontactconfig
+X-KDE-HasReadOnlyMode=false
+X-KDE-ParentApp=kontact
+X-KDE-ParentComponents=kontact
+X-KDE-Weight=0
+
+Name=Kontact
+Name[be]=Кантакт
+Name[hi]=कॉन्टेक्ट
+Name[mk]=Контакт
+Name[ne]=सम्पर्क गर्नुहोस्
+Name[sv]=Kontakt
+Name[ta]=தொடர்பு கொள்
+Name[zh_TW]=Kontact 個人資訊管理
+Comment=KDE Kontact
+Comment[bg]=Управление на личната информация
+Comment[ca]=Kontact de KDE
+Comment[cy]=Kontact KDE
+Comment[de]=Kontact
+Comment[fi]=Kontact
+Comment[hi]=केडीई कॉन्टेक्ट
+Comment[mk]=KDE Контакт
+Comment[ms]=Kontact KDE
+Comment[nds]=KDE-Kontact
+Comment[ne]=केडीई सम्पर्क
+Comment[pl]=Kontact dla KDE
+Comment[pt]=Kontact do KDE
+Comment[pt_BR]=Kontact do KDE
+Comment[ro]=Contact KDE
+Comment[ta]=கேடிஇ தொடர்புகொள்
+Keywords=kontact
+Keywords[be]=кантакт,kontact
+Keywords[bg]=контакти, връзка, информация, личен, поща, бизнес, планиране, kontact
+Keywords[de]=Kontact
+Keywords[hi]=कॉन्टेक्ट
+Keywords[hu]=kapcsolat
+Keywords[mk]=kontact,контакт
+Keywords[nb]=kontact, kontakt
+Keywords[nds]=Kontact
+Keywords[ne]=सम्पर्क
+Keywords[sr]=kontact, контакт
+Keywords[sr@Latn]=kontact, kontakt
+Keywords[sv]=kontakt
+Keywords[ta]=தொடர்புகொள்
+Keywords[tr]=bağlantı
diff --git a/kontact/src/kontactdcop.desktop b/kontact/src/kontactdcop.desktop
new file mode 100644
index 000000000..fdd07b9cc
--- /dev/null
+++ b/kontact/src/kontactdcop.desktop
@@ -0,0 +1,18 @@
+[Desktop Entry]
+Name=Kontact
+Name[be]=Кантакт
+Name[hi]=कॉन्टेक्ट
+Name[mk]=Контакт
+Name[ne]=सम्पर्क गर्नुहोस्
+Name[sv]=Kontakt
+Name[ta]=தொடர்பு கொள்
+Name[zh_TW]=Kontact 個人資訊管理
+Exec=kontact --iconify
+Type=Application
+Icon=kontact
+NoDisplay=true
+X-DCOP-ServiceType=Unique
+X-DCOP-ServiceName=kontact
+ServiceTypes=DCOP/ResourceBackend/IMAP,DCOP/Mailer
+X-KDE-StartupNotify=false
+Categories=Qt;KDE;Office
diff --git a/kontact/src/kontactiface.h b/kontact/src/kontactiface.h
new file mode 100644
index 000000000..7af3e8a5c
--- /dev/null
+++ b/kontact/src/kontactiface.h
@@ -0,0 +1,36 @@
+/*
+ Copyright (c) 2007 Volker Krause <vkrause@kde.org>
+
+ 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.
+*/
+
+#ifndef KONTACT_INTERFACE_H
+#define KONTACT_INTERFACE_H
+
+#include <dcopobject.h>
+
+class KontactIface : public DCOPObject
+{
+ K_DCOP
+ public:
+ KontactIface() : DCOPObject("KontactIface") {}
+
+ k_dcop:
+ virtual void selectPlugin( const QString &name ) = 0;
+
+};
+
+#endif
diff --git a/kontact/src/kontactui.rc b/kontact/src/kontactui.rc
new file mode 100644
index 000000000..8c68f0607
--- /dev/null
+++ b/kontact/src/kontactui.rc
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!DOCTYPE gui SYSTEM "kpartgui.dtd">
+<gui version="22" name="kontact" >
+<MenuBar>
+ <Menu name="file" noMerge="1">
+ <text>&amp;File</text>
+ <Merge/>
+ <Separator/>
+ <Action name="action_new"/>
+ <Separator/>
+ <Action name="file_quit"/>
+ <Merge/>
+ </Menu>
+ <Merge />
+ <Menu name="settings">
+ <text>&amp;Settings</text>
+ <Merge append="save_merge"/>
+<!-- <Separator/> -->
+ <DefineGroup name="settings_configure" append="configure_merge"/>
+ <Action name="settings_configure_kontact" append="configure_merge"/>
+ <Action name="settings_configure_kontact_profiles" append="configure_merge"/>
+
+<!-- Those actions have to be set by the parts because some applications
+ have app.rc == part.rc
+-->
+<!--
+ <Action name="options_configure_keybinding"/>
+ <Action name="options_configure_toolbars"/>
+-->
+ </Menu>
+ <Menu name="help"><text>&amp;Help</text>
+ <Action name="help_introduction"/>
+ <Action name="help_tipofday"/>
+ <Separator/>
+ <Action name="help_requestfeature"/>
+ </Menu>
+</MenuBar>
+<ToolBar position="Top" noMerge="1" name="mainToolBar"><text>Main Toolbar</text>
+ <Action name="action_new"/>
+ <Action name="action_sync"/>
+ <Merge/>
+ <Action name="help_whats_this"/>
+</ToolBar>
+<ToolBar position="Top" hidden="true" name="navigatorToolBar"><text>Navigator</text>
+ <Action name="navigator_spacer_item"/>
+ <ActionList name="navigator_actionlist" />
+</ToolBar>
+</gui>
diff --git a/kontact/src/main.cpp b/kontact/src/main.cpp
new file mode 100644
index 000000000..d3fce17c2
--- /dev/null
+++ b/kontact/src/main.cpp
@@ -0,0 +1,168 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
+ Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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 <iostream>
+
+#include <dcopclient.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstartupinfo.h>
+#include <kuniqueapplication.h>
+#include <kwin.h>
+#include <kstandarddirs.h>
+#include <ktrader.h>
+#include "plugin.h"
+
+#include <qlabel.h>
+#include "prefs.h"
+
+#include "alarmclient.h"
+#include "mainwindow.h"
+#include <uniqueapphandler.h> // in ../interfaces
+
+using namespace std;
+
+static const char description[] =
+ I18N_NOOP( "KDE personal information manager" );
+
+static const char version[] = "1.2.9";
+
+class KontactApp : public KUniqueApplication {
+ public:
+ KontactApp() : mMainWindow( 0 ), mSessionRestored( false ) {}
+ ~KontactApp() {}
+
+ int newInstance();
+ void setMainWindow( Kontact::MainWindow *window ) {
+ mMainWindow = window;
+ setMainWidget( window );
+ }
+ void setSessionRestored( bool restored ) {
+ mSessionRestored = restored;
+ }
+
+ private:
+ void startKOrgac();
+ Kontact::MainWindow *mMainWindow;
+ bool mSessionRestored;
+};
+
+static void listPlugins()
+{
+ KInstance instance( "kontact" ); // Can't use KontactApp since it's too late for adding cmdline options
+ KTrader::OfferList offers = KTrader::self()->query(
+ QString::fromLatin1( "Kontact/Plugin" ),
+ QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );
+ for ( KService::List::Iterator it = offers.begin(); it != offers.end(); ++it ) {
+ KService::Ptr service = (*it);
+ // skip summary only plugins
+ QVariant var = service->property( "X-KDE-KontactPluginHasPart" );
+ if ( var.isValid() && var.toBool() == false )
+ continue;
+ cout << service->library().remove( "libkontact_" ).latin1() << endl;
+ }
+}
+
+int KontactApp::newInstance()
+{
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ QString moduleName;
+ if ( Kontact::Prefs::self()->forceStartupPlugin() ) {
+ moduleName = Kontact::Prefs::self()->forcedStartupPlugin();
+ }
+ if ( args->isSet( "module" ) ) {
+ moduleName = QString::fromLocal8Bit( args->getOption( "module" ) );
+ }
+
+ if ( !mSessionRestored ) {
+ if ( !mMainWindow ) {
+ mMainWindow = new Kontact::MainWindow();
+ if ( !moduleName.isEmpty() )
+ mMainWindow->setActivePluginModule( moduleName );
+ mMainWindow->show();
+ setMainWidget( mMainWindow );
+ // --iconify is needed in kontact, although kstart can do that too,
+ // because kstart returns immediately so it's too early to talk DCOP to the app.
+ if ( args->isSet( "iconify" ) )
+ KWin::iconifyWindow( mMainWindow->winId(), false /*no animation*/ );
+ } else {
+ if ( !moduleName.isEmpty() )
+ mMainWindow->setActivePluginModule( moduleName );
+ }
+ }
+
+ AlarmClient alarmclient;
+ alarmclient.startDaemon();
+
+ // Handle startup notification and window activation
+ // (The first time it will do nothing except note that it was called)
+ return KUniqueApplication::newInstance();
+}
+
+int main( int argc, char **argv )
+{
+ KAboutData about( "kontact", I18N_NOOP( "Kontact" ), version, description,
+ KAboutData::License_GPL, I18N_NOOP("(C) 2001-2008 The Kontact developers"), 0, "http://kontact.org" );
+ about.addAuthor( "Daniel Molkentin", 0, "molkentin@kde.org" );
+ about.addAuthor( "Don Sanders", 0, "sanders@kde.org" );
+ about.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
+ about.addAuthor( "Tobias K\303\266nig", 0, "tokoe@kde.org" );
+ about.addAuthor( "David Faure", 0, "faure@kde.org" );
+ about.addAuthor( "Ingo Kl\303\266cker", 0, "kloecker@kde.org" );
+ about.addAuthor( "Sven L\303\274ppken", 0, "sven@kde.org" );
+ about.addAuthor( "Zack Rusin", 0, "zack@kde.org" );
+ about.addAuthor( "Matthias Hoelzer-Kluepfel", I18N_NOOP("Original Author"), "mhk@kde.org" );
+
+ KCmdLineArgs::init( argc, argv, &about );
+ Kontact::UniqueAppHandler::loadKontactCommandLineOptions();
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ if ( args->isSet( "list" ) ) {
+ listPlugins();
+ return 0;
+ }
+
+ if ( !KontactApp::start() ) {
+ // Already running, brought to the foreground.
+ return 0;
+ }
+
+ KontactApp app;
+ if ( app.restoringSession() ) {
+ // There can only be one main window
+ if ( KMainWindow::canBeRestored( 1 ) ) {
+ Kontact::MainWindow *mainWindow = new Kontact::MainWindow();
+ app.setMainWindow( mainWindow );
+ app.setSessionRestored( true );
+ mainWindow->show();
+ mainWindow->restore( 1 );
+ }
+ }
+
+ bool ret = app.exec();
+ while ( KMainWindow::memberList->first() )
+ delete KMainWindow::memberList->first();
+
+ return ret;
+}
diff --git a/kontact/src/mainwindow.cpp b/kontact/src/mainwindow.cpp
new file mode 100644
index 000000000..de4eb2df7
--- /dev/null
+++ b/kontact/src/mainwindow.cpp
@@ -0,0 +1,1100 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
+ Copyright (c) 2002-2005 Daniel Molkentin <molkentin@kde.org>
+ Copyright (c) 2003-2005 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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 <qcombobox.h>
+#include <qdockarea.h>
+#include <qguardedptr.h>
+#include <qhbox.h>
+#include <qimage.h>
+#include <qobjectlist.h>
+#include <qprogressbar.h>
+#include <qpushbutton.h>
+#include <qsplitter.h>
+#include <qtimer.h>
+#include <qwhatsthis.h>
+
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kedittoolbar.h>
+#include <kguiitem.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <kkeydialog.h>
+#include <klibloader.h>
+#include <klistbox.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kparts/componentfactory.h>
+#include <kplugininfo.h>
+#include <kpopupmenu.h>
+#include <ksettings/dialog.h>
+#include <ksettings/dispatcher.h>
+#include <kshortcut.h>
+#include <kstandarddirs.h>
+#include <kstatusbar.h>
+#include <kstdaction.h>
+#include <ktip.h>
+#include <ktrader.h>
+#include <ksettings/componentsdialog.h>
+#include <kstringhandler.h>
+#include <krsqueezedtextlabel.h>
+#include <khtml_part.h>
+#include <khtmlview.h>
+#include <libkdepim/kfileio.h>
+#include <kcursor.h>
+#include <krun.h>
+#include <kaboutdata.h>
+#include <kmenubar.h>
+#include <kstdaccel.h>
+#include <kcmultidialog.h>
+#include <kipc.h>
+
+#include "aboutdialog.h"
+#include "iconsidepane.h"
+#include "mainwindow.h"
+#include "plugin.h"
+#include "prefs.h"
+#include "profiledialog.h"
+#include "profilemanager.h"
+#include "progressdialog.h"
+#include "statusbarprogresswidget.h"
+#include "broadcaststatus.h"
+
+using namespace Kontact;
+
+class SettingsDialogWrapper : public KSettings::Dialog
+{
+ public:
+ SettingsDialogWrapper( ContentInListView content, QWidget * parent = 0 )
+ : KSettings::Dialog( content, parent, 0 )
+ {
+ }
+
+
+ void fixButtonLabel( QWidget *widget )
+ {
+ QObject *object = widget->child( "KJanusWidget::buttonBelowList" );
+ QPushButton *button = static_cast<QPushButton*>( object );
+ if ( button )
+ button->setText( i18n( "Select Components ..." ) );
+ }
+};
+
+MainWindow::MainWindow()
+ : Kontact::Core(), mTopWidget( 0 ), mSplitter( 0 ),
+ mCurrentPlugin( 0 ), mAboutDialog( 0 ), mReallyClose( false ), mSyncActionsEnabled( true )
+{
+ // Set this to be the group leader for all subdialogs - this means
+ // modal subdialogs will only affect this dialog, not the other windows
+ setWFlags( getWFlags() | WGroupLeader );
+
+ initGUI();
+ initObject();
+}
+
+void MainWindow::initGUI()
+{
+ initWidgets();
+ setupActions();
+ setHelpMenuEnabled( false );
+ KHelpMenu *helpMenu = new KHelpMenu( this, 0, true, actionCollection() );
+ connect( helpMenu, SIGNAL( showAboutApplication() ),
+ SLOT( showAboutDialog() ) );
+
+ KStdAction::keyBindings( this, SLOT( configureShortcuts() ), actionCollection() );
+ KStdAction::configureToolbars( this, SLOT( configureToolbars() ), actionCollection() );
+ setXMLFile( "kontactui.rc" );
+
+ setStandardToolBarMenuEnabled( true );
+
+ createGUI( 0 );
+
+ resize( 700, 520 ); // initial size to prevent a scrollbar in sidepane
+ setAutoSaveSettings();
+
+ connect( Kontact::ProfileManager::self(), SIGNAL( profileLoaded( const QString& ) ),
+ this, SLOT( slotLoadProfile( const QString& ) ) );
+ connect( Kontact::ProfileManager::self(), SIGNAL( saveToProfileRequested( const QString& ) ),
+ this, SLOT( slotSaveToProfile( const QString& ) ) );
+}
+
+
+void MainWindow::initObject()
+{
+ KTrader::OfferList offers = KTrader::self()->query(
+ QString::fromLatin1( "Kontact/Plugin" ),
+ QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );
+ mPluginInfos = KPluginInfo::fromServices( offers, Prefs::self()->config(), "Plugins" );
+
+ KPluginInfo::List::Iterator it;
+ for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) {
+ ( *it )->load();
+ }
+
+ // prepare the part manager
+ mPartManager = new KParts::PartManager( this );
+ connect( mPartManager, SIGNAL( activePartChanged( KParts::Part* ) ),
+ this, SLOT( slotActivePartChanged( KParts::Part* ) ) );
+
+ loadPlugins();
+
+ if ( mSidePane ) {
+ mSidePane->updatePlugins();
+ plugActionList( "navigator_actionlist", mSidePane->actions() );
+ }
+
+ KSettings::Dispatcher::self()->registerInstance( instance(), this,
+ SLOT( updateConfig() ) );
+
+ loadSettings();
+
+ statusBar()->show();
+
+ showTip( false );
+
+ // done initializing
+ slotShowStatusMsg( QString::null );
+
+ connect( KPIM::BroadcastStatus::instance(), SIGNAL( statusMsg( const QString& ) ),
+ this, SLOT( slotShowStatusMsg( const QString& ) ) );
+
+ // launch commandline specified module if any
+ activatePluginModule();
+
+ if ( Prefs::lastVersionSeen() == kapp->aboutData()->version() ) {
+ selectPlugin( mCurrentPlugin );
+ }
+
+ paintAboutScreen( introductionString() );
+ Prefs::setLastVersionSeen( kapp->aboutData()->version() );
+}
+
+MainWindow::~MainWindow()
+{
+ saveSettings();
+
+ QPtrList<KParts::Part> parts = *mPartManager->parts();
+
+ for ( KParts::Part *p = parts.last(); p; p = parts.prev() ) {
+ delete p;
+ p = 0;
+ }
+
+ Prefs::self()->writeConfig();
+}
+
+void MainWindow::setActivePluginModule( const QString &module )
+{
+ mActiveModule = module;
+ activatePluginModule();
+}
+
+void MainWindow::activatePluginModule()
+{
+ if ( !mActiveModule.isEmpty() ) {
+ PluginList::ConstIterator end = mPlugins.end();
+ for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
+ if ( ( *it )->identifier().contains( mActiveModule ) ) {
+ selectPlugin( *it );
+ return;
+ }
+ }
+}
+
+void MainWindow::initWidgets()
+{
+ // includes sidebar and part stack
+ mTopWidget = new QHBox( this );
+ mTopWidget->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ setCentralWidget( mTopWidget );
+
+ QHBox *mBox = 0;
+ mSplitter = new QSplitter( mTopWidget );
+ mBox = new QHBox( mTopWidget );
+ mSidePane = new IconSidePane( this, mSplitter );
+ mSidePane->setSizePolicy( QSizePolicy( QSizePolicy::Maximum,
+ QSizePolicy::Preferred ) );
+ // donÄt occupy screen estate on load
+ QValueList<int> sizes;
+ sizes << 0;
+ mSplitter->setSizes(sizes);
+
+ mSidePane->setActionCollection( actionCollection() );
+
+ connect( mSidePane, SIGNAL( pluginSelected( Kontact::Plugin * ) ),
+ SLOT( selectPlugin( Kontact::Plugin * ) ) );
+
+ QVBox *vBox;
+ if ( mSplitter ) {
+ vBox = new QVBox( mSplitter );
+ } else {
+ vBox = new QVBox( mBox );
+ }
+
+ vBox->setSpacing( 0 );
+
+ mPartsStack = new QWidgetStack( vBox );
+ initAboutScreen();
+
+ QString loading = i18n( "<h2 style='text-align:center; margin-top: 0px; margin-bottom: 0px'>%1</h2>" )
+ .arg( i18n("Loading Kontact...") );
+
+ paintAboutScreen( loading );
+
+ /* Create a progress dialog and hide it. */
+ KPIM::ProgressDialog *progressDialog = new KPIM::ProgressDialog( statusBar(), this );
+ progressDialog->hide();
+
+ mLittleProgress = new KPIM::StatusbarProgressWidget( progressDialog, statusBar() );
+
+ mStatusMsgLabel = new KRSqueezedTextLabel( i18n( " Initializing..." ), statusBar() );
+ mStatusMsgLabel->setAlignment( AlignLeft | AlignVCenter );
+
+ statusBar()->addWidget( mStatusMsgLabel, 10 , false );
+ statusBar()->addWidget( mLittleProgress, 0 , true );
+ mLittleProgress->show();
+}
+
+
+void MainWindow::paintAboutScreen( const QString& msg )
+{
+ QString location = locate( "data", "kontact/about/main.html" );
+ QString content = KPIM::kFileToString( location );
+ content = content.arg( locate( "data", "libkdepim/about/kde_infopage.css" ) );
+ if ( kapp->reverseLayout() )
+ content = content.arg( "@import \"%1\";" ).arg( locate( "data", "libkdepim/about/kde_infopage_rtl.css" ) );
+ else
+ content = content.arg( "" );
+
+ mIntroPart->begin( KURL( location ) );
+
+ QString appName( i18n( "KDE Kontact" ) );
+ QString catchPhrase( i18n( "Get Organized!" ) );
+ QString quickDescription( i18n( "The KDE Personal Information Management Suite" ) );
+
+ mIntroPart->write( content.arg( QFont().pointSize() + 2 ).arg( appName )
+ .arg( catchPhrase ).arg( quickDescription ).arg( msg ) );
+ mIntroPart->end();
+}
+
+void MainWindow::initAboutScreen()
+{
+ QHBox *introbox = new QHBox( mPartsStack );
+ mPartsStack->addWidget( introbox );
+ mPartsStack->raiseWidget( introbox );
+ mIntroPart = new KHTMLPart( introbox );
+ mIntroPart->widget()->setFocusPolicy( WheelFocus );
+ // Let's better be paranoid and disable plugins (it defaults to enabled):
+ mIntroPart->setPluginsEnabled( false );
+ mIntroPart->setJScriptEnabled( false ); // just make this explicit
+ mIntroPart->setJavaEnabled( false ); // just make this explicit
+ mIntroPart->setMetaRefreshEnabled( false );
+ mIntroPart->setURLCursor( KCursor::handCursor() );
+ mIntroPart->view()->setLineWidth( 0 );
+
+ connect( mIntroPart->browserExtension(),
+ SIGNAL( openURLRequest( const KURL&, const KParts::URLArgs& ) ),
+ SLOT( slotOpenUrl( const KURL& ) ) );
+
+ connect( mIntroPart->browserExtension(),
+ SIGNAL( createNewWindow( const KURL&, const KParts::URLArgs& ) ),
+ SLOT( slotOpenUrl( const KURL& ) ) );
+}
+
+void MainWindow::setupActions()
+{
+ KStdAction::quit( this, SLOT( slotQuit() ), actionCollection() );
+ mNewActions = new KToolBarPopupAction( KGuiItem( i18n( "New" ), "" ),
+ KStdAccel::shortcut(KStdAccel::New), this, SLOT( slotNewClicked() ),
+ actionCollection(), "action_new" );
+
+ KConfig* const cfg = Prefs::self()->config();
+ cfg->setGroup( "Kontact Groupware Settings" );
+ mSyncActionsEnabled = cfg->readBoolEntry( "GroupwareMailFoldersEnabled", true );
+
+ if ( mSyncActionsEnabled ) {
+ mSyncActions = new KToolBarPopupAction( KGuiItem( i18n( "Synchronize" ), "kitchensync" ),
+ KStdAccel::shortcut(KStdAccel::Reload), this, SLOT( slotSyncClicked() ),
+ actionCollection(), "action_sync" );
+ }
+ new KAction( i18n( "Configure Kontact..." ), "configure", 0, this, SLOT( slotPreferences() ),
+ actionCollection(), "settings_configure_kontact" );
+
+ new KAction( i18n( "Configure &Profiles..." ), 0, this, SLOT( slotConfigureProfiles() ),
+ actionCollection(), "settings_configure_kontact_profiles" );
+
+ new KAction( i18n( "&Kontact Introduction" ), 0, this, SLOT( slotShowIntroduction() ),
+ actionCollection(), "help_introduction" );
+ new KAction( i18n( "&Tip of the Day" ), 0, this, SLOT( slotShowTip() ),
+ actionCollection(), "help_tipofday" );
+ new KAction( i18n( "&Request Feature..." ), 0, this, SLOT( slotRequestFeature() ),
+ actionCollection(), "help_requestfeature" );
+
+ KWidgetAction* spacerAction = new KWidgetAction( new QWidget( this ), "SpacerAction", "", 0, 0, actionCollection(), "navigator_spacer_item" );
+ spacerAction->setAutoSized( true );
+}
+
+void MainWindow::slotConfigureProfiles()
+{
+ QGuardedPtr<Kontact::ProfileDialog> dlg = new Kontact::ProfileDialog( this );
+ dlg->setModal( true );
+ dlg->exec();
+ delete dlg;
+}
+
+namespace {
+ void copyConfigEntry( KConfig* source, KConfig* dest, const QString& group, const QString& key, const QString& defaultValue=QString() )
+ {
+ source->setGroup( group );
+ dest->setGroup( group );
+ dest->writeEntry( key, source->readEntry( key, defaultValue ) );
+ }
+}
+
+void MainWindow::slotSaveToProfile( const QString& id )
+{
+ const QString path = Kontact::ProfileManager::self()->profileById( id ).saveLocation();
+ if ( path.isNull() )
+ return;
+
+ KConfig* const cfg = Prefs::self()->config();
+ Prefs::self()->writeConfig();
+ saveMainWindowSettings( cfg );
+ saveSettings();
+
+ KConfig profile( path+"/kontactrc", /*read-only=*/false, /*useglobals=*/false );
+ ::copyConfigEntry( cfg, &profile, "MainWindow Toolbar navigatorToolBar", "Hidden", "true" );
+ ::copyConfigEntry( cfg, &profile, "View", "SidePaneSplitter" );
+ ::copyConfigEntry( cfg, &profile, "Icons", "Theme" );
+
+ for ( PluginList::Iterator it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
+ if ( !(*it)->isRunningStandalone() ) {
+ (*it)->part();
+ }
+ (*it)->saveToProfile( path );
+ }
+}
+
+void MainWindow::slotLoadProfile( const QString& id )
+{
+ const QString path = Kontact::ProfileManager::self()->profileById( id ).saveLocation();
+ if ( path.isNull() )
+ return;
+
+ KConfig* const cfg = Prefs::self()->config();
+ Prefs::self()->writeConfig();
+ saveMainWindowSettings( cfg );
+ saveSettings();
+
+ const KConfig profile( path+"/kontactrc", /*read-only=*/false, /*useglobals=*/false );
+ const QStringList groups = profile.groupList();
+ for ( QStringList::ConstIterator it = groups.begin(), end = groups.end(); it != end; ++it )
+ {
+ cfg->setGroup( *it );
+ typedef QMap<QString, QString> StringMap;
+ const StringMap entries = profile.entryMap( *it );
+ for ( StringMap::ConstIterator it2 = entries.begin(), end = entries.end(); it2 != end; ++it2 )
+ {
+ if ( it2.data() == "KONTACT_PROFILE_DELETE_KEY" )
+ cfg->deleteEntry( it2.key() );
+ else
+ cfg->writeEntry( it2.key(), it2.data() );
+ }
+ }
+
+ cfg->sync();
+ Prefs::self()->readConfig();
+ applyMainWindowSettings( cfg );
+ KIconTheme::reconfigure();
+ const WId wid = winId();
+ KIPC::sendMessage( KIPC::PaletteChanged, wid );
+ KIPC::sendMessage( KIPC::FontChanged, wid );
+ KIPC::sendMessage( KIPC::StyleChanged, wid );
+ KIPC::sendMessage( KIPC::SettingsChanged, wid );
+ for ( int i = 0; i < KIcon::LastGroup; ++i )
+ KIPC::sendMessage( KIPC::IconChanged, wid, i );
+
+ loadSettings();
+
+ for ( PluginList::Iterator it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
+ if ( !(*it)->isRunningStandalone() ) {
+ kdDebug() << "Ensure loaded: " << (*it)->identifier() << endl;
+ (*it)->part();
+ }
+ (*it)->loadProfile( path );
+ }
+}
+
+bool MainWindow::isPluginLoaded( const KPluginInfo *info )
+{
+ return (pluginFromInfo( info ) != 0);
+}
+
+Plugin *MainWindow::pluginFromInfo( const KPluginInfo *info )
+{
+ PluginList::ConstIterator end = mPlugins.end();
+ for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
+ if ( (*it)->identifier() == info->pluginName() )
+ return *it;
+
+ return 0;
+}
+
+void MainWindow::loadPlugins()
+{
+ QPtrList<Plugin> plugins;
+ QPtrList<KParts::Part> loadDelayed;
+
+ uint i;
+ KPluginInfo::List::ConstIterator it;
+ for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) {
+ if ( !(*it)->isPluginEnabled() )
+ continue;
+ if ( isPluginLoaded( *it ) ) {
+ Plugin *plugin = pluginFromInfo( *it );
+ if ( plugin )
+ plugin->configUpdated();
+ continue;
+ }
+
+ kdDebug(5600) << "Loading Plugin: " << (*it)->name() << endl;
+ Kontact::Plugin *plugin =
+ KParts::ComponentFactory::createInstanceFromService<Kontact::Plugin>(
+ (*it)->service(), this );
+
+ if ( !plugin )
+ continue;
+
+ plugin->setIdentifier( (*it)->pluginName() );
+ plugin->setTitle( (*it)->name() );
+ plugin->setIcon( (*it)->icon() );
+
+ QVariant libNameProp = (*it)->property( "X-KDE-KontactPartLibraryName" );
+ QVariant exeNameProp = (*it)->property( "X-KDE-KontactPartExecutableName" );
+ QVariant loadOnStart = (*it)->property( "X-KDE-KontactPartLoadOnStart" );
+ QVariant hasPartProp = (*it)->property( "X-KDE-KontactPluginHasPart" );
+
+ if ( !loadOnStart.isNull() && loadOnStart.toBool() )
+ mDelayedPreload.append( plugin );
+
+ kdDebug(5600) << "LIBNAMEPART: " << libNameProp.toString() << endl;
+
+ plugin->setPartLibraryName( libNameProp.toString().utf8() );
+ plugin->setExecutableName( exeNameProp.toString() );
+ if ( hasPartProp.isValid() )
+ plugin->setShowInSideBar( hasPartProp.toBool() );
+
+ for ( i = 0; i < plugins.count(); ++i ) {
+ Plugin *p = plugins.at( i );
+ if ( plugin->weight() < p->weight() )
+ break;
+ }
+
+ plugins.insert( i, plugin );
+ }
+
+ for ( i = 0; i < plugins.count(); ++ i ) {
+ Plugin *plugin = plugins.at( i );
+
+ KAction *action;
+ QPtrList<KAction> *actionList = plugin->newActions();
+
+ for ( action = actionList->first(); action; action = actionList->next() ) {
+ kdDebug(5600) << "Plugging " << action->name() << endl;
+ action->plug( mNewActions->popupMenu() );
+ }
+
+ if ( mSyncActionsEnabled ) {
+ actionList = plugin->syncActions();
+ for ( action = actionList->first(); action; action = actionList->next() ) {
+ kdDebug(5600) << "Plugging " << action->name() << endl;
+ action->plug( mSyncActions->popupMenu() );
+ }
+ }
+ addPlugin( plugin );
+ }
+
+ mNewActions->setEnabled( mPlugins.size() != 0 );
+ if ( mSyncActionsEnabled )
+ mSyncActions->setEnabled( mPlugins.size() != 0 );
+}
+
+void MainWindow::unloadPlugins()
+{
+ KPluginInfo::List::ConstIterator end = mPluginInfos.end();
+ KPluginInfo::List::ConstIterator it;
+ for ( it = mPluginInfos.begin(); it != end; ++it ) {
+ if ( !(*it)->isPluginEnabled() )
+ removePlugin( *it );
+ }
+}
+
+bool MainWindow::removePlugin( const KPluginInfo *info )
+{
+ PluginList::Iterator end = mPlugins.end();
+ for ( PluginList::Iterator it = mPlugins.begin(); it != end; ++it )
+ if ( ( *it )->identifier() == info->pluginName() ) {
+ Plugin *plugin = *it;
+
+ KAction *action;
+ QPtrList<KAction> *actionList = plugin->newActions();
+
+ for ( action = actionList->first(); action; action = actionList->next() ) {
+ kdDebug(5600) << "Unplugging " << action->name() << endl;
+ action->unplug( mNewActions->popupMenu() );
+ }
+
+ if ( mSyncActionsEnabled ) {
+ actionList = plugin->syncActions();
+ for ( action = actionList->first(); action; action = actionList->next() ) {
+ kdDebug(5600) << "Unplugging " << action->name() << endl;
+ action->unplug( mSyncActions->popupMenu() );
+ }
+ }
+ removeChildClient( plugin );
+
+ if ( mCurrentPlugin == plugin )
+ mCurrentPlugin = 0;
+
+ delete plugin; // removes the part automatically
+ mPlugins.remove( it );
+
+ if ( mCurrentPlugin == 0 ) {
+ PluginList::Iterator it;
+ for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
+ if ( (*it)->showInSideBar() ) {
+ selectPlugin( *it );
+ return true;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void MainWindow::addPlugin( Kontact::Plugin *plugin )
+{
+ kdDebug(5600) << "Added plugin" << endl;
+
+ mPlugins.append( plugin );
+
+ // merge the plugins GUI into the main window
+ insertChildClient( plugin );
+}
+
+void MainWindow::partLoaded( Kontact::Plugin*, KParts::ReadOnlyPart *part )
+{
+ // See if we have this part already (e.g. due to two plugins sharing it)
+ if ( mPartsStack->id( part->widget() ) != -1 )
+ return;
+
+ mPartsStack->addWidget( part->widget() );
+
+ mPartManager->addPart( part, false );
+ // Workaround for KParts misbehavior: addPart calls show!
+ part->widget()->hide();
+}
+
+void MainWindow::slotActivePartChanged( KParts::Part *part )
+{
+ if ( !part ) {
+ createGUI( 0 );
+ return;
+ }
+
+ kdDebug(5600) << "Part activated: " << part << " with stack id. "
+ << mPartsStack->id( part->widget() )<< endl;
+
+ //createGUI( part ); // moved to selectPlugin()
+
+ statusBar()->clear();
+}
+
+void MainWindow::slotNewClicked()
+{
+ KAction *action = mCurrentPlugin->newActions()->first();
+ if ( action ) {
+ action->activate();
+ } else {
+ PluginList::Iterator it;
+ for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
+ action = (*it)->newActions()->first();
+ if ( action ) {
+ action->activate();
+ return;
+ }
+ }
+ }
+}
+
+void MainWindow::slotSyncClicked()
+{
+ KAction *action = mCurrentPlugin->syncActions()->first();
+ if ( action ) {
+ action->activate();
+ } else {
+ PluginList::Iterator it;
+ for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
+ action = (*it)->syncActions()->first();
+ if ( action ) {
+ action->activate();
+ return;
+ }
+ }
+ }
+}
+
+KToolBar* Kontact::MainWindow::findToolBar(const char* name)
+{
+ // like KMainWindow::toolBar, but which doesn't create the toolbar if not found
+ return static_cast<KToolBar *>(child(name, "KToolBar"));
+}
+
+void MainWindow::selectPlugin( Kontact::Plugin *plugin )
+{
+ if ( !plugin )
+ return;
+
+ if ( plugin->isRunningStandalone() ) {
+ statusBar()->message( i18n( "Application is running standalone. Foregrounding..." ), 1000 );
+ mSidePane->indicateForegrunding( plugin );
+ plugin->bringToForeground();
+ return;
+ }
+
+ KApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
+
+ KParts::Part *part = plugin->part();
+
+ if ( !part ) {
+ KApplication::restoreOverrideCursor();
+ KMessageBox::error( this, i18n( "Cannot load part for %1." )
+ .arg( plugin->title() )
+ + "\n" + lastErrorMessage() );
+ plugin->setDisabled( true );
+ mSidePane->updatePlugins();
+ return;
+ }
+
+ // store old focus widget
+ QWidget *focusWidget = kapp->focusWidget();
+ if ( mCurrentPlugin && focusWidget ) {
+ // save the focus widget only when it belongs to the activated part
+ QWidget *parent = focusWidget->parentWidget();
+ while ( parent ) {
+ if ( parent == mCurrentPlugin->part()->widget() )
+ mFocusWidgets.insert( mCurrentPlugin->identifier(), QGuardedPtr<QWidget>( focusWidget ) );
+
+ parent = parent->parentWidget();
+ }
+ }
+
+ if ( mSidePane )
+ mSidePane->selectPlugin( plugin );
+
+ plugin->select();
+
+ mPartManager->setActivePart( part );
+ QWidget *view = part->widget();
+ Q_ASSERT( view );
+
+ if ( view ) {
+ mPartsStack->raiseWidget( view );
+ view->show();
+
+ if ( mFocusWidgets.contains( plugin->identifier() ) ) {
+ focusWidget = mFocusWidgets[ plugin->identifier() ];
+ if ( focusWidget )
+ focusWidget->setFocus();
+ } else
+ view->setFocus();
+
+ mCurrentPlugin = plugin;
+ KAction *newAction = plugin->newActions()->first();
+ KAction *syncAction = plugin->syncActions()->first();
+
+ createGUI( plugin->part() );
+
+ KToolBar* navigatorToolBar = findToolBar( "navigatorToolBar" );
+ // Let the navigator toolbar be always the last one, if it's in the top dockwindow
+ if ( navigatorToolBar && !navigatorToolBar->isHidden() &&
+ navigatorToolBar->barPos() == KToolBar::Top ) {
+ topDock()->moveDockWindow( navigatorToolBar, -1 );
+ }
+
+ setCaption( i18n( "Plugin dependent window title" ,"%1 - Kontact" ).arg( plugin->title() ) );
+
+ if ( newAction ) {
+ mNewActions->setIcon( newAction->icon() );
+ mNewActions->setText( newAction->text() );
+ } else { // we'll use the action of the first plugin which offers one
+ PluginList::Iterator it;
+ for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
+ newAction = (*it)->newActions()->first();
+ if ( newAction ) {
+ mNewActions->setIcon( newAction->icon() );
+ mNewActions->setText( newAction->text() );
+ break;
+ }
+ }
+ }
+ if ( mSyncActionsEnabled ) {
+ if ( syncAction ) {
+ mSyncActions->setIcon( syncAction->icon() );
+ mSyncActions->setText( syncAction->text() );
+ } else { // we'll use the action of the first plugin which offers one
+ PluginList::Iterator it;
+ for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) {
+ syncAction = (*it)->syncActions()->first();
+ if ( syncAction ) {
+ mSyncActions->setIcon( syncAction->icon() );
+ mSyncActions->setText( syncAction->text() );
+ break;
+ }
+ }
+ }
+ }
+ }
+ QStringList invisibleActions = plugin->invisibleToolbarActions();
+
+ QStringList::ConstIterator it;
+ for ( it = invisibleActions.begin(); it != invisibleActions.end(); ++it ) {
+ KAction *action = part->actionCollection()->action( (*it).latin1() );
+ if ( action ) {
+ QPtrListIterator<KToolBar> it( toolBarIterator() );
+ for ( ; it.current() ; ++it ) {
+ action->unplug( it.current() );
+ }
+ }
+ }
+
+ KApplication::restoreOverrideCursor();
+}
+
+void MainWindow::selectPlugin( const QString &pluginName )
+{
+ PluginList::ConstIterator end = mPlugins.end();
+ for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it )
+ if ( ( *it )->identifier() == pluginName ) {
+ selectPlugin( *it );
+ return;
+ }
+}
+
+void MainWindow::loadSettings()
+{
+ if ( mSplitter )
+ mSplitter->setSizes( Prefs::self()->mSidePaneSplitter );
+
+ // Preload Plugins. This _must_ happen before the default part is loaded
+ PluginList::ConstIterator it;
+ for ( it = mDelayedPreload.begin(); it != mDelayedPreload.end(); ++it )
+ selectPlugin( *it );
+
+ selectPlugin( Prefs::self()->mActivePlugin );
+}
+
+void MainWindow::saveSettings()
+{
+ if ( mSplitter )
+ Prefs::self()->mSidePaneSplitter = mSplitter->sizes();
+
+ if ( mCurrentPlugin )
+ Prefs::self()->mActivePlugin = mCurrentPlugin->identifier();
+}
+
+void MainWindow::slotShowTip()
+{
+ showTip( true );
+}
+
+void MainWindow::slotRequestFeature()
+{
+ if ( kapp )
+ kapp->invokeBrowser( "http://kontact.org/shopping" );
+}
+
+void MainWindow::slotShowIntroduction()
+{
+ mPartsStack->raiseWidget( 0 ); // ###
+}
+
+void MainWindow::showTip( bool force )
+{
+ QStringList tips;
+ PluginList::ConstIterator end = mPlugins.end();
+ for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) {
+ QString file = (*it)->tipFile();
+ if ( !file.isEmpty() )
+ tips.append( file );
+ }
+
+ KTipDialog::showMultiTip( this, tips, force );
+}
+
+void MainWindow::slotQuit()
+{
+ mReallyClose = true;
+ close();
+}
+
+void MainWindow::slotPreferences()
+{
+ static SettingsDialogWrapper *dlg = 0;
+ if ( !dlg ) {
+ // do not show settings of components running standalone
+ QValueList<KPluginInfo*> filteredPlugins = mPluginInfos;
+ PluginList::ConstIterator it;
+ for ( it = mPlugins.begin(); it != mPlugins.end(); ++it )
+ if ( (*it)->isRunningStandalone() ) {
+ QValueList<KPluginInfo*>::ConstIterator infoIt;
+ for ( infoIt = filteredPlugins.begin(); infoIt != filteredPlugins.end(); ++infoIt ) {
+ if ( (*infoIt)->pluginName() == (*it)->identifier() ) {
+ filteredPlugins.remove( *infoIt );
+ break;
+ }
+ }
+ }
+ dlg = new SettingsDialogWrapper( KSettings::Dialog::Configurable, this );
+ dlg->addPluginInfos( filteredPlugins );
+ connect( dlg, SIGNAL( pluginSelectionChanged() ),
+ SLOT( pluginsChanged() ) );
+ }
+
+ dlg->show();
+ dlg->fixButtonLabel( this );
+}
+
+int MainWindow::startServiceFor( const QString& serviceType,
+ const QString& constraint,
+ const QString& preferences,
+ QString *error, QCString* dcopService,
+ int flags )
+{
+ PluginList::ConstIterator end = mPlugins.end();
+ for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) {
+ if ( (*it)->createDCOPInterface( serviceType ) ) {
+ kdDebug(5600) << "found interface for " << serviceType << endl;
+ if ( dcopService )
+ *dcopService = (*it)->dcopClient()->appId();
+ kdDebug(5600) << "appId=" << (*it)->dcopClient()->appId() << endl;
+ return 0; // success
+ }
+ }
+
+ kdDebug(5600) <<
+ "Didn't find dcop interface, falling back to external process" << endl;
+
+ return KDCOPServiceStarter::startServiceFor( serviceType, constraint,
+ preferences, error, dcopService, flags );
+}
+
+void MainWindow::pluginsChanged()
+{
+ unplugActionList( "navigator_actionlist" );
+ unloadPlugins();
+ loadPlugins();
+ mSidePane->updatePlugins();
+ plugActionList( "navigator_actionlist", mSidePane->actions() );
+}
+
+void MainWindow::updateConfig()
+{
+ kdDebug( 5600 ) << k_funcinfo << endl;
+
+ saveSettings();
+ loadSettings();
+}
+
+void MainWindow::showAboutDialog()
+{
+ KApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
+
+ if ( !mAboutDialog )
+ mAboutDialog = new AboutDialog( this );
+
+ mAboutDialog->show();
+ mAboutDialog->raise();
+ KApplication::restoreOverrideCursor();
+}
+
+void MainWindow::configureShortcuts()
+{
+ KKeyDialog dialog( true, this );
+ dialog.insert( actionCollection() );
+
+ if ( mCurrentPlugin && mCurrentPlugin->part() )
+ dialog.insert( mCurrentPlugin->part()->actionCollection() );
+
+ dialog.configure();
+}
+
+void MainWindow::configureToolbars()
+{
+ saveMainWindowSettings( KGlobal::config(), "MainWindow" );
+
+ KEditToolbar edit( factory() );
+ connect( &edit, SIGNAL( newToolbarConfig() ),
+ this, SLOT( slotNewToolbarConfig() ) );
+ edit.exec();
+}
+
+void MainWindow::slotNewToolbarConfig()
+{
+ if ( mCurrentPlugin && mCurrentPlugin->part() )
+ createGUI( mCurrentPlugin->part() );
+ applyMainWindowSettings( KGlobal::config(), "MainWindow" );
+}
+
+void MainWindow::slotOpenUrl( const KURL &url )
+{
+ if ( url.protocol() == "exec" ) {
+ if ( url.path() == "/switch" ) {
+ selectPlugin( mCurrentPlugin );
+ }
+ if ( url.path() == "/gwwizard" ) {
+ KRun::runCommand( "groupwarewizard" );
+ slotQuit();
+ }
+ } else
+ new KRun( url, this );
+}
+
+void MainWindow::readProperties( KConfig *config )
+{
+ Core::readProperties( config );
+
+ QStringList activePlugins = config->readListEntry( "ActivePlugins" );
+ QValueList<Plugin*>::ConstIterator it = mPlugins.begin();
+ QValueList<Plugin*>::ConstIterator end = mPlugins.end();
+ for ( ; it != end; ++it ) {
+ Plugin *plugin = *it;
+ if ( !plugin->isRunningStandalone() ) {
+ QStringList::ConstIterator activePlugin = activePlugins.find( plugin->identifier() );
+ if ( activePlugin != activePlugins.end() ) {
+ plugin->readProperties( config );
+ }
+ }
+ }
+}
+
+void MainWindow::saveProperties( KConfig *config )
+{
+ Core::saveProperties( config );
+
+ QStringList activePlugins;
+
+ KPluginInfo::List::Iterator it = mPluginInfos.begin();
+ KPluginInfo::List::Iterator end = mPluginInfos.end();
+ for ( ; it != end; ++it ) {
+ KPluginInfo *info = *it;
+ if ( info->isPluginEnabled() ) {
+ Plugin *plugin = pluginFromInfo( info );
+ if ( plugin ) {
+ activePlugins.append( plugin->identifier() );
+ plugin->saveProperties( config );
+ }
+ }
+ }
+
+ config->writeEntry( "ActivePlugins", activePlugins );
+}
+
+bool MainWindow::queryClose()
+{
+ if ( kapp->sessionSaving() || mReallyClose )
+ return true;
+
+ bool localClose = true;
+ QValueList<Plugin*>::ConstIterator end = mPlugins.end();
+ QValueList<Plugin*>::ConstIterator it = mPlugins.begin();
+ for ( ; it != end; ++it ) {
+ Plugin *plugin = *it;
+ if ( !plugin->isRunningStandalone() )
+ if ( !plugin->queryClose() )
+ localClose = false;
+ }
+
+ return localClose;
+}
+
+void MainWindow::slotShowStatusMsg( const QString &msg )
+{
+ if ( !statusBar() || !mStatusMsgLabel )
+ return;
+
+ mStatusMsgLabel->setText( msg );
+}
+
+QString MainWindow::introductionString()
+{
+ KIconLoader *iconloader = KGlobal::iconLoader();
+ int iconSize = iconloader->currentSize( KIcon::Desktop );
+
+ QString handbook_icon_path = iconloader->iconPath( "contents2", KIcon::Desktop );
+ QString html_icon_path = iconloader->iconPath( "html", KIcon::Desktop );
+ QString wizard_icon_path = iconloader->iconPath( "wizard", KIcon::Desktop );
+
+ QString info = i18n( "<h2 style='text-align:center; margin-top: 0px;'>Welcome to Kontact %1</h2>"
+ "<p>%1</p>"
+ "<table align=\"center\">"
+ "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
+ "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
+ "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
+ "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
+ "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>"
+ "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>"
+ "</table>"
+ "<p style=\"margin-bottom: 0px\"> <a href=\"%1\">Skip this introduction</a></p>" )
+ .arg( kapp->aboutData()->version() )
+ .arg( i18n( "Kontact handles your e-mail, addressbook, calendar, to-do list and more." ) )
+ .arg( "help:/kontact" )
+ .arg( iconSize )
+ .arg( iconSize )
+ .arg( handbook_icon_path )
+ .arg( "help:/kontact" )
+ .arg( i18n( "Read Manual" ) )
+ .arg( i18n( "Learn more about Kontact and its components" ) )
+ .arg( "http://kontact.org" )
+ .arg( iconSize )
+ .arg( iconSize )
+ .arg( html_icon_path )
+ .arg( "http://kontact.org" )
+ .arg( i18n( "Visit Kontact Website" ) )
+ .arg( i18n( "Access online resources and tutorials" ) )
+ .arg( "exec:/gwwizard" )
+ .arg( iconSize )
+ .arg( iconSize )
+ .arg( wizard_icon_path )
+ .arg( "exec:/gwwizard" )
+ .arg( i18n( "Configure Kontact as Groupware Client" ) )
+ .arg( i18n( "Prepare Kontact for use in corporate networks" ) )
+ .arg( "exec:/switch" );
+ return info;
+}
+
+#include "mainwindow.moc"
diff --git a/kontact/src/mainwindow.h b/kontact/src/mainwindow.h
new file mode 100644
index 000000000..a96d5bf6b
--- /dev/null
+++ b/kontact/src/mainwindow.h
@@ -0,0 +1,168 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
+ Copyright (c) 2002-2005 Daniel Molkentin <molkentin@kde.org>
+ Copyright (c) 2003-2005 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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 KONTACT_MAINWINDOW_H
+#define KONTACT_MAINWINDOW_H
+
+#include <qguardedptr.h>
+#include <qptrlist.h>
+#include <qwidgetstack.h>
+
+#include <kparts/mainwindow.h>
+#include <kparts/part.h>
+#include <kparts/partmanager.h>
+#include <kdcopservicestarter.h>
+
+#include "core.h"
+#include "kontactiface.h"
+
+class QHBox;
+class QSplitter;
+class QVBox;
+class QFrame;
+
+class KAction;
+class KConfig;
+class KPluginInfo;
+class KRSqueezedTextLabel;
+class KHTMLPart;
+class KeyPressEater;
+
+namespace KPIM
+{
+ class StatusbarProgressWidget;
+}
+
+namespace Kontact
+{
+
+class Plugin;
+class SidePaneBase;
+class AboutDialog;
+
+typedef QValueList<Kontact::Plugin*> PluginList;
+
+class MainWindow : public Kontact::Core, public KDCOPServiceStarter, public KontactIface
+{
+ Q_OBJECT
+
+ public:
+ MainWindow();
+ ~MainWindow();
+
+ // KDCOPServiceStarter interface
+ virtual int startServiceFor( const QString& serviceType,
+ const QString& constraint = QString::null,
+ const QString& preferences = QString::null,
+ QString *error = 0, QCString* dcopService = 0,
+ int flags = 0 );
+
+ virtual PluginList pluginList() const { return mPlugins; }
+ void setActivePluginModule( const QString & );
+
+ public slots:
+ virtual void selectPlugin( Kontact::Plugin *plugin );
+ virtual void selectPlugin( const QString &pluginName );
+
+ void updateConfig();
+
+ protected slots:
+ void initObject();
+ void initGUI();
+ void slotActivePartChanged( KParts::Part *part );
+ void slotPreferences();
+ void slotNewClicked();
+ void slotSyncClicked();
+ void slotQuit();
+ void slotShowTip();
+ void slotRequestFeature();
+ void slotConfigureProfiles();
+ void slotLoadProfile( const QString& id );
+ void slotSaveToProfile( const QString& id );
+ void slotNewToolbarConfig();
+ void slotShowIntroduction();
+ void showAboutDialog();
+ void slotShowStatusMsg( const QString& );
+ void activatePluginModule();
+ void slotOpenUrl( const KURL &url );
+
+ private:
+ void initWidgets();
+ void initAboutScreen();
+ void loadSettings();
+ void saveSettings();
+
+ bool isPluginLoaded( const KPluginInfo * );
+ Kontact::Plugin *pluginFromInfo( const KPluginInfo * );
+ void loadPlugins();
+ void unloadPlugins();
+ bool removePlugin( const KPluginInfo * );
+ void addPlugin( Kontact::Plugin *plugin );
+ void partLoaded( Kontact::Plugin *plugin, KParts::ReadOnlyPart *part );
+ void setupActions();
+ void showTip( bool );
+ virtual bool queryClose();
+ virtual void readProperties( KConfig *config );
+ virtual void saveProperties( KConfig *config );
+ void paintAboutScreen( const QString& msg );
+ static QString introductionString();
+ KToolBar* findToolBar(const char* name);
+
+ private slots:
+ void pluginsChanged();
+
+ void configureShortcuts();
+ void configureToolbars();
+
+ private:
+ QFrame *mTopWidget;
+
+ QSplitter *mSplitter;
+
+ KToolBarPopupAction *mNewActions;
+ KToolBarPopupAction *mSyncActions;
+ SidePaneBase *mSidePane;
+ QWidgetStack *mPartsStack;
+ Plugin *mCurrentPlugin;
+ KParts::PartManager *mPartManager;
+ PluginList mPlugins;
+ PluginList mDelayedPreload;
+ QValueList<KPluginInfo*> mPluginInfos;
+ KHTMLPart *mIntroPart;
+
+ KRSqueezedTextLabel* mStatusMsgLabel;
+ KPIM::StatusbarProgressWidget *mLittleProgress;
+
+ QString mActiveModule;
+
+ QMap<QString, QGuardedPtr<QWidget> > mFocusWidgets;
+
+ AboutDialog *mAboutDialog;
+ bool mReallyClose;
+ bool mSyncActionsEnabled;
+};
+
+}
+
+#endif
+// vim: sw=2 sts=2 et
diff --git a/kontact/src/prefs.kcfgc b/kontact/src/prefs.kcfgc
new file mode 100644
index 000000000..0c200c592
--- /dev/null
+++ b/kontact/src/prefs.kcfgc
@@ -0,0 +1,13 @@
+# Code generation options for kconfig_compiler
+File=kontact.kcfg
+NameSpace=Kontact
+ClassName=Prefs
+Singleton=true
+Mutators=true
+#Inherits=KPimPrefs
+#IncludeFiles=libkdepim/kpimprefs.h
+Visibility=KDE_EXPORT
+MemberVariables=public
+GlobalEnums=true
+ItemAccessors=true
+SetUserTexts=true
diff --git a/kontact/src/profiledialog.cpp b/kontact/src/profiledialog.cpp
new file mode 100644
index 000000000..9525c968a
--- /dev/null
+++ b/kontact/src/profiledialog.cpp
@@ -0,0 +1,267 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include "profiledialog.h"
+#include "profilemanager.h"
+
+#include <kfiledialog.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qstring.h>
+
+Kontact::ProfileDialog::ProfileDialog( QWidget* parent, WFlags flags ) : KDialogBase( parent, /*name=*/0, /*modal=*/true, /*caption=*/QString(), /*buttonMask=*/KDialogBase::Ok|KDialogBase::Close )
+{
+ setWFlags( flags );
+ setCaption( i18n("Configure Profiles") );
+ setButtonOK( i18n("Load Profile") );
+
+ QWidget* mainWidget = new QWidget( this );
+
+ QHBoxLayout* horizontalLayout = new QHBoxLayout( mainWidget );
+ horizontalLayout->setSpacing( 5 );
+
+ m_list = new KListView( mainWidget );
+ m_list->addColumn( i18n("Name") );
+ m_list->addColumn( i18n("Description") );
+ m_list->setSelectionMode( QListView::Single );
+ m_list->setItemsRenameable( true );
+ m_list->setRenameable( NameColumn, true );
+ m_list->setRenameable( DescriptionColumn, true );
+
+ connect( m_list, SIGNAL( selectionChanged() ),
+ this, SLOT( listSelectionChanged() ) );
+ connect( m_list, SIGNAL( itemRenamed( QListViewItem*, const QString&, int ) ),
+ this, SLOT( listItemRenamed( QListViewItem*, const QString&, int ) ) );
+ horizontalLayout->addWidget( m_list );
+
+ QVBoxLayout* buttonLayout = new QVBoxLayout( horizontalLayout );
+ buttonLayout->setSpacing( 5 );
+
+ m_newProfileButton = new QPushButton( mainWidget );
+ m_newProfileButton->setText( i18n("New Profile") );
+ connect( m_newProfileButton, SIGNAL( clicked() ),
+ this, SLOT( addNewProfile() ) );
+ buttonLayout->addWidget( m_newProfileButton );
+
+ m_deleteProfileButton = new QPushButton( mainWidget );
+ m_deleteProfileButton->setText( i18n("Delete Profile") );
+ m_deleteProfileButton->setEnabled( false );
+ connect( m_deleteProfileButton, SIGNAL( clicked() ),
+ this, SLOT( deleteSelectedProfile() ) );
+ buttonLayout->addWidget( m_deleteProfileButton );
+
+ m_saveProfileButton = new QPushButton( mainWidget );
+ m_saveProfileButton->setText( i18n("Save Profile") );
+ m_saveProfileButton->setEnabled( false );
+ connect( m_saveProfileButton, SIGNAL( clicked() ),
+ this, SLOT( saveToSelectedProfile() ) );
+ buttonLayout->addWidget( m_saveProfileButton );
+
+ buttonLayout->addStretch();
+
+ m_importProfileButton = new QPushButton( mainWidget );
+ m_importProfileButton->setText( i18n("Import Profile") );
+ connect( m_importProfileButton, SIGNAL( clicked() ),
+ this, SLOT( importProfile() ) );
+ buttonLayout->addWidget( m_importProfileButton );
+
+ m_exportProfileButton = new QPushButton( mainWidget );
+ m_exportProfileButton->setText( i18n("Export Profile") );
+ m_exportProfileButton->setEnabled( false );
+ connect( m_exportProfileButton, SIGNAL( clicked() ),
+ this, SLOT( exportSelectedProfile() ) );
+ buttonLayout->addWidget( m_exportProfileButton );
+
+ setMainWidget( mainWidget );
+
+ connect( Kontact::ProfileManager::self(), SIGNAL( profileAdded( const QString& ) ),
+ this, SLOT( profileAdded( const QString& ) ) );
+ connect( Kontact::ProfileManager::self(), SIGNAL( profileRemoved( const QString& ) ),
+ this, SLOT( profileRemoved( const QString& ) ) );
+ connect( Kontact::ProfileManager::self(), SIGNAL( profileLoaded( const QString& ) ),
+ this, SLOT( profileLoaded( const QString& ) ) );
+ connect( Kontact::ProfileManager::self(), SIGNAL( profileUpdated( const QString& ) ),
+ this, SLOT( profileUpdated( const QString& ) ) );
+
+ const QValueList<Kontact::Profile> profiles = Kontact::ProfileManager::self()->profiles();
+ for ( QValueList<Kontact::Profile>::ConstIterator it = profiles.begin(), end = profiles.end(); it != end; ++it )
+ {
+ profileAdded( (*it).id() );
+ }
+ updateButtonState();
+}
+
+void Kontact::ProfileDialog::slotOk()
+{
+ loadSelectedProfile();
+ KDialogBase::slotOk();
+}
+
+QString Kontact::ProfileDialog::selectedProfile() const
+{
+ return m_itemToProfile[m_list->selectedItem()];
+}
+
+void Kontact::ProfileDialog::loadSelectedProfile()
+{
+ const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( selectedProfile() );
+ if ( profile.isNull() )
+ return;
+ Kontact::ProfileManager::self()->loadProfile( profile.id() );
+}
+
+void Kontact::ProfileDialog::profileLoaded( const QString& id )
+{
+ const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( id );
+ if ( profile.isNull() )
+ return;
+ KMessageBox::information( this, i18n("The profile \"%1\" was successfully loaded. Some profile settings require a restart to get activated.").arg( profile.name() ), i18n("Profile Loaded") );
+}
+
+void Kontact::ProfileDialog::saveToSelectedProfile()
+{
+ const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( selectedProfile() );
+ if ( profile.isNull() )
+ return;
+ if ( KMessageBox::Yes != KMessageBox::warningYesNo( this, i18n("The profile \"%1\" will be overwritten with the current settings. Are you sure?").arg( profile.name() ), i18n("Save to Profile"), KStdGuiItem::overwrite(), KStdGuiItem::cancel() ) )
+ return;
+ Kontact::ProfileManager::self()->saveToProfile( profile.id() );
+}
+
+void Kontact::ProfileDialog::deleteSelectedProfile()
+{
+ const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( selectedProfile() );
+ if ( profile.isNull() )
+ return;
+ if ( KMessageBox::Yes != KMessageBox::warningYesNo( this, i18n("Do you really want to delete the profile \"%1\"? All profile settings will be lost!").arg( profile.name() ), i18n("Delete Profile"), KStdGuiItem::del(), KStdGuiItem::cancel() ) )
+ return;
+ Kontact::ProfileManager::self()->removeProfile( profile );
+}
+
+void Kontact::ProfileDialog::exportSelectedProfile()
+{
+ const QString id = selectedProfile();
+ const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( id );
+ if ( profile.isNull() )
+ return;
+ const QString path = KFileDialog::getExistingDirectory( QString(), this, i18n("Select Profile Folder") );
+ if ( path.isNull() )
+ return;
+ const Kontact::ProfileManager::ExportError error = Kontact::ProfileManager::self()->exportProfileToDirectory( id, path );
+ if ( error == Kontact::ProfileManager::SuccessfulExport )
+ {
+ KMessageBox::information( this, i18n("The profile \"%1\" was successfully exported.").arg( profile.name() ), i18n("Profile Exported") );
+ }
+ else
+ {
+ // TODO print error
+ }
+}
+
+void Kontact::ProfileDialog::importProfile()
+{
+ const QString path = KFileDialog::getExistingDirectory( QString(), this, i18n("Select Profile Folder") );
+ if ( path.isNull() )
+ return;
+ const Kontact::ProfileManager::ImportError error = Kontact::ProfileManager::self()->importProfileFromDirectory( path );
+ if ( error != Kontact::ProfileManager::SuccessfulImport )
+ {
+ // TODO print error
+ }
+}
+
+void Kontact::ProfileDialog::profileAdded( const QString& id )
+{
+ Q_ASSERT( !m_profileToItem[id] );
+ const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( id );
+ Q_ASSERT( !profile.isNull() );
+ QListViewItem* const item = new QListViewItem( m_list );
+ m_profileToItem[id] = item;
+ m_itemToProfile[item] = id;
+ profileUpdated( id );
+}
+
+void Kontact::ProfileDialog::profileRemoved( const QString& id )
+{
+ QListViewItem* item = m_profileToItem[id];
+ Q_ASSERT( item );
+ m_profileToItem.remove( id );
+ m_itemToProfile.remove( item );
+ delete item;
+}
+
+void Kontact::ProfileDialog::profileUpdated( const QString& id )
+{
+ QListViewItem* item = m_profileToItem[id];
+ Q_ASSERT( item );
+ const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( id );
+ Q_ASSERT( !profile.isNull() );
+ item->setText( NameColumn, profile.name() );
+ item->setText( DescriptionColumn, profile.description() );
+}
+
+void Kontact::ProfileDialog::addNewProfile()
+{
+ Kontact::Profile profile( Kontact::ProfileManager::self()->generateNewId(), true );
+ profile.setName( i18n("New profile") );
+ profile.setDescription( i18n("Enter description") );
+ Kontact::ProfileManager::self()->addProfile( profile );
+}
+
+void Kontact::ProfileDialog::listItemRenamed( QListViewItem* item, const QString& text, int col )
+{
+ Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( m_itemToProfile[item] );
+ Q_ASSERT( !profile.isNull() );
+ switch ( col )
+ {
+ case NameColumn:
+ profile.setName( text );
+ Kontact::ProfileManager::self()->updateProfile( profile );
+ break;
+ case DescriptionColumn:
+ profile.setDescription( text );
+ Kontact::ProfileManager::self()->updateProfile( profile );
+ break;
+ }
+}
+
+void Kontact::ProfileDialog::updateButtonState()
+{
+ const bool hasSelection = m_list->selectedItem() != 0;
+ m_deleteProfileButton->setEnabled( hasSelection );
+ m_saveProfileButton->setEnabled( hasSelection);
+ actionButton( KDialogBase::Ok )->setEnabled( hasSelection );
+ m_exportProfileButton->setEnabled( hasSelection );
+}
+
+void Kontact::ProfileDialog::listSelectionChanged()
+{
+ updateButtonState();
+}
+
+#include "profiledialog.moc"
diff --git a/kontact/src/profiledialog.h b/kontact/src/profiledialog.h
new file mode 100644
index 000000000..7fa620e6e
--- /dev/null
+++ b/kontact/src/profiledialog.h
@@ -0,0 +1,90 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef KONTACT_PROFILEDIALOG_H
+#define KONTACT_PROFILEDIALOG_H
+
+#include <kdialogbase.h>
+
+#include <qmap.h>
+#include <qstring.h>
+
+class QListViewItem;
+
+class KListView;
+class QPushButton;
+
+namespace Kontact {
+
+class ProfileDialog : public KDialogBase
+{
+Q_OBJECT
+
+public:
+ explicit ProfileDialog( QWidget* parent = 0, WFlags f = 0 );
+
+private:
+ enum ListColumn {
+ NameColumn=0,
+ DescriptionColumn=1
+ };
+
+ QString selectedProfile() const;
+ void updateButtonState();
+
+protected slots:
+
+ //override
+ void slotOk();
+
+private slots:
+
+ void loadSelectedProfile();
+ void saveToSelectedProfile();
+ void deleteSelectedProfile();
+ void importProfile();
+ void exportSelectedProfile();
+ void addNewProfile();
+ void listSelectionChanged();
+ void listItemRenamed( QListViewItem* item, const QString& text, int col );
+
+ void profileAdded( const QString& id );
+ void profileRemoved( const QString& id );
+ void profileUpdated( const QString& id );
+ void profileLoaded( const QString& id );
+
+private:
+ KListView* m_list;
+ QPushButton* m_newProfileButton;
+ QPushButton* m_deleteProfileButton;
+ QPushButton* m_saveProfileButton;
+ QPushButton* m_importProfileButton;
+ QPushButton* m_exportProfileButton;
+ QMap<QListViewItem*, QString> m_itemToProfile;
+ QMap<QString, QListViewItem*> m_profileToItem;
+};
+
+} // Kontact
+
+#endif // KONTACT_PROFILEDIALOG_H
diff --git a/kontact/src/profilemanager.cpp b/kontact/src/profilemanager.cpp
new file mode 100644
index 000000000..53419cc54
--- /dev/null
+++ b/kontact/src/profilemanager.cpp
@@ -0,0 +1,340 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include "profilemanager.h"
+
+#include <kio/job.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kstaticdeleter.h>
+#include <kurl.h>
+
+#include <qdir.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+
+Kontact::Profile::Profile( const QString& id, bool isLocal ) : m_id( id ), m_local( isLocal )
+{
+}
+
+Kontact::Profile::Profile() : m_local( false )
+{
+}
+
+QString Kontact::Profile::id() const
+{
+ return m_id;
+}
+
+QString Kontact::Profile::name() const
+{
+ return m_name;
+}
+
+QString Kontact::Profile::description() const
+{
+ return m_description;
+}
+
+bool Kontact::Profile::isNull() const
+{
+ return m_id.isNull();
+}
+
+void Kontact::Profile::setId( const QString& id )
+{
+ m_id = id;
+}
+
+void Kontact::Profile::setDescription( const QString& description )
+{
+ m_description = description;
+}
+
+void Kontact::Profile::setName( const QString& name )
+{
+ m_name = name;
+}
+
+void Kontact::Profile::setLocal( SetLocalMode mode )
+{
+ if ( m_local )
+ return;
+
+ if ( mode == CopyProfileFiles )
+ copyConfigFiles( m_originalLocation, localSaveLocation() );
+
+ m_local = true;
+}
+
+bool Kontact::Profile::isLocal() const
+{
+ return m_local;
+}
+
+void Kontact::Profile::setOriginalLocation( const QString& path )
+{
+ m_originalLocation = path;
+}
+
+QString Kontact::Profile::localSaveLocation() const
+{
+
+ return m_id.isNull() ? QString() : locateLocal( "data", "kontact/profiles/" + m_id, /*create folder=*/true );
+}
+
+QString Kontact::Profile::saveLocation() const
+{
+ return m_local ? localSaveLocation() : m_originalLocation;
+}
+
+bool Kontact::Profile::operator==( const Kontact::Profile& other ) const
+{
+ return m_id == other.m_id && m_name == other.m_name && m_description == other.m_description;
+}
+
+Kontact::ProfileManager* Kontact::ProfileManager::m_self = 0;
+
+static KStaticDeleter<Kontact::ProfileManager> profileManagerSD;
+
+Kontact::ProfileManager* Kontact::ProfileManager::self()
+{
+ if ( m_self == 0 )
+ {
+ profileManagerSD.setObject( m_self, new Kontact::ProfileManager );
+ m_self->readConfig();
+ }
+ return m_self;
+}
+
+Kontact::ProfileManager::ProfileManager( QObject* parent ) : QObject( parent )
+{
+}
+
+Kontact::ProfileManager::~ProfileManager()
+{
+ writeConfig();
+}
+
+void Kontact::ProfileManager::writeConfig() const
+{
+ const QValueList<Kontact::Profile> profiles = m_profiles.values();
+ for ( QValueList<Kontact::Profile>::ConstIterator it = profiles.begin(), end = profiles.end(); it != end; ++it )
+ {
+ writeProfileConfig( *it );
+ }
+}
+
+Kontact::Profile Kontact::ProfileManager::readFromConfiguration( const QString& configFile, bool isLocal )
+{
+ KConfig profileCfg( configFile, true /*read-only*/, false /*no KDE global*/ );
+ const QString configDir = configFile.left( configFile.findRev( QDir::separator(), -1 ) );
+ profileCfg.setGroup( "Kontact Profile" );
+ const QString id = profileCfg.readEntry( "Identifier" );
+ Kontact::Profile profile( id );
+ profile.setName( profileCfg.readEntry( "Name" ) );
+ profile.setDescription( profileCfg.readEntry( "Description" ) );
+ profile.setOriginalLocation( configDir );
+ if ( isLocal )
+ profile.setLocal( Kontact::Profile::DoNotCopyProfileFiles );
+ return profile;
+}
+
+void Kontact::ProfileManager::writeProfileConfig( const Kontact::Profile& profile ) const
+{
+ const QString profileDir = profile.saveLocation();
+ const QString cfgPath = profileDir + "/profile.cfg";
+ KConfig profileCfg( cfgPath, false /*read-only*/, false /*no KDE global*/ );
+ profileCfg.setGroup( "Kontact Profile" );
+ profileCfg.writeEntry( "Identifier", profile.id() );
+ profileCfg.writeEntry( "Name", profile.name() );
+ profileCfg.writeEntry( "Description", profile.description() );
+}
+
+void Kontact::ProfileManager::readConfig()
+{
+
+ const QStringList profilePaths = KGlobal::dirs()->findAllResources( "data", QString::fromLatin1( "kontact/profiles/*/profile.cfg" ) );
+
+ typedef QMap<QString, Kontact::Profile> ProfileMap;
+ ProfileMap profiles;
+ ProfileMap globalProfiles;
+
+ const QString localPrefix = locateLocal( "data", "kontact/profiles/", /*createDir=*/false );
+ for ( QStringList::ConstIterator it = profilePaths.begin(), end = profilePaths.end(); it != end; ++it )
+ {
+ const bool isLocal = (*it).startsWith( localPrefix );
+ const Kontact::Profile profile = readFromConfiguration( *it, isLocal );
+ if ( profile.isNull() )
+ continue;
+ if ( isLocal )
+ profiles[profile.id()] = profile;
+ else
+ globalProfiles[profile.id()] = profile;
+ }
+
+ for ( ProfileMap::ConstIterator it = globalProfiles.begin(), end = globalProfiles.end(); it != end; ++it )
+ {
+ if ( !profiles.contains( it.key() ) )
+ profiles[it.key()] = it.data();
+ }
+
+ for ( ProfileMap::ConstIterator it = profiles.begin(), end = profiles.end(); it != end; ++it )
+ {
+ addProfile( *it, false /*dont sync config */ );
+ }
+}
+
+QValueList<Kontact::Profile> Kontact::ProfileManager::profiles() const
+{
+ return m_profiles.values();
+}
+
+Kontact::Profile Kontact::ProfileManager::profileById( const QString& id ) const
+{
+ return m_profiles[id];
+}
+
+void Kontact::ProfileManager::updateProfile( const Kontact::Profile& profile_ )
+{
+ const QString id = profile_.id();
+ if ( id.isNull() || m_profiles[id] == profile_ )
+ return;
+ Kontact::Profile profile( profile_ );
+ m_profiles[id] = profile;
+ profile.setLocal( Kontact::Profile::CopyProfileFiles );
+ writeProfileConfig( profile );
+ emit profileUpdated( id );
+}
+
+void Kontact::Profile::copyConfigFiles( const QString& source_, const QString& dest_ )
+{
+ const KURL source = KURL::fromPathOrURL( source_+"/*rc" );
+ const KURL dest = KURL::fromPathOrURL( dest_ );
+ KIO::CopyJob* job = KIO::copy( source, dest, /*showProgressInfo=*/false );
+ // TODO better check for the copy result
+}
+
+void Kontact::ProfileManager::saveToProfile( const QString& id )
+{
+ Kontact::Profile profile = profileById( id );
+ if ( profile.isNull() )
+ return;
+ profile.setLocal( Kontact::Profile::CopyProfileFiles );
+ writeProfileConfig( profile );
+ emit saveToProfileRequested( id );
+}
+
+bool Kontact::ProfileManager::addProfile( const Kontact::Profile& profile, bool syncConfig )
+{
+ const QString id = profile.id();
+ if ( m_profiles.contains( id ) )
+ return false;
+ m_profiles[id] = profile;
+ emit profileAdded( id );
+ emit saveToProfileRequested( id );
+ if ( syncConfig ) {
+ writeProfileConfig( profile );
+ }
+
+ return true;
+}
+
+void Kontact::ProfileManager::loadProfile( const QString& id )
+{
+ if ( !m_profiles.contains( id ) )
+ return;
+ emit profileLoaded( id );
+}
+
+void Kontact::ProfileManager::removeProfile( const Kontact::Profile& profile )
+{
+ removeProfile( profile.id() );
+}
+
+void Kontact::ProfileManager::removeProfile( const QString& id )
+{
+ if ( !m_profiles.contains( id ) )
+ return;
+ Kontact::Profile profile = profileById( id );
+ if ( profile.isLocal() ) {
+ KURL location = KURL::fromPathOrURL( profile.saveLocation() );
+ KIO::DeleteJob* job = KIO::del( location, /*shred*/ false, /*showProgressInfo=*/false );
+ // TODO check result
+ }
+ m_profiles.remove( id );
+ emit profileRemoved( id );
+ }
+
+Kontact::ProfileManager::ExportError Kontact::ProfileManager::exportProfileToDirectory( const QString& id, const QString& path )
+{
+ if ( !m_profiles.contains( id ) )
+ return SuccessfulExport;
+
+ if ( !QDir( path ).exists() )
+ return DirectoryDoesNotExist;
+
+ const Kontact::Profile profile = profileById( id );
+ const KURL source = KURL::fromPathOrURL( profile.saveLocation() );
+ const KURL target = KURL::fromPathOrURL( path + QDir::separator() + profile.name() );
+
+ KIO::CopyJob* job = KIO::copy( source, target, /*showProgressInfo=*/false );
+ // TODO check result
+
+ return SuccessfulExport;
+}
+
+Kontact::ProfileManager::ImportError Kontact::ProfileManager::importProfileFromDirectory( const QString& path )
+{
+ Kontact::Profile profile = readFromConfiguration( path + "/profile.cfg", /*isLocal=*/ true );
+ if ( profile.isNull() )
+ return NoValidProfile;
+
+ profile.setId( generateNewId() );
+
+ const KURL source = KURL::fromPathOrURL( path );
+ const KURL target = KURL::fromPathOrURL( profile.saveLocation() );
+
+ KIO::CopyJob* job = KIO::copy( source, target, /*showProgressInfo=*/false );
+ // TODO better check for the copy result
+
+ addProfile( profile );
+
+ return SuccessfulImport;
+}
+
+QString Kontact::ProfileManager::generateNewId() const
+{
+ while ( true )
+ {
+ const QString newId = KApplication::randomString( 10 );
+ if ( !m_profiles.contains( newId ) )
+ return newId;
+ }
+}
+
+#include "profilemanager.moc"
diff --git a/kontact/src/profilemanager.h b/kontact/src/profilemanager.h
new file mode 100644
index 000000000..e8b10adb5
--- /dev/null
+++ b/kontact/src/profilemanager.h
@@ -0,0 +1,162 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef KONTACT_PROFILEMANAGER_H
+#define KONTACT_PROFILEMANAGER_H
+
+#include <qmap.h>
+#include <qobject.h>
+#include <qstring.h>
+
+template <class T> class QValueList;
+
+namespace KIO {
+ class Job;
+}
+
+namespace Kontact {
+
+class Profile
+{
+ friend class ProfileManager;
+public:
+ Profile();
+
+ explicit Profile( const QString& id, bool isLocal = false );
+
+ QString id() const;
+
+ QString name() const;
+
+ QString description() const;
+
+ bool isNull() const;
+
+ void setName( const QString& name );
+
+ void setDescription( const QString& description );
+
+ bool operator==( const Kontact::Profile& other ) const;
+
+ QString saveLocation() const;
+
+private: // ProfileManager only
+
+ enum SetLocalMode {
+ DoNotCopyProfileFiles,
+ CopyProfileFiles
+ };
+ void setLocal( SetLocalMode mode );
+ bool isLocal() const;
+ void setOriginalLocation( const QString& path );
+ void setId( const QString& id );
+
+private:
+
+ static void copyConfigFiles( const QString& source, const QString& dest );
+
+ QString localSaveLocation() const;
+
+private:
+ QString m_id;
+ QString m_name;
+ QString m_description;
+ bool m_local;
+ QString m_originalLocation;
+};
+
+class ProfileManager : public QObject
+{
+Q_OBJECT
+public:
+ enum ImportError {
+ SuccessfulImport=0,
+ NoValidProfile
+ };
+
+ enum ExportError {
+ SuccessfulExport=0,
+ DirectoryDoesNotExist,
+ DirectoryNotWritable
+ };
+
+ static ProfileManager* self();
+
+ ~ProfileManager();
+
+ Kontact::Profile profileById( const QString& id ) const;
+
+ bool addProfile( const Kontact::Profile& profile, bool syncConfig = true );
+
+ void removeProfile( const Kontact::Profile& profile );
+
+ void removeProfile( const QString& id );
+
+ void updateProfile( const Kontact::Profile& profile );
+
+ void loadProfile( const QString& id );
+
+ void saveToProfile( const QString& id );
+
+ QValueList<Kontact::Profile> profiles() const;
+
+ ExportError exportProfileToDirectory( const QString& id, const QString& path );
+
+ ImportError importProfileFromDirectory( const QString& path );
+
+ QString generateNewId() const;
+
+signals:
+ void profileAdded( const QString& id );
+
+ void profileRemoved( const QString& id );
+
+ void profileUpdated( const QString& id );
+
+ void profileLoaded( const QString& id );
+
+ void saveToProfileRequested( const QString& id );
+
+ void profileImportFinished( ImportError status );
+
+private:
+ static ProfileManager* m_self;
+
+ static Kontact::Profile readFromConfiguration( const QString& configFile, bool isLocal );
+
+ explicit ProfileManager( QObject* parent = 0 );
+
+ void readConfig();
+
+ void writeConfig() const;
+
+ void writeProfileConfig( const Kontact::Profile& profile ) const;
+
+private:
+ QMap<QString, Kontact::Profile> m_profiles;
+};
+
+}
+
+#endif // KONTACT_PROFILEMANAGER_H
diff --git a/kontact/src/sidepanebase.cpp b/kontact/src/sidepanebase.cpp
new file mode 100644
index 000000000..781556085
--- /dev/null
+++ b/kontact/src/sidepanebase.cpp
@@ -0,0 +1,52 @@
+/*
+ This file is part of the KDE Kontact.
+
+ Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "core.h"
+
+#include "sidepanebase.h"
+
+using namespace Kontact;
+
+SidePaneBase::SidePaneBase( Core *core, QWidget *parent, const char *name )
+ : QVBox( parent, name ), mCore( core )
+{
+}
+
+SidePaneBase::~SidePaneBase()
+{
+}
+
+Core* SidePaneBase::core() const
+{
+ return mCore;
+}
+
+void SidePaneBase::setActionCollection( KActionCollection *actionCollection )
+{
+ mActionCollection = actionCollection;
+}
+
+KActionCollection *SidePaneBase::actionCollection() const
+{
+ return mActionCollection;
+}
+
+#include "sidepanebase.moc"
diff --git a/kontact/src/sidepanebase.h b/kontact/src/sidepanebase.h
new file mode 100644
index 000000000..95378f919
--- /dev/null
+++ b/kontact/src/sidepanebase.h
@@ -0,0 +1,79 @@
+/*
+ This file is part of the KDE Kontact.
+
+ Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef KONTACT_SIDEPANEBASE_H
+#define KONTACT_SIDEPANEBASE_H
+
+#include <qvbox.h>
+
+namespace KParts { class Part; }
+
+namespace Kontact
+{
+
+class Core;
+class Plugin;
+
+class SidePaneBase : public QVBox
+{
+ Q_OBJECT
+ public:
+ SidePaneBase( Core *core, QWidget *parent, const char *name = 0 );
+ virtual ~SidePaneBase();
+
+ void setActionCollection( KActionCollection *actionCollection );
+ KActionCollection *actionCollection() const;
+
+ virtual const QPtrList<KAction> & actions() = 0;
+
+ signals:
+ void pluginSelected( Kontact::Plugin* );
+
+ public slots:
+ /**
+ This method is called by the core whenever the count
+ of plugins has changed.
+ */
+ virtual void updatePlugins() = 0;
+
+ /**
+ Select the current plugin without emmiting a signal.
+ This is used to sync with the core.
+ */
+ virtual void selectPlugin( Kontact::Plugin* ) = 0;
+
+ /**
+ This is an overloaded member function. It behaves essentially like the
+ above function.
+ */
+ virtual void selectPlugin( const QString &name ) = 0;
+
+ virtual void indicateForegrunding( Kontact::Plugin* ) = 0;
+ protected:
+ Core* core() const;
+
+ private:
+ Core* mCore;
+ KActionCollection *mActionCollection;
+};
+
+}
+
+#endif