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 /kaddressbook/xxport | |
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 'kaddressbook/xxport')
52 files changed, 7127 insertions, 0 deletions
diff --git a/kaddressbook/xxport/HACKING b/kaddressbook/xxport/HACKING new file mode 100644 index 000000000..fb02930cd --- /dev/null +++ b/kaddressbook/xxport/HACKING @@ -0,0 +1,38 @@ +Coding Style +============= + +Please use the coding style conventions from kdepim/kaddressbook/HACKING +if you want to commit your xxport plugin into the cvs. + + + +Programming a XXPort Plugins +============================= + +Implementing a new xxport plugin is quite easy. But for better understanding +you should know what happens during the import or export. + +At first the modules are loaded by kaddressbook (or better said by the +xxportmanager class) and an instance of every modul is created. +In the constructor of a module, the methods createImportAction() and/or +createExportAction() should be called to register the import and/or +export gui items in the GUI menu. + +Now if the user selects one of the items, the xxportmanager searchs the proper +plugin. + +If the item was a export item, the manager do the following 2 steps: + 1) check if the modul requires a sorted list of addresses + 2) show a dialog where the user can select, which contacts shall be exported + and, if requested, which order the contacts shall have +Afterwards the exportContacts() method of the module is called with the +list of all contacts, the user filtered via the dialog. + +If the item was an import item, the importContacts() method of the proper +module is called directly. + +To implement your own module you just need to call the createXXportAction()s +in the constructor and reimplement the importContacts() and/or exportContacts() +method... thats all :) + +<will continue> diff --git a/kaddressbook/xxport/Makefile.am b/kaddressbook/xxport/Makefile.am new file mode 100644 index 000000000..5aebc23f2 --- /dev/null +++ b/kaddressbook/xxport/Makefile.am @@ -0,0 +1,64 @@ +INCLUDES = -I$(top_srcdir) \ + -I$(top_srcdir)/kaddressbook/interfaces \ + -I$(top_srcdir)/kaddressbook \ + -I$(top_srcdir)/libkdenetwork \ + $(GPGME_CFLAGS) \ + $(all_includes) + +if compile_GNOKIIXXPORT + gnokii_MODULE = libkaddrbk_gnokii_xxport.la + gnokii_RCFILE = gnokii_xxportui.rc +endif + +kde_module_LTLIBRARIES = libkaddrbk_csv_xxport.la libkaddrbk_vcard_xxport.la \ + libkaddrbk_kde2_xxport.la libkaddrbk_bookmark_xxport.la \ + libkaddrbk_eudora_xxport.la libkaddrbk_ldif_xxport.la \ + libkaddrbk_opera_xxport.la libkaddrbk_pab_xxport.la $(gnokii_MODULE) + +AM_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -no-undefined + +XXLIBS = $(top_builddir)/kaddressbook/interfaces/libkabinterfaces.la \ + $(top_builddir)/libkdepim/libkdepim.la + +libkaddrbk_csv_xxport_la_SOURCES = csv_xxport.cpp csvimportdialog.cpp dateparser.cpp +libkaddrbk_csv_xxport_la_LIBADD = $(XXLIBS) + +libkaddrbk_vcard_xxport_la_SOURCES = vcard_xxport.cpp +libkaddrbk_vcard_xxport_la_LIBADD = $(XXLIBS) \ + $(top_builddir)/kaddressbook/libkaddressbook.la \ + $(top_builddir)/libkdenetwork/qgpgme/libqgpgme.la + +libkaddrbk_kde2_xxport_la_SOURCES = kde2_xxport.cpp +libkaddrbk_kde2_xxport_la_LIBADD = $(XXLIBS) + +libkaddrbk_bookmark_xxport_la_SOURCES = bookmark_xxport.cpp +libkaddrbk_bookmark_xxport_la_LIBADD = $(XXLIBS) + +libkaddrbk_eudora_xxport_la_SOURCES = eudora_xxport.cpp +libkaddrbk_eudora_xxport_la_LIBADD = $(XXLIBS) + +libkaddrbk_ldif_xxport_la_SOURCES = ldif_xxport.cpp +libkaddrbk_ldif_xxport_la_LIBADD = $(XXLIBS) + +libkaddrbk_gnokii_xxport_la_SOURCES = gnokii_xxport.cpp +libkaddrbk_gnokii_xxport_la_LIBADD = $(XPMLIB) $(LIB_GNOKII) $(XXLIBS) + +libkaddrbk_opera_xxport_la_SOURCES = opera_xxport.cpp +libkaddrbk_opera_xxport_la_LIBADD = $(XXLIBS) + +libkaddrbk_pab_xxport_la_SOURCES = pab_xxport.cpp pab_mapihd.cpp pab_pablib.cpp +libkaddrbk_pab_xxport_la_LIBADD = $(XXLIBS) + +noinst_HEADERS = csvimportdialog.h + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kaddressbook +service_DATA = csv_xxport.desktop vcard_xxport.desktop kde2_xxport.desktop \ + bookmark_xxport.desktop eudora_xxport.desktop ldif_xxport.desktop \ + gnokii_xxport.desktop opera_xxport.desktop pab_xxport.desktop + +rcdir = $(kde_datadir)/kaddressbook +rc_DATA = csv_xxportui.rc vcard_xxportui.rc kde2_xxportui.rc \ + bookmark_xxportui.rc eudora_xxportui.rc ldif_xxportui.rc \ + opera_xxportui.rc pab_xxportui.rc $(gnokii_RCFILE) diff --git a/kaddressbook/xxport/bookmark_xxport.cpp b/kaddressbook/xxport/bookmark_xxport.cpp new file mode 100644 index 000000000..0a8d71bef --- /dev/null +++ b/kaddressbook/xxport/bookmark_xxport.cpp @@ -0,0 +1,72 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Alexander Kellett <[email protected]> + Tobias Koenig <[email protected]> + + 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 <kbookmark.h> +#include <kbookmarkmanager.h> +#include <kbookmarkmenu.h> +#include <kbookmarkdombuilder.h> +#include <klocale.h> +#include <kstandarddirs.h> + +#include "bookmark_xxport.h" + +K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_bookmark_xxport, BookmarkXXPort ) + +BookmarkXXPort::BookmarkXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) + : KAB::XXPort( ab, parent, name ) +{ + createExportAction( i18n( "Export Bookmarks Menu..." ) ); +} + +bool BookmarkXXPort::exportContacts( const KABC::AddresseeList &list, const QString& ) +{ + QString fileName = locateLocal( "data", "kabc/bookmarks.xml" ); + + KBookmarkManager *mgr = KBookmarkManager::managerForFile( fileName ); + KBookmarkDomBuilder *builder = new KBookmarkDomBuilder( mgr->root(), mgr ); + builder->connectImporter( this ); + + KABC::AddresseeList::ConstIterator it; + emit newFolder( i18n( "AddressBook" ), false, "" ); + for ( it = list.begin(); it != list.end(); ++it ) { + if ( !(*it).url().isEmpty() ) { + QString name = (*it).givenName() + " " + (*it).familyName(); + emit newBookmark( name, (*it).url().url().latin1(), QString( "" ) ); + } + } + emit endFolder(); + delete builder; + mgr->save(); + + KBookmarkMenu::DynMenuInfo menu; + menu.name = i18n( "Addressbook Bookmarks" ); + menu.location = fileName; + menu.type = "xbel"; + menu.show = true; + KBookmarkMenu::setDynamicBookmarks( "kabc", menu ); + + return true; +} + +#include "bookmark_xxport.moc" diff --git a/kaddressbook/xxport/bookmark_xxport.desktop b/kaddressbook/xxport/bookmark_xxport.desktop new file mode 100644 index 000000000..54d337162 --- /dev/null +++ b/kaddressbook/xxport/bookmark_xxport.desktop @@ -0,0 +1,103 @@ +[Desktop Entry] +X-KDE-Library=libkaddrbk_bookmark_xxport +Name=KAB Bookmark XXPort Plugin +Name[af]=KAB boekmerk XXPort inprop module +Name[be]=Дапаўненне KAB "Экспарт у закладкі" +Name[bg]=Приставка за XXPort отметки в KAB +Name[br]=Lugent XXPorzh sined KAB +Name[bs]=KAB dodatak za XXPort zabilješki +Name[ca]=Endollable d'importació/exportació de punts per al KAB +Name[cs]=Exportní modul záložek +Name[cy]=Ategyn XXPort Tudnodau KAB +Name[da]=KAB Bogmærke XXPort-plugin +Name[de]=Lesezeichen-XXPort-Modul für Adressbuch +Name[el]=Πρόσθετο εξαγωγής σελιδοδεικτών του KAB +Name[es]=Plugin de KAB para {im,ex}portar marcadores +Name[et]=KAB järjehoidjate eksportplugin +Name[eu]=KAB-en laster-marka in/esportazio plugin-a +Name[fa]=وصلۀ XXPort چوب الف KAB +Name[fi]=KAB-kirjanmerkkiliitännäinen +Name[fr]=Module d'import / export de signets pour KAB +Name[fy]=KAB Blêdwizer XXPort-plugin +Name[gl]=Extensión XXPort de Marcadores para KAB +Name[hi]=केएबी पसंदीदा XXपोर्ट प्लगइन +Name[hu]=KAB könyvjelzőkezelő XXPort bővítőmodul +Name[is]=Íforrit fyrir KAB XXPort bókarmerki +Name[ja]=KAB ブックマーク インポート/エクスポートプラグイン +Name[ka]=KAB სანიშნეების ექსპორტის მოდული +Name[kk]=Бетбелгіні экспорт ету +Name[km]=កម្មវិធីជំនួយ KAB Bookmark XXPort +Name[lt]=KAB žymelių XXPort priedas +Name[ms]=Plug masuk KAB Tanda Laman XXPort +Name[nb]=KAB-programtillegg for bokmerkeeksport +Name[nds]=Leesteken-Exportmoduul för KAdressbook +Name[ne]=KAB पुस्तकचिनो XXPort प्लगइन +Name[nl]=KAB Bladwijzer XXPort-plugin +Name[nn]=KAB-bokmerke XXPort-programtillegg +Name[pl]=Wtyczka KAB do eksportu zakładek +Name[pt]='Plugin' de Exportação XXPort de Favoritos do KAB +Name[pt_BR]=Plug-in de Exportação de Marcadores do KAB +Name[ru]=Экспорт закладок +Name[sk]=KAB modul pre xxport záložiek +Name[sl]=Vstavek KAB Bookmark XXPort +Name[sr]=XXPort прикључак KAB-а за маркере +Name[sr@Latn]=XXPort priključak KAB-a za markere +Name[sv]=Adressbokens överföringsinsticksprogram för bokmärken +Name[ta]=KAB புக்மார்க் ஏற்றுமதி சொருகுப்பொருள் +Name[tg]=Содироти поягузор +Name[tr]=KAB Yer imleri XXPort Eklentisi +Name[uk]=Втулок обміну закладками KAB +Name[zh_CN]=KAB 书签 XXPort 插件 +Name[zh_TW]=KAB Bookmark XXPort 外掛程式 +Comment=Plugin to export the web addresses of the contacts as bookmarks +Comment[af]=Inprop module wat die web adresse van kontakte as boekmerke uitvoer +Comment[bg]=Приставка за експортиране на уеб адресите на контактите, като отметки +Comment[bs]=Dodatak za izvoz web adresa kontakata u formi zabilješki +Comment[ca]=Endollable per a exportar les adreces web dels contactes com a punts +Comment[cs]=Modul pro exportování webových adres kontaktů jako záložky +Comment[cy]=Ategyn i allforio cyfeiriadau gwê y cysylltau fel tudnodau +Comment[da]=Plugin til at eksporte netadresser for kontakter som bogmærker +Comment[de]=Modul zum Export von Web-Adressen der Kontakte als Lesezeichen +Comment[el]=Πρόσθετο για εξαγωγή των διευθύνσεων ιστοσελίδων των επαφών σαν σελιδοδείκτες +Comment[es]=Plugin para exportar las direcciones web de los contactos como marcadores +Comment[et]=Plugin kontaktide veebiaadresside eksportimiseks järjehoidjatena +Comment[eu]=Kontaktuen web-helbideak laster-markak bezala esportatzeko plugin-a +Comment[fa]=وصله برای صادرات نشانیهای وب تماسها به عنوان چوب الفها +Comment[fi]=Liitännäinen, joka muuntaa kontaktien sisältämät verkko-osoitteet kirjanmerkeiksi +Comment[fr]=Module d'export des adresses internet des contacts en signets +Comment[fy]=Plugin foar it eksportearjen fan de webadressen fan de kontaktpersoanen as blêdwizers +Comment[gl]=Extensión para exportar os enderezos web dos contactos como marcadores +Comment[hi]=सम्पर्कों के वेब पते को पसंदीदा के रूप में निर्यात करने का प्लगइन +Comment[hu]=Bővítőmodul webcímek exportáláshoz, könyvjelzőként +Comment[is]=Íforrit til að skrá vefföng tengiliða sem bókarmerki +Comment[it]=Plugin per esportare come segnalibro gli indirizzi web dei contatti +Comment[ja]=連絡先のウェブアドレスをブックマークとしてエクスポートするプラグイン +Comment[ka]= კონტაქტების ვებ-მისამართების სანიშნეებად ექსპორტის მოდული +Comment[kk]=Контакттың веб адрестерін бетбелгіге экспорттау модулі +Comment[km]=កម្មវិធីជំនួយដើម្បីនាំចេញអាសយដ្ឋានបណ្ដាញរបស់ទំនាក់ទំនង ជាចំណាំ +Comment[lt]=Priedas skirtas žiniatinklio adresų kontaktuose eksportavimui į žymeles +Comment[mk]=Приклучок за изнесување на веб-адресите на контактите како обележувачи +Comment[ms]= Plug masuk untuk eksport alamat web untuk perhubungan sebagai tanda laman +Comment[nb]=Programtillegg som eksporterer kontaktenes nett-addresser som bokmerker +Comment[nds]=Moduul för't Exporteren vun Kontakt-Nettadressen as Leestekens +Comment[ne]=पुस्तकचिनो अनुरुपका सम्पर्कका वेब ठेगानाको निर्यात गर्न प्लगइन गर्नुहोस् +Comment[nl]=Plugin voor het exporteren van de webadressen van de contactpersonen als bladwijzers +Comment[nn]=Programtillegg for å eksportera nettadresser av kontaktar som bokmerker +Comment[pl]=Wtyczka eksportująca adresy WWW z wizytówek jako zakładki +Comment[pt]=Um 'plugin' para exportar os endereços Web dos contactos como favoritos +Comment[pt_BR]=Plug-in para exportar os endereços web de contatos como marcadores +Comment[ru]=Экспорт веб-адресов контактов как закладок +Comment[sk]=Modul pre export webových adries kontaktov ako záložiek +Comment[sl]=Vstavek za izvoz spletnih naslovov stikov v obliki zaznamkov +Comment[sr]=Прикључак за извоз веб-адреса контаката као маркера +Comment[sr@Latn]=Priključak za izvoz veb-adresa kontakata kao markera +Comment[sv]=Insticksprogram för export av kontaktwebbadresser som bokmärken +Comment[ta]=இணைய முகவரிகளின் தொடர்புகளை புத்தக குறிப்புகளாக ஏற்றுவதற்கு சொருகுப்பொருள் +Comment[tg]=Модул барои содироти веб-адресҳои алоқа ҳамчун поягузор +Comment[tr]=Bağlantıların web adreslerini yeri imleri olarak aktarmak için eklenti +Comment[uk]=Втулок для експорту адрес контактів у Тенетах як закладок +Comment[zh_CN]=将联系人的网址导出为书签的插件 +Comment[zh_TW]=匯出聯絡人的網頁成書籤的外掛程式 +Type=Service +ServiceTypes=KAddressBook/XXPort +X-KDE-KAddressBook-XXPortPluginVersion=1 diff --git a/kaddressbook/xxport/bookmark_xxport.h b/kaddressbook/xxport/bookmark_xxport.h new file mode 100644 index 000000000..5cc186ed6 --- /dev/null +++ b/kaddressbook/xxport/bookmark_xxport.h @@ -0,0 +1,53 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Alexander Kellett <[email protected]> + Tobias Koenig <[email protected]> + + 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 BOOKMARK_XXPORT_H +#define BOOKMARK_XXPORT_H + +#include <xxport.h> + +class BookmarkXXPort : public KAB::XXPort +{ + Q_OBJECT + + public: + BookmarkXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name = 0 ); + + QString identifier() const { return "bookmark"; } + + public slots: + bool exportContacts( const KABC::AddresseeList &list, const QString &data ); + + signals: + /** + The following signals are used for building a bookmarks file + using KBookmarkDomBuilder. + */ + void newBookmark( const QString &text, const QCString &url, const QString &additionnalInfo ); + void newFolder( const QString &text, bool open, const QString &additionnalInfo ); + void newSeparator(); + void endFolder(); +}; + +#endif diff --git a/kaddressbook/xxport/bookmark_xxportui.rc b/kaddressbook/xxport/bookmark_xxportui.rc new file mode 100644 index 000000000..654981465 --- /dev/null +++ b/kaddressbook/xxport/bookmark_xxportui.rc @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="bookmark_xxport" version="1"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Menu name="file_export"><text>&Export</text> + <Action name="file_export_bookmark"/> + </Menu> + </Menu> +</MenuBar> +</gui> diff --git a/kaddressbook/xxport/configure.in.bot b/kaddressbook/xxport/configure.in.bot new file mode 100644 index 000000000..67bc632e9 --- /dev/null +++ b/kaddressbook/xxport/configure.in.bot @@ -0,0 +1,7 @@ +if test "x$with_gnokii" = xcheck && test -z "$LIB_GNOKII"; then + echo "" + echo "libgnokii (http://www.gnokii.org) is missing. The KDE Addressbook mobile phone import/export filter will not be available." + echo "" + all_tests=bad +fi + diff --git a/kaddressbook/xxport/configure.in.in b/kaddressbook/xxport/configure.in.in new file mode 100644 index 000000000..3b0da67ae --- /dev/null +++ b/kaddressbook/xxport/configure.in.in @@ -0,0 +1,2 @@ +# $Id$ +AM_CONDITIONAL(compile_GNOKIIXXPORT, test -n "$LIB_GNOKII") diff --git a/kaddressbook/xxport/csv_xxport.cpp b/kaddressbook/xxport/csv_xxport.cpp new file mode 100644 index 000000000..31611f390 --- /dev/null +++ b/kaddressbook/xxport/csv_xxport.cpp @@ -0,0 +1,129 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Tobias Koenig <[email protected]> + + 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 <qfile.h> + +#include <kfiledialog.h> +#include <kio/netaccess.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <ktempfile.h> +#include <kurl.h> + +#include "csvimportdialog.h" + +#include "csv_xxport.h" + +K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_csv_xxport, CSVXXPort ) + +CSVXXPort::CSVXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) + : KAB::XXPort( ab, parent, name ) +{ + createImportAction( i18n( "Import CSV List..." ) ); + createExportAction( i18n( "Export CSV List..." ) ); +} + +bool CSVXXPort::exportContacts( const KABC::AddresseeList &list, const QString& ) +{ + KURL url = KFileDialog::getSaveURL( "addressbook.csv" ); + if ( url.isEmpty() ) + return true; + + if ( !url.isLocalFile() ) { + KTempFile tmpFile; + if ( tmpFile.status() != 0 ) { + QString txt = i18n( "<qt>Unable to open file <b>%1</b>.%2.</qt>" ); + KMessageBox::error( parentWidget(), txt.arg( url.url() ) + .arg( strerror( tmpFile.status() ) ) ); + return false; + } + + doExport( tmpFile.file(), list ); + tmpFile.close(); + + return KIO::NetAccess::upload( tmpFile.name(), url, parentWidget() ); + } else { + QFile file( url.path() ); + if ( !file.open( IO_WriteOnly ) ) { + QString txt = i18n( "<qt>Unable to open file <b>%1</b>.</qt>" ); + KMessageBox::error( parentWidget(), txt.arg( url.path() ) ); + return false; + } + + doExport( &file, list ); + file.close(); + + KMessageBox::information( parentWidget(), i18n( "The contacts have been exported successfully." ) ); + + return true; + } +} + +KABC::AddresseeList CSVXXPort::importContacts( const QString& ) const +{ + CSVImportDialog dlg( addressBook(), parentWidget() ); + if ( dlg.exec() ) + return dlg.contacts(); + else + return KABC::AddresseeList(); +} + +void CSVXXPort::doExport( QFile *fp, const KABC::AddresseeList &list ) +{ + QTextStream t( fp ); + t.setEncoding( QTextStream::Locale ); + + KABC::AddresseeList::ConstIterator iter; + KABC::Field::List fields = addressBook()->fields(); + KABC::Field::List::Iterator fieldIter; + bool first = true; + + // First output the column headings + for ( fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter ) { + if ( !first ) + t << ","; + + t << "\"" << (*fieldIter)->label() << "\""; + first = false; + } + t << "\n"; + + // Then all the addressee objects + KABC::Addressee addr; + for ( iter = list.begin(); iter != list.end(); ++iter ) { + addr = *iter; + first = true; + + for ( fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter ) { + if ( !first ) + t << ","; + + t << "\"" << (*fieldIter)->value( addr ).replace( "\n", "\\n" ) << "\""; + first = false; + } + + t << "\n"; + } +} + +#include "csv_xxport.moc" diff --git a/kaddressbook/xxport/csv_xxport.desktop b/kaddressbook/xxport/csv_xxport.desktop new file mode 100644 index 000000000..de6a51c42 --- /dev/null +++ b/kaddressbook/xxport/csv_xxport.desktop @@ -0,0 +1,102 @@ +[Desktop Entry] +X-KDE-Library=libkaddrbk_csv_xxport +Name=KAB CSV XXPort Plugin +Name[af]=KAB CSV XXPort inprop module +Name[be]=Дапаўненне KAB "Імпарт/Экспарт CSV" +Name[bg]=Приставка за CSV XXPort на KAB +Name[br]=Lugent XXPorzh CSV KAB +Name[bs]=KAB dodatak za CSV XXPort +Name[ca]=Endollable d'importació/exportació CSV per al KAB +Name[cs]=Exportní modul CSV +Name[cy]=Ategyn XXPort CSV KAB +Name[da]=KAB CSV XXPort-plugin +Name[de]=CSV-XXPort-Modul für Adressbuch +Name[el]=Πρόσθετο εισαγωγής/εξαγωγής CSV του KAB +Name[es]=Plugin de KAB para {im,ex}portar CSV +Name[et]=KAB CSV eksport/importplugin +Name[eu]=KAB-en CSV in/esportazioa plugin-a +Name[fa]=وصلۀ KAB CSV XXPort +Name[fi]=KAB CSV -liitännäinen +Name[fr]=Module d'import / export CSV pour KAB +Name[gl]=Extensión XXPort de CSV para KAB +Name[he]=תוסף ייבוא/ייצוא של קבצי CSV של KAB +Name[hi]=केएबी सीएसवी XXपोर्ट प्लगइन +Name[hu]=KAB XXPort bővítőmodul +Name[is]=Íforrit fyrir KAV CSV XXPort +Name[ja]=KAB CSV インポート/エクスポートプラグイン +Name[ka]=KAB CSV ექსპორტის მოდული +Name[kk]=CSV файлды экспорт/импорт ету +Name[km]=កម្មវិធីជំនួយ KAB CSV XXPort +Name[lt]=KAB CSV XXPort priedas +Name[ms]=Plug masuk KAB CSV XXPort +Name[nb]=KAB-programtillegg for CSV-eksport +Name[nds]=CSV-Im-/Exportmoduul för KAdressbook +Name[ne]=KAB CSV XXPort प्लगइन +Name[nn]=KAB CSV XXPort programtillegg +Name[pl]=Wtyczka KAB do importu/eksportu z/do formatu CSV +Name[pt]='Plugin' XXPort para CSV do KAB +Name[pt_BR]=Plug-in de Im/Exportação de CSV do KAB +Name[ru]=Экспорт/импорт в файлы CSV +Name[sl]=Vstavek KAB CSV XXPort +Name[sr]=XXPort прикључак KAB-а за CSV +Name[sr@Latn]=XXPort priključak KAB-a za CSV +Name[sv]=Adressbokens CSV-överföringsinsticksprogram +Name[ta]=KAB CSV ஏற்றுமதி சொருகுப்பொருள் +Name[tg]=Содирот/воридот ба файлҳои CSV +Name[tr]=KAB CSV XXPort Eklentisi +Name[uk]=Втулок KAB для обміну через CSV +Name[zh_CN]=KAB CSV XXPort 插件 +Name[zh_TW]=KAB CSV XXPort 外掛程式 +Comment=Plugin to import and export contacts in CSV format +Comment[af]=Inprop module wat kontakte in CSV formaat invoer en uitvoer +Comment[be]=Дапаўненне для імпарту і экспарту кантактаў у фармаце CSV +Comment[bg]=Приставка за импортиране/експортиране на контактите във формат CSV +Comment[bs]=Dodatak za uvoz i izvoz kontakata u CSV formatu +Comment[ca]=Endollable per a importar i exportar contactes en format CSV +Comment[cs]=Modul pro import a export kontaktů ve formátu CSV +Comment[cy]=Ategyn i fewnforio ac allforio cysylltau mewn fformat CSV +Comment[da]=Plugin til at importere og eksportere kontakter i CSV-format +Comment[de]=Modul zum Import/Export von Kontakten im CSV-Format +Comment[el]=Πρόσθετο για εισαγωγή και εξαγωγή των επαφών μορφής CSV +Comment[es]=Plugin para importar y exportar contactos en formato CSV +Comment[et]=Plugin kontaktide importimiseks ja eksportimiseks CSV vormingus +Comment[eu]=CSV formatuan kontaktuak esportatu eta inportatzeko plugin-a +Comment[fa]=وصله برای واردات و صادرات تماسها در قالب CSV +Comment[fi]=Liitännäinen kontaktien vientiin ja tuontiin CSV-muodossa +Comment[fr]=Module d'import / export de contacts au format CSV +Comment[fy]=Plugin foar it ymportearjen en eksportearjen fan kontaktpersoanen yn CSV-formaat +Comment[gl]=Extensión para importar e exportar contactos e formato CSV +Comment[hi]=सम्पर्कों को सीएसवी फार्मेट में निर्यात करने का प्लगइन +Comment[hu]=Bővítőmodul névjegyek importálásához/exportálásához, CSV formátumban +Comment[is]=Íforrit til að flytja tengiliði inn og út í CSV sniði +Comment[it]=Plugin per importare ed esportare contatti in formato CSV +Comment[ja]=CSV フォーマットで連絡先をインポート/エクスポートするプラグイン +Comment[ka]=კონტაქტების CSV ფორმატით იმპორტ/ექსპორტის მოდული +Comment[kk]=Контакттарды CSV пішіміне экспорт/импорт ету модулі +Comment[km]=កម្មវិធី ជំនួយដើម្បីនាំចូល និងនាំចេញទំនាក់ទំនងក្នុងទ្រង់ទ្រាយជា CSV ។ +Comment[lt]=Priedas, skirtas kontaktų eksportui ir importui CSV formatu +Comment[mk]=Приклучок за внесување и изнесување контакти во CSV-формат +Comment[ms]=Plug masuk untuk import dan eksport alamat perhubungan di dalam format CSV +Comment[nb]=Programtillegg for import/eksport av kontakter i CSV-format +Comment[nds]=Moduul för't Im- un Exporteren vun Kontakten in't CSV-Formaat +Comment[ne]=CSV ढाँचाका सम्पर्क आयात र निर्यात गर्न प्लगइन गर्नुहोस् +Comment[nl]=Plugin voor het importeren en exporteren van contactpersonen in CSV-formaat +Comment[nn]=Programtillegg for å importera og eksportera kontaktar i CSV-format +Comment[pl]=Wtyczka do importowania i eksportowania wizytówek w formacie CSV +Comment[pt]=Um 'plugin' para importar e exportar contactos no formato CSV +Comment[pt_BR]=Plug-in para importar e exportar contatos em formato CSV +Comment[ru]=Импорт и экспорт контактов в формате CSV +Comment[sk]=Modul pre import a export kontaktov vo formáte CSV +Comment[sl]=Vstavek za uvoz in izvoz stikov v obliki CSV +Comment[sr]=Прикључак за увоз и извоз контаката у CSV формат +Comment[sr@Latn]=Priključak za uvoz i izvoz kontakata u CSV format +Comment[sv]=Insticksprogram för import och export av kontakter med CSV-format +Comment[ta]=CSV வடிவத்தில் ஏற்றுமதி மற்றும் இறக்குமதி தொடர்புகளுக்கான சொருகுப்பொருள் +Comment[tg]=Модул барои воридот ва содироти алоқа ба формати CSV +Comment[tr]=CSV biçimindeki bağlantıları alma ve gönderme eklentisi +Comment[uk]=Втулок для імпорту та експорту контактів у форматі CSV +Comment[zh_CN]=导入和导出 CSV 格式联系人的插件 +Comment[zh_TW]=以 CSV 格式匯入與匯出聯絡人外掛程式 +Type=Service +ServiceTypes=KAddressBook/XXPort +X-KDE-KAddressBook-XXPortPluginVersion=1 diff --git a/kaddressbook/xxport/csv_xxport.h b/kaddressbook/xxport/csv_xxport.h new file mode 100644 index 000000000..972f4cad4 --- /dev/null +++ b/kaddressbook/xxport/csv_xxport.h @@ -0,0 +1,46 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Tobias Koenig <[email protected]> + + 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 CSV_XXPORT_H +#define CSV_XXPORT_H + +#include <xxport.h> + +class CSVXXPort : public KAB::XXPort +{ + Q_OBJECT + + public: + CSVXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name = 0 ); + + QString identifier() const { return "csv"; } + + public slots: + bool exportContacts( const KABC::AddresseeList &list, const QString &data ); + KABC::AddresseeList importContacts( const QString &data ) const; + + private: + void doExport( QFile *fp, const KABC::AddresseeList &list ); +}; + +#endif diff --git a/kaddressbook/xxport/csv_xxportui.rc b/kaddressbook/xxport/csv_xxportui.rc new file mode 100644 index 000000000..ff8f78a01 --- /dev/null +++ b/kaddressbook/xxport/csv_xxportui.rc @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="csv_xxport" version="1"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Menu name="file_import"><text>&Import</text> + <Action name="file_import_csv"/> + </Menu> + <Menu name="file_export"><text>&Export</text> + <Action name="file_export_csv"/> + </Menu> + </Menu> +</MenuBar> +</gui> diff --git a/kaddressbook/xxport/csvimportdialog.cpp b/kaddressbook/xxport/csvimportdialog.cpp new file mode 100644 index 000000000..f89222aff --- /dev/null +++ b/kaddressbook/xxport/csvimportdialog.cpp @@ -0,0 +1,962 @@ +/* + This file is part of KAddressBook. + Copyright (C) 2003 Tobias Koenig <[email protected]> + based on the code of KSpread's CSV Import Dialog + + 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. +*/ + + +#include <qbuttongroup.h> +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qradiobutton.h> +#include <qtable.h> +#include <qtextcodec.h> +#include <qtooltip.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <kfiledialog.h> +#include <klineedit.h> +#include <klocale.h> +#include <kinputdialog.h> +#include <kmessagebox.h> +#include <kprogress.h> +#include <kstandarddirs.h> +#include <kurlrequester.h> + +#include "dateparser.h" + +#include "csvimportdialog.h" + +enum { Local = 0, Guess = 1, Latin1 = 2, Uni = 3, MSBug = 4, Codec = 5 }; + +CSVImportDialog::CSVImportDialog( KABC::AddressBook *ab, QWidget *parent, + const char * name ) + : KDialogBase( Plain, i18n ( "CSV Import Dialog" ), Ok | Cancel | User1 | + User2, Ok, parent, name, true, true ), + mAdjustRows( false ), + mStartLine( 0 ), + mTextQuote( '"' ), + mDelimiter( "," ), + mAddressBook( ab ) +{ + initGUI(); + + mTypeMap.insert( i18n( "Undefined" ), Undefined ); + mTypeMap.insert( KABC::Addressee::formattedNameLabel(), FormattedName ); + mTypeMap.insert( KABC::Addressee::familyNameLabel(), FamilyName ); + mTypeMap.insert( KABC::Addressee::givenNameLabel(), GivenName ); + mTypeMap.insert( KABC::Addressee::additionalNameLabel(), AdditionalName ); + mTypeMap.insert( KABC::Addressee::prefixLabel(), Prefix ); + mTypeMap.insert( KABC::Addressee::suffixLabel(), Suffix ); + mTypeMap.insert( KABC::Addressee::nickNameLabel(), NickName ); + mTypeMap.insert( KABC::Addressee::birthdayLabel(), Birthday ); + + mTypeMap.insert( KABC::Addressee::homeAddressStreetLabel(), HomeAddressStreet ); + mTypeMap.insert( KABC::Addressee::homeAddressLocalityLabel(), + HomeAddressLocality ); + mTypeMap.insert( KABC::Addressee::homeAddressRegionLabel(), HomeAddressRegion ); + mTypeMap.insert( KABC::Addressee::homeAddressPostalCodeLabel(), + HomeAddressPostalCode ); + mTypeMap.insert( KABC::Addressee::homeAddressCountryLabel(), + HomeAddressCountry ); + mTypeMap.insert( KABC::Addressee::homeAddressLabelLabel(), HomeAddressLabel ); + + mTypeMap.insert( KABC::Addressee::businessAddressStreetLabel(), + BusinessAddressStreet ); + mTypeMap.insert( KABC::Addressee::businessAddressLocalityLabel(), + BusinessAddressLocality ); + mTypeMap.insert( KABC::Addressee::businessAddressRegionLabel(), + BusinessAddressRegion ); + mTypeMap.insert( KABC::Addressee::businessAddressPostalCodeLabel(), + BusinessAddressPostalCode ); + mTypeMap.insert( KABC::Addressee::businessAddressCountryLabel(), + BusinessAddressCountry ); + mTypeMap.insert( KABC::Addressee::businessAddressLabelLabel(), + BusinessAddressLabel ); + + mTypeMap.insert( KABC::Addressee::homePhoneLabel(), HomePhone ); + mTypeMap.insert( KABC::Addressee::businessPhoneLabel(), BusinessPhone ); + mTypeMap.insert( KABC::Addressee::mobilePhoneLabel(), MobilePhone ); + mTypeMap.insert( KABC::Addressee::homeFaxLabel(), HomeFax ); + mTypeMap.insert( KABC::Addressee::businessFaxLabel(), BusinessFax ); + mTypeMap.insert( KABC::Addressee::carPhoneLabel(), CarPhone ); + mTypeMap.insert( KABC::Addressee::isdnLabel(), Isdn ); + mTypeMap.insert( KABC::Addressee::pagerLabel(), Pager ); + mTypeMap.insert( KABC::Addressee::emailLabel(), Email ); + mTypeMap.insert( KABC::Addressee::mailerLabel(), Mailer ); + mTypeMap.insert( KABC::Addressee::titleLabel(), Title ); + mTypeMap.insert( KABC::Addressee::roleLabel(), Role ); + mTypeMap.insert( KABC::Addressee::organizationLabel(), Organization ); + mTypeMap.insert( KABC::Addressee::noteLabel(), Note ); + mTypeMap.insert( KABC::Addressee::urlLabel(), URL ); + + mCustomCounter = mTypeMap.count(); + int count = mCustomCounter; + + KABC::Field::List fields = mAddressBook->fields( KABC::Field::CustomCategory ); + KABC::Field::List::Iterator it; + for ( it = fields.begin(); it != fields.end(); ++it, ++count ) + mTypeMap.insert( (*it)->label(), count ); + + reloadCodecs(); + + connect( mDelimiterBox, SIGNAL( clicked( int ) ), + this, SLOT( delimiterClicked( int ) ) ); + connect( mDelimiterEdit, SIGNAL( returnPressed() ), + this, SLOT( returnPressed() ) ); + connect( mDelimiterEdit, SIGNAL( textChanged ( const QString& ) ), + this, SLOT( textChanged ( const QString& ) ) ); + connect( mComboLine, SIGNAL( activated( const QString& ) ), + this, SLOT( lineSelected( const QString& ) ) ); + connect( mComboQuote, SIGNAL( activated( const QString& ) ), + this, SLOT( textquoteSelected( const QString& ) ) ); + connect( mIgnoreDuplicates, SIGNAL( stateChanged( int ) ), + this, SLOT( ignoreDuplicatesChanged( int ) ) ); + connect( mCodecCombo, SIGNAL( activated( const QString& ) ), + this, SLOT( codecChanged() ) ); + + connect( mUrlRequester, SIGNAL( returnPressed( const QString& ) ), + this, SLOT( setFile( const QString& ) ) ); + connect( mUrlRequester, SIGNAL( urlSelected( const QString& ) ), + this, SLOT( setFile( const QString& ) ) ); + connect( mUrlRequester->lineEdit(), SIGNAL( textChanged ( const QString& ) ), + this, SLOT( urlChanged( const QString& ) ) ); + + connect( this, SIGNAL( user1Clicked() ), + this, SLOT( applyTemplate() ) ); + + connect( this, SIGNAL( user2Clicked() ), + this, SLOT( saveTemplate() ) ); +} + +CSVImportDialog::~CSVImportDialog() +{ + mCodecs.clear(); +} + +KABC::AddresseeList CSVImportDialog::contacts() const +{ + DateParser dateParser( mDatePatternEdit->text() ); + KABC::AddresseeList contacts; + + KProgressDialog progressDialog( mPage ); + progressDialog.setAutoClose( true ); + progressDialog.progressBar()->setTotalSteps( mTable->numRows() ); + progressDialog.setLabel( i18n( "Importing contacts" ) ); + progressDialog.show(); + + kapp->processEvents(); + + for ( int row = 1; row < mTable->numRows(); ++row ) { + KABC::Addressee a; + bool emptyRow = true; + KABC::Address addrHome( KABC::Address::Home ); + KABC::Address addrWork( KABC::Address::Work ); + for ( int col = 0; col < mTable->numCols(); ++col ) { + QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0, + col ) ); + if ( !item ) { + kdError() << "ERROR: item cast failed" << endl; + continue; + } + + QString value = mTable->text( row, col ); + if ( 1 == row && static_cast<QTableItem *>(item)->text() == value ) + // we are looking at a header row, stop now + break; + + if ( !value.isEmpty() ) + emptyRow = false; + + switch ( posToType( item->currentItem() ) ) { + case Undefined: + continue; + break; + case FormattedName: + a.setFormattedName( value ); + break; + case GivenName: + a.setGivenName( value ); + break; + case FamilyName: + a.setFamilyName( value ); + break; + case AdditionalName: + a.setAdditionalName( value ); + break; + case Prefix: + a.setPrefix( value ); + break; + case Suffix: + a.setSuffix( value ); + break; + case NickName: + a.setNickName( value ); + break; + case Birthday: + a.setBirthday( dateParser.parse( value ) ); + break; + case Email: + if ( !value.isEmpty() ) + a.insertEmail( value, true ); + break; + case Role: + a.setRole( value ); + break; + case Title: + a.setTitle( value ); + break; + case Mailer: + a.setMailer( value ); + break; + case URL: + a.setUrl( KURL( value ) ); + break; + case Organization: + a.setOrganization( value ); + break; + case Note: + a.setNote( a.note() + value + "\n" ); + break; + + case HomePhone: + if ( !value.isEmpty() ) { + KABC::PhoneNumber number( value, KABC::PhoneNumber::Home ); + a.insertPhoneNumber( number ); + } + break; + case BusinessPhone: + if ( !value.isEmpty() ) { + KABC::PhoneNumber number( value, KABC::PhoneNumber::Work ); + a.insertPhoneNumber( number ); + } + break; + case MobilePhone: + if ( !value.isEmpty() ) { + KABC::PhoneNumber number( value, KABC::PhoneNumber::Cell ); + a.insertPhoneNumber( number ); + } + break; + case HomeFax: + if ( !value.isEmpty() ) { + KABC::PhoneNumber number( value, KABC::PhoneNumber::Home | + KABC::PhoneNumber::Fax ); + a.insertPhoneNumber( number ); + } + break; + case BusinessFax: + if ( !value.isEmpty() ) { + KABC::PhoneNumber number( value, KABC::PhoneNumber::Work | + KABC::PhoneNumber::Fax ); + a.insertPhoneNumber( number ); + } + break; + case CarPhone: + if ( !value.isEmpty() ) { + KABC::PhoneNumber number( value, KABC::PhoneNumber::Car ); + a.insertPhoneNumber( number ); + } + break; + case Isdn: + if ( !value.isEmpty() ) { + KABC::PhoneNumber number( value, KABC::PhoneNumber::Isdn ); + a.insertPhoneNumber( number ); + } + break; + case Pager: + if ( !value.isEmpty() ) { + KABC::PhoneNumber number( value, KABC::PhoneNumber::Pager ); + a.insertPhoneNumber( number ); + } + break; + + case HomeAddressStreet: + addrHome.setStreet( value ); + break; + case HomeAddressLocality: + addrHome.setLocality( value ); + break; + case HomeAddressRegion: + addrHome.setRegion( value ); + break; + case HomeAddressPostalCode: + addrHome.setPostalCode( value ); + break; + case HomeAddressCountry: + addrHome.setCountry( value ); + break; + case HomeAddressLabel: + addrHome.setLabel( value ); + break; + + case BusinessAddressStreet: + addrWork.setStreet( value ); + break; + case BusinessAddressLocality: + addrWork.setLocality( value ); + break; + case BusinessAddressRegion: + addrWork.setRegion( value ); + break; + case BusinessAddressPostalCode: + addrWork.setPostalCode( value ); + break; + case BusinessAddressCountry: + addrWork.setCountry( value ); + break; + case BusinessAddressLabel: + addrWork.setLabel( value ); + break; + default: + KABC::Field::List fields = mAddressBook->fields( KABC::Field::CustomCategory ); + KABC::Field::List::Iterator it; + + int counter = 0; + for ( it = fields.begin(); it != fields.end(); ++it ) { + if ( counter == (int)( posToType( item->currentItem() ) - mCustomCounter ) ) { + (*it)->setValue( a, value ); + break; + } + ++counter; + } + break; + } + } + + kapp->processEvents(); + + if ( progressDialog.wasCancelled() ) + return KABC::AddresseeList(); + + progressDialog.progressBar()->advance( 1 ); + + if ( !addrHome.isEmpty() ) + a.insertAddress( addrHome ); + if ( !addrWork.isEmpty() ) + a.insertAddress( addrWork ); + + if ( !emptyRow && !a.isEmpty() ) + contacts.append( a ); + } + + return contacts; +} + +void CSVImportDialog::initGUI() +{ + mPage = plainPage(); + + QGridLayout *layout = new QGridLayout( mPage, 1, 1, marginHint(), + spacingHint() ); + QHBoxLayout *hbox = new QHBoxLayout(); + hbox->setSpacing( spacingHint() ); + + QLabel *label = new QLabel( i18n( "File to import:" ), mPage ); + hbox->addWidget( label ); + + mUrlRequester = new KURLRequester( mPage ); + mUrlRequester->setFilter( "*.csv" ); + hbox->addWidget( mUrlRequester ); + + layout->addMultiCellLayout( hbox, 0, 0, 0, 4 ); + + // Delimiter: comma, semicolon, tab, space, other + mDelimiterBox = new QButtonGroup( i18n( "Delimiter" ), mPage ); + mDelimiterBox->setColumnLayout( 0, Qt::Vertical ); + mDelimiterBox->layout()->setSpacing( spacingHint() ); + mDelimiterBox->layout()->setMargin( marginHint() ); + QGridLayout *delimiterLayout = new QGridLayout( mDelimiterBox->layout() ); + delimiterLayout->setAlignment( Qt::AlignTop ); + layout->addMultiCellWidget( mDelimiterBox, 1, 4, 0, 0 ); + + mRadioComma = new QRadioButton( i18n( "Comma" ), mDelimiterBox ); + mRadioComma->setChecked( true ); + delimiterLayout->addWidget( mRadioComma, 0, 0 ); + + mRadioSemicolon = new QRadioButton( i18n( "Semicolon" ), mDelimiterBox ); + delimiterLayout->addWidget( mRadioSemicolon, 0, 1 ); + + mRadioTab = new QRadioButton( i18n( "Tabulator" ), mDelimiterBox ); + delimiterLayout->addWidget( mRadioTab, 1, 0 ); + + mRadioSpace = new QRadioButton( i18n( "Space" ), mDelimiterBox ); + delimiterLayout->addWidget( mRadioSpace, 1, 1 ); + + mRadioOther = new QRadioButton( i18n( "Other" ), mDelimiterBox ); + delimiterLayout->addWidget( mRadioOther, 0, 2 ); + + mDelimiterEdit = new QLineEdit( mDelimiterBox ); + delimiterLayout->addWidget( mDelimiterEdit, 1, 2 ); + + mComboLine = new QComboBox( false, mPage ); + mComboLine->insertItem( i18n( "1" ) ); + layout->addWidget( mComboLine, 2, 3 ); + + mComboQuote = new QComboBox( false, mPage ); + mComboQuote->insertItem( i18n( "\"" ), 0 ); + mComboQuote->insertItem( i18n( "'" ), 1 ); + mComboQuote->insertItem( i18n( "None" ), 2 ); + layout->addWidget( mComboQuote, 2, 2 ); + + mDatePatternEdit = new QLineEdit( mPage ); + mDatePatternEdit->setText( "Y-M-D" ); // ISO 8601 format as default + QToolTip::add( mDatePatternEdit, i18n( "<ul><li>y: year with 2 digits</li>" + "<li>Y: year with 4 digits</li>" + "<li>m: month with 1 or 2 digits</li>" + "<li>M: month with 2 digits</li>" + "<li>d: day with 1 or 2 digits</li>" + "<li>D: day with 2 digits</li></ul>" ) ); + layout->addWidget( mDatePatternEdit, 2, 4 ); + + label = new QLabel( i18n( "Start at line:" ), mPage ); + layout->addWidget( label, 1, 3 ); + + label = new QLabel( i18n( "Textquote:" ), mPage ); + layout->addWidget( label, 1, 2 ); + + label = new QLabel( i18n( "Date format:" ), mPage ); + layout->addWidget( label, 1, 4 ); + + mIgnoreDuplicates = new QCheckBox( mPage ); + mIgnoreDuplicates->setText( i18n( "Ignore duplicate delimiters" ) ); + layout->addMultiCellWidget( mIgnoreDuplicates, 3, 3, 2, 4 ); + + mCodecCombo = new QComboBox( mPage ); + layout->addMultiCellWidget( mCodecCombo, 4, 4, 2, 4 ); + + mTable = new QTable( 0, 0, mPage ); + mTable->setSelectionMode( QTable::NoSelection ); + mTable->horizontalHeader()->hide(); + layout->addMultiCellWidget( mTable, 5, 5, 0, 4 ); + + setButtonText( User1, i18n( "Apply Template..." ) ); + setButtonText( User2, i18n( "Save Template..." ) ); + + enableButtonOK( false ); + actionButton( User1 )->setEnabled( false ); + actionButton( User2 )->setEnabled( false ); + + resize( 400, 300 ); +} + +void CSVImportDialog::fillTable() +{ + int row, column; + bool lastCharDelimiter = false; + bool ignoreDups = mIgnoreDuplicates->isChecked(); + enum { S_START, S_QUOTED_FIELD, S_MAYBE_END_OF_QUOTED_FIELD, S_END_OF_QUOTED_FIELD, + S_MAYBE_NORMAL_FIELD, S_NORMAL_FIELD } state = S_START; + + QChar x; + QString field; + + // store previous assignment + mTypeStore.clear(); + for ( column = 0; column < mTable->numCols(); ++column ) { + QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0, + column ) ); + if ( !item || mClearTypeStore ) + mTypeStore.append( typeToPos( Undefined ) ); + else if ( item ) + mTypeStore.append( item->currentItem() ); + } + + clearTable(); + + row = column = 1; + + QTextStream inputStream( mFileArray, IO_ReadOnly ); + + // find the current codec + int code = mCodecCombo->currentItem(); + if ( code == Local ) + inputStream.setEncoding( QTextStream::Locale ); + else if ( code >= Codec ) + inputStream.setCodec( mCodecs.at( code - Codec ) ); + else if ( code == Uni ) + inputStream.setEncoding( QTextStream::Unicode ); + else if ( code == MSBug ) + inputStream.setEncoding( QTextStream::UnicodeReverse ); + else if ( code == Latin1 ) + inputStream.setEncoding( QTextStream::Latin1 ); + else if ( code == Guess ) { + QTextCodec* codec = QTextCodec::codecForContent( mFileArray.data(), mFileArray.size() ); + if ( codec ) { + KMessageBox::information( this, i18n( "Using codec '%1'" ).arg( codec->name() ), i18n( "Encoding" ) ); + inputStream.setCodec( codec ); + } + } + + int maxColumn = 0; + while ( !inputStream.atEnd() ) { + inputStream >> x; // read one char + + if ( x == '\r' ) inputStream >> x; // eat '\r', to handle DOS/LOSEDOWS files correctly + + switch ( state ) { + case S_START : + if ( x == mTextQuote ) { + state = S_QUOTED_FIELD; + } else if ( x == mDelimiter ) { + if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) ) + ++column; + lastCharDelimiter = true; + } else if ( x == '\n' ) { + ++row; + column = 1; + } else { + field += x; + state = S_MAYBE_NORMAL_FIELD; + } + break; + case S_QUOTED_FIELD : + if ( x == mTextQuote ) { + state = S_MAYBE_END_OF_QUOTED_FIELD; + } else if ( x == '\n' && mTextQuote.isNull() ) { + setText( row - mStartLine + 1, column, field ); + field = ""; + if ( x == '\n' ) { + ++row; + column = 1; + } else { + if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) ) + ++column; + lastCharDelimiter = true; + } + state = S_START; + } else { + field += x; + } + break; + case S_MAYBE_END_OF_QUOTED_FIELD : + if ( x == mTextQuote ) { + field += x; + state = S_QUOTED_FIELD; + } else if ( x == mDelimiter || x == '\n' ) { + setText( row - mStartLine + 1, column, field ); + field = ""; + if ( x == '\n' ) { + ++row; + column = 1; + } else { + if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) ) + ++column; + lastCharDelimiter = true; + } + state = S_START; + } else { + state = S_END_OF_QUOTED_FIELD; + } + break; + case S_END_OF_QUOTED_FIELD : + if ( x == mDelimiter || x == '\n' ) { + setText( row - mStartLine + 1, column, field ); + field = ""; + if ( x == '\n' ) { + ++row; + column = 1; + } else { + if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) ) + ++column; + lastCharDelimiter = true; + } + state = S_START; + } else { + state = S_END_OF_QUOTED_FIELD; + } + break; + case S_MAYBE_NORMAL_FIELD : + if ( x == mTextQuote ) { + field = ""; + state = S_QUOTED_FIELD; + break; + } + case S_NORMAL_FIELD : + if ( x == mDelimiter || x == '\n' ) { + setText( row - mStartLine + 1, column, field ); + field = ""; + if ( x == '\n' ) { + ++row; + column = 1; + } else { + if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) ) + ++column; + lastCharDelimiter = true; + } + state = S_START; + } else { + field += x; + } + } + if ( x != mDelimiter ) + lastCharDelimiter = false; + + if ( column > maxColumn ) + maxColumn = column; + } + + // file with only one line without '\n' + if ( field.length() > 0 ) { + setText( row - mStartLine + 1, column, field ); + ++row; + field = ""; + } + + adjustRows( row - mStartLine ); + mTable->setNumCols( maxColumn ); + + for ( column = 0; column < mTable->numCols(); ++column ) { + QComboTableItem *item = new QComboTableItem( mTable, mTypeMap.keys() ); + mTable->setItem( 0, column, item ); + if ( column < (int)mTypeStore.count() ) + item->setCurrentItem( mTypeStore[ column ] ); + else + item->setCurrentItem( typeToPos( Undefined ) ); + mTable->adjustColumn( column ); + } + + resizeColumns(); +} + +void CSVImportDialog::clearTable() +{ + for ( int row = 0; row < mTable->numRows(); ++row ) + for ( int column = 0; column < mTable->numCols(); ++column ) + mTable->clearCell( row, column ); +} + +void CSVImportDialog::fillComboBox() +{ + mComboLine->clear(); + for ( int row = 1; row < mTable->numRows() + 1; ++row ) + mComboLine->insertItem( QString::number( row ), row - 1 ); +} + +void CSVImportDialog::reloadCodecs() +{ + mCodecCombo->clear(); + + mCodecs.clear(); + + QTextCodec *codec; + for ( int i = 0; ( codec = QTextCodec::codecForIndex( i ) ); i++ ) + mCodecs.append( codec ); + + mCodecCombo->insertItem( i18n( "Local (%1)" ).arg( QTextCodec::codecForLocale()->name() ), Local ); + mCodecCombo->insertItem( i18n( "[guess]" ), Guess ); + mCodecCombo->insertItem( i18n( "Latin1" ), Latin1 ); + mCodecCombo->insertItem( i18n( "Unicode" ), Uni ); + mCodecCombo->insertItem( i18n( "Microsoft Unicode" ), MSBug ); + + for ( uint i = 0; i < mCodecs.count(); i++ ) + mCodecCombo->insertItem( mCodecs.at( i )->name(), Codec + i ); +} + +void CSVImportDialog::setText( int row, int col, const QString& text ) +{ + if ( row < 1 ) // skipped by the user + return; + + if ( mTable->numRows() < row ) { + mTable->setNumRows( row + 5000 ); // We add 5000 at a time to limit recalculations + mAdjustRows = true; + } + + if ( mTable->numCols() < col ) + mTable->setNumCols( col + 50 ); // We add 50 at a time to limit recalculation + + mTable->setText( row - 1, col - 1, text ); +} + +/* + * Called after the first fillTable() when number of rows are unknown. + */ +void CSVImportDialog::adjustRows( int rows ) +{ + if ( mAdjustRows ) { + mTable->setNumRows( rows ); + mAdjustRows = false; + } +} + +void CSVImportDialog::resizeColumns() +{ + QFontMetrics fm = fontMetrics(); + int width = 0; + + QMap<QString, uint>::ConstIterator it; + for ( it = mTypeMap.begin(); it != mTypeMap.end(); ++it ) { + width = QMAX( width, fm.width( it.key() ) ); + } + + for ( int i = 0; i < mTable->numCols(); ++i ) + mTable->setColumnWidth( i, QMAX( width + 15, mTable->columnWidth( i ) ) ); +} + +void CSVImportDialog::returnPressed() +{ + if ( mDelimiterBox->id( mDelimiterBox->selected() ) != 4 ) + return; + + mDelimiter = mDelimiterEdit->text(); + fillTable(); +} + +void CSVImportDialog::textChanged ( const QString& ) +{ + mRadioOther->setChecked ( true ); + delimiterClicked( 4 ); // other +} + +void CSVImportDialog::delimiterClicked( int id ) +{ + switch ( id ) { + case 0: // comma + mDelimiter = ","; + break; + case 4: // other + mDelimiter = mDelimiterEdit->text(); + break; + case 2: // tab + mDelimiter = "\t"; + break; + case 3: // space + mDelimiter = " "; + break; + case 1: // semicolon + mDelimiter = ";"; + break; + } + + fillTable(); +} + +void CSVImportDialog::textquoteSelected( const QString& mark ) +{ + if ( mComboQuote->currentItem() == 2 ) + mTextQuote = 0; + else + mTextQuote = mark[ 0 ]; + + fillTable(); +} + +void CSVImportDialog::lineSelected( const QString& line ) +{ + mStartLine = line.toInt() - 1; + fillTable(); +} + +void CSVImportDialog::slotOk() +{ + bool assigned = false; + + for ( int column = 0; column < mTable->numCols(); ++column ) { + QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0, + column ) ); + if ( item && posToType( item->currentItem() ) != Undefined ) + assigned = true; + } + + if ( assigned ) + KDialogBase::slotOk(); + else + KMessageBox::sorry( this, i18n( "You have to assign at least one column." ) ); +} + +void CSVImportDialog::applyTemplate() +{ + QMap<uint,int> columnMap; + QMap<QString, QString> fileMap; + QStringList templates; + + // load all template files + QStringList list = KGlobal::dirs()->findAllResources( "data" , QString( kapp->name() ) + + "/csv-templates/*.desktop", true, true ); + + for ( QStringList::iterator it = list.begin(); it != list.end(); ++it ) + { + KSimpleConfig config( *it, true ); + + if ( !config.hasGroup( "csv column map" ) ) + continue; + + config.setGroup( "Misc" ); + templates.append( config.readEntry( "Name" ) ); + fileMap.insert( config.readEntry( "Name" ), *it ); + } + + // let the user chose, what to take + bool ok = false; + QString tmp; + tmp = KInputDialog::getItem( i18n( "Template Selection" ), + i18n( "Please select a template, that matches the CSV file:" ), + templates, 0, false, &ok, this ); + + if ( !ok ) + return; + + KSimpleConfig config( fileMap[ tmp ], true ); + config.setGroup( "General" ); + mDatePatternEdit->setText( config.readEntry( "DatePattern", "Y-M-D" ) ); + uint numColumns = config.readUnsignedNumEntry( "Columns" ); + mDelimiterEdit->setText( config.readEntry( "DelimiterOther" ) ); + mDelimiterBox->setButton( config.readNumEntry( "DelimiterType" ) ); + delimiterClicked( config.readNumEntry( "DelimiterType" ) ); + int quoteType = config.readNumEntry( "QuoteType" ); + mComboQuote->setCurrentItem( quoteType ); + textquoteSelected( mComboQuote->currentText() ); + + // create the column map + config.setGroup( "csv column map" ); + for ( uint i = 0; i < numColumns; ++i ) { + int col = config.readNumEntry( QString::number( i ) ); + columnMap.insert( i, col ); + } + + // apply the column map + for ( uint column = 0; column < columnMap.count(); ++column ) { + int type = columnMap[ column ]; + QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0, + column ) ); + if ( item ) + item->setCurrentItem( typeToPos( type ) ); + } +} + +void CSVImportDialog::saveTemplate() +{ + QString fileName = KFileDialog::getSaveFileName( + locateLocal( "data", QString( kapp->name() ) + "/csv-templates/" ), + "*.desktop", this ); + + if ( fileName.isEmpty() ) + return; + + if ( !fileName.contains( ".desktop" ) ) + fileName += ".desktop"; + + QString name = KInputDialog::getText( i18n( "Template Name" ), i18n( "Please enter a name for the template:" ) ); + + if ( name.isEmpty() ) + return; + + KConfig config( fileName ); + config.setGroup( "General" ); + config.writeEntry( "DatePattern", mDatePatternEdit->text() ); + config.writeEntry( "Columns", mTable->numCols() ); + config.writeEntry( "DelimiterType", mDelimiterBox->id( mDelimiterBox->selected() ) ); + config.writeEntry( "DelimiterOther", mDelimiterEdit->text() ); + config.writeEntry( "QuoteType", mComboQuote->currentItem() ); + + config.setGroup( "Misc" ); + config.writeEntry( "Name", name ); + + config.setGroup( "csv column map" ); + + for ( int column = 0; column < mTable->numCols(); ++column ) { + QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0, + column ) ); + if ( item ) + config.writeEntry( QString::number( column ), posToType( + item->currentItem() ) ); + else + config.writeEntry( QString::number( column ), 0 ); + } + + config.sync(); +} + +QString CSVImportDialog::getText( int row, int col ) +{ + return mTable->text( row, col ); +} + +uint CSVImportDialog::posToType( int pos ) const +{ + uint counter = 0; + QMap<QString, uint>::ConstIterator it; + for ( it = mTypeMap.begin(); it != mTypeMap.end(); ++it, ++counter ) + if ( counter == (uint)pos ) + return it.data(); + + return 0; +} + +int CSVImportDialog::typeToPos( uint type ) const +{ + uint counter = 0; + QMap<QString, uint>::ConstIterator it; + for ( it = mTypeMap.begin(); it != mTypeMap.end(); ++it, ++counter ) + if ( it.data() == type ) + return counter; + + return -1; +} + +void CSVImportDialog::ignoreDuplicatesChanged( int ) +{ + fillTable(); +} + +void CSVImportDialog::setFile( const QString &fileName ) +{ + if ( fileName.isEmpty() ) + return; + + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) { + KMessageBox::sorry( this, i18n( "Cannot open input file." ) ); + file.close(); + return; + } + + mFileArray = file.readAll(); + file.close(); + + mClearTypeStore = true; + clearTable(); + mTable->setNumCols( 0 ); + mTable->setNumRows( 0 ); + fillTable(); + mClearTypeStore = false; + + fillComboBox(); +} + +void CSVImportDialog::urlChanged( const QString &file ) +{ + bool state = !file.isEmpty(); + + enableButtonOK( state ); + actionButton( User1 )->setEnabled( state ); + actionButton( User2 )->setEnabled( state ); +} + +void CSVImportDialog::codecChanged() +{ + fillTable(); +} + +#include <csvimportdialog.moc> diff --git a/kaddressbook/xxport/csvimportdialog.h b/kaddressbook/xxport/csvimportdialog.h new file mode 100644 index 000000000..8e9dd0710 --- /dev/null +++ b/kaddressbook/xxport/csvimportdialog.h @@ -0,0 +1,124 @@ +/* + This file is part of KAddressBook. + Copyright (C) 2003 Tobias Koenig <[email protected]> + based on the code of KSpread's CSV Import Dialog + + 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 CSV_IMPORT_DLG_H +#define CSV_IMPORT_DLG_H + +#include <kabc/addressbook.h> +#include <kabc/addresseelist.h> +#include <kdialogbase.h> + +#include <qvaluelist.h> + +class KURLRequester; + +class QButtonGroup; +class QComboBox; +class QCheckBox; +class QLineEdit; +class QPushButton; +class QRadioButton; +class QTable; + +class CSVImportDialog : public KDialogBase +{ + Q_OBJECT + + public: + CSVImportDialog( KABC::AddressBook *ab, QWidget *parent, + const char *name = 0 ); + ~CSVImportDialog(); + + KABC::AddresseeList contacts() const; + + protected slots: + virtual void slotOk(); + + private slots: + void returnPressed(); + void delimiterClicked( int id ); + void lineSelected( const QString& line ); + void textquoteSelected( const QString& mark ); + void textChanged ( const QString & ); + void ignoreDuplicatesChanged( int ); + void setFile( const QString& ); + void urlChanged( const QString& ); + void codecChanged(); + + void applyTemplate(); + void saveTemplate(); + + private: + enum { Undefined, FormattedName, FamilyName, GivenName, AdditionalName, + Prefix, Suffix, NickName, Birthday, + HomeAddressStreet, HomeAddressLocality, HomeAddressRegion, + HomeAddressPostalCode, HomeAddressCountry, HomeAddressLabel, + BusinessAddressStreet, BusinessAddressLocality, BusinessAddressRegion, + BusinessAddressPostalCode, BusinessAddressCountry, + BusinessAddressLabel, + HomePhone, BusinessPhone, MobilePhone, HomeFax, BusinessFax, CarPhone, + Isdn, Pager, Email, Mailer, Title, Role, Organization, Note, URL + }; + + QTable* mTable; + QButtonGroup* mDelimiterBox; + QRadioButton* mRadioComma; + QRadioButton* mRadioSemicolon; + QRadioButton* mRadioTab; + QRadioButton* mRadioSpace; + QRadioButton* mRadioOther; + QLineEdit* mDelimiterEdit; + QLineEdit* mDatePatternEdit; + QComboBox* mComboLine; + QComboBox* mComboQuote; + QCheckBox* mIgnoreDuplicates; + QComboBox* mCodecCombo; + QWidget* mPage; + KURLRequester* mUrlRequester; + + void initGUI(); + void fillTable(); + void clearTable(); + void fillComboBox(); + void setText( int row, int col, const QString& text ); + void adjustRows( int rows ); + void resizeColumns(); + QString getText( int row, int col ); + uint posToType( int pos ) const; + int typeToPos( uint type ) const; + + void reloadCodecs(); + QTextCodec *currentCodec(); + QPtrList<QTextCodec> mCodecs; + + bool mAdjustRows; + int mStartLine; + QChar mTextQuote; + QString mDelimiter; + QByteArray mFileArray; + QMap<QString, uint> mTypeMap; + KABC::AddressBook *mAddressBook; + int mCustomCounter; + bool mClearTypeStore; + QValueList<int> mTypeStore; +}; + +#endif diff --git a/kaddressbook/xxport/dateparser.cpp b/kaddressbook/xxport/dateparser.cpp new file mode 100644 index 000000000..ed485e0dd --- /dev/null +++ b/kaddressbook/xxport/dateparser.cpp @@ -0,0 +1,112 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Tobias Koenig <[email protected]> + + 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 <qdatetime.h> + +#include "dateparser.h" + +DateParser::DateParser( const QString &pattern ) + : mPattern( pattern ) +{ +} + +DateParser::~DateParser() +{ +} + +QDate DateParser::parse( const QString &dateStr ) const +{ + int year, month, day; + year = month = day = 0; + + uint currPos = 0; + for ( uint i = 0; i < mPattern.length(); ++i ) { + if ( mPattern[ i ] == 'y' ) { // 19YY + if ( currPos + 1 < dateStr.length() ) { + year = 1900 + dateStr.mid( currPos, 2 ).toInt(); + currPos += 2; + } else + return QDate(); + } else if ( mPattern[ i ] == 'Y' ) { // YYYY + if ( currPos + 3 < dateStr.length() ) { + year = dateStr.mid( currPos, 4 ).toInt(); + currPos += 4; + } else + return QDate(); + } else if ( mPattern[ i ] == 'm' ) { // M or MM + if ( currPos + 1 < dateStr.length() ) { + if ( dateStr[ currPos ].isDigit() ) { + if ( dateStr[ currPos + 1 ].isDigit() ) { + month = dateStr.mid( currPos, 2 ).toInt(); + currPos += 2; + continue; + } + } + } + if ( currPos < dateStr.length() ) { + if ( dateStr[ currPos ].isDigit() ) { + month = dateStr.mid( currPos, 1 ).toInt(); + currPos++; + continue; + } + } + + return QDate(); + } else if ( mPattern[ i ] == 'M' ) { // 0M or MM + if ( currPos + 1 < dateStr.length() ) { + month = dateStr.mid( currPos, 2 ).toInt(); + currPos += 2; + } else + return QDate(); + } else if ( mPattern[ i ] == 'd' ) { // D or DD + if ( currPos + 1 < dateStr.length() ) { + if ( dateStr[ currPos ].isDigit() ) { + if ( dateStr[ currPos + 1 ].isDigit() ) { + day = dateStr.mid( currPos, 2 ).toInt(); + currPos += 2; + continue; + } + } + } + if ( currPos < dateStr.length() ) { + if ( dateStr[ currPos ].isDigit() ) { + day = dateStr.mid( currPos, 1 ).toInt(); + currPos++; + continue; + } + } + + return QDate(); + } else if ( mPattern[ i ] == 'D' ) { // 0D or DD + if ( currPos + 1 < dateStr.length() ) { + day = dateStr.mid( currPos, 2 ).toInt(); + currPos += 2; + } else + return QDate(); + } else { + currPos++; + } + } + + return QDate( year, month, day ); +} diff --git a/kaddressbook/xxport/dateparser.h b/kaddressbook/xxport/dateparser.h new file mode 100644 index 000000000..93eb597da --- /dev/null +++ b/kaddressbook/xxport/dateparser.h @@ -0,0 +1,51 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Tobias Koenig <[email protected]> + + 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 DATEPARSER_H +#define DATEPARSER_H + +#include <qstring.h> + +/** + This class parses the date out of a given string with the + help of a pattern. + The pattern can contains the following key characters: + y = year (e.g. 82) + Y = year (e.g. 1982) + m = month (e.g. 7, 07 or 12) + M = month (e.g. 07 or 12) + d = day (e.g. 3, 03 or 17) + D = day (e.g. 03 or 17 ) + */ +class DateParser +{ + public: + DateParser( const QString &pattern ); + ~DateParser(); + + QDate parse( const QString &dateStr ) const; + private: + QString mPattern; +}; + +#endif diff --git a/kaddressbook/xxport/eudora_xxport.cpp b/kaddressbook/xxport/eudora_xxport.cpp new file mode 100644 index 000000000..bb4ae373b --- /dev/null +++ b/kaddressbook/xxport/eudora_xxport.cpp @@ -0,0 +1,213 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Daniel Molkentin <[email protected]> + + 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 <qfile.h> + +#include <kfiledialog.h> +#include <kio/netaccess.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <ktempfile.h> +#include <kurl.h> + +#include <kdebug.h> + +#include "eudora_xxport.h" + +#define CTRL_C 3 + +K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_eudora_xxport, EudoraXXPort ) + +EudoraXXPort::EudoraXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) + : KAB::XXPort( ab, parent, name ) +{ + createImportAction( i18n( "Import Eudora Addressbook..." ) ); +} + +KABC::AddresseeList EudoraXXPort::importContacts( const QString& ) const +{ + QString fileName = KFileDialog::getOpenFileName( QDir::homeDirPath(), + "*.[tT][xX][tT]|" + i18n("Eudora Light Addressbook (*.txt)"), 0 ); + if ( fileName.isEmpty() ) + return KABC::AddresseeList(); + + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) + return KABC::AddresseeList(); + + QString line; + QTextStream stream( &file ); + KABC::Addressee *a = 0; + int bytesRead = 0; + + KABC::AddresseeList list; + + while( !stream.eof() ) { + line = stream.readLine(); + bytesRead += line.length(); + QString tmp; + + if ( line.startsWith( "alias" ) ) { + if ( a ) { // Write it out + list << *a; + delete a; + a = 0; + a = new KABC::Addressee(); + } else + a = new KABC::Addressee(); + + tmp = key( line ).stripWhiteSpace(); + if ( !tmp.isEmpty() ) + a->setFormattedName( tmp ); + + tmp = email( line ).stripWhiteSpace(); + if ( !tmp.isEmpty() ) + a->insertEmail( tmp ); + } else if ( line.startsWith( "note" ) ) { + if ( !a ) // Must have an alias before a note + break; + + tmp = comment( line ).stripWhiteSpace(); + if ( !tmp.isEmpty() ) + a->setNote( tmp ); + + tmp = get( line, "name" ).stripWhiteSpace(); + if ( !tmp.isEmpty() ) + a->setNameFromString( tmp ); + + tmp = get( line, "address" ).stripWhiteSpace(); + if ( !tmp.isEmpty() ) { + KABC::Address addr; + kdDebug(5720) << tmp << endl; // dump complete address + addr.setLabel( tmp ); + a->insertAddress( addr ); + } + + tmp = get( line, "phone" ).stripWhiteSpace(); + if ( !tmp.isEmpty() ) + a->insertPhoneNumber( KABC::PhoneNumber( tmp, KABC::PhoneNumber::Home ) ); + } + } + + if ( a ) { // Write out address + list << *a; + delete a; + a = 0; + } + + file.close(); + + return list; +} + +QString EudoraXXPort::key( const QString& line) const +{ + int e; + QString result; + int b = line.find( '\"', 0 ); + + if ( b == -1 ) { + b = line.find( ' ' ); + if ( b == -1 ) + return result; + + b++; + e = line.find( ' ', b ); + result = line.mid( b, e - b ); + + return result; + } + + b++; + e = line.find( '\"', b ); + if ( e == -1 ) + return result; + + result = line.mid( b, e - b ); + + return result; +} + +QString EudoraXXPort::email( const QString& line ) const +{ + int b; + QString result; + b = line.findRev( '\"' ); + if ( b == -1 ) { + b = line.findRev( ' ' ); + if ( b == -1 ) + return result; + } + result = line.mid( b + 1 ); + + return result; +} + +QString EudoraXXPort::comment( const QString& line ) const +{ + int b; + QString result; + uint i; + b = line.findRev( '>' ); + if ( b == -1 ) { + b = line.findRev( '\"' ); + if ( b == -1 ) + return result; + } + + result = line.mid( b + 1 ); + for ( i = 0; i < result.length(); i++ ) { + if ( result[ i ] == CTRL_C ) + result[ i ] = '\n'; + } + + return result; +} + +QString EudoraXXPort::get( const QString& line, const QString& key ) const +{ + QString fd = "<" + key + ":"; + int b, e; + uint i; + + // Find formatted key, return on error + b = line.find( fd ); + if ( b == -1 ) + return QString::null; + + b += fd.length(); + e = line.find( '>', b ); + if ( e == -1 ) + return QString::null; + + e--; + QString result = line.mid( b, e - b + 1 ); + for ( i = 0; i < result.length(); i++ ) { + if ( result[ i ] == CTRL_C ) + result[ i ] = '\n'; + } + + return result; +} + +#include "eudora_xxport.moc" diff --git a/kaddressbook/xxport/eudora_xxport.desktop b/kaddressbook/xxport/eudora_xxport.desktop new file mode 100644 index 000000000..a075f3f83 --- /dev/null +++ b/kaddressbook/xxport/eudora_xxport.desktop @@ -0,0 +1,104 @@ +[Desktop Entry] +X-KDE-Library=libkaddrbk_eudora_xxport +Name=KAB Eudora XXPort Plugin +Name[af]=KAB Eudora XXPort inprop module +Name[be]=Дапаўненне KAB "Імпарт/Экспарт Eudora" +Name[bg]=Приставка за Eudora XXPort на KAB +Name[br]=Lugent XXPorzh Eudora KAB +Name[bs]=KAB dodatak za Eudora XXPort +Name[ca]=Endollable d'importació/exportació Eudora per al KAB +Name[cs]=Exportní modul do Eudory +Name[cy]=Ategyn XXPort Eudora KAB +Name[da]=KAB Eudora XXPort-plugin +Name[de]=Eudora-XXPort-Modul für Adressbuch +Name[el]=Πρόσθετο εισαγωγής/εξαγωγής Eudora του KAB +Name[es]=Plugin de KAB para {ex,im}portar de Eudora +Name[et]=KAB Eudora eksport/importplugin +Name[eu]=KAB-en Eudora in/esportazio plugin-a +Name[fa]=وصلۀ KAB Eudora XXPort +Name[fi]=KAB Euroda -liitännäinen +Name[fr]=Module d'import / export Eudora pour KAB +Name[gl]=Extensión XXPort de Eudora para KA +Name[he]=תוסף ייבוא/ייצוא עבור Eurdora של KAB +Name[hi]=केएबी यूडोरा XXपोर्ट प्लगइन +Name[hu]=KAB Eudora XXPort bővítőmodul +Name[is]=Íforrit fyrir KAB Eudora XXPort +Name[ja]=KAB Eudora インポート/エクスポートプラグイン +Name[ka]= KAB Eudora-სთან ექსპორტის მოდული +Name[kk]=Eudora-ға экспорт/импорт ету +Name[km]=កម្មវិធីជំនួយ KAB Eudora XXPort +Name[lt]=KAB Eudora XXPort priedas +Name[ms]=Plug masuk KAB Eudora XXPort +Name[nb]=KAB-programtillegg for Eudora-eksport +Name[nds]=Eudora-Im-/Exportmoduul för KAdressbook +Name[ne]=KAB यूडोरा XXPort प्लगइन +Name[nn]=KAB Eudora XXPort programtillegg +Name[pl]=Wtyczka KAB do importu/eksportu wizytówek Eudory +Name[pt]='Plugin' XXPort para Eudora do KAB +Name[pt_BR]=Plug-in de Im/Exportação de/para Eudora do KAB +Name[ru]=Обмен информацией с Eudora +Name[sk]=KAB modul pre xxport Eudora +Name[sl]=Vstavek KAB Eudora XXPort +Name[sr]=XXPort прикључак KAB-а за Eudora-у +Name[sr@Latn]=XXPort priključak KAB-a za Eudora-u +Name[sv]=Adressbokens Eudora-överföringsinsticksprogram +Name[ta]=KAB யுடோரா XXபோர்ட் சொருகுப்பொருள் +Name[tg]=Мубодилаи иттилоот бо Eudora +Name[tr]=KAB Eudora XXPort Eklentisi +Name[uk]=Втулок KAB для обміну з Eudora +Name[zh_CN]=KAB Eudora XXPort 插件 +Name[zh_TW]=KAB Eudora XXPort 外掛程式 +Comment=Plugin to import and export Eudora contacts +Comment[af]=Inprop module wat kontakte in Eudora formaat invoer en uitvoer +Comment[be]=Дапаўненне для імпарту і экспарту кантактаў Eudora +Comment[bg]=Приставка за импортиране/експортиране на контактите във формат на Eudora +Comment[bs]=Dodatak za uvoz i izvoz kontakata iz Eudore +Comment[ca]=Endollable per a importar i exportar contactes de l'Eudora +Comment[cs]=Modul pro import a export kontaktů programu Eudora +Comment[cy]=Ategyn i fewnforio ac allforio cysylltau Eudora +Comment[da]=Plugin til at importere og eksportere Eudora-kontakter +Comment[de]=Modul zum Import/Export von Eudora-Kontakten +Comment[el]=Πρόσθετο για εισαγωγή και εξαγωγή επαφών του Eudora +Comment[es]=Plugin para importar y exportar contactos de Eudora +Comment[et]=Plugin Eudora kontaktide importimiseks ja eksportimiseks +Comment[eu]=Eudora kontaktuak inportatu/esportatzeko plugin-a +Comment[fa]=وصله برای واردات و صادرات تماسهای Eudora +Comment[fi]=Liitännäinen Eudora-kontaktien tuomiseen ja viemiseen +Comment[fr]=Module d'import / export de contacts Eudora +Comment[fy]=Plugin foar it importearjen en eksportearjen fan Eudora-kontaktpersoanen +Comment[gl]=Extensión para importar e exportar contactos Eudora +Comment[hi]=यूडोरा सम्पर्कों को आयात और निर्यात करने का प्लगइन +Comment[hu]=Bővítőmodul Eudora névjegyek importálásához/exportálásához +Comment[is]=Íforrit til að flytja inn og út Eudora tengiliði +Comment[it]=Plugin importare ed esportare contatti Eudora +Comment[ja]=Eudora の連絡先をインポート/エクスポートするプラグイン +Comment[ka]=Eudora-ს კონტაქტების იმპორტ/ექსპორტის მოდული +Comment[kk]=Eudora контакттарды экспорт/импорт ету модулі +Comment[km]=កម្មវិធីជំនួយដើម្បីនាំចូល និងនាំចេញទំនាក់ទំនងរបស់ Eudora +Comment[lt]=Priedas Eudora kontaktų importui ir eksportui +Comment[mk]=Приклучок за внесување и изнесување контакти од Eudora +Comment[ms]=Plug masuk untuk import dan eksport alamat perhubungan Eudora +Comment[nb]=Programtillegg for import/eksport av Eudora-kontakter +Comment[nds]=Moduul för't Im- un Exporteren vun Eudora-Kontakten +Comment[ne]=यूडोरा सम्पर्क आयात निर्यात गर्न प्लगइन गर्नुहोस् +Comment[nl]=Plugin voor het importeren en exporteren van Eudora-contactpersonen +Comment[nn]=Programtillegg for å importera og eksportera Eudora-kontaktar +Comment[pl]=Wtyczka do importowania i eksportowania wizytówek z/do Eudory +Comment[pt]=Um 'plugin' para importar e exportar contactos do Eudora +Comment[pt_BR]=Plug-in para importar e exportar contatos do Eudora +Comment[ro]=Modul de importat şi exportat contacte Eudora +Comment[ru]=Импорт и экспорт контактов Eudora +Comment[sk]=Modul pre import a export kontaktov Eudora +Comment[sl]=Vstavek za uvoz in izvoz stikov Eudore +Comment[sr]=Прикључак за увоз и извоз Eudora контаката +Comment[sr@Latn]=Priključak za uvoz i izvoz Eudora kontakata +Comment[sv]=Insticksprogram för import och export av Eudora-kontakter +Comment[ta]=யுடோரா ஏற்றுமதி மற்றும் இறக்குமதி செய்ய சொருகுப்பொருள் +Comment[tg]=Модул барои воридот ва содироти алоқаи Eudora +Comment[tr]=Eudora bağlantılarını alma ve gönderme eklentisi +Comment[uk]=Втулок для імпорту та експорту контактів з або до Eudora +Comment[zh_CN]=导入和导出 Eudora 联系人的插件 +Comment[zh_TW]=匯入與匯出 Eudora 聯絡人的外掛程式 +Type=Service +ServiceTypes=KAddressBook/XXPort +X-KDE-KAddressBook-XXPortPluginVersion=1 diff --git a/kaddressbook/xxport/eudora_xxport.h b/kaddressbook/xxport/eudora_xxport.h new file mode 100644 index 000000000..be1df8ead --- /dev/null +++ b/kaddressbook/xxport/eudora_xxport.h @@ -0,0 +1,49 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Daniel Molkentin <[email protected]> + + 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 EUDORA_XXPORT_H +#define EUDORA_XXPORT_H + +#include <xxport.h> + +class EudoraXXPort : public KAB::XXPort +{ + Q_OBJECT + + public: + EudoraXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name = 0 ); + + QString identifier() const { return "eudora"; } + + public slots: + KABC::AddresseeList importContacts( const QString &data ) const; + + private: + QString get( const QString& line, const QString& key ) const; + QString comment( const QString& line ) const; + QString email( const QString& line ) const; + QString key( const QString& line ) const; + int find( const QString& key ) const; +}; + +#endif diff --git a/kaddressbook/xxport/eudora_xxportui.rc b/kaddressbook/xxport/eudora_xxportui.rc new file mode 100644 index 000000000..0aab8deeb --- /dev/null +++ b/kaddressbook/xxport/eudora_xxportui.rc @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="eudora_xxport" version="2"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Menu name="file_import"><text>&Import</text> + <Action name="file_import_eudora"/> + </Menu> + </Menu> +</MenuBar> +</gui> diff --git a/kaddressbook/xxport/gnokii_xxport.cpp b/kaddressbook/xxport/gnokii_xxport.cpp new file mode 100644 index 000000000..60675384c --- /dev/null +++ b/kaddressbook/xxport/gnokii_xxport.cpp @@ -0,0 +1,1609 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003-2006 Helge Deller <[email protected]> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + 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. +*/ +/* + Description: + This filter allows you to import and export the KDE addressbook entries + to/from a mobile phone, which is accessible via gnokii. + Gnokii homepage: http://www.gnokii.org + + TODO: + - create a log file and give user possibility to see it afterwards + - handle callergroup value (Friend, VIP, Family, ...) better +*/ + +#include "config.h" + +#ifdef HAVE_GNOKII_H +extern "C" { +#include <gnokii.h> +} +#else +#ifdef __GNUC__ +# warning "Please install gnokii (http://www.gnokii.org) development headers and libraries !" +# warning "Please use at least version 0.6.13 or later of gnokii." +#endif +#endif + +#include <qcursor.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kprogress.h> +#include <kguiitem.h> + +#include "gnokii_xxport.h" + +#define APP "GNOKII_XXPORT" + +#if 1 // !defined(NDEBUG) + #define GNOKII_DEBUG(x) do { kdWarning() << (x); } while (0) +#else + #define GNOKII_DEBUG(x) do { } while (0) +#endif +#define GNOKII_CHECK_ERROR(error) \ + do { \ + if (error) \ + kdError() << QString("ERROR %1: %2\n").arg(error).arg(gn_error_print(error));\ + } while (0) + +// Locale conversion routines: +// Gnokii uses the local 8 Bit encoding (based on LC_ALL), kaddressbook uses Unicode +#define GN_FROM(x) QString::fromLocal8Bit(x) +#define GN_TO(x) (x).local8Bit() + +// static variables for GUI updates +static GNOKIIXXPort *this_filter; +static KProgressDialog *m_progressDlg; + +K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_gnokii_xxport, GNOKIIXXPort ) + +GNOKIIXXPort::GNOKIIXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) + : KAB::XXPort( ab, parent, name ) +{ + this_filter = this; + m_progressDlg = NULL; + createImportAction( i18n( "Import From Mobile Phone..." ) ); + createExportAction( i18n( "Export to Mobile Phone..." ) ); +} + + +#ifdef HAVE_GNOKII_H +static QString makeValidPhone( const QString &number ) +{ + // allowed chars: 0-9, *, #, p, w, + + QString num = number.simplifyWhiteSpace(); + QString allowed("0123456789*+#pw"); + for (unsigned int i=num.length(); i>=1; i--) + if (allowed.find(num[i-1])==-1) + num.remove(i-1,1); + if (num.isEmpty()) + num = "0"; + return num; +} +#endif + +/****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ******************************************************************************/ + +#if defined(HAVE_GNOKII_H) && defined(LIBGNOKII_VERSION_MAJOR) && (LIBGNOKII_VERSION_MAJOR >= 3) + +/* NEW GNOKII LIBRARIES (>= 0.6.13) */ + +static const char *manufacturer, *model, *revision, *imei; +static struct gn_statemachine *state; + +static void busterminate(void) +{ + gn_lib_phone_close(state); + gn_lib_phoneprofile_free(&state); + gn_lib_library_free(); +} + +static QString businit(void) +{ + GNOKII_DEBUG( "Using new gnokii version." ); + + GNOKII_DEBUG( QString("Compiled with libgnokii version 0x%1\n").arg(QString::number(LIBGNOKII_VERSION,16)) ); + GNOKII_DEBUG( QString("Using libgnokii runtime version 0x%1\n").arg(QString::number(gn_lib_version(),16)) ); + + gn_error error = gn_lib_phoneprofile_load(NULL, &state); + if (error) + return i18n("Failed to initialize the gnokii library."); + + error = gn_lib_phone_open( state ); + GNOKII_CHECK_ERROR(error); + if (error != GN_ERR_NONE) { + busterminate(); + return i18n("<qt><center>Mobile Phone interface initialization failed.<br><br>" + "The returned error message was:<br><b>%1</b><br><br>" + "You might try to run \"gnokii --identify\" on the command line to " + "check any cable/transport issues and to verify if your gnokii " + "configuration is correct.</center></qt>") + .arg(gn_error_print(error)); + } + + // identify phone + manufacturer = gn_lib_get_phone_manufacturer(state); + model = gn_lib_get_phone_model(state); + revision = gn_lib_get_phone_revision(state); + imei = gn_lib_get_phone_imei(state); + + GNOKII_DEBUG( QString("Found mobile phone: %1 %2, Revision: %3, IMEI: %4\n") + .arg(manufacturer, model, revision, imei) ); + + return QString::null; +} + + +// get number of entries in this phone memory type (internal/SIM-card) +static gn_error read_phone_memstat( const gn_memory_type memtype, gn_memory_status *memstat ) +{ + gn_error error; + + error = gn_lib_addressbook_memstat(state, memtype, &memstat->used, &memstat->free); + + GNOKII_DEBUG( QString("\n\nMobile phone memory status: Type: %1, used=%2, free=%3, total=%4\n\n") + .arg(memtype).arg(memstat->used).arg(memstat->free).arg(memstat->used+memstat->free) ); + return error; +} + + +static QString buildPhoneInfoString( const gn_memory_status &memstat ) +{ + QString format = QString::fromLatin1("<tr><td><b>%1</b></td><td>%2</td></tr>"); + + return QString::fromLatin1("<b>%1</b><br><table>%2%3%4%5%6</table><br>") + .arg(i18n("Mobile Phone information:")) + .arg(format.arg(i18n("Manufacturer")).arg(GN_FROM(manufacturer))) + .arg(format.arg(i18n("Phone model")).arg(GN_FROM(model))) + .arg(format.arg(i18n("Revision")).arg(GN_FROM(revision))) + .arg(format.arg(i18n("IMEI")).arg(GN_FROM(imei))) + .arg(format.arg(i18n("Phonebook status")) + .arg(i18n("%1 out of %2 contacts used").arg(memstat.used).arg(memstat.used+memstat.free))); +} + +// read and evaluate all phone entries +static gn_error read_phone_entries( const char *memtypestr, gn_memory_type memtype, + KABC::AddresseeList *addrList ) +{ + gn_error error; + + if (m_progressDlg->wasCancelled()) + return GN_ERR_NONE; + + KProgress* progress = (KProgress*)m_progressDlg->progressBar(); + + progress->setProgress(0); + this_filter->processEvents(); + + // get number of entries in this phone memory type (internal/SIM-card) + gn_memory_status memstat; + error = read_phone_memstat(memtype, &memstat); + + QStringList addrlist; + KABC::Address *addr; + QString s, country; + + progress->setTotalSteps(memstat.used); + m_progressDlg->setLabel(i18n("<qt>Importing <b>%1</b> contacts from <b>%2</b> of the Mobile Phone.<br><br>%3</qt>") + .arg(memstat.used) + .arg(gn_memory_type2str(memtype)) + .arg(buildPhoneInfoString(memstat)) ); + + int num_read = 0; + + for (int i = 1; !m_progressDlg->wasCancelled() && i <= memstat.used + memstat.free; i++) { + error = gn_lib_phonebook_read_entry(state, memtype, i); + GNOKII_CHECK_ERROR(error); + + progress->setProgress(num_read); + this_filter->processEvents(); + + if (error == GN_ERR_EMPTYLOCATION) + continue; + if (error == GN_ERR_INVALIDLOCATION) + break; + if (error == GN_ERR_INVALIDMEMORYTYPE) + break; + if (error == GN_ERR_NONE) { + const int subentries_count = gn_lib_get_pb_num_subentries(state); + const char *name = gn_lib_get_pb_name(state); + const char *number = gn_lib_get_pb_number(state); + + GNOKII_DEBUG(QString("%1: %2, num=%3, location=%4, group=%5, count=%6\n").arg(i) + .arg(GN_FROM(name)).arg(GN_FROM(number)) + .arg(gn_lib_get_pb_location(state)).arg(gn_lib_get_pb_caller_group(state)) + .arg(subentries_count)); + KABC::Addressee *a = new KABC::Addressee(); + + // try to split Name into FamilyName and GivenName + s = GN_FROM(name).simplifyWhiteSpace(); + a->setFormattedName(s); // set formatted name as in Phone + if (s.find(',') == -1) { + // assumed format: "givenname [... familyname]" + addrlist = QStringList::split(' ', s); + if (addrlist.count() == 1) { + // only one string -> put it in the GivenName + a->setGivenName(s); + } else { + // multiple strings -> split them. + a->setFamilyName(addrlist.last().simplifyWhiteSpace()); + addrlist.remove(addrlist.last()); + a->setGivenName(addrlist.join(" ").simplifyWhiteSpace()); + } + } else { + // assumed format: "familyname, ... givenname" + addrlist = QStringList::split(',', s); + a->setFamilyName(addrlist.first().simplifyWhiteSpace()); + addrlist.remove(addrlist.first()); + a->setGivenName(addrlist.join(" ").simplifyWhiteSpace()); + } + + a->insertCustom(APP, "X_GSM_CALLERGROUP", s.setNum(gn_lib_get_pb_caller_group(state))); + a->insertCustom(APP, "X_GSM_STORE_AT", QString("%1%2").arg(memtypestr).arg(gn_lib_get_pb_location(state))); + + // set ProductId + a->setProductId(QString("%1-%2-%3-%4").arg(APP).arg(model).arg(revision).arg(imei)); + + // evaluate timestamp (ignore timezone) + QDateTime datetime; + gn_timestamp ts = gn_lib_get_pb_date(state); + if (ts.year<1998) + datetime = QDateTime::currentDateTime(); + else + datetime = QDateTime( QDate(ts.year, ts.month, ts.day), + QTime(ts.hour, ts.minute, ts.second) ); + GNOKII_DEBUG(QString(" date=%1\n").arg(datetime.toString())); + a->setRevision(datetime); + + if (!subentries_count) + a->insertPhoneNumber(KABC::PhoneNumber(number, + KABC::PhoneNumber::Work | KABC::PhoneNumber::Pref)); + + /* scan sub-entries */ + if (subentries_count) + for (int n=0; n<subentries_count; n++) { + gn_phonebook_entry_type entry_type; + gn_phonebook_number_type number_type; + const char *number; + + error = gn_lib_get_pb_subentry(state, n, &entry_type, &number_type, &number); + GNOKII_CHECK_ERROR(error); + + QString s = GN_FROM(number).simplifyWhiteSpace(); + GNOKII_DEBUG(QString(" Subentry#%1, entry_type=%2, number_type=%3, number=%4\n") + .arg(n).arg(entry_type).arg(number_type).arg(s)); + if (s.isEmpty()) + continue; + switch(entry_type) { + case GN_PHONEBOOK_ENTRY_Name: + a->setName(s); + break; + case GN_PHONEBOOK_ENTRY_Email: + a->insertEmail(s); + break; + case GN_PHONEBOOK_ENTRY_Postal: + addrlist = QStringList::split(';', s, true); + addr = new KABC::Address(KABC::Address::Work); + if (addrlist.count() <= 1) { + addrlist = QStringList::split(',', s, true); + if (addrlist.count() > 1 ) { + // assumed format: "Locality, ZIP, Country" + addr->setLocality(addrlist[0]); + addr->setPostalCode(addrlist[1]); + if (!addrlist[2].isEmpty()) + addr->setCountry(i18n(GN_TO(addrlist[2]))); + } else { + // no idea about the format, just store it. + addr->setLocality(s); + } + } else { + // assumed format: "POBox; Extended; Street; Locality; Region; ZIP [;Country] + addr->setPostOfficeBox(addrlist[0]); + addr->setExtended(addrlist[1]); + addr->setStreet(addrlist[2]); + addr->setLocality(addrlist[3]); + addr->setRegion(addrlist[4]); + addr->setPostalCode(addrlist[5]); + country = addrlist[6]; + if (!country.isEmpty()) + addr->setCountry(i18n(GN_TO(country))); + } + a->insertAddress(*addr); + delete addr; + break; + case GN_PHONEBOOK_ENTRY_Note: + if (!a->note().isEmpty()) + s = "\n" + s; + a->setNote(a->note()+s); + break; + case GN_PHONEBOOK_ENTRY_Number: + enum KABC::PhoneNumber::Types phonetype; + switch (number_type) { + case GN_PHONEBOOK_NUMBER_Mobile: phonetype = KABC::PhoneNumber::Cell; break; + case GN_PHONEBOOK_NUMBER_Fax: phonetype = KABC::PhoneNumber::Fax; break; + case GN_PHONEBOOK_NUMBER_General: + case GN_PHONEBOOK_NUMBER_Work: phonetype = KABC::PhoneNumber::Work; break; + default: + case GN_PHONEBOOK_NUMBER_Home: phonetype = KABC::PhoneNumber::Home; break; + } + //if (s == entry.number) + // type = (KABC::PhoneNumber::Types) (phonetype | KABC::PhoneNumber::Pref); + a->insertPhoneNumber(KABC::PhoneNumber(s, phonetype)); + break; + case GN_PHONEBOOK_ENTRY_URL: + a->setUrl(s); + break; + case GN_PHONEBOOK_ENTRY_Group: + a->insertCategory(s); + break; + default: + GNOKII_DEBUG(QString(" Not handled id=%1, entry=%2\n") + .arg(entry_type).arg(s)); + break; + } // switch() + } // if(subentry) + + // add only if entry was valid + if (strlen(name) || strlen(number) || subentries_count) + addrList->append(*a); + + // did we read all valid phonebook-entries ? + num_read++; + delete a; + if (num_read >= memstat.used) + break; // yes, all were read + else + continue; // no, we are still missing some. + } + GNOKII_CHECK_ERROR(error); + } + + return GN_ERR_NONE; +} + +// export to phone + +static gn_error xxport_phone_write_entry( int phone_location, gn_memory_type memtype, + const KABC::Addressee *addr) +{ + QString s; + + /* initialize the phonebook entry values to zero */ + gn_lib_phonebook_prepare_write_entry(state); + + gn_lib_set_pb_location(state, phone_location); + + gn_lib_set_pb_name(state, GN_TO(addr->realName())); + s = addr->phoneNumber(KABC::PhoneNumber::Pref).number(); + if (s.isEmpty()) + s = addr->phoneNumber(KABC::PhoneNumber::Work).number(); + if (s.isEmpty()) + s = addr->phoneNumber(KABC::PhoneNumber::Home).number(); + if (s.isEmpty()) + s = addr->phoneNumber(KABC::PhoneNumber::Cell).number(); + if (s.isEmpty() && addr->phoneNumbers().count()>0) + s = (*addr->phoneNumbers().at(0)).number(); + s = makeValidPhone(s); + gn_lib_set_pb_number(state, s.ascii()); + gn_lib_set_pb_memtype(state, memtype); + QString cg = addr->custom(APP, "X_GSM_CALLERGROUP"); + if (cg.isEmpty()) + gn_lib_set_pb_caller_group(state, GN_PHONEBOOK_GROUP_None); // default group + else + gn_lib_set_pb_caller_group(state, (gn_phonebook_group_type) cg.toInt()); + + // set date/revision + QDateTime datetime = addr->revision(); + QDate date(datetime.date()); + QTime time(datetime.time()); + gn_timestamp ts; + gn_timestamp_set( &ts, date.year(), date.month(), date.day(), + time.hour(), time.minute(), time.second(), 0 ); + gn_lib_set_pb_date(state, ts); + + GNOKII_DEBUG(QString("Write #%1: name=%2, number=%3\n").arg(phone_location) + .arg(GN_FROM(gn_lib_get_pb_name(state))).arg(GN_FROM(gn_lib_get_pb_number(state)))); + + const KABC::Address homeAddr = addr->address(KABC::Address::Home); + const KABC::Address workAddr = addr->address(KABC::Address::Work); + + // add all phone numbers + const KABC::PhoneNumber::List phoneList = addr->phoneNumbers(); + KABC::PhoneNumber::List::ConstIterator it; + for ( it = phoneList.begin(); it != phoneList.end(); ++it ) { + const KABC::PhoneNumber *phonenumber = &(*it); + s = phonenumber->number(); + if (s.isEmpty()) continue; + gn_phonebook_number_type type; + int pn_type = phonenumber->type(); + if ((pn_type & KABC::PhoneNumber::Cell)) + type = GN_PHONEBOOK_NUMBER_Mobile; + else if ((pn_type & KABC::PhoneNumber::Fax)) + type = GN_PHONEBOOK_NUMBER_Fax; + else if ((pn_type & KABC::PhoneNumber::Home)) + type = GN_PHONEBOOK_NUMBER_Home; + else if ((pn_type & KABC::PhoneNumber::Work)) + type = GN_PHONEBOOK_NUMBER_Work; + else type = GN_PHONEBOOK_NUMBER_General; + gn_lib_set_pb_subentry(state, -1 /* index to append entry */, + GN_PHONEBOOK_ENTRY_Number, type, makeValidPhone(s).ascii()); + /*subentry->id = phone_location<<8+entry.subentries_count;*/ + } + // add URL + s = addr->url().prettyURL(); + if (!s.isEmpty()) { + gn_lib_set_pb_subentry(state, -1 /* index to append entry */, + GN_PHONEBOOK_ENTRY_URL, GN_PHONEBOOK_NUMBER_General, GN_TO(s)); + } + // add E-Mails + QStringList emails = addr->emails(); + for (unsigned int n=0; n<emails.count(); n++) { + s = emails[n].simplifyWhiteSpace(); + if (s.isEmpty()) continue; + // only one email allowed if we have URLS, notes, addresses (to avoid phone limitations) + if (n && !addr->url().isEmpty() && !addr->note().isEmpty() && addr->addresses().count()) { + GNOKII_DEBUG(QString(" DROPPED email %1 in favor of URLs, notes and addresses.\n") + .arg(s)); + continue; + } + gn_lib_set_pb_subentry(state, -1 /* index to append entry */, + GN_PHONEBOOK_ENTRY_Email, GN_PHONEBOOK_NUMBER_General, GN_TO(s)); + } + // add Adresses + const KABC::Address::List addresses = addr->addresses(); + KABC::Address::List::ConstIterator it2; + for ( it2 = addresses.begin(); it2 != addresses.end(); ++it2 ) { + const KABC::Address *Addr = &(*it2); + if (Addr->isEmpty()) continue; + QStringList a; + QChar sem(';'); + QString sem_repl(QString::fromLatin1(",")); + a.append( Addr->postOfficeBox().replace( sem, sem_repl ) ); + a.append( Addr->extended() .replace( sem, sem_repl ) ); + a.append( Addr->street() .replace( sem, sem_repl ) ); + a.append( Addr->locality() .replace( sem, sem_repl ) ); + a.append( Addr->region() .replace( sem, sem_repl ) ); + a.append( Addr->postalCode() .replace( sem, sem_repl ) ); + a.append( Addr->country() .replace( sem, sem_repl ) ); + s = a.join(sem); + gn_lib_set_pb_subentry(state, -1 /* index to append entry */, + GN_PHONEBOOK_ENTRY_Postal, GN_PHONEBOOK_NUMBER_General, GN_TO(s)); + } + // add Note + s = addr->note().simplifyWhiteSpace(); + if (!s.isEmpty()) { + gn_lib_set_pb_subentry(state, -1 /* index to append entry */, + GN_PHONEBOOK_ENTRY_Note, GN_PHONEBOOK_NUMBER_General, GN_TO(s)); + } + + // debug output + for (int st=0; st<gn_lib_get_pb_num_subentries(state); st++) { + gn_phonebook_entry_type entry_type; + gn_phonebook_number_type number_type; + const char *number; + gn_lib_get_pb_subentry(state, st, &entry_type, &number_type, &number); + GNOKII_DEBUG(QString(" SubTel #%1: entry_type=%2, number_type=%3, number=%4\n") + .arg(st).arg(entry_type) + .arg(number_type).arg(GN_FROM(number))); + } + + gn_error error = gn_lib_phonebook_write_entry(state, memtype, phone_location); + GNOKII_CHECK_ERROR(error); + + return error; +} + + +static gn_error xxport_phone_delete_entry( int phone_location, gn_memory_type memtype ) +{ + return gn_lib_phonebook_entry_delete(state, memtype, phone_location); +} + + +KABC::AddresseeList GNOKIIXXPort::importContacts( const QString& ) const +{ + KABC::AddresseeList addrList; + + if (KMessageBox::Continue != KMessageBox::warningContinueCancel(parentWidget(), + i18n("<qt>Please connect your Mobile Phone to your computer and press " + "<b>Continue</b> to start importing the personal contacts.<br><br>" + "Please note that if your Mobile Phone is not properly connected " + "the following detection phase might take up to two minutes, during which " + "KAddressbook will behave unresponsively.</qt>") )) + return addrList; + + m_progressDlg = new KProgressDialog( parentWidget(), "importwidget", + i18n("Mobile Phone Import"), + i18n("<qt><center>Establishing connection to the Mobile Phone.<br><br>" + "Please wait...</center></qt>") ); + m_progressDlg->setAllowCancel(true); + m_progressDlg->progressBar()->setProgress(0); + m_progressDlg->progressBar()->setCenterIndicator(true); + m_progressDlg->setModal(true); + m_progressDlg->setInitialSize(QSize(450,350)); + m_progressDlg->show(); + processEvents(); + +#if (QT_VERSION >= 0x030300) + m_progressDlg->setCursor( Qt::BusyCursor ); +#endif + QString errStr = businit(); + m_progressDlg->unsetCursor(); + + if (!errStr.isEmpty()) { + KMessageBox::error(parentWidget(), errStr); + delete m_progressDlg; + return addrList; + } + + GNOKII_DEBUG("GNOKII import filter started.\n"); + m_progressDlg->setButtonText(i18n("&Stop Import")); + + read_phone_entries("ME", GN_MT_ME, &addrList); // internal phone memory + read_phone_entries("SM", GN_MT_SM, &addrList); // SIM card + + GNOKII_DEBUG("GNOKII import filter finished.\n"); + + busterminate(); + delete m_progressDlg; + + return addrList; +} + + +bool GNOKIIXXPort::exportContacts( const KABC::AddresseeList &list, const QString & ) +{ + if (KMessageBox::Continue != KMessageBox::warningContinueCancel(parentWidget(), + i18n("<qt>Please connect your Mobile Phone to your computer and press " + "<b>Continue</b> to start exporting the selected personal contacts.<br><br>" + "Please note that if your Mobile Phone is not properly connected " + "the following detection phase might take up to two minutes, during which " + "KAddressbook will behave unresponsively.</qt>") )) + return false; + + m_progressDlg = new KProgressDialog( parentWidget(), "importwidget", + i18n("Mobile Phone Export"), + i18n("<qt><center>Establishing connection to the Mobile Phone.<br><br>" + "Please wait...</center></qt>") ); + m_progressDlg->setAllowCancel(true); + m_progressDlg->progressBar()->setProgress(0); + m_progressDlg->progressBar()->setCenterIndicator(true); + m_progressDlg->setModal(true); + m_progressDlg->setInitialSize(QSize(450,350)); + m_progressDlg->show(); + processEvents(); + + KProgress* progress = (KProgress*)m_progressDlg->progressBar(); + + KABC::AddresseeList::ConstIterator it; + QStringList failedList; + + gn_error error; + bool deleteLabelInitialized = false; + +#if (QT_VERSION >= 0x030300) + m_progressDlg->setCursor( Qt::BusyCursor ); +#endif + QString errStr = businit(); + m_progressDlg->unsetCursor(); + + if (!errStr.isEmpty()) { + KMessageBox::error(parentWidget(), errStr); + delete m_progressDlg; + return false; + } + + GNOKII_DEBUG("GNOKII export filter started.\n"); + + gn_memory_type memtype = GN_MT_ME; // internal phone memory + + int phone_count; // num entries in phone + bool overwrite_phone_entries = false; + int phone_entry_no, entries_written; + bool entry_empty; + + // get number of entries in this phone memory + gn_memory_status memstat; + error = read_phone_memstat(memtype, &memstat); + if (error == GN_ERR_NONE) { + GNOKII_DEBUG("Writing to internal phone memory.\n"); + } else { + memtype = GN_MT_SM; // try SIM card instead + error = read_phone_memstat(memtype, &memstat); + if (error != GN_ERR_NONE) + goto finish; + GNOKII_DEBUG("Writing to SIM card memory.\n"); + } + phone_count = memstat.used; + + if (memstat.free >= (int) list.count()) { + if (KMessageBox::No == KMessageBox::questionYesNo(parentWidget(), + i18n("<qt>Do you want the selected contacts to be <b>appended</b> to " + "the current mobile phonebook or should they <b>replace</b> all " + "currently existing phonebook entries ?<br><br>" + "Please note, that in case you choose to replace the phonebook " + "entries, every contact in your phone will be deleted and only " + "the newly exported contacts will be available from inside your phone.</qt>"), + i18n("Export to Mobile Phone"), + KGuiItem(i18n("&Append to Current Phonebook")), + KGuiItem(i18n("&Replace Current Phonebook with New Contacts")) ) ) + overwrite_phone_entries = true; + } + + progress->setTotalSteps(list.count()); + entries_written = 0; + progress->setProgress(entries_written); + m_progressDlg->setButtonText(i18n("&Stop Export")); + m_progressDlg->setLabel(i18n("<qt>Exporting <b>%1</b> contacts to the <b>%2</b> " + "of the Mobile Phone.<br><br>%3</qt>") + .arg(list.count()) + .arg(gn_memory_type2str(memtype)) + .arg(buildPhoneInfoString(memstat)) ); + + // Now run the loop... + phone_entry_no = 1; + for ( it = list.begin(); it != list.end(); ++it ) { + const KABC::Addressee *addr = &(*it); + if (addr->isEmpty()) + continue; + // don't write back SIM-card entries ! + if (addr->custom(APP, "X_GSM_STORE_AT").startsWith("SM")) + continue; + + progress->setProgress(entries_written++); + +try_next_phone_entry: + this_filter->processEvents(); + if (m_progressDlg->wasCancelled()) + break; + + // End of phone memory reached ? + if (phone_entry_no > (memstat.used + memstat.free)) + break; + + GNOKII_DEBUG(QString("Try to write entry '%1' at phone_entry_no=%2, phone_count=%3\n") + .arg(addr->realName()).arg(phone_entry_no).arg(phone_count)); + + error = GN_ERR_NONE; + + // is this phone entry empty ? + entry_empty = gn_lib_phonebook_entry_isempty(state, memtype, phone_entry_no); + if (overwrite_phone_entries) { + // overwrite this phonebook entry ... + if (!entry_empty) + phone_count--; + error = xxport_phone_write_entry( phone_entry_no, memtype, addr); + phone_entry_no++; + } else { + // add this phonebook entry if possible ... + if (entry_empty) { + error = xxport_phone_write_entry( phone_entry_no, memtype, addr); + phone_entry_no++; + } else { + phone_entry_no++; + goto try_next_phone_entry; + } + } + + if (error != GN_ERR_NONE) + failedList.append(addr->realName()); + + // break if we got an error on the first entry + if (error != GN_ERR_NONE && it==list.begin()) + break; + + } // for() + + // if we wanted to overwrite all entries, make sure, that we also + // delete all remaining entries in the mobile phone. + while (overwrite_phone_entries && error==GN_ERR_NONE && phone_count>0) { + if (m_progressDlg->wasCancelled()) + break; + if (!deleteLabelInitialized) { + m_progressDlg->setLabel( + i18n("<qt><center>" + "All selected contacts have been sucessfully copied to " + "the Mobile Phone.<br><br>" + "Please wait until all remaining orphaned contacts from " + "the Mobile Phone have been deleted.</center></qt>") ); + m_progressDlg->setButtonText(i18n("&Stop Delete")); + deleteLabelInitialized = true; + progress->setTotalSteps(phone_count); + entries_written = 0; + progress->setProgress(entries_written); + this_filter->processEvents(); + } + if (phone_entry_no > (memstat.used + memstat.free)) + break; + entry_empty = gn_lib_phonebook_entry_isempty(state, memtype, phone_entry_no); + if (!entry_empty) { + error = xxport_phone_delete_entry(phone_entry_no, memtype); + phone_count--; + progress->setProgress(++entries_written); + this_filter->processEvents(); + } + phone_entry_no++; + } + +finish: + m_progressDlg->setLabel(i18n("Export to phone finished.")); + this_filter->processEvents(); + + GNOKII_DEBUG("GNOKII export filter finished.\n"); + + busterminate(); + delete m_progressDlg; + + if (!failedList.isEmpty()) { + GNOKII_DEBUG(QString("Failed to export: %1\n").arg(failedList.join(", "))); + KMessageBox::informationList(parentWidget(), + i18n("<qt>The following contacts could not be exported to the Mobile Phone. " + "Possible Reasons for this problem could be:<br><ul>" + "<li>The contacts contain more information per entry than the phone can store.</li>" + "<li>Your phone does not allow to store multiple addresses, emails, homepages, ...</li>" + "<li>other storage size related problems.</li>" + "</ul>" + "To avoid those kind of problems in the future please reduce the amount of different " + "fields in the above contacts.</qt>"), + failedList, + i18n("Mobile Phone Export") ); + } + + + return true; +} + +/****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ******************************************************************************/ + +#elif defined(HAVE_GNOKII_H) + +#ifdef __GNUC__ +# warning "Please upgrade your gnokii installation to at least version 0.6.13" +# warning "Older gnokii versions below 0.6.13 are not binary compatible and" +# warning "prevents KDE users to upgrade gnokii to newer versions later." +#endif + +/* OLD GNOKII LIBRARIES (< 0.6.13) */ + +/* import */ +static char *lockfile = NULL; +static char manufacturer[64], model[GN_MODEL_MAX_LENGTH+1], + revision[GN_REVISION_MAX_LENGTH+1], imei[GN_IMEI_MAX_LENGTH+1]; +static QString PhoneProductId; + +static struct gn_statemachine state; +static gn_data data; + +static void busterminate(void) +{ + gn_sm_functions(GN_OP_Terminate, NULL, &state); + if (lockfile) gn_device_unlock(lockfile); +} + +static QString businit(void) +{ + gn_error error; + char *aux; + + GNOKII_DEBUG( "Using old gnokii version." ); + +#if defined(LIBGNOKII_VERSION) + if (gn_cfg_read_default()<0) +#else + static char *BinDir; + if (gn_cfg_read(&BinDir)<0) +#endif + return i18n("Failed to initialize the gnokii library."); + + if (!gn_cfg_phone_load("", &state)) + return i18n("Gnokii is not yet configured."); + + // uncomment to debug all gnokii communication on stderr. + // gn_log_debug_mask = GN_LOG_T_STDERR; + + gn_data_clear(&data); + + aux = gn_cfg_get(gn_cfg_info, "global", "use_locking"); + // Defaults to 'no' + if (aux && !strcmp(aux, "yes")) { + lockfile = gn_device_lock(state.config.port_device); + if (lockfile == NULL) { + return i18n("Gnokii reports a 'Lock File Error'.\n " + "Please exit all other running instances of gnokii, check if you have " + "write permissions in the /var/lock directory and try again."); + } + } + + // Initialise the code for the GSM interface. + int old_dcd = state.config.require_dcd; // work-around for older gnokii versions + state.config.require_dcd = false; + error = gn_gsm_initialise(&state); + GNOKII_CHECK_ERROR(error); + state.config.require_dcd = old_dcd; + if (error != GN_ERR_NONE) { + busterminate(); + return i18n("<qt><center>Mobile Phone interface initialization failed.<br><br>" + "The returned error message was:<br><b>%1</b><br><br>" + "You might try to run \"gnokii --identify\" on the command line to " + "check any cable/transport issues and to verify if your gnokii " + "configuration is correct.</center></qt>") + .arg(gn_error_print(error)); + } + + // identify phone + gn_data_clear(&data); + data.manufacturer = manufacturer; + data.model = model; + data.revision = revision; + data.imei = imei; + + QCString unknown(GN_TO(i18n("Unknown"))); + qstrncpy(manufacturer, unknown, sizeof(manufacturer)-1); + qstrncpy(model, unknown, sizeof(model)-1); + qstrncpy(revision, unknown, sizeof(revision)-1); + qstrncpy(imei, unknown, sizeof(imei)-1); + + if (m_progressDlg->wasCancelled()) + return QString::null; + else + error = gn_sm_functions(GN_OP_Identify, &data, &state); + GNOKII_CHECK_ERROR(error); + + GNOKII_DEBUG( QString("Found mobile phone: %1 %2, Revision: %3, IMEI: %4\n") + .arg(manufacturer, model, revision, imei) ); + + PhoneProductId = QString("%1-%2-%3-%4").arg(APP).arg(model).arg(revision).arg(imei); + + return QString::null; +} + + +// get number of entries in this phone memory type (internal/SIM-card) +static gn_error read_phone_memstat( const gn_memory_type memtype, gn_memory_status *memstat ) +{ + gn_error error; + + gn_data_clear(&data); + memset(memstat, 0, sizeof(*memstat)); + memstat->memory_type = memtype; + data.memory_status = memstat; + error = gn_sm_functions(GN_OP_GetMemoryStatus, &data, &state); + GNOKII_CHECK_ERROR(error); + if (error != GN_ERR_NONE) { + switch (memtype) { + case GN_MT_SM: + // use at least 100 entries + memstat->used = 0; + memstat->free = 100; + break; + default: + case GN_MT_ME: + // Phone doesn't support ME (5110) + memstat->used = memstat->free = 0; + break; + } + } + GNOKII_DEBUG( QString("\n\nMobile phone memory status: Type: %1, used=%2, free=%3, total=%4\n\n") + .arg(memtype).arg(memstat->used).arg(memstat->free).arg(memstat->used+memstat->free) ); + return error; +} + + +// read phone entry #index from memory #memtype +static gn_error read_phone_entry( const int index, const gn_memory_type memtype, gn_phonebook_entry *entry ) +{ + gn_error error; + entry->memory_type = memtype; + entry->location = index; + data.phonebook_entry = entry; + error = gn_sm_functions(GN_OP_ReadPhonebook, &data, &state); + GNOKII_CHECK_ERROR(error); + return error; +} + +static bool phone_entry_empty( const int index, const gn_memory_type memtype ) +{ + gn_error error; + gn_phonebook_entry entry; + entry.memory_type = memtype; + entry.location = index; + data.phonebook_entry = &entry; + error = gn_sm_functions(GN_OP_ReadPhonebook, &data, &state); + if (error == GN_ERR_EMPTYLOCATION) + return true; + GNOKII_CHECK_ERROR(error); + if (error == GN_ERR_NONE && entry.empty) + return true; + return false; +} + +static QString buildPhoneInfoString( const gn_memory_status &memstat ) +{ + QString format = QString::fromLatin1("<tr><td><b>%1</b></td><td>%2</td></tr>"); + + return QString::fromLatin1("<b>%1</b><br><table>%2%3%4%5%6</table><br>") + .arg(i18n("Mobile Phone information:")) + .arg(format.arg(i18n("Manufacturer")).arg(GN_FROM(manufacturer))) + .arg(format.arg(i18n("Phone model")).arg(GN_FROM(model))) + .arg(format.arg(i18n("Revision")).arg(GN_FROM(revision))) + .arg(format.arg(i18n("IMEI")).arg(GN_FROM(imei))) + .arg(format.arg(i18n("Phonebook status")) + .arg(i18n("%1 out of %2 contacts used").arg(memstat.used).arg(memstat.used+memstat.free))); +} + +static QString buildMemoryTypeString( gn_memory_type memtype ) +{ + switch (memtype) { + case GN_MT_ME: return i18n("internal memory"); + case GN_MT_SM: return i18n("SIM-card memory"); + default: return i18n("unknown memory"); + } +} + +// read and evaluate all phone entries +static gn_error read_phone_entries( const char *memtypestr, gn_memory_type memtype, + KABC::AddresseeList *addrList ) +{ + gn_error error; + + if (m_progressDlg->wasCancelled()) + return GN_ERR_NONE; + + KProgress* progress = (KProgress*)m_progressDlg->progressBar(); + + progress->setProgress(0); + this_filter->processEvents(); + + // get number of entries in this phone memory type (internal/SIM-card) + gn_memory_status memstat; + error = read_phone_memstat(memtype, &memstat); + + gn_phonebook_entry entry; + QStringList addrlist; + KABC::Address *addr; + QString s, country; + + progress->setTotalSteps(memstat.used); + m_progressDlg->setLabel(i18n("<qt>Importing <b>%1</b> contacts from <b>%2</b> of the Mobile Phone.<br><br>%3</qt>") + .arg(memstat.used) + .arg(buildMemoryTypeString(memtype)) + .arg(buildPhoneInfoString(memstat)) ); + + int num_read = 0; + + for (int i = 1; !m_progressDlg->wasCancelled() && i <= memstat.used + memstat.free; i++) { + error = read_phone_entry( i, memtype, &entry ); + + progress->setProgress(num_read); + this_filter->processEvents(); + + if (error == GN_ERR_EMPTYLOCATION) + continue; + if (error == GN_ERR_INVALIDLOCATION) + break; + if (error == GN_ERR_INVALIDMEMORYTYPE) + break; + if (error == GN_ERR_NONE) { + GNOKII_DEBUG(QString("%1: %2, num=%3, location=%4, group=%5, count=%6\n").arg(i).arg(GN_FROM(entry.name)) + .arg(GN_FROM(entry.number)).arg(entry.location).arg(entry.caller_group).arg(entry.subentries_count)); + KABC::Addressee *a = new KABC::Addressee(); + + // try to split Name into FamilyName and GivenName + s = GN_FROM(entry.name).simplifyWhiteSpace(); + a->setFormattedName(s); // set formatted name as in Phone + if (s.find(',') == -1) { + // assumed format: "givenname [... familyname]" + addrlist = QStringList::split(' ', s); + if (addrlist.count() == 1) { + // only one string -> put it in the GivenName + a->setGivenName(s); + } else { + // multiple strings -> split them. + a->setFamilyName(addrlist.last().simplifyWhiteSpace()); + addrlist.remove(addrlist.last()); + a->setGivenName(addrlist.join(" ").simplifyWhiteSpace()); + } + } else { + // assumed format: "familyname, ... givenname" + addrlist = QStringList::split(',', s); + a->setFamilyName(addrlist.first().simplifyWhiteSpace()); + addrlist.remove(addrlist.first()); + a->setGivenName(addrlist.join(" ").simplifyWhiteSpace()); + } + + a->insertCustom(APP, "X_GSM_CALLERGROUP", s.setNum(entry.caller_group)); + a->insertCustom(APP, "X_GSM_STORE_AT", QString("%1%2").arg(memtypestr).arg(entry.location)); + + // set ProductId + a->setProductId(PhoneProductId); + + // evaluate timestamp (ignore timezone) + QDateTime datetime; + if (entry.date.year<1998) + datetime = QDateTime::currentDateTime(); + else + datetime = QDateTime( QDate(entry.date.year, entry.date.month, entry.date.day), + QTime(entry.date.hour, entry.date.minute, entry.date.second) ); + GNOKII_DEBUG(QString(" date=%1\n").arg(datetime.toString())); + a->setRevision(datetime); + + if (!entry.subentries_count) + a->insertPhoneNumber(KABC::PhoneNumber(entry.number, KABC::PhoneNumber::Work | KABC::PhoneNumber::Pref)); + + /* scan sub-entries */ + if (entry.subentries_count) + for (int n=0; n<entry.subentries_count; n++) { + QString s = GN_FROM(entry.subentries[n].data.number).simplifyWhiteSpace(); + GNOKII_DEBUG(QString(" Subentry#%1, entry_type=%2, number_type=%3, number=%4\n") + .arg(n).arg(entry.subentries[n].entry_type) + .arg(entry.subentries[n].number_type).arg(s)); + if (s.isEmpty()) + continue; + switch(entry.subentries[n].entry_type) { + case GN_PHONEBOOK_ENTRY_Name: + a->setName(s); + break; + case GN_PHONEBOOK_ENTRY_Email: + a->insertEmail(s); + break; + case GN_PHONEBOOK_ENTRY_Postal: + addrlist = QStringList::split(';', s, true); + addr = new KABC::Address(KABC::Address::Work); + if (addrlist.count() <= 1) { + addrlist = QStringList::split(',', s, true); + if (addrlist.count() > 1 ) { + // assumed format: "Locality, ZIP, Country" + addr->setLocality(addrlist[0]); + addr->setPostalCode(addrlist[1]); + if (!addrlist[2].isEmpty()) + addr->setCountry(i18n(GN_TO(addrlist[2]))); + } else { + // no idea about the format, just store it. + addr->setLocality(s); + } + } else { + // assumed format: "POBox; Extended; Street; Locality; Region; ZIP [;Country] + addr->setPostOfficeBox(addrlist[0]); + addr->setExtended(addrlist[1]); + addr->setStreet(addrlist[2]); + addr->setLocality(addrlist[3]); + addr->setRegion(addrlist[4]); + addr->setPostalCode(addrlist[5]); + country = addrlist[6]; + if (!country.isEmpty()) + addr->setCountry(i18n(GN_TO(country))); + } + a->insertAddress(*addr); + delete addr; + break; + case GN_PHONEBOOK_ENTRY_Note: + if (!a->note().isEmpty()) + s = "\n" + s; + a->setNote(a->note()+s); + break; + case GN_PHONEBOOK_ENTRY_Number: + enum KABC::PhoneNumber::Types phonetype; + switch (entry.subentries[n].number_type) { + case GN_PHONEBOOK_NUMBER_Mobile: phonetype = KABC::PhoneNumber::Cell; break; + case GN_PHONEBOOK_NUMBER_Fax: phonetype = KABC::PhoneNumber::Fax; break; + case GN_PHONEBOOK_NUMBER_General: + case GN_PHONEBOOK_NUMBER_Work: phonetype = KABC::PhoneNumber::Work; break; + default: + case GN_PHONEBOOK_NUMBER_Home: phonetype = KABC::PhoneNumber::Home; break; + } + //if (s == entry.number) + // type = (KABC::PhoneNumber::Types) (phonetype | KABC::PhoneNumber::Pref); + a->insertPhoneNumber(KABC::PhoneNumber(s, phonetype)); + break; + case GN_PHONEBOOK_ENTRY_URL: + a->setUrl(s); + break; + case GN_PHONEBOOK_ENTRY_Group: + a->insertCategory(s); + break; + default: + GNOKII_DEBUG(QString(" Not handled id=%1, entry=%2\n") + .arg(entry.subentries[n].entry_type).arg(s)); + break; + } // switch() + } // if(subentry) + + // add only if entry was valid + if (strlen(entry.name) || strlen(entry.number) || entry.subentries_count) + addrList->append(*a); + + // did we read all valid phonebook-entries ? + num_read++; + delete a; + if (num_read >= memstat.used) + break; // yes, all were read + else + continue; // no, we are still missing some. + } + GNOKII_CHECK_ERROR(error); + } + + return GN_ERR_NONE; +} + + +// export to phone + +static gn_error xxport_phone_write_entry( int phone_location, gn_memory_type memtype, + const KABC::Addressee *addr) +{ + gn_phonebook_entry entry; + QString s; + + memset(&entry, 0, sizeof(entry)); + strncpy(entry.name, GN_TO(addr->realName()), sizeof(entry.name)-1); + s = addr->phoneNumber(KABC::PhoneNumber::Pref).number(); + if (s.isEmpty()) + s = addr->phoneNumber(KABC::PhoneNumber::Work).number(); + if (s.isEmpty()) + s = addr->phoneNumber(KABC::PhoneNumber::Home).number(); + if (s.isEmpty()) + s = addr->phoneNumber(KABC::PhoneNumber::Cell).number(); + if (s.isEmpty() && addr->phoneNumbers().count()>0) + s = (*addr->phoneNumbers().at(0)).number(); + s = makeValidPhone(s); + strncpy(entry.number, s.ascii(), sizeof(entry.number)-1); + entry.memory_type = memtype; + QString cg = addr->custom(APP, "X_GSM_CALLERGROUP"); + if (cg.isEmpty()) + entry.caller_group = 5; // default group + else + entry.caller_group = cg.toInt(); + entry.location = phone_location; + + // set date/revision + QDateTime datetime = addr->revision(); + QDate date(datetime.date()); + QTime time(datetime.time()); + entry.date.year = date.year(); + entry.date.month = date.month(); + entry.date.day = date.day(); + entry.date.hour = time.hour(); + entry.date.minute = time.minute(); + entry.date.second = time.second(); + + GNOKII_DEBUG(QString("Write #%1: name=%2, number=%3\n").arg(phone_location) + .arg(GN_FROM(entry.name)).arg(GN_FROM(entry.number))); + + const KABC::Address homeAddr = addr->address(KABC::Address::Home); + const KABC::Address workAddr = addr->address(KABC::Address::Work); + + entry.subentries_count = 0; + gn_phonebook_subentry *subentry = &entry.subentries[0]; + // add all phone numbers + const KABC::PhoneNumber::List phoneList = addr->phoneNumbers(); + KABC::PhoneNumber::List::ConstIterator it; + for ( it = phoneList.begin(); it != phoneList.end(); ++it ) { + const KABC::PhoneNumber *phonenumber = &(*it); + s = phonenumber->number(); + if (s.isEmpty()) continue; + subentry->entry_type = GN_PHONEBOOK_ENTRY_Number; + gn_phonebook_number_type type; + int pn_type = phonenumber->type(); + if ((pn_type & KABC::PhoneNumber::Cell)) + type = GN_PHONEBOOK_NUMBER_Mobile; + else if ((pn_type & KABC::PhoneNumber::Fax)) + type = GN_PHONEBOOK_NUMBER_Fax; + else if ((pn_type & KABC::PhoneNumber::Home)) + type = GN_PHONEBOOK_NUMBER_Home; + else if ((pn_type & KABC::PhoneNumber::Work)) + type = GN_PHONEBOOK_NUMBER_Work; + else type = GN_PHONEBOOK_NUMBER_General; + subentry->number_type = type; + strncpy(subentry->data.number, makeValidPhone(s).ascii(), sizeof(subentry->data.number)-1); + subentry->id = phone_location<<8+entry.subentries_count; + entry.subentries_count++; + subentry++; + if (entry.subentries_count >= GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER) + break; // Phonebook full + } + // add URL + s = addr->url().prettyURL(); + if (!s.isEmpty() && (entry.subentries_count<GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER)) { + subentry->entry_type = GN_PHONEBOOK_ENTRY_URL; + strncpy(subentry->data.number, GN_TO(s), sizeof(subentry->data.number)-1); + entry.subentries_count++; + subentry++; + } + // add E-Mails + QStringList emails = addr->emails(); + for (unsigned int n=0; n<emails.count(); n++) { + if (entry.subentries_count >= GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER) + break; // Phonebook full + s = emails[n].simplifyWhiteSpace(); + if (s.isEmpty()) continue; + // only one email allowed if we have URLS, notes, addresses (to avoid phone limitations) + if (n && !addr->url().isEmpty() && !addr->note().isEmpty() && addr->addresses().count()) { + GNOKII_DEBUG(QString(" DROPPED email %1 in favor of URLs, notes and addresses.\n") + .arg(s)); + continue; + } + subentry->entry_type = GN_PHONEBOOK_ENTRY_Email; + strncpy(subentry->data.number, GN_TO(s), sizeof(subentry->data.number)-1); + entry.subentries_count++; + subentry++; + } + // add Adresses + const KABC::Address::List addresses = addr->addresses(); + KABC::Address::List::ConstIterator it2; + for ( it2 = addresses.begin(); it2 != addresses.end(); ++it2 ) { + if (entry.subentries_count >= GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER) + break; // Phonebook full + const KABC::Address *Addr = &(*it2); + if (Addr->isEmpty()) continue; + subentry->entry_type = GN_PHONEBOOK_ENTRY_Postal; + QStringList a; + QChar sem(';'); + QString sem_repl(QString::fromLatin1(",")); + a.append( Addr->postOfficeBox().replace( sem, sem_repl ) ); + a.append( Addr->extended() .replace( sem, sem_repl ) ); + a.append( Addr->street() .replace( sem, sem_repl ) ); + a.append( Addr->locality() .replace( sem, sem_repl ) ); + a.append( Addr->region() .replace( sem, sem_repl ) ); + a.append( Addr->postalCode() .replace( sem, sem_repl ) ); + a.append( Addr->country() .replace( sem, sem_repl ) ); + s = a.join(sem); + strncpy(subentry->data.number, GN_TO(s), sizeof(subentry->data.number)-1); + entry.subentries_count++; + subentry++; + } + // add Note + s = addr->note().simplifyWhiteSpace(); + if (!s.isEmpty() && (entry.subentries_count<GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER)) { + subentry->entry_type = GN_PHONEBOOK_ENTRY_Note; + strncpy(subentry->data.number, GN_TO(s), sizeof(subentry->data.number)-1); + entry.subentries_count++; + subentry++; + } + + // debug output + for (int st=0; st<entry.subentries_count; st++) { + gn_phonebook_subentry *subentry = &entry.subentries[st]; + GNOKII_DEBUG(QString(" SubTel #%1: entry_type=%2, number_type=%3, number=%4\n") + .arg(st).arg(subentry->entry_type) + .arg(subentry->number_type).arg(GN_FROM(subentry->data.number))); + } + + data.phonebook_entry = &entry; + gn_error error = gn_sm_functions(GN_OP_WritePhonebook, &data, &state); + GNOKII_CHECK_ERROR(error); + + return error; +} + + +static gn_error xxport_phone_delete_entry( int phone_location, gn_memory_type memtype ) +{ + gn_phonebook_entry entry; + memset(&entry, 0, sizeof(entry)); + entry.empty = 1; + entry.memory_type = memtype; + entry.location = phone_location; + data.phonebook_entry = &entry; + GNOKII_DEBUG(QString("Deleting entry %1\n").arg(phone_location)); + gn_error error = gn_sm_functions(GN_OP_WritePhonebook, &data, &state); + GNOKII_CHECK_ERROR(error); + return error; +} + +KABC::AddresseeList GNOKIIXXPort::importContacts( const QString& ) const +{ + KABC::AddresseeList addrList; + + if (KMessageBox::Continue != KMessageBox::warningContinueCancel(parentWidget(), + i18n("<qt>Please connect your Mobile Phone to your computer and press " + "<b>Continue</b> to start importing the personal contacts.<br><br>" + "Please note that if your Mobile Phone is not properly connected " + "the following detection phase might take up to two minutes, during which " + "KAddressbook will behave unresponsively.</qt>") )) + return addrList; + + m_progressDlg = new KProgressDialog( parentWidget(), "importwidget", + i18n("Mobile Phone Import"), + i18n("<qt><center>Establishing connection to the Mobile Phone.<br><br>" + "Please wait...</center></qt>") ); + m_progressDlg->setAllowCancel(true); + m_progressDlg->progressBar()->setProgress(0); + m_progressDlg->progressBar()->setCenterIndicator(true); + m_progressDlg->setModal(true); + m_progressDlg->setInitialSize(QSize(450,350)); + m_progressDlg->show(); + processEvents(); + +#if (QT_VERSION >= 0x030300) + m_progressDlg->setCursor( Qt::BusyCursor ); +#endif + QString errStr = businit(); + m_progressDlg->unsetCursor(); + + if (!errStr.isEmpty()) { + KMessageBox::error(parentWidget(), errStr); + delete m_progressDlg; + return addrList; + } + + GNOKII_DEBUG("GNOKII import filter started.\n"); + m_progressDlg->setButtonText(i18n("&Stop Import")); + + read_phone_entries("ME", GN_MT_ME, &addrList); // internal phone memory + read_phone_entries("SM", GN_MT_SM, &addrList); // SIM card + + GNOKII_DEBUG("GNOKII import filter finished.\n"); + + busterminate(); + delete m_progressDlg; + + return addrList; +} + + +bool GNOKIIXXPort::exportContacts( const KABC::AddresseeList &list, const QString & ) +{ + if (KMessageBox::Continue != KMessageBox::warningContinueCancel(parentWidget(), + i18n("<qt>Please connect your Mobile Phone to your computer and press " + "<b>Continue</b> to start exporting the selected personal contacts.<br><br>" + "Please note that if your Mobile Phone is not properly connected " + "the following detection phase might take up to two minutes, during which " + "KAddressbook will behave unresponsively.</qt>") )) + return false; + + m_progressDlg = new KProgressDialog( parentWidget(), "importwidget", + i18n("Mobile Phone Export"), + i18n("<qt><center>Establishing connection to the Mobile Phone.<br><br>" + "Please wait...</center></qt>") ); + m_progressDlg->setAllowCancel(true); + m_progressDlg->progressBar()->setProgress(0); + m_progressDlg->progressBar()->setCenterIndicator(true); + m_progressDlg->setModal(true); + m_progressDlg->setInitialSize(QSize(450,350)); + m_progressDlg->show(); + processEvents(); + + KProgress* progress = (KProgress*)m_progressDlg->progressBar(); + + KABC::AddresseeList::ConstIterator it; + QStringList failedList; + + gn_error error; + bool deleteLabelInitialized = false; + +#if (QT_VERSION >= 0x030300) + m_progressDlg->setCursor( Qt::BusyCursor ); +#endif + QString errStr = businit(); + m_progressDlg->unsetCursor(); + + if (!errStr.isEmpty()) { + KMessageBox::error(parentWidget(), errStr); + delete m_progressDlg; + return false; + } + + GNOKII_DEBUG("GNOKII export filter started.\n"); + + gn_memory_type memtype = GN_MT_ME; // internal phone memory + + int phone_count; // num entries in phone + bool overwrite_phone_entries = false; + int phone_entry_no, entries_written; + bool entry_empty; + + // get number of entries in this phone memory + gn_memory_status memstat; + error = read_phone_memstat(memtype, &memstat); + if (error == GN_ERR_NONE) { + GNOKII_DEBUG("Writing to internal phone memory.\n"); + } else { + memtype = GN_MT_SM; // try SIM card instead + error = read_phone_memstat(memtype, &memstat); + if (error != GN_ERR_NONE) + goto finish; + GNOKII_DEBUG("Writing to SIM card memory.\n"); + } + phone_count = memstat.used; + + if (memstat.free >= (int) list.count()) { + if (KMessageBox::No == KMessageBox::questionYesNo(parentWidget(), + i18n("<qt>Do you want the selected contacts to be <b>appended</b> to " + "the current mobile phonebook or should they <b>replace</b> all " + "currently existing phonebook entries ?<br><br>" + "Please note, that in case you choose to replace the phonebook " + "entries, every contact in your phone will be deleted and only " + "the newly exported contacts will be available from inside your phone.</qt>"), + i18n("Export to Mobile Phone"), + KGuiItem(i18n("&Append to Current Phonebook")), + KGuiItem(i18n("&Replace Current Phonebook with New Contacts")) ) ) + overwrite_phone_entries = true; + } + + progress->setTotalSteps(list.count()); + entries_written = 0; + progress->setProgress(entries_written); + m_progressDlg->setButtonText(i18n("&Stop Export")); + m_progressDlg->setLabel(i18n("<qt>Exporting <b>%1</b> contacts to the <b>%2</b> " + "of the Mobile Phone.<br><br>%3</qt>") + .arg(list.count()) + .arg(buildMemoryTypeString(memtype)) + .arg(buildPhoneInfoString(memstat)) ); + + // Now run the loop... + phone_entry_no = 1; + for ( it = list.begin(); it != list.end(); ++it ) { + const KABC::Addressee *addr = &(*it); + if (addr->isEmpty()) + continue; + // don't write back SIM-card entries ! + if (addr->custom(APP, "X_GSM_STORE_AT").startsWith("SM")) + continue; + + progress->setProgress(entries_written++); + +try_next_phone_entry: + this_filter->processEvents(); + if (m_progressDlg->wasCancelled()) + break; + + // End of phone memory reached ? + if (phone_entry_no > (memstat.used + memstat.free)) + break; + + GNOKII_DEBUG(QString("Try to write entry '%1' at phone_entry_no=%2, phone_count=%3\n") + .arg(addr->realName()).arg(phone_entry_no).arg(phone_count)); + + error = GN_ERR_NONE; + + // is this phone entry empty ? + entry_empty = phone_entry_empty(phone_entry_no, memtype); + if (overwrite_phone_entries) { + // overwrite this phonebook entry ... + if (!entry_empty) + phone_count--; + error = xxport_phone_write_entry( phone_entry_no, memtype, addr); + phone_entry_no++; + } else { + // add this phonebook entry if possible ... + if (entry_empty) { + error = xxport_phone_write_entry( phone_entry_no, memtype, addr); + phone_entry_no++; + } else { + phone_entry_no++; + goto try_next_phone_entry; + } + } + + if (error != GN_ERR_NONE) + failedList.append(addr->realName()); + + // break if we got an error on the first entry + if (error != GN_ERR_NONE && it==list.begin()) + break; + + } // for() + + // if we wanted to overwrite all entries, make sure, that we also + // delete all remaining entries in the mobile phone. + while (overwrite_phone_entries && error==GN_ERR_NONE && phone_count>0) { + if (m_progressDlg->wasCancelled()) + break; + if (!deleteLabelInitialized) { + m_progressDlg->setLabel( + i18n("<qt><center>" + "All selected contacts have been sucessfully copied to " + "the Mobile Phone.<br><br>" + "Please wait until all remaining orphaned contacts from " + "the Mobile Phone have been deleted.</center></qt>") ); + m_progressDlg->setButtonText(i18n("&Stop Delete")); + deleteLabelInitialized = true; + progress->setTotalSteps(phone_count); + entries_written = 0; + progress->setProgress(entries_written); + this_filter->processEvents(); + } + if (phone_entry_no > (memstat.used + memstat.free)) + break; + entry_empty = phone_entry_empty(phone_entry_no, memtype); + if (!entry_empty) { + error = xxport_phone_delete_entry(phone_entry_no, memtype); + phone_count--; + progress->setProgress(++entries_written); + this_filter->processEvents(); + } + phone_entry_no++; + } + +finish: + m_progressDlg->setLabel(i18n("Export to phone finished.")); + this_filter->processEvents(); + + GNOKII_DEBUG("GNOKII export filter finished.\n"); + + busterminate(); + delete m_progressDlg; + + if (!failedList.isEmpty()) { + GNOKII_DEBUG(QString("Failed to export: %1\n").arg(failedList.join(", "))); + KMessageBox::informationList(parentWidget(), + i18n("<qt>The following contacts could not be exported to the Mobile Phone. " + "Possible Reasons for this problem could be:<br><ul>" + "<li>The contacts contain more information per entry than the phone can store.</li>" + "<li>Your phone does not allow to store multiple addresses, emails, homepages, ...</li>" + "<li>other storage size related problems.</li>" + "</ul>" + "To avoid those kind of problems in the future please reduce the amount of different " + "fields in the above contacts.</qt>"), + failedList, + i18n("Mobile Phone Export") ); + } + + return true; +} + + +/****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ******************************************************************************/ + +#else /* no gnokii installed */ + +KABC::AddresseeList GNOKIIXXPort::importContacts( const QString& ) const +{ + KABC::AddresseeList addrList; + KMessageBox::error(parentWidget(), i18n("Gnokii interface is not available.\n" + "Please ask your distributor to add gnokii at compile time.")); + return addrList; +} + +bool GNOKIIXXPort::exportContacts( const KABC::AddresseeList &list, const QString & ) +{ + Q_UNUSED(list); + KMessageBox::error(parentWidget(), i18n("Gnokii interface is not available.\n" + "Please ask your distributor to add gnokii at compile time.")); + return true; +} + +#endif /* END OF GNOKII LIB SWITCH */ + +/****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ******************************************************************************/ + +#include "gnokii_xxport.moc" + +/* vim: set sts=4 ts=4 sw=4: */ diff --git a/kaddressbook/xxport/gnokii_xxport.desktop b/kaddressbook/xxport/gnokii_xxport.desktop new file mode 100644 index 000000000..c937a7d70 --- /dev/null +++ b/kaddressbook/xxport/gnokii_xxport.desktop @@ -0,0 +1,103 @@ +[Desktop Entry] +X-KDE-Library=libkaddrbk_gnokii_xxport +Name=KAB Mobile Phone XXPort Plugin +Name[af]=KAB selfoon XXPort inprop module +Name[bg]=Приставка за XXPort на мобилен телефон на KAB +Name[bs]=KAB dodatak XXPort u/iz mobilnog telefona +Name[ca]=Endollable d'importació/exportació de telèfon mòbil per al KAB +Name[cs]=Exportní modul do mobilního telefonu +Name[cy]=Ategyn XXPort Ffôn Symudol KAB +Name[da]=KAB Mobiltelefon XXPort-plugin +Name[de]=Mobiltelefon-XXPort-Modul für Adressbuch +Name[el]=Πρόσθετο εισαγωγής/εξαγωγής κινητών τηλεφώνων του KAB +Name[es]=Plugin de KAB para {im,ex}portar números de móvil +Name[et]=KAB mobiiltelefoni eksport/importplugin +Name[eu]=KAB-en mugikorren in/esporatazio plugin-a +Name[fa]=وصلۀ XXPort تلفن همراه KAB +Name[fi]=KAB-matkapuhelinliitännäinen +Name[fr]=Module d'import / export de téléphone portable pour KAB +Name[fy]=KAB Mobile Tillefoan XXPort-plugin +Name[gl]=Extensión XXPort de Teléfono Móbil para KAB +Name[he]=תוסף ייבוא/ייצוא עבור טלפונים ניידים של KAB +Name[hi]=केएबी मोबाइल फोन XXपोर्ट प्लगइन +Name[hu]=KAB mobiltelefon XXPort bővítőmodul +Name[is]=Íforrit fyrir KAB farsíma XXPort +Name[it]=Plugin KAB telefono cellulare XXPort +Name[ja]=KAB 携帯電話インポート/エクスポートプラグイン +Name[ka]=KAB მობილურ ტელეფონთან ექსპორტის მოდული +Name[kk]=Қалта телефонға экспорт/импорт ету +Name[km]=កម្មវិធីជំនួយ KAB Mobile Phone XXPort +Name[lt]=KAB mobilaus telefono XXPort priedas +Name[ms]=Plug masuk KAB Fon Mudah Alih XXPort +Name[nb]=KAB-programtillegg for mobiltelefon +Name[nds]=Mobiltelefoon-Im-/Exportmoduul för KAdressbook +Name[ne]=KAB मोबाइल फोन XXPort प्लगइन +Name[nl]=KAB Mobiele Telefoon XXPort-plugin +Name[nn]=KAB Mobiltelefon XXPort programtillegg +Name[pl]=Wtyczka KAB do importu/eksportu z/do telefonu komórkowego +Name[pt]='Plugin' XXPort para Telemóveis do KAB +Name[pt_BR]=Plug-in de Im/Exportação de/para Telefone Móvel do KAB +Name[ru]=Синхронизация с мобильным телефоном +Name[sk]=KAB modul pre xxport z mobilu +Name[sl]=Vstavek KAB Mobile Phone XXPort +Name[sr]=XXPort прикључак KAB-а за мобилне телефоне +Name[sr@Latn]=XXPort priključak KAB-a za mobilne telefone +Name[sv]=Adressbokens överföringsinsticksprogram för mobiltelefon +Name[ta]=KAB நடமாடும் தொலைபேசி XXபோர்ட் சொருகுப்பொருள் +Name[tg]=Синхронизатсия бо телефони мобилӣ +Name[tr]=KAB Cep Telefonu XXPort Eklentisi +Name[uk]=Втулок KAB для обміну з мобільними телефонами +Name[zh_CN]=KAB 移动电话 XXPort 插件 +Name[zh_TW]=KAB Mobile Phone XXPort 外掛程式 +Comment=Mobile Phone Plugin to Import and Export Addressbook Entries +Comment[af]=Inprop module wat kontakte in selfoon formaat invoer en uitvoer +Comment[bg]=Приставка за експортиране/импортиране на контактите от/към мобилен телефон +Comment[bs]=Dodatak za uvoz i izvoz stavki adresara iz mobilnog telefona +Comment[ca]=Endollable de telèfon mòbil per a importar i exportar entrades de la llibreta d'adreces +Comment[cs]=Modul mobilního telefonu pro import a export záznamů Knihy adres +Comment[cy]=Ategyn Ffôn Symudol i fewnforio ac allforio cofnodion y Llyfr Cyfeiriadau +Comment[da]=Mobiltelefon-plugin til at importere og eksportere adressebogsindgange +Comment[de]=Mobiltelefon-Modul zum Import/Export von Adressbuch-Einträgen +Comment[el]=Πρόσθετο για εισαγωγή και εξαγωγή επαφών βιβλίου διευθύνσεων από κινητά τηλέφωνα +Comment[es]=Plugin para importar y exportar números de móviles de las entradas de la libreta de direcciones +Comment[et]=Mobiiltelefoni plugin aadressiraamatu kirjete importimiseks ja eksportimiseks +Comment[eu]=Helbide-liburuko sarrerak in/esportatzeko mugikorren plugin-a +Comment[fa]=وصلۀ تلفن همراه جهت واردات و صادرات مدخلهای کتاب نشانی +Comment[fi]=Matkapuhelinliitännäinen osoitekirjan kontaktien tuontiin ja vientiin. +Comment[fr]=Module de téléphone portable pour importer et exporter des entrées du carnet d'adresses +Comment[fy]=Mobile-tillefoan-plugin faor it importearjen en eksportearjen fan adresboekitems +Comment[gl]=Extensión de Teléfono Móbil para importar e exportar entradas do caderno de enderezos +Comment[hi]=पता पुस्तिका प्रविष्टियों को आयात और निर्यात करने का मोबाइल फोन प्लगइन +Comment[hu]=Mobiltelefonos bővítőmodul címbejegyzések importálásához/exportálásához +Comment[is]=Íforrit til að færa tengilið milli póstfangaskrár og farsíma +Comment[it]=Plugin per importare ed esportare voci della rubrica da un telefono cellulare +Comment[ja]=アドレス帳のエントリをインポート/エクスポートする携帯電話用プラグイン +Comment[ka]=მობილური ტელეფონის მოდული წიგნაკის ელემენტების იმპორტ/ექსპორტისათვის +Comment[kk]=Қалта телефонға адр. кітапша жазуын экспорт/импорт ету модулі +Comment[km]=កម្មវិធីជំនួយទូរស័ព្ទចល័តដើម្បីនាំចូល និងនាំចេញធាតុសៀវភៅអាសយដ្ឋាន +Comment[lt]=Priedas skirtas importuoti ir eksportuoti adresų knygelės įrašus į mobiliuosius telefonus +Comment[mk]=Приклучок за мобилни телефони за внесување и изнесување контакти од адресарот +Comment[ms]=Plug masuk Fon Mudah Alih untuk Import dan Eksport Input Buku Alamat +Comment[nb]=Programtillegg for import/eksport av adressebok fra/til mobiltelefon +Comment[nds]=Mobiltelefoon-Moduul för't Im- un Exporteren vun KAdressbook-Indrääg +Comment[ne]=ठेगाना पुस्तिका प्रविष्टि आयात र निर्यात गर्न मोबाइल फोन प्लगइन गर्नुहोस् +Comment[nl]=Mobiele-telefoon-plugin voor het importeren en exporteren van adresboekitems +Comment[nn]=Programtillegg for å importera og eksportera adressebokoppføringar i mobiltelefon +Comment[pl]=Wtyczka do importowania i eksportowania wizytówek z/do telefonu komórkowego +Comment[pt]=Um 'plugin' para importar e exportar contactos da agenda do telemóvel +Comment[pt_BR]=Plug-in para Importar e Exportar Entradas do Livro de Endereços de/para Telefone Móvel +Comment[ru]=Импорт и экспорт контактов мобильного телефона +Comment[sk]=Modul pre import a export kontaktov z modulu +Comment[sl]=Vstavek za uvoz in izvoz vnosov v adresarju prenosnih telefonov. +Comment[sr]=Прикључак за увоз и извоз ставки из адресара у мобилни телефон +Comment[sr@Latn]=Priključak za uvoz i izvoz stavki iz adresara u mobilni telefon +Comment[sv]=Insticksprogram för import och export av adressboksposter till mobiltelefon +Comment[ta]=முகவரி புத்தகத்தின் உள்ளிடுகளை ஏற்றுமதி மற்றும் இறக்குமதி செய்ய செல்பேசி மூலம் சொருகுப்பொருள் +Comment[tg]=Модул барои воридот ва содироти алоқаи телефони мобилӣ +Comment[tr]=Adres Defteri Girdilerini Cep Telefonuna Alma ve Gönderme Eklentisi +Comment[uk]=Втулок для імпорту та експорту записів у адресній книзі мобільних телефонів +Comment[zh_CN]=导入和导出地址簿项的移动电话插件 +Comment[zh_TW]=匯入與匯出通訊錄的手機外掛程式 +Type=Service +ServiceTypes=KAddressBook/XXPort +X-KDE-KAddressBook-XXPortPluginVersion=1 diff --git a/kaddressbook/xxport/gnokii_xxport.h b/kaddressbook/xxport/gnokii_xxport.h new file mode 100644 index 000000000..64176fcaf --- /dev/null +++ b/kaddressbook/xxport/gnokii_xxport.h @@ -0,0 +1,43 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 - 2003 Helge Deller <[email protected]> + + 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 GNOKII_XXPORT_H +#define GNOKII_XXPORT_H + +#include <xxport.h> + +class GNOKIIXXPort : public KAB::XXPort +{ + Q_OBJECT + + public: + GNOKIIXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name = 0 ); + + QString identifier() const { return "gnokii"; } + + public slots: + bool exportContacts( const KABC::AddresseeList &list, const QString &data ); + KABC::AddresseeList importContacts( const QString &data ) const; +}; + +#endif diff --git a/kaddressbook/xxport/gnokii_xxportui.rc b/kaddressbook/xxport/gnokii_xxportui.rc new file mode 100644 index 000000000..78e323a45 --- /dev/null +++ b/kaddressbook/xxport/gnokii_xxportui.rc @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="gnokii_xxport" version="2"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Menu name="file_import"><text>&Import</text> + <Action name="file_import_gnokii"/> + </Menu> + <Menu name="file_export"><text>&Export</text> + <Action name="file_export_gnokii"/> + </Menu> + </Menu> +</MenuBar> +</gui> diff --git a/kaddressbook/xxport/kde2_xxport.cpp b/kaddressbook/xxport/kde2_xxport.cpp new file mode 100644 index 000000000..03a524e9f --- /dev/null +++ b/kaddressbook/xxport/kde2_xxport.cpp @@ -0,0 +1,79 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Tobias Koenig <[email protected]> + + 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 <qfile.h> + +#include <kdebug.h> +#include <kfiledialog.h> +#include <kio/netaccess.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kurl.h> + +#include "xxportmanager.h" + +#include "kde2_xxport.h" + +K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_kde2_xxport, KDE2XXPort ) + +KDE2XXPort::KDE2XXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) + : KAB::XXPort( ab, parent, name ) +{ + createImportAction( i18n( "Import KDE 2 Addressbook..." ) ); +} + +KABC::AddresseeList KDE2XXPort::importContacts( const QString& ) const +{ + QString fileName = locateLocal( "data", "kabc/std.vcf" ); + if ( !QFile::exists( fileName ) ) { + KMessageBox::sorry( parentWidget(), i18n( "<qt>Could not find a KDE 2 address book <b>%1</b>.</qt>" ).arg( fileName ) ); + return KABC::AddresseeList(); + } + + int result = KMessageBox::questionYesNoCancel( parentWidget(), + i18n( "Override previously imported entries?" ), + i18n( "Import KDE 2 Addressbook" ), i18n("Import"), i18n("Do Not Import") ); + + if ( !result ) return KABC::AddresseeList(); + + KProcess proc; + + if ( result == KMessageBox::Yes ) { + proc << "kab2kabc"; + proc << "--override"; + } else if ( result == KMessageBox::No ) + proc << "kab2kabc"; + else + kdDebug(5720) << "KAddressBook::importKDE2(): Unknow return value." << endl; + + proc.start( KProcess::Block ); + + addressBook()->load(); + + return KABC::AddresseeList(); +} + +#include "kde2_xxport.moc" diff --git a/kaddressbook/xxport/kde2_xxport.desktop b/kaddressbook/xxport/kde2_xxport.desktop new file mode 100644 index 000000000..f2c20026c --- /dev/null +++ b/kaddressbook/xxport/kde2_xxport.desktop @@ -0,0 +1,106 @@ +[Desktop Entry] +X-KDE-Library=libkaddrbk_kde2_xxport +Name=KAB KDE2 XXPort Plugin +Name[af]=KAB KDE2 XXPort inprop module +Name[be]=Дапаўненне KAB "Імпарт/Экспарт KDE2" +Name[bg]=Приставка за KDE2 XXPort на KAB +Name[br]=Lugent XXPorzh KAB KDE2 +Name[bs]=KAB dodatak za KDE2 XXPort +Name[ca]=Endollable d'importació/exportació KDE2 per al KAB +Name[cs]=Exportní modul KDE2 +Name[cy]=Ategyn XXPort KDE2 KAB +Name[da]=KAB KDE2 XXPort-plugin +Name[de]=KDE2-XXPort-Modul für Adressbuch +Name[el]=Πρόσθετο εισαγωγής KDE2 του KAB +Name[es]=Plugin KAB para {im,ex}portar KDE2 +Name[et]=KAB KDE2 importplugin +Name[eu]=KAB-en KDE2 in/esportazio plugin-a +Name[fa]=وصلۀ KAB KDE2 XXPort +Name[fi]=KAB KDE2 -liitännäinen +Name[fr]=Module d'import / export de KDE 2 pour KAB +Name[fy]=KAB KDE2 XXPort-plugin +Name[gl]=Extensión XXPort de KDE2 para KAB +Name[he]=תוסף ייבוא/ייצוא עבור KDE2 של KAB +Name[hi]=केएबी केडीई2 XXपोर्ट प्लगइन +Name[hu]=KAB KDE2 XXPort bővítőmodul +Name[is]=Íforrit fyrir KAB KDE2 XXPort +Name[ja]=KAB KDE2 インポート/プラグイン +Name[ka]=KAB KDE2-ს ექსპორტის მოდული +Name[kk]=KDE2 пішімінен импорт ету +Name[km]=កម្មវិធីជំនួយ KAB KDE2 XXPort +Name[lt]=KAB KDE2 XXPort priedas +Name[ms]=Plug masuk KAB KDE2 XXPort +Name[nb]=KAB-programtillegg for KDE2 +Name[nds]=KDE2-Importmoduul för KAdressbook +Name[ne]=KAB KDE2 XXPort प्लगइन +Name[nl]=KAB KDE2 XXPort-plugin +Name[nn]=KAB KDE2 XXPort programtillegg +Name[pl]=Wtyczka KAB do importu książki adresowej KDE2 +Name[pt]='Plugin' XXPort para KDE2 do KAB +Name[pt_BR]=Plug-in de Importação de KDE2 do KAB +Name[ru]=Импорт адресной книги KDE2 +Name[sl]=Vstavek KAB KDE2 XXPort +Name[sr]=XXPort прикључак KAB-а за KDE2 +Name[sr@Latn]=XXPort priključak KAB-a za KDE2 +Name[sv]=Adressbokens KDE 2-överföringsinsticksprogram +Name[ta]=KAB KDE2 ஏற்றுமதி சொருகுப்பொருள் +Name[tg]=Воридоти китоби адресии KDE2 +Name[tr]=KAB KDE2 XXPort Eklentisi +Name[uk]=Втулок KAB для обміну з KDE2 +Name[zh_CN]=KAB KDE2 XXPort 插件 +Name[zh_TW]=KAB KDE2 XXPort 外掛程式 +Comment=Plugin to import the old KDE 2 address book +Comment[af]=Inprop module om 'n ou KDE 2 adres boek in te voer +Comment[be]=Дапаўненне для імпарту старой адраснай кнігі KDE 2 +Comment[bg]=Приставка за импортиране на контактите от адресника в KDE 2 +Comment[bs]=Dodatak za uvoz iz starog KDE 2 adresara +Comment[ca]=Endollable per a importar l'antiga llibreta d'adreces del KDE 2 +Comment[cs]=Modul pro import staré KDE 2 knihy adres +Comment[cy]=Ategyn i fewnforio'r hen lyfr cyfeiriadau KDE2 +Comment[da]=Plugin til at importere den gamle KDE 2 adressebog +Comment[de]=Modul zum Import von Adressbüchern aus KDE 2 +Comment[el]=Πρόσθετο για εισαγωγή του παλιού βιβλίου διευθύνσεων του KDE 2 +Comment[es]=Plugin para importar de la libreta de direcciones de KDE 2 +Comment[et]=Plugin vana KDE2 aadressiraamatu importimiseks +Comment[eu]=KDE2-ko helbide-liburu zaharrak inporatzeko plugin-a +Comment[fa]=وصله برای واردات کتاب نشانی قدیمی KDE ۲ +Comment[fi]=Liitännäinen vanhan KDE2-osoitekirjan tuontiin +Comment[fr]=Module d'import du vieux carnet d'adresses de KDE 2 +Comment[fy]=Plugin foar it importearjen fan it âlde KDE 2-adresboek +Comment[gl]=Extensión para importar o vello caderno de enderezos de KDE 2 +Comment[hi]=पुराना केडीई 2 पता पुस्तिका को आयात के लिए प्लगइन +Comment[hu]=Bővítőmodul KDE2-es címjegyzék importálásához +Comment[is]=Íforrit til að færa inn gömlu KDE2 vistfangaskrána +Comment[it]=Plugin per importare le vecchie voci della rubrica di KDE2 +Comment[ja]=古い KDE 2 アドレス帳をインポートするプラグイン +Comment[ka]=ძველი KDE2-ს წიგნაკის იმპორტის მოდული +Comment[kk]=Ескі KDE2 адр.кітапшасынан импорт ету модулі +Comment[km]=កម្មវិធីជំនួយដើម្បីនាំចូលសៀវភៅអាសយដ្ឋាន KDE 2 ចាស់ៗ +Comment[lt]=Priedas senosios KDE 2 adresų knygelės importui +Comment[mk]=Приклучок за внесување на старите адресари од KDE 2 +Comment[ms]=Plug masuk untuk import buku alamat lama KDE 2 +Comment[nb]=Programtillegg for å importere adressebok fra KDE2 +Comment[nds]=Moduul för't Importeren vun KDE2-Adressböker +Comment[ne]=पूरानो केडीई २ ठेगाना पुस्तिका आयात गर्न प्लगइन गर्नुहोस् +Comment[nl]=Plugin voor het importeren van het oude KDE 2-adresboek +Comment[nn]=Programtillegg for å importera den gamle KDE 2 adresseboka +Comment[pl]=Wtyczka do importu starej książki adresowej z KDE 2 +Comment[pt]=Um 'plugin' para importar o livro de endereços antigo do KDE 2 +Comment[pt_BR]=Plug-in para importar o antigo livro de endereços do KDE2 +Comment[ru]=Импорт файлов адресной книги KDE2 +Comment[sk]=Plugin pre import starej knihy adries z KDE 2 +Comment[sl]=Vstavek za uvoz starih adresarjev iz KDE 2 +Comment[sr]=Прикључак за увоз старог KDE 2 адресара +Comment[sr@Latn]=Priključak za uvoz starog KDE 2 adresara +Comment[sv]=Insticksprogram för import av den gamla KDE 2 adressboken +Comment[ta]=பழைய KDE 2 கேமுகவரிபுத்தகத்தை ஏற்றுமதி செய்ய சொருகுப்பொருள் +Comment[tg]=Модул барои воридоти файлҳои китобиадресии KDE2 +Comment[tr]=KDE 2 adres defteri bilgilerini alma eklentisi +Comment[uk]=Втулок для імпорту адресної книги старого формату часів KDE 2 +Comment[uz]=Eski KDE 2 manzillar daftarini import qilish uchun plagin +Comment[uz@cyrillic]=Эски KDE 2 манзиллар дафтарини импорт қилиш учун плагин +Comment[zh_CN]=导入旧的 KDE 2 地址簿的插件 +Comment[zh_TW]=匯入舊的 KDE2 通訊錄的外掛程式 +Type=Service +ServiceTypes=KAddressBook/XXPort +X-KDE-KAddressBook-XXPortPluginVersion=1 diff --git a/kaddressbook/xxport/kde2_xxport.h b/kaddressbook/xxport/kde2_xxport.h new file mode 100644 index 000000000..4f5f2edb0 --- /dev/null +++ b/kaddressbook/xxport/kde2_xxport.h @@ -0,0 +1,42 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Tobias Koenig <[email protected]> + + 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 KDE2_XXPORT_H +#define KDE2_XXPORT_H + +#include <xxport.h> + +class KDE2XXPort : public KAB::XXPort +{ + Q_OBJECT + + public: + KDE2XXPort( KABC::AddressBook *ab, QWidget *parent, const char *name = 0 ); + + QString identifier() const { return "kde2"; } + + public slots: + KABC::AddresseeList importContacts( const QString &data ) const; +}; + +#endif diff --git a/kaddressbook/xxport/kde2_xxportui.rc b/kaddressbook/xxport/kde2_xxportui.rc new file mode 100644 index 000000000..990b3e7b3 --- /dev/null +++ b/kaddressbook/xxport/kde2_xxportui.rc @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="kde2_xxport" version="1"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Menu name="file_import"><text>&Import</text> + <Action name="file_import_kde2"/> + </Menu> + </Menu> +</MenuBar> +</gui> diff --git a/kaddressbook/xxport/ldif_xxport.cpp b/kaddressbook/xxport/ldif_xxport.cpp new file mode 100644 index 000000000..342ff9d81 --- /dev/null +++ b/kaddressbook/xxport/ldif_xxport.cpp @@ -0,0 +1,140 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2000 - 2002 Oliver Strutynski <[email protected]> + Copyright (c) 2002 - 2003 Helge Deller <[email protected]> + Tobias Koenig <[email protected]> + + 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. +*/ + +/* + Description: + The LDAP Data Interchange Format (LDIF) is a common ASCII-text based + Internet interchange format. Most programs allow you to export data in + LDIF format and e.g. Netscape and Mozilla store by default their + Personal Address Book files in this format. + This import and export filter reads and writes any LDIF version 1 files + into your KDE Addressbook. +*/ + +#include <qfile.h> + +#include <kfiledialog.h> +#include <kio/netaccess.h> +#include <klocale.h> +#include <kmdcodec.h> +#include <kmessagebox.h> +#include <ktempfile.h> +#include <kurl.h> +#include <kabc/ldifconverter.h> + +#include <kdebug.h> + +#include "ldif_xxport.h" + +K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_ldif_xxport, LDIFXXPort ) + +LDIFXXPort::LDIFXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) + : KAB::XXPort( ab, parent, name ) +{ + createImportAction( i18n( "Import LDIF Addressbook..." ) ); + createExportAction( i18n( "Export LDIF Addressbook..." ) ); +} + +/* import */ + +KABC::AddresseeList LDIFXXPort::importContacts( const QString& ) const +{ + KABC::AddresseeList addrList; + + QString fileName = KFileDialog::getOpenFileName( QDir::homeDirPath(), + "text/x-ldif", 0 ); + if ( fileName.isEmpty() ) + return addrList; + + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) { + QString msg = i18n( "<qt>Unable to open <b>%1</b> for reading.</qt>" ); + KMessageBox::error( parentWidget(), msg.arg( fileName ) ); + return addrList; + } + + QTextStream t( &file ); + t.setEncoding( QTextStream::Latin1 ); + QString wholeFile = t.read(); + QDateTime dtDefault = QFileInfo(file).lastModified(); + file.close(); + + KABC::LDIFConverter::LDIFToAddressee( wholeFile, addrList, dtDefault ); + + return addrList; +} + + +/* export */ + +bool LDIFXXPort::exportContacts( const KABC::AddresseeList &list, const QString& ) +{ + KURL url = KFileDialog::getSaveURL( QDir::homeDirPath() + "/addressbook.ldif", + "text/x-ldif" ); + if ( url.isEmpty() ) + return true; + + if ( !url.isLocalFile() ) { + KTempFile tmpFile; + if ( tmpFile.status() != 0 ) { + QString txt = i18n( "<qt>Unable to open file <b>%1</b>.%2.</qt>" ); + KMessageBox::error( parentWidget(), txt.arg( url.url() ) + .arg( strerror( tmpFile.status() ) ) ); + return false; + } + + doExport( tmpFile.file(), list ); + tmpFile.close(); + + return KIO::NetAccess::upload( tmpFile.name(), url, parentWidget() ); + } else { + QString filename = url.path(); + QFile file( filename ); + + if ( !file.open( IO_WriteOnly ) ) { + QString txt = i18n( "<qt>Unable to open file <b>%1</b>.</qt>" ); + KMessageBox::error( parentWidget(), txt.arg( filename ) ); + return false; + } + + doExport( &file, list ); + file.close(); + + return true; + } +} + +void LDIFXXPort::doExport( QFile *fp, const KABC::AddresseeList &list ) +{ + QString str; + KABC::LDIFConverter::addresseeToLDIF( list, str ); + + QTextStream t( fp ); + t.setEncoding( QTextStream::UnicodeUTF8 ); + t << str; +} + +#include "ldif_xxport.moc" + diff --git a/kaddressbook/xxport/ldif_xxport.desktop b/kaddressbook/xxport/ldif_xxport.desktop new file mode 100644 index 000000000..abdc10958 --- /dev/null +++ b/kaddressbook/xxport/ldif_xxport.desktop @@ -0,0 +1,105 @@ +[Desktop Entry] +X-KDE-Library=libkaddrbk_ldif_xxport +Name=KAB LDIF XXPort Plugin +Name[af]=KAB LDIF XXPort inprop module +Name[be]=Дапаўненне KAB "Імпарт LDIF" +Name[bg]=Приставка за LDIF XXPort на KAB +Name[br]=Lugent XXPorzh KAB LDIF +Name[bs]=KAB dodatak za LDIF XXPort +Name[ca]=Endollable per importació/exportació de LDIF per al KAB +Name[cs]=Exportní modul LDIF +Name[cy]=Ategyn XXPort LDIF KAB +Name[da]=KAB LDIF XXPort-plugin +Name[de]=LDIF-XXPort-Modul für Adressbuch +Name[el]=Πρόσθετο εισαγωγής/εξαγωγής LDIF του KAB +Name[es]=Plugin para {im,ex}portar LDIF +Name[et]=KAB LDIF eksport/importplugin +Name[eu]=KAB-en LDIF in/esportazio plugin-a +Name[fa]=وصلۀ KAB LDIF XXPort +Name[fi]=KAB LDIF -liitännäinen +Name[fr]=Module d'import / export LDIF pour KAB +Name[fy]=KAB LDIF XXPort-plugin +Name[gl]=Extensión XXPort de LDIF para KAB +Name[he]=תוסף ייבוא/ייצוא עבור LDIF של KAB +Name[hi]=केएबी एलडीआईएफ XXपोर्ट प्लगइन +Name[hu]=KAB LDIF XXPort bővítőmodul +Name[is]=Íforrit fyrir KAB LDIF XXPort +Name[ja]=KAB LDIF インポート/エクスポートプラグイン +Name[ka]=KAB LDIF-ის ექსპორტის მოდული +Name[kk]=LDIF пішіміне экспорт/импорт ету +Name[km]=កម្មវិធីជំនួយ KAB LDIF XXPort +Name[lt]=KAB LDIF XXPort priedas +Name[ms]=Plug masuk KAB LDIF XXPort +Name[nb]=KAB-programtillegg for LDIF-format +Name[nds]=LDIF-Im-/Exportmoduul för KAdressbook +Name[ne]=KAB LDIF XXPort प्लगइन +Name[nl]=KAB LDIF XXPort-plugin +Name[nn]=KAB LDIF XXPort programtillegg +Name[pl]=Wtyczka KAB do importu/eksportu z/do formatu LDIF +Name[pt]='Plugin' XXPort para LDIF do KAB +Name[pt_BR]=Plug-in de Im/Exportação de LDIF do KAB +Name[ru]=Обмен информацией через LDIF +Name[sk]=KAB modul pre xxport LDIF +Name[sl]=Vstavek KAB LDIF XXPort +Name[sr]=XXPort прикључак KAB-а за LDIF +Name[sr@Latn]=XXPort priključak KAB-a za LDIF +Name[sv]=Adressbokens LDIF-överföringsinsticksprogram +Name[ta]=KAB LDIF சோதனை சொருகுப்பொருள் +Name[tg]=Мубодилаи иттилоот аз KDE2 +Name[tr]=KAB LDIF XXPort Eklentisi +Name[uk]=Втулок KAB для обміну через LDIF +Name[zh_CN]=KAB LDIF XXPort 插件 +Name[zh_TW]=KAB LDIF XXPort 外掛程式 +Comment=Plugin to import and export contacts in Netscape and Mozilla LDIF format +Comment[af]=Inprop module wat kontakte in Netscape/Mozilla LDIF formaat invoer en uitvoer +Comment[be]=Дапаўненне для імпарту кантактаў у фармаце Netscape/Mozilla LDIF +Comment[bg]=Приставка за импортиране/експортиране на контактите във формат на Netscape и Mozilla (LDIF) +Comment[bs]=Dodatak za uvoz i izvoz kontakata iz LDIF formata koji koriste Netscape i Mozilla +Comment[ca]=Endollable per a importar i exportar contactes en el format LDIF de Mozilla i Netscape +Comment[cs]=Modul pro import a export kontaktů ve formátu Netscape a Mozilla LDIF +Comment[cy]=Ategyn i fewnforio ac allforio cysylltau yn fformat LDIF Netscape a Mozilla +Comment[da]=Plugin til at importere og eksportere kontakter i Netscape og Mozilla LDIF-format +Comment[de]=Modul zum Import/Export von Kontakten im LDIF-Format aus Netscape und Mozilla +Comment[el]=Πρόσθετο για εισαγωγή και εξαγωγή επαφών μορφής LDIF του Netscape και Mozilla +Comment[es]=Plugin para importar y exportar contactos en el formato de intercambio LDIF de Netscape y Mozilla +Comment[et]=Plugin kontaktide importimiseks ja ekportimiseks Netscape ja Mozilla LDIF vormingus +Comment[eu]=Netscape eta Mozilla-ren LDIF formatuan kontaktuak in/esportatzeko plugin-a +Comment[fa]=وصله برای واردات و صادرات تماسها در قالب LDIF موزیلا و نتاسکیپ +Comment[fi]=Liitännäinen Netscapen ja Mozillan LDIF-muodon kontaktien tuontiin ja vientiin +Comment[fr]=Module d'import / export des contacts au format LDIF Mozilla et Netscape +Comment[fy]=Plugin foar it ymportearjen en eksportearjen fan kontaktpersoanen yn Netscape's en Mozilla's LDIF-formaat +Comment[gl]=Extensión para importar e exportar contactos en formato LDIF de Netscape e Mozilla +Comment[hi]=नेटस्केप तथा मोजिला एलडीआईएफ फार्मेट में सम्पर्कों को आयात और निर्यात करने का प्लगइन +Comment[hu]=Bővítőmodul Netscape és Mozilla LDIF formátumú névjegyek importálásához/exportálásához +Comment[is]=Íforrit sem flytur flytja inn eða út tengiliði í Netscape og Mozilla LDIF sniði +Comment[it]=Plugin per importare ed esportare contatti in formato Netscape e Mozilla LDIF +Comment[ja]=Netscape と Mozilla の LDIF フォーマットで連絡先をインポート/エクスポートするプラグイン +Comment[ka]= Netscape-სა და Mozilla-ს კონტაქტების იმპორტ/ექსპორტის მოდული LDIF ფორმატით +Comment[kk]=Netscape пен Mozilla LDIF пішіміне экспорт/импорт ету модулі +Comment[km]=កម្មវិធីជំនួយដើម្បីនាំចូល និងនាំចេញទំនាក់ទំនងក្នុងទ្រង់ទ្រាយជា Netscape និង Mozilla LDIF +Comment[lt]=Priedas, skirtas kontaktų importavimui ir eksportavimui Netscape ir Mozilla LDIFF formatu +Comment[mk]=Приклучок за внесување и изнесување контакти во форматите на Netscape и Mozilla LDIF +Comment[ms]=Plug masuk untuk import dan eksport alamat perhubungan di dalam format LDIF Netscape dan Mozilla +Comment[nb]=Programtillegg for import/eksport av kontakter i Netscape og Mozillas LDIF-format +Comment[nds]=Moduul för't Im- un Exporteren vun Kontakten in't LDIF-Formaat vun Netscape und Mozilla +Comment[ne]=नेटस्क्येप र मोजिला LDIF ढाँचामा आयात निर्यात गर्न प्लगइन गर्नुहोस् +Comment[nl]=Plugin voor het importeren en exporteren van contactpersonen in Netscape's en Mozilla's LDIF-formaat +Comment[nn]=Programtillegg for å importera og eksportera kontaktar i Netscape og Mozilla LDIF-format +Comment[pl]=Wtyczka do importowania i eksportowania wizytówek z/do formatu LDIF używanego przez Mozillę i Netscape'a +Comment[pt]=Um 'plugin' para importar e exportar os contactos no formato LDIF do Netscape e do Mozilla +Comment[pt_BR]=Plug-in para importar e exportar contatos no formato LDIF do Netscape e Mozilla +Comment[ru]=Импорт и экспорт контактов через формат LDIF Netscape и Mozilla +Comment[sk]=Modul pre import a export kontaktov z Netscape a Mozilla formátu LDIF +Comment[sl]=Vstavek za uvoz in izvoz stikov v obliki LDIF (Netscape in Mozilla) +Comment[sr]=Прикључак за увоз и извоз контаката у Netscape и Mozilla LDIF формат +Comment[sr@Latn]=Priključak za uvoz i izvoz kontakata u Netscape i Mozilla LDIF format +Comment[sv]=Insticksprogram för import och export av kontakter med Netscapes och Mozillas LDIF-format +Comment[ta]=நெட்ஸ்கேப் மற்றும் மொசில்லா LDIF வடிவமைப்பை ஏற்றுமதி/இறக்குமதியில் தொடர்புக்கொள்ள சொருகுப்பொருள் +Comment[tg]=Модул барои воридот ва содироти алоқа аз формати LDIF Netscape ва Mozilla +Comment[tr]=Netscape ve Mozilla'nın LDIF biçimindeki bağlantılarını alma ve gönderme eklentisi +Comment[uk]=Втулок для імпорту та експорту контактів у LDIF сумісний з Netscape та Mozilla +Comment[zh_CN]=导入和导出 Netscape 和 Mozilla LDIF 格式联系人的插件 +Comment[zh_TW]=匯入與匯出 Netscape 與 Mozilla LDIF 格式聯絡人的外掛程式 +Type=Service +ServiceTypes=KAddressBook/XXPort +X-KDE-KAddressBook-XXPortPluginVersion=1 diff --git a/kaddressbook/xxport/ldif_xxport.h b/kaddressbook/xxport/ldif_xxport.h new file mode 100644 index 000000000..d5ae2cdd3 --- /dev/null +++ b/kaddressbook/xxport/ldif_xxport.h @@ -0,0 +1,47 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2000 - 2003 Oliver Strutynski <[email protected]> + Tobias Koenig <[email protected]> + + 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 LDIF_XXPORT_H +#define LDIF_XXPORT_H + +#include <xxport.h> + +class LDIFXXPort : public KAB::XXPort +{ + Q_OBJECT + + public: + LDIFXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name = 0 ); + + QString identifier() const { return "ldif"; } + + public slots: + bool exportContacts( const KABC::AddresseeList &list, const QString &data ); + KABC::AddresseeList importContacts( const QString &data ) const; + + private: + void doExport( QFile *fp, const KABC::AddresseeList &list ); +}; + +#endif diff --git a/kaddressbook/xxport/ldif_xxportui.rc b/kaddressbook/xxport/ldif_xxportui.rc new file mode 100644 index 000000000..53e80523e --- /dev/null +++ b/kaddressbook/xxport/ldif_xxportui.rc @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="ldif_xxport" version="3"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Menu name="file_import"><text>&Import</text> + <Action name="file_import_ldif"/> + </Menu> + <Menu name="file_export"><text>&Export</text> + <Action name="file_export_ldif"/> + </Menu> + </Menu> +</MenuBar> +</gui> diff --git a/kaddressbook/xxport/opera_xxport.cpp b/kaddressbook/xxport/opera_xxport.cpp new file mode 100644 index 000000000..c3d707b88 --- /dev/null +++ b/kaddressbook/xxport/opera_xxport.cpp @@ -0,0 +1,126 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 - 2003 Daniel Molkentin <[email protected]> + Tobias Koenig <[email protected]> + + 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 <qfile.h> +#include <qregexp.h> + +#include <kfiledialog.h> +#include <kio/netaccess.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <ktempfile.h> +#include <kurl.h> + +#include <kdebug.h> + +#include "opera_xxport.h" + +K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_opera_xxport, OperaXXPort ) + +OperaXXPort::OperaXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) + : KAB::XXPort( ab, parent, name ) +{ + createImportAction( i18n( "Import Opera Addressbook..." ) ); +} + +KABC::AddresseeList OperaXXPort::importContacts( const QString& ) const +{ + KABC::AddresseeList addrList; + + QString fileName = KFileDialog::getOpenFileName( QDir::homeDirPath() + QString::fromLatin1( "/.opera/contacts.adr" ) ); + if ( fileName.isEmpty() ) + return addrList; + + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) { + QString msg = i18n( "<qt>Unable to open <b>%1</b> for reading.</qt>" ); + KMessageBox::error( parentWidget(), msg.arg( fileName ) ); + return addrList; + } + + QTextStream stream( &file ); + stream.setEncoding( QTextStream::UnicodeUTF8 ); + QString line, key, value; + bool parseContact = false; + KABC::Addressee addr; + + QRegExp separator( "\x02\x02" ); + + while ( !stream.atEnd() ) { + line = stream.readLine(); + line = line.stripWhiteSpace(); + if ( line == QString::fromLatin1( "#CONTACT" ) ) { + parseContact = true; + addr = KABC::Addressee(); + continue; + } else if ( line.isEmpty() ) { + parseContact = false; + if ( !addr.isEmpty() ) { + addrList.append( addr ); + addr = KABC::Addressee(); + } + continue; + } + + if ( parseContact == true ) { + int sep = line.find( '=' ); + key = line.left( sep ).lower(); + value = line.mid( sep + 1 ); + if ( key == QString::fromLatin1( "name" ) ) + addr.setNameFromString( value ); + else if ( key == QString::fromLatin1( "mail" ) ) { + QStringList emails = QStringList::split( separator, value ); + + QStringList::Iterator it = emails.begin(); + bool preferred = true; + for ( ; it != emails.end(); ++it ) { + addr.insertEmail( *it, preferred ); + preferred = false; + } + } else if ( key == QString::fromLatin1( "phone" ) ) + addr.insertPhoneNumber( KABC::PhoneNumber( value ) ); + else if ( key == QString::fromLatin1( "fax" ) ) + addr.insertPhoneNumber( KABC::PhoneNumber( value, + KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home ) ); + else if ( key == QString::fromLatin1( "postaladdress" ) ) { + KABC::Address address( KABC::Address::Home ); + address.setLabel( value.replace( separator, "\n" ) ); + addr.insertAddress( address ); + } else if ( key == QString::fromLatin1( "description" ) ) + addr.setNote( value.replace( separator, "\n" ) ); + else if ( key == QString::fromLatin1( "url" ) ) + addr.setUrl( KURL( value ) ); + else if ( key == QString::fromLatin1( "pictureurl" ) ) { + KABC::Picture pic( value ); + addr.setPhoto( pic ); + } + } + } + + file.close(); + + return addrList; +} + +#include "opera_xxport.moc" diff --git a/kaddressbook/xxport/opera_xxport.desktop b/kaddressbook/xxport/opera_xxport.desktop new file mode 100644 index 000000000..ddbcff7bf --- /dev/null +++ b/kaddressbook/xxport/opera_xxport.desktop @@ -0,0 +1,103 @@ +[Desktop Entry] +X-KDE-Library=libkaddrbk_opera_xxport +Name=KAB Opera XXPort Plugin +Name[af]=KAB Opera XXPort inprop module +Name[be]=Дапаўненне KAB "Імпарт Opera" +Name[bg]=Приставка за Opera XXPort на KAB +Name[br]=Lugent KAB Opera XXPort +Name[bs]=KAB dodatak za Opera XXPort +Name[ca]=Endollable d'importació/exportació d'Opera per al KAB +Name[cs]=Exportní modul do Opery +Name[cy]=Ategyn XXPort Opera KAB +Name[da]=KAB Opera XXPort-plugin +Name[de]=Opera-XXPort-Modul für Adressbuch +Name[el]=Πρόσθετο εισαγωγής Opera του KAB +Name[es]=Plugin KAB para {im,ex}portar Opera +Name[et]=KAB Opera importplugin +Name[eu]=KAB-en Opera in/esportazio plugin-a +Name[fa]=وصلۀ KAB Opera XXPort +Name[fi]=KAB Opera -liitännäinen +Name[fr]=Module d'import / export Opera pour KAB +Name[gl]=Extensión XXPort para de Opera KAB +Name[he]=תוסף ייבוא/ייצוא עבור Opera של KAB +Name[hi]=केएबी ऑपेरा XXपोर्ट प्लगइन +Name[hu]=KAB Opera XXPort bővítőmodul +Name[is]=Íforrit fyrir KAP Opera XXPort +Name[ja]=KAB Opera インポート/エクスポートプラグイン +Name[ka]=KAB Opera-ს ექსპორტის მოდული +Name[kk]=Opera пішіміне экспорт/импорт ету +Name[km]=កម្មវិធីជំនួយ KAB Opera XXPort +Name[lt]=KAB Opera XXPort priedas +Name[ms]=Plugin KAB Opera XXPort +Name[nb]=KAB-programtillegg for Opera +Name[nds]=Opera-Importmoduul för KAdressbook +Name[ne]=KAB ओपेरा XXPort प्लगइन +Name[nn]=KAB Opera XXPort programtillegg +Name[pl]=Wtyczka KAB do importu z Opery +Name[pt]='Plugin' XXPort para Opera do KAB +Name[pt_BR]=Plug-in de Importação de Opera do KAB +Name[ru]=Обмен информацией с Opera +Name[sk]=KAB modul pre xxport z Opera +Name[sl]=Vstavek KAB Opera XXPort +Name[sr]=XXPort прикључак KAB-а за Opera-у +Name[sr@Latn]=XXPort priključak KAB-a za Opera-u +Name[sv]=AdressbokensOpera-överföringsinsticksprogram +Name[ta]=KAB ஓப்பெரா ஏற்றுமதி சொருகுப்பொருள் +Name[tg]=Мубодилаи иттилоот бо Opera +Name[tr]=KAB Opera XXPort Eklentisi +Name[uk]=Name=Втулок KAB для обміну з Opera +Name[zh_CN]=KAB Opera XXPort 插件 +Name[zh_TW]=KAB Opera XXPort 外掛程式 +Comment=Plugin to import Opera contacts +Comment[af]=Inprop module wat kontakte in Opera formaat invoer +Comment[be]=Дапаўненне для імпарту кантактаў Opera +Comment[bg]=Приставка за импортиране на контактите от Опера +Comment[bs]=Dodatak za uvoz kontakata iz Opere +Comment[ca]=Endollable per a importar contactes des d'Opera +Comment[cs]=Modul pro import a export kontaktů programu Opera +Comment[cy]=Ategyn i fewnforio cysylltau Opera +Comment[da]=Plugin til at importere Opera-kontakter +Comment[de]=Modul zum Import von Opera-Kontakten +Comment[el]=Πρόσθετο για εισαγωγή επαφών του Opera +Comment[es]=Plugin para importar contactos de Opera +Comment[et]=Plugin Opera kontaktide importimiseks +Comment[eu]=Operaren kontaktuak inportatzeko plugin-a +Comment[fa]=وصله برای واردات تماسهای Opera +Comment[fi]=Liitännäinen Operan kontaktien tuomiseen +Comment[fr]=Module d'import de contacts Opera +Comment[fy]=Plugin foar ymportearjen fan Opera's kontaktpersoanen +Comment[gl]=Extensión para importar contactos de Opera +Comment[hi]=ऑपेरा सम्पर्कों को आयात करने का प्लगइन +Comment[hu]=Bővítőmodul Opera névjegyek importálásához +Comment[is]=Íforrit til flytja inn eða út Opera tengiliði +Comment[it]=Plugin per importare contatti da Opera +Comment[ja]=Opera の連絡先をインポートするプラグイン +Comment[ka]=Opera-ს კონტაქტების იმპორტის მოდული +Comment[kk]=Opera контактарын экспорт/импорт ету модулі +Comment[km]=កម្មវិធីជំនួយដើម្បីនាំចូលទំនាក់ទំនងរបស់ Opera +Comment[lt]=Priedas Opera kontaktų importui +Comment[mk]=Приклучок за внесување контакти од Opera +Comment[ms]=Plug masuk untuk import alamat perhubungan Opera +Comment[nb]=Programtillegg for å importere Opera-kontakter +Comment[nds]=Modul för't Importeren vun Opera-Kontakten +Comment[ne]=ओपेरा सम्पर्क आयात गर्न प्लगइन गर्नुहोस् +Comment[nl]=Plugin voor het importeren an Opera's contactpersonen +Comment[nn]=Programtillegg for å imortera Opera-kontaktar +Comment[pl]=Wtyczka do importu wizytówek z Opery +Comment[pt]=Um 'plugin' para importar os contactos do Opera +Comment[pt_BR]=Plug-in para importar contatos do Opera +Comment[ru]=Импорт контактов Opera +Comment[sk]=Plugin pre import kontaktov z Opera +Comment[sl]=Vstavek za uvoz stikov iz Opere +Comment[sr]=Прикључак за увоз Opera контаката +Comment[sr@Latn]=Priključak za uvoz Opera kontakata +Comment[sv]=Insticksprogram för import av Opera-kontakter +Comment[ta]=ஓப்பெரா தொடர்புகளை இறக்குமதி செய்ய சொருகுப்பொருள் +Comment[tg]=Модул барои воридоти алоқаи Opera +Comment[tr]=Opera bağlantılarını alma eklentisi +Comment[uk]=Втулок для імпорту контактів Opera +Comment[zh_CN]=导入 Opera 联系人的插件 +Comment[zh_TW]=匯入 Opera 聯絡人的外掛程式 +Type=Service +ServiceTypes=KAddressBook/XXPort +X-KDE-KAddressBook-XXPortPluginVersion=1 diff --git a/kaddressbook/xxport/opera_xxport.h b/kaddressbook/xxport/opera_xxport.h new file mode 100644 index 000000000..ec4838be1 --- /dev/null +++ b/kaddressbook/xxport/opera_xxport.h @@ -0,0 +1,43 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 - 2003 Daniel Molkentin <[email protected]> + Tobias Koenig <[email protected]> + + 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 OPERA_XXPORT_H +#define OPERA_XXPORT_H + +#include <xxport.h> + +class OperaXXPort : public KAB::XXPort +{ + Q_OBJECT + + public: + OperaXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name = 0 ); + + QString identifier() const { return "opera"; } + + public slots: + KABC::AddresseeList importContacts( const QString &data ) const; +}; + +#endif diff --git a/kaddressbook/xxport/opera_xxportui.rc b/kaddressbook/xxport/opera_xxportui.rc new file mode 100644 index 000000000..84e4e1eb3 --- /dev/null +++ b/kaddressbook/xxport/opera_xxportui.rc @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="opera_xxport" version="2"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Menu name="file_import"><text>&Import</text> + <Action name="file_import_opera"/> + </Menu> + </Menu> +</MenuBar> +</gui> diff --git a/kaddressbook/xxport/pab_mapihd.cpp b/kaddressbook/xxport/pab_mapihd.cpp new file mode 100644 index 000000000..bcf541d75 --- /dev/null +++ b/kaddressbook/xxport/pab_mapihd.cpp @@ -0,0 +1,396 @@ +/*************************************************************************** + mapihd.cpp - description + ------------------- + begin : Tue Jul 25 2000 + copyright : (C) 2000 by Hans Dijkema + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "pab_pablib.h" + +bool operator < (mapitag_t & a,mapitag_t & b) { return a._order<b._order; } +bool operator > (mapitag_t & a,mapitag_t & b) { return a._order>b._order; } +bool operator == (mapitag_t & a,mapitag_t & b) { return a._order==b._order; } + +static word_t +map_givenname[]= + { pr_givenname, + SET_MS_GIVEN_NAME, + 0 + }, +map_email[]= + { pr_email, + SET_MS_EMAIL, + 0 + }, +map_firstname[]= + { pr_firstname, + SET_MS_FIRSTNAME, + 0 + }, +map_lastname[]= + { pr_lastname, + SET_MS_LASTNAME, + 0 + }, +map_additionalname[]= + { pr_additionalname, + SET_MS_MIDDLENAME, + 0 + }, +map_title[]= + { pr_title, + SET_MS_TITLE, + 0 + }, +map_address[]= + { pr_address, + SET_MS_ADDRESS, + 0 + }, +map_zip[]= + { pr_zip, + SET_MS_ZIP, + 0 + }, +map_state[]= + { pr_state, + SET_MS_STATE, + 0 + }, +map_town[]= + { pr_town, + SET_MS_TOWN, + 0 + }, +map_country[]= + { pr_country, + SET_MS_COUNTRY, + 0 + }, +map_tel[]= + { pr_tel, + SET_MS_TEL, + 0 + }, +map_mobile[]= + { pr_mobile, + SET_MS_MOBILE, + 0 + }, +map_fax[]= + { pr_fax, + SET_MS_FAX, + 0 + }, +map_job[]= + { pr_job, + HP_OPENMAIL_JOB, + 0 + }, +map_organization[]= + { pr_organization, + SET_MS_ORGANIZATION, + HP_OPENMAIL_ORGANIZATION, + 0 + }, +map_department[]= + { pr_department, + SET_MS_DEPARTMENT, + HP_OPENMAIL_DEPARTMENT, + 0 + }, +map_subdep[]= + { pr_subdep, + HP_OPENMAIL_SUBDEP, + 0 + }, +map_notes[]= + { pr_notes, + SET_MS_COMMENT, + 0 + }, +map_notused[]= + { pr_notused, + HP_OPENMAIL_LOCATION_OF_WORK, // location of work + SET_NOT_USED, + 0 + }; + + +static word_t *mapi_map[]={ map_givenname, map_email, + map_firstname, map_lastname, map_additionalname,map_title, + map_address, map_town, map_zip, map_state, map_country, + map_tel, map_mobile, map_fax, + map_organization, map_department, map_subdep, map_job, + map_notes, + map_notused, + NULL + }; + +pabrec_entry mapitag_t::matchTag(void) +{ +int i,j; +pabrec_entry e=pr_unknown; + + for(i=0;mapi_map[i]!=NULL && e==pr_unknown;i++) { + for(j=1;mapi_map[i][j]!=0 && _tag!=mapi_map[i][j];j++); + if (mapi_map[i][j]!=0) { + e=(pabrec_entry) mapi_map[i][0]; + } + } +return e; +} + +pabfields_t::pabfields_t(pabrec & R, QWidget * /*parent*/) +{ + // Skip the first two words, because they're always the + // same 000c 0014 ==> 0014 gives us the types, so we + // parse from 0014 till the next offset and order the tags. + + int mb,me; + uint i,k; + content_t _tag,_order; + + mb=R[1]; + me=R[2]; + + while (mb<me) { + _tag=R.read(mb);mb+=sizeof(_tag); + _order=R.read(mb);mb+=sizeof(_order); + + {mapitag_t mt(_tag,_order); + tags[tags.size()]=mt; + context_tags[context_tags.size()]=mt; + } + } + tags.sort(); + + // get the right entries now + + for(i=2,k=0;i<R.N() && k<tags.size();i++,k++) { + if (!isUsed(k)) { i-=1; } + else {pabrec_entry e; + QString E; + + e=isWhat(k); + E=R.getEntry(i); + { QString s=E; + s=s.stripWhiteSpace(); + E=s; + } + + /* + { char m[1024]; + snprintf(m, sizeof(m), "%d %d %04x %08lx %d %s %d %d",i,k,literal(k),order(k),e,E.latin1(),E[0].latin1(),E.length()); + info->addLog(m); + } + */ + + if (!E.isEmpty()) { + + switch (e) { + case pr_givenname: givenName=E; + break; + case pr_email: email=E; + break; + case pr_firstname: firstName=E; + break; + case pr_additionalname: additionalName=E; + break; + case pr_lastname: lastName=E; + break; + case pr_title: title=E; + break; + case pr_address: address=E; + break; + case pr_town: town=E; + break; + case pr_state: state=E; + break; + case pr_zip: zip=E; + break; + case pr_country: country=E; + break; + case pr_organization: organization=E; + break; + case pr_department: department=E; + break; + case pr_subdep: subDep=E; + break; + case pr_job: job=E; + break; + case pr_tel: tel=E; + break; + case pr_fax: fax=E; + break; + case pr_modem: modem=E; + break; + case pr_mobile: mobile=E; + break; + case pr_url: homepage=E; + break; + case pr_talk: talk=E; + break; + case pr_notes: comment=E; + break; + case pr_birthday: birthday=E; + break; + case pr_notused: + break; + default: {/*char m[250]; + snprintf(m,sizeof(m),"unknown tag '%x'",literal(k)); + info->log(m);*/ + } + break; + } + } + } + } + + if (!firstName.isEmpty() && !lastName.isEmpty()) { + givenName=lastName+", "+firstName; + } + + // Determine if the record is ok. + + OK=true; +} + +bool pabfields_t::isUsed(int k) +{ +return tags[k].isUsed(); +} + +pabrec_entry pabfields_t::isWhat(int k) +{ +return tags[k].matchTag(); +} + +word_t pabfields_t::literal(int k) +{ +return tags[k].literal(); +} + +content_t pabfields_t::order(int k) +{ +return tags[k].order(); +} + +KABC::Addressee pabfields_t::get() { + KABC::Addressee a; + if (!givenName.isEmpty()) a.setFormattedName(givenName); + if (!email.isEmpty()) a.insertEmail(email); + if (!title.isEmpty()) a.setTitle(title); + if (!firstName.isEmpty()) a.setName(firstName); + if (!additionalName.isEmpty()) a.setAdditionalName(additionalName); + if (!lastName.isEmpty()) a.setFamilyName(lastName); + + KABC::Address addr; + if (!address.isEmpty()) addr.setStreet(address); + if (!town.isEmpty()) addr.setLocality(town); + if (!zip.isEmpty()) addr.setPostalCode(zip); + if (!state.isEmpty()) addr.setRegion(state); + if (!country.isEmpty()) addr.setCountry(country); + a.insertAddress(addr); + + if (!organization.isEmpty()) a.setOrganization(organization); + if (!department.isEmpty()) a.setRole(department); + // Miss out department, subDep, job + if (!tel.isEmpty()) a.insertPhoneNumber( KABC::PhoneNumber( tel, KABC::PhoneNumber::Voice ) ); + if (!fax.isEmpty()) a.insertPhoneNumber( KABC::PhoneNumber( fax, KABC::PhoneNumber::Fax ) ); + if (!mobile.isEmpty()) a.insertPhoneNumber( KABC::PhoneNumber( mobile, KABC::PhoneNumber::Cell ) ); + if (!modem.isEmpty()) a.insertPhoneNumber( KABC::PhoneNumber( modem, KABC::PhoneNumber::Modem ) ); + if (!homepage.isEmpty()) a.setUrl(KURL( homepage )); + // Miss out talk + if (!comment.isEmpty()) a.setNote(comment); + // Miss out birthday + return a; +} + + + + +/* class pabrec { + private: + char entry[1024]; + byte *_mem; + word_t *_N; + word_t *_w; + public: + pabrec(pab *); // expects record the begin at reading point (ftell). + ~pabrec(); + public: + word_t N(void) { return _N[0]; } + word_t operator[](int i) { return _w[i]; } + const char *getEntry(int i); + public: + content_t read(word_t offset); + }; +*/ + +pabrec::pabrec(pab & P) +{ +adr_t A=P.tell(); +content_t hdr; +word_t offset,size,dummy; +int i; + + hdr=P.go(A); + offset=P.lower(hdr); + + size=offset; + _mem=new byte[size]; + P.read(_mem,size); + + P.go(A+offset); + P.read(m_N); + m_W=new word_t[m_N+1]; + + P.read(dummy); + for(i=0;i<=m_N;i++) { + P.read(m_W[i]); + } +} + +pabrec::~pabrec() +{ + delete _mem; + delete m_W; +} + + +content_t pabrec::read(word_t offset) +{ +content_t R; + R=_mem[offset+3]; + R<<=8;R+=_mem[offset+2]; + R<<=8;R+=_mem[offset+1]; + R<<=8;R+=_mem[offset]; +return R; +} + +const char *pabrec::getEntry(int i) +{ +int mb,me; +int k; + mb=m_W[i];me=m_W[i+1]; + for(k=0;mb!=me;mb++) { + if (_mem[mb]>=' ' || _mem[mb]=='\n' || _mem[mb]==13 || _mem[mb]=='\t') { + if (_mem[mb]==13) { entry[k]='\n'; } + else { entry[k]=_mem[mb]; } + k+=1; + } + } + entry[k]='\0'; +return (const char *) entry; +} diff --git a/kaddressbook/xxport/pab_mapihd.h b/kaddressbook/xxport/pab_mapihd.h new file mode 100644 index 000000000..c4bb58a77 --- /dev/null +++ b/kaddressbook/xxport/pab_mapihd.h @@ -0,0 +1,117 @@ +/*************************************************************************** + mapihd.h - description + ------------------- + begin : Tue Jul 25 2000 + copyright : (C) 2000 by Hans Dijkema + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _MAPIHD_H_ +#define _MAPIHD_H_ + +#include <qmemarray.h> + +#include "pab_xxport.h" + +#define T_MS_ARRAY 0x1100 // Some sort of array +#define T_MS_STRING ((unsigned long) 0x1e) // definitely a string + + typedef unsigned long adr_t; + typedef unsigned long content_t; + typedef unsigned short pabsize_t; + typedef unsigned char byte_t; + typedef unsigned short word_t; + typedef byte_t byte; + + class pab; + + class pabrec { + private: + char entry[1024]; + byte *_mem; + word_t m_N; + word_t *m_W; + public: + pabrec(pab &); // expects record the begin at reading point (ftell). + ~pabrec(); + public: + word_t N(void) { return m_N; } + word_t operator[](int i) { return m_W[i]; } + const char *getEntry(int i); + public: + content_t read(word_t offset); + }; + + typedef enum { + pr_unknown,pr_notused, + pr_givenname,pr_email, + pr_firstname,pr_additionalname,pr_lastname,pr_title, + pr_address,pr_town,pr_state,pr_zip,pr_country, + pr_organization,pr_department,pr_subdep,pr_job, + pr_tel,pr_fax,pr_modem,pr_mobile,pr_url,pr_talk, + pr_notes,pr_birthday + } + pabrec_entry; + + class mapitag_t + { + friend bool operator < (mapitag_t &,mapitag_t &); + friend bool operator > (mapitag_t &,mapitag_t &); + friend bool operator == (mapitag_t &,mapitag_t &); + private: + word_t _tag; + word_t _type; + content_t _order; + public: + mapitag_t(content_t tag,content_t order) { _tag=(word_t) tag;_type=(word_t) (tag>>16);_order=order; } + mapitag_t() { _tag=0;_type=0;_order=0; } + public: + mapitag_t & operator = (mapitag_t & t) { _tag=t._tag;_type=t._type;_order=t._order;return *this; } + public: + bool isUsed(void) { return (_type==T_MS_STRING || (_type&T_MS_ARRAY)!=0) && _order!=0; } + word_t literal(void) { return _tag; } + content_t order(void) { return _order; } + pabrec_entry matchTag(void); + }; + + bool operator < (mapitag_t & a,mapitag_t & b); + bool operator > (mapitag_t & a,mapitag_t & b); + bool operator == (mapitag_t & a,mapitag_t & b); + + class pabfields_t + { + private: + QMemArray<mapitag_t> tags,context_tags; + pabrec *m_R; + QString givenName,email, + title,firstName,additionalName,lastName, + address,town,state,zip,country, + organization,department,subDep,job, + tel,fax,modem,mobile,homepage,talk, + comment,birthday; + bool OK; + private: + bool isUsed(int k); + pabrec_entry isWhat(int k); + word_t literal(int k); + content_t order(int k); + public: + pabfields_t(pabrec & R, QWidget *parent); + public: + KABC::Addressee get( ); + bool isOK(void) { return OK; } + bool isUsable(void) { return givenName!=""; } + }; + + +#endif + diff --git a/kaddressbook/xxport/pab_pablib.cpp b/kaddressbook/xxport/pab_pablib.cpp new file mode 100644 index 000000000..c56c4e9a3 --- /dev/null +++ b/kaddressbook/xxport/pab_pablib.cpp @@ -0,0 +1,333 @@ +/*************************************************************************** + pablib.cxx - description + ------------------- + begin : Tue Jul 4 2000 + copyright : (C) 2000 by Hans Dijkema + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "pab_pablib.h" + +#define REC_OK PAB_REC_OK + + +pab::pab(const char *_pabfile) +{ + pabfile=_pabfile; + in.setName(pabfile); + in.open(IO_ReadOnly); + cap=i18n("Import MS Exchange Personal Address Book (.PAB)"); +} + + +pab::~pab() +{ + if (in.isOpen()) { in.close(); } +} + +////////////////////////////////////////////////////////////////////// +// +// Main conversion +// +////////////////////////////////////////////////////////////////////// + +bool pab::convert(void) +{ +adr_t A; +bool ret; + + if (!in.isOpen()) {QString msg; + msg=i18n("Cannot open %1 for reading").arg(pabfile); + // info->alert(msg); + return false; + } + if (!knownPAB()) { + return false; + } + +/* + if (!f->openAddressBook(info)) { + return false; + } +*/ + + A=go(INDEX_OF_INDEX); + ret=convert(A,0,0); + + // f->closeAddressBook(); + +return ret; +} + +bool pab::convert(adr_t A,content_t ,content_t ) +{ +adr_t table; +content_t start,stop,T; +int n, N = 0; + + go(A); + T=read(); + + // Now we have to decide if this is a distribution list + // or an addressbook container. If it is the last just + // jump directly to dotable(). + + //if (upper(T)==PAB_REC_OK) { + // dotable(A,strt,stp); + // return true; + //} + + // OK, it's not an addressbook container, + // handle it like a distribution list + + start=T; + while(start!=0) { + N+=1; + stop=read(); + table=read(); + start=read(); + } + if (N==0) { N=1; } +/* {char m[100]; + sprintf(m,"%d",N); + info->alert("",m); + }*/ + + //A=go(INDEX_OF_INDEX); + //printf("IoI=%08lx\n",A); + go(A); + start=read(); + n=0; + while(start!=0) {adr_t cp; + stop=read(); + table=read(); + cp=tell(); + dotable(table,start,stop); + //convert(table,start,stop); + go(cp); + start=read(); + n+=1; + // info->setOverall( 100 * n / N ); + } + +return true; +} + + +void pab::dotable(adr_t T,content_t start,content_t stop) +{ +adr_t REC,pREC,cp; +content_t cmp,skip; +int N,n; + + go(T); + cp=tell(); + + REC=0xffffffff; + pREC=0; + cmp=read(); + if (cmp!=start) { + // first try processing as if this was a record. I.e. at the stop thing + processRec(stop); + // Then exit + // info->setCurrent(); + // info->setCurrent(100); + return; + } // This is not a table. + + // info->setCurrent(); + N=0; + while (cmp!=stop && REC!=pREC) { + pREC=REC; + REC=read(); + if (REC!=pREC) { + skip=read(); + cmp=read(); + } + N+=1; + } + + go(cp); + REC=0xffffffff; + pREC=0; + + cmp=read(); + + n=0; + while(cmp!=stop && REC!=pREC) {adr_t cp; + pREC=REC; + REC=read(); + if (REC!=pREC) { + skip=read(); + cp=tell(); + processRec(REC); + go(cp); + cmp=read(); + } + n+=1; + // info->setCurrent(100 * n / N); + } + + // info->setCurrent(); + // info->setCurrent(100); +} + + +void pab::processRec(adr_t REC) +{ +content_t hdr; + + hdr=go(REC); + if (upper(hdr)==REC_OK) { // Now read a record and instantiate! + pabrec rec(*this); + pabfields_t fields(rec, NULL); + + if (fields.isOK() && fields.isUsable()) { + // f->addContact( fields.get() ); + } + } +} + +void pab::prt(unsigned char *,pabrec &,pabrec_entry ) +{ +} + +#define PABREC_N (sizeof(pabrec)/sizeof(word_t)) + +void pab::rdPabRec(pabrec & ) +{ +} + +////////////////////////////////////////////////////////////////////// +// +// Here's where we recognize the record types +// +////////////////////////////////////////////////////////////////////// + +bool pab::recUnknown(pabrec &) +{ +return false; +} + +bool pab::recNoFunction(pabrec & ) +{ +return false; +} + +const char *pab::get(unsigned char *,pabrec_entry ,pabrec & ) +{ +return ""; +} + +void pab::getrange(pabrec & ,pabrec_entry ,word_t & ,word_t & ) +{ +} + +////////////////////////////////////////////////////////////////////// +// +// Here's where we recognize the PAB files +// +////////////////////////////////////////////////////////////////////// + +bool pab::knownPAB(void) +{ +content_t id; + id=go(0); + if (id!=PAB_FILE_ID) {QString msg; + msg=i18n("%1 has no PAB id that I know of, cannot convert this").arg(pabfile); + // info->alert(msg); + return false; + } +return true; +} + + +////////////////////////////////////////////////////////////////////// +// +// Functions to do file reading/positioning +// +////////////////////////////////////////////////////////////////////// + +content_t pab::go(adr_t a) +{ +content_t A; + in.at(a); + A=read(); + in.at(a); +return A; +} + +content_t pab::read(void) +{ +unsigned char mem[4]; +content_t A; + in.readBlock((char *) &mem, sizeof(A)); // WinTel unsigned long opslag + A=mem[3]; + A<<=8;A|=mem[2]; + A<<=8;A|=mem[1]; + A<<=8;A|=mem[0]; +return A; +} + +void pab::read(word_t & w) +{ +unsigned char mem[2]; + in.readBlock((char *) &mem, sizeof(w)); + w=mem[1]; + w<<=8;w|=mem[0]; +} + +content_t pab::relative(int words) +{ +adr_t a; + a=in.at(); +return go(a+(words*sizeof(content_t))); +} + +content_t pab::add(adr_t & A,int words) +{ + A+=(words*sizeof(content_t)); +return go(A); +} + +pabsize_t pab::size(content_t A) +{ +return A&0xFFFF; +} + +word_t pab::lower(content_t A) +{ +return A&0xFFFF; +} + +word_t pab::upper(content_t A) +{ +return A>>16; +} + +void pab::size(content_t A,pabsize_t & s1,pabsize_t & s2) +{ + s1=A&0xFFFF; + s2>>=16; +} + +byte_t pab::readbyte(void) +{ +byte_t c; + c=in.getch(); +return c; +} + +void pab::read(unsigned char *mem,content_t size) +{ + in.readBlock((char *) mem, size); +} diff --git a/kaddressbook/xxport/pab_pablib.h b/kaddressbook/xxport/pab_pablib.h new file mode 100644 index 000000000..ff54a32a2 --- /dev/null +++ b/kaddressbook/xxport/pab_pablib.h @@ -0,0 +1,77 @@ +/*************************************************************************** + pablib.hxx - description + ------------------- + begin : Tue Jul 4 2000 + copyright : (C) 2000 by Hans Dijkema + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + + +#ifndef PAB_LIB_HXX +#define PAB_LIB_HXX + +#include <klocale.h> +#include <qfile.h> + +#include "pab_mapihd.h" + +#define INDEX_OF_INDEX 0x000000c4 +#define PAB_REC_OK 0xbcec +#define PAB_FILE_ID 0x4e444221 + +class pab +{ + friend class pabrec; + + private: + QFile in; + const char *pabfile; + QString cap; + QWidget *parent; + public: + pab(const char *pabFile); + ~pab(); + private: + content_t skip(int longwords) { return relative(longwords); } + content_t go(adr_t); + content_t relative(int longwords); + content_t relative(pabsize_t); + content_t add(adr_t &,int words); + content_t read(void); + void read(unsigned char *mem,content_t size); + void read(word_t &); + pabsize_t size(content_t); + void size(content_t,pabsize_t &, pabsize_t &); + word_t lower(content_t); + word_t upper(content_t); + byte_t readbyte(void); + adr_t curpos(void) { return in.at(); } + adr_t tell(void) { return curpos(); } + private: + bool recUnknown(pabrec & R); + bool recNoFunction(pabrec & R); + const char *get(unsigned char *mem,pabrec_entry e,pabrec & R); + bool knownPAB(void); + private: + void rdPabRec(pabrec & R); + void prt(unsigned char *mem,pabrec & R,pabrec_entry E); + void getrange(pabrec & R,pabrec_entry e,word_t & b,word_t & _e); + private: + bool convert(adr_t A,content_t start,content_t stop); + void dotable(adr_t table,content_t start,content_t stop); + void processRec(adr_t REC); + public: + bool convert(void); +}; + + +#endif diff --git a/kaddressbook/xxport/pab_xxport.cpp b/kaddressbook/xxport/pab_xxport.cpp new file mode 100644 index 000000000..621e5d2c2 --- /dev/null +++ b/kaddressbook/xxport/pab_xxport.cpp @@ -0,0 +1,71 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2000 Hans Dijkema <[email protected]> + Copyright (c) 2003 Helge Deller <[email protected]> + + 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 <qfile.h> + +#include <kdebug.h> +#include <kfiledialog.h> +#include <kio/netaccess.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kurl.h> + +#include "xxportmanager.h" + +#include "pab_xxport.h" + +K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_pab_xxport, PABXXPort ) + +PABXXPort::PABXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) + : KAB::XXPort( ab, parent, name ) +{ + createImportAction( i18n("Import MS Exchange Personal Address Book (.PAB)") ); +} + +KABC::AddresseeList PABXXPort::importContacts( const QString& ) const +{ + KABC::AddresseeList addrList; + + QString fileName = KFileDialog::getOpenFileName( QDir::homeDirPath(), + "*.[pP][aA][bB]|" + i18n("MS Exchange Personal Address Book Files (*.pab)"), 0 ); + if ( fileName.isEmpty() ) + return addrList; + if ( !QFile::exists( fileName ) ) { + KMessageBox::sorry( parentWidget(), i18n( "<qt>Could not find a MS Exchange Personal Address Book <b>%1</b>.</qt>" ).arg( fileName ) ); + return addrList; + } + + // pab PAB(QFile::encodeName(file),this,info); + // info->setFrom(file); + // PAB.convert(); + + return addrList; +} + +#include "pab_xxport.moc" + +// vim: ts=2 sw=2 et diff --git a/kaddressbook/xxport/pab_xxport.desktop b/kaddressbook/xxport/pab_xxport.desktop new file mode 100644 index 000000000..e35ad24d4 --- /dev/null +++ b/kaddressbook/xxport/pab_xxport.desktop @@ -0,0 +1,103 @@ +[Desktop Entry] +X-KDE-Library=libkaddrbk_pab_xxport +Name=KAB MS Exchange Personal Addressbook XXPort Plugin +Name[af]=KAB MS Exchange adresboek XXPort inprop module +Name[be]=Дапаўненне KAB "Імпарт пэрсанальнай адраснай кнігі MS Exchange" +Name[bg]=Приставка за XXPort на MS Exchange на KAB +Name[bs]=KAB dodatak za MS Exchange Personal Addressbook XXPort +Name[ca]=Endollable d'importació/exportació de la llibreta d'adreces personal d'MS Exchange per al KAB +Name[cs]=Exportní modul do adresáře MS Exchange +Name[cy]=Ategyn XXPort Llyfr Cyfeiriadau Personol MS Exchange KAB +Name[da]=KAB MS Exchange personlig adressebog XXPort Plugin +Name[de]=MS-Exchange-Adressbuch-XXPort-Modul +Name[el]=Πρόσθετο εισαγωγής MS Exchange προσωπικού βιβλίου διευθύνσεων του KAB +Name[es]=Plugin de KAB para {im,ex}portar libretas de direcciones personales de MS Exchange +Name[et]=KAB MS Exchange personaalse aadressiraamatu importplugin +Name[eu]=KAB-en MS Exchange Personal helbide-liburu in/esportazio plugin-a +Name[fa]=وصلۀ XXPort کتاب نشانی شخصی مبادلۀ KAB MS +Name[fi]=KAB MS Exchangen henkilökohtaisen osoitekirjan liitännäinen +Name[fr]=Module d'import / export de carnets d'adresses personnels de MS Exchange pour KAB +Name[fy]=KAB MS Exchange Personal Addressbook XXPort-plugin +Name[gl]=Extensión XXPort do Caderno de Enderezos de MS Exchange para KAB +Name[hi]=केएबी एमएस एक्सचेंज निजी पता पुस्तिका XXपोर्ट प्लगइन +Name[hu]=KAB XXPort bővítőmodul MS Exchange személyes címjegyzékekhez +Name[is]=Íforrit fyrir KAB MS Exchange Personal Addressbook XXPort +Name[ja]=KAB MS Exchange パーソナルアドレス帳インポート/エクスポートプラグイン +Name[ka]= MS Exchange-ის პერსონალური წიგნაკის ექსპორტის მოდული +Name[kk]=MS Exchange адрестік кітапшасына экспорт/импорт ету +Name[km]=កម្មវិធីជំនួយ KAB MS Exchange Personal Addressbook XXPort +Name[lt]=KAB MS Exchange asmeninės adresų knygelės XXPort priedas +Name[ms]=Plugin Buku Alamat Peribadi KAB MS Exchange XXPort Plugin +Name[nb]=KAB-programtillegg for import fra MS Exchange +Name[nds]=MSExchange-Importmoduul för KAdressbook +Name[ne]=KAB MS बिनिमय व्यक्तिगत ठेगाना पुस्तिका XXPort प्लगइन +Name[nl]=KAB MS Exchange Personal Addressbook XXPort-plugin +Name[nn]=KAB MS Exchange personleg adressebok XXPort programtillegg +Name[pl]=Wtyczka KAB do importu Osobistej książki adresowej MS Exchange +Name[pt]='Plugin' XXPort do Livro de Endereços Pessoal do MS Exchange para o KAB +Name[pt_BR]=Plug-in do KAB para Im/Exportação de/para Livro de Endereços Pessoal do MS Exchange +Name[ru]=Импорт контактов MS Exchange +Name[sk]=KAB modul pre xxport z osobného adresára MS Exchange +Name[sl]=Vstavek KAB MS Exchange Personal Addressbook XXPort +Name[sr]=XXPort прикључак KAB-а за MS Exchange лични адресар +Name[sr@Latn]=XXPort priključak KAB-a za MS Exchange lični adresar +Name[sv]=Adressbokens överföringsinsticksprogram för MS Exchange personlig adressbok +Name[ta]=KAB MS Exchange Personal Address Books ஏற்றுமதி சொருகுப்பொருள் +Name[tg]=Воридоти алоқаҳои MS Exchange +Name[tr]=KAB MS Exchange Kişisel Adres Defteri XXPort Eklentisi +Name[uk]=Втулок KAB для обміну з персональною адресною книгою MS Exchange +Name[zh_CN]=KAB MS Exchange 个人地址簿 XXPort 插件 +Name[zh_TW]=KAB MS Exchange Personal Addressbook XXPort 外掛程式 +Comment=Plugin to import MS Exchange Personal Address Books +Comment[af]=Inprop module wat kontakte in MS Exchange adresboek formaat invoer +Comment[be]=Дапаўненне для імпарту пэрсанальнай адраснай кнігі MS Exchange +Comment[bg]=Приставка за импортиране на контактите от MS Exchange Personal Address Books +Comment[bs]=Dodatak za uvoz iz MS Exchange personalnog adresara +Comment[ca]=Endollable per a importar des de la llibreta d'adreces personal d'MS Exchange +Comment[cs]=Modul pro import osobní knihy adres MS Exchange +Comment[cy]=Ategyn i fewnforio Llyfrau Cyfeiriadau Personol MS Exchange +Comment[da]=Plugin til at importere MS Exchange personlige adressebøger +Comment[de]=Modul für den Import von persönlichen Adressbüchern aus MS Exchange +Comment[el]=Πρόσθετο για εισαγωγή προσωπικών βιβλίων διευθύνσεων του MS Exchange +Comment[es]=Plugin para importar libretas de direcciones personales de MS Exchange +Comment[et]=Plugin MS Exchange personaalse aadressiraamatu importimiseks +Comment[eu]=MS Exchange Personal helbid-liburuak in/esportatzeko plugina- +Comment[fa]=وصله برای واردات کتابهای نشانی شخصی مبادلۀ MS +Comment[fi]=Liitännäinen MS Exchangen henkilökohtaisten osoitekirjojen tuontiin +Comment[fr]=Module d'import des carnets d'adresses personnels MS Exchange +Comment[fy]=Plugin foar it ymporteajen fan MS Exchange-adresboeken +Comment[gl]=Extensión para importar Cadernos de Enderezos Persoais de MS Exchange +Comment[hi]=एमएस एक्सचेंज निजी पता पुस्तिका को आयात करने का प्लगइन +Comment[hu]=Bővítőmodul MS Exchange személyes címjegyzékek importálásához +Comment[is]=Íforrit til að flytja tengiliði í eða úr MS Exchange Personal Address Book +Comment[it]=Plugin per importare rubriche personali da MS Exchange +Comment[ja]=MS Exchange パーソナルアドレス帳をインポートするプラグイン +Comment[ka]=MS Exchange-ის პერსონალური წიგნაკის იმპორტის მოდული +Comment[kk]=MS Exchange адрестік кітапшасына экспорт/импорт ету модулі +Comment[km]=កម្មវិធីជំនួយដើម្បីនាំចូលសៀវភៅអាសយដ្ឋានផ្ទាល់ខ្លួនរបស់ MS Exchange +Comment[lt]=Priedas leidžiantis importuoti MS Exchange asmenines adresų knygeles +Comment[mk]=Приклучок за внесување лични адресари од MS Exchange +Comment[ms]=Plugin untuk mengimpot Buku Alamat Peribadi MS Exchange +Comment[nb]=Programtillegg for import av personlige adressebøker fra MS Exchange +Comment[nds]=Moduul för't Importeren vun persöönliche Adressböker ut MS Exchange +Comment[ne]=MS बिनिमय व्यक्तिगत ठेगाना पुस्तिका आयात गर्न प्लगइन गर्नुहोस् +Comment[nl]=Plugin voor het importeren van MS Exchange-adresboeken +Comment[nn]=Programtillegg for å imortera MS Exchange personleg adressebok +Comment[pl]=Wtyczka do importu Osobistej książki adresowej z MS Exchange +Comment[pt]=Um 'plugin' para importar os livros de endereços pessoais do MS Exchange +Comment[pt_BR]=Plug-in para importar Livros de Endereços Pessoais do MS Exchange +Comment[ru]=Импорт персональных адресных книг MS Exchange +Comment[sk]=Modul pre import osobných adresárov MS Exchange +Comment[sl]=Vstavek za uvoz osebnih adresarjev MS Exchange +Comment[sr]=Прикључак за увоз MS Exchange личних адресара +Comment[sr@Latn]=Priključak za uvoz MS Exchange ličnih adresara +Comment[sv]=Insticksprogram för import av MS Exchange personliga adressböcker +Comment[ta]=MS Exchange Personal Address Books இறக்குமதி செய்ய சொருகுப்பொருள் +Comment[tg]=Модул барои воридоти китобҳои адреси шахсии MS Exchange +Comment[tr]=MS Exchange Kişisel Adres Defteri aktarım eklentisi +Comment[uk]=Втулок для імпорту персональних адресних книг MS Exchange +Comment[zh_CN]=导入 MS Exchange 个人地址簿的插件 +Comment[zh_TW]=匯入 MS Exchange Personal 通訊錄的外掛程式 +Type=Service +ServiceTypes=KAddressBook/XXPort +X-KDE-KAddressBook-XXPortPluginVersion=1 diff --git a/kaddressbook/xxport/pab_xxport.h b/kaddressbook/xxport/pab_xxport.h new file mode 100644 index 000000000..5c1edb508 --- /dev/null +++ b/kaddressbook/xxport/pab_xxport.h @@ -0,0 +1,217 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2000 - 2000 Hans Dijkema <[email protected]> + 2003 - 2003 Helge Deller <[email protected]> + + 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 PAB_XXPORT_H +#define PAB_XXPORT_H + +#include <xxport.h> + +class PABXXPort : public KAB::XXPort +{ + Q_OBJECT + + public: + PABXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name = 0 ); + + QString identifier() const { return "pab"; } + + public slots: + KABC::AddresseeList importContacts( const QString &data ) const; + + private: + void doExport( QFile *fp, const KABC::AddresseeList &list ); +}; + + + + +///////////////////////////////////////////////////////////////////////////// + +/* + * MS Windows tags as reengineered from an MS Exchange .PAB and + * Outlook .PAB file. + */ + +///////////////////////////////////////////////////////////////////////////// + +#define MS_GIVEN_NAME 0x3a13 +#define MS_GIVEN_NAME_1 0x3a45 +#define MS_GIVEN_NAME_2 0x3a47 +#define MS_GIVEN_NAME_3 0x3a4f +#define MS_GIVEN_NAME_4 0x3001 +#define MS_GIVEN_NAME_5 0x3a20 +#define SET_MS_GIVEN_NAME \ + MS_GIVEN_NAME,MS_GIVEN_NAME_1,MS_GIVEN_NAME_2, \ + MS_GIVEN_NAME_3,MS_GIVEN_NAME_4,MS_GIVEN_NAME_5 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_EMAIL 0x3a56 +#define MS_EMAIL_1 0x3003 +#define SET_MS_EMAIL \ + MS_EMAIL,MS_EMAIL_1 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_FIRSTNAME 0x3a06 +#define SET_MS_FIRSTNAME \ + MS_FIRSTNAME + +///////////////////////////////////////////////////////////////////////////// + +#define MS_LASTNAME 0x3a11 +#define SET_MS_LASTNAME \ + MS_LASTNAME + + +///////////////////////////////////////////////////////////////////////////// + +#define MS_MIDDLENAME 0x3a44 +#define SET_MS_MIDDLENAME \ + MS_MIDDLENAME + +///////////////////////////////////////////////////////////////////////////// + +#define MS_TITLE 0x3a17 +#define SET_MS_TITLE \ + MS_TITLE + +///////////////////////////////////////////////////////////////////////////// + +#define MS_ADDRESS 0x3a15 +#define MS_ADDRESS_1 0x3a29 +#define MS_ADDRESS_2 0x3a59 +#define SET_MS_ADDRESS \ + MS_ADDRESS, MS_ADDRESS_1, MS_ADDRESS_2 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_ZIP 0x3a5b +#define MS_ZIP_1 0x3a2a +#define SET_MS_ZIP \ + MS_ZIP, MS_ZIP_1 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_STATE 0x3a28 +#define MS_STATE_1 0x3a5c +#define SET_MS_STATE \ + MS_STATE, MS_STATE_1 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_TOWN 0x3a27 +#define MS_TOWN_1 0x3a59 +#define SET_MS_TOWN \ + MS_TOWN, MS_TOWN_1 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_COUNTRY 0x3a26 +#define MS_COUNTRY_1 0x3a5a +#define SET_MS_COUNTRY \ + MS_COUNTRY, MS_COUNTRY_1 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_TEL 0x3a08 +#define MS_TEL_1 0x3a09 +#define MS_TEL_2 0x3a1a +#define MS_TEL_3 0x3a1b +#define MS_TEL_4 0x3a1f +#define MS_TEL_5 0x3a1d +#define MS_TEL_6 0x3a2d +#define MS_TEL_7 0x3a2f +#define SET_MS_TEL \ + MS_TEL,MS_TEL_1,MS_TEL_2,MS_TEL_3,MS_TEL_4, \ + MS_TEL_5,MS_TEL_6,MS_TEL_7 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_MOBILE 0x3a1c +#define MS_MOBILE_1 0x3a1e +#define MS_MOBILE_2 0x3a21 +#define SET_MS_MOBILE \ + MS_MOBILE,MS_MOBILE_1,MS_MOBILE_2 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_FAX 0x3a23 +#define MS_FAX_1 0x3a24 +#define MS_FAX_2 0x3a25 +#define MS_FAX_3 0x3a2c +#define SET_MS_FAX \ + MS_FAX,MS_FAX_1,MS_FAX_2,MS_FAX_3 + +///////////////////////////////////////////////////////////////////////////// + +#define MS_ORG 0x3a16 +#define SET_MS_ORGANIZATION \ + MS_ORG + +///////////////////////////////////////////////////////////////////////////// + +#define MS_DEP 0x3a18 +#define SET_MS_DEPARTMENT \ + MS_DEP + +///////////////////////////////////////////////////////////////////////////// + +#define MS_COMMENT 0x3004 +#define SET_MS_COMMENT \ + MS_COMMENT + +///////////////////////////////////////////////////////////////////////////// + +#define SET_NOT_USED \ + 0x3002, \ + 0x300b, \ + 0x3a2e, \ + 0x3a30, \ + 0x3a19 + // 3002 probably address type + // 300b some sort of key + // 3a2e secretary tel number + // 3a30 name of secretary + // 3a19 office location + + + +///////////////////////////////////////////////////////////////////////////// + +/* + * HP Openmail as reengineered from the X.400 .PAB file. + */ + +///////////////////////////////////////////////////////////////////////////// + +#define HP_OPENMAIL_JOB 0x672b +#define HP_OPENMAIL_ORGANIZATION 0x6728 +#define HP_OPENMAIL_DEPARTMENT 0x6729 +#define HP_OPENMAIL_SUBDEP 0x672b +#define HP_OPENMAIL_LOCATION_OF_WORK 0x672a + +///////////////////////////////////////////////////////////////////////////// + +#endif diff --git a/kaddressbook/xxport/pab_xxportui.rc b/kaddressbook/xxport/pab_xxportui.rc new file mode 100644 index 000000000..14117f742 --- /dev/null +++ b/kaddressbook/xxport/pab_xxportui.rc @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="pab_xxport" version="1"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Menu name="file_import"><text>&Import</text> + <Action name="file_import_pab"/> + </Menu> + </Menu> +</MenuBar> +</gui> diff --git a/kaddressbook/xxport/samples/PAB_format.pdf b/kaddressbook/xxport/samples/PAB_format.pdf Binary files differnew file mode 100644 index 000000000..d94e1ac77 --- /dev/null +++ b/kaddressbook/xxport/samples/PAB_format.pdf diff --git a/kaddressbook/xxport/samples/ecdancers.txt b/kaddressbook/xxport/samples/ecdancers.txt new file mode 100644 index 000000000..7358e2bf7 --- /dev/null +++ b/kaddressbook/xxport/samples/ecdancers.txt @@ -0,0 +1,193 @@ +alias "John Collings" [email protected] +note "John Collings" <name:John Collings>Ball '99 +alias "Al Blank" [email protected] +note "Al Blank" <name:Al Blank and Nancy E. DeVore><address:123 Some AvenueSome Town, NY 12345-6789><phone:123 456-7890>Albert Blank & Nancy DeVore123 Some AvenueSome Town, NY 12345 +alias "Alan Wright" [email protected] +note "Alan Wright" <name:Alan Wright>Ball '99 +alias "Ann Margaret McKillop" [email protected] +note "Ann Margaret McKillop" <name:Ann Margaret McKillop> +alias "Anne Leslie" [email protected] +note "Anne Leslie" <name:Anne Leslie> +alias "Anne Lowenthal" [email protected] +note "Anne Lowenthal" <name:Anne Lowenthal> +alias "Annie Eden" [email protected] +note "Annie Eden" <name:Annie Eden> +alias "Aurlie Laurence" [email protected] +note "Aurlie Laurence" <name:Aurelie Laurence>Ball '99 +alias "Barbara Bezdek" [email protected] +note "Barbara Bezdek" <name:Barbara Bezdek> +alias "Barbara Orton" [email protected] +note "Barbara Orton" <name:Barbara Orton> +alias Bec [email protected] +note Bec <name:Bec Hamadock> +alias "Bob Le Mar" [email protected] +note "Bob Le Mar" <name:Robert D. Le Mar>ArtistP.O. Box 12345Some Park, MD 12345123-345-7890 +alias "Carl Andersen" [email protected] +note "Carl Andersen" <name:Carl E. Andersen (CAP, CORP)>Carol Kerr, tooECDers, '99 +alias Carl_F [email protected] +note Carl_F <name:Carl Friedman> +alias "Carolyn Worthing" [email protected] +note "Carolyn Worthing" <name:Carolyn Worthing> +alias "Catherine Langrehr" [email protected] +note "Catherine Langrehr" <name:Catherine Langrehr>ECD Ball 99 +alias "Charlotte Bristow" [email protected] +note "Charlotte Bristow" <name:Charlotte Bristow> +alias "Chloe Maher" [email protected] +note "Chloe Maher" <name:Chloe Maher> +alias "Crystal Paul" [email protected] +note "Crystal Paul" <name:Crystal Paul>ECD Ball '99 +alias "Dan Gillespie" [email protected] +note "Dan Gillespie" <name:Dan Gillespie> +alias "Debra Rolison" [email protected] +note "Debra Rolison" <name:Debra Rolison> +alias "Denis Orton" [email protected] +note "Denis Orton" <name:Denis Orton> +alias "Elizabeth Vermeer" [email protected] +note "Elizabeth Vermeer" <name:Elizabeth Vermeer> +alias "Ellen Blumner" [email protected] +note "Ellen Blumner" <name:Ellen Blumner> +alias "Erica Knicker" [email protected] +note "Erica Knicker" <name:Erica Knicker>Ball '99 +alias "Fred Blonder" [email protected] +note "Fred Blonder" <name:Fred Blonder> +alias "Gabriel Epstein" [email protected] +note "Gabriel Epstein" <name:Gabriel Epstein> +alias "Grigsby Wotton" [email protected] +note "Grigsby Wotton" <name:Grigsby Wotton> +alias "Helen Powell" [email protected] +note "Helen Powell" <name:Spronging> +alias "Henry Szymanski" [email protected] +note "Henry Szymanski" <name:Henry Szymanski> +alias Howard [email protected] +note Howard <name:Howard A. Markham> +alias "Jason Birzer" [email protected] +note "Jason Birzer" <name:Jason W. Birzer> +alias "Jean Murphy" [email protected] +note "Jean Murphy" <name:Jean Murphy>ECD '99 +alias "Jennie Hango" [email protected] +note "Jennie Hango" <name:Jennie Hango> +alias "Jenny Beer" [email protected] +note "Jenny Beer" <name:Jennifer Beer> +alias "Joan Milstead" [email protected] +note "Joan Milstead" <name:Joan M. Milstead>99 Ball +alias "JoAnn Morris" [email protected] +note "JoAnn Morris" <name:JoAnn Morris> +alias "John Montrie" [email protected] +note "John Montrie" <name:John Montrie>Ball '99 +alias Jailbait [email protected], +note Jailbait <name:Richard (Jailbait) Segal> +alias "Judith DeBiase" [email protected] +note "Judith DeBiase" <name:Judith DeBiase> +alias "Kloper - Dave and Julie" [email protected] +note "Kloper - Dave and Julie" <name:Dave and Julie Kloper> +alias "Linda Taggart" [email protected] +note "Linda Taggart" <name:Linda D. Taggart> +alias "Lois Czapiewski" [email protected] +note "Lois Czapiewski" <name:Lois Czapiewski>EDC ball 1999 +alias "Lou Vosteen" [email protected] +note "Lou Vosteen" <name:Lou Vosteen><address:Louis Vosteen1234 Some TreeSome Town VA 12345>ECDer +alias "Maryn McKenna" [email protected]> +note "Maryn McKenna" <name:Maryn McKenna> +alias "Maureen Orton" [email protected] +note "Maureen Orton" <name:Maureen Orton>Maureen and DenisBall 99 +alias "Melissa Weisshaus" [email protected] +note "Melissa Weisshaus" <name:Melissa Weisshaus>Entered MSW program at Bryn Mawr, Fall/Winter 1997. +alias "Naomi Davis" [email protected] +note "Naomi Davis" <name:Naomi Davis>Ball '99 +alias "Pat Ruggiero" [email protected] +note "Pat Ruggiero" <phone:804-589-6264><address:RR #1, Box 12345Some Town, VA 12345><name:Pat Ruggiero> +alias "Pat Ruth" [email protected] +note "Pat Ruth" <name:Pat Ruth> +alias "Paul Ballard" [email protected] +note "Paul Ballard" <name:Paul Ballard> +alias "Ralph Shore" [email protected] +note "Ralph Shore" <name:Ralph Shore>ECD Ball 1999 +alias "Richard Winston" [email protected] +note "Richard Winston" <name:Richard B. Winston>ECD '99 +alias Rudy [email protected] +note Rudy <name:Susan Rudy> +alias "Sam Rotenberg" [email protected] +note "Sam Rotenberg" <name:Sam Rotenberg> +alias "Sandra Linenschmidt" [email protected] +note "Sandra Linenschmidt" <name:Sandi Linenschmidt>Ball '99 +alias "Susan Dudley" [email protected] +note "Susan Dudley" <name:Susan Dudley>Ball Registrant, 1998 +alias "Susie Lorland" [email protected] +note "Susie Lorland" <name:Susie Lorland> +alias "Tanya Rotenberg" [email protected] +note "Tanya Rotenberg" <name:Tanya Rotenberg> +alias "Ted Rudofker" [email protected] +note "Ted Rudofker" <name:Ted Rudofker> +alias "Tenby Ihde" [email protected] +note "Tenby Ihde" <name:Tenby Ihde>New ECDer from VA. +alias "Terry Shehan" [email protected] +note "Terry Shehan" <name:Terry Sheehan> +alias "Tom Anastasio" [email protected] +note "Tom Anastasio" <name:Tom Anastasio> +alias "Vicky Bocock" [email protected] +note "Vicky Bocock" <name:Vicky Bocock> +alias "Wayne Harvey" [email protected] +note "Wayne Harvey" <name:Wayne Harvey> +alias Wexelblatt [email protected] +note Wexelblatt <name:Pat Wexelblatt> +alias Witt [email protected] +note Witt <name:Gretchen & Andrew Witt> +alias "Kim Shaw" [email protected] +note "Kim Shaw" <name:Kim Shaw>Ball '99 on scholarship +alias "JoAnne Rawls" [email protected] +note "JoAnne Rawls" <name:JoAnne Rawls>[email protected] +alias "Susan Murrow" [email protected] +note "Susan Murrow" <name:Susan Murrow> +alias "Carol Oneill" +note "Carol Oneill" <address:12346 Some AveSome Town, PA 12345-1234><name:Carol Oneill> +alias "Valerie Webster" [email protected] +note "Valerie Webster" <address:2 Some CloseSome Town, Some County AB12 3DFEngland><name:Valerie and Ian Webster>Dancer in England +alias "Margherita Davis" [email protected] +note "Margherita Davis" <name:Margherita Davis> +alias Sheryl [email protected] +note Sheryl <name:Sheryl Griffith> +alias "Alice Rose" [email protected] +note "Alice Rose" <name:Alice Rose Adams> +alias "Arlene Ring" [email protected] +note "Arlene Ring" <name:Arlene Ring> +alias "Tom Maher" [email protected] +note "Tom Maher" <name:Tom Maher> +alias "Holly Steussy" [email protected] +note "Holly Steussy" <name:Holly Steussy> +alias "Barbara Harding" [email protected] +note "Barbara Harding" <name:Barbara Harding> +alias "David Millstone" [email protected] +note "David Millstone" <name:David H. Millstone> +alias "Leonard Lu" [email protected] +alias "Al Petty" [email protected] +note "Al Petty" <name:Al Petty> +alias "Bob Farrell" [email protected] +note "Bob Farrell" <name:Bob Farrell> +alias "Deborah Sheldon" [email protected] +note "Deborah Sheldon" <name:Deborah Sheldon> +alias "Diane Friedman" [email protected] +note "Diane Friedman" <name:Diane Friedman> +alias "Peggy Edwards" [email protected] +note "Peggy Edwards" <name:Peggy Edwards> +alias "David Mallinak" [email protected] +note "David Mallinak" <name:David Mallinak> +alias "Kathleen Norvell" [email protected] +note "Kathleen Norvell" <name:Kathleen Norvell> +alias "Linda Wolfe" [email protected] +note "Linda Wolfe" <name:Linda Wolfe> +alias "Theresa Abell" [email protected] +note "Theresa Abell" <name:Theresa Abell> +alias "Karen Grycewicz" [email protected] +note "Karen Grycewicz" <name:Karen Grycewicz> +alias "Kathy Wooldridge" [email protected] +note "Kathy Wooldridge" <name:Kathy Wooldridge> +alias "Paul Koehler" [email protected] +note "Paul Koehler" <name:Paul Koehler> +alias "Lori Fraind" [email protected] +note "Lori Fraind" <name:Lori Fraind> +alias "Tabitha Barr" [email protected] +note "Tabitha Barr" <name:Tabitha Barr> +alias "Gordon Daiger" Gordon Daiger <[email protected]> +note "Gordon Daiger" <name:Gordon Daiger> +alias "Virginia Jenkins" [email protected] +note "Virginia Jenkins" <name:Gina Jenkins> diff --git a/kaddressbook/xxport/samples/netscape.ldif b/kaddressbook/xxport/samples/netscape.ldif new file mode 100644 index 000000000..85f090079 --- /dev/null +++ b/kaddressbook/xxport/samples/netscape.ldif @@ -0,0 +1,38 @@ +dn: cn=John Smith,[email protected] +modifytimestamp: 20030219222547Z +cn: John Smith +xmozillanickname: JS +mail: [email protected] +xmozillausehtmlmail: FALSE +o: Beer +locality: Peckham +givenname: John +sn: Smith +st: London +description:: Tm9uZSByZWFsbHkKQW5vdGhlciBsaW5lIQ== +title: Mr +streetaddress: 1 Some Street +postalcode: ABC 123 +countryname: England +telephonenumber: 020 8888 2232 +homephone: 020 8888 1234 +facsimiletelephonenumber: 020 7777 1234 +xmozillauseconferenceserver: 0 +ou: Brewing +cellphone: 07752 123 456 +homeurl: www.johnsmith.com +xmozillaanyphone: 020 8888 2232 +objectclass: top +objectclass: person + +# this is a comment +dn: cn=KDE,[email protected] +modifytimestamp: 20030219222638Z +cn: KDE +mail: [email protected] +xmozillausehtmlmail: FALSE +givenname: KDE +xmozillauseconferenceserver: 0 +objectclass: top +objectclass: person + diff --git a/kaddressbook/xxport/samples/rfc2849.txt b/kaddressbook/xxport/samples/rfc2849.txt new file mode 100644 index 000000000..040022d86 --- /dev/null +++ b/kaddressbook/xxport/samples/rfc2849.txt @@ -0,0 +1 @@ +http://www.rfc-editor.org/rfc/rfc2849.txt diff --git a/kaddressbook/xxport/vcard_xxport.cpp b/kaddressbook/xxport/vcard_xxport.cpp new file mode 100644 index 000000000..9fb368278 --- /dev/null +++ b/kaddressbook/xxport/vcard_xxport.cpp @@ -0,0 +1,537 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Tobias Koenig <[email protected]> + + 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 <qcheckbox.h> +#include <qfile.h> +#include <qfont.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> + +#include <kabc/vcardconverter.h> +#include <kdialogbase.h> +#include <kfiledialog.h> +#include <kio/netaccess.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <ktempfile.h> +#include <kurl.h> +#include <kapplication.h> +#include <libkdepim/addresseeview.h> + +#include "config.h" // ?? + +#include "gpgmepp/context.h" +#include "gpgmepp/data.h" +#include "gpgmepp/key.h" +#include "qgpgme/dataprovider.h" + +#include "xxportmanager.h" + +#include "vcard_xxport.h" + +K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_vcard_xxport, VCardXXPort ) + +class VCardViewerDialog : public KDialogBase +{ + public: + VCardViewerDialog( const KABC::Addressee::List &list, + QWidget *parent, const char *name = 0 ); + + KABC::Addressee::List contacts() const; + + protected: + void slotUser1(); + void slotUser2(); + void slotApply(); + void slotCancel(); + + private: + void updateView(); + + KPIM::AddresseeView *mView; + + KABC::Addressee::List mContacts; + KABC::Addressee::List::Iterator mIt; +}; + +class VCardExportSelectionDialog : public KDialogBase +{ + public: + VCardExportSelectionDialog( QWidget *parent, const char *name = 0 ); + ~VCardExportSelectionDialog(); + + bool exportPrivateFields() const; + bool exportBusinessFields() const; + bool exportOtherFields() const; + bool exportEncryptionKeys() const; + + private: + QCheckBox *mPrivateBox; + QCheckBox *mBusinessBox; + QCheckBox *mOtherBox; + QCheckBox *mEncryptionKeys; +}; + +VCardXXPort::VCardXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) + : KAB::XXPort( ab, parent, name ) +{ + createImportAction( i18n( "Import vCard..." ) ); + createExportAction( i18n( "Export vCard 2.1..." ), "v21" ); + createExportAction( i18n( "Export vCard 3.0..." ), "v30" ); +} + +bool VCardXXPort::exportContacts( const KABC::AddresseeList &addrList, const QString &data ) +{ + KABC::VCardConverter converter; + KURL url; + KABC::AddresseeList list; + + list = filterContacts( addrList ); + + bool ok = true; + if ( list.isEmpty() ) { + return ok; + } else if ( list.count() == 1 ) { + url = KFileDialog::getSaveURL( list[ 0 ].givenName() + "_" + list[ 0 ].familyName() + ".vcf" ); + if ( url.isEmpty() ) + return true; + + if ( data == "v21" ) + ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v2_1 ) ); + else + ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v3_0 ) ); + } else { + QString msg = i18n( "You have selected a list of contacts, shall they be " + "exported to several files?" ); + + switch ( KMessageBox::questionYesNo( parentWidget(), msg, QString::null, i18n("Export to Several Files"), i18n("Export to One File") ) ) { + case KMessageBox::Yes: { + KURL baseUrl = KFileDialog::getExistingURL(); + if ( baseUrl.isEmpty() ) + return true; + + KABC::AddresseeList::ConstIterator it; + uint counter = 0; + for ( it = list.begin(); it != list.end(); ++it ) { + QString testUrl; + if ( (*it).givenName().isEmpty() && (*it).familyName().isEmpty() ) + testUrl = baseUrl.url() + "/" + (*it).organization(); + else + testUrl = baseUrl.url() + "/" + (*it).givenName() + "_" + (*it).familyName(); + + if ( KIO::NetAccess::exists( testUrl + (counter == 0 ? "" : QString::number( counter )) + ".vcf", false, parentWidget() ) ) { + counter++; + url = testUrl + QString::number( counter ) + ".vcf"; + } else + url = testUrl + ".vcf"; + + bool tmpOk; + KABC::AddresseeList tmpList; + tmpList.append( *it ); + + if ( data == "v21" ) + tmpOk = doExport( url, converter.createVCards( tmpList, KABC::VCardConverter::v2_1 ) ); + else + tmpOk = doExport( url, converter.createVCards( tmpList, KABC::VCardConverter::v3_0 ) ); + + ok = ok && tmpOk; + } + break; + } + case KMessageBox::No: + default: { + url = KFileDialog::getSaveURL( "addressbook.vcf" ); + if ( url.isEmpty() ) + return true; + + if ( data == "v21" ) + ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v2_1 ) ); + else + ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v3_0 ) ); + } + } + } + + return ok; +} + +KABC::AddresseeList VCardXXPort::importContacts( const QString& ) const +{ + QString fileName; + KABC::AddresseeList addrList; + KURL::List urls; + + if ( !XXPortManager::importData.isEmpty() ) + addrList = parseVCard( XXPortManager::importData ); + else { + if ( XXPortManager::importURL.isEmpty() ) + urls = KFileDialog::getOpenURLs( QString::null, "*.vcf|vCards", parentWidget(), + i18n( "Select vCard to Import" ) ); + else + urls.append( XXPortManager::importURL ); + + if ( urls.count() == 0 ) + return addrList; + + QString caption( i18n( "vCard Import Failed" ) ); + bool anyFailures = false; + KURL::List::Iterator it; + for ( it = urls.begin(); it != urls.end(); ++it ) { + if ( KIO::NetAccess::download( *it, fileName, parentWidget() ) ) { + + QFile file( fileName ); + + if ( file.open( IO_ReadOnly ) ) { + QByteArray rawData = file.readAll(); + file.close(); + if ( rawData.size() > 0 ) + addrList += parseVCard( rawData ); + + KIO::NetAccess::removeTempFile( fileName ); + } else { + QString text = i18n( "<qt>When trying to read the vCard, there was an error opening the file '%1': %2</qt>" ); + text = text.arg( (*it).url() ); + text = text.arg( kapp->translate( "QFile", + file.errorString().latin1() ) ); + KMessageBox::error( parentWidget(), text, caption ); + anyFailures = true; + } + } else { + QString text = i18n( "<qt>Unable to access vCard: %1</qt>" ); + text = text.arg( KIO::NetAccess::lastErrorString() ); + KMessageBox::error( parentWidget(), text, caption ); + anyFailures = true; + } + } + + if ( !XXPortManager::importURL.isEmpty() ) { // a vcard was passed via cmd + if ( addrList.isEmpty() ) { + if ( anyFailures && urls.count() > 1 ) + KMessageBox::information( parentWidget(), + i18n( "No contacts were imported, due to errors with the vCards." ) ); + else if ( !anyFailures ) + KMessageBox::information( parentWidget(), i18n( "The vCard does not contain any contacts." ) ); + } else { + VCardViewerDialog dlg( addrList, parentWidget() ); + dlg.exec(); + addrList = dlg.contacts(); + } + } + } + + return addrList; +} + +KABC::AddresseeList VCardXXPort::parseVCard( const QString &data ) const +{ + KABC::VCardConverter converter; + + return converter.parseVCards( data ); +} + +bool VCardXXPort::doExport( const KURL &url, const QString &data ) +{ + KTempFile tmpFile; + tmpFile.setAutoDelete( true ); + + QTextStream stream( tmpFile.file() ); + stream.setEncoding( QTextStream::UnicodeUTF8 ); + + stream << data; + tmpFile.close(); + + return KIO::NetAccess::upload( tmpFile.name(), url, parentWidget() ); +} + +KABC::AddresseeList VCardXXPort::filterContacts( const KABC::AddresseeList &addrList ) +{ + KABC::AddresseeList list; + + if ( addrList.isEmpty() ) + return addrList; + + VCardExportSelectionDialog dlg( parentWidget() ); + if ( !dlg.exec() ) + return list; + + KABC::AddresseeList::ConstIterator it; + for ( it = addrList.begin(); it != addrList.end(); ++it ) { + KABC::Addressee addr; + + addr.setUid( (*it).uid() ); + addr.setFormattedName( (*it).formattedName() ); + addr.setPrefix( (*it).prefix() ); + addr.setGivenName( (*it).givenName() ); + addr.setAdditionalName( (*it).additionalName() ); + addr.setFamilyName( (*it).familyName() ); + addr.setSuffix( (*it).suffix() ); + addr.setNickName( (*it).nickName() ); + addr.setMailer( (*it).mailer() ); + addr.setTimeZone( (*it).timeZone() ); + addr.setGeo( (*it).geo() ); + addr.setProductId( (*it).productId() ); + addr.setSortString( (*it).sortString() ); + addr.setUrl( (*it).url() ); + addr.setSecrecy( (*it).secrecy() ); + addr.setSound( (*it).sound() ); + addr.setEmails( (*it).emails() ); + addr.setCategories( (*it).categories() ); + + if ( dlg.exportPrivateFields() ) { + addr.setBirthday( (*it).birthday() ); + addr.setNote( (*it).note() ); + addr.setPhoto( (*it).photo() ); + } + + if ( dlg.exportBusinessFields() ) { + addr.setTitle( (*it).title() ); + addr.setRole( (*it).role() ); + addr.setOrganization( (*it).organization() ); + + addr.setLogo( (*it).logo() ); + + KABC::PhoneNumber::List phones = (*it).phoneNumbers( KABC::PhoneNumber::Work ); + KABC::PhoneNumber::List::Iterator phoneIt; + for ( phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt ) + addr.insertPhoneNumber( *phoneIt ); + + KABC::Address::List addresses = (*it).addresses( KABC::Address::Work ); + KABC::Address::List::Iterator addrIt; + for ( addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt ) + addr.insertAddress( *addrIt ); + } + + KABC::PhoneNumber::List phones = (*it).phoneNumbers(); + KABC::PhoneNumber::List::Iterator phoneIt; + for ( phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt ) { + int type = (*phoneIt).type(); + + if ( type & KABC::PhoneNumber::Home && dlg.exportPrivateFields() ) + addr.insertPhoneNumber( *phoneIt ); + else if ( type & KABC::PhoneNumber::Work && dlg.exportBusinessFields() ) + addr.insertPhoneNumber( *phoneIt ); + else if ( dlg.exportOtherFields() ) + addr.insertPhoneNumber( *phoneIt ); + } + + KABC::Address::List addresses = (*it).addresses(); + KABC::Address::List::Iterator addrIt; + for ( addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt ) { + int type = (*addrIt).type(); + + if ( type & KABC::Address::Home && dlg.exportPrivateFields() ) + addr.insertAddress( *addrIt ); + else if ( type & KABC::Address::Work && dlg.exportBusinessFields() ) + addr.insertAddress( *addrIt ); + else if ( dlg.exportOtherFields() ) + addr.insertAddress( *addrIt ); + } + + if ( dlg.exportOtherFields() ) + addr.setCustoms( (*it).customs() ); + + if ( dlg.exportEncryptionKeys() ) { + addKey( addr, KABC::Key::PGP ); + addKey( addr, KABC::Key::X509 ); + } + + list.append( addr ); + } + + return list; +} + +void VCardXXPort::addKey( KABC::Addressee &addr, KABC::Key::Types type ) +{ + QString fingerprint = addr.custom( "KADDRESSBOOK", + (type == KABC::Key::PGP ? "OPENPGPFP" : "SMIMEFP") ); + if ( fingerprint.isEmpty() ) + return; + + GpgME::Context * context = GpgME::Context::createForProtocol( GpgME::Context::OpenPGP ); + if ( !context ) { + kdError() << "No context available" << endl; + return; + } + + context->setArmor( false ); + context->setTextMode( false ); + + QGpgME::QByteArrayDataProvider dataProvider; + GpgME::Data dataObj( &dataProvider ); + GpgME::Error error = context->exportPublicKeys( fingerprint.latin1(), dataObj ); + delete context; + + if ( error ) { + kdError() << error.asString() << endl; + return; + } + + KABC::Key key; + key.setType( type ); + key.setBinaryData( dataProvider.data() ); + + addr.insertKey( key ); +} + +// ---------- VCardViewer Dialog ---------------- // + +VCardViewerDialog::VCardViewerDialog( const KABC::Addressee::List &list, + QWidget *parent, const char *name ) + : KDialogBase( Plain, i18n( "Import vCard" ), Yes | No | Apply | Cancel, Yes, + parent, name, true, true, KStdGuiItem::no(), KStdGuiItem::yes() ), + mContacts( list ) +{ + QFrame *page = plainPage(); + QVBoxLayout *layout = new QVBoxLayout( page, marginHint(), spacingHint() ); + + QLabel *label = new QLabel( i18n( "Do you want to import this contact in your address book?" ), page ); + QFont font = label->font(); + font.setBold( true ); + label->setFont( font ); + layout->addWidget( label ); + + mView = new KPIM::AddresseeView( page ); + mView->enableLinks( 0 ); + mView->setVScrollBarMode( QScrollView::Auto ); + layout->addWidget( mView ); + + setButtonText( Apply, i18n( "Import All..." ) ); + + mIt = mContacts.begin(); + + updateView(); +} + +KABC::Addressee::List VCardViewerDialog::contacts() const +{ + return mContacts; +} + +void VCardViewerDialog::updateView() +{ + mView->setAddressee( *mIt ); + + KABC::Addressee::List::Iterator it = mIt; + actionButton( Apply )->setEnabled( (++it) != mContacts.end() ); +} + +void VCardViewerDialog::slotUser1() +{ + mIt = mContacts.remove( mIt ); + + if ( mIt == mContacts.end() ) + slotApply(); + + updateView(); +} + +void VCardViewerDialog::slotUser2() +{ + mIt++; + + if ( mIt == mContacts.end() ) + slotApply(); + + updateView(); +} + +void VCardViewerDialog::slotApply() +{ + QDialog::accept(); +} + +void VCardViewerDialog::slotCancel() +{ + mContacts.clear(); + QDialog::accept(); +} + +// ---------- VCardExportSelection Dialog ---------------- // + +VCardExportSelectionDialog::VCardExportSelectionDialog( QWidget *parent, + const char *name ) + : KDialogBase( Plain, i18n( "Select vCard Fields" ), Ok | Cancel, Ok, + parent, name, true, true ) +{ + QFrame *page = plainPage(); + + QVBoxLayout *layout = new QVBoxLayout( page, marginHint(), spacingHint() ); + + QLabel *label = new QLabel( i18n( "Select the fields which shall be exported in the vCard." ), page ); + layout->addWidget( label ); + + mPrivateBox = new QCheckBox( i18n( "Private fields" ), page ); + layout->addWidget( mPrivateBox ); + + mBusinessBox = new QCheckBox( i18n( "Business fields" ), page ); + layout->addWidget( mBusinessBox ); + + mOtherBox = new QCheckBox( i18n( "Other fields" ), page ); + layout->addWidget( mOtherBox ); + + mEncryptionKeys = new QCheckBox( i18n( "Encryption keys" ), page ); + layout->addWidget( mEncryptionKeys ); + + KConfig config( "kaddressbookrc" ); + config.setGroup( "XXPortVCard" ); + + mPrivateBox->setChecked( config.readBoolEntry( "ExportPrivateFields", true ) ); + mBusinessBox->setChecked( config.readBoolEntry( "ExportBusinessFields", false ) ); + mOtherBox->setChecked( config.readBoolEntry( "ExportOtherFields", false ) ); + mEncryptionKeys->setChecked( config.readBoolEntry( "ExportEncryptionKeys", false ) ); +} + +VCardExportSelectionDialog::~VCardExportSelectionDialog() +{ + KConfig config( "kaddressbookrc" ); + config.setGroup( "XXPortVCard" ); + + config.writeEntry( "ExportPrivateFields", mPrivateBox->isChecked() ); + config.writeEntry( "ExportBusinessFields", mBusinessBox->isChecked() ); + config.writeEntry( "ExportOtherFields", mOtherBox->isChecked() ); + config.writeEntry( "ExportEncryptionKeys", mEncryptionKeys->isChecked() ); +} + +bool VCardExportSelectionDialog::exportPrivateFields() const +{ + return mPrivateBox->isChecked(); +} + +bool VCardExportSelectionDialog::exportBusinessFields() const +{ + return mBusinessBox->isChecked(); +} + +bool VCardExportSelectionDialog::exportOtherFields() const +{ + return mOtherBox->isChecked(); +} + +bool VCardExportSelectionDialog::exportEncryptionKeys() const +{ + return mEncryptionKeys->isChecked(); +} + +#include "vcard_xxport.moc" diff --git a/kaddressbook/xxport/vcard_xxport.desktop b/kaddressbook/xxport/vcard_xxport.desktop new file mode 100644 index 000000000..d0a0146a2 --- /dev/null +++ b/kaddressbook/xxport/vcard_xxport.desktop @@ -0,0 +1,105 @@ +[Desktop Entry] +X-KDE-Library=libkaddrbk_vcard_xxport +Name=KAB vCard XXPort Plugin +Name[af]=KAB vCard XXPort inprop module +Name[be]=Дапаўненне KAB "Імпарт/Экспарт vCard" +Name[bg]=Приставка за vCard XXPort на KAB +Name[br]=Lugent KAB vCard XXPort +Name[bs]=KAB dodatak za vCard XXPort +Name[ca]=Endollable d'importació/exportació vCard per al KAB +Name[cs]=Exportní modul vCard +Name[cy]=Ategyn XXPort vCard KAB +Name[da]=KAB vCard XXPort-plugin +Name[de]=vCard-XXPort-Modul für Adressbuch +Name[el]=Πρόσθετο εισαγωγής/εξαγωγής vCard του KAB +Name[es]=Plugin KAB para {im,ex}portar vCard +Name[et]=KAB vCardi eksport/importplugin +Name[eu]=KAB-en vCard in/esportazio plugin-a +Name[fa]=وصلۀ KAB vCard XXPort +Name[fi]=KAB vCard liitännäinen +Name[fr]=Module d'import / export vCard pour KAB +Name[fy]=KAB vCard XXPort-plugin +Name[gl]=Extensión XXPort de vCard para KAB +Name[he]=תוסף ייבוא/ייצוא עבור vCard של KAB +Name[hi]=केएबी वी-कार्डXXपोर्ट प्लगइन +Name[hu]=KAB vCard XXPort bővítőmodul +Name[is]=Íforrit fyrir KAB vCard XXPort +Name[ja]=KAB vCazrd インポート/エクスポートプラグイン +Name[ka]=KAB vCard ექსპორტის მოდული +Name[kk]=vCard-ты экспорт/импорт ету +Name[km]=កម្មវិធីជំនួយ KAB vCard XXPort +Name[lt]=KAB vCard XXPort priedas +Name[ms]=Plugin KAB vCard XXPort +Name[nb]=KAB-programtillegg for vCard +Name[nds]=vCard-Im-/Exportmoduul för KAdressbook +Name[ne]=KAB भी कार्ड XXPort प्लगइन +Name[nl]=KAB vCard XXPort-plugin +Name[nn]=KAB vCard XXPort programtillegg +Name[pl]=Wtyczka KAB do importu/eksportu z/do formatu vCard +Name[pt]='Plugin' XXPort para vCard do KAB +Name[pt_BR]=Plug-in de Im/Exportação de vCard do KAB +Name[ru]=Работа с vCard +Name[sk]=KAB modul pre xxport z vCard +Name[sl]=Vstavek KAB vCard XXPort +Name[sr]=XXPort прикључак KAB-а за vCard +Name[sr@Latn]=XXPort priključak KAB-a za vCard +Name[sv]=Adressbokens vCard-överföringsinsticksprogram +Name[ta]=kab vஅட்டைxxபோர்ட் சொருகுப்பொருள் +Name[tg]=Кор бо vCard +Name[tr]=KAB vCard XXPort Eklentisi +Name[uk]=Втулок KAB для обміну через vCard +Name[zh_CN]=KAB vCard XXPort 插件 +Name[zh_TW]=KAB vCard XXPort 外掛程式 +Comment=Plugin to import and export contacts in vCard format +Comment[af]=Inprop module wat kontakte in vCard formaat invoer en uitvoer +Comment[be]=Дапаўненне для імпарту і экспарту кантактаў у фармаце vCard +Comment[bg]=Приставка за експортиране/импортиране на контактите във формат на vCard +Comment[bs]=Dodatak za uvoz i izvoz kontakata u vCard formatu +Comment[ca]=Endollable per a importar i exportar contactes en el format vCard +Comment[cs]=Modul pro import a export kontaktů ve formátu vCard +Comment[cy]=Ategyn i fewnforio ac allforio cysylltau yn fformat vCard +Comment[da]=Plugin til at importere og eksportere kontakter i vCard-format +Comment[de]=Modul für Import/Export von Kontakten im vCard-Format +Comment[el]=Πρόσθετο για εισαγωγή και εξαγωγή επαφών μορφής vCard +Comment[es]=Plugin para importar y exportar contactos en formato vCard +Comment[et]=Plugin kontaktide importimiseks ja eksportimiseks vCardi vormingus +Comment[eu]=vCard formatuko kontaktuak in/esportatzeko plugin-a +Comment[fa]=وصله برای واردات و صادرات تماسها در قالب vCard +Comment[fi]=Liitännäinen vCard-muodossa olevien kontaktien tuontiin ja vientiin +Comment[fr]=Module d'import / export de contacts au format vCard +Comment[fy]=Plugin foar it ymportearjen fan kontaktpersoanen yn vCard-formaat +Comment[gl]=Plugin para importar e exportar contactos en formato vCard +Comment[hi]=सम्पर्कों को वी-कार्ड फार्मेट में आयात और निर्यात करने का प्लगइन +Comment[hu]=Bővítőmodul vCard névjegyek importálásához/exportálásához +Comment[is]=Íforrit til að flytja inn eða út tengiliði í vCard sniði +Comment[it]=Plugin per importare ed esportare contatti in formato vCard +Comment[ja]=vCard フォーマットで連絡先をインポート/エクスポートするプラグイン +Comment[ka]=კონტაქტების vCard-ის ფორმატით იმპორტ/ექსპორტის მოდული +Comment[kk]=vCard пішіміне экспорт/импорт ету модулі +Comment[km]=កម្មវិធីជំនួយដើម្បីនាំចូល និងនាំចេញទំនាក់ទំនងក្នុងទ្រង់ទ្រាយជា vCard +Comment[lt]=Įskiepis kontaktų importavimui ir eksportavimui vCard formatu +Comment[mk]=Приклучок за внесување и изнесување контакти во vCard-формат +Comment[ms]=Plugin untuk mengimpot dan mengekspot orang hubungan dalam format vCard +Comment[nb]=Programtillegg for import og eksport av kontakter i vCard-format +Comment[nds]=Moduul för't Im-/Exporteren vun Kontakten in't vCard-Formaat +Comment[ne]=भी कार्ड ढाँचामा आयात र निर्यात गर्न प्लगइन गर्नुहोस् +Comment[nl]=Plugin voor het importeren en exporteren van contactpersonen in vCard-formaat +Comment[nn]=Programtillegg for å importera og eksportera kontaktar i vCard-format +Comment[pl]=Wtyczka do importu i eksportu wizytówek w formacie vCard +Comment[pt]=Um 'plugin' para importar e exportar os contactos no formato vCard +Comment[pt_BR]=Plug-in para importar e exportar contatos no formato vCard +Comment[ru]=Импорта и экспорт контактов в формате vCard +Comment[sk]=Plugin pre import a export kontaktov v vCard formáte +Comment[sl]=Vstavek za uvoz in izvoz stikov v obliki vCard +Comment[sr]=Прикључак за увоз и извоз контаката у vCard формат +Comment[sr@Latn]=Priključak za uvoz i izvoz kontakata u vCard format +Comment[sv]=Insticksprogram för import och export av kontakter med vCard-format +Comment[ta]=ஏற்றுமதி மற்றும் இறக்குமதி தொடர்புகளை vஅட்டை வடிவமைப்பில் செலுத்த சொருகுப்பொருள் +Comment[tg]=Модул барои воридот ва содироти алоқот ба формати vCard +Comment[tr]=vCard biçimi bağlantıları alma ve gönderme eklentisi +Comment[uk]=Втулок для імпорту та експорту контактів у форматі vCard +Comment[zh_CN]=导入和导出 vCard 格式联系人的插件 +Comment[zh_TW]=匯入與匯出 vCard 格式聯絡人的外掛程式 +Type=Service +ServiceTypes=KAddressBook/XXPort +X-KDE-KAddressBook-XXPortPluginVersion=1 diff --git a/kaddressbook/xxport/vcard_xxport.h b/kaddressbook/xxport/vcard_xxport.h new file mode 100644 index 000000000..d67aaeffe --- /dev/null +++ b/kaddressbook/xxport/vcard_xxport.h @@ -0,0 +1,50 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 Tobias Koenig <[email protected]> + + 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 VCARD_XXPORT_H +#define VCARD_XXPORT_H + +#include <xxport.h> + +class VCardXXPort : public KAB::XXPort +{ + Q_OBJECT + + public: + VCardXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name = 0 ); + + QString identifier() const { return "vcard"; } + + public slots: + bool exportContacts( const KABC::AddresseeList &list, const QString &data ); + KABC::AddresseeList importContacts( const QString &data ) const; + + private: + KABC::AddresseeList parseVCard( const QString &data ) const; + bool doExport( const KURL &url, const QString &data ); + void addKey( KABC::Addressee &addr, KABC::Key::Types type ); + + KABC::AddresseeList filterContacts( const KABC::AddresseeList& ); +}; + +#endif diff --git a/kaddressbook/xxport/vcard_xxportui.rc b/kaddressbook/xxport/vcard_xxportui.rc new file mode 100644 index 000000000..2c748af87 --- /dev/null +++ b/kaddressbook/xxport/vcard_xxportui.rc @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="vcard_xxport" version="1"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Menu name="file_import"><text>&Import</text> + <Action name="file_import_vcard"/> + </Menu> + <Menu name="file_export"><text>&Export</text> + <Action name="file_export_vcard_v21"/> + <Action name="file_export_vcard_v30"/> + </Menu> + </Menu> +</MenuBar> +</gui> |