-
Notifications
You must be signed in to change notification settings - Fork 40
/
qsdiffrunner.cpp
99 lines (76 loc) · 2.57 KB
/
qsdiffrunner.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* QSyncable Project
Author: Ben Lau
License: Apache-2.0
Web: https://github.com/benlau/qsyncable
*/
#include <QHash>
#include <QDebug>
#include <QLinkedList>
#include "qsdiffrunner.h"
#include "priv/qsdiffrunneralgo_p.h"
/*!
\class QSDiffRunner
\inmodule QSyncable
QSDiffRunner compares two QVariantList to produce a patch for transforming one of the list to another list with minimum no. of steps. \
The result can be applied on a QSListModel via QSPatchable interface.
QSDiffRunner use an average O(n) algorithm and therefore it should be fast enough for regular UI application.
*/
QSDiffRunner::QSDiffRunner()
{
}
QString QSDiffRunner::keyField() const
{
return m_keyField;
}
/*! \fn void QSDiffRunner::setKeyField(const QString &keyField)
Call this function to set the key field before using compare().
If it is not set, it won't be able to identify insert, remove and move
changes.
*/
void QSDiffRunner::setKeyField(const QString &keyField)
{
m_keyField = keyField;
}
/*! \fn QList<QSChange> QSDiffRunner::compare(const QVariantList &from, const QVariantList &to)
Call this function to compare two list, then return a
list of patches required to transform from a list to other with
the minimum number of steps. It uses an algorithm with average O(n) runtime.
You should set the key field before calling this function.
\sa setKeyField
*/
QSPatchSet QSDiffRunner::compare(const QVariantList &from, const QVariantList &to)
{
QSDiffRunnerAlgo algo;
algo.setKeyField(m_keyField);
return algo.compare(from, to);
}
/*! \fn bool QSDiffRunner::patch(QSPatchable *patchable, const QSPatchSet& patches) const
Call this function to patch a list model that implemented the QSPatchable interface. You should
use the result generated by QSDiffRunner::compare().
*/
bool QSDiffRunner::patch(QSPatchable *patchable, const QSPatchSet& patches) const
{
QVariantMap diff;
foreach (QSPatch patch, patches) {
switch (patch.type()) {
case QSPatch::Remove:
patchable->remove(patch.from(), patch.count());
break;
case QSPatch::Insert:
patchable->insert(patch.from(), patch.data());
break;
case QSPatch::Move:
patchable->move(patch.from(), patch.to(), patch.count());
break;
case QSPatch::Update:
if (patch.data().size() > 0) {
diff = patch.data().at(0).toMap();
}
patchable->set(patch.from(), diff);
break;
default:
break;
}
}
return true;
}