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 /kmobile/devices/gnokii | |
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 'kmobile/devices/gnokii')
-rw-r--r-- | kmobile/devices/gnokii/Makefile.am | 11 | ||||
-rw-r--r-- | kmobile/devices/gnokii/configure.in.in | 2 | ||||
-rw-r--r-- | kmobile/devices/gnokii/gnokii_mobile.cpp | 878 | ||||
-rw-r--r-- | kmobile/devices/gnokii/gnokii_mobile.h | 93 | ||||
-rw-r--r-- | kmobile/devices/gnokii/gnokiiconfig.cpp | 98 | ||||
-rw-r--r-- | kmobile/devices/gnokii/gnokiiconfig.h | 41 | ||||
-rw-r--r-- | kmobile/devices/gnokii/gnokiiconfigui.ui | 273 | ||||
-rw-r--r-- | kmobile/devices/gnokii/libkmobile_gnokii.desktop | 109 |
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 ¬e ) +{ + // 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 ¬e ); + +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>&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>&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>&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 |