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.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Oct 21 19:46:32 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003