00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "options.h"
00034
00035
00036 #include <stdio.h>
00037 #include <unistd.h>
00038
00039 #ifndef QDIR_H
00040 #include <qdir.h>
00041 #endif
00042 #ifndef QHBOX_H
00043 #include <qhbox.h>
00044 #endif
00045 #include <qwhatsthis.h>
00046 #include <qheader.h>
00047
00048 #ifndef _KSIMPLECONFIG_H
00049 #include <ksimpleconfig.h>
00050 #endif
00051 #ifndef _KAPP_H
00052 #include <kapplication.h>
00053 #endif
00054 #ifndef _KPROCESS_H
00055 #include <kprocess.h>
00056 #endif
00057 #ifndef _KMESSAGEBOX_H
00058 #include <kmessagebox.h>
00059 #endif
00060 #ifndef _KSTDDIRS_H
00061 #include <kstddirs.h>
00062 #endif
00063 #ifndef _KDEBUG_H
00064 #include <kdebug.h>
00065 #endif
00066 #ifndef _KUSERPROFILE_H
00067 #include <kuserprofile.h>
00068 #endif
00069 #ifndef _KSERVICE_H
00070 #include <kservice.h>
00071 #endif
00072 #ifndef _KSERVICETYPE_H
00073 #include <kservicetype.h>
00074 #endif
00075
00076 #ifndef _KPILOT_KPILOTCONFIG_H
00077 #include "kpilotConfig.h"
00078 #endif
00079
00080 #include "conduitSetup.moc"
00081
00082
00083 static const char *conduitsetup_id =
00084 "$Id: conduitSetup.cc,v 1.42 2003/07/11 19:18:19 kainhofe Exp $";
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 #define CONDUIT_NAME (0)
00098 #define CONDUIT_COMMENT (1)
00099 #define CONDUIT_DESKTOP (2)
00100 #define CONDUIT_EXEC (3)
00101
00102 CConduitSetup::CConduitSetup(QWidget * parent,
00103 const char *name) :
00104 KDialogBase(parent, name, true,
00105 i18n("External Conduit Setup"),
00106 User1 | User2 | User3 | Ok | Cancel, Cancel,
00107 true,
00108 i18n("Activate"),
00109 i18n("Deactivate"),
00110 i18n("Configure")),
00111 conduitSetup(0L)
00112 {
00113 FUNCTIONSETUP;
00114
00115 QHBox *top = makeHBoxMainWidget();
00116
00117 categories = new ListCategorizer(top, "conduits");
00118 categories->setStartOpen(true);
00119
00120 active = categories->addCategory(i18n("Active"),
00121 i18n("Conduits that will run when a HotSync is done"));
00122 available = categories->addCategory(i18n("Available"),
00123 i18n("Conduits installed on your system but not active"));
00124
00125 categories->adjustSize();
00126 categories->setColumnWidthMode(CONDUIT_COMMENT,QListView::Manual);
00127 categories->header()->setResizeEnabled(false,CONDUIT_COMMENT);
00128
00129 connect(categories, SIGNAL(selectionChanged(QListViewItem *)),
00130 this, SLOT(conduitSelected(QListViewItem *)));
00131
00132 QWhatsThis::add(categories,
00133 i18n("You can drag and drop conduits between the\n"
00134 "active and available groups. Only the conduits\n"
00135 "in the active group will run when you do a HotSync."));
00136
00137
00138 fillLists();
00139 adjustSize();
00140 conduitSelected(0L);
00141
00142 conduitPaths = KGlobal::dirs()->resourceDirs("conduits");
00143 }
00144
00145 CConduitSetup::~CConduitSetup()
00146 {
00147 FUNCTIONSETUP;
00148 }
00149
00150 void CConduitSetup::slotUser1()
00151 {
00152 FUNCTIONSETUP;
00153
00154 QListViewItem *p = categories->selectedItem();
00155
00156 if (!p)
00157 {
00158 #ifdef DEBUG
00159 DEBUGKPILOT << fname
00160 << ": No item selected, but activate clicked?"
00161 << endl;
00162 #endif
00163 return;
00164 }
00165
00166 if (p->parent() != available)
00167 {
00168 #ifdef DEBUG
00169 DEBUGKPILOT << fname
00170 << ": Active conduit selected, but activate clicked?"
00171 << endl;
00172 #endif
00173 return;
00174 }
00175
00176 categories->moveItem(p,active,0L);
00177 categories->setSelected(p,true);
00178 categories->ensureItemVisible(p);
00179
00180 conduitSelected(p);
00181 }
00182
00183 void CConduitSetup::slotUser2()
00184 {
00185 FUNCTIONSETUP;
00186
00187 QListViewItem *p = categories->selectedItem();
00188
00189 if (!p)
00190 {
00191 #ifdef DEBUG
00192 DEBUGKPILOT << fname
00193 << ": No item selected, but activate clicked?"
00194 << endl;
00195 #endif
00196 return;
00197 }
00198
00199 if (p->parent() != active)
00200 {
00201 #ifdef DEBUG
00202 DEBUGKPILOT << fname
00203 << ": InActive conduit selected, but deactivate clicked?"
00204 << endl;
00205 #endif
00206 return;
00207 }
00208
00209 categories->moveItem(p,available,0L);
00210 categories->setSelected(p,true);
00211 categories->ensureItemVisible(p);
00212
00213 conduitSelected(p);
00214 }
00215
00216 void CConduitSetup::slotUser3()
00217 {
00218 FUNCTIONSETUP;
00219
00220 QListViewItem *p = categories->selectedItem();
00221
00222 if (!p)
00223 {
00224 #ifdef DEBUG
00225 DEBUGKPILOT << fname
00226 << ": No item selected, but configure clicked?"
00227 << endl;
00228 #endif
00229 return;
00230 }
00231
00232 if (p->parent() != active)
00233 {
00234 #ifdef DEBUG
00235 DEBUGKPILOT << fname
00236 << ": Inactive conduti selected, but configure clicked?"
00237 << endl;
00238 #endif
00239 return;
00240 }
00241
00242 conduitExecuted(p);
00243 }
00244
00245 void CConduitSetup::conduitExecuted(QListViewItem * p)
00246 {
00247 FUNCTIONSETUP;
00248 if (!p)
00249 {
00250 #ifdef DEBUG
00251 DEBUGKPILOT << fname << ": Executed NULL conduit?" << endl;
00252 #endif
00253 return;
00254 }
00255
00256 if (!p->parent())
00257 {
00258 #ifdef DEBUG
00259 DEBUGKPILOT << fname << ": Executed a category?" << endl;
00260 #endif
00261 return;
00262 }
00263
00264 #ifdef DEBUG
00265 DEBUGKPILOT << fname << ": Executing conduit " << p->text(0) << endl;
00266 #endif
00267
00268 QString execPath = findExecPath(p);
00269
00270 #ifdef DEBUG
00271 DEBUGKPILOT << fname << ": Exec path=" << execPath << endl;
00272 #endif
00273
00274 if (execPath.isNull())
00275 {
00276 warnNoExec(p);
00277 return;
00278 }
00279
00280 if (conduitSetup)
00281 {
00282 warnSetupRunning();
00283 return;
00284 }
00285
00286 conduitSetup = new KProcess;
00287 *conduitSetup << execPath << "--setup";
00288 *conduitSetup << "-geometry"
00289 << CSL1("+%1+%2").arg(x() + 20).arg(y() + 20);
00290 #ifdef DEBUG
00291 if (debug_level)
00292 {
00293 *conduitSetup << "--debug" << QString::number(debug_level);
00294 }
00295 #endif
00296
00297 connect(conduitSetup,
00298 SIGNAL(processExited(KProcess *)),
00299 this, SLOT(setupDone(KProcess *)));
00300 if (!conduitSetup->start(KProcess::NotifyOnExit))
00301 {
00302 kdWarning() << k_funcinfo
00303 << ": Could not start process for conduit setup!"
00304 << endl;
00305 warnNoExec(p);
00306 delete conduitSetup;
00307
00308 conduitSetup = 0L;
00309 }
00310 }
00311
00312 void CConduitSetup::setupDone(KProcess * p)
00313 {
00314 FUNCTIONSETUP;
00315
00316 if (p != conduitSetup)
00317 {
00318 #ifdef DEBUG
00319 DEBUGKPILOT << fname << ": Process other than setup exited?"
00320 << endl;
00321 #endif
00322 return;
00323 }
00324
00325 delete p;
00326
00327 conduitSetup = 0L;
00328 }
00329
00330 void CConduitSetup::slotOk()
00331 {
00332 FUNCTIONSETUP;
00333 writeInstalledConduits();
00334 KDialogBase::slotOk();
00335 }
00336
00337 void CConduitSetup::fillLists()
00338 {
00339 FUNCTIONSETUP;
00340
00341 QStringList potentiallyInstalled =
00342 KPilotConfig::getConfig().setConduitGroup().
00343 getInstalledConduits();
00344 KServiceTypeProfile::OfferList offers =
00345 KServiceTypeProfile::offers(CSL1("KPilotConduit"));
00346
00347 #ifdef DEBUG
00348 {
00349 QStringList::Iterator i = potentiallyInstalled.begin();
00350
00351
00352 DEBUGKPILOT << fname
00353 << ": Currently active conduits are:" << endl;
00354
00355 while (i != potentiallyInstalled.end())
00356 {
00357 DEBUGKPILOT << fname << ": " << (*i) << endl;
00358 ++i;
00359 }
00360
00361 DEBUGKPILOT << fname
00362 << ": Currently installed conduits are:" << endl;
00363 }
00364 #endif
00365
00366
00367
00368
00369
00370 QValueListIterator < KServiceOffer > availList(offers.begin());
00371 while (availList != offers.end())
00372 {
00373 KSharedPtr < KService > o = (*availList).service();
00374
00375 #ifdef DEBUG
00376 DEBUGKPILOT << fname << ": "
00377 << o->desktopEntryName()
00378 << " = " << o->name() << endl;
00379 #endif
00380
00381 RichListViewItem *p = 0L;
00382
00383 if (potentiallyInstalled.contains(o->desktopEntryName()) == 0)
00384 {
00385 p=new RichListViewItem(available,o->name(),6);
00386 }
00387 else
00388 {
00389 p=new RichListViewItem(active,o->name(),6);
00390 }
00391 if (p)
00392 {
00393 p->setText(CONDUIT_COMMENT,o->comment());
00394 p->setText(CONDUIT_DESKTOP,o->desktopEntryName());
00395 p->setText(CONDUIT_EXEC,o->exec());
00396
00397 p->setRich(CONDUIT_COMMENT,true);
00398 }
00399
00400 ++availList;
00401 }
00402 }
00403
00404
00405 QString CConduitSetup::findExecPath(const QListViewItem * p) const
00406 {
00407 FUNCTIONSETUP;
00408
00409 QString currentConduit(QString::null);
00410
00411 if (conduitPaths.isEmpty())
00412 {
00413 currentConduit = KGlobal::dirs()->findResource("exe",
00414 p->text(CONDUIT_EXEC));
00415 if (currentConduit.isNull())
00416 {
00417 currentConduit = p->text(CONDUIT_EXEC);
00418 }
00419 }
00420 else
00421 {
00422
00423
00424
00425
00426 QStringList::ConstIterator i;
00427
00428 currentConduit = QString::null;
00429 for (i = conduitPaths.begin(); i != conduitPaths.end(); ++i)
00430 {
00431 if (QFile::exists((*i) + '/' + p->text(CONDUIT_EXEC)))
00432 {
00433 currentConduit =
00434 (*i) + '/' + p->text(CONDUIT_EXEC);
00435 break;
00436 }
00437 }
00438 }
00439
00440 return currentConduit;
00441 }
00442
00443
00444 void CConduitSetup::writeInstalledConduits()
00445 {
00446 FUNCTIONSETUP;
00447
00448 char dbName[255];
00449 int len = 0;
00450
00451 KPilotConfigSettings & config = KPilotConfig::getConfig();
00452
00453 config.setConduitGroup().setInstalledConduits(
00454 categories->listSiblings(active->firstChild(), CONDUIT_DESKTOP));
00455 config.setDatabaseGroup();
00456
00457 const QListViewItem *p = active->firstChild();
00458
00459 while (p)
00460 {
00461 FILE *conduitpipe;
00462
00463 #ifdef DEBUG
00464 DEBUGKPILOT << fname
00465 << ": Current conduit = "
00466 << p->text(CONDUIT_NAME) << endl;
00467 DEBUGKPILOT << fname
00468 << ": Current conduit service from "
00469 << p->text(CONDUIT_DESKTOP)
00470 << " says exec=" << p->text(CONDUIT_EXEC) << endl;
00471 #endif
00472
00473 QString currentConduit = findExecPath(p);
00474
00475 if (currentConduit.isNull())
00476 {
00477 warnNoExec(p);
00478 goto nextConduit;
00479 }
00480
00481
00482
00483 currentConduit += CSL1(" --info");
00484 #ifdef DEBUG
00485 if (debug_level)
00486 {
00487 currentConduit += CSL1(" --debug ");
00488 currentConduit += QString().setNum(debug_level);
00489 }
00490
00491 DEBUGKPILOT << fname
00492 << ": Conduit startup command line is: "
00493 << currentConduit << endl;
00494 #endif
00495
00496 len = 0;
00497 conduitpipe = popen(currentConduit.local8Bit(), "r");
00498 if (conduitpipe)
00499 {
00500 len = fread(dbName, 1, 255, conduitpipe);
00501 pclose(conduitpipe);
00502 }
00503 conduitpipe = 0;
00504 dbName[len] = 0L;
00505 if (len == 0)
00506 {
00507 QString tmpMessage =
00508 i18n("The conduit %1 did not identify "
00509 "what database it supports. "
00510 "\nPlease check with the conduits "
00511 "author to correct it.").arg(p->
00512 text(CONDUIT_NAME));
00513
00514
00515
00516 KMessageBox::error(this, tmpMessage,
00517 i18n("Conduit Error"));
00518 }
00519 else if (strcmp(dbName, "<none>") == 0)
00520 {
00521 #ifdef DEBUG
00522 DEBUGKPILOT << fname
00523 << ": Conduit "
00524 << p->text(0)
00525 << " supports no databases." << endl;
00526 #endif
00527 }
00528 else
00529 {
00530 QStringList l = QStringList::split(QChar(','),
00531 QString(QString::fromLatin1(dbName)));
00532
00533 QStringList::Iterator i;
00534 const QString & m = p->text(CONDUIT_DESKTOP);
00535
00536 for (i = l.begin(); i != l.end(); ++i)
00537 {
00538 config.setDatabaseConduit((*i).
00539 stripWhiteSpace(), m);
00540 }
00541 }
00542 nextConduit:
00543 p = p->nextSibling();
00544 }
00545 config.sync();
00546 }
00547
00548 void CConduitSetup::conduitSelected(QListViewItem *p)
00549 {
00550 FUNCTIONSETUP;
00551
00552 if (!p)
00553 {
00554 enableButton(User1,false);
00555 enableButton(User2,false);
00556 enableButton(User3,false);
00557 return;
00558 }
00559
00560 if (!p->parent())
00561 {
00562 #ifdef DEBUG
00563 DEBUGKPILOT << fname
00564 << ": Selected a category?"
00565 << endl;
00566 #endif
00567 return;
00568 }
00569
00570
00571 if (p->parent() == active)
00572 {
00573 enableButton(User1,false);
00574 enableButton(User2,true);
00575 enableButton(User3,true);
00576 }
00577 else
00578 {
00579 enableButton(User1,true);
00580 enableButton(User2,false);
00581 enableButton(User3,false);
00582 }
00583 }
00584
00585
00586
00587 void CConduitSetup::warnNoExec(const QListViewItem * p)
00588 {
00589 FUNCTIONSETUP;
00590
00591 QString msg = i18n("No executable could be "
00592 "found for the conduit %1.").arg(p->text(CONDUIT_NAME));
00593
00594 #ifdef DEBUG
00595 DEBUGKPILOT << fname << ": " << msg << endl;
00596 #endif
00597
00598 KMessageBox::error(this, msg, i18n("Conduit Error"));
00599 }
00600
00601 void CConduitSetup::warnSetupRunning()
00602 {
00603 FUNCTIONSETUP;
00604
00605 QString msg = i18n("A conduit is already being set up. "
00606 "Please complete that action before setting "
00607 "up another conduit.");
00608
00609 #ifdef DEBUG
00610 DEBUGKPILOT << fname << ": " << msg << endl;
00611 #endif
00612
00613 KMessageBox::error(this, msg, i18n("Conduit Setup Error"));
00614
00615
00616 (void) conduitsetup_id;
00617 }
00618
00619