groupitem.cpp
00001 /* 00002 This file is part of KitchenSync. 00003 00004 Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include <tdeapplication.h> 00022 #include <kdialog.h> 00023 #include <tdeglobal.h> 00024 #include <tdeglobalsettings.h> 00025 #include <kiconloader.h> 00026 #include <tdelocale.h> 00027 #include <kpassivepopup.h> 00028 #include <kurllabel.h> 00029 00030 #include <tqlabel.h> 00031 #include <tqlayout.h> 00032 #include <tqpixmap.h> 00033 #include <tqprogressbar.h> 00034 #include <tqvbox.h> 00035 00036 #include "memberinfo.h" 00037 #include "multiconflictdialog.h" 00038 #include "singleconflictdialog.h" 00039 #include "syncprocessmanager.h" 00040 00041 #include "groupitem.h" 00042 00043 GroupItem::GroupItem( KWidgetList *parent, SyncProcess *process ) 00044 : KWidgetListItem( parent ), mSyncProcess( process ), 00045 mCallbackHandler( new QSync::CallbackHandler ), 00046 mProcessedItems( 0 ), mMaxProcessedItems( 0 ), 00047 mSynchronizing( false ) 00048 { 00049 TQFont boldFont; 00050 boldFont.setBold( true ); 00051 boldFont.setPointSize( boldFont.pointSize() + 2 ); 00052 00053 TQGridLayout *layout = new TQGridLayout( this, 4, 4, KDialog::marginHint(), KDialog::spacingHint() ); 00054 00055 mBox = new TQVBox( this ); 00056 mBox->setMargin( 5 ); 00057 mProgressBar = new TQProgressBar( this ); 00058 mProgressBar->setTotalSteps( 100 ); 00059 00060 mTime = new TQLabel( this ); 00061 mSyncAction = new KURLLabel( "exec:/sync", i18n( "Synchronize Now" ), this ); 00062 mConfigureAction = new KURLLabel( "exec:/config", i18n( "Configure" ), this ); 00063 00064 // header 00065 TQHBox* hbox = new TQHBox( this ); 00066 hbox->setMargin( 2 ); 00067 00068 static TQPixmap icon; 00069 if ( icon.isNull() ) 00070 icon = TDEGlobal::iconLoader()->loadIcon( "kontact_summary", TDEIcon::Desktop ); 00071 00072 mIcon = new TQLabel( hbox ); 00073 mIcon->setPixmap( icon ); 00074 mIcon->setFixedSize( mIcon->sizeHint() ); 00075 mIcon->setPaletteBackgroundColor( colorGroup().mid() ); 00076 00077 mGroupName = new TQLabel( hbox ); 00078 mGroupName->setAlignment( AlignLeft | AlignVCenter ); 00079 mGroupName->setIndent( KDialog::spacingHint() ); 00080 mGroupName->setFont( boldFont ); 00081 mGroupName->setPaletteForegroundColor( colorGroup().light() ); 00082 mGroupName->setPaletteBackgroundColor( colorGroup().mid() ); 00083 00084 mStatus = new TQLabel( hbox ); 00085 mStatus->setAlignment( TQt::AlignRight ); 00086 mStatus->setAlignment( AlignRight | AlignVCenter ); 00087 mStatus->setIndent( KDialog::spacingHint() ); 00088 mStatus->setFont( boldFont ); 00089 mStatus->setPaletteForegroundColor( colorGroup().light() ); 00090 mStatus->setPaletteBackgroundColor( colorGroup().mid() ); 00091 mStatus->setText( i18n( "Ready" ) ); 00092 00093 hbox->setPaletteBackgroundColor( colorGroup().mid() ); 00094 hbox->setMaximumHeight( hbox->minimumSizeHint().height() ); 00095 00096 layout->addMultiCellWidget( hbox, 0, 0, 0, 3 ); 00097 layout->addMultiCellWidget( mBox, 1, 1, 0, 3 ); 00098 layout->addWidget( mTime, 2, 0 ); 00099 layout->addWidget( mSyncAction, 2, 1 ); 00100 layout->addWidget( mConfigureAction, 2, 2 ); 00101 layout->addWidget( mProgressBar, 2, 3 ); 00102 layout->setColStretch( 0, 1 ); 00103 layout->setRowStretch( 3, 1 ); 00104 00105 setPaletteBackgroundColor( kapp->palette().active().base() ); 00106 00107 connect( mCallbackHandler, TQT_SIGNAL( conflict( QSync::SyncMapping ) ), 00108 this, TQT_SLOT( conflict( QSync::SyncMapping ) ) ); 00109 connect( mCallbackHandler, TQT_SIGNAL( change( const QSync::SyncChangeUpdate& ) ), 00110 this, TQT_SLOT( change( const QSync::SyncChangeUpdate& ) ) ); 00111 connect( mCallbackHandler, TQT_SIGNAL( mapping( const QSync::SyncMappingUpdate& ) ), 00112 this, TQT_SLOT( mapping( const QSync::SyncMappingUpdate& ) ) ); 00113 connect( mCallbackHandler, TQT_SIGNAL( engine( const QSync::SyncEngineUpdate& ) ), 00114 this, TQT_SLOT( engine( const QSync::SyncEngineUpdate& ) ) ); 00115 connect( mCallbackHandler, TQT_SIGNAL( member( const QSync::SyncMemberUpdate& ) ), 00116 this, TQT_SLOT( member( const QSync::SyncMemberUpdate& ) ) ); 00117 connect( mSyncAction, TQT_SIGNAL( leftClickedURL() ), 00118 this, TQT_SLOT( synchronize() ) ); 00119 connect( mConfigureAction, TQT_SIGNAL( leftClickedURL() ), 00120 this, TQT_SLOT( configure() ) ); 00121 connect( mSyncProcess, TQT_SIGNAL( engineChanged( QSync::Engine* ) ), 00122 this, TQT_SLOT( engineChanged( QSync::Engine* ) ) ); 00123 00124 mCallbackHandler->setEngine( mSyncProcess->engine() ); 00125 00126 setSelectionForegroundColor( TDEGlobalSettings::textColor() ); 00127 setSelectionBackgroundColor( TDEGlobalSettings::alternateBackgroundColor() ); 00128 00129 update(); 00130 } 00131 00132 GroupItem::~GroupItem() 00133 { 00134 delete mCallbackHandler; 00135 mCallbackHandler = 0; 00136 } 00137 00138 void GroupItem::update() 00139 { 00140 clear(); 00141 00142 mGroupName->setText( i18n( "Group: %1" ).arg( mSyncProcess->group().name() ) ); 00143 00144 TQDateTime dateTime = mSyncProcess->group().lastSynchronization(); 00145 if ( dateTime.isValid() ) 00146 mTime->setText( i18n( "Last synchronized on: %1" ).arg( TDEGlobal::locale()->formatDateTime( dateTime ) ) ); 00147 else 00148 mTime->setText( i18n( "Not synchronized yet" ) ); 00149 00150 mProgressBar->reset(); 00151 mProgressBar->hide(); 00152 00153 QSync::Group group = mSyncProcess->group(); 00154 QSync::Group::Iterator memberIt( group.begin() ); 00155 QSync::Group::Iterator memberEndIt( group.end() ); 00156 00157 for ( ; memberIt != memberEndIt; ++memberIt ) { 00158 MemberItem *item = new MemberItem( mBox, mSyncProcess, *memberIt ); 00159 item->show(); 00160 item->setStatusMessage( i18n( "Ready" ) ); 00161 mMemberItems.append( item ); 00162 } 00163 } 00164 00165 void GroupItem::clear() 00166 { 00167 mGroupName->setText( TQString() ); 00168 00169 TQValueList<MemberItem*>::Iterator it; 00170 for ( it = mMemberItems.begin(); it != mMemberItems.end(); ++it ) 00171 delete *it; 00172 00173 mMemberItems.clear(); 00174 } 00175 00176 void GroupItem::conflict( QSync::SyncMapping mapping ) 00177 { 00178 if ( mapping.changesCount() == 2 ) { 00179 SingleConflictDialog dlg( mapping, this ); 00180 dlg.exec(); 00181 } else { 00182 MultiConflictDialog dlg( mapping, this ); 00183 dlg.exec(); 00184 } 00185 } 00186 00187 void GroupItem::change( const QSync::SyncChangeUpdate &update ) 00188 { 00189 switch ( update.type() ) { 00190 case QSync::SyncChangeUpdate::Received: 00191 mProcessedItems++; 00192 mStatus->setText( i18n( "%1 entries read" ).arg( mProcessedItems ) ); 00193 break; 00194 case QSync::SyncChangeUpdate::ReceivedInfo: 00195 mStatus->setText( i18n( "Receive information" ) ); 00196 break; 00197 case QSync::SyncChangeUpdate::Sent: 00198 mProcessedItems--; 00199 mStatus->setText( i18n( "%1 entries written" ).arg( mMaxProcessedItems - mProcessedItems ) ); 00200 00201 mProgressBar->show(); 00202 00203 { 00204 int progress = 100; 00205 if ( mMaxProcessedItems != 0 ) 00206 progress = (mProcessedItems * 100) / mMaxProcessedItems; 00207 00208 if ( progress < 0 ) 00209 progress = 0; 00210 00211 mProgressBar->setProgress( 100 - progress ); 00212 } 00213 break; 00214 case QSync::SyncChangeUpdate::WriteError: 00215 mStatus->setText( i18n( "Error" ) ); 00216 KPassivePopup::message( update.result().message(), this ); 00217 break; 00218 case QSync::SyncChangeUpdate::ReceiveError: 00219 mStatus->setText( i18n( "Error" ) ); 00220 KPassivePopup::message( update.result().message(), this ); 00221 break; 00222 default: 00223 mStatus->setText( TQString() ); 00224 break; 00225 } 00226 } 00227 00228 void GroupItem::mapping( const QSync::SyncMappingUpdate& ) 00229 { 00230 } 00231 00232 void GroupItem::engine( const QSync::SyncEngineUpdate &update ) 00233 { 00234 switch ( update.type() ) { 00235 case QSync::SyncEngineUpdate::EndPhaseConnected: 00236 mStatus->setText( i18n( "Connected" ) ); 00237 mProgressBar->setProgress( 0 ); 00238 mSynchronizing = true; 00239 mSyncAction->setText( "Abort Synchronization" ); 00240 break; 00241 case QSync::SyncEngineUpdate::EndPhaseRead: 00242 mStatus->setText( i18n( "Data read" ) ); 00243 break; 00244 case QSync::SyncEngineUpdate::EndPhaseWrite: 00245 mStatus->setText( i18n( "Data written" ) ); 00246 mProgressBar->setProgress( 100 ); 00247 mProcessedItems = mMaxProcessedItems = 0; 00248 break; 00249 case QSync::SyncEngineUpdate::EndPhaseDisconnected: 00250 mStatus->setText( i18n( "Disconnected" ) ); 00251 break; 00252 case QSync::SyncEngineUpdate::Error: 00253 mStatus->setText( i18n( "Synchronization failed" ) ); 00254 KPassivePopup::message( update.result().message(), this ); 00255 this->update(); 00256 00257 mSynchronizing = false; 00258 mSyncAction->setText( i18n( "Synchronize Now" ) ); 00259 break; 00260 case QSync::SyncEngineUpdate::SyncSuccessfull: 00261 mStatus->setText( i18n( "Successfully synchronized" ) ); 00262 mSyncProcess->group().setLastSynchronization( TQDateTime::currentDateTime() ); 00263 mSyncProcess->group().save(); 00264 this->update(); 00265 00266 mSynchronizing = false; 00267 mSyncAction->setText( i18n( "Synchronize Now" ) ); 00268 break; 00269 case QSync::SyncEngineUpdate::PrevUnclean: 00270 mStatus->setText( i18n( "Previous synchronization failed" ) ); 00271 break; 00272 case QSync::SyncEngineUpdate::EndConflicts: 00273 mStatus->setText( i18n( "Conflicts solved" ) ); 00274 mMaxProcessedItems = mProcessedItems; 00275 break; 00276 default: 00277 mStatus->setText( TQString() ); 00278 break; 00279 } 00280 } 00281 00282 void GroupItem::member( const QSync::SyncMemberUpdate &update ) 00283 { 00284 TQValueList<MemberItem*>::Iterator it; 00285 for ( it = mMemberItems.begin(); it != mMemberItems.end(); ++it ) { 00286 if ( (*it)->member() == update.member() ) { 00287 switch ( update.type() ) { 00288 case QSync::SyncMemberUpdate::Connected: 00289 (*it)->setStatusMessage( i18n( "Connected" ) ); 00290 break; 00291 case QSync::SyncMemberUpdate::SentChanges: 00292 (*it)->setStatusMessage( i18n( "Changes read" ) ); 00293 break; 00294 case QSync::SyncMemberUpdate::CommittedAll: 00295 (*it)->setStatusMessage( i18n( "Changes written" ) ); 00296 break; 00297 case QSync::SyncMemberUpdate::Disconnected: 00298 (*it)->setStatusMessage( i18n( "Disconnected" ) ); 00299 break; 00300 case QSync::SyncMemberUpdate::ConnectError: 00301 (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) ); 00302 break; 00303 case QSync::SyncMemberUpdate::GetChangesError: 00304 (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) ); 00305 break; 00306 case QSync::SyncMemberUpdate::CommittedAllError: 00307 (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) ); 00308 break; 00309 case QSync::SyncMemberUpdate::SyncDoneError: 00310 (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) ); 00311 break; 00312 case QSync::SyncMemberUpdate::DisconnectedError: 00313 (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) ); 00314 break; 00315 default: 00316 break; 00317 } 00318 00319 return; 00320 } 00321 } 00322 } 00323 00324 void GroupItem::synchronize() 00325 { 00326 if ( !mSynchronizing ) 00327 emit synchronizeGroup( mSyncProcess ); 00328 else 00329 emit abortSynchronizeGroup( mSyncProcess ); 00330 } 00331 00332 void GroupItem::configure() 00333 { 00334 emit configureGroup( mSyncProcess ); 00335 00336 this->update(); 00337 } 00338 00339 void GroupItem::engineChanged( QSync::Engine *engine ) 00340 { 00341 Q_ASSERT( engine ); 00342 00343 mCallbackHandler->setEngine( engine ); 00344 00345 this->update(); 00346 } 00347 00348 MemberItem::MemberItem( TQWidget *parent, SyncProcess *process, 00349 const QSync::Member &member ) 00350 : TQWidget( parent ), mSyncProcess( process ), mMember( member ) 00351 { 00352 TQFont boldFont; 00353 boldFont.setBold( true ); 00354 00355 MemberInfo mi( member ); 00356 00357 TQPixmap icon = mi.smallIcon(); 00358 00359 QSync::Plugin plugin = member.plugin(); 00360 00361 TQVBoxLayout *layout = new TQVBoxLayout( this ); 00362 00363 TQHBox* box = new TQHBox( this ); 00364 box->setMargin( 5 ); 00365 box->setSpacing( 6 ); 00366 layout->addWidget( box ); 00367 00368 mIcon = new TQLabel( box ); 00369 mIcon->setPixmap( icon ); 00370 mIcon->setAlignment( TQt::AlignTop ); 00371 mIcon->setFixedWidth( mIcon->sizeHint().width() ); 00372 00373 TQVBox *nameBox = new TQVBox( box ); 00374 mMemberName = new TQLabel( nameBox ); 00375 mMemberName->setFont( boldFont ); 00376 mDescription = new TQLabel( nameBox ); 00377 00378 mStatus = new TQLabel( box ); 00379 00380 mMemberName->setText( member.name() ); 00381 mDescription->setText( plugin.longName() ); 00382 } 00383 00384 void MemberItem::setStatusMessage( const TQString &msg ) 00385 { 00386 mStatus->setText( msg ); 00387 } 00388 00389 #include "groupitem.moc"