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
99
100
101
102
103
104
105
106
107
|
/***************************************************************************
copyright : (C) 2007 by Robby Stephenson
email : robby@periapsis.org
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of version 2 of the GNU General Public License as *
* published by the Free Software Foundation; *
* *
***************************************************************************/
#include "entrymerger.h"
#include "entry.h"
#include "collection.h"
#include "tellico_kernel.h"
#include "controller.h"
#include "progressmanager.h"
#include "statusbar.h"
#include "tellico_debug.h"
#include <tdelocale.h>
#include <tqtimer.h>
using Tellico::EntryMerger;
EntryMerger::EntryMerger(Data::EntryVec entries_, TQObject* parent_)
: TQObject(parent_), m_entriesToCheck(entries_), m_origCount(entries_.count()), m_cancelled(false) {
m_entriesLeft = m_entriesToCheck;
Kernel::self()->beginCommandGroup(i18n("Merge Entries"));
TQString label = i18n("Merging entries...");
ProgressItem& item = ProgressManager::self()->newProgressItem(this, label, true /*canCancel*/);
item.setTotalSteps(m_origCount);
connect(&item, TQT_SIGNAL(signalCancelled(ProgressItem*)), TQT_SLOT(slotCancel()));
// done if no entries to merge
if(m_origCount < 2) {
TQTimer::singleShot(500, this, TQT_SLOT(slotCleanup()));
} else {
slotStartNext(); // starts fetching
}
}
void EntryMerger::slotStartNext() {
TQString statusMsg = i18n("Total merged/scanned entries: %1/%2")
.arg(m_entriesToRemove.count())
.arg(m_origCount - m_entriesToCheck.count());
StatusBar::self()->setStatus(statusMsg);
ProgressManager::self()->setProgress(this, m_origCount - m_entriesToCheck.count());
Data::EntryPtr baseEntry = m_entriesToCheck.front();
Data::EntryVec::Iterator it = m_entriesToCheck.begin();
++it; // skip checking against first
for( ; it != m_entriesToCheck.end(); ++it) {
bool match = cleanMerge(baseEntry, &*it);
if(!match) {
int score = baseEntry->collection()->sameEntry(baseEntry, &*it);
match = score >= Data::Collection::ENTRY_PERFECT_MATCH;
}
if(match) {
bool merge_ok = baseEntry->collection()->mergeEntry(baseEntry, &*it, false /*overwrite*/, true /*askUser*/);
if(merge_ok) {
m_entriesToRemove.append(it);
m_entriesLeft.remove(it);
}
}
}
m_entriesToCheck.remove(baseEntry);
if(m_cancelled || m_entriesToCheck.count() < 2) {
TQTimer::singleShot(0, this, TQT_SLOT(slotCleanup()));
} else {
TQTimer::singleShot(0, this, TQT_SLOT(slotStartNext()));
}
}
void EntryMerger::slotCancel() {
m_cancelled = true;
}
void EntryMerger::slotCleanup() {
Kernel::self()->removeEntries(m_entriesToRemove);
Controller::self()->slotUpdateSelection(0, m_entriesLeft);
StatusBar::self()->clearStatus();
ProgressManager::self()->setDone(this);
Kernel::self()->endCommandGroup();
deleteLater();
}
bool EntryMerger::cleanMerge(Data::EntryPtr e1, Data::EntryPtr e2) const {
// figure out if there's a clean merge possible
Data::FieldVec fields = e1->collection()->fields();
for(Data::FieldVecIt it = fields.begin(); it != fields.end(); ++it) {
TQString val1 = e1->field(it);
TQString val2 = e2->field(it);
if(val1 != val2 && !val1.isEmpty() && !val2.isEmpty()) {
return false;
}
}
return true;
}
#include "entrymerger.moc"
|