kitchensync

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., 51 Franklin Street, Fifth Floor,
00021     Boston, MA 02110-1301, 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 
00043 #include "syncconfig.h"
00044 #include "configuredialog.h"
00045 #include "partbar.h"
00046 #include "profiledialog.h"
00047 #include "engine.h"
00048 #include "konnectorbar.h"
00049 #include "mainwindow.h"
00050 #include "actionmanager.h"
00051 
00052 #include "kitchensync.h"
00053 
00054 using namespace KSync;
00055 
00056 KitchenSync::KitchenSync( ActionManager *actionManager, QWidget *parent )
00057   : Core( parent ), mActionManager( actionManager ), m_profileManager( 0 )
00058 {
00059   m_syncUi = 0;
00060   m_partsIt = 0;
00061   m_isSyncing = false;
00062 
00063   QBoxLayout *topLayout = new QHBoxLayout( this );
00064 
00065   m_bar = new PartBar( this, "partBar" );
00066   topLayout->addWidget( m_bar );
00067   m_stack = new QWidgetStack( this, "dummy" );
00068   topLayout->addWidget( m_stack );
00069 
00070   QWidget *test = new QWidget( m_stack );
00071   test->setBackgroundColor( Qt::red );
00072   m_stack->addWidget( test, 0 );
00073   m_stack->raiseWidget( 0 );
00074   m_bar->setMaximumWidth( 100 );
00075   m_bar->setMinimumWidth( 100 );
00076 
00077   connect( m_bar, SIGNAL( activated( ActionPart * ) ),
00078            SLOT( slotActivated( ActionPart * ) ) );
00079 
00080   resize( 600, 400 );
00081 
00082   m_parts.setAutoDelete( true );
00083 
00084   initSystray();
00085   m_tray->show();
00086 
00087   mEngine = new Engine( m_parts );
00088 
00089   KonnectorManager *m = KonnectorManager::self();
00090   connect( m, SIGNAL( synceesRead( KSync::Konnector * ) ),
00091            mEngine, SLOT( slotSynceesRead( KSync::Konnector * ) ) );
00092   connect( m, SIGNAL( synceeReadError( KSync::Konnector * ) ),
00093            mEngine, SLOT( slotSynceeReadError( KSync::Konnector * ) ) );
00094   connect( m, SIGNAL( synceesWritten( KSync::Konnector * ) ),
00095            mEngine, SLOT( slotSynceesWritten( KSync::Konnector * ) ) );
00096   connect( m, SIGNAL( synceeWriteError( KSync::Konnector * ) ),
00097            mEngine, SLOT( slotSynceeWriteError( KSync::Konnector * ) ) );
00098 
00099   connect( mEngine, SIGNAL(doneSync()),
00100            this, SIGNAL(doneSync()));
00101 }
00102 
00103 KitchenSync::~KitchenSync()
00104 {
00105   writeProfileConfig();
00106   m_profileManager->save();
00107 
00108   /*
00109    * delete the parts before the currentProfile() so Parts
00110    * can safe on destruction
00111    */
00112   m_parts.clear();
00113   delete m_profileManager;
00114 }
00115 
00116 void KitchenSync::readProfileConfig()
00117 {
00118   KConfig *config = KGlobal::config();
00119   config->setGroup( "Layout_" + currentProfile().uid() );
00120   m_bar->selectPart( config->readEntry( "CurrentPart" ) );
00121 }
00122 
00123 void KitchenSync::writeProfileConfig()
00124 {
00125   KConfig *config = KGlobal::config();
00126   config->setGroup( "Layout_" + currentProfile().uid() );
00127   if ( m_bar->currentItem() && m_bar->currentItem()->part() ) {
00128     config->writeEntry( "CurrentPart", m_bar->currentItem()->part()->name() );
00129 
00130     config->sync();
00131   }
00132 }
00133 
00134 void KitchenSync::addPart( const ActionPartService &service )
00135 {
00136     kdDebug() << "KitchenSync::addPart() " << service.name() << endl;
00137 
00138     ActionPart *part = KParts::ComponentFactory
00139       ::createInstanceFromLibrary<ActionPart>( service.libraryName().local8Bit(),
00140                                                this );
00141 
00142     if ( !part ) {
00143       kdError() << "Unable to create part '" << service.name() << "'"
00144                 << endl;
00145       return;
00146     }
00147 
00148     if ( part->hasGui() )  {
00149         kdDebug(5210) << "Part has GUI (" << part->name() << ")" << endl;
00150         int pos = -1;
00151 
00152         QWidget *topWidget = new QWidget( m_stack );
00153 
00154         QBoxLayout *frameLayout = new QHBoxLayout( topWidget );
00155         frameLayout->addSpacing( KDialog::spacingHint() );
00156 
00157         QBoxLayout *topLayout = new QVBoxLayout( frameLayout );
00158         topLayout->setSpacing( KDialog::spacingHint() );
00159 
00160         QLabel *label = new QLabel( "<h3>" + part->title() + "</h3>",
00161                                     topWidget );
00162         topLayout->addWidget( label );
00163 
00164         QWidget *partWidget = part->widget();
00165         partWidget->reparent( topWidget, 0, QPoint( 0, 0 ) );
00166         topLayout->addWidget( partWidget );
00167 
00168         m_stack->addWidget( topWidget );
00169 
00170         mActionWidgetMap.insert( part, topWidget );
00171 
00172         /* overview is special for us ;) */
00173         if ( part->type() == i18n("Overview") ) {
00174             m_stack->raiseWidget( mActionWidgetMap[ part ] );
00175             pos = 0;
00176         }
00177         m_bar->insertItem( part, pos );
00178     }
00179     m_parts.append( part );
00180 }
00181 
00182 void KitchenSync::initSystray( void )
00183 {
00184   m_tray = new KSyncSystemTray( parentWidget() );
00185   KPopupMenu *popMenu = m_tray->getContextMenu();
00186   popMenu->insertSeparator();
00187 }
00188 
00189 void KitchenSync::slotSync()
00190 {
00191   mEngine->go();
00192 }
00193 
00194 void KitchenSync::slotActivated( ActionPart *part )
00195 {
00196   emit partChanged( part );
00197   m_stack->raiseWidget( mActionWidgetMap[ part ] );
00198 }
00199 
00200 KSyncSystemTray* KitchenSync::tray()
00201 {
00202   return m_tray;
00203 }
00204 
00205 /*
00206  * we're now initializing the ordinary profiles
00207  */
00208 void KitchenSync::initProfiles()
00209 {
00210     kdDebug() << "KitchenSync::initProfiles()" << endl;
00211 
00212     m_profileManager = new ProfileManager();
00213     m_profileManager->load();
00214     initProfileList();
00215     activateProfile();
00216 
00217     kdDebug() << "KitchenSync::initProfiles() done" << endl;
00218 }
00219 
00220 Profile KitchenSync::currentProfile() const
00221 {
00222     return m_profileManager->currentProfile();
00223 }
00224 
00225 ProfileManager *KitchenSync::profileManager() const
00226 {
00227     return m_profileManager;
00228 }
00229 
00230 Engine *KitchenSync::engine() const
00231 {
00232   return mEngine;
00233 }
00234 
00235 void KitchenSync::configureProfiles()
00236 {
00237     ProfileDialog dlg( m_profileManager->profiles(),
00238                        ActionPartService::availableParts() );
00239     if ( dlg.exec() ) {
00240         m_profileManager->setProfiles( dlg.profiles() );
00241         m_profileManager->save();
00242         // switch profile
00243         initProfileList();
00244         activateProfile();
00245     }
00246 }
00247 
00248 void KitchenSync::activateProfile()
00249 {
00250     int item = mActionManager->currentProfile();
00251     if ( item < 0 ) item = 0; // for initialization
00252     if ( m_profileManager->count() == 0 ) return;
00253 
00254     Profile currentProfile = m_profileManager->profile( item );
00255 
00256     activateProfile( currentProfile );
00257     m_profileManager->setCurrentProfile( currentProfile );
00258 }
00259 
00260 void KitchenSync::activateProfile( const Profile &prof )
00261 {
00262     kdDebug() << "KitchenSync::activateProfile(): " << prof.name() << endl;
00263 
00264     if ( prof.uid() == m_profileManager->currentProfile().uid() ) {
00265       kdDebug() << "Profile already active" << endl;
00266       return;
00267     }
00268 
00269     writeProfileConfig();
00270 
00271     m_bar->clear();
00272 
00273     m_parts.setAutoDelete( true );
00274     m_parts.clear();
00275     delete m_partsIt;
00276     m_partsIt = 0;
00277 
00278     ActionPartService::List lst = prof.actionParts();
00279     ActionPartService::List::Iterator it;
00280     for (it = lst.begin(); it != lst.end(); ++it ) {
00281         addPart( (*it) );
00282     }
00283     m_profileManager->setCurrentProfile( prof );
00284     emit profileChanged( prof );
00285 
00286     readProfileConfig();
00287 }
00288 
00289 /*
00290  * configure current loaded
00291  * we will hack our SyncAlgo configurator into  that
00292  * that widget
00293  */
00294 void KitchenSync::configureCurrentProfile()
00295 {
00296     ConfigureDialog *dlg = new ConfigureDialog(this);
00297     ActionPart *part = 0;
00298     SyncConfig* conf = new SyncConfig( currentProfile().confirmDelete(), currentProfile().confirmSync() );
00299     dlg->addWidget( conf, i18n("General"), new QPixmap( KGlobal::iconLoader()->loadIcon("package_settings", KIcon::Desktop, 48 ) ) );
00300 
00301     for (part = m_parts.first(); part != 0; part = m_parts.next() ) {
00302         if( part->configIsVisible() )
00303             dlg->addWidget(part->configWidget(),
00304                            part->title(),
00305                            part->pixmap() );
00306     }
00307     if (dlg->exec()) {
00308         Profile prof =  currentProfile();
00309         prof.setConfirmSync( conf->confirmSync() );
00310         prof.setConfirmDelete( conf->confirmDelete() );
00311         profileManager()->replaceProfile( prof );
00312         profileManager()->setCurrentProfile( prof );
00313 
00314         for (part = m_parts.first(); part != 0; part = m_parts.next() ) {
00315             part->slotConfigOk();
00316         }
00317     }
00318     delete dlg;
00319     m_profileManager->save();
00320 }
00321 
00322 void KitchenSync::initProfileList()
00323 {
00324     Profile::List list = m_profileManager->profiles();
00325     Profile::List::Iterator it;
00326     QStringList lst;
00327     for ( it = list.begin(); it != list.end(); ++it ) {
00328         lst << (*it).name();
00329     }
00330     mActionManager->setProfiles( lst );
00331 }
00332 
00333 SyncUi *KitchenSync::syncUi()
00334 {
00335     m_syncUi = new SyncUiKde( this, currentProfile().confirmDelete(), true );
00336     return m_syncUi;
00337 }
00338 
00339 const QPtrList<ActionPart> KitchenSync::parts() const
00340 {
00341     return m_parts;
00342 }
00343 
00344 /*
00345  * emitted when one part is done with syncing
00346  * go to the next part and continue
00347  */
00348 void KitchenSync::slotPartProg( ActionPart *par, int prog )
00349 {
00350     kdDebug(5210) << "PartProg: " << par << " " << prog << endl;
00351     if (prog != 2 ) return;
00352 
00353 }
00354 
00355 void KitchenSync::slotPartSyncStatus( ActionPart *par, int err )
00356 {
00357     kdDebug(5210) << "SyncStatus: " << par << " " << err << endl;
00358 }
00359 
00360 QWidget *KitchenSync::widgetStack()
00361 {
00362     return m_stack;
00363 }
00364 
00365 void KitchenSync::slotKonnectorBar( bool b )
00366 {
00367     kdDebug(5210) << "slotKonnectorBar " << b << endl;
00368 }
00369 
00370 void KitchenSync::slotPreferences()
00371 {
00372   KCMultiDialog *dialog = new KCMultiDialog( this );
00373   connect( dialog, SIGNAL( applyClicked() ), SLOT( updateConfig() ) );
00374   connect( dialog, SIGNAL( okClicked() ), SLOT( updateConfig() ) );
00375 
00376   dialog->addModule( "Settings/Components/kresources.desktop" );
00377 
00378   dialog->show();
00379   dialog->raise();
00380 }
00381 
00382 void KitchenSync::updateConfig()
00383 {
00384 }
00385 
00386 #include "kitchensync.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys