kpilot

syncAction.cc

Go to the documentation of this file.
00001 /* KPilot
00002 **
00003 ** Copyright (C) 1998-2001 by Dan Pilone
00004 ** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00005 ** Copyright (C) 2001 by Waldo Bastian (code in questionYesNo)
00006 **
00007 */
00008 
00009 /*
00010 ** This program is free software; you can redistribute it and/or modify
00011 ** it under the terms of the GNU Lesser General Public License as published by
00012 ** the Free Software Foundation; either version 2.1 of the License, or
00013 ** (at your option) any later version.
00014 **
00015 ** This program is distributed in the hope that it will be useful,
00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018 ** GNU Lesser General Public License for more details.
00019 **
00020 ** You should have received a copy of the GNU Lesser General Public License
00021 ** along with this program in a file called COPYING; if not, write to
00022 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00023 ** MA 02110-1301, USA.
00024 */
00025 
00026 /*
00027 ** Bug reports and questions can be sent to kde-pim@kde.org
00028 */
00029 
00030 #include "options.h"
00031 
00032 #include <time.h>
00033 
00034 #include <pi-socket.h>
00035 #include <pi-dlp.h>
00036 
00037 #include <qtimer.h>
00038 #include <qvbox.h>
00039 #include <qlayout.h>
00040 #include <qcheckbox.h>
00041 #include <qlabel.h>
00042 #include <qmessagebox.h>
00043 #include <qdir.h>
00044 #include <qfile.h>
00045 #include <qfileinfo.h>
00046 #include <qtl.h>
00047 #include <qstyle.h>
00048 
00049 #include <kdialogbase.h>
00050 #include <kglobal.h>
00051 #include <kstandarddirs.h>
00052 #include <kconfig.h>
00053 #include <kmessagebox.h>
00054 
00055 #include "syncAction.moc"
00056 #include "kpilotlibSettings.h"
00057 
00058 SyncAction::SyncAction(KPilotLink  *p,
00059     const char *name) :
00060     QObject(p, name),
00061     fHandle(p),
00062     fParent(0L)
00063 {
00064     FUNCTIONSETUP;
00065 }
00066 
00067 SyncAction::SyncAction(KPilotLink *p,
00068     QWidget * visibleparent,
00069     const char *name) :
00070     QObject(p, name),
00071     fHandle(p),
00072     fParent(visibleparent)
00073 {
00074     FUNCTIONSETUP;
00075 }
00076 
00077 SyncAction::~SyncAction()
00078 {
00079 }
00080 
00081 /* virtual */ QString SyncAction::statusString() const
00082 {
00083     FUNCTIONSETUP;
00084     QString s = CSL1("status=");
00085 
00086     s.append(QString::number(status()));
00087     return s;
00088 }
00089 
00090 /* slot */ void SyncAction::execConduit()
00091 {
00092     FUNCTIONSETUP;
00093 
00094     DEBUGKPILOT << fname << ": Exec " << name() << endl;
00095 
00096     bool r = this->exec();
00097 
00098     DEBUGKPILOT << fname << ": Exec " << name()
00099         << (r ? " is running" : " failed to start") << endl;
00100 
00101     if (!r)
00102     {
00103         emit logError(i18n("The conduit %1 could not be executed.")
00104             .arg(QString::fromLatin1(name())));
00105         delayDone();
00106     }
00107 }
00108 
00109 /* slot */ void SyncAction::delayedDoneSlot()
00110 {
00111     emit syncDone(this);
00112 }
00113 
00114 bool SyncAction::delayDone()
00115 {
00116     QTimer::singleShot(0,this,SLOT(delayedDoneSlot()));
00117     return true;
00118 }
00119 
00120 static struct
00121 {
00122     SyncAction::SyncMode::Mode mode;
00123     const char *name;
00124 } maps[] =
00125 {
00126     { SyncAction::SyncMode::eHotSync, "--hotsync" },
00127     { SyncAction::SyncMode::eFullSync, "--full" },
00128     { SyncAction::SyncMode::eCopyPCToHH, "--copyPCToHH" },
00129     { SyncAction::SyncMode::eCopyHHToPC, "--copyHHToPC" },
00130     { SyncAction::SyncMode::eBackup, "--backup" },
00131     { SyncAction::SyncMode::eRestore, "--restore" },
00132     { SyncAction::SyncMode::eFullSync, "--fullsync" },
00133     { SyncAction::SyncMode::eHotSync, (const char *)0 }
00134 }
00135 ;
00136 
00137 SyncAction::SyncMode::SyncMode(const QStringList &args) :
00138     fMode(eHotSync),
00139     fTest(args.contains("--test")),
00140     fLocal(args.contains("--local"))
00141 {
00142     int i = 0;
00143     while(maps[i].name)
00144     {
00145         if (args.contains(QString::fromLatin1(maps[i].name)))
00146         {
00147             fMode = maps[i].mode;
00148             break;
00149         }
00150         i++;
00151     }
00152 
00153     if (!maps[i].name)
00154     {
00155         WARNINGKPILOT << "No mode set by arguments ("
00156             << args.join(",") << ") defaulting to HotSync." << endl;
00157     }
00158 }
00159 
00160 SyncAction::SyncMode::SyncMode(Mode m, bool test, bool local) :
00161     fMode(m),
00162     fTest(test),
00163     fLocal(local)
00164 {
00165     if ( ((int)m<(int)eHotSync) || ((int)m>(int)eRestore) )
00166     {
00167         WARNINGKPILOT << "Mode value " << (int)m << " is illegal"
00168             ", defaulting to HotSync." << endl;
00169         fMode = eHotSync;
00170     }
00171 }
00172 
00173 QStringList SyncAction::SyncMode::list() const
00174 {
00175     FUNCTIONSETUPL(3);
00176 
00177     QStringList l;
00178     int i=0;
00179 
00180     while(maps[i].name)
00181     {
00182         if ( fMode == maps[i].mode )
00183         {
00184             l.append(QString::fromLatin1(maps[i].name));
00185             break;
00186         }
00187         i++;
00188     }
00189     if ( !maps[i].name )
00190     {
00191         WARNINGKPILOT << "Mode " << fMode << " does not have a name." << endl;
00192         l.append(QString::fromLatin1(maps[0].name));
00193     }
00194 
00195     if (isTest()) l.append(CSL1("--test"));
00196     if (isLocal()) l.append(CSL1("--local"));
00197     return l;
00198 }
00199 
00200 /* static */ QString SyncAction::SyncMode::name(SyncAction::SyncMode::Mode e)
00201 {
00202     switch(e)
00203     {
00204     case eHotSync : return i18n("HotSync");
00205     case eFullSync : return i18n("Full Synchronization");
00206     case eCopyPCToHH : return i18n("Copy PC to Handheld");
00207     case eCopyHHToPC : return i18n("Copy Handheld to PC");
00208     case eBackup : return i18n("Backup");
00209     case eRestore : return i18n("Restore From Backup");
00210     }
00211     return CSL1("<unknown>");
00212 }
00213 
00214 QString SyncAction::SyncMode::name() const
00215 {
00216     QString s = name(fMode);
00217     if (isTest())
00218     {
00219 
00220         s.append(CSL1(" [%1]").arg(i18n("Test Sync")));
00221     }
00222     if (isLocal())
00223     {
00224         s.append(CSL1(" [%1]").arg(i18n("Local Sync")));
00225     }
00226     return s;
00227 }
00228 
00229 bool SyncAction::SyncMode::setMode(int mode)
00230 {
00231     // Resets test and local flags too
00232     fTest = fLocal = false;
00233 
00234     if ( (mode>0) && (mode<=eRestore) )
00235     {
00236         fMode = (SyncAction::SyncMode::Mode) mode;
00237         return true;
00238     }
00239     else
00240     {
00241         WARNINGKPILOT << "Bad sync mode " << mode << " requested." << endl ;
00242         fMode = eHotSync;
00243         return false;
00244     }
00245 }
00246 
00247 bool SyncAction::SyncMode::setMode(SyncAction::SyncMode::Mode m)
00248 {
00249     int i=0;
00250     while ( maps[i].name )
00251     {
00252         if ( maps[i].mode == m )
00253         {
00254             fMode = m;
00255             return true;
00256         }
00257         i++;
00258     }
00259 
00260     WARNINGKPILOT << "Bad sync mode " << m << " requested." << endl ;
00261     fMode = eHotSync;
00262     return false;
00263 }
00264 
00265 void SyncAction::startTickle(unsigned timeout)
00266 {
00267     FUNCTIONSETUP;
00268 
00269     if (!deviceLink())
00270     {
00271         WARNINGKPILOT << "Trying to tickle without a device." << endl;
00272     }
00273     else
00274     {
00275         connect(deviceLink(),SIGNAL(timeout()),this,SIGNAL(timeout()));
00276         deviceLink()->startTickle(timeout);
00277     }
00278 }
00279 
00280 void SyncAction::stopTickle()
00281 {
00282     FUNCTIONSETUP;
00283     if (!deviceLink())
00284     {
00285         WARNINGKPILOT << "Trying to tickle without a device." << endl;
00286     }
00287     else
00288     {
00289         disconnect(deviceLink(),SIGNAL(timeout()),this,SIGNAL(timeout()));
00290         deviceLink()->stopTickle();
00291     }
00292 }
00293 
00294 
00295 int SyncAction::questionYesNo(const QString & text,
00296     const QString & caption,
00297     const QString & key,
00298     unsigned timeout,
00299     const QString & yes,
00300     const QString &no )
00301 {
00302     FUNCTIONSETUP;
00303 
00304     bool checkboxReturn = false;
00305     int r;
00306     KMessageBox::ButtonCode result;
00307     if (!key.isEmpty())
00308     {
00309         if (!KMessageBox::shouldBeShownYesNo(key,result))
00310         {
00311             return result;
00312         }
00313     }
00314 
00315     KDialogBase *dialog =
00316         new KDialogBase(caption.isNull()? i18n("Question") : caption,
00317         KDialogBase::Yes | KDialogBase::No,
00318         KDialogBase::Yes, KDialogBase::No,
00319         fParent, "questionYesNo", true, true,
00320         yes.isEmpty() ? KStdGuiItem::yes() : yes,
00321         no.isEmpty() ? KStdGuiItem::no() : no);
00322 
00323     if ( (timeout > 0) && ( deviceLink() ) )
00324     {
00325         QObject::connect(deviceLink(), SIGNAL(timeout()),
00326             dialog, SLOT(slotCancel()));
00327         startTickle(timeout);
00328     }
00329 
00330 #if KDE_IS_VERSION(3,3,0)
00331     r = (KMessageBox::ButtonCode) KMessageBox::createKMessageBox(dialog,
00332         QMessageBox::Question,
00333         text,
00334         QStringList(),
00335         (key.isEmpty() ? QString::null : i18n("&Do not ask again")),
00336         &checkboxReturn,
00337         0);
00338 
00339 #else
00340     // The following code is taken from KDialogBase.cc,
00341     // part of the KDE 2.2 libraries. Copyright 2001
00342     // by Waldo Bastian.
00343     //
00344     //
00345     QVBox *topcontents = new QVBox(dialog);
00346 
00347     topcontents->setSpacing(KDialog::spacingHint() * 2);
00348     topcontents->setMargin(KDialog::marginHint() * 2);
00349 
00350     QWidget *contents = new QWidget(topcontents);
00351     QHBoxLayout *lay = new QHBoxLayout(contents);
00352 
00353     lay->setSpacing(KDialog::spacingHint() * 2);
00354 
00355     lay->addStretch(1);
00356     QLabel *label1 = new QLabel( contents);
00357     label1->setPixmap(QMessageBox::standardIcon(QMessageBox::Information));
00358     lay->add( label1 );
00359     QLabel *label2 = new QLabel( text, contents);
00360     label2->setMinimumSize(label2->sizeHint());
00361     lay->add(label2);
00362     lay->addStretch(1);
00363 
00364     QSize extraSize = QSize(50, 30);
00365 
00366     QCheckBox *checkbox = 0L;
00367     if (!key.isEmpty())
00368     {
00369         checkbox = new QCheckBox(i18n("Do not ask again"),topcontents);
00370         extraSize = QSize(50,0);
00371     }
00372 
00373     dialog->setMainWidget(topcontents);
00374     dialog->enableButtonSeparator(false);
00375     dialog->incInitialSize(extraSize);
00376 
00377     r = dialog->exec();
00378     if (checkbox)
00379     {
00380         checkboxReturn = checkbox->isChecked();
00381     }
00382 #endif
00383 
00384     switch(r)
00385     {
00386     case KDialogBase::Yes : result=KMessageBox::Yes ; break;
00387     case KDialogBase::No  : result=KMessageBox::No; break;
00388     case KDialogBase::Cancel : result=KMessageBox::Cancel; break;
00389     default : break;
00390     }
00391 
00392     stopTickle();
00393 
00394     if (!key.isEmpty() && checkboxReturn)
00395     {
00396         KMessageBox::saveDontShowAgainYesNo(key,result);
00397     }
00398 
00399     return result;
00400 }
00401 
00402 
00403 int SyncAction::questionYesNoCancel(const QString & text,
00404     const QString & caption,
00405     const QString & key,
00406     unsigned timeout,
00407     const QString &yes,
00408     const QString &no)
00409 {
00410     FUNCTIONSETUP;
00411 
00412     bool checkboxReturn = false;
00413     int r;
00414     KMessageBox::ButtonCode result;
00415 
00416     if (!key.isEmpty())
00417     {
00418         if (!KMessageBox::shouldBeShownYesNo(key,result))
00419         {
00420             if (result != KMessageBox::Cancel)
00421             {
00422                 return result;
00423             }
00424         }
00425     }
00426 
00427     KDialogBase *dialog =
00428         new KDialogBase(caption.isNull()? i18n("Question") : caption,
00429         KDialogBase::Yes | KDialogBase::No | KDialogBase::Cancel,
00430         KDialogBase::Yes, KDialogBase::Cancel,
00431         fParent, "questionYesNoCancel", true, true,
00432         (yes.isEmpty() ? KStdGuiItem::yes() : yes),
00433         (no.isEmpty() ? KStdGuiItem::no() : no),
00434         KStdGuiItem::cancel());
00435 
00436     if ( (timeout > 0) && (deviceLink()) )
00437     {
00438         QObject::connect(deviceLink(), SIGNAL(timeout()),
00439             dialog, SLOT(slotCancel()));
00440         startTickle(timeout);
00441     }
00442 
00443 #if KDE_IS_VERSION(3,3,0)
00444     r = KMessageBox::createKMessageBox(dialog,
00445         QMessageBox::Question,
00446         text,
00447         QStringList(),
00448         (key.isEmpty() ? QString::null : i18n("&Do not ask again")),
00449         &checkboxReturn,
00450         0);
00451 #else
00452     // The following code is taken from KDialogBase.cc,
00453     // part of the KDE 2.2 libraries. Copyright 2001
00454     // by Waldo Bastian.
00455     //
00456     //
00457     QVBox *topcontents = new QVBox(dialog);
00458 
00459     topcontents->setSpacing(KDialog::spacingHint() * 2);
00460     topcontents->setMargin(KDialog::marginHint() * 2);
00461 
00462     QWidget *contents = new QWidget(topcontents);
00463     QHBoxLayout *lay = new QHBoxLayout(contents);
00464 
00465     lay->setSpacing(KDialog::spacingHint() * 2);
00466 
00467     lay->addStretch(1);
00468     QLabel *label1 = new QLabel( contents);
00469     label1->setPixmap(QMessageBox::standardIcon(QMessageBox::Information));
00470     lay->add( label1 );
00471     QLabel *label2 = new QLabel( text, contents);
00472     label2->setMinimumSize(label2->sizeHint());
00473     lay->add(label2);
00474     lay->addStretch(1);
00475 
00476     QSize extraSize = QSize(50, 30);
00477 
00478     QCheckBox *checkbox = 0L;
00479     if (!key.isEmpty())
00480     {
00481         checkbox = new QCheckBox(i18n("Do not ask again"),topcontents);
00482         extraSize = QSize(50,0);
00483     }
00484 
00485     dialog->setMainWidget(topcontents);
00486     dialog->enableButtonSeparator(false);
00487     dialog->incInitialSize(extraSize);
00488 
00489     r = dialog->exec();
00490     if (checkbox)
00491     {
00492         checkboxReturn = checkbox->isChecked();
00493     }
00494 #endif
00495 
00496     switch(r)
00497     {
00498     case KDialogBase::Yes : result=KMessageBox::Yes ; break;
00499     case KDialogBase::No  : result=KMessageBox::No; break;
00500     case KDialogBase::Cancel : result=KMessageBox::Cancel; break;
00501     default : break;
00502     }
00503     stopTickle();
00504 
00505     if (!key.isEmpty() && checkboxReturn)
00506     {
00507         KMessageBox::saveDontShowAgainYesNo(key,result);
00508     }
00509 
00510     return result;
00511 }
00512