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

akonadi

  • 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
37using namespace Akonadi;
38
39static inline QString textToHTML( const QString &text )
40{
41 return Qt::convertFromPlainText( text );
42}
43
44class HtmlDifferencesReporter : public AbstractDifferencesReporter
45{
46public:
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
99private:
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
128static 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
189ConflictResolveDialog::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
217void 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
245ConflictHandler::ResolveStrategy ConflictResolveDialog::resolveStrategy() const
246{
247 return mResolveStrategy;
248}
249
250void ConflictResolveDialog::slotUseLocalItemChoosen()
251{
252 mResolveStrategy = ConflictHandler::UseLocalItem;
253 accept();
254}
255
256void ConflictResolveDialog::slotUseOtherItemChoosen()
257{
258 mResolveStrategy = ConflictHandler::UseOtherItem;
259 accept();
260}
261
262void ConflictResolveDialog::slotUseBothItemsChoosen()
263{
264 mResolveStrategy = ConflictHandler::UseBothItems;
265 accept();
266}
267
268#include "moc_conflictresolvedialog_p.cpp"
Akonadi::AbstractDifferencesReporter
An interface to report differences between two arbitrary objects.
Definition abstractdifferencesreporter.h:93
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::AbstractDifferencesReporter::AdditionalLeftMode
@ AdditionalLeftMode
The left column contains a property value that is not available in the right column.
Definition abstractdifferencesreporter.h:101
Akonadi::AbstractDifferencesReporter::NormalMode
@ NormalMode
The left and right column show the same property values.
Definition abstractdifferencesreporter.h:99
Akonadi::AbstractDifferencesReporter::ConflictMode
@ ConflictMode
The left and right column show conflicting property values.
Definition abstractdifferencesreporter.h:100
Akonadi::AbstractDifferencesReporter::AdditionalRightMode
@ AdditionalRightMode
The right column contains a property value that is not available in the left column.
Definition abstractdifferencesreporter.h:102
Akonadi::Attribute
Provides interface for custom attributes for Entity.
Definition attribute.h:139
Akonadi::ConflictHandler
A class to handle conflicts in Akonadi.
Definition conflicthandler_p.h:40
Akonadi::ConflictHandler::ResolveStrategy
ResolveStrategy
Describes the strategy that should be used for resolving the conflict.
Definition conflicthandler_p.h:57
Akonadi::ConflictHandler::UseOtherItem
@ UseOtherItem
The local item is dropped and the other item from the Akonadi storage is used.
Definition conflicthandler_p.h:59
Akonadi::ConflictHandler::UseBothItems
@ UseBothItems
Both items are kept in the Akonadi storage.
Definition conflicthandler_p.h:60
Akonadi::ConflictHandler::UseLocalItem
@ UseLocalItem
The local item overwrites the other item inside the Akonadi storage.
Definition conflicthandler_p.h:58
Akonadi::ConflictResolveDialog::ConflictResolveDialog
ConflictResolveDialog(QWidget *parent=0)
Creates a new conflict resolve dialog.
Definition conflictresolvedialog.cpp:189
Akonadi::ConflictResolveDialog::resolveStrategy
ConflictHandler::ResolveStrategy resolveStrategy() const
Returns the resolve strategy the user choose.
Definition conflictresolvedialog.cpp:245
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::DifferencesAlgorithmInterface
An interface to find out differences between two Akonadi objects.
Definition differencesalgorithminterface.h:38
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::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:441
Akonadi
FreeBusyManager::Singleton.
Definition actionstatemanager_p.h:28
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Jan 24 2024 00:00:00 by doxygen 1.10.0 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
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
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