[app] Corrected page stack behaviour
It couldn't push the same position that was just popped. Also, some countChanged signals were not being deferred - it was probably not intentional, at least I couldn't remember why it was done like that. Let all countChanged signals be deferred.
This commit is contained in:
parent
7a7067869d
commit
feffa61273
1 changed files with 75 additions and 56 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016-2017 Jolla Ltd.
|
||||
* Copyright (C) 2016-2018 Jolla Ltd.
|
||||
* Contact: Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* 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<BooksPageStack*>(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]);
|
||||
if (iQueuedSignals) {
|
||||
BooksPageStack* model = parentModel();
|
||||
for (uint i=0; i<n && iQueuedSignals; i++) {
|
||||
if (iQueuedSignals & signalInfo[i].signal) {
|
||||
iQueuedSignals &= ~signalInfo[i].signal;
|
||||
Q_EMIT (iModel->*(signalInfo[i].fn))();
|
||||
Q_EMIT (model->*(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<int> 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,18 +411,19 @@ 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();
|
||||
// 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
|
||||
iModel->beginRemoveRows(QModelIndex(), iCurrentIndex+2, n-1);
|
||||
BooksPageStack* model = parentModel();
|
||||
model->beginRemoveRows(QModelIndex(), iCurrentIndex+2, n-1);
|
||||
while (iEntries.count() > iCurrentIndex+2) {
|
||||
iEntries.removeLast();
|
||||
}
|
||||
iModel->endRemoveRows();
|
||||
Q_EMIT iModel->countChanged();
|
||||
model->endRemoveRows();
|
||||
queueSignals(SignalCountChanged);
|
||||
}
|
||||
// And replace the next one
|
||||
|
@ -425,25 +442,25 @@ void BooksPageStack::Private::push(BooksPos aPos, int aPage)
|
|||
} else {
|
||||
// Just push the new one
|
||||
const int i = iCurrentIndex+1;
|
||||
iModel->beginInsertRows(QModelIndex(), i, i);
|
||||
BooksPageStack* model = parentModel();
|
||||
model->beginInsertRows(QModelIndex(), i, i);
|
||||
iEntries.append(Entry(aPos, aPage));
|
||||
iModel->endInsertRows();
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue