You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1405 lines
32 KiB
1405 lines
32 KiB
/* KPilot
|
|
**
|
|
** Copyright (C) 1998-2001 by Dan Pilone
|
|
** Copyright (C) 2001-2004 by Adriaan de Groot
|
|
** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
|
|
**
|
|
** This is the KPilot Daemon, which does the actual communication with
|
|
** the Pilot and with the conduits.
|
|
*/
|
|
|
|
/*
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 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 General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU 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 kde-pim@kde.org
|
|
*/
|
|
|
|
#include "options.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <tqtimer.h>
|
|
#include <tqtooltip.h>
|
|
#include <tqpixmap.h>
|
|
|
|
#include <kuniqueapplication.h>
|
|
#include <tdeaboutapplication.h>
|
|
#include <tdecmdlineargs.h>
|
|
#include <twin.h>
|
|
#include <kurl.h>
|
|
#include <tdepopupmenu.h>
|
|
#include <kiconloader.h>
|
|
#include <kdebug.h>
|
|
#include <kprocess.h>
|
|
#include <dcopclient.h>
|
|
#include <kurldrag.h>
|
|
#include <kservice.h>
|
|
#include <tdeapplication.h>
|
|
#include <khelpmenu.h>
|
|
|
|
#include "pilotRecord.h"
|
|
|
|
#include "fileInstaller.h"
|
|
#include "pilotUser.h"
|
|
#include "pilotDatabase.h"
|
|
#include "kpilotlink.h"
|
|
#include "kpilotdevicelink.h"
|
|
#include "actionQueue.h"
|
|
#include "actions.h"
|
|
|
|
#include "hotSync.h"
|
|
#include "internalEditorAction.h"
|
|
#include "logFile.h"
|
|
|
|
#include "kpilotConfig.h"
|
|
|
|
|
|
#include "kpilotDCOP_stub.h"
|
|
#include "kpilotDCOP.h"
|
|
#include "loggerDCOP_stub.h"
|
|
|
|
#include "pilotDaemon.moc"
|
|
|
|
static TDEAboutData *aboutData = 0L;
|
|
|
|
PilotDaemonTray::PilotDaemonTray(PilotDaemon * p) :
|
|
KSystemTray(0, "pilotDaemon"),
|
|
fSyncTypeMenu(0L),
|
|
daemon(p),
|
|
kap(0L),
|
|
fBlinkTimer(0L)
|
|
{
|
|
FUNCTIONSETUP;
|
|
setupWidget();
|
|
setAcceptDrops(true);
|
|
}
|
|
|
|
/* virtual */ void PilotDaemonTray::dragEnterEvent(TQDragEnterEvent * e)
|
|
{
|
|
FUNCTIONSETUP;
|
|
e->accept(KURLDrag::canDecode(e));
|
|
}
|
|
|
|
/* virtual */ void PilotDaemonTray::dropEvent(TQDropEvent * e)
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
KURL::List list;
|
|
|
|
KURLDrag::decode(e, list);
|
|
|
|
TQStringList files;
|
|
for(KURL::List::ConstIterator it = list.begin(); it != list.end(); ++it)
|
|
{
|
|
if ((*it).isLocalFile())
|
|
files << (*it).path();
|
|
}
|
|
|
|
daemon->addInstallFiles(files);
|
|
}
|
|
|
|
/* virtual */ void PilotDaemonTray::mousePressEvent(TQMouseEvent * e)
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
switch (e->button())
|
|
{
|
|
case TQt::RightButton:
|
|
{
|
|
TDEPopupMenu *menu = contextMenu();
|
|
contextMenuAboutToShow(menu);
|
|
menu->popup(e->globalPos());
|
|
}
|
|
break;
|
|
case TQt::LeftButton:
|
|
if (daemon) daemon->slotRunKPilot();
|
|
break;
|
|
default:
|
|
KSystemTray::mousePressEvent(e);
|
|
}
|
|
}
|
|
|
|
/* virtual */ void PilotDaemonTray::closeEvent(TQCloseEvent *)
|
|
{
|
|
FUNCTIONSETUP;
|
|
daemon->quitNow();
|
|
}
|
|
|
|
void PilotDaemonTray::setupWidget()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
TDEGlobal::iconLoader()->addAppDir( CSL1("kpilot") );
|
|
icons[Normal] = loadIcon( CSL1("kpilotDaemon") );
|
|
icons[Busy] = loadIcon( CSL1("busysync") );
|
|
icons[NotListening] = loadIcon( CSL1("nosync") );
|
|
|
|
slotShowNotListening();
|
|
TQTimer::singleShot(2000,this,TQ_SLOT(slotShowNormal()));
|
|
|
|
TDEPopupMenu *menu = contextMenu();
|
|
|
|
menuKPilotItem = menu->insertItem(i18n("Start &KPilot"), daemon,
|
|
TQ_SLOT(slotRunKPilot()));
|
|
menuConfigureConduitsItem = menu->insertItem(i18n("&Configure KPilot..."),
|
|
daemon, TQ_SLOT(slotRunConfig()));
|
|
menu->insertSeparator();
|
|
|
|
fSyncTypeMenu = new TDEPopupMenu(menu,"sync_type_menu");
|
|
TQString once = i18n("Appended to names of sync types to indicate the sync will happen just one time"," (once)");
|
|
#define MI(a) fSyncTypeMenu->insertItem( \
|
|
SyncAction::SyncMode::name(SyncAction::SyncMode::a) + once, \
|
|
(int)(SyncAction::SyncMode::a));
|
|
fSyncTypeMenu->insertItem(i18n("Default (%1)")
|
|
.arg(SyncAction::SyncMode::name((SyncAction::SyncMode::Mode)KPilotSettings::syncType())),
|
|
0);
|
|
fSyncTypeMenu->insertSeparator();
|
|
|
|
// Keep this synchronized with kpilotui.rc and kpilot.cpp if at all possible.
|
|
MI(eHotSync);
|
|
MI(eFullSync);
|
|
MI(eBackup);
|
|
MI(eRestore);
|
|
MI(eCopyHHToPC);
|
|
MI(eCopyPCToHH);
|
|
|
|
fSyncTypeMenu->setCheckable(true);
|
|
fSyncTypeMenu->setItemChecked(0,true);
|
|
#undef MI
|
|
connect(fSyncTypeMenu,TQ_SIGNAL(activated(int)),daemon,TQ_SLOT(requestSync(int)));
|
|
menu->insertItem(i18n("Next &Sync"),fSyncTypeMenu);
|
|
|
|
KHelpMenu *help = new KHelpMenu(menu,aboutData);
|
|
menu->insertItem(
|
|
TDEGlobal::iconLoader()->loadIconSet(CSL1("help"),TDEIcon::Small,0,true),
|
|
i18n("&Help"),help->menu(),false /* no whatsthis */);
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname << ": Finished getting icons" << endl;
|
|
#endif
|
|
}
|
|
|
|
void PilotDaemonTray::slotShowAbout()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
if (!kap)
|
|
{
|
|
kap = new TDEAboutApplication(0, "kpdab", false);
|
|
}
|
|
|
|
kap->show();
|
|
}
|
|
|
|
|
|
void PilotDaemonTray::enableRunKPilot(bool b)
|
|
{
|
|
FUNCTIONSETUP;
|
|
contextMenu()->setItemEnabled(menuKPilotItem, b);
|
|
contextMenu()->setItemEnabled(menuConfigureConduitsItem, b);
|
|
}
|
|
|
|
|
|
void PilotDaemonTray::changeIcon(IconShape i)
|
|
{
|
|
FUNCTIONSETUP;
|
|
if (icons[i].isNull())
|
|
{
|
|
WARNINGKPILOT << "Icon #"<<i<<" is NULL!" << endl;
|
|
}
|
|
setPixmap(icons[i]);
|
|
fCurrentIcon = i;
|
|
}
|
|
|
|
void PilotDaemonTray::slotShowNormal()
|
|
{
|
|
FUNCTIONSETUP;
|
|
changeIcon(Normal);
|
|
}
|
|
|
|
void PilotDaemonTray::slotShowBusy()
|
|
{
|
|
FUNCTIONSETUP;
|
|
changeIcon(Busy);
|
|
}
|
|
|
|
void PilotDaemonTray::slotShowNotListening()
|
|
{
|
|
FUNCTIONSETUP;
|
|
changeIcon( NotListening );
|
|
}
|
|
|
|
void PilotDaemonTray::slotBusyTimer()
|
|
{
|
|
if (fCurrentIcon == Busy) changeIcon(Normal);
|
|
else if (fCurrentIcon == Normal) changeIcon(Busy);
|
|
}
|
|
|
|
void PilotDaemonTray::startHotSync()
|
|
{
|
|
changeIcon(Busy);
|
|
if (!fBlinkTimer)
|
|
{
|
|
fBlinkTimer = new TQTimer(this,"blink timer");
|
|
}
|
|
if (fBlinkTimer)
|
|
{
|
|
connect(fBlinkTimer,TQ_SIGNAL(timeout()),
|
|
this,TQ_SLOT(slotBusyTimer()));
|
|
fBlinkTimer->start(750,false);
|
|
}
|
|
}
|
|
|
|
void PilotDaemonTray::endHotSync()
|
|
{
|
|
changeIcon(Normal);
|
|
if (fBlinkTimer)
|
|
{
|
|
fBlinkTimer->stop();
|
|
}
|
|
}
|
|
|
|
|
|
PilotDaemon::PilotDaemon() :
|
|
DCOPObject("KPilotDaemonIface"),
|
|
fDaemonStatus(INIT),
|
|
fPostSyncAction(None),
|
|
fPilotLink(0L),
|
|
fNextSyncType(SyncAction::SyncMode::eHotSync,true),
|
|
fSyncStack(0L),
|
|
fTray(0L),
|
|
fInstaller(0L),
|
|
fLogFile(0L),
|
|
fLogStub(new LoggerDCOP_stub("kpilot", "LogIface")),
|
|
fLogFileStub(new LoggerDCOP_stub("kpilotDaemon", "LogIface")),
|
|
fKPilotStub(new KPilotDCOP_stub("kpilot", "KPilotIface")),
|
|
fTempDevice(TQString())
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
setupPilotLink();
|
|
reloadSettings();
|
|
|
|
if (fDaemonStatus == ERROR)
|
|
{
|
|
WARNINGKPILOT << "Connecting to device failed." << endl;
|
|
return;
|
|
}
|
|
|
|
fInstaller = new FileInstaller;
|
|
fLogFile = new LogFile;
|
|
connect(fInstaller, TQ_SIGNAL(filesChanged()),
|
|
this, TQ_SLOT(slotFilesChanged()));
|
|
|
|
fNextSyncType.setMode( KPilotSettings::syncType() );
|
|
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname
|
|
<< ": The daemon is ready with status "
|
|
<< statusString() << " (" << (int) fDaemonStatus << ")" << endl;
|
|
#endif
|
|
}
|
|
|
|
PilotDaemon::~PilotDaemon()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
KPILOT_DELETE(fPilotLink);
|
|
KPILOT_DELETE(fSyncStack);
|
|
KPILOT_DELETE(fInstaller);
|
|
|
|
(void) PilotDatabase::instanceCount();
|
|
}
|
|
|
|
void PilotDaemon::addInstallFiles(const TQStringList &l)
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
fInstaller->addFiles( l, fTray );
|
|
}
|
|
|
|
int PilotDaemon::getPilotSpeed()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
int speed = KPilotSettings::pilotSpeed();
|
|
|
|
// Translate the speed entry in the
|
|
// config file to something we can
|
|
// put in the environment (for who?)
|
|
//
|
|
//
|
|
const char *speedname = 0L;
|
|
|
|
switch (speed)
|
|
{
|
|
case 0:
|
|
speedname = "PILOTRATE=9600";
|
|
break;
|
|
case 1:
|
|
speedname = "PILOTRATE=19200";
|
|
break;
|
|
case 2:
|
|
speedname = "PILOTRATE=38400";
|
|
break;
|
|
case 3:
|
|
speedname = "PILOTRATE=57600";
|
|
break;
|
|
case 4:
|
|
speedname = "PILOTRATE=115200";
|
|
break;
|
|
default:
|
|
speedname = "PILOTRATE=9600";
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname
|
|
<< ": Speed set to "
|
|
<< speedname << " (" << speed << ")" << endl;
|
|
#endif
|
|
|
|
putenv((char *) speedname);
|
|
|
|
return speed;
|
|
}
|
|
|
|
|
|
void PilotDaemon::showTray()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
if (!fTray)
|
|
{
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname << ": No tray icon to display!" << endl;
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
// Copied from Klipper
|
|
KWin::setSystemTrayWindowFor(fTray->winId(), 0);
|
|
fTray->setGeometry(-100, -100, 42, 42);
|
|
fTray->show();
|
|
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname << ": Tray icon displayed." << endl;
|
|
#endif
|
|
|
|
updateTrayStatus();
|
|
}
|
|
|
|
/* DCOP ASYNC */ void PilotDaemon::setTempDevice(TQString d)
|
|
{
|
|
if ( !d.isEmpty() ){
|
|
fTempDevice = d;
|
|
if (fPilotLink)
|
|
fPilotLink->setTempDevice( fTempDevice );
|
|
reloadSettings();
|
|
}
|
|
}
|
|
|
|
/* DCOP ASYNC */ void PilotDaemon::reloadSettings()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
switch (fDaemonStatus)
|
|
{
|
|
case INIT:
|
|
case HOTSYNC_END:
|
|
case ERROR:
|
|
case READY:
|
|
case NOT_LISTENING:
|
|
// It's OK to reload settings in these states.
|
|
break;
|
|
case HOTSYNC_START:
|
|
case FILE_INSTALL_REQ:
|
|
// Postpone the reload till the sync finishes.
|
|
fPostSyncAction |= ReloadSettings;
|
|
return;
|
|
break;
|
|
}
|
|
|
|
// TODO: Is this bunch of calls really necessary to reload the settings???
|
|
delete KPilotSettings::self();
|
|
KPilotSettings::self()->config()->reparseConfiguration();
|
|
KPilotSettings::self()->readConfig();
|
|
getPilotSpeed();
|
|
|
|
(void) Pilot::setupPilotCodec(KPilotSettings::encoding());
|
|
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname
|
|
<< ": Got configuration "
|
|
<< KPilotSettings::pilotDevice()
|
|
<< endl;
|
|
DEBUGKPILOT << fname
|
|
<< ": Got conduit list "
|
|
<< (KPilotSettings::installedConduits().join(CSL1(",")))
|
|
<< endl;
|
|
#endif
|
|
|
|
requestSync(0);
|
|
|
|
|
|
if (fPilotLink)
|
|
{
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname
|
|
<< ": Resetting with device "
|
|
<< KPilotSettings::pilotDevice()
|
|
<< endl;
|
|
#endif
|
|
|
|
fPilotLink->reset( KPilotSettings::pilotDevice() );
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname
|
|
<< ": Using workarounds "
|
|
<< KPilotSettings::workarounds()
|
|
<< endl;
|
|
#endif
|
|
if ( KPilotSettings::workarounds() == KPilotSettings::eWorkaroundUSB )
|
|
{
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname
|
|
<< ": Using Zire31 USB workaround." << endl;
|
|
#endif
|
|
fPilotLink->setWorkarounds(true);
|
|
}
|
|
}
|
|
|
|
if (KPilotSettings::dockDaemon())
|
|
{
|
|
if (!fTray)
|
|
{
|
|
fTray = new PilotDaemonTray(this);
|
|
fTray->show();
|
|
}
|
|
else
|
|
{
|
|
fTray->show();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (fTray)
|
|
{
|
|
fTray->hide();
|
|
delete fTray;
|
|
|
|
fTray = 0L;
|
|
}
|
|
}
|
|
|
|
updateTrayStatus();
|
|
logProgress(TQString(),0);
|
|
}
|
|
|
|
/* DCOP */ void PilotDaemon::stopListening()
|
|
{
|
|
fIsListening=false;
|
|
fTray->changeIcon(PilotDaemonTray::NotListening);
|
|
fDaemonStatus=NOT_LISTENING;
|
|
fPilotLink->close();
|
|
}
|
|
|
|
/* DCOP */ void PilotDaemon::startListening()
|
|
{
|
|
fIsListening=true;
|
|
fTray->changeIcon(PilotDaemonTray::Normal);
|
|
fDaemonStatus=INIT;
|
|
fPilotLink->reset();
|
|
}
|
|
|
|
/* DCOP */ TQString PilotDaemon::statusString()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
TQString s = CSL1("PilotDaemon=");
|
|
s.append(shorStatusString());
|
|
|
|
s.append(CSL1("; NextSync="));
|
|
s.append(fNextSyncType.name());
|
|
|
|
s.append(CSL1(" ("));
|
|
if (fPilotLink)
|
|
{
|
|
s.append(fPilotLink->statusString());
|
|
}
|
|
s.append(CSL1(");"));
|
|
|
|
return s;
|
|
}
|
|
|
|
/* DCOP */ TQString PilotDaemon::shorStatusString()
|
|
{
|
|
TQString s;
|
|
|
|
switch (status())
|
|
{
|
|
case INIT:
|
|
s.append(CSL1("Waiting for sync"));
|
|
break;
|
|
case READY:
|
|
s.append(CSL1("Listening on device"));
|
|
break;
|
|
case ERROR:
|
|
s=CSL1("Error");
|
|
break;
|
|
case FILE_INSTALL_REQ:
|
|
s=CSL1("Installing File");
|
|
break;
|
|
case HOTSYNC_END:
|
|
s=CSL1("End of Hotsync");
|
|
break;
|
|
case HOTSYNC_START:
|
|
s=CSL1("Syncing");
|
|
break;
|
|
case NOT_LISTENING:
|
|
s.append(CSL1("Not Listening (stopped manually)"));
|
|
break;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
bool PilotDaemon::setupPilotLink()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
KPILOT_DELETE(fPilotLink);
|
|
fPilotLink = new KPilotDeviceLink( 0, 0, fTempDevice );
|
|
if (!fPilotLink)
|
|
{
|
|
WARNINGKPILOT << "Can't get pilot link." << endl;
|
|
return false;
|
|
}
|
|
|
|
TQObject::connect(fPilotLink, TQ_SIGNAL(deviceReady(KPilotLink*)),
|
|
this, TQ_SLOT(startHotSync(KPilotLink*)));
|
|
// connect the signals emitted by the pilotDeviceLink
|
|
TQObject::connect(fPilotLink, TQ_SIGNAL(logError(const TQString &)),
|
|
this, TQ_SLOT(logError(const TQString &)));
|
|
TQObject::connect(fPilotLink, TQ_SIGNAL(logMessage(const TQString &)),
|
|
this, TQ_SLOT(logMessage(const TQString &)));
|
|
TQObject::connect(fPilotLink,
|
|
TQ_SIGNAL(logProgress(const TQString &,int)),
|
|
this, TQ_SLOT(logProgress(const TQString &,int)));
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/* DCOP ASYNC */ void PilotDaemon::quitNow()
|
|
{
|
|
FUNCTIONSETUP;
|
|
// Using switch to make sure we cover all the cases.
|
|
//
|
|
//
|
|
switch (fDaemonStatus)
|
|
{
|
|
case INIT:
|
|
case HOTSYNC_END:
|
|
case ERROR:
|
|
case NOT_LISTENING:
|
|
getKPilot().daemonStatus(KPilotDCOP::DaemonQuit);
|
|
kapp->quit();
|
|
break;
|
|
case READY:
|
|
case HOTSYNC_START:
|
|
case FILE_INSTALL_REQ:
|
|
fPostSyncAction |= Quit;
|
|
break;
|
|
}
|
|
emitDCOPSignal( "kpilotDaemonStatusChanged()", TQByteArray() );
|
|
}
|
|
|
|
/* DCOP ASYNC */ void PilotDaemon::requestRegularSyncNext()
|
|
{
|
|
requestSync(SyncAction::SyncMode::eHotSync);
|
|
}
|
|
|
|
|
|
/* DCOP ASYNC */ void PilotDaemon::requestSync(int mode)
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
if ( 0==mode )
|
|
{
|
|
mode = KPilotSettings::syncType();
|
|
}
|
|
|
|
if ( !fNextSyncType.setMode(mode) )
|
|
{
|
|
WARNINGKPILOT << "Ignored fake sync type " << mode << endl;
|
|
return;
|
|
}
|
|
|
|
updateTrayStatus();
|
|
|
|
if (fTray && (fTray->fSyncTypeMenu))
|
|
{
|
|
for (int i=((int)SyncAction::SyncMode::eHotSync);
|
|
i<=((int)SyncAction::SyncMode::eRestore) /* Restore */ ;
|
|
++i)
|
|
{
|
|
fTray->fSyncTypeMenu->setItemChecked(i,mode==i);
|
|
}
|
|
}
|
|
|
|
getLogger().logMessage(i18n("Next HotSync will be: %1. ").arg(fNextSyncType.name()) +
|
|
i18n("Please press the HotSync button."));
|
|
}
|
|
|
|
/* DCOP ASYNC */ void PilotDaemon::requestSyncType(TQString s)
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
// This checks unique prefixes of the names of the various sync types.
|
|
if (s.startsWith(CSL1("H"))) requestSync(SyncAction::SyncMode::eHotSync);
|
|
else if (s.startsWith(CSL1("Fu"))) requestSync(SyncAction::SyncMode::eFullSync);
|
|
else if (s.startsWith(CSL1("B"))) requestSync(SyncAction::SyncMode::eBackup);
|
|
else if (s.startsWith(CSL1("R"))) requestSync(SyncAction::SyncMode::eRestore);
|
|
else if (s.startsWith(CSL1("T"))) { fNextSyncType.setOptions(true,false); }
|
|
else if (s.startsWith(CSL1("CopyHHToPC"))) requestSync(SyncAction::SyncMode::eCopyHHToPC);
|
|
else if (s.startsWith(CSL1("CopyPCToHH"))) requestSync(SyncAction::SyncMode::eCopyPCToHH);
|
|
else if (s.startsWith(CSL1("D"))) requestSync(0);
|
|
else
|
|
{
|
|
WARNINGKPILOT << "Unknown sync type " << ( s.isEmpty() ? CSL1("<none>") : s )
|
|
<< endl;
|
|
}
|
|
}
|
|
|
|
/* DCOP ASYNC */ void PilotDaemon::requestSyncOptions(bool test, bool local)
|
|
{
|
|
if ( !fNextSyncType.setOptions(test,local) )
|
|
{
|
|
WARNINGKPILOT << "Nonsensical request for "
|
|
<< (test ? "test" : "notest")
|
|
<< ' '
|
|
<< (local ? "local" : "nolocal")
|
|
<< " in mode "
|
|
<< fNextSyncType.name() << endl;
|
|
}
|
|
}
|
|
|
|
/* DCOP */ int PilotDaemon::nextSyncType() const
|
|
{
|
|
return fNextSyncType.mode();
|
|
}
|
|
|
|
/**
|
|
* DCOP Functions reporting some status data, e.g. for the kontact plugin.
|
|
*/
|
|
TQDateTime PilotDaemon::lastSyncDate()
|
|
{
|
|
return KPilotSettings::lastSyncTime();
|
|
}
|
|
|
|
|
|
static TQDict<TQString> *conduitNameMap = 0L;
|
|
|
|
static void fillConduitNameMap()
|
|
{
|
|
if ( !conduitNameMap )
|
|
{
|
|
conduitNameMap = new TQDict<TQString>;
|
|
conduitNameMap->setAutoDelete(true);
|
|
}
|
|
conduitNameMap->clear();
|
|
|
|
TQStringList l = KPilotSettings::installedConduits();
|
|
// Fill with internal settings.
|
|
if ( l.find( CSL1("internal_fileinstall") ) != l.end() ) {
|
|
conduitNameMap->insert( CSL1("internal_fileinstall"),
|
|
new TQString(i18n("File Installer")) );
|
|
}
|
|
|
|
TQStringList::ConstIterator end = l.end();
|
|
for (TQStringList::ConstIterator i = l.begin(); i != end; ++i)
|
|
{
|
|
if (!conduitNameMap->find(*i))
|
|
{
|
|
TQString readableName = CSL1("<unknown>");
|
|
TDESharedPtr < KService > o = KService::serviceByDesktopName(*i);
|
|
if (!o)
|
|
{
|
|
WARNINGKPILOT << "No service for " << *i << endl;
|
|
}
|
|
else
|
|
{
|
|
readableName = o->name();
|
|
}
|
|
conduitNameMap->insert( *i, new TQString(readableName) );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
TQStringList PilotDaemon::configuredConduitList()
|
|
{
|
|
fillConduitNameMap();
|
|
|
|
TQStringList keys;
|
|
|
|
TQDictIterator<TQString> it(*conduitNameMap);
|
|
for ( ; *it; ++it)
|
|
{
|
|
keys << it.currentKey();
|
|
}
|
|
keys.sort();
|
|
|
|
TQStringList::ConstIterator end = keys.end();
|
|
TQStringList result;
|
|
for (TQStringList::ConstIterator i = keys.begin(); i != end; ++i)
|
|
{
|
|
result << *(conduitNameMap->find(*i));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
TQString PilotDaemon::logFileName()
|
|
{
|
|
return KPilotSettings::logFileName();
|
|
}
|
|
|
|
TQString PilotDaemon::userName()
|
|
{
|
|
return KPilotSettings::userName();
|
|
}
|
|
TQString PilotDaemon::pilotDevice()
|
|
{
|
|
return KPilotSettings::pilotDevice();
|
|
}
|
|
|
|
bool PilotDaemon::killDaemonOnExit()
|
|
{
|
|
return KPilotSettings::killDaemonAtExit();
|
|
}
|
|
|
|
typedef enum { NotLocked=0, Locked=1, DCOPError=2 } KDesktopLockStatus;
|
|
static KDesktopLockStatus isKDesktopLockRunning()
|
|
{
|
|
if (!KPilotSettings::screenlockSecure()) return NotLocked;
|
|
|
|
DCOPClient *dcopptr = TDEApplication::kApplication()->dcopClient();
|
|
|
|
// Can't tell, very weird, err on the side of safety.
|
|
if (!dcopptr || !dcopptr->isAttached())
|
|
{
|
|
WARNINGKPILOT << "Could not make DCOP connection. "
|
|
<< "Assuming screensaver is active." << endl;
|
|
return DCOPError;
|
|
}
|
|
|
|
TQByteArray data,returnValue;
|
|
TQCString returnType;
|
|
|
|
if (!dcopptr->call("kdesktop","KScreensaverIface","isBlanked()",
|
|
data,returnType,returnValue,true))
|
|
{
|
|
WARNINGKPILOT << "Check for screensaver failed."
|
|
<< "Assuming screensaver is active." << endl;
|
|
// Err on the side of safety again.
|
|
return DCOPError;
|
|
}
|
|
|
|
if (returnType == "bool")
|
|
{
|
|
bool b;
|
|
TQDataStream reply(returnValue,IO_ReadOnly);
|
|
reply >> b;
|
|
return (b ? Locked : NotLocked);
|
|
}
|
|
else
|
|
{
|
|
WARNINGKPILOT << "Strange return value from screensaver. "
|
|
<< "Assuming screensaver is active." << endl;
|
|
// Err on the side of safety.
|
|
return DCOPError;
|
|
}
|
|
}
|
|
|
|
|
|
static void informOthers(KPilotDCOP_stub &kpilot,
|
|
LoggerDCOP_stub &log,
|
|
LoggerDCOP_stub &filelog)
|
|
{
|
|
kpilot.daemonStatus(KPilotDCOP::StartOfHotSync);
|
|
log.logStartSync();
|
|
filelog.logStartSync();
|
|
}
|
|
|
|
static bool isSyncPossible(ActionQueue *fSyncStack,
|
|
KPilotLink *pilotLink,
|
|
KPilotDCOP_stub &kpilot)
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
/**
|
|
* If KPilot is busy with something - like configuring
|
|
* conduit - then we shouldn't run a real sync, but
|
|
* just tell the user that the sync couldn't run because
|
|
* of that.
|
|
*/
|
|
int kpilotstatus = kpilot.kpiloStatus();
|
|
DCOPStub::Status callstatus = kpilot.status();
|
|
|
|
#ifdef DEBUG
|
|
if (callstatus != DCOPStub::CallSucceeded)
|
|
{
|
|
DEBUGKPILOT << fname <<
|
|
": Could not call KPilot for status." << endl;
|
|
}
|
|
else
|
|
{
|
|
DEBUGKPILOT << fname << ": KPilot status " << kpilotstatus << endl;
|
|
}
|
|
#endif
|
|
/**
|
|
* If the call fails, then KPilot is probably not running
|
|
* and we can behave normally.
|
|
*/
|
|
if ((callstatus == DCOPStub::CallSucceeded) &&
|
|
(kpilotstatus != KPilotDCOP::WaitingForDaemon))
|
|
{
|
|
WARNINGKPILOT << "KPilot returned status " << kpilotstatus << endl;
|
|
|
|
fSyncStack->queueInit();
|
|
fSyncStack->addAction(new SorryAction(pilotLink));
|
|
return false;
|
|
}
|
|
|
|
switch (isKDesktopLockRunning())
|
|
{
|
|
case NotLocked :
|
|
break; /* Fall through to return true below */
|
|
case Locked :
|
|
fSyncStack->queueInit();
|
|
fSyncStack->addAction(new SorryAction(pilotLink,
|
|
i18n("HotSync is disabled while the screen is locked.")));
|
|
return false;
|
|
case DCOPError :
|
|
fSyncStack->queueInit();
|
|
fSyncStack->addAction(new SorryAction(pilotLink,
|
|
i18n("HotSync is disabled because KPilot could not "
|
|
"determine the state of the screen saver. You "
|
|
"can disable this security feature by unchecking "
|
|
"the 'do not sync when screensaver is active' box "
|
|
"in the HotSync page of the configuration dialog.")));
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void queueInstaller(ActionQueue *fSyncStack,
|
|
KPilotLink *pilotLink,
|
|
FileInstaller *fInstaller,
|
|
const TQStringList &c)
|
|
{
|
|
if (c.findIndex(CSL1("internal_fileinstall")) >= 0)
|
|
{
|
|
fSyncStack->addAction(new FileInstallAction(pilotLink,fInstaller->dir()));
|
|
}
|
|
}
|
|
|
|
static void queueEditors(ActionQueue *fSyncStack, KPilotLink *pilotLink)
|
|
{
|
|
if (KPilotSettings::internalEditors())
|
|
{
|
|
fSyncStack->addAction(new InternalEditorAction(pilotLink));
|
|
}
|
|
}
|
|
|
|
static void queueConduits(ActionQueue *fSyncStack,
|
|
const TQStringList &conduits,
|
|
SyncAction::SyncMode e)
|
|
{
|
|
if (conduits.count() > 0)
|
|
{
|
|
fSyncStack->queueConduits(conduits,e);
|
|
// TQString s = i18n("Conduit flags: ");
|
|
// s.append(ConduitProxy::flagsForMode(e).join(CSL1(" ")));
|
|
// logMessage(s);
|
|
}
|
|
}
|
|
|
|
bool PilotDaemon::shouldBackup()
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
bool ret = false;
|
|
int backupfreq = KPilotSettings::backupFrequency();
|
|
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname << ": Backup Frequency is: [" << backupfreq <<
|
|
"]. " << endl;
|
|
#endif
|
|
|
|
if ( (fNextSyncType == SyncAction::SyncMode::eHotSync) ||
|
|
(fNextSyncType == SyncAction::SyncMode::eFullSync) )
|
|
{
|
|
/** If we're doing a Hot or Full sync, see if our user has
|
|
* configured us to or to not always do a backup.
|
|
*/
|
|
if ( backupfreq == SyncAction::eOnRequestOnly )
|
|
{
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname << ": Should not do backup..." << endl;
|
|
#endif
|
|
ret = false;
|
|
}
|
|
else if ( backupfreq == SyncAction::eEveryHotSync )
|
|
{
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname << ": Should do backup..." << endl;
|
|
#endif
|
|
ret = true;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
/* slot */ void PilotDaemon::startHotSync(KPilotLink *pilotLink)
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
bool pcchanged=false; // If last PC to sync was a different one (implies full sync, normally)
|
|
TQStringList conduits ; // list of conduits to run
|
|
TQString s; // a generic string for stuff
|
|
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname
|
|
<< ": Starting Sync with type "
|
|
<< fNextSyncType.name() << endl;
|
|
DEBUGKPILOT << fname << ": Status is " << shorStatusString() << endl;
|
|
(void) PilotDatabase::instanceCount();
|
|
#endif
|
|
|
|
fDaemonStatus = HOTSYNC_START ;
|
|
if (fTray)
|
|
{
|
|
fTray->startHotSync();
|
|
}
|
|
informOthers(getKPilot(),getLogger(),getFileLogger());
|
|
|
|
|
|
// Queue to add all the actions for this sync to.
|
|
fSyncStack = new ActionQueue(pilotLink);
|
|
|
|
// Check if the sync is possible at all.
|
|
if (!isSyncPossible(fSyncStack,pilotLink,getKPilot()))
|
|
{
|
|
// Sync is not possible now, sorry action was added to
|
|
// the queue, and we run that -- skipping all the rest of the sync stuff.
|
|
goto launch;
|
|
}
|
|
|
|
// Except when the user has requested a Restore, in which case she knows she doesn't
|
|
// want to sync with a blank palm and then back up the result over her stored backup files,
|
|
// do a Full Sync when changing the PC or using a different Palm Desktop app.
|
|
if (fNextSyncType.mode() != SyncAction::SyncMode::eRestore)
|
|
{ // Use gethostid to determine , since JPilot uses 1+(2000000000.0*random()/(RAND_MAX+1.0))
|
|
// as PC_ID, so using JPilot and KPilot is the same as using two different PCs
|
|
KPilotUser &usr = pilotLink->getPilotUser();
|
|
pcchanged = usr.getLastSyncPC() !=(unsigned long) gethostid();
|
|
|
|
if (pcchanged)
|
|
{
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname << ": PC changed. Last sync PC: [" << usr.getLastSyncPC()
|
|
<< "], me: [" << (unsigned long) gethostid() << "]" << endl;
|
|
#endif
|
|
if ( KPilotSettings::fullSyncOnPCChange() )
|
|
{
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname << ": Setting sync mode to full sync. " << endl;
|
|
#endif
|
|
fNextSyncType = SyncAction::SyncMode::eFullSync;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname << ": Not changing sync mode because of settings. " << endl;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
// Normal case: regular sync.
|
|
fSyncStack->queueInit();
|
|
fSyncStack->addAction(new CheckUser(pilotLink));
|
|
|
|
conduits = KPilotSettings::installedConduits() ;
|
|
|
|
if (fNextSyncType.isTest())
|
|
{
|
|
fSyncStack->addAction(new TestLink(pilotLink));
|
|
}
|
|
else
|
|
{
|
|
switch (fNextSyncType.mode())
|
|
{
|
|
case SyncAction::SyncMode::eBackup:
|
|
if (KPilotSettings::runConduitsWithBackup() && (conduits.count() > 0))
|
|
{
|
|
queueConduits(fSyncStack,conduits,fNextSyncType);
|
|
}
|
|
fSyncStack->addAction(new BackupAction(pilotLink,true));
|
|
break;
|
|
case SyncAction::SyncMode::eRestore:
|
|
fSyncStack->addAction(new RestoreAction(pilotLink));
|
|
queueInstaller(fSyncStack,pilotLink,fInstaller,conduits);
|
|
break;
|
|
case SyncAction::SyncMode::eFullSync:
|
|
case SyncAction::SyncMode::eHotSync:
|
|
// first install the files, and only then do the conduits
|
|
// (conduits might want to sync a database that will be installed
|
|
queueInstaller(fSyncStack,pilotLink,fInstaller,conduits);
|
|
queueEditors(fSyncStack,pilotLink);
|
|
queueConduits(fSyncStack,conduits,fNextSyncType);
|
|
// After running the conduits, install new databases
|
|
queueInstaller(fSyncStack,pilotLink,fInstaller,conduits);
|
|
// And sync the remaining databases if needed.
|
|
if (shouldBackup())
|
|
{
|
|
fSyncStack->addAction(new BackupAction(pilotLink, (fNextSyncType == SyncAction::SyncMode::eFullSync)));
|
|
}
|
|
break;
|
|
case SyncAction::SyncMode::eCopyPCToHH:
|
|
queueConduits(fSyncStack,conduits,SyncAction::SyncMode::eCopyPCToHH);
|
|
break;
|
|
case SyncAction::SyncMode::eCopyHHToPC:
|
|
queueConduits(fSyncStack,conduits,SyncAction::SyncMode::eCopyHHToPC);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Jump here to finalize the connections to the sync action
|
|
// queue and start the actual sync.
|
|
launch:
|
|
fSyncStack->queueCleanup();
|
|
|
|
TQObject::connect(fSyncStack, TQ_SIGNAL(logError(const TQString &)),
|
|
this, TQ_SLOT(logError(const TQString &)));
|
|
TQObject::connect(fSyncStack, TQ_SIGNAL(logMessage(const TQString &)),
|
|
this, TQ_SLOT(logMessage(const TQString &)));
|
|
TQObject::connect(fSyncStack,
|
|
TQ_SIGNAL(logProgress(const TQString &,int)),
|
|
this, TQ_SLOT(logProgress(const TQString &,int)));
|
|
|
|
TQObject::connect(fSyncStack, TQ_SIGNAL(syncDone(SyncAction *)),
|
|
this, TQ_SLOT(endHotSync()));
|
|
|
|
TQTimer::singleShot(0,fSyncStack,TQ_SLOT(execConduit()));
|
|
|
|
updateTrayStatus();
|
|
}
|
|
|
|
/* slot */ void PilotDaemon::logMessage(const TQString & s)
|
|
{
|
|
FUNCTIONSETUPL(2);
|
|
|
|
getLogger().logMessage(s);
|
|
getFileLogger().logMessage(s);
|
|
updateTrayStatus(s);
|
|
}
|
|
|
|
/* slot */ void PilotDaemon::logError(const TQString & s)
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
getLogger().logError(s);
|
|
getFileLogger().logError(s);
|
|
updateTrayStatus(s);
|
|
}
|
|
|
|
/* slot */ void PilotDaemon::logProgress(const TQString & s, int i)
|
|
{
|
|
FUNCTIONSETUPL(2);
|
|
|
|
getLogger().logProgress(s, i);
|
|
getFileLogger().logProgress(s, i);
|
|
if (!s.isEmpty()) updateTrayStatus(s);
|
|
}
|
|
|
|
/* slot */ void PilotDaemon::endHotSync()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
if (fTray)
|
|
{
|
|
fTray->endHotSync();
|
|
}
|
|
|
|
KPILOT_DELETE(fSyncStack);
|
|
fPilotLink->close();
|
|
|
|
getLogger().logProgress(i18n("HotSync Completed.<br>"), 100);
|
|
getFileLogger().logProgress(i18n("HotSync Completed.<br>"), 100);
|
|
getLogger().logEndSync();
|
|
getFileLogger().logEndSync();
|
|
getKPilot().daemonStatus(KPilotDCOP::EndOfHotSync);
|
|
KPilotSettings::setLastSyncTime(TQDateTime::currentDateTime());
|
|
KPilotSettings::self()->writeConfig();
|
|
|
|
fDaemonStatus = HOTSYNC_END;
|
|
|
|
if (fPostSyncAction & Quit)
|
|
{
|
|
getKPilot().daemonStatus(KPilotDCOP::DaemonQuit);
|
|
kapp->quit();
|
|
}
|
|
if (fPostSyncAction & ReloadSettings)
|
|
{
|
|
reloadSettings();
|
|
}
|
|
else
|
|
{
|
|
TQTimer::singleShot(10000,fPilotLink,TQ_SLOT(reset()));
|
|
}
|
|
|
|
fPostSyncAction = None;
|
|
requestSync(0);
|
|
|
|
(void) PilotDatabase::instanceCount();
|
|
|
|
updateTrayStatus();
|
|
}
|
|
|
|
|
|
void PilotDaemon::slotFilesChanged()
|
|
{
|
|
FUNCTIONSETUP;
|
|
}
|
|
|
|
void PilotDaemon::slotRunKPilot()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
TQString kpilotError;
|
|
TQCString kpilotDCOP;
|
|
int kpilotPID;
|
|
|
|
if (TDEApplication::startServiceByDesktopName(CSL1("kpilot"),
|
|
TQString(), &kpilotError, &kpilotDCOP, &kpilotPID
|
|
#if (TDE_VERSION >= 220)
|
|
// Startup notification added in 2.2
|
|
, ""
|
|
#endif
|
|
))
|
|
{
|
|
WARNINGKPILOT << "Couldn't start KPilot! " << kpilotError << endl;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname
|
|
<< ": Started KPilot with DCOP name "
|
|
<< kpilotDCOP << " (pid " << kpilotPID << ")" << endl;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void PilotDaemon::slotRunConfig()
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
// This function tries to send the raise() DCOP call to kpilot.
|
|
// If it succeeds, we can assume kpilot is running and then try
|
|
// to send the configure() DCOP call.
|
|
// If it fails (probably because kpilot isn't running) it tries
|
|
// to call kpilot via TDEProcess (using a command line switch to
|
|
// only bring up the configure dialog).
|
|
//
|
|
// Implementing the function this way catches all cases.
|
|
// ie 1 KPilot running with configure dialog open (raise())
|
|
// 2 KPilot running with dialog NOT open (configureConduits())
|
|
// 3 KPilot NOT running (TDEProcess)
|
|
|
|
DCOPClient *client = kapp->dcopClient();
|
|
|
|
// This DCOP call to kpilot's raise function solves the final case
|
|
// ie when kpilot already has the dialog open
|
|
|
|
if ( client->isApplicationRegistered( "kpilot" ) )
|
|
{
|
|
client->send("kpilot", "kpilot-mainwindow#1", "raise()",TQString());
|
|
client->send("kpilot", "KPilotIface", "configure()", TQString());
|
|
}
|
|
else
|
|
{
|
|
// KPilot not running
|
|
TDEProcess *p = new TDEProcess;
|
|
*p << "kpilot" << "-s";
|
|
|
|
p->start();
|
|
}
|
|
}
|
|
|
|
void PilotDaemon::updateTrayStatus(const TQString &s)
|
|
{
|
|
if (!fTray) return;
|
|
|
|
TQString tipText = CSL1("<qt>");
|
|
tipText.append( s );
|
|
tipText.append( CSL1(" ") );
|
|
tipText.append( i18n("Next sync is %1.")
|
|
.arg( fNextSyncType.name() ) );
|
|
tipText.append( CSL1("</qt>") );
|
|
|
|
TQToolTip::remove(fTray);
|
|
TQToolTip::add(fTray,tipText);
|
|
emitDCOPSignal( "kpilotDaemonStatusChanged()", TQByteArray() );
|
|
// emit the same dcop signal but including the information needed by Kontact to update its kpilot summary widget
|
|
TQByteArray data;
|
|
TQDataStream arg(data, IO_WriteOnly);
|
|
arg << lastSyncDate();
|
|
arg << shorStatusString();
|
|
arg << configuredConduitList();
|
|
arg << logFileName();
|
|
arg << userName();
|
|
arg << pilotDevice();
|
|
arg << killDaemonOnExit();
|
|
emitDCOPSignal( "kpilotDaemonStatusDetails(TQDateTime,TQString,TQStringList,TQString,TQString,TQString,bool)", data );
|
|
}
|
|
|
|
static TDECmdLineOptions daemonoptions[] = {
|
|
#ifdef DEBUG
|
|
{"debug <level>", I18N_NOOP("Set debugging level"), "0"},
|
|
#endif
|
|
{ "device <device>", I18N_NOOP("Device to try first"), ""},
|
|
{"fail-silently", I18N_NOOP("Exit instead of complaining about bad configuration files"), 0},
|
|
TDECmdLineLastOption
|
|
} ;
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
FUNCTIONSETUP;
|
|
|
|
TDELocale::setMainCatalogue("kpilot");
|
|
|
|
TDEAboutData about("kpilotDaemon",
|
|
I18N_NOOP("KPilot Daemon"),
|
|
KPILOT_VERSION,
|
|
"KPilot - HotSync software for TDE\n\n",
|
|
TDEAboutData::License_GPL,
|
|
"(c) 1998-2000,2001, Dan Pilone (c) 2000-2004, Adriaan de Groot",
|
|
0L,
|
|
"http://www.kpilot.org/"
|
|
);
|
|
about.addAuthor("Dan Pilone",
|
|
I18N_NOOP("Project Leader"),
|
|
"pilone@slac.com");
|
|
about.addAuthor("Adriaan de Groot",
|
|
I18N_NOOP("Maintainer"),
|
|
"groot@kde.org", "http://www.kpilot.org/");
|
|
about.addAuthor("Reinhold Kainhofer",
|
|
I18N_NOOP("Developer"),
|
|
"reinhold@kainhofer.com", "http://reinhold.kainhofer.com/Linux/");
|
|
aboutData = &about;
|
|
|
|
|
|
TDECmdLineArgs::init(argc, argv, &about);
|
|
TDECmdLineArgs::addCmdLineOptions(daemonoptions,"kpilotconfig");
|
|
KUniqueApplication::addCmdLineOptions();
|
|
TDECmdLineArgs *p = TDECmdLineArgs::parsedArgs();
|
|
|
|
#ifdef DEBUG
|
|
KPilotConfig::getDebugLevel(p);
|
|
#endif
|
|
if (!KUniqueApplication::start())
|
|
{
|
|
if (p->isSet("device")){
|
|
// tell the running kpilotDaemon to use
|
|
// this device now
|
|
DCOPClient d;
|
|
TQString dev(p->getOption("device"));
|
|
TQByteArray data;
|
|
TQDataStream arg(data, IO_WriteOnly);
|
|
arg << dev;
|
|
if (d.attach()){
|
|
d.send("kpilotDaemon", "KPilotDaemonIface", "setTempDevice(TQString)", data );
|
|
d.detach();
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
KUniqueApplication a(true, true);
|
|
|
|
// A block just to keep variables local.
|
|
//
|
|
//
|
|
{
|
|
// KPilotSettings::self()->config()->setReadOnly(false);
|
|
|
|
if (KPilotSettings::configVersion() < KPilotConfig::ConfigurationVersion)
|
|
{
|
|
WARNINGKPILOT << "Is still not configured for use."
|
|
<< endl;
|
|
if (!p->isSet("fail-silently"))
|
|
{
|
|
KPilotConfig::sorryVersionOutdated(KPilotSettings::configVersion());
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
DEBUGKPILOT << fname
|
|
<< ": Configuration version "
|
|
<< KPilotSettings::configVersion() << endl;
|
|
#endif
|
|
}
|
|
|
|
|
|
PilotDaemon *gPilotDaemon = new PilotDaemon();
|
|
|
|
if (p->isSet("device"))
|
|
gPilotDaemon->setTempDevice(p->getOption("device"));
|
|
|
|
if (gPilotDaemon->status() == PilotDaemon::ERROR)
|
|
{
|
|
delete gPilotDaemon;
|
|
|
|
gPilotDaemon = 0;
|
|
WARNINGKPILOT << "Failed to start up daemon "
|
|
"due to errors constructing it." << endl;
|
|
return 2;
|
|
}
|
|
|
|
gPilotDaemon->showTray();
|
|
|
|
return a.exec();
|
|
}
|
|
|
|
|
|
|