kpilot/lib

plugin.cc

00001 /* KPilot
00002 **
00003 ** Copyright (C) 2001 by Dan Pilone
00004 ** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00005 **
00006 ** This file defines the base class of all KPilot conduit plugins configuration
00007 ** dialogs. This is necessary so that we have a fixed API to talk to from
00008 ** inside KPilot.
00009 **
00010 ** The factories used by KPilot plugins are also documented here.
00011 */
00012 
00013 /*
00014 ** This program is free software; you can redistribute it and/or modify
00015 ** it under the terms of the GNU Lesser General Public License as published by
00016 ** the Free Software Foundation; either version 2.1 of the License, or
00017 ** (at your option) any later version.
00018 **
00019 ** This program is distributed in the hope that it will be useful,
00020 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00022 ** GNU Lesser General Public License for more details.
00023 **
00024 ** You should have received a copy of the GNU Lesser General Public License
00025 ** along with this program in a file called COPYING; if not, write to
00026 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00027 ** MA 02110-1301, USA.
00028 */
00029 
00030 /*
00031 ** Bug reports and questions can be sent to kde-pim@kde.org
00032 */
00033 
00034 #include "options.h"
00035 
00036 #include <stdlib.h>
00037 
00038 #include <qstringlist.h>
00039 #include <qfileinfo.h>
00040 #include <qdir.h>
00041 #include <qregexp.h>
00042 #include <qtextcodec.h>
00043 
00044 #include <dcopclient.h>
00045 #include <kapplication.h>
00046 #include <kmessagebox.h>
00047 #include <kstandarddirs.h>
00048 #include <klibloader.h>
00049 
00050 #include "pilotSerialDatabase.h"
00051 #include "pilotLocalDatabase.h"
00052 #include "pilotAppCategory.h"
00053 
00054 #include "plugin.moc"
00055 
00056 ConduitConfigBase::ConduitConfigBase(QWidget *parent,
00057     const char *name) :
00058     QObject(parent,name),
00059     fModified(false),
00060     fWidget(0L),
00061     fConduitName(i18n("Unnamed"))
00062 {
00063     FUNCTIONSETUP;
00064 }
00065 
00066 ConduitConfigBase::~ConduitConfigBase()
00067 {
00068     FUNCTIONSETUP;
00069 }
00070 
00071 /* slot */ void ConduitConfigBase::modified()
00072 {
00073     fModified=true;
00074     emit changed(true);
00075 }
00076 
00077 /* virtual */ QString ConduitConfigBase::maybeSaveText() const
00078 {
00079     FUNCTIONSETUP;
00080 
00081     return i18n("<qt>The <i>%1</i> conduit's settings have been changed. Do you "
00082         "want to save the changes before continuing?</qt>").arg(this->conduitName());
00083 }
00084 
00085 /* virtual */ bool ConduitConfigBase::maybeSave()
00086 {
00087     FUNCTIONSETUP;
00088 
00089     if (!isModified()) return true;
00090 
00091     int r = KMessageBox::questionYesNoCancel(fWidget,
00092         maybeSaveText(),
00093         i18n("%1 Conduit").arg(this->conduitName()), KStdGuiItem::save(), KStdGuiItem::discard());
00094     if (r == KMessageBox::Cancel) return false;
00095     if (r == KMessageBox::Yes) commit();
00096     return true;
00097 }
00098 
00099 ConduitAction::ConduitAction(KPilotDeviceLink *p,
00100     const char *name,
00101     const QStringList &args) :
00102     SyncAction(p,name),
00103     fDatabase(0L),
00104     fLocalDatabase(0L),
00105     fSyncDirection(args),
00106     fConflictResolution(SyncAction::eAskUser),
00107     fFirstSync(false)
00108 {
00109     FUNCTIONSETUP;
00110 
00111     QString cResolution(args.grep(QRegExp(CSL1("--conflictResolution \\d*"))).first());
00112     if (cResolution.isEmpty())
00113     {
00114         fConflictResolution=(SyncAction::ConflictResolution)
00115             cResolution.replace(QRegExp(CSL1("--conflictResolution (\\d*)")), CSL1("\\1")).toInt();
00116     }
00117 
00118 #ifdef DEBUG
00119     for (QStringList::ConstIterator it = args.begin();
00120         it != args.end();
00121         ++it)
00122     {
00123         DEBUGCONDUIT << fname << ": " << *it << endl;
00124     }
00125 
00126     DEBUGCONDUIT << fname << ": Direction=" << fSyncDirection.name() << endl;
00127 #endif
00128 }
00129 
00130 /* virtual */ ConduitAction::~ConduitAction()
00131 {
00132     FUNCTIONSETUP;
00133     KPILOT_DELETE(fDatabase);
00134     KPILOT_DELETE(fLocalDatabase);
00135 }
00136 
00137 bool ConduitAction::openDatabases_(const QString &name, bool *retrieved)
00138 {
00139     FUNCTIONSETUP;
00140 
00141 #ifdef DEBUG
00142     DEBUGCONDUIT << fname
00143         << ": Trying to open database "
00144         << name << endl;
00145 #endif
00146 
00147     KPILOT_DELETE(fLocalDatabase);
00148     PilotLocalDatabase *localDB = new PilotLocalDatabase(name, true);
00149 
00150     if (!localDB)
00151     {
00152         kdWarning() << k_funcinfo
00153             << ": Could not initialize object for local copy of database \""
00154             << name
00155             << "\"" << endl;
00156         if (retrieved) *retrieved = false;
00157         return false;
00158     }
00159 
00160     // if there is no backup db yet, fetch it from the palm, open it and set the full sync flag.
00161     if (!localDB->isDBOpen() )
00162     {
00163         QString dbpath(localDB->dbPathName());
00164         KPILOT_DELETE(localDB);
00165 #ifdef DEBUG
00166         DEBUGCONDUIT << fname
00167             << ": Backup database "<< dbpath <<" could not be opened. Will fetch a copy from the palm and do a full sync"<<endl;
00168 #endif
00169         struct DBInfo dbinfo;
00170         if (fHandle->findDatabase(PilotAppCategory::codec()->fromUnicode( name ), &dbinfo)<0 )
00171         {
00172 #ifdef DEBUG
00173             DEBUGCONDUIT << fname
00174                 << ": Could not get DBInfo for "<<name<<"! "<<endl;
00175 #endif
00176             if (retrieved) *retrieved = false;
00177             return false;
00178         }
00179 #ifdef DEBUG
00180         DEBUGCONDUIT << fname
00181                 << ": Found Palm database: "<<dbinfo.name<<endl
00182                 <<"type = "<< dbinfo.type<<endl
00183                 <<"creator = "<< dbinfo.creator<<endl
00184                 <<"version = "<< dbinfo.version<<endl
00185                 <<"index = "<< dbinfo.index<<endl;
00186 #endif
00187         dbinfo.flags &= ~dlpDBFlagOpen;
00188 
00189         // make sure the dir for the backup db really exists!
00190         QFileInfo fi(dbpath);
00191         QString path(QFileInfo(dbpath).dir(TRUE).absPath());
00192         if (!path.endsWith(CSL1("/"))) path.append(CSL1("/"));
00193         if (!KStandardDirs::exists(path))
00194         {
00195 #ifdef DEBUG
00196             DEBUGCONDUIT << fname << ": Trying to create path for database: <"
00197                 << path << ">" << endl;
00198 #endif
00199             KStandardDirs::makeDir(path);
00200         }
00201         if (!KStandardDirs::exists(path))
00202         {
00203 #ifdef DEBUG
00204             DEBUGCONDUIT << fname << ": Database directory does not exist." << endl;
00205 #endif
00206             if (retrieved) *retrieved = false;
00207             return false;
00208         }
00209 
00210         if (!fHandle->retrieveDatabase(dbpath, &dbinfo) )
00211         {
00212 #ifdef DEBUG
00213             DEBUGCONDUIT << fname << ": Could not retrieve database "<<name<<" from the handheld."<<endl;
00214 #endif
00215             if (retrieved) *retrieved = false;
00216             return false;
00217         }
00218         localDB = new PilotLocalDatabase(name, true);
00219         if (!localDB || !localDB->isDBOpen())
00220         {
00221 #ifdef DEBUG
00222             DEBUGCONDUIT << fname << ": local backup of database "<<name<<" could not be initialized."<<endl;
00223 #endif
00224             if (retrieved) *retrieved = false;
00225             return false;
00226         }
00227         if (retrieved) *retrieved=true;
00228     }
00229     fLocalDatabase = localDB;
00230 
00231     fDatabase = new PilotSerialDatabase(pilotSocket(), name /* On pilot */);
00232 
00233     if (!fDatabase)
00234     {
00235         kdWarning() << k_funcinfo
00236             << ": Could not open database \""
00237             << name
00238             << "\" on the pilot."
00239             << endl;
00240     }
00241 
00242     return (fDatabase && fDatabase->isDBOpen() &&
00243             fLocalDatabase && fLocalDatabase->isDBOpen() );
00244 }
00245 
00246 // This whole function is for debugging purposes only.
00247 bool ConduitAction::openDatabases_(const QString &dbName,const QString &localPath)
00248 {
00249     FUNCTIONSETUP;
00250 #ifdef DEBUG
00251     DEBUGCONDUIT << fname << ": Doing local test mode for " << dbName << endl;
00252 #endif
00253     if (localPath.isNull())
00254     {
00255 #ifdef DEBUG
00256         DEBUGCONDUIT << fname
00257             << ": local mode test for one database only."
00258             << endl;
00259 #endif
00260         fDatabase = new PilotLocalDatabase(dbName,false);
00261         fLocalDatabase = 0L;
00262         return false;
00263     }
00264 
00265     fDatabase = new PilotLocalDatabase(localPath,dbName);
00266     fLocalDatabase= new PilotLocalDatabase(dbName, true); // From default
00267     if (!fLocalDatabase || !fDatabase)
00268     {
00269 #ifdef DEBUG
00270         const QString *where2 = PilotLocalDatabase::getDBPath();
00271 
00272         QString none = CSL1("<null>");
00273         DEBUGCONDUIT << fname
00274             << ": Could not open both local copies of \""
00275             << dbName
00276             << "\"" << endl
00277             << "Using \""
00278             << (where2 ? *where2 : none)
00279             << "\" and \""
00280             << (localPath.isEmpty() ? localPath : none)
00281             << "\""
00282             << endl;
00283 #endif
00284     }
00285 #ifdef DEBUG
00286     if (fLocalDatabase)
00287     {
00288         DEBUGCONDUIT << fname
00289             << ": Opened local database "
00290             << fLocalDatabase->dbPathName()
00291             << (fLocalDatabase->isDBOpen() ? " OK" : "")
00292             << endl;
00293     }
00294     if (fDatabase)
00295     {
00296         DEBUGCONDUIT << fname
00297             << ": Opened database "
00298             << fDatabase->dbPathName()
00299             << (fDatabase->isDBOpen() ? " OK" : "")
00300             << endl;
00301     }
00302 #endif
00303 
00304     return (fDatabase && fLocalDatabase);
00305 }
00306 
00307 bool ConduitAction::openDatabases(const QString &dbName, bool *retrieved)
00308 {
00309     FUNCTIONSETUP;
00310 
00311 #ifdef DEBUG
00312     DEBUGCONDUIT << fname
00313         << ": Mode="
00314         << (syncMode().isTest() ? "test " : "")
00315         << (syncMode().isLocal() ? "local " : "")
00316         << endl ;
00317 #endif
00318 
00319     if (syncMode().isLocal())
00320     {
00321         return openDatabases_(dbName,CSL1("/tmp/"));
00322     }
00323     else
00324     {
00325         return openDatabases_(dbName, retrieved);
00326     }
00327 }
00328 
00329 bool ConduitAction::changeSync(SyncMode::Mode m)
00330 {
00331     FUNCTIONSETUP;
00332 
00333     if ( fSyncDirection.isSync() && SyncMode::eFullSync == m)
00334     {
00335         fSyncDirection.setMode(m);
00336         return true;
00337     }
00338     return false;
00339 }
00340 
00341 int PluginUtility::findHandle(const QStringList &a)
00342 {
00343     FUNCTIONSETUP;
00344 
00345     int handle = -1;
00346     for (QStringList::ConstIterator i = a.begin();
00347         i != a.end(); ++i)
00348     {
00349         if ((*i).left(7) == CSL1("handle="))
00350         {
00351             QString s = (*i).mid(7);
00352             if (s.isEmpty()) continue;
00353 
00354             handle = s.toInt();
00355 #ifdef DEBUG
00356             DEBUGCONDUIT << fname
00357                 << ": Got handle "
00358                 << handle
00359                 << endl;
00360 #endif
00361             if (handle<1)
00362             {
00363                 kdWarning() << k_funcinfo
00364                     << ": Improbable handle value found."
00365                     << endl;
00366             }
00367             return handle;
00368         }
00369     }
00370 
00371 #ifdef DEBUG
00372     DEBUGCONDUIT << fname
00373         << ": No handle= parameter found."
00374         << endl;
00375 #endif
00376 
00377     return -1;
00378 }
00379 
00380 bool PluginUtility::isModal(const QStringList &a)
00381 {
00382     return a.contains(CSL1("modal"));
00383 }
00384 
00385 /* static */ bool PluginUtility::isRunning(const QCString &n)
00386 {
00387     DCOPClient *dcop = KApplication::kApplication()->dcopClient();
00388     QCStringList apps = dcop->registeredApplications();
00389     return apps.contains(n);
00390 }
00391 
00392 
00393 /* static */ long PluginUtility::pluginVersion(const KLibrary *lib)
00394 {
00395     QString symbol = CSL1("version_");
00396     symbol.append(lib->name());
00397 
00398     if (!lib->hasSymbol(symbol.latin1())) return 0;
00399 
00400     long *p = (long *)(lib->symbol(symbol.latin1()));
00401     return *p;
00402 }
00403 
00404 
00405 /* static */ QString PluginUtility::pluginVersionString(const KLibrary *lib)
00406 {
00407     QString symbol= CSL1("id_");
00408     symbol.append(lib->name());
00409 
00410     if (!lib->hasSymbol(symbol.latin1())) return QString::null;
00411 
00412     return QString::fromLatin1(*((const char **)(lib->symbol(symbol.latin1()))));
00413 }
00414 
00415 
KDE Home | KDE Accessibility Home | Description of Access Keys