655 lines
18 KiB
C++
655 lines
18 KiB
C++
/*
|
|
* Copyright (C) 2016-2018 Jolla Ltd.
|
|
* Copyright (C) 2015-2018 Slava Monich <slava.monich@jolla.com>
|
|
*
|
|
* You may use this file under the terms of the BSD license as follows:
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* * Neither the name of Jolla Ltd nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this
|
|
* software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "BooksPageStack.h"
|
|
|
|
#include "HarbourDebug.h"
|
|
|
|
#define SignalModelChanged (1 << 0)
|
|
#define SignalCountChanged (1 << 1)
|
|
#define SignalCurrentIndexChanged (1 << 2)
|
|
#define SignalCurrentPageChanged (1 << 3)
|
|
|
|
// ==========================================================================
|
|
// BooksPageStack::Entry
|
|
// ==========================================================================
|
|
|
|
class BooksPageStack::Entry {
|
|
public:
|
|
BooksPos iPos;
|
|
int iPage;
|
|
|
|
public:
|
|
Entry() : iPos(0, 0, 0), iPage(0) {}
|
|
Entry(const BooksPos& aPos, int aPage) : iPos(aPos), iPage(aPage) {}
|
|
Entry(const Entry& aEntry) : iPos(aEntry.iPos), iPage(aEntry.iPage) {}
|
|
|
|
const Entry& operator = (const Entry& Entry)
|
|
{
|
|
iPage = Entry.iPage;
|
|
iPos = Entry.iPos;
|
|
return *this;
|
|
}
|
|
|
|
bool operator == (const Entry& aEntry) const
|
|
{
|
|
return iPage == aEntry.iPage && iPos == aEntry.iPos;
|
|
}
|
|
|
|
bool operator != (const Entry& aEntry) const
|
|
{
|
|
return iPage != aEntry.iPage || iPos != aEntry.iPos;
|
|
}
|
|
};
|
|
|
|
// ==========================================================================
|
|
// BooksPageStack::Private
|
|
// ==========================================================================
|
|
|
|
class BooksPageStack::Private : public QObject {
|
|
Q_OBJECT
|
|
public:
|
|
QList<Entry> iEntries;
|
|
int iCurrentIndex;
|
|
int iQueuedSignals;
|
|
|
|
enum {
|
|
MAX_DEPTH = 10
|
|
};
|
|
|
|
private:
|
|
BooksPos::List iPageMarks;
|
|
|
|
public:
|
|
Private(BooksPageStack* aModel);
|
|
|
|
BooksPos::Stack getStack() const;
|
|
bool atEnd() const;
|
|
bool isValidIndex(int aIndex) const;
|
|
void setCurrentIndex(int aIndex);
|
|
int currentPage() const;
|
|
int pageAt(int aIndex) const;
|
|
void setCurrentPage(int aPage);
|
|
void setPageAt(int aIndex, int aPage);
|
|
void setStack(BooksPos::List aStack, int aCurrentPos);
|
|
void setPageMarks(BooksPos::List aPageMarks);
|
|
void push(BooksPos);
|
|
void push(int aPage);
|
|
void pop();
|
|
void clear();
|
|
void emitQueuedSignals();
|
|
|
|
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;
|
|
void pageChanged(int aIndex);
|
|
void checkCurrentIndex(int aLastIndex);
|
|
void checkCurrentPage(int aLastCurrentPage);
|
|
void checkCount(int aLastCount);
|
|
int validateCurrentIndex();
|
|
void queueSignals(int aSignals);
|
|
};
|
|
|
|
BooksPageStack::Private::Private(BooksPageStack* aModel) :
|
|
QObject(aModel),
|
|
iCurrentIndex(0),
|
|
iQueuedSignals(0)
|
|
{
|
|
iEntries.append(Entry());
|
|
connect(aModel,
|
|
SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
|
|
SLOT(onModelChanged()));
|
|
connect(aModel,
|
|
SIGNAL(rowsInserted(QModelIndex,int,int)),
|
|
SLOT(onModelChanged()));
|
|
connect(aModel,
|
|
SIGNAL(rowsRemoved(QModelIndex,int,int)),
|
|
SLOT(onModelChanged()));
|
|
connect(aModel,
|
|
SIGNAL(modelReset()),
|
|
SLOT(onModelChanged()));
|
|
}
|
|
|
|
inline BooksPageStack* BooksPageStack::Private::parentModel() const
|
|
{
|
|
return qobject_cast<BooksPageStack*>(parent());
|
|
}
|
|
|
|
void BooksPageStack::Private::emitQueuedSignals()
|
|
{
|
|
static const struct SignalInfo {
|
|
int signal;
|
|
void (BooksPageStack::*fn)();
|
|
} signalInfo [] = {
|
|
{ SignalModelChanged, &BooksPageStack::changed },
|
|
{ SignalCountChanged, &BooksPageStack::countChanged },
|
|
{ SignalCurrentIndexChanged, &BooksPageStack::currentIndexChanged },
|
|
{ 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 (model->*(signalInfo[i].fn))();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void BooksPageStack::Private::onModelChanged()
|
|
{
|
|
queueSignals(SignalModelChanged);
|
|
}
|
|
|
|
inline void BooksPageStack::Private::queueSignals(int aSignals)
|
|
{
|
|
iQueuedSignals |= aSignals;
|
|
}
|
|
|
|
int BooksPageStack::Private::makeIndexValid(int aIndex) const
|
|
{
|
|
if (aIndex < 0) {
|
|
return 0;
|
|
} else if (aIndex >= iEntries.count()) {
|
|
return iEntries.count() - 1;
|
|
}
|
|
return aIndex;
|
|
}
|
|
|
|
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) {
|
|
queueSignals(SignalCurrentIndexChanged);
|
|
}
|
|
}
|
|
|
|
inline void BooksPageStack::Private::checkCurrentPage(int aLastCurrentPage)
|
|
{
|
|
if (currentPage() != aLastCurrentPage) {
|
|
queueSignals(SignalCurrentPageChanged);
|
|
}
|
|
}
|
|
|
|
inline void BooksPageStack::Private::checkCount(int aLastCount)
|
|
{
|
|
if (iEntries.count() != aLastCount) {
|
|
queueSignals(SignalCountChanged);
|
|
}
|
|
}
|
|
|
|
int BooksPageStack::Private::validateCurrentIndex()
|
|
{
|
|
const int validIndex = makeIndexValid(iCurrentIndex);
|
|
if (iCurrentIndex != validIndex) {
|
|
iCurrentIndex = validIndex;
|
|
queueSignals(SignalCurrentIndexChanged);
|
|
}
|
|
return iCurrentIndex;
|
|
}
|
|
|
|
inline int BooksPageStack::Private::currentPage() const
|
|
{
|
|
return iEntries.at(iCurrentIndex).iPage;
|
|
}
|
|
|
|
int BooksPageStack::Private::pageAt(int aIndex) const
|
|
{
|
|
if (isValidIndex(aIndex)) {
|
|
return iEntries.at(aIndex).iPage;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void BooksPageStack::Private::setCurrentIndex(int aIndex)
|
|
{
|
|
const int newIndex = makeIndexValid(aIndex);
|
|
if (iCurrentIndex != newIndex) {
|
|
const int oldCurrentPage = currentPage();
|
|
iCurrentIndex = newIndex;
|
|
HDEBUG(iCurrentIndex);
|
|
checkCurrentPage(oldCurrentPage);
|
|
queueSignals(SignalCurrentIndexChanged);
|
|
}
|
|
}
|
|
|
|
void BooksPageStack::Private::setPageAt(int aIndex, int aPage)
|
|
{
|
|
Entry entry = iEntries.at(aIndex);
|
|
if (entry.iPage != aPage) {
|
|
entry.iPage = aPage;
|
|
const int np = iPageMarks.count();
|
|
if (np > 0) {
|
|
entry.iPos = (aPage < 0) ? iPageMarks.at(0) :
|
|
(aPage >= np) ? iPageMarks.at(np-1) :
|
|
iPageMarks.at(aPage);
|
|
} else {
|
|
entry.iPos.set(0, 0, 0);
|
|
}
|
|
iEntries[aIndex] = entry;
|
|
pageChanged(aIndex);
|
|
}
|
|
}
|
|
|
|
inline void BooksPageStack::Private::setCurrentPage(int aPage)
|
|
{
|
|
setPageAt(iCurrentIndex, aPage);
|
|
}
|
|
|
|
void BooksPageStack::Private::pageChanged(int aIndex)
|
|
{
|
|
QVector<int> roles;
|
|
roles.append(PageRole);
|
|
BooksPageStack* model = parentModel();
|
|
QModelIndex modelIndex(model->createIndex(aIndex, 0));
|
|
Q_EMIT model->dataChanged(modelIndex, modelIndex, roles);
|
|
if (aIndex == iCurrentIndex) {
|
|
queueSignals(SignalCurrentPageChanged);
|
|
}
|
|
}
|
|
|
|
void BooksPageStack::Private::setStack(BooksPos::List aStack, int aStackPos)
|
|
{
|
|
if (aStack.isEmpty()) {
|
|
aStack = BooksPos::List();
|
|
aStack.append(BooksPos(0, 0, 0));
|
|
}
|
|
|
|
// First entry (always exists)
|
|
BooksPos pos = aStack.at(0);
|
|
Entry lastEntry(pos, findPage(pos));
|
|
if (iEntries.at(0) != lastEntry) {
|
|
iEntries[0] = lastEntry;
|
|
pageChanged(0);
|
|
} else {
|
|
iEntries[0] = lastEntry;
|
|
}
|
|
|
|
// Update other entries
|
|
int entryIndex = 1, stackIndex = 1;
|
|
const int oldEntryCount = iEntries.count();
|
|
while (entryIndex < oldEntryCount && stackIndex < aStack.count()) {
|
|
pos = aStack.at(stackIndex++);
|
|
Entry entry(pos, findPage(pos));
|
|
if (iEntries.at(entryIndex) != entry) {
|
|
iEntries[entryIndex] = entry;
|
|
pageChanged(entryIndex);
|
|
} else {
|
|
iEntries[entryIndex] = entry;
|
|
}
|
|
lastEntry = entry;
|
|
entryIndex++;
|
|
}
|
|
|
|
if (entryIndex < oldEntryCount) {
|
|
// We have run out of stack entries, remove remainig rows
|
|
BooksPageStack* model = parentModel();
|
|
model->beginRemoveRows(QModelIndex(), entryIndex, oldEntryCount-1);
|
|
while (iEntries.count() > entryIndex) {
|
|
iEntries.removeLast();
|
|
}
|
|
model->endRemoveRows();
|
|
queueSignals(SignalCountChanged);
|
|
} else {
|
|
// Add new entries if necessary
|
|
while (stackIndex < aStack.count()) {
|
|
pos = aStack.at(stackIndex++);
|
|
Entry entry(pos, findPage(pos));
|
|
if (entry != lastEntry) {
|
|
iEntries.append(entry);
|
|
lastEntry = entry;
|
|
}
|
|
}
|
|
const int n = iEntries.count();
|
|
if (n > oldEntryCount) {
|
|
// We have added some entries, update the model
|
|
BooksPageStack* model = parentModel();
|
|
model->beginInsertRows(QModelIndex(), oldEntryCount, n-1);
|
|
model->endInsertRows();
|
|
queueSignals(SignalCountChanged);
|
|
}
|
|
}
|
|
|
|
setCurrentIndex(aStackPos);
|
|
validateCurrentIndex();
|
|
}
|
|
|
|
void BooksPageStack::Private::setPageMarks(BooksPos::List aPageMarks)
|
|
{
|
|
if (iPageMarks != aPageMarks) {
|
|
iPageMarks = aPageMarks;
|
|
const int prevCurrentPage = currentPage();
|
|
HDEBUG(iPageMarks);
|
|
const int n = iEntries.count();
|
|
for (int i=0; i<n; i++) {
|
|
Entry entry = iEntries.at(i);
|
|
const int page = findPage(entry.iPos);
|
|
if (entry.iPage != page) {
|
|
entry.iPage = page;
|
|
iEntries[i] = entry;
|
|
pageChanged(i);
|
|
}
|
|
}
|
|
checkCurrentPage(prevCurrentPage);
|
|
}
|
|
}
|
|
|
|
int BooksPageStack::Private::findPage(BooksPos aPos) const
|
|
{
|
|
BooksPos::ConstIterator it = qBinaryFind(iPageMarks, aPos);
|
|
if (it == iPageMarks.end()) {
|
|
it = qLowerBound(iPageMarks, aPos);
|
|
if (it == iPageMarks.end()) {
|
|
return iPageMarks.count() - 1;
|
|
} else if (it == iPageMarks.begin()) {
|
|
return 0;
|
|
} else {
|
|
return (it - iPageMarks.begin()) - 1;
|
|
}
|
|
} else {
|
|
return it - iPageMarks.begin();
|
|
}
|
|
}
|
|
|
|
BooksPos BooksPageStack::Private::getPosAt(int aIndex) const
|
|
{
|
|
if (iPageMarks.isEmpty()) {
|
|
return BooksPos(0, 0, 0);
|
|
} else if (aIndex < 0) {
|
|
return iPageMarks.first();
|
|
} else if (aIndex >= iPageMarks.count()) {
|
|
return iPageMarks.last();
|
|
} else {
|
|
return iPageMarks.at(aIndex);
|
|
}
|
|
}
|
|
|
|
void BooksPageStack::Private::push(BooksPos aPos, int aPage)
|
|
{
|
|
Entry last = iEntries.last();
|
|
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();
|
|
}
|
|
model->endRemoveRows();
|
|
queueSignals(SignalCountChanged);
|
|
}
|
|
// 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; i<n; i++) {
|
|
iEntries[i-1] = iEntries[i];
|
|
pageChanged(i-1);
|
|
}
|
|
iEntries[n-1] = Entry(aPos, aPage);
|
|
pageChanged(n-1);
|
|
checkCurrentPage(oldCurrentPage);
|
|
} else {
|
|
// Just push the new one
|
|
const int i = iCurrentIndex+1;
|
|
BooksPageStack* model = parentModel();
|
|
model->beginInsertRows(QModelIndex(), i, i);
|
|
iEntries.append(Entry(aPos, aPage));
|
|
model->endInsertRows();
|
|
queueSignals(SignalCountChanged);
|
|
setCurrentIndex(i);
|
|
}
|
|
}
|
|
|
|
void BooksPageStack::Private::push(BooksPos aPos)
|
|
{
|
|
if (!atEnd() || iEntries.last().iPos != aPos) {
|
|
push(aPos, findPage(aPos));
|
|
}
|
|
}
|
|
|
|
void BooksPageStack::Private::push(int aPage)
|
|
{
|
|
if (!atEnd() || iEntries.last().iPage != aPage) {
|
|
push(getPosAt(aPage), aPage);
|
|
}
|
|
}
|
|
|
|
void BooksPageStack::Private::pop()
|
|
{
|
|
const int n = iEntries.count();
|
|
if (n > 1) {
|
|
BooksPageStack* model = parentModel();
|
|
model->beginRemoveRows(QModelIndex(), n-1, n-1);
|
|
iEntries.removeLast();
|
|
validateCurrentIndex();
|
|
model->endRemoveRows();
|
|
queueSignals(SignalCountChanged);
|
|
}
|
|
}
|
|
|
|
void BooksPageStack::Private::clear()
|
|
{
|
|
const int n = iEntries.count();
|
|
if (n > 1) {
|
|
BooksPageStack* model = parentModel();
|
|
Entry currentEntry = iEntries.at(iCurrentIndex);
|
|
model->beginRemoveRows(QModelIndex(), 1, n-1);
|
|
while (iEntries.count() > 1) {
|
|
iEntries.removeLast();
|
|
}
|
|
validateCurrentIndex();
|
|
model->endRemoveRows();
|
|
if (iEntries.at(0) != currentEntry) {
|
|
iEntries[0] = currentEntry;
|
|
pageChanged(0);
|
|
}
|
|
queueSignals(SignalCountChanged);
|
|
}
|
|
}
|
|
|
|
BooksPos::Stack BooksPageStack::Private::getStack() const
|
|
{
|
|
const int n = iEntries.count();
|
|
BooksPos::Stack stack;
|
|
stack.iList.reserve(n);
|
|
for (int i=0; i<n; i++) {
|
|
stack.iList.append(iEntries.at(i).iPos);
|
|
}
|
|
stack.iPos = iCurrentIndex;
|
|
return stack;
|
|
}
|
|
|
|
// ==========================================================================
|
|
// BooksPageStack
|
|
// ==========================================================================
|
|
|
|
BooksPageStack::BooksPageStack(QObject* aParent) :
|
|
QAbstractListModel(aParent),
|
|
iPrivate(new Private(this))
|
|
{
|
|
#if QT_VERSION < 0x050000
|
|
setRoleNames(roleNames());
|
|
#endif
|
|
}
|
|
|
|
int BooksPageStack::count() const
|
|
{
|
|
return iPrivate->iEntries.count();
|
|
}
|
|
|
|
int BooksPageStack::currentIndex() const
|
|
{
|
|
return iPrivate->iCurrentIndex;
|
|
}
|
|
|
|
int BooksPageStack::currentPage() const
|
|
{
|
|
return iPrivate->currentPage();
|
|
}
|
|
|
|
void BooksPageStack::setCurrentIndex(int aIndex)
|
|
{
|
|
iPrivate->setCurrentIndex(aIndex);
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
void BooksPageStack::setCurrentPage(int aPage)
|
|
{
|
|
iPrivate->setCurrentPage(aPage);
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
void BooksPageStack::back()
|
|
{
|
|
iPrivate->setCurrentIndex(iPrivate->iCurrentIndex - 1);
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
void BooksPageStack::forward()
|
|
{
|
|
iPrivate->setCurrentIndex(iPrivate->iCurrentIndex + 1);
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
BooksPos::Stack BooksPageStack::getStack() const
|
|
{
|
|
return iPrivate->getStack();
|
|
}
|
|
|
|
void BooksPageStack::setStack(BooksPos::List aStack, int aCurrentPos)
|
|
{
|
|
iPrivate->setStack(aStack, aCurrentPos);
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
void BooksPageStack::setPageMarks(BooksPos::List aPageMarks)
|
|
{
|
|
iPrivate->setPageMarks(aPageMarks);
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
int BooksPageStack::pageAt(int aIndex)
|
|
{
|
|
return iPrivate->pageAt(aIndex);
|
|
}
|
|
|
|
void BooksPageStack::pushPage(int aPage)
|
|
{
|
|
HDEBUG(aPage);
|
|
iPrivate->push(aPage);
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
void BooksPageStack::pushPosition(BooksPos aPos)
|
|
{
|
|
HDEBUG("" << aPos);
|
|
iPrivate->push(aPos);
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
void BooksPageStack::pop()
|
|
{
|
|
HDEBUG("");
|
|
iPrivate->pop();
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
void BooksPageStack::clear()
|
|
{
|
|
HDEBUG("");
|
|
iPrivate->clear();
|
|
iPrivate->emitQueuedSignals();
|
|
}
|
|
|
|
QHash<int,QByteArray> BooksPageStack::roleNames() const
|
|
{
|
|
QHash<int, QByteArray> roles;
|
|
roles.insert(PageRole, "page");
|
|
return roles;
|
|
}
|
|
|
|
int BooksPageStack::rowCount(const QModelIndex&) const
|
|
{
|
|
return iPrivate->iEntries.count();
|
|
}
|
|
|
|
QVariant BooksPageStack::data(const QModelIndex& aIndex, int aRole) const
|
|
{
|
|
const int row = aIndex.row();
|
|
if (iPrivate->isValidIndex(row) && aRole == PageRole) {
|
|
return iPrivate->iEntries.at(row).iPage;
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
bool BooksPageStack::setData(const QModelIndex& aIndex, const QVariant& aValue,
|
|
int aRole)
|
|
{
|
|
const int row = aIndex.row();
|
|
if (iPrivate->isValidIndex(row) && aRole == PageRole) {
|
|
bool ok = false;
|
|
const int page = aValue.toInt(&ok);
|
|
if (page >= 0 && ok) {
|
|
iPrivate->setPageAt(row, page);
|
|
iPrivate->emitQueuedSignals();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#include "BooksPageStack.moc"
|