kitchensync Library API Documentation

kitchensync.cpp

00001 /*
00002     This file is part of KitchenSync.
00003 
00004     Copyright (c) 2002,2003 Holger Freyther <zecke@handhelds.org>
00005     Copyright (c) 2002,2003 Maximilian Reiß <harlekin@handhelds.org>
00006     Copyright (c) 2003,2004 Cornelius Schumacher <schumacher@kde.org>
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Library General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Library General Public License for more details.
00017 
00018     You should have received a copy of the GNU Library General Public License
00019     along with this library; see the file COPYING.LIB.  If not, write to
00020     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00021     Boston, MA 02111-1307, USA.
00022 */
00023 
00024 #include <qwidgetstack.h>
00025 #include <qlayout.h>
00026 
00027 #include <klocale.h>
00028 #include <kstatusbar.h>
00029 #include <kfiledialog.h>
00030 #include <kdebug.h>
00031 #include <kiconloader.h>
00032 #include <kcmultidialog.h>
00033 
00034 #include <kparts/componentfactory.h>
00035 #include <kpopupmenu.h>
00036 
00037 #include <syncer.h>
00038 #include <syncuikde.h>
00039 
00040 #include <konnectormanager.h>
00041 #include <konnector.h>
00042 #include <error.h>
00043 #include <progress.h>
00044 
00045 #include "syncconfig.h"
00046 #include "configuredialog.h"
00047 #include "partbar.h"
00048 #include "profiledialog.h"
00049 #include "engine.h"
00050 #include "konnectorbar.h"
00051 #include "syncalgo.h"
00052 #include "mainwindow.h"
00053 #include "actionmanager.h"
00054 
00055 #include "kitchensync.h"
00056 
00057 using namespace KSync;
00058 
00059 namespace {
00060 
00061 struct MainProgress
00062 {
00063     static Error noKonnector();
00064     static Error noPush();
00065 };
00066 
00067 Error MainProgress::noKonnector()
00068 {
00069     return Error(i18n("There is no current Konnector") );
00070 }
00071 
00072 Error MainProgress::noPush()
00073 {
00074     return Error(i18n("The current Konnector does not support pushing") );
00075 }
00076 
00077 kdbgstream operator<<( kdbgstream str, const Notify& no )
00078 {
00079     str << no.code() << " " << no.text();
00080     return str;
00081 }
00082 
00083 }
00084 
00085 KitchenSync::KitchenSync( ActionManager *actionManager, QWidget *parent )
00086   : Core( parent ), mActionManager( actionManager ), m_profileManager( 0 )
00087 {
00088   m_syncAlg = 0;
00089   m_syncUi = 0;
00090 
00091   m_partsIt = 0;
00092 
00093   m_isSyncing = false;
00094 
00095 #if 0
00096   initActions();
00097   setXMLFile("ksyncgui.rc");
00098   setInstance( KGlobal::instance() );
00099 
00100   createGUI( 0 );
00101 #endif
00102 
00103   QBoxLayout *topLayout = new QHBoxLayout( this );
00104 
00105   m_bar = new PartBar( this, "partBar" );
00106   topLayout->addWidget( m_bar );
00107   m_stack = new QWidgetStack( this, "dummy" );
00108   topLayout->addWidget( m_stack );
00109 
00110   QWidget *test = new QWidget( m_stack );
00111   test->setBackgroundColor( Qt::red );
00112   m_stack->addWidget( test, 0 );
00113   m_stack->raiseWidget( 0 );
00114   m_bar->setMaximumWidth( 100 );
00115   m_bar->setMinimumWidth( 100 );
00116 
00117   connect( m_bar, SIGNAL( activated( ActionPart * ) ),
00118            SLOT( slotActivated( ActionPart * ) ) );
00119 
00120   resize( 600, 400 );
00121 
00122   m_parts.setAutoDelete( true );
00123 
00124   initSystray();
00125   m_tray->show();
00126 
00127   mEngine = new Engine( m_parts );
00128 
00129   KonnectorManager *m = KonnectorManager::self();
00130   connect( m, SIGNAL( synceesRead( Konnector * ) ),
00131            mEngine, SLOT( slotSynceesRead( Konnector * ) ) );
00132   connect( m, SIGNAL( synceeReadError( Konnector * ) ),
00133            mEngine, SLOT( slotSynceeReadError( Konnector * ) ) );
00134   connect( m, SIGNAL( synceesWritten( Konnector * ) ),
00135            mEngine, SLOT( slotSynceesWritten( Konnector * ) ) );
00136   connect( m, SIGNAL( synceeWriteError( Konnector * ) ),
00137            mEngine, SLOT( slotSynceeWriteError( Konnector * ) ) );
00138 }
00139 
00140 KitchenSync::~KitchenSync()
00141 {
00142   writeProfileConfig();
00143 
00144   m_profileManager->save();
00145 
00146   delete m_profileManager;
00147 }
00148 
00149 void KitchenSync::readProfileConfig()
00150 {
00151   KConfig *config = KGlobal::config();
00152   config->setGroup( "Layout_" + currentProfile().uid() );
00153   m_bar->selectPart( config->readEntry( "CurrentPart" ) );
00154 }
00155 
00156 void KitchenSync::writeProfileConfig()
00157 {
00158   KConfig *config = KGlobal::config();
00159   config->setGroup( "Layout_" + currentProfile().uid() );
00160   if ( m_bar->currentItem() && m_bar->currentItem()->part() ) {
00161     config->writeEntry( "CurrentPart", m_bar->currentItem()->part()->name() );
00162   
00163     config->sync();
00164   }
00165 }
00166 
00167 void KitchenSync::addPart( const ActionPartService &service )
00168 {
00169     kdDebug() << "KitchenSync::addPart() " << service.name() << endl;
00170 
00171     ActionPart *part = KParts::ComponentFactory
00172       ::createInstanceFromLibrary<ActionPart>( service.libname().local8Bit(),
00173                                                this );
00174   
00175     if ( !part ) {
00176       kdError() << "Unable to create part '" << service.name() << "'"
00177                 << endl;
00178       return;
00179     }
00180 
00181 // We don't need this anymore. The Engine class takes care of the signals/slots.
00182 #if 0
00183     /* the usual signal and slots */
00184     connect( part, SIGNAL(sig_progress(ActionPart*, int ) ),
00185              SLOT(slotPartProg(ActionPart*, int ) ) );
00186     connect( part, SIGNAL(sig_progress(ActionPart*, const Progress& ) ),
00187              SLOT(slotPartProg(ActionPart*, const Progress& ) ) );
00188     connect( part, SIGNAL(sig_error(ActionPart*, const Error& ) ),
00189              SLOT(slotPartErr(ActionPart*, const Error& ) ) );
00190     connect( part, SIGNAL(sig_syncStatus(ActionPart*, int) ),
00191              SLOT(slotPartSyncStatus( ActionPart*, int ) ) );
00192 
00193     KonnectorManager *m = KonnectorManager::self();
00194     connect( m, SIGNAL( synceesRead( Konnector * ) ),
00195              part, SLOT( slotSynceesRead( Konnector * ) ) );
00196     connect( m, SIGNAL( synceeReadError( Konnector * ) ),
00197              part, SLOT( slotSynceeReadError( Konnector * ) ) );
00198     connect( m, SIGNAL( synceesWritten( Konnector * ) ),
00199              part, SLOT( slotSynceesWritten( Konnector * ) ) );
00200     connect( m, SIGNAL( synceeWriteError( Konnector * ) ),
00201              part, SLOT( slotSynceeWriteError( Konnector * ) ) );
00202 #endif
00203 
00204     if ( part->hasGui() )  {
00205         kdDebug(5210) << "Part has GUI (" << part->name() << ")" << endl;
00206         int pos = -1;
00207         
00208         QWidget *topWidget = new QWidget( m_stack );
00209 
00210         QBoxLayout *frameLayout = new QHBoxLayout( topWidget );
00211         frameLayout->addSpacing( KDialog::spacingHint() );
00212 
00213         QBoxLayout *topLayout = new QVBoxLayout( frameLayout );
00214         topLayout->setSpacing( KDialog::spacingHint() );
00215 
00216         QLabel *label = new QLabel( "<h3>" + part->title() + "</h3>",
00217                                     topWidget );
00218         topLayout->addWidget( label );
00219 
00220         QWidget *partWidget = part->widget();
00221         partWidget->reparent( topWidget, 0, QPoint( 0, 0 ) );
00222         topLayout->addWidget( partWidget );
00223         
00224         m_stack->addWidget( topWidget );
00225 
00226         mActionWidgetMap.insert( part, topWidget );
00227 
00228         /* overview is special for us ;) */
00229         if ( part->type() == i18n("Overview") ) {
00230             m_stack->raiseWidget( mActionWidgetMap[ part ] );
00231             pos = 0;
00232         }
00233         m_bar->insertItem( part, pos );
00234     }
00235     m_parts.append( part );
00236 }
00237 
00238 void KitchenSync::initSystray( void )
00239 {
00240   m_tray = new KSyncSystemTray( parentWidget() );
00241   KPopupMenu *popMenu = m_tray->getContextMenu();
00242   popMenu->insertSeparator();
00243 }
00244 
00245 void KitchenSync::slotSync()
00246 {
00247   emit partProgress( 0, Progress( i18n( "Starting sync" ) ) );
00248 
00249   mEngine->go();
00250 }
00251 
00252 void KitchenSync::slotActivated( ActionPart *part )
00253 {
00254     emit partChanged( part );
00255     m_stack->raiseWidget( mActionWidgetMap[ part ] );
00256 //    createGUI( part );
00257 }
00258 
00259 KSyncSystemTray* KitchenSync::tray()
00260 {
00261     return m_tray;
00262 }
00263 
00264 /*
00265  * we're now initializing the ordinary profiles
00266  */
00267 void KitchenSync::initProfiles()
00268 {
00269     kdDebug() << "KitchenSync::initProfiles()" << endl;
00270 
00271     m_profileManager = new ProfileManager();
00272     m_profileManager->load();
00273     initProfileList();
00274     activateProfile();
00275 
00276     kdDebug() << "KitchenSync::initProfiles() done" << endl;
00277 }
00278 
00279 Profile KitchenSync::currentProfile() const
00280 {
00281     return m_profileManager->currentProfile();
00282 }
00283 
00284 ProfileManager *KitchenSync::profileManager() const
00285 {
00286     return m_profileManager;
00287 }
00288 
00289 Engine *KitchenSync::engine() const
00290 {
00291   return mEngine;
00292 }
00293 
00294 #if 0
00295 // do we need to change the Konnector first?
00296 // raise overview and then pipe informations
00297 // when switching to KSyncee/KSyncEntry we will make
00298 // it asynchronus
00299 void KitchenSync::slotSync( Konnector *konnector, SynceeList lis)
00300 {
00301     if ( konnector != currentKonnectorProfile().konnector() ) {
00302         emit partError( 0, Error(i18n("A Konnector wanted to sync but it's not the current one") ) );
00303         KonnectorManager::self()->write( konnector, lis );
00304         return;
00305     }
00306     if ( m_isSyncing ) {
00307         emit partError( 0, Error(i18n("A sync is currently taking place. We will just ignore this request.") ) );
00308         return;
00309     }
00310     m_isSyncing = true;
00311     emit startSync();
00312     m_outSyncee.clear();
00313     m_inSyncee = lis;
00314     kdDebug(5210) << "KitchenSync::Start sync" << endl;
00315     m_partsIt = new QPtrListIterator<ActionPart>( m_parts );
00316 
00317     ActionPart *part = m_partsIt->current();
00318     if ( part ) {
00319         kdDebug(5210) << "Syncing first " << endl;
00320         emit startSync( part );
00321         emit syncProgress( part, 0, 0 );
00322         part->sync( m_inSyncee, m_outSyncee );
00323     } else {
00324         emit partProgress( 0, Progress(i18n("Error could not start syncing with the parts.") ) );
00325         delete m_partsIt;
00326         m_partsIt = 0;
00327         KonnectorManager::self()->write( konnector, lis );
00328         m_isSyncing = false;
00329     }
00330 }
00331 #endif
00332 
00333 void KitchenSync::configureProfiles()
00334 {
00335     ProfileDialog dlg( m_profileManager->profiles(),
00336                        ActionPartService::availableParts() );
00337     if ( dlg.exec() ) {
00338         m_profileManager->setProfiles( dlg.profiles() );
00339         m_profileManager->save();
00340         // switch profile
00341         initProfileList();
00342         activateProfile();
00343     }
00344 }
00345 
00346 void KitchenSync::activateProfile()
00347 {
00348     int item = mActionManager->currentProfile();
00349     if ( item < 0 ) item = 0; // for initialization
00350     if ( m_profileManager->count() == 0 ) return;
00351 
00352     Profile currentProfile = m_profileManager->profile( item );
00353 
00354     activateProfile( currentProfile );
00355     m_profileManager->setCurrentProfile( currentProfile );
00356 }
00357 
00358 void KitchenSync::activateProfile( const Profile &prof )
00359 {
00360     kdDebug() << "KitchenSync::activateProfile(): " << prof.name() << endl;
00361 
00362     if ( prof.uid() == m_profileManager->currentProfile().uid() ) {
00363       kdDebug() << "Profile already active" << endl;
00364       return;
00365     }
00366 
00367     writeProfileConfig();
00368 
00369     m_bar->clear();
00370 
00371     m_parts.setAutoDelete( true );
00372     m_parts.clear();
00373     delete m_partsIt;
00374     m_partsIt = 0;
00375 
00376     ActionPartService::List lst = prof.actionParts();
00377     ActionPartService::List::Iterator it;
00378     for (it = lst.begin(); it != lst.end(); ++it ) {
00379         addPart( (*it) );
00380     }
00381     m_profileManager->setCurrentProfile( prof );
00382     emit profileChanged( prof );
00383 
00384     readProfileConfig();
00385 }
00386 
00387 /*
00388  * configure current loaded
00389  * we will hack our SyncAlgo configurator into  that
00390  * that widget
00391  */
00392 void KitchenSync::configureCurrentProfile()
00393 {
00394     ConfigureDialog *dlg = new ConfigureDialog(this);
00395     ActionPart *part = 0;
00396     SyncConfig* conf = new SyncConfig( currentProfile().confirmDelete(), currentProfile().confirmSync() );
00397     dlg->addWidget( conf, i18n("General"), new QPixmap( KGlobal::iconLoader()->loadIcon("package_settings", KIcon::Desktop, 48 ) ) );
00398 
00399     for (part = m_parts.first(); part != 0; part = m_parts.next() ) {
00400         if( part->configIsVisible() )
00401             dlg->addWidget(part->configWidget(),
00402                            part->name(),
00403                            part->pixmap() );
00404     }
00405     if (dlg->exec()) {
00406         Profile prof =  currentProfile();
00407         prof.setConfirmSync( conf->confirmSync() );
00408         prof.setConfirmDelete( conf->confirmDelete() );
00409         profileManager()->replaceProfile( prof );
00410         profileManager()->setCurrentProfile( prof );
00411 
00412         for (part = m_parts.first(); part != 0; part = m_parts.next() ) {
00413             part->slotConfigOk();
00414         }
00415     }
00416     delete dlg;
00417     m_profileManager->save();
00418 }
00419 
00420 void KitchenSync::initProfileList()
00421 {
00422     Profile::List list = m_profileManager->profiles();
00423     Profile::List::Iterator it;
00424     QStringList lst;
00425     for ( it = list.begin(); it != list.end(); ++it ) {
00426         lst << (*it).name();
00427     }
00428     mActionManager->setProfiles( lst );
00429 }
00430 
00431 SyncUi *KitchenSync::syncUi()
00432 {
00433     m_syncUi = new SyncUiKde( this, currentProfile().confirmDelete(), true );
00434     return m_syncUi;
00435 }
00436 
00437 SyncAlgorithm *KitchenSync::syncAlgorithm()
00438 {
00439     m_syncAlg = new PIMSyncAlg( syncUi() );
00440 
00441     return m_syncAlg;
00442 }
00443 
00444 const QPtrList<ActionPart> KitchenSync::parts() const
00445 {
00446     return m_parts;
00447 }
00448 
00449 void KitchenSync::slotKonnectorProg( Konnector *konnector,
00450                                          const Progress & prog )
00451 {
00452     switch( prog.code() ) {
00453     case Progress::Connected:
00454 //        m_konBar->setState( true );
00455         m_tray->setState( true );
00456         break;
00457     case Progress::Done:
00458         emit doneSync();
00459         m_isSyncing = false;
00460         break;
00461     default:
00462         break;
00463     }
00464     emit konnectorProgress( konnector, prog );
00465 }
00466 
00467 void KitchenSync::slotKonnectorErr( Konnector *konnector,
00468                                         const Error & prog )
00469 {
00470     switch( prog.code() ) {
00471       case Error::ConnectionLost: // fall through
00472       case Error::CouldNotConnect:
00473 //        m_konBar->setState( false );
00474         m_tray->setState( false );
00475         break;
00476       case Error::CouldNotDisconnect:
00477 //        if ( konnector->isConnected() ) m_konBar->setState( true );
00478         m_tray->setState( true );
00479       default:
00480         break;
00481     }
00482     emit konnectorError( konnector, prog );
00483 }
00484 
00485 /*
00486  * emitted when one part is done with syncing
00487  * go to the next part and continue
00488  */
00489 void KitchenSync::slotPartProg( ActionPart *par, int prog )
00490 {
00491     kdDebug(5210) << "PartProg: " << par << " " << prog << endl;
00492     if (prog != 2 ) return;
00493 
00494 }
00495 
00496 void KitchenSync::slotPartProg( ActionPart *part, const Progress &prog )
00497 {
00498     emit partProgress( part, prog );
00499     emit syncProgress( part, 1, 0 );
00500 }
00501 
00502 void KitchenSync::slotPartErr( ActionPart *part, const Error &err )
00503 {
00504     emit partError( part, err );
00505     emit syncProgress( part, 3, 0 );
00506 }
00507 
00508 void KitchenSync::slotPartSyncStatus( ActionPart *par, int err )
00509 {
00510     kdDebug(5210) << "SyncStatus: " << par << " " << err << endl;
00511 #if 0
00512     emit doneSync( par );
00513     emit syncProgress( par, 2, 0 );
00514     // done() from ActionPart now go on to the next ActionPart...
00515     ++( *m_partsIt );
00516     ActionPart *part = m_partsIt->current();
00517     if ( part ) {
00518         kdDebug(5210) << "Syncing " << part->name() << endl;
00519         emit startSync( part );
00520         emit syncProgress( part, 0, 0 );
00521         part->sync( m_inSyncee, m_outSyncee );
00522     } else { // we're done go write it back
00523         emit partProgress( 0, Progress(i18n("Going to write the information back now.") ) );
00524         delete m_partsIt;
00525         m_partsIt = 0;
00526         kdDebug(5210) << "Going to write back " << m_outSyncee.count() << endl;
00527         KonnectorManager::self()->write( currentKonnectorProfile().konnector(),
00528                                          m_outSyncee );
00529         // now we only wait for the done
00530     }
00531 #endif
00532 }
00533 
00534 QWidget *KitchenSync::widgetStack()
00535 {
00536     return m_stack;
00537 }
00538 
00539 void KitchenSync::slotKonnectorBar( bool b )
00540 {
00541     kdDebug(5210) << "slotKonnectorBar " << b << endl;
00542 
00543 #if 0
00544     Konnector *k = currentKonnectorProfile().konnector();
00545     if ( b ) {
00546         if ( k->isConnected() ) {
00547             kdDebug(5210) << "Going to connect " << endl;
00548             k->connectDevice();
00549         }
00550     } else {
00551         kdDebug(5210) << "disconnecting " << endl;
00552         k->disconnectDevice();
00553         m_konBar->setState( b );
00554         m_tray->setState( b );
00555     }
00556 #endif
00557 }
00558 
00559 void KitchenSync::slotPreferences()
00560 {
00561   KCMultiDialog *dialog = new KCMultiDialog( this );
00562   connect( dialog, SIGNAL( applyClicked() ), SLOT( updateConfig() ) );
00563   connect( dialog, SIGNAL( okClicked() ), SLOT( updateConfig() ) );
00564 
00565   dialog->addModule( "Settings/Components/kresources.desktop" );
00566 
00567   dialog->show();
00568   dialog->raise();
00569 }
00570 
00571 void KitchenSync::updateConfig()
00572 {
00573 }
00574 
00575 #include "kitchensync.moc"
KDE Logo
This file is part of the documentation for kitchensync Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Dec 21 14:23:40 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003