kitchensync

groupitem.cpp
1 /*
2  This file is part of KitchenSync.
3 
4  Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20 
21 #include <tdeapplication.h>
22 #include <kdialog.h>
23 #include <tdeglobal.h>
24 #include <tdeglobalsettings.h>
25 #include <kiconloader.h>
26 #include <tdelocale.h>
27 #include <kpassivepopup.h>
28 #include <kurllabel.h>
29 
30 #include <tqlabel.h>
31 #include <tqlayout.h>
32 #include <tqpixmap.h>
33 #include <tqprogressbar.h>
34 #include <tqvbox.h>
35 
36 #include "memberinfo.h"
37 #include "multiconflictdialog.h"
38 #include "singleconflictdialog.h"
39 #include "syncprocessmanager.h"
40 
41 #include "groupitem.h"
42 
43 GroupItem::GroupItem( KWidgetList *parent, SyncProcess *process )
44  : KWidgetListItem( parent ), mSyncProcess( process ),
45  mCallbackHandler( new QSync::CallbackHandler ),
46  mProcessedItems( 0 ), mMaxProcessedItems( 0 ),
47  mSynchronizing( false )
48 {
49  TQFont boldFont;
50  boldFont.setBold( true );
51  boldFont.setPointSize( boldFont.pointSize() + 2 );
52 
53  TQGridLayout *layout = new TQGridLayout( this, 4, 4, KDialog::marginHint(), KDialog::spacingHint() );
54 
55  mBox = new TQVBox( this );
56  mBox->setMargin( 5 );
57  mProgressBar = new TQProgressBar( this );
58  mProgressBar->setTotalSteps( 100 );
59 
60  mTime = new TQLabel( this );
61  mSyncAction = new KURLLabel( "exec:/sync", i18n( "Synchronize Now" ), this );
62  mConfigureAction = new KURLLabel( "exec:/config", i18n( "Configure" ), this );
63 
64  // header
65  TQHBox* hbox = new TQHBox( this );
66  hbox->setMargin( 2 );
67 
68  static TQPixmap icon;
69  if ( icon.isNull() )
70  icon = TDEGlobal::iconLoader()->loadIcon( "kontact_summary", TDEIcon::Desktop );
71 
72  mIcon = new TQLabel( hbox );
73  mIcon->setPixmap( icon );
74  mIcon->setFixedSize( mIcon->sizeHint() );
75  mIcon->setPaletteBackgroundColor( colorGroup().mid() );
76 
77  mGroupName = new TQLabel( hbox );
78  mGroupName->setAlignment( AlignLeft | AlignVCenter );
79  mGroupName->setIndent( KDialog::spacingHint() );
80  mGroupName->setFont( boldFont );
81  mGroupName->setPaletteForegroundColor( colorGroup().light() );
82  mGroupName->setPaletteBackgroundColor( colorGroup().mid() );
83 
84  mStatus = new TQLabel( hbox );
85  mStatus->setAlignment( TQt::AlignRight );
86  mStatus->setAlignment( AlignRight | AlignVCenter );
87  mStatus->setIndent( KDialog::spacingHint() );
88  mStatus->setFont( boldFont );
89  mStatus->setPaletteForegroundColor( colorGroup().light() );
90  mStatus->setPaletteBackgroundColor( colorGroup().mid() );
91  mStatus->setText( i18n( "Ready" ) );
92 
93  hbox->setPaletteBackgroundColor( colorGroup().mid() );
94  hbox->setMaximumHeight( hbox->minimumSizeHint().height() );
95 
96  layout->addMultiCellWidget( hbox, 0, 0, 0, 3 );
97  layout->addMultiCellWidget( mBox, 1, 1, 0, 3 );
98  layout->addWidget( mTime, 2, 0 );
99  layout->addWidget( mSyncAction, 2, 1 );
100  layout->addWidget( mConfigureAction, 2, 2 );
101  layout->addWidget( mProgressBar, 2, 3 );
102  layout->setColStretch( 0, 1 );
103  layout->setRowStretch( 3, 1 );
104 
105  setPaletteBackgroundColor( kapp->palette().active().base() );
106 
107  connect( mCallbackHandler, TQT_SIGNAL( conflict( QSync::SyncMapping ) ),
108  this, TQT_SLOT( conflict( QSync::SyncMapping ) ) );
109  connect( mCallbackHandler, TQT_SIGNAL( change( const QSync::SyncChangeUpdate& ) ),
110  this, TQT_SLOT( change( const QSync::SyncChangeUpdate& ) ) );
111  connect( mCallbackHandler, TQT_SIGNAL( mapping( const QSync::SyncMappingUpdate& ) ),
112  this, TQT_SLOT( mapping( const QSync::SyncMappingUpdate& ) ) );
113  connect( mCallbackHandler, TQT_SIGNAL( engine( const QSync::SyncEngineUpdate& ) ),
114  this, TQT_SLOT( engine( const QSync::SyncEngineUpdate& ) ) );
115  connect( mCallbackHandler, TQT_SIGNAL( member( const QSync::SyncMemberUpdate& ) ),
116  this, TQT_SLOT( member( const QSync::SyncMemberUpdate& ) ) );
117  connect( mSyncAction, TQT_SIGNAL( leftClickedURL() ),
118  this, TQT_SLOT( synchronize() ) );
119  connect( mConfigureAction, TQT_SIGNAL( leftClickedURL() ),
120  this, TQT_SLOT( configure() ) );
121  connect( mSyncProcess, TQT_SIGNAL( engineChanged( QSync::Engine* ) ),
122  this, TQT_SLOT( engineChanged( QSync::Engine* ) ) );
123 
124  mCallbackHandler->setEngine( mSyncProcess->engine() );
125 
126  setSelectionForegroundColor( TDEGlobalSettings::textColor() );
127  setSelectionBackgroundColor( TDEGlobalSettings::alternateBackgroundColor() );
128 
129  update();
130 }
131 
132 GroupItem::~GroupItem()
133 {
134  delete mCallbackHandler;
135  mCallbackHandler = 0;
136 }
137 
138 void GroupItem::update()
139 {
140  clear();
141 
142  mGroupName->setText( i18n( "Group: %1" ).arg( mSyncProcess->group().name() ) );
143 
144  TQDateTime dateTime = mSyncProcess->group().lastSynchronization();
145  if ( dateTime.isValid() )
146  mTime->setText( i18n( "Last synchronized on: %1" ).arg( TDEGlobal::locale()->formatDateTime( dateTime ) ) );
147  else
148  mTime->setText( i18n( "Not synchronized yet" ) );
149 
150  mProgressBar->reset();
151  mProgressBar->hide();
152 
153  QSync::Group group = mSyncProcess->group();
154  QSync::Group::Iterator memberIt( group.begin() );
155  QSync::Group::Iterator memberEndIt( group.end() );
156 
157  for ( ; memberIt != memberEndIt; ++memberIt ) {
158  MemberItem *item = new MemberItem( mBox, mSyncProcess, *memberIt );
159  item->show();
160  item->setStatusMessage( i18n( "Ready" ) );
161  mMemberItems.append( item );
162  }
163 }
164 
165 void GroupItem::clear()
166 {
167  mGroupName->setText( TQString() );
168 
169  TQValueList<MemberItem*>::Iterator it;
170  for ( it = mMemberItems.begin(); it != mMemberItems.end(); ++it )
171  delete *it;
172 
173  mMemberItems.clear();
174 }
175 
176 void GroupItem::conflict( QSync::SyncMapping mapping )
177 {
178  if ( mapping.changesCount() == 2 ) {
179  SingleConflictDialog dlg( mapping, this );
180  dlg.exec();
181  } else {
182  MultiConflictDialog dlg( mapping, this );
183  dlg.exec();
184  }
185 }
186 
187 void GroupItem::change( const QSync::SyncChangeUpdate &update )
188 {
189  switch ( update.type() ) {
190  case QSync::SyncChangeUpdate::Received:
191  mProcessedItems++;
192  mStatus->setText( i18n( "%1 entries read" ).arg( mProcessedItems ) );
193  break;
194  case QSync::SyncChangeUpdate::ReceivedInfo:
195  mStatus->setText( i18n( "Receive information" ) );
196  break;
197  case QSync::SyncChangeUpdate::Sent:
198  mProcessedItems--;
199  mStatus->setText( i18n( "%1 entries written" ).arg( mMaxProcessedItems - mProcessedItems ) );
200 
201  mProgressBar->show();
202 
203  {
204  int progress = 100;
205  if ( mMaxProcessedItems != 0 )
206  progress = (mProcessedItems * 100) / mMaxProcessedItems;
207 
208  if ( progress < 0 )
209  progress = 0;
210 
211  mProgressBar->setProgress( 100 - progress );
212  }
213  break;
214  case QSync::SyncChangeUpdate::WriteError:
215  mStatus->setText( i18n( "Error" ) );
216  KPassivePopup::message( update.result().message(), this );
217  break;
218  case QSync::SyncChangeUpdate::ReceiveError:
219  mStatus->setText( i18n( "Error" ) );
220  KPassivePopup::message( update.result().message(), this );
221  break;
222  default:
223  mStatus->setText( TQString() );
224  break;
225  }
226 }
227 
228 void GroupItem::mapping( const QSync::SyncMappingUpdate& )
229 {
230 }
231 
232 void GroupItem::engine( const QSync::SyncEngineUpdate &update )
233 {
234  switch ( update.type() ) {
235  case QSync::SyncEngineUpdate::EndPhaseConnected:
236  mStatus->setText( i18n( "Connected" ) );
237  mProgressBar->setProgress( 0 );
238  mSynchronizing = true;
239  mSyncAction->setText( "Abort Synchronization" );
240  break;
241  case QSync::SyncEngineUpdate::EndPhaseRead:
242  mStatus->setText( i18n( "Data read" ) );
243  break;
244  case QSync::SyncEngineUpdate::EndPhaseWrite:
245  mStatus->setText( i18n( "Data written" ) );
246  mProgressBar->setProgress( 100 );
247  mProcessedItems = mMaxProcessedItems = 0;
248  break;
249  case QSync::SyncEngineUpdate::EndPhaseDisconnected:
250  mStatus->setText( i18n( "Disconnected" ) );
251  break;
252  case QSync::SyncEngineUpdate::Error:
253  mStatus->setText( i18n( "Synchronization failed" ) );
254  KPassivePopup::message( update.result().message(), this );
255  this->update();
256 
257  mSynchronizing = false;
258  mSyncAction->setText( i18n( "Synchronize Now" ) );
259  break;
260  case QSync::SyncEngineUpdate::SyncSuccessfull:
261  mStatus->setText( i18n( "Successfully synchronized" ) );
262  mSyncProcess->group().setLastSynchronization( TQDateTime::currentDateTime() );
263  mSyncProcess->group().save();
264  this->update();
265 
266  mSynchronizing = false;
267  mSyncAction->setText( i18n( "Synchronize Now" ) );
268  break;
269  case QSync::SyncEngineUpdate::PrevUnclean:
270  mStatus->setText( i18n( "Previous synchronization failed" ) );
271  break;
272  case QSync::SyncEngineUpdate::EndConflicts:
273  mStatus->setText( i18n( "Conflicts solved" ) );
274  mMaxProcessedItems = mProcessedItems;
275  break;
276  default:
277  mStatus->setText( TQString() );
278  break;
279  }
280 }
281 
282 void GroupItem::member( const QSync::SyncMemberUpdate &update )
283 {
284  TQValueList<MemberItem*>::Iterator it;
285  for ( it = mMemberItems.begin(); it != mMemberItems.end(); ++it ) {
286  if ( (*it)->member() == update.member() ) {
287  switch ( update.type() ) {
288  case QSync::SyncMemberUpdate::Connected:
289  (*it)->setStatusMessage( i18n( "Connected" ) );
290  break;
291  case QSync::SyncMemberUpdate::SentChanges:
292  (*it)->setStatusMessage( i18n( "Changes read" ) );
293  break;
294  case QSync::SyncMemberUpdate::CommittedAll:
295  (*it)->setStatusMessage( i18n( "Changes written" ) );
296  break;
297  case QSync::SyncMemberUpdate::Disconnected:
298  (*it)->setStatusMessage( i18n( "Disconnected" ) );
299  break;
300  case QSync::SyncMemberUpdate::ConnectError:
301  (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) );
302  break;
303  case QSync::SyncMemberUpdate::GetChangesError:
304  (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) );
305  break;
306  case QSync::SyncMemberUpdate::CommittedAllError:
307  (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) );
308  break;
309  case QSync::SyncMemberUpdate::SyncDoneError:
310  (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) );
311  break;
312  case QSync::SyncMemberUpdate::DisconnectedError:
313  (*it)->setStatusMessage( i18n( "Error: %1" ).arg( update.result().message() ) );
314  break;
315  default:
316  break;
317  }
318 
319  return;
320  }
321  }
322 }
323 
324 void GroupItem::synchronize()
325 {
326  if ( !mSynchronizing )
327  emit synchronizeGroup( mSyncProcess );
328  else
329  emit abortSynchronizeGroup( mSyncProcess );
330 }
331 
332 void GroupItem::configure()
333 {
334  emit configureGroup( mSyncProcess );
335 
336  this->update();
337 }
338 
339 void GroupItem::engineChanged( QSync::Engine *engine )
340 {
341  Q_ASSERT( engine );
342 
343  mCallbackHandler->setEngine( engine );
344 
345  this->update();
346 }
347 
348 MemberItem::MemberItem( TQWidget *parent, SyncProcess *process,
349  const QSync::Member &member )
350  : TQWidget( parent ), mSyncProcess( process ), mMember( member )
351 {
352  TQFont boldFont;
353  boldFont.setBold( true );
354 
355  MemberInfo mi( member );
356 
357  TQPixmap icon = mi.smallIcon();
358 
359  QSync::Plugin plugin = member.plugin();
360 
361  TQVBoxLayout *layout = new TQVBoxLayout( this );
362 
363  TQHBox* box = new TQHBox( this );
364  box->setMargin( 5 );
365  box->setSpacing( 6 );
366  layout->addWidget( box );
367 
368  mIcon = new TQLabel( box );
369  mIcon->setPixmap( icon );
370  mIcon->setAlignment( TQt::AlignTop );
371  mIcon->setFixedWidth( mIcon->sizeHint().width() );
372 
373  TQVBox *nameBox = new TQVBox( box );
374  mMemberName = new TQLabel( nameBox );
375  mMemberName->setFont( boldFont );
376  mDescription = new TQLabel( nameBox );
377 
378  mStatus = new TQLabel( box );
379 
380  mMemberName->setText( member.name() );
381  mDescription->setText( plugin.longName() );
382 }
383 
384 void MemberItem::setStatusMessage( const TQString &msg )
385 {
386  mStatus->setText( msg );
387 }
388 
389 #include "groupitem.moc"