00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00182 #if 0
00183
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
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
00257 }
00258
00259 KSyncSystemTray* KitchenSync::tray()
00260 {
00261 return m_tray;
00262 }
00263
00264
00265
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
00296
00297
00298
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
00341 initProfileList();
00342 activateProfile();
00343 }
00344 }
00345
00346 void KitchenSync::activateProfile()
00347 {
00348 int item = mActionManager->currentProfile();
00349 if ( item < 0 ) item = 0;
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
00389
00390
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
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:
00472 case Error::CouldNotConnect:
00473
00474 m_tray->setState( false );
00475 break;
00476 case Error::CouldNotDisconnect:
00477
00478 m_tray->setState( true );
00479 default:
00480 break;
00481 }
00482 emit konnectorError( konnector, prog );
00483 }
00484
00485
00486
00487
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
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 {
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
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"