You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tellico/src/entrymerger.cpp

108 lines
3.7 KiB

/***************************************************************************
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, TQ_SIGNAL(signalCancelled(ProgressItem*)), TQ_SLOT(slotCancel()));
// done if no entries to merge
if(m_origCount < 2) {
TQTimer::singleShot(500, this, TQ_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, TQ_SLOT(slotCleanup()));
} else {
TQTimer::singleShot(0, this, TQ_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"