summaryrefslogtreecommitdiffstats
path: root/kmobile/devices/gnokii
diff options
context:
space:
mode:
Diffstat (limited to 'kmobile/devices/gnokii')
-rw-r--r--kmobile/devices/gnokii/Makefile.am11
-rw-r--r--kmobile/devices/gnokii/configure.in.in2
-rw-r--r--kmobile/devices/gnokii/gnokii_mobile.cpp878
-rw-r--r--kmobile/devices/gnokii/gnokii_mobile.h93
-rw-r--r--kmobile/devices/gnokii/gnokiiconfig.cpp98
-rw-r--r--kmobile/devices/gnokii/gnokiiconfig.h41
-rw-r--r--kmobile/devices/gnokii/gnokiiconfigui.ui273
-rw-r--r--kmobile/devices/gnokii/libkmobile_gnokii.desktop109
8 files changed, 1505 insertions, 0 deletions
diff --git a/kmobile/devices/gnokii/Makefile.am b/kmobile/devices/gnokii/Makefile.am
new file mode 100644
index 000000000..c9ec8642c
--- /dev/null
+++ b/kmobile/devices/gnokii/Makefile.am
@@ -0,0 +1,11 @@
+INCLUDES = -I$(top_srcdir)/kmobile -I$(top_srcdir) $(all_includes)
+
+METASOURCES = AUTO
+
+kde_module_LTLIBRARIES = libkmobile_gnokii.la
+
+kde_services_DATA = libkmobile_gnokii.desktop
+
+libkmobile_gnokii_la_SOURCES = gnokii_mobile.cpp gnokiiconfigui.ui gnokiiconfig.cpp
+libkmobile_gnokii_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) $(KDE_RPATH) -no-undefined -module
+libkmobile_gnokii_la_LIBADD = ../../libkmobiledevice.la ../../../libkcal/libkcal.la $(XPMLIB) $(LIB_GNOKII)
diff --git a/kmobile/devices/gnokii/configure.in.in b/kmobile/devices/gnokii/configure.in.in
new file mode 100644
index 000000000..150191bf6
--- /dev/null
+++ b/kmobile/devices/gnokii/configure.in.in
@@ -0,0 +1,2 @@
+# $Id$
+AM_CONDITIONAL(include_gnokii_device, test -n "$LIB_GNOKII")
diff --git a/kmobile/devices/gnokii/gnokii_mobile.cpp b/kmobile/devices/gnokii/gnokii_mobile.cpp
new file mode 100644
index 000000000..871442847
--- /dev/null
+++ b/kmobile/devices/gnokii/gnokii_mobile.cpp
@@ -0,0 +1,878 @@
+/* This file is part of the KDE mobile library.
+ Copyright (C) 2003-2005 Helge Deller <deller@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qdir.h>
+
+#include <klibloader.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <kio/global.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <gnokii.h>
+
+#include "gnokii_mobile.h"
+#include "gnokiiconfig.h"
+
+
+#define KGNOKII_DEBUG_AREA 5730
+#define PRINT_DEBUG kdDebug(KGNOKII_DEBUG_AREA) << "KMobileGnokii: "
+#define GNOKII_DEBUG(x) PRINT_DEBUG << x
+
+
+#define APP "KMobileGnokii"
+#define GNOKII_CHECK_ERROR(error) \
+ do { \
+ if (error) \
+ PRINT_DEBUG << QString("ERROR %1: %2\n").arg(error).arg(gn_error_print(error));\
+ } while (0)
+
+
+/* This is a loaded library, which is initialized with the line below */
+K_EXPORT_COMPONENT_FACTORY( libkmobile_gnokii, KMobileGnokii() )
+
+/* createObject needs to be reimplemented by every KMobileDevice driver */
+QObject *KMobileGnokii::createObject( QObject *parent, const char *name,
+ const char *, const QStringList &args )
+{
+ return new KMobileGnokii( parent, name, args );
+}
+
+
+static char *BinDir;
+static char *lockfile = NULL;
+static char model[GN_MODEL_MAX_LENGTH+1], revision[GN_REVISION_MAX_LENGTH+1], imei[GN_IMEI_MAX_LENGTH+1];
+static QString PhoneProductId;
+
+static gn_statemachine state;
+static gn_data data;
+static gn_calnote_list calnote_list;
+
+
+/**
+ * The KDE gnokii mobile device driver.
+ */
+
+KMobileGnokii::KMobileGnokii(QObject *obj, const char *name, const QStringList &args )
+ : KMobileDevice(obj, name, args)
+{
+ // set initial device info
+ setClassType( Phone );
+ m_deviceName = i18n("Mobile Phone accessed via GNOKII");
+ m_deviceRevision = "";
+ m_connectionName = "/dev/ircomm0";
+ setCapabilities( hasAddressBook | hasNotes );
+
+ m_numAddresses = -1;
+
+ // now initialize the configuration based on the
+ // given config file from args[0]
+ loadDeviceConfiguration();
+ if (m_modelnr.isEmpty())
+ loadGnokiiConfiguration();
+
+ if (m_modelnr.isEmpty()) {
+ // default communcation values
+ m_modelnr = "6310";
+ m_connection = "infrared";
+ m_port = "/dev/ircomm0";
+ m_baud = "9600";
+ }
+
+ PRINT_DEBUG << QString("Using GNOKII configuration: %1 %2 %3 %4\n").arg(m_modelnr)
+ .arg(m_connection).arg(m_port).arg(m_baud);
+
+ saveDeviceConfiguration();
+ saveGnokiiConfiguration();
+}
+
+KMobileGnokii::~KMobileGnokii()
+{
+}
+
+
+/******************************************************************************************
+ * GNOKII lowlevel interface
+ ******************************************************************************************/
+
+static gn_connection_type connectionToValue( QString connectionName )
+{
+ if (connectionName == "serial")
+ return GN_CT_Serial;
+ if (connectionName == "dau9p")
+ return GN_CT_DAU9P;
+ if (connectionName == "dlr3p")
+ return GN_CT_DLR3P;
+ if (connectionName == "infrared")
+ return GN_CT_Infrared;
+ if (connectionName == "m2bus")
+ return GN_CT_M2BUS;
+ if (connectionName == "irda")
+ return GN_CT_Irda;
+ if (connectionName == "bluetooth")
+ return GN_CT_Bluetooth;
+//#ifndef WIN32
+ if (connectionName == "tcp")
+ return GN_CT_TCP;
+//#endif
+ if (connectionName == "tekram")
+ return GN_CT_Tekram;
+ return GN_CT_Serial; /* default */
+}
+
+bool KMobileGnokii::setGnokiiStateMachine()
+{
+ // set the state machine to our configuration
+ qstrncpy( state.config.model, m_modelnr.utf8(), sizeof(state.config.model)-1 );
+ qstrncpy( state.config.port_device, m_port.utf8(), sizeof(state.config.port_device)-1 );
+ state.config.connection_type = connectionToValue(m_connection);
+ state.config.serial_baudrate = m_baud.toUInt();
+ return true;
+}
+
+bool KMobileGnokii::saveConfig( KConfig &conf, QString group )
+{
+ conf.setGroup(group);
+ conf.writeEntry("model", m_modelnr );
+ conf.writeEntry("port", m_port );
+ conf.writeEntry("connection", m_connection );
+// conf.writeEntry("initlength", "default" );
+ conf.writeEntry("serial_baudrate", m_baud );
+// conf.writeEntry("serial_write_usleep", "0" );
+// conf.writeEntry("handshake", "" ); // software (or:rtscts), hardware (or:xonxoff)
+ conf.writeEntry("require_dcd", "1" );
+// conf.writeEntry("smsc_timeout", "1" );
+ conf.sync();
+ return true;
+}
+
+bool KMobileGnokii::loadConfig( KConfig &conf, QString group )
+{
+ conf.setGroup(group);
+ m_modelnr = conf.readEntry("model", m_modelnr );
+ m_port = conf.readEntry("port", m_port );
+ m_connection = conf.readEntry("connection", m_connection );
+ m_baud = conf.readEntry("serial_baudrate", m_baud );
+ return true;
+}
+
+bool KMobileGnokii::saveGnokiiConfiguration()
+{
+ KConfig conf( QDir::homeDirPath() + "/.gnokiirc", false, false, "" );
+ return saveConfig( conf, "global" );
+}
+
+bool KMobileGnokii::loadGnokiiConfiguration()
+{
+ KConfig conf( QDir::homeDirPath() + "/.gnokiirc", true, false, "" );
+ return loadConfig( conf, "global" );
+}
+
+bool KMobileGnokii::saveDeviceConfiguration()
+{
+ return saveConfig( *config(), "global" );
+}
+
+bool KMobileGnokii::loadDeviceConfiguration()
+{
+ return loadConfig( *config(), "global" );
+}
+
+
+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;
+
+ if (gn_cfg_read(&BinDir)<0 || !gn_cfg_phone_load("", &state))
+ return i18n("GNOKII isn't yet configured.");
+
+ 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("Lock file error.\n "
+ "Please exit all other running instances of gnokii 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("Mobile phone interface initialization failed:\n%1").arg(gn_error_print(error));
+ }
+
+ // model
+ gn_data_clear(&data);
+ data.model = model;
+ model[0] = 0;
+ error = gn_sm_functions(GN_OP_GetModel, &data, &state);
+ GNOKII_CHECK_ERROR(error);
+ if (model[0] == 0)
+ strcpy(model, i18n("unknown").utf8());
+ data.model = NULL;
+
+ // revision
+ data.revision = revision;
+ revision[0] = 0;
+ error = gn_sm_functions(GN_OP_GetRevision, &data, &state);
+ GNOKII_CHECK_ERROR(error);
+ data.revision = NULL;
+
+ // imei
+ data.imei = imei;
+ imei[0] = 0;
+ error = gn_sm_functions(GN_OP_GetImei, &data, &state);
+ GNOKII_CHECK_ERROR(error);
+ data.imei = NULL;
+
+ GNOKII_DEBUG( QString("Found mobile phone: Model: %1, Revision: %2, IMEI: %3\n")
+ .arg(model).arg(revision).arg(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( 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( int index, 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;
+}
+
+#if 0
+static bool phone_entry_empty( int index, gn_memory_type memtype )
+{
+ gn_phonebook_entry entry;
+ gn_error error;
+ error = read_phone_entry( index, memtype, &entry );
+ if (error == GN_ERR_EMPTYLOCATION)
+ return true;
+ if (error == GN_ERR_NONE && entry.empty)
+ return true;
+ return false;
+}
+#endif
+
+static int gn_error2kio_error( gn_error err )
+{
+ if (err != GN_ERR_NONE)
+ GNOKII_CHECK_ERROR(err);
+
+ switch (err) {
+ case GN_ERR_NONE:
+ return 0;
+ case GN_ERR_INVALIDMEMORYTYPE:
+ case GN_ERR_INVALIDLOCATION:
+ case GN_ERR_EMPTYLOCATION:
+ return KIO::ERR_DOES_NOT_EXIST;
+ case GN_ERR_MEMORYFULL:
+ return KIO::ERR_OUT_OF_MEMORY;
+ case GN_ERR_NOLINK:
+ return KIO::ERR_COULD_NOT_CONNECT;
+ case GN_ERR_TIMEOUT:
+ return KIO::ERR_SERVER_TIMEOUT;
+ case GN_ERR_ENTRYTOOLONG:
+ case GN_ERR_WRONGDATAFORMAT:
+ case GN_ERR_INVALIDSIZE:
+ return KIO::ERR_COULD_NOT_WRITE;
+ default:
+ return KIO::ERR_INTERNAL;
+ }
+}
+
+static gn_error read_phone_entry_highlevel( int index, const gn_memory_type memtype, KABC::Addressee *a )
+{
+ gn_phonebook_entry entry;
+ QStringList addrlist;
+ QString s, country;
+ KABC::Address *addr;
+ gn_error error;
+
+// if (index > (memstat.used + memstat.free))
+// return GN_ERR_INVALIDLOCATION;
+
+ error = read_phone_entry( index, memtype, &entry );
+ if (error != GN_ERR_NONE)
+ return error;
+
+ GNOKII_DEBUG(QString("%1: %2, num=%3, location=%4, group=%5, count=%6\n").arg(index).arg(entry.name)
+ .arg(entry.number).arg(entry.location).arg(entry.caller_group).arg(entry.subentries_count));
+
+ // try to split Name into FamilyName and GivenName
+ s = QString(entry.name).simplifyWhiteSpace();
+ a->setFormattedName(s);
+ if (s.find(',')!=-1) {
+ addrlist = QStringList::split(',', s);
+ if (addrlist.count()==2) {
+ a->setFamilyName(addrlist[0].simplifyWhiteSpace());
+ a->setGivenName(addrlist[1].simplifyWhiteSpace());
+ } else
+ a->setGivenName(s);
+ } else {
+ addrlist = QStringList::split(' ', s);
+ if (addrlist.count()==2) {
+ a->setFamilyName(addrlist[1].simplifyWhiteSpace());
+ a->setGivenName(addrlist[0].simplifyWhiteSpace());
+ } else
+ a->setGivenName(s);
+ }
+
+ a->insertCustom(APP, "X_GSM_CALLERGROUP", s.setNum(entry.caller_group));
+ a->insertCustom(APP, "X_GSM_STORE_AT", QString("%1_%2").arg(GN_MT_ME).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 = QString(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);
+ switch (addrlist.count()) {
+ case 4: addr->setStreet(addrlist[0].simplifyWhiteSpace());
+ addr->setLocality(addrlist[1].simplifyWhiteSpace());
+ addr->setPostalCode(addrlist[2].simplifyWhiteSpace());
+ country = addrlist[3].simplifyWhiteSpace();
+ if (!country.isEmpty())
+ addr->setCountry(i18n(country.utf8()));
+ break;
+ case 3: addr->setLocality(addrlist[0].simplifyWhiteSpace());
+ addr->setPostalCode(addrlist[1].simplifyWhiteSpace());
+ country = addrlist[2].simplifyWhiteSpace();
+ if (!country.isEmpty())
+ addr->setCountry(i18n(country.utf8()));
+ break;
+ default: addr->setStreet(s.simplifyWhiteSpace());
+ }
+ 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()
+ } // for(subentry)
+
+ GNOKII_CHECK_ERROR(error);
+ return error;
+}
+
+/******************************************************************************************
+ *
+ ******************************************************************************************/
+
+
+
+// connect the device and ask user to turn device on (if necessary)
+bool KMobileGnokii::connectDevice(QWidget * /*parent*/)
+{
+ if (connected())
+ return true;
+
+ QString err = businit();
+ m_connected = err.isEmpty();
+ PRINT_DEBUG << QString("connectDevice() : %1\n").arg(m_connected ? "Ok" : err);
+ return m_connected;
+}
+
+// disconnect the device and return true, if sucessful
+bool KMobileGnokii::disconnectDevice(QWidget * /*parent*/)
+{
+ if (!connected())
+ return true;
+ busterminate();
+ m_connected = false;
+ PRINT_DEBUG << QString("disconnectDevice() : %1\n").arg("done");
+ return true;
+}
+
+// provice the own configuration dialog
+bool KMobileGnokii::configDialog(QWidget *parent)
+{
+ QString model, connection, port, baud;
+ int ok = 0;
+ GnokiiConfig *dialog = new GnokiiConfig(parent);
+ if (dialog) {
+ dialog->setValues(m_modelnr, m_connection, m_port, m_baud);
+ ok = dialog->exec();
+ }
+ dialog->getValues(model, connection, port, baud);
+ delete dialog;
+ if (ok == QDialog::Accepted) {
+ m_modelnr = model;
+ m_connection = connection;
+ m_port = port;
+ m_baud = baud;
+ saveDeviceConfiguration();
+ };
+ return true;
+}
+
+QString KMobileGnokii::iconFileName() const
+{
+ return "mobile_phone";
+}
+
+// return a unique ID, e.g. the IMEI number of phones, or a serial number
+// this String is used to have a unique identification for syncronisation.
+QString KMobileGnokii::deviceUniqueID()
+{
+ return QString("GNOKII-IMEI-%1").arg(QString::fromLocal8Bit(imei));
+}
+
+
+
+/**********************************************************************************
+ * Addressbook / Phonebook support *
+ **********************************************************************************/
+
+int KMobileGnokii::numAddresses()
+{
+ if (!connectDevice(NULL))
+ return 0;
+
+ gn_memory_status memstat;
+ gn_error error;
+
+ if (m_numAddresses>=0)
+ return m_numAddresses;
+
+ error = read_phone_memstat( GN_MT_ME, &memstat );
+ GNOKII_CHECK_ERROR(error);
+ if (error)
+ memstat.used = -1;
+
+ m_numAddresses = memstat.used;
+
+ if (m_numAddresses>0) {
+ // initialize the addrList array
+ m_addrList.clear();
+ KABC::Addressee addr;
+ for (int i=0; i<=m_numAddresses; i++)
+ m_addrList.append(addr);
+ }
+
+ return m_numAddresses;
+}
+
+int KMobileGnokii::readAddress( int index, KABC::Addressee &addr )
+{
+ PRINT_DEBUG << QString("############ GET ADDRESS #%1\n").arg(index);
+ // index is zero-based, but in gnokii the first address starts at 1
+ if (index<0 || index>=numAddresses())
+ return KIO::ERR_DOES_NOT_EXIST;
+
+ // now get our addressbook entry
+
+ // do we have this entry in the cache already ?
+ if (m_addrList.count() > (unsigned)index && !m_addrList[index].isEmpty()) {
+ addr = m_addrList[index];
+ return 0;
+ }
+
+ gn_error err = read_phone_entry_highlevel(index+1, GN_MT_ME, &addr );
+ if (!err)
+ m_addrList[index] = addr;
+
+ return gn_error2kio_error(err);
+}
+
+int KMobileGnokii::storeAddress( int, const KABC::Addressee &, bool )
+{
+ /* XXX: this is a read-only device */
+ return KIO::ERR_WRITE_ACCESS_DENIED;
+}
+
+
+
+/**********************************************************************************
+ * Calendar support *
+ **********************************************************************************/
+
+static void QDateTime_2_timestamp( const QDateTime &qdt, gn_timestamp &ts )
+{
+ ts.year = qdt.date().year();
+ ts.month = qdt.date().month();
+ ts.day = qdt.date().day();
+ ts.hour = qdt.time().hour();
+ ts.minute = qdt.time().minute();
+ ts.second = qdt.time().second();
+ ts.timezone = 0;
+}
+
+static QDateTime timestamp_2_QDateTime( const gn_timestamp &ts )
+{
+ return QDateTime( QDate(ts.year, ts.month, ts.day),
+ QTime(ts.hour, ts.minute, ts.second) );
+}
+
+static void print_calnote( const gn_calnote &entry )
+{
+ gn_timestamp ts = entry.time;
+ kdWarning() << "location=" << entry.location /* The number of the note in the phone memory */
+ << " type=" << entry.type /* The type of the note */
+ << " gn_timestamp=" << /* The time of the note */
+ " year=" << ts.year <<
+ " month=" << ts.month <<
+ " day=" << ts.day <<
+ " hour=" << ts.hour <<
+ " minute=" << ts.minute <<
+ " second=" << ts.second <<
+ " TZ=" << ts.timezone
+ << " gn_calnote_alarm="<< entry.alarm.enabled /* The alarm of the note */
+ << " text=" << entry.text /* The text of the note */
+ << " number=" << entry.phone_number /* For Call only: the phone number */
+ << " recurr=" << entry.recurrence << endl << endl;
+}
+
+
+
+
+int KMobileGnokii::numCalendarEntries()
+{
+ gn_data_clear(&data);
+ gn_calnote entry;
+
+ memset(&entry, 0, sizeof(entry));
+ data.calnote = &entry;
+ entry.location = 1;
+ data.calnote_list = &calnote_list;
+
+ gn_error error = gn_sm_functions(GN_OP_GetCalendarNote, &data, &state);
+ switch (error) {
+ case GN_ERR_NONE:
+ case GN_ERR_INVALIDLOCATION:
+ case GN_ERR_EMPTYLOCATION:
+ return calnote_list.number;
+ default:
+ GNOKII_CHECK_ERROR(error);
+ return 0;
+ }
+}
+
+int KMobileGnokii::readCalendarEntry( int index, KCal::Event &event )
+{
+ if (index < 0 || index >= GN_CALNOTE_MAX_NUMBER)
+ return KIO::ERR_DOES_NOT_EXIST;
+
+ gn_data_clear(&data);
+ gn_calnote entry;
+
+ memset(&entry, 0, sizeof(entry));
+ entry.location = index+1;
+ data.calnote = &entry;
+ data.calnote_list = &calnote_list;
+
+ gn_error error = gn_sm_functions(GN_OP_GetCalendarNote, &data, &state);
+ GNOKII_CHECK_ERROR(error);
+ if (error != GN_ERR_NONE)
+ return gn_error2kio_error(error);
+
+ print_calnote( entry );
+
+ QDateTime dt_start = timestamp_2_QDateTime(entry.time);
+ QDateTime dt_end = dt_start.addSecs( 60*60 ); // XXX: assume one hour
+ event.setDtStart( dt_start );
+ event.setDtEnd( dt_end );
+ event.setSummary( QString::fromUtf8(entry.text) );
+
+ // type:
+ switch (entry.type) {
+ case GN_CALNOTE_MEETING:
+ event.setCategories(i18n("MEETING"));
+ break;
+ case GN_CALNOTE_CALL:
+ event.setCategories(i18n("PHONE CALL"));
+ event.setDescription(QString::fromUtf8(entry.phone_number));
+ break;
+ case GN_CALNOTE_BIRTHDAY:
+ event.setCategories(i18n("BIRTHDAY"));
+ break;
+ case GN_CALNOTE_REMINDER:
+ event.setCategories(i18n("REMINDER"));
+ break;
+ default:
+ kdWarning() << "unknown calendar GN_CALNOTE_XXXX type #" << entry.type << endl;
+ }
+
+ // alarm:
+ if (entry.alarm.enabled) {
+ QDateTime at = timestamp_2_QDateTime(entry.alarm.timestamp);
+ if (at.isValid() && dt_start.isValid()) {
+ int seconds = abs(at.secsTo(dt_start));
+ seconds %= 60*60*24; /* max. 1 day in advance... */
+ KCal::Alarm *eventalarm = event.newAlarm();
+ eventalarm->setStartOffset(KCal::Duration(seconds));
+ }
+ }
+
+ // recurrence:
+ switch (entry.recurrence) {
+ case GN_CALNOTE_NEVER:
+ break;
+ case GN_CALNOTE_DAILY:
+ event.recurrence()->setDaily(1,-1);
+ break;
+ case GN_CALNOTE_WEEKLY:
+ case GN_CALNOTE_2WEEKLY:
+ event.recurrence()->setDaily( 7 + (entry.recurrence==GN_CALNOTE_2WEEKLY ? 7:0) , -1);
+ break;
+ case GN_CALNOTE_MONTHLY:
+ event.recurrence()->setMonthly(KCal::Recurrence::rMonthlyPos, 1, -1);
+ break;
+ case GN_CALNOTE_YEARLY:
+ event.recurrence()->setYearly(KCal::Recurrence::rYearlyPos, 1, -1);
+ break;
+ default: // hourly
+ event.recurrence()->setHourly(entry.recurrence, -1);
+ break;
+ }
+
+ return 0;
+}
+
+int KMobileGnokii::storeCalendarEntry( int index, const KCal::Event &event )
+{
+ if (index < 0 || index >= GN_CALNOTE_MAX_NUMBER)
+ return KIO::ERR_DOES_NOT_EXIST;
+
+ gn_error error;
+ gn_calnote entry;
+
+ gn_data_clear(&data);
+ memset(&entry, 0, sizeof(entry));
+ entry.location = index+1;
+ data.calnote = &entry;
+ data.calnote_list = &calnote_list;
+
+ // read first
+ error = gn_sm_functions(GN_OP_GetCalendarNote, &data, &state);
+ // GNOKII_CHECK_ERROR(error);
+
+ QDateTime_2_timestamp( event.dtStart(), entry.time );
+ strncpy(entry.text, event.summary().utf8(), sizeof(entry.text)-1);
+
+ // type:
+ entry.type = GN_CALNOTE_MEETING;
+ if (event.categories().findIndex(i18n("MEETING")) != -1) {
+ entry.type = GN_CALNOTE_MEETING;
+ } else if (event.categories().findIndex(i18n("PHONE CALL")) != -1) {
+ entry.type = GN_CALNOTE_CALL;
+ strncpy(entry.phone_number, event.description().utf8(), sizeof(entry.phone_number)-1);
+ } else if (event.categories().findIndex(i18n("BIRTHDAY")) != -1) {
+ entry.type = GN_CALNOTE_BIRTHDAY;
+ } else { // assume i18n("REMINDER")
+ entry.type = GN_CALNOTE_REMINDER;
+ }
+
+ // alarm:
+ entry.alarm.enabled = 0;
+ if (event.isAlarmEnabled()) {
+ const KCal::Alarm *eventalarm = *event.alarms().at(0);
+ if (eventalarm) {
+ if (eventalarm->hasTime()) {
+
+ QDateTime_2_timestamp( eventalarm->time(), entry.alarm.timestamp );
+ } else
+ if (eventalarm->hasStartOffset()) {
+ QDateTime dt = event.dtStart();
+ dt = dt.addSecs(-eventalarm->startOffset().asSeconds());
+ QDateTime_2_timestamp( dt, entry.alarm.timestamp );
+ }
+ }
+ }
+
+ // recurrence:
+ switch (event.recurrence()->recurrenceType()) {
+ case KCal::Recurrence::rNone:
+ default:
+ entry.recurrence = GN_CALNOTE_NEVER;
+ break;
+ case KCal::Recurrence::rHourly:
+ entry.recurrence = (gn_calnote_recurrence) (event.recurrence()->frequency());
+ break;
+ case KCal::Recurrence::rDaily:
+ entry.recurrence = GN_CALNOTE_DAILY;
+ break;
+ case KCal::Recurrence::rWeekly:
+ entry.recurrence = (gn_calnote_recurrence) (GN_CALNOTE_WEEKLY * event.recurrence()->frequency());
+ break;
+ case KCal::Recurrence::rMonthlyPos:
+ case KCal::Recurrence::rMonthlyDay:
+ entry.recurrence = GN_CALNOTE_MONTHLY;
+ break;
+ case KCal::Recurrence::rYearlyMonth:
+ case KCal::Recurrence::rYearlyDay:
+ case KCal::Recurrence::rYearlyPos:
+ entry.recurrence = GN_CALNOTE_YEARLY;
+ break;
+ }
+
+ print_calnote( entry );
+
+return 0; // XXX
+
+ error = gn_sm_functions(GN_OP_WriteCalendarNote, &data, &state);
+ GNOKII_CHECK_ERROR(error);
+
+ return 0;
+}
+
+
+/**********************************************************************************
+ * Notes support *
+ **********************************************************************************/
+
+int KMobileGnokii::numNotes()
+{
+ return 100; /* we simulate one address */
+}
+
+int KMobileGnokii::readNote( int index, QString &note )
+{
+ // index is zero-based, and we only have one simulated note
+ if (index<0 || index>=numNotes())
+ return KIO::ERR_DOES_NOT_EXIST;
+
+ note = QString("NOTE #%1\n"
+ "--------\n"
+ "This is a sample note #%2\n\n"
+ "DeviceClassName: %3\n"
+ "Device Driver : %4\n"
+ "Device Revision: %5\n")
+ .arg(index).arg(index)
+ .arg(deviceClassName()).arg(deviceName()).arg(revision());
+ return 0;
+}
+
+#include "gnokii_mobile.moc"
diff --git a/kmobile/devices/gnokii/gnokii_mobile.h b/kmobile/devices/gnokii/gnokii_mobile.h
new file mode 100644
index 000000000..fdc61e30e
--- /dev/null
+++ b/kmobile/devices/gnokii/gnokii_mobile.h
@@ -0,0 +1,93 @@
+/*
+ This file is part of libkmobile.
+ Copyright (c) 2003 - 2003 Helge Deller <deller@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef LIBKMOBILE_GNOKII_H
+#define LIBKMOBILE_GNOKII_H
+
+#include <kmobiledevice.h>
+#include <kabc/addressee.h>
+
+class KMobileGnokii : public KMobileDevice
+{
+Q_OBJECT
+public:
+ KMobileGnokii( QObject *obj=0, const char *name=0, const QStringList &args=QStringList() );
+ ~KMobileGnokii();
+
+ // createObject needs to be reimplemented by every KMobileDevice driver
+ QObject *createObject( QObject *parent=0, const char *name=0,
+ const char *classname="QObject", const QStringList &args=QStringList() );
+
+ // connect, disconnect and current status
+ bool connectDevice(QWidget *parent);
+ bool disconnectDevice(QWidget *parent);
+
+ // provide a device-specific configure dialog
+ bool configDialog(QWidget *parent);
+
+ // filename and path to gnokii-icon
+ QString iconFileName() const;
+
+ QString deviceUniqueID();
+
+ /*
+ * Addressbook / Phonebook support
+ */
+ int numAddresses();
+ int readAddress( int index, KABC::Addressee &adr );
+ int storeAddress( int index, const KABC::Addressee &adr, bool append = false );
+
+ /*
+ * Calendar support
+ */
+ int numCalendarEntries();
+ int readCalendarEntry( int index, KCal::Event &entry );
+ int storeCalendarEntry( int index, const KCal::Event &entry );
+
+ /*
+ * Notes support
+ */
+ int numNotes();
+ int readNote( int index, QString &note );
+
+signals:
+ void connectionChanged( bool connected );
+ void message( int msgLevel, const QString &msg );
+
+protected:
+ bool setGnokiiStateMachine();
+ bool saveConfig( KConfig &conf, QString group );
+ bool loadConfig( KConfig &conf, QString group );
+ bool saveGnokiiConfiguration();
+ bool loadGnokiiConfiguration();
+ bool saveDeviceConfiguration();
+ bool loadDeviceConfiguration();
+
+private:
+ QString m_modelnr, m_connection, m_port, m_baud;
+
+ int m_numAddresses;
+ KABC::Addressee::List m_addrList;
+};
+
+#endif
diff --git a/kmobile/devices/gnokii/gnokiiconfig.cpp b/kmobile/devices/gnokii/gnokiiconfig.cpp
new file mode 100644
index 000000000..780dc23ce
--- /dev/null
+++ b/kmobile/devices/gnokii/gnokiiconfig.cpp
@@ -0,0 +1,98 @@
+/* This file is part of the KDE mobile library.
+ Copyright (C) 2003 Helge Deller <deller@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ 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 <qstring.h>
+#include <qstringlist.h>
+#include <qlabel.h>
+#include <qwidget.h>
+#include <qcombobox.h>
+
+#include "gnokiiconfigui.h"
+#include "gnokiiconfig.h"
+
+#define MODELS "AT 1611 2110i 2148i 2711 2731 3110 3210 3310 3330 3360 3410 3810 " \
+ "5100 5110 5120 5130 5160 5190 540 550 6110 6120 6130 6150 616x " \
+ "6185 6190 6210 6230 6250 6310 6310i 6360 640 650 6510 6610 7110 7190 " \
+ "7650 8110 8210 8250 8290 8310 8810 9110 9210 RPM-1"
+
+#define CONNECTIONS "serial infrared irda dau9p dlr3p m2bus bluetooth tekram tcp"
+
+#if defined(__linux__) || defined(__linux)
+#define AVAILABLE_PORTS "/dev/ttyS0 /dev/ttyS1 /dev/ttyS2 /dev/ttyS3 " \
+ "/dev/ircomm0 /dev/ircomm1 /dev/irda /dev/rfcomm0 /dev/rfcomm1"
+#else
+#define AVAILABLE_PORTS "/dev/ttyS0"
+#endif
+
+#define BAUDRATES "57600 38400 19200 14400 9600 4800 2400"
+
+
+GnokiiConfig::GnokiiConfig( QWidget* parent, const char* name, bool modal, WFlags fl )
+ : GnokiiConfigUI(parent, name, modal, fl)
+{
+ QStringList list = QStringList::split(" ", MODELS);
+ cb_Model->insertStringList(list);
+
+ list = QStringList::split(" ", CONNECTIONS);
+ cb_Connection->insertStringList(list);
+
+ list = QStringList::split(" ", AVAILABLE_PORTS);
+ cb_Port->insertStringList(list);
+
+ list = QStringList::split(" ", BAUDRATES);
+ cb_Baud->insertStringList(list);
+}
+
+GnokiiConfig::~GnokiiConfig()
+{
+}
+
+void GnokiiConfig::setValues(const QString &model, const QString &connection, const QString &port, const QString &baud)
+{
+ cb_Model->setCurrentText(model);
+ cb_Connection->setCurrentText(connection);
+ cb_Port->setCurrentText(port);
+ cb_Baud->setCurrentText(baud);
+
+ slotCheckValues();
+
+ connect( cb_Connection, SIGNAL(textChanged(const QString &)), this, SLOT(slotCheckValues(const QString &)) );
+}
+
+void GnokiiConfig::getValues(QString &model, QString &connection, QString &port, QString &baud) const
+{
+ model = cb_Model->currentText();
+ connection = cb_Connection->currentText();
+ port = cb_Port->currentText();
+ baud = cb_Baud->currentText();
+}
+
+void GnokiiConfig::slotCheckValues(const QString &txt)
+{
+ bool disable_serial = (QString("infrared irda").find(txt,0,false)>=0);
+ textLabelBaudRate->setDisabled(disable_serial);
+ cb_Baud->setDisabled(disable_serial);
+}
+
+void GnokiiConfig::slotCheckValues()
+{
+ slotCheckValues(cb_Connection->currentText());
+}
+
+#include "gnokiiconfig.moc"
diff --git a/kmobile/devices/gnokii/gnokiiconfig.h b/kmobile/devices/gnokii/gnokiiconfig.h
new file mode 100644
index 000000000..662386010
--- /dev/null
+++ b/kmobile/devices/gnokii/gnokiiconfig.h
@@ -0,0 +1,41 @@
+/* This file is part of the KDE mobile library.
+ Copyright (C) 2004 Helge Deller <deller@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ 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 GNOKIICONFIG_H
+#define GNOKIICONFIG_H
+
+#include <qobject.h>
+
+#include <gnokiiconfigui.h>
+
+class GnokiiConfig : public GnokiiConfigUI
+{
+Q_OBJECT
+public:
+ GnokiiConfig( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
+ ~GnokiiConfig();
+
+ void setValues(const QString &model, const QString &connection, const QString &port, const QString &baud);
+ void getValues(QString &model, QString &connection, QString &port, QString &baud) const;
+
+private slots:
+ void slotCheckValues();
+ void slotCheckValues(const QString &);
+};
+
+#endif
diff --git a/kmobile/devices/gnokii/gnokiiconfigui.ui b/kmobile/devices/gnokii/gnokiiconfigui.ui
new file mode 100644
index 000000000..5b2893a3a
--- /dev/null
+++ b/kmobile/devices/gnokii/gnokiiconfigui.ui
@@ -0,0 +1,273 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>GnokiiConfigUI</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>GnokiiConfigUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>471</width>
+ <height>308</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Configure Gnokii Mobile Device</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonHelp</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Help</string>
+ </property>
+ <property name="accel">
+ <string>F1</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonOk</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QFrame" row="0" column="0">
+ <property name="name">
+ <cstring>frame7</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Please configure your Gnokii mobile device</string>
+ </property>
+ </widget>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>140</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QFrame" row="1" column="0">
+ <property name="name">
+ <cstring>frame8</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QComboBox" row="3" column="1">
+ <property name="name">
+ <cstring>cb_Baud</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>cb_Connection</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>4</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="2" column="1">
+ <property name="name">
+ <cstring>cb_Port</cstring>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="1">
+ <property name="name">
+ <cstring>cb_Model</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>41</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Connection:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Phone model:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabelBaudRate</cstring>
+ </property>
+ <property name="text">
+ <string>Baudrate:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>GnokiiConfigUI</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>GnokiiConfigUI</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kmobile/devices/gnokii/libkmobile_gnokii.desktop b/kmobile/devices/gnokii/libkmobile_gnokii.desktop
new file mode 100644
index 000000000..6479e480a
--- /dev/null
+++ b/kmobile/devices/gnokii/libkmobile_gnokii.desktop
@@ -0,0 +1,109 @@
+[Desktop Entry]
+Name=Mobile Phone or Organizer (gnokii)
+Name[af]=Selfoon of Digitale Dagboek (gnokii)
+Name[ar]=الهاتف النقّال أو المنظم (gnokii)
+Name[be]=Мабільны тэлефон ці арганізатар (gnokii)
+Name[bg]=Мобилни телефони или организатори (gnokii)
+Name[bs]=Mobilni telefon ili organizer (gnokii)
+Name[ca]=Telèfon mòbil o organitzador (gnokii)
+Name[cs]=Mobilní telefon nebo Organizér (gnokii)
+Name[cy]=Ffôn Symudol neu Drefnydd (gnokii)
+Name[da]=Mobiltelefon eller organisator (gnokii)
+Name[de]=Mobiltelefon oder Organizer (gnokii)
+Name[el]=Κινητό τηλέφωνο ή Organizer (gnokii)
+Name[en_GB]=Mobile Phone or Organiser (gnokii)
+Name[es]=Teléfono móvil u organizador (gnokii)
+Name[et]=Mobiiltelefon või Organizer (gnokii)
+Name[eu]=Mugikorra edo antolatzailea (gnokii)
+Name[fa]=تلفن همراه یا سازمان‌دهنده (gnokii)
+Name[fi]=Matkapuhelin tai organisoija (gnokii)
+Name[fr]=Téléphone portable ou organiseur (gnokii)
+Name[fy]=Mobile tillefoan of Organizer (gnokii)
+Name[ga]=Fón Póca nó Eagraí (gnokii)
+Name[gl]=Teléfono móbil ou organizador (gnokii)
+Name[he]=טלפון נייד או אירגונית (gnokii)
+Name[hi]=मोबाइल फोन या आर्गेनाइज़र (ग्नोकी)
+Name[hu]=Mobiltelefon/határidőnapló-kezelő (Gnokii)
+Name[is]=Farsími eða lófatölva (gnokii)
+Name[it]=Telefono cellulare o organizer (gnokii)
+Name[ja]=携帯電話またはスケジュール管理 (gnokii)
+Name[ka]=მობილური ტელეფონი ან ორგანიზატორი(gnokii)
+Name[kk]=Қалта телефон не Ұйымдастырғыш (gnokii)
+Name[km]=កម្មវិធី​រៀបចំ​ទូរស័ព្ទ​ចល័ត (gnokii)
+Name[lt]=Mobilus telefonas ar asmeninės info tvarkyklė (gnokii)
+Name[ms]=Telefon Bimbit atau Penyusun (gnokii)
+Name[nb]=Mobiltelefon eller PDA (gnokii)
+Name[nds]=Mobiltelefoon oder Handreekner (gnokii)
+Name[ne]=मोबाइल फोन वा आयोजक (जिनोकी)
+Name[nl]=Mobiele telefoon of Organizer (gnokii)
+Name[nn]=Mobiltelefon eller organisator (gnokii)
+Name[pl]=Telefon komórkowy lub organizer (gnokii)
+Name[pt]=Organizador ou Telemóvel (Gnokii)
+Name[pt_BR]=Telefone Móvel ou Organizador (gnokii)
+Name[ru]=Мобильный телефон или органайзер (gnokii)
+Name[sk]=Mobil alebo organizér (gnokii)
+Name[sl]=Prenosni telefon ali organizator (gnokii)
+Name[sr]=Мобилни телефон или организатор (gnokii)
+Name[sr@Latn]=Mobilni telefon ili organizator (gnokii)
+Name[sv]=Mobilenhet (gnokii)
+Name[ta]=செல்பேசி அல்லது ஒருங்கிணைப்பாளர்(gnokii)
+Name[tg]=Телефони мобилӣ ё органайзери (gnokii)
+Name[tr]=Cep Telefonu ya da Organizer (gnokii)
+Name[uk]=Мобільний телефон та тижневик (gnokii)
+Name[uz]=Uyali telefon yoki organayzer (gnokii)
+Name[uz@cyrillic]=Уяли телефон ёки органайзер (gnokii)
+Name[zh_CN]=移动电话或 PDA(gnokii)
+Name[zh_TW]=行動電話或數位助理(gnokii)
+Comment=This driver supports many NOKIA and other mobile phones via the gnokii library
+Comment[af]=Hierdie drywer ondersteun baie Nokia en ander selfone d.m.v. die gnokii biblioteek
+Comment[bg]=Драйвер за поддръжка на мобилни телефони, предимно Нокиа, чрез библиотеката gnokii
+Comment[bs]=Ovaj drajver podržava mnoge NOKIA i druge mobilne telefone putem gnokii biblioteke
+Comment[ca]=Aquest controlador accepta molts NOKIA i d'altres telèfons mòbils mitjançant la biblioteca «gnokii»
+Comment[cs]=Tento ovladač podporuje mnoho mobilních telefonů NOKIA a dalších pomocí knihovny gnokii
+Comment[cy]=Cynhala'r gyrrydd yma lawer o ffoniau NOKIA a ffoniau symudol eraill drwy'r rhaglengell gnokii
+Comment[da]=Denne driver understøtter mange NOKIA og andre mobiltelefoner via gnokii-biblioteket
+Comment[de]=Ein Treiber, der zahlreiche NOKIA- und sonstige Mobiltelefone über die gnokii-Bibliothek unterstützt
+Comment[el]=Αυτός ο οδηγός υποστηρίζει πολλά NOKIA και άλλα κινητά τηλέφωνα μέσω της βιβλιοθήκης gnokii
+Comment[es]=Este manejador admite muchos teléfonos móviles NOKIA y de otras marcas vía la biblioteca gnokii
+Comment[et]=See draiver toetab gnokii teegi vahendusel paljusid Nokia ja teisi mobiiltelefone
+Comment[eu]=Kontrolatzaile honek NOKIA eta beste mugikor asko onartzen ditu gnokii liburutegiaren bidez
+Comment[fa]=این گرداننده، اغلب تلفنهای همراه نوکیا و غیره را از طریق کتابخانۀ gnokii پشتیبانی می‌کند
+Comment[fi]=Tämä ajuri tukee monia Nokian ja muita matkapuhelimia gnokii-kirjaston kautta
+Comment[fr]=Ce pilote prend en charge beaucoup de téléphones portables Nokia et autres à l'aide de la bibliothèque gnokii
+Comment[fy]=Dit stjoerprogramma jout stipe foar in soad Nokia- en oare mobile tilefoans fia de gnokii-bibliotheek
+Comment[ga]=Tacaíonn an tiománaí seo le neart fóin NOKIA agus cinn eile, tríd an leabharlann gnokii
+Comment[gl]=Este controlador soporta moitos móbiles Nokia e outros mediante a libraría gnokii
+Comment[hi]=यह ड्राइवर बहुत से नोकिया तथा अन्य मोबाइल फोनों को ग्नोकी लाइब्रेरी के द्वारा समर्थित करता है
+Comment[hu]=Ez a meghajtó mobiltelefonok (elsősorban Nokia gyártmányúak) kezelését teszi lehetővé a Gnokii programkönyvtáron keresztül
+Comment[is]=Þessi rekill styður marga farsíma frá NOKIA og fleiri gegnum gnokii aðgerðasafnið
+Comment[it]=Questo driver supporta molti NOKIA e altri telefoni cellulari tramite la libreria gnokii
+Comment[ja]=このドライバは gnokii ライブラリを介して NOKIA および他社製の携帯電話を幅広くサポートします
+Comment[ka]=ეს დრაივერი მხარს უჭერს Nokia-ს მრავალ და სხვა ტელეფონებს gnokii ბიბლიოთეკის საშუალებით
+Comment[kk]=Бұл көп NOKIA мен басқа қалта құрылғыларды, gnokii жиыны арқылы, қамтитын драйвер
+Comment[km]=កម្មវិធី​បញ្ជា​នេះ​គាំទ្រ​ប្រភេទ​ទូរស័ព្ទ​ណូគៀ និង​ទូរស័ព្ទ​ផ្សេងៗ​ទៀត​ជាច្រើន​តាម​រយៈ​បណ្ណាល័យ gnokii
+Comment[lt]=Ši tvarkyklė palaiko daugelį NOKIA ir kitų telefonų pasinaudodama gnokii biblioteka
+Comment[ms]=Pemacu ini menyokong banyak NOKIA dan telefon bimbit lain melalui pustaka gnokii
+Comment[nb]=Denne driveren støtter mange NOKIA og andre mobiltelefoner via gnokii-biblioteket
+Comment[nds]=Disse Driever ünnerstütt vele Nokia- un anner Mobiltelefonen över de gnokii-Bibliotheek
+Comment[ne]=यो ड्राइभरले जिनोकी लाइब्रेरीबाट धेरै नोकिया र अन्य मोबाइल फोन समर्थन गर्छ
+Comment[nl]=Dit stuurprogramma biedt ondersteuning voor veel Nokia- en andere mobiele telefoons via de gnokii-bibliotheek
+Comment[nn]=Denne drivaren støttar mange NOKIA og andre mobiltelefonar via gnokii-biblioteket
+Comment[pl]=Ten sterownik obsługuje wiele telefonów komórkowych Nokia i innych za pomocą biblioteki gnokii
+Comment[pt]=Este controlador suportar muitos NOKIAs, bem como outros telemóveis, com a biblioteca 'gnokii'
+Comment[pt_BR]=Este driver suporta muitos telefones móveis, NOKIA e outros, via biblioteca gnokii
+Comment[ru]=Этот драйвер поддерживает множество моделей мобильных телефонов Nokia и других производителей через библиотеку gnokii
+Comment[sk]=Tento ovládač podporuje veľa mobilov NOKIA a iných pomocou knižnice gnokii
+Comment[sl]=Ta gonilnik preko knjižnice gnokii podpira mnoge prenosne telefone NOKIA kot tudi druge
+Comment[sr]=Овај управљачки програм подржава многе Nokia-ине и друге мобилне телефоне преко библиотеке gnokii
+Comment[sr@Latn]=Ovaj upravljački program podržava mnoge Nokia-ine i druge mobilne telefone preko biblioteke gnokii
+Comment[sv]=Den här drivrutinen stöder många Nokia och andra mobiltelefoner via biblioteket gnokii
+Comment[ta]=இந்த இயக்கி பல NOKIA மற்றும் மற்ற செல்பேசிகளை gnokii நூலகம் வழியாக ஆதரிக்கிறது.
+Comment[tg]=Ин драйвер бисёри тамсилаҳои телефонҳои мобилии Nokia-ро ва дигар истеҳсолкунандаҳоро аз китобхонаи gnokii дастгирӣ мекунад
+Comment[tr]=Bu sürücü birçok NOKIA ve gnokii kütüphanesiyle diğer cep telefonlarını destekler
+Comment[uk]=Цей драйвер підтримує багато мобільних телефонів фірми NOKIA та інших мобільних телефонів через бібліотеку gnokii
+Comment[zh_CN]=此驱动程序通过 gnokii 库支持许多诺基亚和其它移动电话
+Comment[zh_TW]=此驅動程式支援許多 NOKIA 及其他手機,使用 gnokii 函式庫
+Type=Service
+ServiceTypes=kdedevice/mobiledevice
+X-KDE-Library=libkmobile_gnokii
+Icon=mobile_phone