diff options
Diffstat (limited to 'kpilot/lib/plugin.cc')
-rw-r--r-- | kpilot/lib/plugin.cc | 760 |
1 files changed, 0 insertions, 760 deletions
diff --git a/kpilot/lib/plugin.cc b/kpilot/lib/plugin.cc deleted file mode 100644 index 128c8ba99..000000000 --- a/kpilot/lib/plugin.cc +++ /dev/null @@ -1,760 +0,0 @@ -/* KPilot -** -** Copyright (C) 2001 by Dan Pilone -** Copyright (C) 2003-2004 Reinhold Kainhofer <[email protected]> -** -** This file defines the base class of all KPilot conduit plugins configuration -** dialogs. This is necessary so that we have a fixed API to talk to from -** inside KPilot. -** -** The factories used by KPilot plugins are also documented here. -*/ - -/* -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU Lesser General Public License as published by -** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public License -** along with this program in a file called COPYING; if not, write to -** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -** MA 02110-1301, USA. -*/ - -/* -** Bug reports and questions can be sent to [email protected] -*/ - -#include "options.h" - -#include <stdlib.h> - -#include <tqdir.h> -#include <tqfileinfo.h> -#include <tqhbox.h> -#include <tqlabel.h> -#include <tqlayout.h> -#include <tqpushbutton.h> -#include <tqregexp.h> -#include <tqstringlist.h> -#include <tqtabwidget.h> -#include <tqtextview.h> -#include <tqtimer.h> - -#include <dcopclient.h> -#include <kaboutapplication.h> -#include <kactivelabel.h> -#include <kapplication.h> -#include <kglobal.h> -#include <kiconloader.h> -#include <kinstance.h> -#include <klibloader.h> -#include <kmessagebox.h> -#include <kservice.h> -#include <kservicetype.h> -#include <kstandarddirs.h> - -#include "pilotSerialDatabase.h" -#include "pilotLocalDatabase.h" - -#include "plugin.moc" - -ConduitConfigBase::ConduitConfigBase(TQWidget *parent, - const char *name) : - TQObject(parent,name), - fModified(false), - fWidget(0L), - fConduitName(i18n("Unnamed")) -{ - FUNCTIONSETUP; -} - -ConduitConfigBase::~ConduitConfigBase() -{ - FUNCTIONSETUP; -} - -/* slot */ void ConduitConfigBase::modified() -{ - fModified=true; - emit changed(true); -} - -/* virtual */ TQString ConduitConfigBase::maybeSaveText() const -{ - FUNCTIONSETUP; - - return i18n("<qt>The <i>%1</i> conduit's settings have been changed. Do you " - "want to save the changes before continuing?</qt>").arg(this->conduitName()); -} - -/* virtual */ bool ConduitConfigBase::maybeSave() -{ - FUNCTIONSETUP; - - if (!isModified()) return true; - - int r = KMessageBox::questionYesNoCancel(fWidget, - maybeSaveText(), - i18n("%1 Conduit").arg(this->conduitName()), KStdGuiItem::save(), KStdGuiItem::discard()); - if (r == KMessageBox::Cancel) return false; - if (r == KMessageBox::Yes) commit(); - return true; -} - -TQWidget *ConduitConfigBase::aboutPage(TQWidget *parent, KAboutData *ad) -{ - FUNCTIONSETUP; - - TQWidget *w = new TQWidget(parent, "aboutpage"); - - TQString s; - TQLabel *text; - KIconLoader *l = KGlobal::iconLoader(); - const KAboutData *p = ad ? ad : KGlobal::instance()->aboutData(); - - TQGridLayout *grid = new TQGridLayout(w, 5, 4, SPACING); - - grid->addColSpacing(0, SPACING); - grid->addColSpacing(4, SPACING); - - - TQPixmap applicationIcon = - l->loadIcon(TQString::fromLatin1(p->appName()), - KIcon::Desktop, - 64, KIcon::DefaultState, 0L, - true); - - if (applicationIcon.isNull()) - { - applicationIcon = l->loadIcon(TQString::fromLatin1("kpilot"), - KIcon::Desktop); - } - - text = new TQLabel(w); - // Experiment with a long non-<qt> string. Use that to find - // sensible widths for the columns. - // - text->setText(i18n("Send questions and comments to [email protected]")); - text->adjustSize(); - - int linewidth = text->size().width(); - int lineheight = text->size().height(); - - // Use the label to display the applciation icon - text->setText(TQString::null); - text->setPixmap(applicationIcon); - text->adjustSize(); - grid->addWidget(text, 0, 1); - - - KActiveLabel *linktext = new KActiveLabel(w); - grid->addRowSpacing(1,kMax(100,6*lineheight)); - grid->addRowSpacing(2,kMax(100,6*lineheight)); - grid->addColSpacing(2,SPACING+linewidth/2); - grid->addColSpacing(3,SPACING+linewidth/2); - grid->setRowStretch(1,50); - grid->setRowStretch(2,50); - grid->setColStretch(2,50); - grid->setColStretch(3,50); - linktext->setMinimumSize(linewidth,kMax(260,60+12*lineheight)); - linktext->setFixedHeight(kMax(260,60+12*lineheight)); - linktext->setVScrollBarMode(TQScrollView::Auto/*AlwaysOn*/); - text = new TQLabel(w); - grid->addMultiCellWidget(text,0,0,2,3); - grid->addMultiCellWidget(linktext,1,2,1,3); - - // Now set the program and copyright information. - s = CSL1("<qt><h3>"); - s += p->programName(); - s += ' '; - s += p->version(); - s += CSL1("</h3>"); - s += p->copyrightStatement() + CSL1("<br></qt>"); - text->setText(s); - - linktext->append(p->shortDescription() + CSL1("<br>")); - - if (!p->homepage().isEmpty()) - { - s = TQString::null; - s += CSL1("<a href=\"%1\">").arg(p->homepage()); - s += p->homepage(); - s += CSL1("</a><br>"); - linktext->append(s); - } - - s = TQString::null; - s += i18n("Send questions and comments to <a href=\"mailto:%1\">%2</a>.") - .arg( CSL1("[email protected]") ) - .arg( CSL1("[email protected]") ); - s += ' '; - s += i18n("Send bug reports to <a href=\"mailto:%1\">%2</a>.") - .arg(p->bugAddress()) - .arg(p->bugAddress()); - s += ' '; - s += i18n("For trademark information, see the " - "<a href=\"help:/kpilot/trademarks.html\">KPilot User's Guide</a>."); - s += CSL1("<br>"); - linktext->append(s); - linktext->append(TQString::null); - - - - TQValueList<KAboutPerson> pl = p->authors(); - TQValueList<KAboutPerson>::ConstIterator i; - - s = i18n("<b>Authors:</b> "); - - TQString comma = CSL1(", "); - - unsigned int count=1; - for (i=pl.begin(); i!=pl.end(); ++i) - { - s.append(CSL1("%1 (<i>%2</i>)%3") - .arg((*i).name()) - .arg((*i).task()) - .arg(count<pl.count() ? comma : TQString::null) - ); - count++; - } - linktext->append(s); - - s = TQString::null; - pl = p->credits(); - if (pl.count()>0) - { - count=1; - s.append(i18n("<b>Credits:</b> ")); - for (i=pl.begin(); i!=pl.end(); ++i) - { - s.append(CSL1("%1 (<i>%2</i>)%3") - .arg((*i).name()) - .arg((*i).task()) - .arg(count<pl.count() ? comma : TQString::null) - ); - count++; - } - } - linktext->append(s); - linktext->ensureVisible(0,0); - - w->adjustSize(); - - return w; -} - -/* static */ void ConduitConfigBase::addAboutPage(TQTabWidget *tw, - KAboutData *ad) -{ - FUNCTIONSETUP; - - Q_ASSERT(tw); - - TQWidget *w = aboutPage(tw,ad); - TQSize sz = w->size(); - - if (sz.width() < tw->size().width()) - { - sz.setWidth(tw->size().width()); - } - if (sz.height() < tw->size().height()) - { - sz.setHeight(tw->size().height()); - } - - tw->resize(sz); - tw->addTab(w, i18n("About")); - tw->adjustSize(); -} - - - -ConduitAction::ConduitAction(KPilotLink *p, - const char *name, - const TQStringList &args) : - SyncAction(p,name), - fDatabase(0L), - fLocalDatabase(0L), - fCtrHH(0L), - fCtrPC(0L), - fSyncDirection(args), - fConflictResolution(SyncAction::eAskUser), - fFirstSync(false) -{ - FUNCTIONSETUP; - - TQString cResolution(args.grep(TQRegExp(CSL1("--conflictResolution \\d*"))).first()); - if (cResolution.isEmpty()) - { - fConflictResolution=(SyncAction::ConflictResolution) - cResolution.replace(TQRegExp(CSL1("--conflictResolution (\\d*)")), CSL1("\\1")).toInt(); - } - - for (TQStringList::ConstIterator it = args.begin(); - it != args.end(); - ++it) - { - DEBUGKPILOT << fname << ": " << *it << endl; - } - - DEBUGKPILOT << fname << ": Direction=" << fSyncDirection.name() << endl; - fCtrHH = new CUDCounter(i18n("Handheld")); - fCtrPC = new CUDCounter(i18n("PC")); -} - -/* virtual */ ConduitAction::~ConduitAction() -{ - FUNCTIONSETUP; - - KPILOT_DELETE(fDatabase); - KPILOT_DELETE(fLocalDatabase); - - KPILOT_DELETE(fCtrHH); - KPILOT_DELETE(fCtrPC); -} - -bool ConduitAction::openDatabases(const TQString &name, bool *retrieved) -{ - FUNCTIONSETUP; - - DEBUGKPILOT << fname - << ": Trying to open database " - << name << endl; - DEBUGKPILOT << fname - << ": Mode=" - << (syncMode().isTest() ? "test " : "") - << (syncMode().isLocal() ? "local " : "") - << endl ; - - KPILOT_DELETE(fLocalDatabase); - - TQString localPathName = PilotLocalDatabase::getDBPath() + name; - - // we always want to use the conduits/ directory for our local - // databases. this keeps our backups and data that our conduits use - // for record keeping separate - localPathName.replace(CSL1("DBBackup/"), CSL1("conduits/")); - - DEBUGKPILOT << fname << ": localPathName: [" << localPathName - << "]" << endl; - - PilotLocalDatabase *localDB = new PilotLocalDatabase( localPathName ); - - if (!localDB) - { - WARNINGKPILOT << "Could not initialize object for local copy of database \"" - << name - << "\"" << endl; - if (retrieved) *retrieved = false; - return false; - } - - // if there is no backup db yet, fetch it from the palm, open it and set the full sync flag. - if (!localDB->isOpen() ) - { - TQString dbpath(localDB->dbPathName()); - KPILOT_DELETE(localDB); - DEBUGKPILOT << fname - << ": Backup database " << dbpath - << " not found." << endl; - struct DBInfo dbinfo; - -// TODO Extend findDatabase() with extra overload? - if (deviceLink()->findDatabase(Pilot::toPilot( name ), &dbinfo)<0 ) - { - WARNINGKPILOT << "Could not get DBInfo for " << name << endl; - if (retrieved) *retrieved = false; - return false; - } - - DEBUGKPILOT << fname - << ": Found Palm database: " << dbinfo.name <<endl - << fname << ": type = " << dbinfo.type - << " creator = " << dbinfo.creator - << " version = " << dbinfo.version - << " index = " << dbinfo.index << endl; - dbinfo.flags &= ~dlpDBFlagOpen; - - // make sure the dir for the backup db really exists! - TQFileInfo fi(dbpath); - TQString path(TQFileInfo(dbpath).dir(true).absPath()); - if (!path.endsWith(CSL1("/"))) path.append(CSL1("/")); - if (!KStandardDirs::exists(path)) - { - DEBUGKPILOT << fname << ": Trying to create path for database: <" - << path << ">" << endl; - KStandardDirs::makeDir(path); - } - if (!KStandardDirs::exists(path)) - { - DEBUGKPILOT << fname << ": Database directory does not exist." << endl; - if (retrieved) *retrieved = false; - return false; - } - - if (!deviceLink()->retrieveDatabase(dbpath, &dbinfo) ) - { - WARNINGKPILOT << "Could not retrieve database " - << name << " from the handheld." << endl; - if (retrieved) *retrieved = false; - return false; - } - localDB = new PilotLocalDatabase( localPathName ); - if (!localDB || !localDB->isOpen()) - { - WARNINGKPILOT << "local backup of database " << name << " could not be initialized." << endl; - if (retrieved) *retrieved = false; - return false; - } - if (retrieved) *retrieved=true; - } - fLocalDatabase = localDB; - - fDatabase = deviceLink()->database( name ); - - if (!fDatabase) - { - WARNINGKPILOT << "Could not open database \"" - << name - << "\" on the pilot." - << endl; - } - else - { - fCtrHH->setStartCount(fDatabase->recordCount()); - } - - return (fDatabase && fDatabase->isOpen() && - fLocalDatabase && fLocalDatabase->isOpen() ); -} - - -bool ConduitAction::changeSync(SyncMode::Mode m) -{ - FUNCTIONSETUP; - - if ( fSyncDirection.isSync() && SyncMode::eFullSync == m) - { - fSyncDirection.setMode(m); - return true; - } - return false; -} - -void ConduitAction::finished() -{ - FUNCTIONSETUP; - - if (fDatabase && fCtrHH) - fCtrHH->setEndCount(fDatabase->recordCount()); - - if (fCtrHH && fCtrPC) - { - addSyncLogEntry(fCtrHH->moo() +"\n",false); - DEBUGKPILOT << fname << ": " << fCtrHH->moo() << endl; - addSyncLogEntry(fCtrPC->moo() +"\n",false); - DEBUGKPILOT << fname << ": " << fCtrPC->moo() << endl; - - // STEP2 of making sure we don't delete our little user's - // precious data... - // sanity checks for handheld... - int hhVolatility = fCtrHH->percentDeleted() + - fCtrHH->percentUpdated() + - fCtrHH->percentCreated(); - - int pcVolatility = fCtrPC->percentDeleted() + - fCtrPC->percentUpdated() + - fCtrPC->percentCreated(); - - // TODO: allow user to configure this... - // this is a percentage... - int allowedVolatility = 70; - - TQString caption = i18n("Large Changes Detected"); - // args are already i18n'd - TQString query = i18n("The %1 conduit has made a " - "large number of changes to your %2. Do you want " - "to allow this change?\nDetails:\n\t%3"); - - if (hhVolatility > allowedVolatility) - { - query = query.arg(fConduitName) - .arg(fCtrHH->type()).arg(fCtrHH->moo()); - - DEBUGKPILOT << fname << ": Yikes, lots of volatility " - << "caught. Check with user: [" << query - << "]." << endl; - - /* - int rc = questionYesNo(query, caption, - TQString::null, 0 ); - if (rc == KMessageBox::Yes) - { - // TODO: add commit and rollback code. - // note: this will require some thinking, - // since we have to undo changes to the - // pilot databases, changes to the PC - // resources, changes to the mappings files - // (record id mapping, etc.) - } - */ - } - - - } - -} - - -ConduitProxy::ConduitProxy(KPilotLink *p, - const TQString &name, - const SyncAction::SyncMode &m) : - ConduitAction(p,name.latin1(),m.list()), - fDesktopName(name) -{ - FUNCTIONSETUP; -} - -/* virtual */ bool ConduitProxy::exec() -{ - FUNCTIONSETUP; - - // query that service - KSharedPtr < KService > o = KService::serviceByDesktopName(fDesktopName); - if (!o) - { - WARNINGKPILOT << "Can't find desktop file for conduit " - << fDesktopName - << endl; - addSyncLogEntry(i18n("Could not find conduit %1.").arg(fDesktopName)); - return false; - } - - - // load the lib - fLibraryName = o->library(); - DEBUGKPILOT << fname - << ": Loading desktop " - << fDesktopName - << " with lib " - << fLibraryName - << endl; - - KLibrary *library = KLibLoader::self()->library( - TQFile::encodeName(fLibraryName)); - if (!library) - { - WARNINGKPILOT << "Can't load library " - << fLibraryName - << " - " - << KLibLoader::self()->lastErrorMessage() - << endl; - addSyncLogEntry(i18n("Could not load conduit %1.").arg(fDesktopName)); - return false; - } - - unsigned long version = PluginUtility::pluginVersion(library); - if ( Pilot::PLUGIN_API != version ) - { - WARNINGKPILOT << "Library " - << fLibraryName - << " has version " - << version - << endl; - addSyncLogEntry(i18n("Conduit %1 has wrong version (%2).").arg(fDesktopName).arg(version)); - return false; - } - - KLibFactory *factory = library->factory(); - if (!factory) - { - WARNINGKPILOT << "Can't find factory in library " - << fLibraryName - << endl; - addSyncLogEntry(i18n("Could not initialize conduit %1.").arg(fDesktopName)); - return false; - } - - TQStringList l = syncMode().list(); - - DEBUGKPILOT << fname << ": Flags: " << syncMode().name() << endl; - - TQObject *object = factory->create(fHandle,name(),"SyncAction",l); - - if (!object) - { - WARNINGKPILOT << "Can't create SyncAction." << endl; - addSyncLogEntry(i18n("Could not create conduit %1.").arg(fDesktopName)); - return false; - } - - fConduit = dynamic_cast<ConduitAction *>(object); - - if (!fConduit) - { - WARNINGKPILOT << "Can't cast to ConduitAction." << endl; - addSyncLogEntry(i18n("Could not create conduit %1.").arg(fDesktopName)); - return false; - } - - addSyncLogEntry(i18n("[Conduit %1]").arg(fDesktopName)); - - // Handle the syncDone signal properly & unload the conduit. - TQObject::connect(fConduit,TQT_SIGNAL(syncDone(SyncAction *)), - this,TQT_SLOT(execDone(SyncAction *))); - // Proxy all the log and error messages. - TQObject::connect(fConduit,TQT_SIGNAL(logMessage(const TQString &)), - this,TQT_SIGNAL(logMessage(const TQString &))); - TQObject::connect(fConduit,TQT_SIGNAL(logError(const TQString &)), - this,TQT_SIGNAL(logError(const TQString &))); - TQObject::connect(fConduit,TQT_SIGNAL(logProgress(const TQString &,int)), - this,TQT_SIGNAL(logProgress(const TQString &,int))); - - TQTimer::singleShot(0,fConduit,TQT_SLOT(execConduit())); - return true; -} - -void ConduitProxy::execDone(SyncAction *p) -{ - FUNCTIONSETUP; - - if (p!=fConduit) - { - WARNINGKPILOT << "Unknown conduit @" - << (void *) p - << " finished." - << endl; - emit syncDone(this); - return; - } - - // give our worker a chance to sanity check the results... - fConduit->finished(); - - addSyncLogEntry(CSL1("\n"),false); // Put bits of the conduit logs on separate lines - - KPILOT_DELETE(p); - - emit syncDone(this); -} - - -namespace PluginUtility -{ - -TQString findArgument(const TQStringList &a, const TQString &arg) -{ - FUNCTIONSETUP; - - TQString search; - - if (arg.startsWith( CSL1("--") )) - { - search = arg; - } - else - { - search = CSL1("--") + arg; - } - search.append( CSL1("=") ); - - - TQStringList::ConstIterator end = a.end(); - for (TQStringList::ConstIterator i = a.begin(); i != end; ++i) - { - if ((*i).startsWith( search )) - { - TQString s = (*i).mid(search.length()); - return s; - } - } - - return TQString::null; -} - -/* static */ bool isRunning(const TQCString &n) -{ - DCOPClient *dcop = KApplication::kApplication()->dcopClient(); - QCStringList apps = dcop->registeredApplications(); - return apps.contains(n); -} - - -/* static */ unsigned long pluginVersion(const KLibrary *lib) -{ - TQString symbol = CSL1("version_"); - symbol.append(lib->name()); - - if (!lib->hasSymbol(symbol.latin1())) return 0; - - unsigned long *p = (unsigned long *)(lib->symbol(symbol.latin1())); - return *p; -} - - -/* static */ TQString pluginVersionString(const KLibrary *lib) -{ - TQString symbol= CSL1("id_"); - symbol.append(lib->name()); - - if (!lib->hasSymbol(symbol.latin1())) return TQString::null; - - return TQString::fromLatin1(*((const char **)(lib->symbol(symbol.latin1())))); -} - - -} - - -CUDCounter::CUDCounter(TQString s) : - fC(0),fU(0),fD(0),fStart(0),fEnd(0),fType(s) -{ -} - -void CUDCounter::created(unsigned int c) -{ - fC += c; -} - -void CUDCounter::updated(unsigned int c) -{ - fU += c; -} - -void CUDCounter::deleted(unsigned int c) -{ - fD += c; -} - -void CUDCounter::setStartCount(unsigned int t) -{ - fStart = t; -} - -void CUDCounter::setEndCount(unsigned int t) -{ - fEnd = t; -} - -TQString CUDCounter::moo() const -{ - TQString result = fType + ": " + - i18n("Start: %1. End: %2. ").arg(fStart).arg(fEnd); - - if (fC > 0) result += i18n("%1 new. ").arg(fC); - if (fU > 0) result += i18n("%1 changed. ").arg(fU); - if (fD > 0) result += i18n("%1 deleted. ").arg(fD); - - if ( (fC+fU+fD) <= 0) result += i18n("No changes made. "); - - return result; -} - - |