diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch) | |
tree | 67208f7c145782a7e90b123b982ca78d88cc2c87 /kontact/src | |
download | tdepim-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')
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 Binary files differnew file mode 100644 index 000000000..bf15f38b5 --- /dev/null +++ b/kontact/src/about/top-right-kontact.png 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 += " <<a href=\"mailto:" + email + "\">" + email + "</a>>"; + } + + 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 Binary files differnew file mode 100644 index 000000000..e8da426c5 --- /dev/null +++ b/kontact/src/hi128-app-kontact.png diff --git a/kontact/src/hi16-app-kontact.png b/kontact/src/hi16-app-kontact.png Binary files differnew file mode 100644 index 000000000..4d6e54d21 --- /dev/null +++ b/kontact/src/hi16-app-kontact.png diff --git a/kontact/src/hi22-app-kontact.png b/kontact/src/hi22-app-kontact.png Binary files differnew file mode 100644 index 000000000..af2614a26 --- /dev/null +++ b/kontact/src/hi22-app-kontact.png diff --git a/kontact/src/hi32-app-kontact.png b/kontact/src/hi32-app-kontact.png Binary files differnew file mode 100644 index 000000000..81d42536f --- /dev/null +++ b/kontact/src/hi32-app-kontact.png diff --git a/kontact/src/hi48-app-kontact.png b/kontact/src/hi48-app-kontact.png Binary files differnew file mode 100644 index 000000000..c45ac6f8d --- /dev/null +++ b/kontact/src/hi48-app-kontact.png diff --git a/kontact/src/hi64-app-kontact.png b/kontact/src/hi64-app-kontact.png Binary files differnew file mode 100644 index 000000000..7d2c409ed --- /dev/null +++ b/kontact/src/hi64-app-kontact.png 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>&File</text> + <Merge/> + <Separator/> + <Action name="action_new"/> + <Separator/> + <Action name="file_quit"/> + <Merge/> + </Menu> + <Merge /> + <Menu name="settings"> + <text>&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>&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 |