diff options
Diffstat (limited to 'Swift')
-rw-r--r-- | Swift/Controllers/Roster/TableRoster.cpp | 83 | ||||
-rw-r--r-- | Swift/Controllers/Roster/TableRoster.h | 4 | ||||
-rw-r--r-- | Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp | 18 |
3 files changed, 83 insertions, 22 deletions
diff --git a/Swift/Controllers/Roster/TableRoster.cpp b/Swift/Controllers/Roster/TableRoster.cpp index 66e3a85..54f2484 100644 --- a/Swift/Controllers/Roster/TableRoster.cpp +++ b/Swift/Controllers/Roster/TableRoster.cpp @@ -40,7 +40,7 @@ namespace Swift { struct ItemNeedsUpdate { bool operator()(const TableRoster::Item& i1, const TableRoster::Item& i2) const { - return i1.description != i2.description || i1.name != i2.name; + return i1.status != i2.status || i1.description != i2.description || i1.name != i2.name; } }; @@ -58,18 +58,24 @@ namespace Swift { using namespace Swift; -TableRoster::TableRoster(Roster* model, TimerFactory* timerFactory, int updateDelay) : model(model) { +TableRoster::TableRoster(Roster* model, TimerFactory* timerFactory, int updateDelay) : model(model), updatePending(false) { updateTimer = timerFactory->createTimer(updateDelay); - model->onChildrenChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this)); - model->onGroupAdded.connect(boost::bind(&TableRoster::scheduleUpdate, this)); - model->onDataChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this)); + updateTimer->onTick.connect(boost::bind(&TableRoster::handleUpdateTimerTick, this)); + if (model) { + model->onChildrenChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this)); + model->onGroupAdded.connect(boost::bind(&TableRoster::scheduleUpdate, this)); + model->onDataChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this)); + } } TableRoster::~TableRoster() { - model->onDataChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); - model->onGroupAdded.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); - model->onChildrenChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); updateTimer->stop(); + updateTimer->onTick.disconnect(boost::bind(&TableRoster::handleUpdateTimerTick, this)); + if (model) { + model->onDataChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); + model->onGroupAdded.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); + model->onChildrenChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); + } } size_t TableRoster::getNumberOfSections() const { @@ -94,15 +100,19 @@ void TableRoster::handleUpdateTimerTick() { // Get a model for the new roster std::vector<Section> newSections; - foreach(RosterItem* item, model->getRoot()->getDisplayedChildren()) { - if (GroupRosterItem* groupItem = boost::polymorphic_downcast<GroupRosterItem*>(item)) { - Section section(groupItem->getDisplayName()); - foreach(RosterItem* groupChildItem, groupItem->getDisplayedChildren()) { - if (ContactRosterItem* contact = boost::polymorphic_downcast<ContactRosterItem*>(groupChildItem)) { - section.items.push_back(Item(contact->getDisplayName(), contact->getStatusText(), contact->getDisplayJID())); + if (model) { + foreach(RosterItem* item, model->getRoot()->getDisplayedChildren()) { + if (GroupRosterItem* groupItem = boost::polymorphic_downcast<GroupRosterItem*>(item)) { + //std::cerr << "* " << groupItem->getDisplayName() << std::endl; + Section section(groupItem->getDisplayName()); + foreach(RosterItem* groupChildItem, groupItem->getDisplayedChildren()) { + if (ContactRosterItem* contact = boost::polymorphic_downcast<ContactRosterItem*>(groupChildItem)) { + //std::cerr << " - " << contact->getDisplayJID() << std::endl; + section.items.push_back(Item(contact->getDisplayName(), contact->getStatusText(), contact->getDisplayJID(), contact->getStatusShow())); + } } + newSections.push_back(section); } - newSections.push_back(section); } } @@ -120,17 +130,48 @@ void TableRoster::handleUpdateTimerTick() { std::vector<size_t> itemRemoves; std::vector<size_t> itemInserts; computeIndexDiff<Item, ItemEquals, ItemNeedsUpdate >(sections[sectionUpdates[i]].items, newSections[sectionPostUpdates[i]].items, itemUpdates, itemPostUpdates, itemRemoves, itemInserts); - update.insertedRows.resize(itemInserts.size()); - std::transform(itemInserts.begin(), itemInserts.end(), update.insertedRows.begin(), CreateIndexForSection(sectionPostUpdates[i])); - update.deletedRows.resize(itemRemoves.size()); - std::transform(itemRemoves.begin(), itemRemoves.end(), update.deletedRows.begin(), CreateIndexForSection(sectionPostUpdates[i])); - update.updatedRows.resize(itemUpdates.size()); - std::transform(itemUpdates.begin(), itemUpdates.end(), update.updatedRows.begin(), CreateIndexForSection(sectionPostUpdates[i])); + size_t end = update.insertedRows.size(); + update.insertedRows.resize(update.insertedRows.size() + itemInserts.size()); + std::transform(itemInserts.begin(), itemInserts.end(), update.insertedRows.begin() + end, CreateIndexForSection(sectionPostUpdates[i])); + end = update.deletedRows.size(); + update.deletedRows.resize(update.deletedRows.size() + itemRemoves.size()); + std::transform(itemRemoves.begin(), itemRemoves.end(), update.deletedRows.begin() + end, CreateIndexForSection(sectionUpdates[i])); + end = update.updatedRows.size(); + update.updatedRows.resize(update.updatedRows.size() + itemUpdates.size()); + std::transform(itemUpdates.begin(), itemUpdates.end(), update.updatedRows.begin() + end, CreateIndexForSection(sectionPostUpdates[i])); } // Switch the old model with the new sections.swap(newSections); + /* + std::cerr << "-S: "; + for (size_t i = 0; i < update.deletedSections.size(); ++i) { + std::cerr << update.deletedSections[i] << " "; + } + std::cerr << std::endl; + std::cerr << "+S: "; + for (size_t i = 0; i < update.insertedSections.size(); ++i) { + std::cerr << update.insertedSections[i] << " "; + } + std::cerr << std::endl; + std::cerr << "-R: "; + for (size_t i = 0; i < update.deletedRows.size(); ++i) { + std::cerr << update.deletedRows[i].section << "," << update.deletedRows[i].row << " "; + } + std::cerr << std::endl; + std::cerr << "*R: "; + for (size_t i = 0; i < update.updatedRows.size(); ++i) { + std::cerr << update.updatedRows[i].section << "," << update.updatedRows[i].row << " "; + } + std::cerr << std::endl; + std::cerr << "+R: "; + for (size_t i = 0; i < update.insertedRows.size(); ++i) { + std::cerr << update.insertedRows[i].section << "," << update.insertedRows[i].row << " "; + } + std::cerr << std::endl; + */ + // Emit the update onUpdate(update); } diff --git a/Swift/Controllers/Roster/TableRoster.h b/Swift/Controllers/Roster/TableRoster.h index 7360d20..a19d592 100644 --- a/Swift/Controllers/Roster/TableRoster.h +++ b/Swift/Controllers/Roster/TableRoster.h @@ -11,6 +11,7 @@ #include <Swiften/Base/boost_bsignals.h> #include <Swiften/JID/JID.h> +#include <Swiften/Elements/StatusShow.h> namespace Swift { class Roster; @@ -20,11 +21,12 @@ namespace Swift { class TableRoster { public: struct Item { - Item(const std::string& name, const std::string& description, const JID& jid) : name(name), description(description), jid(jid) { + Item(const std::string& name, const std::string& description, const JID& jid, StatusShow::Type status) : name(name), description(description), jid(jid), status(status) { } std::string name; std::string description; JID jid; + StatusShow::Type status; }; struct Index { diff --git a/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp b/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp index 97b5406..3acab12 100644 --- a/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp +++ b/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp @@ -45,6 +45,7 @@ class LeastCommonSubsequenceTest : public CppUnit::TestFixture { CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_NoCommonSequence); CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_SameSequences); CPPUNIT_TEST(testComputeIndexDiff_1); + CPPUNIT_TEST(testComputeIndexDiff_2); CPPUNIT_TEST(testComputeIndexDiff_Sequence1Empty); CPPUNIT_TEST(testComputeIndexDiff_Sequence2Empty); CPPUNIT_TEST(testComputeIndexDiff_BothSequencesEmpty); @@ -181,6 +182,23 @@ class LeastCommonSubsequenceTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts); } + void testComputeIndexDiff_2() { + std::vector<char> x = boost::assign::list_of('x')('y'); + std::vector<char> y = boost::assign::list_of('x'); + + std::vector<size_t> updates; + std::vector<size_t> postUpdates; + std::vector<size_t> removes; + std::vector<size_t> inserts; + computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); + + std::vector<size_t> expectedRemoves = boost::assign::list_of(1); + CPPUNIT_ASSERT(updates.empty()); + CPPUNIT_ASSERT(postUpdates.empty()); + CPPUNIT_ASSERT(inserts.empty()); + CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); + } + void testComputeIndexDiff_Sequence1Empty() { std::vector<char> x; std::vector<char> y = boost::assign::list_of('a')('b')('c'); |