kpilot/lib

syncAction.cc

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