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
43GroupItem::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
132GroupItem::~GroupItem()
133{
134 delete mCallbackHandler;
135 mCallbackHandler = 0;
136}
137
138void 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
165void 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
176void 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
187void 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
228void GroupItem::mapping( const QSync::SyncMappingUpdate& )
229{
230}
231
232void 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
282void 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
324void GroupItem::synchronize()
325{
326 if ( !mSynchronizing )
327 emit synchronizeGroup( mSyncProcess );
328 else
329 emit abortSynchronizeGroup( mSyncProcess );
330}
331
332void GroupItem::configure()
333{
334 emit configureGroup( mSyncProcess );
335
336 this->update();
337}
338
339void GroupItem::engineChanged( QSync::Engine *engine )
340{
341 Q_ASSERT( engine );
342
343 mCallbackHandler->setEngine( engine );
344
345 this->update();
346}
347
348MemberItem::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
384void MemberItem::setStatusMessage( const TQString &msg )
385{
386 mStatus->setText( msg );
387}
388
389#include "groupitem.moc"