diff --git a/app/src/BooksPageStack.cpp b/app/src/BooksPageStack.cpp index 661adf1..1050a02 100644 --- a/app/src/BooksPageStack.cpp +++ b/app/src/BooksPageStack.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Jolla Ltd. + * Copyright (C) 2016-2018 Jolla Ltd. * Contact: Slava Monich * * You may use this file under the terms of the BSD license as follows: @@ -89,12 +89,12 @@ public: private: BooksPos::List iPageMarks; - BooksPageStack* iModel; public: Private(BooksPageStack* aModel); BooksPos::Stack getStack() const; + bool atEnd() const; bool isValidIndex(int aIndex) const; void setCurrentIndex(int aIndex); int currentPage() const; @@ -103,7 +103,6 @@ public: void setPageAt(int aIndex, int aPage); void setStack(BooksPos::List aStack, int aCurrentPos); void setPageMarks(BooksPos::List aPageMarks); - void push(BooksPos aPos, int aPage); void push(BooksPos); void push(int aPage); void pop(); @@ -114,6 +113,8 @@ private Q_SLOTS: void onModelChanged(); private: + BooksPageStack* parentModel() const; + void push(BooksPos aPos, int aPage); BooksPos getPosAt(int aIndex) const; int findPage(BooksPos aPos) const; int makeIndexValid(int aIndex) const; @@ -128,8 +129,7 @@ private: BooksPageStack::Private::Private(BooksPageStack* aModel) : QObject(aModel), iCurrentIndex(0), - iQueuedSignals(0), - iModel(aModel) + iQueuedSignals(0) { iEntries.append(Entry()); connect(aModel, @@ -146,6 +146,11 @@ BooksPageStack::Private::Private(BooksPageStack* aModel) : SLOT(onModelChanged())); } +inline BooksPageStack* BooksPageStack::Private::parentModel() const +{ + return qobject_cast(parent()); +} + void BooksPageStack::Private::emitQueuedSignals() { static const struct SignalInfo { @@ -158,10 +163,13 @@ void BooksPageStack::Private::emitQueuedSignals() { SignalCurrentPageChanged, &BooksPageStack::currentPageChanged} }; const uint n = sizeof(signalInfo)/sizeof(signalInfo[0]); - for (uint i=0; i*(signalInfo[i].fn))(); + if (iQueuedSignals) { + BooksPageStack* model = parentModel(); + for (uint i=0; i*(signalInfo[i].fn))(); + } } } } @@ -191,6 +199,11 @@ inline bool BooksPageStack::Private::isValidIndex(int aIndex) const return aIndex >= 0 && aIndex < iEntries.count(); } +inline bool BooksPageStack::Private::atEnd() const +{ + return (iCurrentIndex + 1) >= iEntries.count(); +} + inline void BooksPageStack::Private::checkCurrentIndex(int aLastIndex) { if (validateCurrentIndex() != aLastIndex) { @@ -274,8 +287,9 @@ void BooksPageStack::Private::pageChanged(int aIndex) { QVector roles; roles.append(PageRole); - QModelIndex modelIndex(iModel->createIndex(aIndex, 0)); - Q_EMIT iModel->dataChanged(modelIndex, modelIndex, roles); + BooksPageStack* model = parentModel(); + QModelIndex modelIndex(model->createIndex(aIndex, 0)); + Q_EMIT model->dataChanged(modelIndex, modelIndex, roles); } void BooksPageStack::Private::setStack(BooksPos::List aStack, int aStackPos) @@ -313,12 +327,13 @@ void BooksPageStack::Private::setStack(BooksPos::List aStack, int aStackPos) if (entryIndex < oldEntryCount) { // We have run out of stack entries, remove remainig rows - iModel->beginRemoveRows(QModelIndex(), entryIndex, oldEntryCount-1); + BooksPageStack* model = parentModel(); + model->beginRemoveRows(QModelIndex(), entryIndex, oldEntryCount-1); while (iEntries.count() > entryIndex) { iEntries.removeLast(); } - iModel->endRemoveRows(); - Q_EMIT iModel->countChanged(); + model->endRemoveRows(); + queueSignals(SignalCountChanged); } else { // Add new entries if necessary while (stackIndex < aStack.count()) { @@ -332,9 +347,10 @@ void BooksPageStack::Private::setStack(BooksPos::List aStack, int aStackPos) const int n = iEntries.count(); if (n > oldEntryCount) { // We have added some entries, update the model - iModel->beginInsertRows(QModelIndex(), oldEntryCount, n-1); - iModel->endInsertRows(); - Q_EMIT iModel->countChanged(); + BooksPageStack* model = parentModel(); + model->beginInsertRows(QModelIndex(), oldEntryCount, n-1); + model->endInsertRows(); + queueSignals(SignalCountChanged); } } @@ -395,55 +411,56 @@ BooksPos BooksPageStack::Private::getPosAt(int aIndex) const void BooksPageStack::Private::push(BooksPos aPos, int aPage) { Entry last = iEntries.last(); - if (last.iPos != aPos || last.iPage != aPage) { - const int n = iEntries.count(); - if (n >= iCurrentIndex+2) { - // Push on top of the current position. - if (n > iCurrentIndex+2) { - // Drop unnecessary entries - iModel->beginRemoveRows(QModelIndex(), iCurrentIndex+2, n-1); - while (iEntries.count() > iCurrentIndex+2) { - iEntries.removeLast(); - } - iModel->endRemoveRows(); - Q_EMIT iModel->countChanged(); - queueSignals(SignalCountChanged); + const int n = iEntries.count(); + // The caller makes sure that the operation makes sense + HASSERT(!atEnd() || last.iPos != aPos || last.iPage != aPage); + if (n >= iCurrentIndex+2) { + // Push on top of the current position. + if (n > iCurrentIndex+2) { + // Drop unnecessary entries + BooksPageStack* model = parentModel(); + model->beginRemoveRows(QModelIndex(), iCurrentIndex+2, n-1); + while (iEntries.count() > iCurrentIndex+2) { + iEntries.removeLast(); } - // And replace the next one - setPageAt(iCurrentIndex+1, aPage); - setCurrentIndex(iCurrentIndex+1); - } else if (n >= MAX_DEPTH) { - // We have reached the depth limit, push the entire stack down - const int oldCurrentPage = currentPage(); - for (int i=1; ibeginInsertRows(QModelIndex(), i, i); - iEntries.append(Entry(aPos, aPage)); - iModel->endInsertRows(); + model->endRemoveRows(); queueSignals(SignalCountChanged); - setCurrentIndex(i); } + // And replace the next one + setPageAt(iCurrentIndex+1, aPage); + setCurrentIndex(iCurrentIndex+1); + } else if (n >= MAX_DEPTH) { + // We have reached the depth limit, push the entire stack down + const int oldCurrentPage = currentPage(); + for (int i=1; ibeginInsertRows(QModelIndex(), i, i); + iEntries.append(Entry(aPos, aPage)); + model->endInsertRows(); + queueSignals(SignalCountChanged); + setCurrentIndex(i); } } void BooksPageStack::Private::push(BooksPos aPos) { - if (iEntries.last().iPos != aPos) { + if (!atEnd() || iEntries.last().iPos != aPos) { push(aPos, findPage(aPos)); } } void BooksPageStack::Private::push(int aPage) { - if (iEntries.last().iPage != aPage) { + if (!atEnd() || iEntries.last().iPage != aPage) { push(getPosAt(aPage), aPage); } } @@ -452,10 +469,11 @@ void BooksPageStack::Private::pop() { const int n = iEntries.count(); if (n > 1) { - iModel->beginRemoveRows(QModelIndex(), n-1, n-1); + BooksPageStack* model = parentModel(); + model->beginRemoveRows(QModelIndex(), n-1, n-1); iEntries.removeLast(); validateCurrentIndex(); - iModel->endRemoveRows(); + model->endRemoveRows(); queueSignals(SignalCountChanged); } } @@ -464,13 +482,14 @@ void BooksPageStack::Private::clear() { const int n = iEntries.count(); if (n > 1) { + BooksPageStack* model = parentModel(); Entry currentEntry = iEntries.at(iCurrentIndex); - iModel->beginRemoveRows(QModelIndex(), 1, n-1); + model->beginRemoveRows(QModelIndex(), 1, n-1); while (iEntries.count() > 1) { iEntries.removeLast(); } validateCurrentIndex(); - iModel->endRemoveRows(); + model->endRemoveRows(); if (iEntries.at(0) != currentEntry) { iEntries[0] = currentEntry; pageChanged(0);