• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.12
  • kdepimlibs
  • akonadi
  • conflicthandling
conflictresolvedialog.cpp
1 /*
2  Copyright (c) 2010 KDAB
3  Author: Tobias Koenig <tokoe@kde.org>
4 
5  This library is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or (at your
8  option) any later version.
9 
10  This library is distributed in the hope that it will be useful, but WITHOUT
11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13  License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to the
17  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  02110-1301, USA.
19 */
20 
21 #include "conflictresolvedialog_p.h"
22 
23 #include "abstractdifferencesreporter.h"
24 #include "differencesalgorithminterface.h"
25 #include "typepluginloader_p.h"
26 
27 #include <QVBoxLayout>
28 #include <QLabel>
29 
30 #include <kcolorscheme.h>
31 #include <klocale.h>
32 #include <klocalizedstring.h>
33 #include <kglobal.h>
34 #include <kpushbutton.h>
35 #include <ktextbrowser.h>
36 
37 using namespace Akonadi;
38 
39 static inline QString textToHTML( const QString &text )
40 {
41  return Qt::convertFromPlainText( text );
42 }
43 
44 class HtmlDifferencesReporter : public AbstractDifferencesReporter
45 {
46  public:
47  HtmlDifferencesReporter()
48  {
49  }
50 
51  QString toHtml() const
52  {
53  return header() + mContent + footer();
54  }
55 
56  void setPropertyNameTitle( const QString &title )
57  {
58  mNameTitle = title;
59  }
60 
61  void setLeftPropertyValueTitle( const QString &title )
62  {
63  mLeftTitle = title;
64  }
65 
66  void setRightPropertyValueTitle( const QString &title )
67  {
68  mRightTitle = title;
69  }
70 
71  void addProperty( Mode mode, const QString &name, const QString &leftValue, const QString &rightValue )
72  {
73  switch ( mode ) {
74  case NormalMode:
75  mContent.append( QString::fromLatin1( "<tr><td align=\"right\"><b>%1:</b></td><td>%2</td><td></td><td>%3</td></tr>" )
76  .arg( name,
77  textToHTML( leftValue ),
78  textToHTML( rightValue ) ) );
79  break;
80  case ConflictMode:
81  mContent.append( QString::fromLatin1( "<tr><td align=\"right\"><b>%1:</b></td><td bgcolor=\"#ff8686\">%2</td><td></td><td bgcolor=\"#ff8686\">%3</td></tr>" )
82  .arg( name,
83  textToHTML( leftValue ),
84  textToHTML( rightValue ) ) );
85  break;
86  case AdditionalLeftMode:
87  mContent.append( QString::fromLatin1( "<tr><td align=\"right\"><b>%1:</b></td><td bgcolor=\"#9cff83\">%2</td><td></td><td></td></tr>" )
88  .arg( name,
89  textToHTML( leftValue ) ) );
90  break;
91  case AdditionalRightMode:
92  mContent.append( QString::fromLatin1( "<tr><td align=\"right\"><b>%1:</b></td><td></td><td></td><td bgcolor=\"#9cff83\">%2</td></tr>" )
93  .arg( name,
94  textToHTML( rightValue ) ) );
95  break;
96  }
97  }
98 
99  private:
100  QString header() const
101  {
102  QString header = QLatin1String( "<html>" );
103  header += QString::fromLatin1( "<body text=\"%1\" bgcolor=\"%2\">" )
104  .arg( KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() )
105  .arg( KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() );
106  header += QLatin1String( "<center><table>" );
107  header += QString::fromLatin1( "<tr><th align=\"center\">%1</th><th align=\"center\">%2</th><td>&nbsp;</td><th align=\"center\">%3</th></tr>" )
108  .arg( mNameTitle )
109  .arg( mLeftTitle )
110  .arg( mRightTitle );
111 
112  return header;
113  }
114 
115  QString footer() const
116  {
117  return QLatin1String( "</table></center>"
118  "</body>"
119  "</html>" );
120  }
121 
122  QString mContent;
123  QString mNameTitle;
124  QString mLeftTitle;
125  QString mRightTitle;
126 };
127 
128 static void compareItems( AbstractDifferencesReporter *reporter, const Akonadi::Item &localItem, const Akonadi::Item &otherItem )
129 {
130  if ( localItem.modificationTime() != otherItem.modificationTime() ) {
131  reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Modification Time" ),
132  KGlobal::locale()->formatDateTime( localItem.modificationTime(), KLocale::ShortDate, true ),
133  KGlobal::locale()->formatDateTime( otherItem.modificationTime(), KLocale::ShortDate, true ) );
134  }
135 
136  if ( localItem.flags() != otherItem.flags() ) {
137  QStringList localFlags;
138  foreach ( const QByteArray &localFlag, localItem.flags() ) {
139  localFlags.append( QString::fromUtf8( localFlag ) );
140  }
141 
142  QStringList otherFlags;
143  foreach ( const QByteArray &otherFlag, otherItem.flags() ) {
144  otherFlags.append( QString::fromUtf8( otherFlag ) );
145  }
146 
147  reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Flags" ),
148  localFlags.join( QLatin1String( ", " ) ),
149  otherFlags.join( QLatin1String( ", " ) ) );
150  }
151 
152  QHash<QByteArray, QByteArray> localAttributes;
153  foreach ( Akonadi::Attribute *attribute, localItem.attributes() ) {
154  localAttributes.insert( attribute->type(), attribute->serialized() );
155  }
156 
157  QHash<QByteArray, QByteArray> otherAttributes;
158  foreach ( Akonadi::Attribute *attribute, otherItem.attributes() ) {
159  otherAttributes.insert( attribute->type(), attribute->serialized() );
160  }
161 
162  if ( localAttributes != otherAttributes ) {
163  foreach ( const QByteArray &localKey, localAttributes ) {
164  if ( !otherAttributes.contains( localKey ) ) {
165  reporter->addProperty( AbstractDifferencesReporter::AdditionalLeftMode, i18n( "Attribute: %1", QString::fromUtf8( localKey ) ),
166  QString::fromUtf8( localAttributes.value( localKey ) ),
167  QString() );
168  } else {
169  const QByteArray localValue = localAttributes.value( localKey );
170  const QByteArray otherValue = otherAttributes.value( localKey );
171  if ( localValue != otherValue ) {
172  reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Attribute: %1", QString::fromUtf8( localKey ) ),
173  QString::fromUtf8( localValue ),
174  QString::fromUtf8( otherValue ) );
175  }
176  }
177  }
178 
179  foreach ( const QByteArray &otherKey, otherAttributes ) {
180  if ( !localAttributes.contains( otherKey ) ) {
181  reporter->addProperty( AbstractDifferencesReporter::AdditionalRightMode, i18n( "Attribute: %1", QString::fromUtf8( otherKey ) ),
182  QString(),
183  QString::fromUtf8( otherAttributes.value( otherKey ) ) );
184  }
185  }
186  }
187 }
188 
189 ConflictResolveDialog::ConflictResolveDialog( QWidget *parent )
190  : KDialog( parent ), mResolveStrategy( ConflictHandler::UseBothItems )
191 {
192  setCaption( i18nc( "@title:window", "Conflict Resolution" ) );
193  setButtons( User1 | User2 | User3 );
194  setDefaultButton( User3 );
195 
196  button( User3 )->setText( i18n( "Take left one" ) );
197  button( User2 )->setText( i18n( "Take right one" ) );
198  button( User1 )->setText( i18n( "Keep both" ) );
199 
200  connect( this, SIGNAL(user1Clicked()), SLOT(slotUseBothItemsChoosen()) );
201  connect( this, SIGNAL(user2Clicked()), SLOT(slotUseOtherItemChoosen()) );
202  connect( this, SIGNAL(user3Clicked()), SLOT(slotUseLocalItemChoosen()) );
203 
204  QWidget *mainWidget = new QWidget;
205  QVBoxLayout *layout = new QVBoxLayout( mainWidget );
206 
207  QLabel* label = new QLabel( i18nc( "@label", "Two updates conflict with each other.<nl/>Please choose which update(s) to apply." ), mainWidget );
208  layout->addWidget( label );
209 
210  mView = new KTextBrowser;
211 
212  layout->addWidget( mView );
213 
214  setMainWidget( mainWidget );
215 }
216 
217 void ConflictResolveDialog::setConflictingItems( const Akonadi::Item &localItem, const Akonadi::Item &otherItem )
218 {
219  mLocalItem = localItem;
220  mOtherItem = otherItem;
221 
222  HtmlDifferencesReporter reporter;
223  compareItems( &reporter, localItem, otherItem );
224 
225  if ( mLocalItem.hasPayload() && mOtherItem.hasPayload() ) {
226 
227  QObject *object = TypePluginLoader::objectForMimeTypeAndClass( localItem.mimeType(), localItem.availablePayloadMetaTypeIds() );
228  if ( object ) {
229  DifferencesAlgorithmInterface *algorithm = qobject_cast<DifferencesAlgorithmInterface*>( object );
230  if ( algorithm ) {
231  algorithm->compare( &reporter, localItem, otherItem );
232  mView->setHtml( reporter.toHtml() );
233  return;
234  }
235  }
236 
237  reporter.addProperty( HtmlDifferencesReporter::NormalMode, i18n( "Data" ),
238  QString::fromUtf8( mLocalItem.payloadData() ),
239  QString::fromUtf8( mOtherItem.payloadData() ) );
240  }
241 
242  mView->setHtml( reporter.toHtml() );
243 }
244 
245 ConflictHandler::ResolveStrategy ConflictResolveDialog::resolveStrategy() const
246 {
247  return mResolveStrategy;
248 }
249 
250 void ConflictResolveDialog::slotUseLocalItemChoosen()
251 {
252  mResolveStrategy = ConflictHandler::UseLocalItem;
253  accept();
254 }
255 
256 void ConflictResolveDialog::slotUseOtherItemChoosen()
257 {
258  mResolveStrategy = ConflictHandler::UseOtherItem;
259  accept();
260 }
261 
262 void ConflictResolveDialog::slotUseBothItemsChoosen()
263 {
264  mResolveStrategy = ConflictHandler::UseBothItems;
265  accept();
266 }
267 
268 #include "moc_conflictresolvedialog_p.cpp"
Akonadi::AbstractDifferencesReporter::AdditionalLeftMode
The left column contains a property value that is not available in the right column.
Definition: abstractdifferencesreporter.h:101
Akonadi::ConflictHandler::UseLocalItem
The local item overwrites the other item inside the Akonadi storage.
Definition: conflicthandler_p.h:58
Akonadi::ConflictResolveDialog::setConflictingItems
void setConflictingItems(const Akonadi::Item &localItem, const Akonadi::Item &otherItem)
Sets the items that causes the conflict.
Definition: conflictresolvedialog.cpp:217
Akonadi::ConflictHandler::UseBothItems
Both items are kept in the Akonadi storage.
Definition: conflicthandler_p.h:60
Akonadi::ConflictResolveDialog::resolveStrategy
ConflictHandler::ResolveStrategy resolveStrategy() const
Returns the resolve strategy the user choose.
Definition: conflictresolvedialog.cpp:245
Akonadi::Attribute
Provides interface for custom attributes for Entity.
Definition: attribute.h:138
Akonadi::DifferencesAlgorithmInterface
An interface to find out differences between two Akonadi objects.
Definition: differencesalgorithminterface.h:37
Akonadi::AbstractDifferencesReporter::ConflictMode
The left and right column show conflicting property values.
Definition: abstractdifferencesreporter.h:100
Akonadi::TypePluginLoader::objectForMimeTypeAndClass
QObject * objectForMimeTypeAndClass(const QString &mimetype, const QVector< int > &metaTypeIds, Options options=NoOptions)
Returns the type plugin object that matches the given mimetype, and any of the classes described by m...
Definition: typepluginloader.cpp:398
Akonadi::AbstractDifferencesReporter
An interface to report differences between two arbitrary objects.
Definition: abstractdifferencesreporter.h:92
Akonadi::AbstractDifferencesReporter::addProperty
virtual void addProperty(Mode mode, const QString &name, const QString &leftValue, const QString &rightValue)=0
Adds a new property entry to the table.
Akonadi::ConflictHandler::UseOtherItem
The local item is dropped and the other item from the Akonadi storage is used.
Definition: conflicthandler_p.h:59
Akonadi::AbstractDifferencesReporter::AdditionalRightMode
The right column contains a property value that is not available in the left column.
Definition: abstractdifferencesreporter.h:102
Akonadi::Attribute::serialized
virtual QByteArray serialized() const =0
Returns a QByteArray representation of the attribute which will be storaged.
Akonadi::ConflictResolveDialog::ConflictResolveDialog
ConflictResolveDialog(QWidget *parent=0)
Creates a new conflict resolve dialog.
Definition: conflictresolvedialog.cpp:189
Akonadi::ConflictHandler
A class to handle conflicts in Akonadi.
Definition: conflicthandler_p.h:39
Akonadi::ConflictHandler::ResolveStrategy
ResolveStrategy
Describes the strategy that should be used for resolving the conflict.
Definition: conflicthandler_p.h:57
Akonadi::DifferencesAlgorithmInterface::compare
virtual void compare(AbstractDifferencesReporter *reporter, const Akonadi::Item &leftItem, const Akonadi::Item &rightItem)=0
Calculates the differences between two Akonadi objects and reports them to a reporter object...
Akonadi::Attribute::type
virtual QByteArray type() const =0
Returns the type of the attribute.
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal