[app] Reworked support for folder renaming
The actual renaming is easier to do in BooksShelf rather than BooksPathModel and it generally makes more sense. Editing now also starts after long-pressing the title of the current folder.
This commit is contained in:
parent
9f1261a822
commit
34fb489107
8 changed files with 111 additions and 89 deletions
|
@ -38,24 +38,16 @@ MouseArea {
|
||||||
property alias text: label.text
|
property alias text: label.text
|
||||||
property bool currentFolder
|
property bool currentFolder
|
||||||
property bool editable
|
property bool editable
|
||||||
property bool _editing
|
|
||||||
property bool _highlighted: pressed
|
property bool _highlighted: pressed
|
||||||
property color _highlightedColor: Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
|
property color _highlightedColor: Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
|
||||||
property bool _showPress: !currentFolder && (_highlighted || pressTimer.running)
|
property bool _showPress: !currentFolder && (_highlighted || pressTimer.running)
|
||||||
|
|
||||||
signal rename(var to)
|
signal rename(var to)
|
||||||
|
signal startEdit()
|
||||||
function editName() {
|
|
||||||
if (editable && !_editing) {
|
|
||||||
editor.text = text
|
|
||||||
_editing = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onEditableChanged: {
|
onEditableChanged: {
|
||||||
if (!editable && _editing) {
|
// Sync edit field and the label
|
||||||
_editing = false
|
if (editable) editor.text = text
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
@ -94,13 +86,14 @@ MouseArea {
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if (!_editing) {
|
if (!editable) {
|
||||||
editor.text = text
|
editor.text = text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
color: (currentFolder || pressed) ? Theme.highlightColor : Theme.primaryColor
|
color: (currentFolder || pressed) ? Theme.highlightColor : Theme.primaryColor
|
||||||
opacity: _editing ? 0 : 1
|
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
|
opacity: editable ? 0 : 1
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
Behavior on color { ColorAnimation { duration: 100 } }
|
Behavior on color { ColorAnimation { duration: 100 } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,17 +108,17 @@ MouseArea {
|
||||||
textLeftMargin: 0
|
textLeftMargin: 0
|
||||||
textRightMargin: 0
|
textRightMargin: 0
|
||||||
textTopMargin: 0
|
textTopMargin: 0
|
||||||
opacity: _editing ? 1 : 0
|
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
|
opacity: editable ? 1 : 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
//% "Enter folder name"
|
//% "Enter folder name"
|
||||||
placeholderText: qsTrId("shelf-title-placeholder")
|
placeholderText: qsTrId("shelf-title-placeholder")
|
||||||
EnterKey.enabled: text.length > 0 && text !== "." && text !== ".." && text.indexOf("/") < 0
|
EnterKey.enabled: text.length > 0 && text !== "." && text !== ".." && text.indexOf("/") < 0
|
||||||
EnterKey.onClicked: {
|
EnterKey.onClicked: {
|
||||||
if (_editing) {
|
if (editable) {
|
||||||
if (text) {
|
if (text) {
|
||||||
root.rename(text)
|
root.rename(text)
|
||||||
}
|
}
|
||||||
_editing = false
|
|
||||||
parent.focus = true
|
parent.focus = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,6 +134,15 @@ MouseArea {
|
||||||
onPressed: pressTimer.start()
|
onPressed: pressTimer.start()
|
||||||
onCanceled: pressTimer.stop()
|
onCanceled: pressTimer.stop()
|
||||||
|
|
||||||
|
onPressAndHold: {
|
||||||
|
if (currentFolder && !editable) {
|
||||||
|
root.startEdit()
|
||||||
|
if (editable) {
|
||||||
|
editor.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: _showPress ? _highlightedColor : "transparent"
|
color: _showPress ? _highlightedColor : "transparent"
|
||||||
|
|
|
@ -70,12 +70,12 @@ SilicaFlickable {
|
||||||
onNeedDummyItemChanged: if (needDummyItem) hasDummyItem = true
|
onNeedDummyItemChanged: if (needDummyItem) hasDummyItem = true
|
||||||
editMode: shelfView.editMode
|
editMode: shelfView.editMode
|
||||||
onRelativePathChanged: longStartTimer.restart()
|
onRelativePathChanged: longStartTimer.restart()
|
||||||
|
onPathChanged: globalSettings.currentFolder = path
|
||||||
}
|
}
|
||||||
|
|
||||||
BooksPathModel {
|
BooksPathModel {
|
||||||
id: pathModel
|
id: pathModel
|
||||||
path: shelfModel.relativePath
|
path: shelfModel.relativePath
|
||||||
storage: shelfModel.storage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onEditModeChanged: {
|
onEditModeChanged: {
|
||||||
|
@ -176,15 +176,10 @@ SilicaFlickable {
|
||||||
BooksShelfTitle {
|
BooksShelfTitle {
|
||||||
width: grid.width
|
width: grid.width
|
||||||
text: model.name
|
text: model.name
|
||||||
editable: editMode
|
editable: editMode && currentFolder
|
||||||
currentFolder: model.index === (pathModel.count-1)
|
currentFolder: model.index === (pathModel.count-1)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (currentFolder) {
|
if (!currentFolder) {
|
||||||
if (editMode) {
|
|
||||||
console.log("editing", model.name)
|
|
||||||
editName()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("switching to", model.path)
|
console.log("switching to", model.path)
|
||||||
shelfView.stopEditing()
|
shelfView.stopEditing()
|
||||||
shelfModel.relativePath = model.path
|
shelfModel.relativePath = model.path
|
||||||
|
@ -192,8 +187,9 @@ SilicaFlickable {
|
||||||
}
|
}
|
||||||
onRename: {
|
onRename: {
|
||||||
console.log(to)
|
console.log(to)
|
||||||
model.name = to
|
shelfModel.name = to
|
||||||
}
|
}
|
||||||
|
onStartEdit: shelfView.startEditing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,9 +63,7 @@ void BooksPathModel::setPath(QString aPath)
|
||||||
int i;
|
int i;
|
||||||
QString path;
|
QString path;
|
||||||
QStringList pathList;
|
QStringList pathList;
|
||||||
QStringList parentList;
|
|
||||||
for (i=0; i<newSize; i++) {
|
for (i=0; i<newSize; i++) {
|
||||||
parentList.append(path);
|
|
||||||
if (!path.isEmpty()) path += "/";
|
if (!path.isEmpty()) path += "/";
|
||||||
path += newNames.at(i);
|
path += newNames.at(i);
|
||||||
pathList.append(path);
|
pathList.append(path);
|
||||||
|
@ -74,7 +72,7 @@ void BooksPathModel::setPath(QString aPath)
|
||||||
if (oldSize < newSize) {
|
if (oldSize < newSize) {
|
||||||
beginInsertRows(QModelIndex(), oldSize, newSize-1);
|
beginInsertRows(QModelIndex(), oldSize, newSize-1);
|
||||||
for (int i=oldSize; i<newSize; i++) {
|
for (int i=oldSize; i<newSize; i++) {
|
||||||
Data data(parentList.at(i), pathList.at(i), newNames.at(i));
|
Data data(pathList.at(i), newNames.at(i));
|
||||||
iList.append(data);
|
iList.append(data);
|
||||||
}
|
}
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
@ -104,20 +102,6 @@ void BooksPathModel::setPath(QString aPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooksPathModel::setStorage(QObject* aStorage)
|
|
||||||
{
|
|
||||||
BooksStorage storage;
|
|
||||||
if (aStorage) {
|
|
||||||
BooksStorage* newStorage = qobject_cast<BooksStorage*>(aStorage);
|
|
||||||
if (newStorage) storage.set(*newStorage);
|
|
||||||
}
|
|
||||||
if (!iStorage.equal(storage)) {
|
|
||||||
HDEBUG(storage.booksDir());
|
|
||||||
iStorage.set(storage);
|
|
||||||
Q_EMIT storageChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<int,QByteArray> BooksPathModel::roleNames() const
|
QHash<int,QByteArray> BooksPathModel::roleNames() const
|
||||||
{
|
{
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
|
@ -142,30 +126,3 @@ QVariant BooksPathModel::data(const QModelIndex& aIndex, int aRole) const
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BooksPathModel::setData(const QModelIndex& aIndex, const QVariant& aValue, int aRole)
|
|
||||||
{
|
|
||||||
const int i = aIndex.row();
|
|
||||||
if (validIndex(i) && aRole == BooksPathModelName && iStorage.isPresent()) {
|
|
||||||
QString newName(aValue.toString());
|
|
||||||
if (iList.at(i).iName != newName) {
|
|
||||||
const Data& data = iList.at(i);
|
|
||||||
QString oldPath = iStorage.fullPath(data.iPath);
|
|
||||||
QString newPath = iStorage.fullPath(data.iParentPath);
|
|
||||||
newPath += "/";
|
|
||||||
newPath += newName;
|
|
||||||
|
|
||||||
HDEBUG("renaming" << qPrintable(oldPath) << "->" << qPrintable(newPath));
|
|
||||||
if (rename(qPrintable(oldPath), qPrintable(newPath)) == 0) {
|
|
||||||
iList[i].iName = newName;
|
|
||||||
iList[i].iPath = newPath;
|
|
||||||
QModelIndex index = createIndex(i, 0);
|
|
||||||
Q_EMIT dataChanged(index, index);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
HDEBUG(strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#define BOOKS_PATH_MODEL_H
|
#define BOOKS_PATH_MODEL_H
|
||||||
|
|
||||||
#include "BooksTypes.h"
|
#include "BooksTypes.h"
|
||||||
#include "BooksStorage.h"
|
|
||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
@ -48,7 +47,6 @@ class BooksPathModel: public QAbstractListModel
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
||||||
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
|
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
|
||||||
Q_PROPERTY(QObject* storage READ storage WRITE setStorage NOTIFY storageChanged)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BooksPathModel(QObject* aParent = NULL);
|
explicit BooksPathModel(QObject* aParent = NULL);
|
||||||
|
@ -56,19 +54,15 @@ public:
|
||||||
int count() const { return iList.count(); }
|
int count() const { return iList.count(); }
|
||||||
QString path() const { return iPath; }
|
QString path() const { return iPath; }
|
||||||
void setPath(QString aPath);
|
void setPath(QString aPath);
|
||||||
QObject* storage() { return &iStorage; }
|
|
||||||
void setStorage(QObject* aStorage);
|
|
||||||
|
|
||||||
// QAbstractListModel
|
// QAbstractListModel
|
||||||
virtual QHash<int,QByteArray> roleNames() const;
|
virtual QHash<int,QByteArray> roleNames() const;
|
||||||
virtual int rowCount(const QModelIndex& aParent) const;
|
virtual int rowCount(const QModelIndex& aParent) const;
|
||||||
virtual QVariant data(const QModelIndex& aIndex, int aRole) const;
|
virtual QVariant data(const QModelIndex& aIndex, int aRole) const;
|
||||||
virtual bool setData(const QModelIndex& aIndex, const QVariant& aValue, int aRole);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void countChanged();
|
void countChanged();
|
||||||
void pathChanged();
|
void pathChanged();
|
||||||
void storageChanged();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool validIndex(int aIndex) const;
|
bool validIndex(int aIndex) const;
|
||||||
|
@ -76,14 +70,11 @@ private:
|
||||||
private:
|
private:
|
||||||
class Data {
|
class Data {
|
||||||
public:
|
public:
|
||||||
QString iParentPath;
|
|
||||||
QString iPath;
|
QString iPath;
|
||||||
QString iName;
|
QString iName;
|
||||||
Data(QString aParentPath, QString aPath, QString aName) :
|
Data(QString aPath, QString aName) : iPath(aPath), iName(aName) {}
|
||||||
iParentPath(aParentPath), iPath(aPath), iName(aName) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BooksStorage iStorage;
|
|
||||||
QList<Data> iList;
|
QList<Data> iList;
|
||||||
QString iPath;
|
QString iPath;
|
||||||
};
|
};
|
||||||
|
|
|
@ -547,10 +547,6 @@ BooksShelf::BooksShelf(BooksStorage aStorage, QString aRelativePath) :
|
||||||
// They also don't need to read the content of the directory -
|
// They also don't need to read the content of the directory -
|
||||||
// only the objects allocated by QML do that.
|
// only the objects allocated by QML do that.
|
||||||
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
|
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
int slashPos = aRelativePath.lastIndexOf('/');
|
|
||||||
iFileName = (slashPos >= 0) ?
|
|
||||||
aRelativePath.right(aRelativePath.length() - slashPos - 1) :
|
|
||||||
aRelativePath;
|
|
||||||
updatePath();
|
updatePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,6 +586,60 @@ void BooksShelf::setDevice(QString aDevice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BooksShelf::setName(QString aName)
|
||||||
|
{
|
||||||
|
if (iStorage.isValid() &&
|
||||||
|
BooksUtil::isValidFileName(aName) &&
|
||||||
|
iFileName != aName) {
|
||||||
|
QString parentDir;
|
||||||
|
const int lastSlash = iRelativePath.lastIndexOf('/');
|
||||||
|
if (lastSlash > 0) {
|
||||||
|
parentDir = iRelativePath.left(lastSlash);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString newRelativePath;
|
||||||
|
if (!parentDir.isEmpty()) {
|
||||||
|
newRelativePath = parentDir;
|
||||||
|
newRelativePath += '/';
|
||||||
|
}
|
||||||
|
newRelativePath += aName;
|
||||||
|
|
||||||
|
QString oldPath = iStorage.fullPath(iRelativePath);
|
||||||
|
QString newPath = iStorage.fullPath(newRelativePath);
|
||||||
|
|
||||||
|
HDEBUG("renaming" << qPrintable(oldPath) << "->" << qPrintable(newPath));
|
||||||
|
if (rename(qPrintable(oldPath), qPrintable(newPath)) == 0) {
|
||||||
|
const QString oldFileName(iFileName);
|
||||||
|
iRelativePath = newRelativePath;
|
||||||
|
iPath = iStorage.fullPath(iRelativePath);
|
||||||
|
updateFileName();
|
||||||
|
Q_EMIT pathChanged();
|
||||||
|
Q_EMIT relativePathChanged();
|
||||||
|
|
||||||
|
// Since this directiry has been renamed, we need to update the
|
||||||
|
// order of objects in the parent directory.
|
||||||
|
QVariantMap state;
|
||||||
|
const QString stateFile = stateFileName(parentDir);
|
||||||
|
if (HarbourJson::load(stateFile, state)) {
|
||||||
|
QVariantList order = state.value(SHELF_STATE_ORDER).toList();
|
||||||
|
int i, n = order.count();
|
||||||
|
for (i=0; i<n; i++) {
|
||||||
|
if (order.at(i).toString() == oldFileName) {
|
||||||
|
order[i] = iFileName;
|
||||||
|
state.insert(SHELF_STATE_ORDER, order);
|
||||||
|
if (HarbourJson::save(stateFile, state)) {
|
||||||
|
HDEBUG("wrote" << qPrintable(stateFile));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HDEBUG(strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BooksShelf::updatePath()
|
void BooksShelf::updatePath()
|
||||||
{
|
{
|
||||||
BooksLoadingSignalBlocker block(this);
|
BooksLoadingSignalBlocker block(this);
|
||||||
|
@ -598,6 +648,7 @@ void BooksShelf::updatePath()
|
||||||
if (iStorage.isValid()) {
|
if (iStorage.isValid()) {
|
||||||
iPath = iStorage.fullPath(iRelativePath);
|
iPath = iStorage.fullPath(iRelativePath);
|
||||||
}
|
}
|
||||||
|
updateFileName();
|
||||||
if (oldPath != iPath) {
|
if (oldPath != iPath) {
|
||||||
const int oldDummyItemIndex = iDummyItemIndex;
|
const int oldDummyItemIndex = iDummyItemIndex;
|
||||||
Counts counts(this);
|
Counts counts(this);
|
||||||
|
@ -628,6 +679,18 @@ void BooksShelf::updatePath()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BooksShelf::updateFileName()
|
||||||
|
{
|
||||||
|
const int slashPos = iRelativePath.lastIndexOf('/');
|
||||||
|
const QString fileName = (slashPos >= 0) ?
|
||||||
|
iRelativePath.right(iRelativePath.length() - slashPos - 1) :
|
||||||
|
iRelativePath;
|
||||||
|
if (iFileName != fileName) {
|
||||||
|
iFileName = fileName;
|
||||||
|
Q_EMIT nameChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BooksShelf::onLoadTaskDone()
|
void BooksShelf::onLoadTaskDone()
|
||||||
{
|
{
|
||||||
HASSERT(iLoadTask);
|
HASSERT(iLoadTask);
|
||||||
|
@ -680,7 +743,7 @@ void BooksShelf::saveState()
|
||||||
QVariantMap state;
|
QVariantMap state;
|
||||||
state.insert(SHELF_STATE_ORDER, order);
|
state.insert(SHELF_STATE_ORDER, order);
|
||||||
if (HarbourJson::save(stateFileName(), state)) {
|
if (HarbourJson::save(stateFileName(), state)) {
|
||||||
HDEBUG("wrote" << stateFileName());
|
HDEBUG("wrote" << qPrintable(stateFileName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,10 +754,10 @@ void BooksShelf::queueStateSave()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BooksShelf::stateFileName() const
|
QString BooksShelf::stateFileName(QString aRelativePath) const
|
||||||
{
|
{
|
||||||
return iStorage.isValid() ?
|
return iStorage.isValid() ?
|
||||||
iStorage.configDir().path() + "/" + iRelativePath + ("/" SHELF_STATE_FILE) :
|
iStorage.configDir().path() + "/" + aRelativePath + ("/" SHELF_STATE_FILE) :
|
||||||
QString();
|
QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,8 +808,7 @@ void BooksShelf::setEditMode(bool aEditMode)
|
||||||
iEditMode = aEditMode;
|
iEditMode = aEditMode;
|
||||||
HDEBUG(iEditMode);
|
HDEBUG(iEditMode);
|
||||||
if (iSaveTimer && iSaveTimer->saveRequested()) {
|
if (iSaveTimer && iSaveTimer->saveRequested()) {
|
||||||
iSaveTimer->cancelSave();
|
iSaveTimer->saveNow();
|
||||||
saveState();
|
|
||||||
}
|
}
|
||||||
setHasDummyItem(false);
|
setHasDummyItem(false);
|
||||||
Q_EMIT editModeChanged();
|
Q_EMIT editModeChanged();
|
||||||
|
|
|
@ -56,7 +56,7 @@ class BooksShelf: public QAbstractListModel, public BooksItem, public BooksLoadi
|
||||||
Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
|
Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
|
||||||
Q_PROPERTY(bool accessible READ accessible CONSTANT)
|
Q_PROPERTY(bool accessible READ accessible CONSTANT)
|
||||||
Q_PROPERTY(QString path READ path NOTIFY pathChanged)
|
Q_PROPERTY(QString path READ path NOTIFY pathChanged)
|
||||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
|
||||||
Q_PROPERTY(QString device READ device WRITE setDevice NOTIFY deviceChanged)
|
Q_PROPERTY(QString device READ device WRITE setDevice NOTIFY deviceChanged)
|
||||||
Q_PROPERTY(QString relativePath READ relativePath WRITE setRelativePath NOTIFY relativePathChanged)
|
Q_PROPERTY(QString relativePath READ relativePath WRITE setRelativePath NOTIFY relativePathChanged)
|
||||||
Q_PROPERTY(bool editMode READ editMode WRITE setEditMode NOTIFY editModeChanged)
|
Q_PROPERTY(bool editMode READ editMode WRITE setEditMode NOTIFY editModeChanged)
|
||||||
|
@ -90,6 +90,7 @@ public:
|
||||||
void setRelativePath(QString aPath);
|
void setRelativePath(QString aPath);
|
||||||
BooksBook* bookAt(int aIndex) const;
|
BooksBook* bookAt(int aIndex) const;
|
||||||
QObject* storage() { return &iStorage; }
|
QObject* storage() { return &iStorage; }
|
||||||
|
void setName(QString aName);
|
||||||
|
|
||||||
bool editMode() const { return iEditMode; }
|
bool editMode() const { return iEditMode; }
|
||||||
void setEditMode(bool aEditMode);
|
void setEditMode(bool aEditMode);
|
||||||
|
@ -147,6 +148,7 @@ private Q_SLOTS:
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
QString stateFileName() const;
|
QString stateFileName() const;
|
||||||
|
QString stateFileName(QString aRelativePath) const;
|
||||||
int bookIndex(BooksBook* aBook) const;
|
int bookIndex(BooksBook* aBook) const;
|
||||||
int itemIndex(QString aFileName, int aStartIndex = 0) const;
|
int itemIndex(QString aFileName, int aStartIndex = 0) const;
|
||||||
bool validIndex(int aIndex) const;
|
bool validIndex(int aIndex) const;
|
||||||
|
@ -154,6 +156,7 @@ private:
|
||||||
void queueStateSave();
|
void queueStateSave();
|
||||||
void loadBookList();
|
void loadBookList();
|
||||||
void updatePath();
|
void updatePath();
|
||||||
|
void updateFileName();
|
||||||
void submitDeleteTask(int aIndex);
|
void submitDeleteTask(int aIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -184,5 +187,7 @@ QML_DECLARE_TYPE(BooksShelf)
|
||||||
|
|
||||||
inline bool BooksShelf::validIndex(int aIndex) const
|
inline bool BooksShelf::validIndex(int aIndex) const
|
||||||
{ return aIndex >= 0 && aIndex < iList.count(); }
|
{ return aIndex >= 0 && aIndex < iList.count(); }
|
||||||
|
inline QString BooksShelf::stateFileName() const
|
||||||
|
{ return stateFileName(iRelativePath); }
|
||||||
|
|
||||||
#endif // BOOKS_SHELF_MODEL_H
|
#endif // BOOKS_SHELF_MODEL_H
|
||||||
|
|
|
@ -77,3 +77,11 @@ shared_ptr<Book> BooksUtil::bookFromFile(std::string aPath)
|
||||||
}
|
}
|
||||||
return book;
|
return book;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BooksUtil::isValidFileName(QString aName)
|
||||||
|
{
|
||||||
|
return !aName.isEmpty() &&
|
||||||
|
aName != QStringLiteral(".") &&
|
||||||
|
aName != QStringLiteral("..") &&
|
||||||
|
!aName.contains('/');
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
namespace BooksUtil {
|
namespace BooksUtil {
|
||||||
shared_ptr<Book> bookFromFile(std::string aPath);
|
shared_ptr<Book> bookFromFile(std::string aPath);
|
||||||
shared_ptr<Book> bookFromFile(QString aPath);
|
shared_ptr<Book> bookFromFile(QString aPath);
|
||||||
|
bool isValidFileName(QString aName);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline shared_ptr<Book> BooksUtil::bookFromFile(QString aPath)
|
inline shared_ptr<Book> BooksUtil::bookFromFile(QString aPath)
|
||||||
|
|
Loading…
Reference in a new issue