[app] Tweaking book copy
This commit is contained in:
parent
84b9b77523
commit
c95bb79aa2
13 changed files with 230 additions and 117 deletions
|
@ -138,14 +138,24 @@ Item {
|
||||||
|
|
||||||
ProgressCircle {
|
ProgressCircle {
|
||||||
id: progressIndicator
|
id: progressIndicator
|
||||||
width: parent.width/2
|
width: busyIndicator.width
|
||||||
height: width
|
height: width
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: busyIndicator
|
||||||
opacity: (copying && !longCopyTimer.running && value > 0 && value < 1) ? 1 : 0
|
opacity: (copying && !longCopyTimer.running && value > 0 && value < 1) ? 1 : 0
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
Behavior on opacity { FadeAnimation {} }
|
Behavior on opacity { FadeAnimation {} }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
id: busyIndicator
|
||||||
|
size: BusyIndicatorSize.Medium
|
||||||
|
x: cover.x + cover.centerX - width/2
|
||||||
|
y: cover.y + cover.centerY - height/2
|
||||||
|
visible: opacity > 0
|
||||||
|
running: copying && !longCopyTimer.running && (progressIndicator.value <= 0 || progressIndicator.value >= 1)
|
||||||
|
Behavior on opacity { enabled: false }
|
||||||
|
}
|
||||||
|
|
||||||
function withinDeleteButton(x, y) {
|
function withinDeleteButton(x, y) {
|
||||||
return x >= deleteButton.x - deleteButton.margin &&
|
return x >= deleteButton.x - deleteButton.margin &&
|
||||||
x < deleteButton.x + deleteButton.width + deleteButton.margin &&
|
x < deleteButton.x + deleteButton.width + deleteButton.margin &&
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "BooksTextView.h"
|
#include "BooksTextView.h"
|
||||||
#include "BooksTextStyle.h"
|
#include "BooksTextStyle.h"
|
||||||
#include "BooksPaintContext.h"
|
#include "BooksPaintContext.h"
|
||||||
|
#include "BooksUtil.h"
|
||||||
|
|
||||||
#include "HarbourJson.h"
|
#include "HarbourJson.h"
|
||||||
#include "HarbourDebug.h"
|
#include "HarbourDebug.h"
|
||||||
|
@ -46,6 +47,7 @@
|
||||||
#include "bookmodel/BookModel.h"
|
#include "bookmodel/BookModel.h"
|
||||||
#include "library/Author.h"
|
#include "library/Author.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
|
@ -132,15 +134,16 @@ bool BooksBook::CoverPaintContext::gotIt() const
|
||||||
class BooksBook::CoverTask : public BooksTask
|
class BooksBook::CoverTask : public BooksTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CoverTask(QString aStateDir, shared_ptr<Book> aBook) :
|
CoverTask(QString aStateDir, shared_ptr<Book> aBook, QString aImagePath) :
|
||||||
iStateDir(aStateDir), iBook(aBook), iCoverMissing(false) {}
|
iStateDir(aStateDir), iBook(aBook), iImagePath(aImagePath),
|
||||||
|
iCoverMissing(false) {}
|
||||||
|
|
||||||
bool hasImage() const;
|
bool hasImage() const;
|
||||||
QString cachedImagePath() const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QString iStateDir;
|
QString iStateDir;
|
||||||
shared_ptr<Book> iBook;
|
shared_ptr<Book> iBook;
|
||||||
|
QString iImagePath;
|
||||||
QImage iCoverImage;
|
QImage iCoverImage;
|
||||||
bool iCoverMissing;
|
bool iCoverMissing;
|
||||||
};
|
};
|
||||||
|
@ -150,16 +153,6 @@ inline bool BooksBook::CoverTask::hasImage() const
|
||||||
return iCoverImage.width() > 0 && iCoverImage.height() > 0;
|
return iCoverImage.width() > 0 && iCoverImage.height() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BooksBook::CoverTask::cachedImagePath() const
|
|
||||||
{
|
|
||||||
if (!iStateDir.isEmpty()) {
|
|
||||||
return iStateDir + "/" +
|
|
||||||
QString::fromStdString(iBook->file().name(false)) +
|
|
||||||
BOOK_COVER_SUFFIX + "jpg";
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// BooksBook::LoadCoverTask
|
// BooksBook::LoadCoverTask
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -168,8 +161,8 @@ class BooksBook::LoadCoverTask : public BooksBook::CoverTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LoadCoverTask(QString aStateDir, shared_ptr<Book> aBook,
|
LoadCoverTask(QString aStateDir, shared_ptr<Book> aBook,
|
||||||
shared_ptr<FormatPlugin> aFormatPlugin) :
|
shared_ptr<FormatPlugin> aFormatPlugin, QString aImagePath) :
|
||||||
BooksBook::CoverTask(aStateDir, aBook),
|
BooksBook::CoverTask(aStateDir, aBook, aImagePath),
|
||||||
iFormatPlugin(aFormatPlugin) {}
|
iFormatPlugin(aFormatPlugin) {}
|
||||||
|
|
||||||
virtual void performTask();
|
virtual void performTask();
|
||||||
|
@ -234,8 +227,8 @@ void BooksBook::LoadCoverTask::performTask()
|
||||||
class BooksBook::GuessCoverTask : public BooksBook::CoverTask
|
class BooksBook::GuessCoverTask : public BooksBook::CoverTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuessCoverTask(QString aStateDir, shared_ptr<Book> aBook) :
|
GuessCoverTask(QString aStateDir, shared_ptr<Book> aBook, QString aImagePath) :
|
||||||
BooksBook::CoverTask(aStateDir, aBook) {}
|
BooksBook::CoverTask(aStateDir, aBook, aImagePath) {}
|
||||||
|
|
||||||
virtual void performTask();
|
virtual void performTask();
|
||||||
};
|
};
|
||||||
|
@ -264,17 +257,16 @@ void BooksBook::GuessCoverTask::performTask()
|
||||||
iCoverImage.width() << "as cover for" << iBook->title().c_str());
|
iCoverImage.width() << "as cover for" << iBook->title().c_str());
|
||||||
|
|
||||||
// Save the extracted image
|
// Save the extracted image
|
||||||
QString coverPath(cachedImagePath());
|
if (!iImagePath.isEmpty()) {
|
||||||
if (!coverPath.isEmpty()) {
|
QFileInfo file(iImagePath);
|
||||||
QFileInfo file(coverPath);
|
|
||||||
QDir dir(file.dir());
|
QDir dir(file.dir());
|
||||||
if (!dir.mkpath(dir.absolutePath())) {
|
if (!dir.mkpath(dir.absolutePath())) {
|
||||||
HWARN("failed to create" << qPrintable(dir.absolutePath()));
|
HWARN("failed to create" << qPrintable(dir.absolutePath()));
|
||||||
}
|
}
|
||||||
if (iCoverImage.save(coverPath)) {
|
if (iCoverImage.save(iImagePath)) {
|
||||||
HDEBUG("saved cover to" << qPrintable(coverPath));
|
HDEBUG("saved cover to" << qPrintable(iImagePath));
|
||||||
} else {
|
} else {
|
||||||
HWARN("failed to save" << qPrintable(coverPath));
|
HWARN("failed to save" << qPrintable(iImagePath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isCanceled()) {
|
} else if (isCanceled()) {
|
||||||
|
@ -285,12 +277,11 @@ void BooksBook::GuessCoverTask::performTask()
|
||||||
|
|
||||||
// Create empty file. Guessing the cover image is an expensive task,
|
// Create empty file. Guessing the cover image is an expensive task,
|
||||||
// we don't want to do it every time the application is started.
|
// we don't want to do it every time the application is started.
|
||||||
QString coverPath(cachedImagePath());
|
if (!iImagePath.isEmpty() &&
|
||||||
if (!coverPath.isEmpty() &&
|
|
||||||
// Check if the book file still exists - the failure could've
|
// Check if the book file still exists - the failure could've
|
||||||
// been caused by the SD-card removal.
|
// been caused by the SD-card removal.
|
||||||
QFile::exists(QString::fromStdString(iBook->file().path()))) {
|
QFile::exists(QString::fromStdString(iBook->file().path()))) {
|
||||||
QFile(coverPath).open(QIODevice::WriteOnly);
|
QFile(iImagePath).open(QIODevice::WriteOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,7 +304,7 @@ BooksBook::BooksBook(const BooksStorage& aStorage, QString aRelativePath,
|
||||||
iRef(1),
|
iRef(1),
|
||||||
iStorage(aStorage),
|
iStorage(aStorage),
|
||||||
iBook(aBook),
|
iBook(aBook),
|
||||||
iTaskQueue(BooksTaskQueue::instance())
|
iTaskQueue(BooksTaskQueue::defaultQueue())
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
HASSERT(!iBook.isNull());
|
HASSERT(!iBook.isNull());
|
||||||
|
@ -328,8 +319,10 @@ BooksBook::BooksBook(const BooksStorage& aStorage, QString aRelativePath,
|
||||||
iAuthors += QString::fromStdString(authors[i]->name());
|
iAuthors += QString::fromStdString(authors[i]->name());
|
||||||
}
|
}
|
||||||
if (iStorage.isValid()) {
|
if (iStorage.isValid()) {
|
||||||
iStateDir = iStorage.configDir().path() + "/" + aRelativePath;
|
iStateDir = QDir::cleanPath(iStorage.configDir().path() +
|
||||||
iStateFilePath = iStateDir + "/" + iFileName + BOOKS_STATE_FILE_SUFFIX;
|
QDir::separator() + aRelativePath);
|
||||||
|
iStateFilePath = QDir::cleanPath(iStateDir +
|
||||||
|
QDir::separator() + iFileName + BOOKS_STATE_FILE_SUFFIX);
|
||||||
// Load the state
|
// Load the state
|
||||||
QVariantMap state;
|
QVariantMap state;
|
||||||
if (HarbourJson::load(iStateFilePath, state)) {
|
if (HarbourJson::load(iStateFilePath, state)) {
|
||||||
|
@ -430,11 +423,6 @@ void BooksBook::setCopyingOut(bool aValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage BooksBook::coverImage()
|
|
||||||
{
|
|
||||||
return iCoverImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BooksBook::hasCoverImage() const
|
bool BooksBook::hasCoverImage() const
|
||||||
{
|
{
|
||||||
return iCoverImage.width() > 0 && iCoverImage.height() > 0;
|
return iCoverImage.width() > 0 && iCoverImage.height() > 0;
|
||||||
|
@ -453,7 +441,8 @@ bool BooksBook::requestCoverImage()
|
||||||
if (!iBook.isNull() && !iFormatPlugin.isNull() &&
|
if (!iBook.isNull() && !iFormatPlugin.isNull() &&
|
||||||
!iCoverTasksDone && !iCoverTask) {
|
!iCoverTasksDone && !iCoverTask) {
|
||||||
HDEBUG(iTitle);
|
HDEBUG(iTitle);
|
||||||
iCoverTask = new LoadCoverTask(iStateDir, iBook, iFormatPlugin);
|
iCoverTask = new LoadCoverTask(iStateDir, iBook, iFormatPlugin,
|
||||||
|
cachedImagePath());
|
||||||
connect(iCoverTask, SIGNAL(done()), SLOT(onLoadCoverTaskDone()));
|
connect(iCoverTask, SIGNAL(done()), SLOT(onLoadCoverTaskDone()));
|
||||||
iTaskQueue->submit(iCoverTask);
|
iTaskQueue->submit(iCoverTask);
|
||||||
Q_EMIT loadingCoverChanged();
|
Q_EMIT loadingCoverChanged();
|
||||||
|
@ -492,7 +481,7 @@ void BooksBook::onLoadCoverTaskDone()
|
||||||
iCoverTasksDone = true;
|
iCoverTasksDone = true;
|
||||||
Q_EMIT loadingCoverChanged();
|
Q_EMIT loadingCoverChanged();
|
||||||
} else {
|
} else {
|
||||||
iCoverTask = new GuessCoverTask(iStateDir, iBook);
|
iCoverTask = new GuessCoverTask(iStateDir, iBook, cachedImagePath());
|
||||||
connect(iCoverTask, SIGNAL(done()), SLOT(onGuessCoverTaskDone()));
|
connect(iCoverTask, SIGNAL(done()), SLOT(onGuessCoverTaskDone()));
|
||||||
iTaskQueue->submit(iCoverTask);
|
iTaskQueue->submit(iCoverTask);
|
||||||
}
|
}
|
||||||
|
@ -501,22 +490,21 @@ void BooksBook::onLoadCoverTaskDone()
|
||||||
void BooksBook::onGuessCoverTaskDone()
|
void BooksBook::onGuessCoverTaskDone()
|
||||||
{
|
{
|
||||||
HDEBUG(iTitle);
|
HDEBUG(iTitle);
|
||||||
|
|
||||||
if (iCoverTask->iCoverMissing && !iCoverImage.isNull()) {
|
|
||||||
// This may happen after the book with custom cover has been moved
|
|
||||||
// between SD-card and the internal storage. Store the custom cover
|
|
||||||
// so that it doesn't get lost. This is a fairly rare situation.
|
|
||||||
QString coverPath(iCoverTask->cachedImagePath());
|
|
||||||
if (!coverPath.isEmpty() && iCoverImage.save(coverPath)) {
|
|
||||||
HDEBUG("saved custom cover to" << qPrintable(coverPath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
coverTaskDone();
|
coverTaskDone();
|
||||||
iCoverTasksDone = true;
|
iCoverTasksDone = true;
|
||||||
Q_EMIT loadingCoverChanged();
|
Q_EMIT loadingCoverChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString BooksBook::cachedImagePath() const
|
||||||
|
{
|
||||||
|
if (!iStateDir.isEmpty() && !iBook.isNull()) {
|
||||||
|
return QDir::cleanPath(iStateDir + QDir::separator() +
|
||||||
|
QString::fromStdString(iBook->file().name(false)) +
|
||||||
|
BOOK_COVER_SUFFIX "jpg");
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
void BooksBook::saveState()
|
void BooksBook::saveState()
|
||||||
{
|
{
|
||||||
if (!iStateFilePath.isEmpty()) {
|
if (!iStateFilePath.isEmpty()) {
|
||||||
|
@ -551,6 +539,21 @@ void BooksBook::deleteFiles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BooksBook* BooksBook::newBook(const BooksStorage& aStorage, QString aRelPath,
|
||||||
|
QString aFileName)
|
||||||
|
{
|
||||||
|
shared_ptr<Book> ref = BooksUtil::bookFromFile(
|
||||||
|
QFileInfo(QDir(aStorage.fullPath(aRelPath)), aFileName).
|
||||||
|
absoluteFilePath());
|
||||||
|
if (!ref.isNull()) {
|
||||||
|
BooksBook* book = new BooksBook(aStorage, aRelPath, ref);
|
||||||
|
book->moveToThread(qApp->thread());
|
||||||
|
return book;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: below methods are invoked on the worker thread
|
// NOTE: below methods are invoked on the worker thread
|
||||||
bool BooksBook::makeLink(QString aDestPath)
|
bool BooksBook::makeLink(QString aDestPath)
|
||||||
{
|
{
|
||||||
|
@ -574,21 +577,24 @@ bool BooksBook::makeLink(QString aDestPath)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BooksBook::copyTo(QDir aDestDir, CopyOperation* aOperation)
|
BooksItem* BooksBook::copyTo(const BooksStorage& aStorage, QString aRelPath,
|
||||||
|
CopyOperation* aOperation)
|
||||||
{
|
{
|
||||||
QString destPath(QFileInfo(aDestDir, iFileName).absoluteFilePath());
|
QDir destDir(aStorage.fullPath(aRelPath));
|
||||||
aDestDir.mkpath(aDestDir.path());
|
destDir.mkpath(destDir.path());
|
||||||
if (!isCanceled(aOperation) && makeLink(destPath)) {
|
const QString absDestPath(QFileInfo(QDir(aStorage.fullPath(aRelPath)),
|
||||||
return true;
|
iFileName).absoluteFilePath());
|
||||||
|
if (!isCanceled(aOperation) && makeLink(absDestPath)) {
|
||||||
|
return newBook(aStorage, aRelPath, iFileName);
|
||||||
} else if (isCanceled(aOperation)) {
|
} else if (isCanceled(aOperation)) {
|
||||||
return true;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
bool success = false;
|
BooksBook* copy = NULL;
|
||||||
QFile src(iPath);
|
QFile src(iPath);
|
||||||
const qint64 total = src.size();
|
const qint64 total = src.size();
|
||||||
qint64 copied = 0;
|
qint64 copied = 0;
|
||||||
if (src.open(QIODevice::ReadOnly)) {
|
if (src.open(QIODevice::ReadOnly)) {
|
||||||
QFile dest(destPath);
|
QFile dest(absDestPath);
|
||||||
if (dest.open(QIODevice::WriteOnly)) {
|
if (dest.open(QIODevice::WriteOnly)) {
|
||||||
QDateTime lastTime;
|
QDateTime lastTime;
|
||||||
const qint64 bufsiz = 0x1000;
|
const qint64 bufsiz = 0x1000;
|
||||||
|
@ -614,32 +620,40 @@ bool BooksBook::copyTo(QDir aDestDir, CopyOperation* aOperation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aOperation->copyProgressChanged(PROGRESS_PRECISION);
|
|
||||||
delete [] buf;
|
delete [] buf;
|
||||||
dest.close();
|
dest.close();
|
||||||
|
aOperation->copyProgressChanged(PROGRESS_PRECISION);
|
||||||
if (copied == total) {
|
if (copied == total) {
|
||||||
dest.setPermissions(BOOKS_FILE_PERMISSIONS);
|
dest.setPermissions(BOOKS_FILE_PERMISSIONS);
|
||||||
success = true;
|
|
||||||
HDEBUG(total << "bytes copied from"<< qPrintable(iPath) <<
|
HDEBUG(total << "bytes copied from"<< qPrintable(iPath) <<
|
||||||
"to" << qPrintable(destPath));
|
"to" << qPrintable(absDestPath));
|
||||||
|
copy = newBook(aStorage, aRelPath, iFileName);
|
||||||
|
|
||||||
|
// Copy cover image too
|
||||||
|
if (copy && !iCoverImage.isNull()) {
|
||||||
|
QString cover(copy->cachedImagePath());
|
||||||
|
if (!cover.isEmpty() && iCoverImage.save(cover)) {
|
||||||
|
HDEBUG("copied cover to" << qPrintable(cover));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isCanceled(aOperation)) {
|
if (isCanceled(aOperation)) {
|
||||||
HDEBUG("copy" << qPrintable(iPath) << "to" <<
|
HDEBUG("copy" << qPrintable(iPath) << "to" <<
|
||||||
qPrintable(destPath) << "cancelled");
|
qPrintable(absDestPath) << "cancelled");
|
||||||
} else {
|
} else {
|
||||||
HWARN(copied << "out of" << total <<
|
HWARN(copied << "out of" << total <<
|
||||||
"bytes copied from" << qPrintable(iPath) <<
|
"bytes copied from" << qPrintable(iPath) <<
|
||||||
"to" << qPrintable(destPath));
|
"to" << qPrintable(absDestPath));
|
||||||
}
|
}
|
||||||
dest.remove();
|
dest.remove();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
HWARN("failed to open" << qPrintable(destPath));
|
HWARN("failed to open" << qPrintable(absDestPath));
|
||||||
}
|
}
|
||||||
src.close();
|
src.close();
|
||||||
} else {
|
} else {
|
||||||
HWARN("failed to open" << qPrintable(iPath));
|
HWARN("failed to open" << qPrintable(iPath));
|
||||||
}
|
}
|
||||||
return success;
|
return copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,9 @@ public:
|
||||||
shared_ptr<Book> aBook);
|
shared_ptr<Book> aBook);
|
||||||
~BooksBook();
|
~BooksBook();
|
||||||
|
|
||||||
|
static BooksBook* newBook(const BooksStorage& aStorage, QString aRelPath,
|
||||||
|
QString aFileName);
|
||||||
|
|
||||||
QString title() const { return iTitle; }
|
QString title() const { return iTitle; }
|
||||||
QString authors() const { return iAuthors; }
|
QString authors() const { return iAuthors; }
|
||||||
BooksPos lastPos() const { return iLastPos; }
|
BooksPos lastPos() const { return iLastPos; }
|
||||||
|
@ -82,8 +85,7 @@ public:
|
||||||
bool requestCoverImage();
|
bool requestCoverImage();
|
||||||
void cancelCoverRequest();
|
void cancelCoverRequest();
|
||||||
void setCoverImage(QImage aImage);
|
void setCoverImage(QImage aImage);
|
||||||
QImage coverImage();
|
QImage coverImage() const;
|
||||||
|
|
||||||
void setCopyingOut(bool aValue);
|
void setCopyingOut(bool aValue);
|
||||||
|
|
||||||
// BooksItem
|
// BooksItem
|
||||||
|
@ -97,7 +99,8 @@ public:
|
||||||
virtual QString path() const;
|
virtual QString path() const;
|
||||||
virtual bool accessible() const;
|
virtual bool accessible() const;
|
||||||
virtual void deleteFiles();
|
virtual void deleteFiles();
|
||||||
virtual bool copyTo(QDir aDestDir, CopyOperation* aObserver);
|
virtual BooksItem* copyTo(const BooksStorage& aStorage, QString aRelPath,
|
||||||
|
CopyOperation* aObserver);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void coverImageChanged();
|
void coverImageChanged();
|
||||||
|
@ -115,6 +118,7 @@ private:
|
||||||
void init();
|
void init();
|
||||||
bool coverTaskDone();
|
bool coverTaskDone();
|
||||||
bool makeLink(QString aDestPath);
|
bool makeLink(QString aDestPath);
|
||||||
|
QString cachedImagePath() const;
|
||||||
static bool isCanceled(CopyOperation* aOperation);
|
static bool isCanceled(CopyOperation* aOperation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -141,5 +145,7 @@ QML_DECLARE_TYPE(BooksBook)
|
||||||
|
|
||||||
inline bool BooksBook::isCanceled(CopyOperation* aObserver)
|
inline bool BooksBook::isCanceled(CopyOperation* aObserver)
|
||||||
{ return aObserver && aObserver->isCanceled(); }
|
{ return aObserver && aObserver->isCanceled(); }
|
||||||
|
inline QImage BooksBook::coverImage() const
|
||||||
|
{ return iCoverImage; }
|
||||||
|
|
||||||
#endif // BOOKS_BOOK_H
|
#endif // BOOKS_BOOK_H
|
||||||
|
|
|
@ -210,7 +210,7 @@ BooksBookModel::BooksBookModel(QObject* aParent) :
|
||||||
iTask(NULL),
|
iTask(NULL),
|
||||||
iData(NULL),
|
iData(NULL),
|
||||||
iData2(NULL),
|
iData2(NULL),
|
||||||
iTaskQueue(BooksTaskQueue::instance()),
|
iTaskQueue(BooksTaskQueue::defaultQueue()),
|
||||||
iTextStyle(BooksTextStyle::defaults())
|
iTextStyle(BooksTextStyle::defaults())
|
||||||
{
|
{
|
||||||
HDEBUG("created");
|
HDEBUG("created");
|
||||||
|
|
|
@ -198,7 +198,7 @@ void BooksCoverWidget::DefaultImage::release(QImage* aImage)
|
||||||
|
|
||||||
BooksCoverWidget::BooksCoverWidget(QQuickItem* aParent) :
|
BooksCoverWidget::BooksCoverWidget(QQuickItem* aParent) :
|
||||||
QQuickPaintedItem(aParent),
|
QQuickPaintedItem(aParent),
|
||||||
iTaskQueue(BooksTaskQueue::instance()),
|
iTaskQueue(BooksTaskQueue::scaleQueue()),
|
||||||
iScaleTask(NULL),
|
iScaleTask(NULL),
|
||||||
iBook(NULL),
|
iBook(NULL),
|
||||||
iDefaultImage(NULL),
|
iDefaultImage(NULL),
|
||||||
|
@ -234,7 +234,6 @@ void BooksCoverWidget::setBook(BooksBook* aBook)
|
||||||
if (aBook) {
|
if (aBook) {
|
||||||
(iBook = aBook)->retain();
|
(iBook = aBook)->retain();
|
||||||
iBook->requestCoverImage();
|
iBook->requestCoverImage();
|
||||||
iBookRef = iBook->bookRef();
|
|
||||||
iCoverImage = iBook->coverImage();
|
iCoverImage = iBook->coverImage();
|
||||||
iTitle = iBook->title();
|
iTitle = iBook->title();
|
||||||
connect(iBook,
|
connect(iBook,
|
||||||
|
@ -246,7 +245,6 @@ void BooksCoverWidget::setBook(BooksBook* aBook)
|
||||||
HDEBUG(iTitle);
|
HDEBUG(iTitle);
|
||||||
} else {
|
} else {
|
||||||
iBook = NULL;
|
iBook = NULL;
|
||||||
iBookRef.reset();
|
|
||||||
iCoverImage = QImage();
|
iCoverImage = QImage();
|
||||||
iTitle.clear();
|
iTitle.clear();
|
||||||
HDEBUG("<none>");
|
HDEBUG("<none>");
|
||||||
|
@ -333,7 +331,7 @@ void BooksCoverWidget::onSizeChanged()
|
||||||
|
|
||||||
bool BooksCoverWidget::empty() const
|
bool BooksCoverWidget::empty() const
|
||||||
{
|
{
|
||||||
return !iBook || !iBook->hasCoverImage() || iScaledImage.isNull();
|
return iScaledImage.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BooksCoverWidget::loading() const
|
bool BooksCoverWidget::loading() const
|
||||||
|
@ -358,6 +356,7 @@ void BooksCoverWidget::scaleImage(bool aWasEmpty)
|
||||||
HWARN("Failed to load" << qPrintable(path));
|
HWARN("Failed to load" << qPrintable(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iCoverImage.isNull()) {
|
if (iCoverImage.isNull()) {
|
||||||
if (!iDefaultImage) iDefaultImage = DefaultImage::retain();
|
if (!iDefaultImage) iDefaultImage = DefaultImage::retain();
|
||||||
if (iDefaultImage) iCoverImage = *iDefaultImage;
|
if (iDefaultImage) iCoverImage = *iDefaultImage;
|
||||||
|
@ -380,6 +379,8 @@ void BooksCoverWidget::scaleImage(bool aWasEmpty)
|
||||||
iScaledImage = QImage();
|
iScaledImage = QImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateCenter();
|
||||||
|
|
||||||
if (aWasEmpty != empty()) {
|
if (aWasEmpty != empty()) {
|
||||||
Q_EMIT emptyChanged();
|
Q_EMIT emptyChanged();
|
||||||
}
|
}
|
||||||
|
@ -393,6 +394,7 @@ void BooksCoverWidget::onScaleTaskDone()
|
||||||
iScaleTask->release(this);
|
iScaleTask->release(this);
|
||||||
iScaleTask = NULL;
|
iScaleTask = NULL;
|
||||||
update();
|
update();
|
||||||
|
updateCenter();
|
||||||
if (wasEmpty != empty()) {
|
if (wasEmpty != empty()) {
|
||||||
Q_EMIT emptyChanged();
|
Q_EMIT emptyChanged();
|
||||||
}
|
}
|
||||||
|
@ -404,6 +406,8 @@ void BooksCoverWidget::paint(QPainter* aPainter)
|
||||||
const qreal h = height();
|
const qreal h = height();
|
||||||
if (w > 0 && h > 0) {
|
if (w > 0 && h > 0) {
|
||||||
qreal sw, sh;
|
qreal sw, sh;
|
||||||
|
|
||||||
|
// This has to be consistent with updateCenter()
|
||||||
if (!iScaledImage.isNull()) {
|
if (!iScaledImage.isNull()) {
|
||||||
sw = iScaledImage.width();
|
sw = iScaledImage.width();
|
||||||
sh = iScaledImage.height();
|
sh = iScaledImage.height();
|
||||||
|
@ -412,7 +416,7 @@ void BooksCoverWidget::paint(QPainter* aPainter)
|
||||||
sh = h;
|
sh = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int x = (w - sw)/2;
|
const int x = floor((w - sw)/2);
|
||||||
const int y = h - sh;
|
const int y = h - sh;
|
||||||
|
|
||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
|
@ -424,7 +428,7 @@ void BooksCoverWidget::paint(QPainter* aPainter)
|
||||||
const qreal d = 2*iBorderRadius;
|
const qreal d = 2*iBorderRadius;
|
||||||
w1 = qMin(w, qMax(sw, 2*d)) - iBorderWidth;
|
w1 = qMin(w, qMax(sw, 2*d)) - iBorderWidth;
|
||||||
h1 = qMin(h, qMax(sh, 3*d)) - iBorderWidth;
|
h1 = qMin(h, qMax(sh, 3*d)) - iBorderWidth;
|
||||||
x1 = (w - w1)/2;
|
x1 = floor((w - w1)/2);
|
||||||
y1 = h - h1 - iBorderWidth/2;
|
y1 = h - h1 - iBorderWidth/2;
|
||||||
|
|
||||||
const qreal x2 = x1 + w1 - d;
|
const qreal x2 = x1 + w1 - d;
|
||||||
|
@ -439,7 +443,7 @@ void BooksCoverWidget::paint(QPainter* aPainter)
|
||||||
} else {
|
} else {
|
||||||
w1 = sw - iBorderWidth;
|
w1 = sw - iBorderWidth;
|
||||||
h1 = sh - iBorderWidth;
|
h1 = sh - iBorderWidth;
|
||||||
x1 = (w - w1)/2;
|
x1 = floor((w - w1)/2);
|
||||||
y1 = h - h1 - iBorderWidth/2;
|
y1 = h - h1 - iBorderWidth/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,3 +465,28 @@ void BooksCoverWidget::paint(QPainter* aPainter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BooksCoverWidget::updateCenter()
|
||||||
|
{
|
||||||
|
const QPoint oldCenter(iCenter);
|
||||||
|
const qreal w = width();
|
||||||
|
const qreal h = height();
|
||||||
|
|
||||||
|
// This has to be consistent with paint()
|
||||||
|
iCenter.setX(floor(w/2));
|
||||||
|
if (iScaledImage.isNull()) {
|
||||||
|
iCenter.setY(floor(h/2));
|
||||||
|
} else {
|
||||||
|
iCenter.setY(floor(h - iScaledImage.height()/2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iCenter != oldCenter) {
|
||||||
|
Q_EMIT centerChanged();
|
||||||
|
if (iCenter.x() != oldCenter.x()) {
|
||||||
|
Q_EMIT centerXChanged();
|
||||||
|
}
|
||||||
|
if (iCenter.y() != oldCenter.y()) {
|
||||||
|
Q_EMIT centerYChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -57,6 +57,9 @@ class BooksCoverWidget: public QQuickPaintedItem
|
||||||
Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged)
|
Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged)
|
||||||
Q_PROPERTY(QUrl defaultCover READ defaultCover WRITE setDefaultCover NOTIFY defaultCoverChanged)
|
Q_PROPERTY(QUrl defaultCover READ defaultCover WRITE setDefaultCover NOTIFY defaultCoverChanged)
|
||||||
Q_PROPERTY(BooksBook* book READ book WRITE setBook NOTIFY bookChanged)
|
Q_PROPERTY(BooksBook* book READ book WRITE setBook NOTIFY bookChanged)
|
||||||
|
Q_PROPERTY(qreal centerX READ centerX NOTIFY centerXChanged)
|
||||||
|
Q_PROPERTY(qreal centerY READ centerY NOTIFY centerYChanged)
|
||||||
|
Q_PROPERTY(QPoint center READ center NOTIFY centerChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BooksCoverWidget(QQuickItem* aParent = NULL);
|
BooksCoverWidget(QQuickItem* aParent = NULL);
|
||||||
|
@ -86,6 +89,10 @@ public:
|
||||||
bool synchronous() const { return iSynchronous; }
|
bool synchronous() const { return iSynchronous; }
|
||||||
void setSynchronous(bool aValue);
|
void setSynchronous(bool aValue);
|
||||||
|
|
||||||
|
qreal centerX() const { return iCenter.x(); }
|
||||||
|
qreal centerY() const { return iCenter.y(); }
|
||||||
|
QPoint center() const { return iCenter; }
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void bookChanged();
|
void bookChanged();
|
||||||
void emptyChanged();
|
void emptyChanged();
|
||||||
|
@ -96,6 +103,9 @@ Q_SIGNALS:
|
||||||
void borderRadiusChanged();
|
void borderRadiusChanged();
|
||||||
void borderColorChanged();
|
void borderColorChanged();
|
||||||
void defaultCoverChanged();
|
void defaultCoverChanged();
|
||||||
|
void centerXChanged();
|
||||||
|
void centerYChanged();
|
||||||
|
void centerChanged();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void onCoverImageChanged();
|
void onCoverImageChanged();
|
||||||
|
@ -106,6 +116,7 @@ private:
|
||||||
void paint(QPainter *painter);
|
void paint(QPainter *painter);
|
||||||
void scaleImage(bool aWasEmpty);
|
void scaleImage(bool aWasEmpty);
|
||||||
void scaleImage() { scaleImage(empty()); }
|
void scaleImage() { scaleImage(empty()); }
|
||||||
|
void updateCenter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ScaleTask;
|
class ScaleTask;
|
||||||
|
@ -114,7 +125,6 @@ private:
|
||||||
ScaleTask* iScaleTask;
|
ScaleTask* iScaleTask;
|
||||||
QImage iScaledImage;
|
QImage iScaledImage;
|
||||||
QImage iCoverImage;
|
QImage iCoverImage;
|
||||||
shared_ptr<Book> iBookRef;
|
|
||||||
BooksBook* iBook;
|
BooksBook* iBook;
|
||||||
QImage* iDefaultImage;
|
QImage* iDefaultImage;
|
||||||
qreal iBorderWidth;
|
qreal iBorderWidth;
|
||||||
|
@ -122,6 +132,7 @@ private:
|
||||||
QColor iBorderColor;
|
QColor iBorderColor;
|
||||||
QUrl iDefaultCover;
|
QUrl iDefaultCover;
|
||||||
QString iTitle;
|
QString iTitle;
|
||||||
|
QPoint iCenter;
|
||||||
bool iStretch;
|
bool iStretch;
|
||||||
bool iSynchronous;
|
bool iSynchronous;
|
||||||
};
|
};
|
||||||
|
|
|
@ -278,7 +278,7 @@ BooksImportModel::BooksImportModel(QObject* aParent) :
|
||||||
iProgress(0),
|
iProgress(0),
|
||||||
iSelectedCount(0),
|
iSelectedCount(0),
|
||||||
iAutoRefresh(false),
|
iAutoRefresh(false),
|
||||||
iTaskQueue(BooksTaskQueue::instance()),
|
iTaskQueue(BooksTaskQueue::defaultQueue()),
|
||||||
iTask(NULL)
|
iTask(NULL)
|
||||||
{
|
{
|
||||||
iSelectedRole.append(BooksImportRoleSelected);
|
iSelectedRole.append(BooksImportRoleSelected);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#define BOOKS_ITEM_H
|
#define BOOKS_ITEM_H
|
||||||
|
|
||||||
#include "BooksTypes.h"
|
#include "BooksTypes.h"
|
||||||
|
#include "BooksStorage.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
|
@ -65,7 +66,8 @@ public:
|
||||||
virtual QString path() const = 0;
|
virtual QString path() const = 0;
|
||||||
virtual bool accessible() const = 0;
|
virtual bool accessible() const = 0;
|
||||||
virtual void deleteFiles() = 0;
|
virtual void deleteFiles() = 0;
|
||||||
virtual bool copyTo(QDir aDestDir, CopyOperation* aOperation = NULL) = 0;
|
virtual BooksItem* copyTo(const BooksStorage& aStorage, QString aRelPath,
|
||||||
|
CopyOperation* aOperation = NULL) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BOOKS_ITEM_H
|
#endif // BOOKS_ITEM_H
|
||||||
|
|
|
@ -158,7 +158,7 @@ void BooksPageWidget::RenderTask::performTask()
|
||||||
|
|
||||||
BooksPageWidget::BooksPageWidget(QQuickItem* aParent) :
|
BooksPageWidget::BooksPageWidget(QQuickItem* aParent) :
|
||||||
QQuickPaintedItem(aParent),
|
QQuickPaintedItem(aParent),
|
||||||
iTaskQueue(BooksTaskQueue::instance()),
|
iTaskQueue(BooksTaskQueue::defaultQueue()),
|
||||||
iTextStyle(BooksTextStyle::defaults()),
|
iTextStyle(BooksTextStyle::defaults()),
|
||||||
iResizeTimer(new QTimer(this)),
|
iResizeTimer(new QTimer(this)),
|
||||||
iModel(NULL),
|
iModel(NULL),
|
||||||
|
|
|
@ -77,9 +77,12 @@ Q_SIGNALS:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BooksShelf::Data* iDestData;
|
BooksShelf::Data* iDestData;
|
||||||
|
BooksStorage iDestStorage;
|
||||||
|
QString iDestRelPath;
|
||||||
|
QString iDestAbsPath;
|
||||||
BooksItem* iSrcItem;
|
BooksItem* iSrcItem;
|
||||||
|
BooksItem* iDestItem;
|
||||||
int iCopyProgress;
|
int iCopyProgress;
|
||||||
bool iSuccess;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -323,9 +326,12 @@ inline bool BooksShelf::Data::copyingOut()
|
||||||
|
|
||||||
BooksShelf::CopyTask::CopyTask(BooksShelf::Data* aDestData, BooksItem* aSrcItem) :
|
BooksShelf::CopyTask::CopyTask(BooksShelf::Data* aDestData, BooksItem* aSrcItem) :
|
||||||
iDestData(aDestData),
|
iDestData(aDestData),
|
||||||
|
iDestStorage(aDestData->iShelf->storage()),
|
||||||
|
iDestRelPath(aDestData->iShelf->relativePath()),
|
||||||
|
iDestAbsPath(iDestStorage.fullPath(iDestRelPath + "/" + aSrcItem->fileName())),
|
||||||
iSrcItem(aSrcItem->retain()),
|
iSrcItem(aSrcItem->retain()),
|
||||||
iCopyProgress(0),
|
iDestItem(NULL),
|
||||||
iSuccess(false)
|
iCopyProgress(0)
|
||||||
{
|
{
|
||||||
if (iDestData->iCopyTask) {
|
if (iDestData->iCopyTask) {
|
||||||
iDestData->iCopyTask->release(iDestData->iShelf);
|
iDestData->iCopyTask->release(iDestData->iShelf);
|
||||||
|
@ -341,6 +347,7 @@ BooksShelf::CopyTask::~CopyTask()
|
||||||
{
|
{
|
||||||
HASSERT(!iDestData);
|
HASSERT(!iDestData);
|
||||||
iSrcItem->release();
|
iSrcItem->release();
|
||||||
|
if (iDestItem) iDestItem->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QString BooksShelf::CopyTask::srcPath() const
|
inline QString BooksShelf::CopyTask::srcPath() const
|
||||||
|
@ -350,13 +357,12 @@ inline QString BooksShelf::CopyTask::srcPath() const
|
||||||
|
|
||||||
inline QString BooksShelf::CopyTask::destPath() const
|
inline QString BooksShelf::CopyTask::destPath() const
|
||||||
{
|
{
|
||||||
return QFileInfo(iDestData->iShelf->path(),
|
return iDestAbsPath;
|
||||||
iSrcItem->fileName()).absoluteFilePath();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooksShelf::CopyTask::performTask()
|
void BooksShelf::CopyTask::performTask()
|
||||||
{
|
{
|
||||||
iSuccess = iSrcItem->copyTo(QDir(iDestData->iShelf->path()), this);
|
iDestItem = iSrcItem->copyTo(iDestStorage, iDestRelPath, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BooksShelf::CopyTask::isCanceled() const
|
bool BooksShelf::CopyTask::isCanceled() const
|
||||||
|
@ -470,7 +476,7 @@ BooksShelf::BooksShelf(QObject* aParent) :
|
||||||
iEditMode(false),
|
iEditMode(false),
|
||||||
iRef(-1),
|
iRef(-1),
|
||||||
iSaveTimer(new BooksSaveTimer(this)),
|
iSaveTimer(new BooksSaveTimer(this)),
|
||||||
iTaskQueue(BooksTaskQueue::instance())
|
iTaskQueue(BooksTaskQueue::defaultQueue())
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
connect(iSaveTimer, SIGNAL(save()), SLOT(saveState()));
|
connect(iSaveTimer, SIGNAL(save()), SLOT(saveState()));
|
||||||
|
@ -485,7 +491,7 @@ BooksShelf::BooksShelf(BooksStorage aStorage, QString aRelativePath) :
|
||||||
iEditMode(false),
|
iEditMode(false),
|
||||||
iRef(1),
|
iRef(1),
|
||||||
iSaveTimer(NULL),
|
iSaveTimer(NULL),
|
||||||
iTaskQueue(BooksTaskQueue::instance())
|
iTaskQueue(BooksTaskQueue::defaultQueue())
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
// Refcounted BooksShelf objects are managed by C++ code
|
// Refcounted BooksShelf objects are managed by C++ code
|
||||||
|
@ -1088,7 +1094,7 @@ void BooksShelf::onCopyTaskDone()
|
||||||
if (task) {
|
if (task) {
|
||||||
QString dest = task->destPath();
|
QString dest = task->destPath();
|
||||||
HDEBUG(qPrintable(task->srcPath()) << "->" << qPrintable(dest) <<
|
HDEBUG(qPrintable(task->srcPath()) << "->" << qPrintable(dest) <<
|
||||||
"copy" << (task->iSuccess ? "done" : "FAILED"));
|
"copy" << (task->iDestItem ? "done" : "FAILED"));
|
||||||
|
|
||||||
Data* data = task->iDestData;
|
Data* data = task->iDestData;
|
||||||
const int row = iList.indexOf(data);
|
const int row = iList.indexOf(data);
|
||||||
|
@ -1099,15 +1105,15 @@ void BooksShelf::onCopyTaskDone()
|
||||||
HASSERT(src);
|
HASSERT(src);
|
||||||
if (src) {
|
if (src) {
|
||||||
src->retain();
|
src->retain();
|
||||||
if (task->iSuccess) {
|
if (task->iDestItem) {
|
||||||
shared_ptr<Book> book = BooksUtil::bookFromFile(dest);
|
copy = task->iDestItem->book();
|
||||||
if (!book.isNull()) {
|
if (copy) {
|
||||||
copy = new BooksBook(iStorage, iRelativePath, book);
|
copy->retain();
|
||||||
copy->setLastPos(src->lastPos());
|
copy->setLastPos(src->lastPos());
|
||||||
copy->setCoverImage(src->coverImage());
|
copy->setCoverImage(src->coverImage());
|
||||||
copy->requestCoverImage();
|
copy->requestCoverImage();
|
||||||
} else {
|
} else {
|
||||||
HWARN("can't open copied book" << qPrintable(dest));
|
HWARN("not a book:" << qPrintable(dest));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1167,10 +1173,11 @@ void BooksShelf::deleteFiles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BooksShelf::copyTo(QDir aDestDir, CopyOperation* aOperation)
|
BooksItem* BooksShelf::copyTo(const BooksStorage& aStorage, QString aRelPath,
|
||||||
|
CopyOperation* aObserver)
|
||||||
{
|
{
|
||||||
HWARN("copying folders is not implemented!!");
|
HWARN("copying folders is not implemented!!");
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int,QByteArray> BooksShelf::roleNames() const
|
QHash<int,QByteArray> BooksShelf::roleNames() const
|
||||||
|
|
|
@ -65,7 +65,7 @@ class BooksShelf: public QAbstractListModel, public BooksItem, public BooksLoadi
|
||||||
Q_PROPERTY(int dummyItemIndex READ dummyItemIndex WRITE setDummyItemIndex NOTIFY dummyItemIndexChanged)
|
Q_PROPERTY(int dummyItemIndex READ dummyItemIndex WRITE setDummyItemIndex NOTIFY dummyItemIndexChanged)
|
||||||
Q_PROPERTY(BooksBook* book READ book CONSTANT)
|
Q_PROPERTY(BooksBook* book READ book CONSTANT)
|
||||||
Q_PROPERTY(BooksShelf* shelf READ shelf CONSTANT)
|
Q_PROPERTY(BooksShelf* shelf READ shelf CONSTANT)
|
||||||
Q_PROPERTY(QObject* storage READ storage CONSTANT)
|
Q_PROPERTY(QObject* storage READ storageObject CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BooksShelf(QObject* aParent = NULL);
|
explicit BooksShelf(QObject* aParent = NULL);
|
||||||
|
@ -89,7 +89,8 @@ public:
|
||||||
QString relativePath() const { return iRelativePath; }
|
QString relativePath() const { return iRelativePath; }
|
||||||
void setRelativePath(QString aPath);
|
void setRelativePath(QString aPath);
|
||||||
BooksBook* bookAt(int aIndex) const;
|
BooksBook* bookAt(int aIndex) const;
|
||||||
QObject* storage() { return &iStorage; }
|
QObject* storageObject() { return &iStorage; }
|
||||||
|
const BooksStorage& storage() const { return iStorage; }
|
||||||
void setName(QString aName);
|
void setName(QString aName);
|
||||||
|
|
||||||
bool editMode() const { return iEditMode; }
|
bool editMode() const { return iEditMode; }
|
||||||
|
@ -120,7 +121,8 @@ public:
|
||||||
virtual QString path() const;
|
virtual QString path() const;
|
||||||
virtual bool accessible() const;
|
virtual bool accessible() const;
|
||||||
virtual void deleteFiles();
|
virtual void deleteFiles();
|
||||||
virtual bool copyTo(QDir aDestDir, CopyOperation* aOperation);
|
virtual BooksItem* copyTo(const BooksStorage& aStorage, QString aRelPath,
|
||||||
|
CopyOperation* aObserver);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void loadingChanged();
|
void loadingChanged();
|
||||||
|
|
|
@ -36,32 +36,61 @@
|
||||||
|
|
||||||
#include "HarbourDebug.h"
|
#include "HarbourDebug.h"
|
||||||
|
|
||||||
static weak_ptr<BooksTaskQueue> booksTaskQueueInstance;
|
class BooksTaskQueue::Private {
|
||||||
|
public:
|
||||||
|
static weak_ptr<BooksTaskQueue> gDefaultQueue;
|
||||||
|
static weak_ptr<BooksTaskQueue> gScaleQueue;
|
||||||
|
|
||||||
shared_ptr<BooksTaskQueue> BooksTaskQueue::instance()
|
static BooksTaskQueue* newDefaultQueue() { return new BooksTaskQueue(1); }
|
||||||
{
|
static BooksTaskQueue* newScaleQueue() { return new BooksTaskQueue(2); }
|
||||||
shared_ptr<BooksTaskQueue> worker;
|
|
||||||
if (booksTaskQueueInstance.isNull()) {
|
static void waitForDone(shared_ptr<BooksTaskQueue> aQueue, int aMsecs) {
|
||||||
booksTaskQueueInstance = (worker = new BooksTaskQueue());
|
if (!aQueue.isNull()) {
|
||||||
} else {
|
aQueue->iPool->waitForDone(aMsecs);
|
||||||
worker = booksTaskQueueInstance;
|
}
|
||||||
}
|
}
|
||||||
return worker;
|
|
||||||
|
static void waitForDone(int aMsecs) {
|
||||||
|
waitForDone(gDefaultQueue, aMsecs);
|
||||||
|
waitForDone(gScaleQueue, aMsecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static shared_ptr<BooksTaskQueue> get(weak_ptr<BooksTaskQueue>* aQueue,
|
||||||
|
BooksTaskQueue* (*aNewFunc)())
|
||||||
|
{
|
||||||
|
shared_ptr<BooksTaskQueue> queue;
|
||||||
|
if (aQueue->isNull()) {
|
||||||
|
*aQueue = (queue = aNewFunc());
|
||||||
|
} else {
|
||||||
|
queue = *aQueue;
|
||||||
|
}
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
weak_ptr<BooksTaskQueue> BooksTaskQueue::Private::gDefaultQueue;
|
||||||
|
weak_ptr<BooksTaskQueue> BooksTaskQueue::Private::gScaleQueue;
|
||||||
|
|
||||||
|
shared_ptr<BooksTaskQueue> BooksTaskQueue::defaultQueue()
|
||||||
|
{
|
||||||
|
return Private::get(&Private::gDefaultQueue, Private::newDefaultQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
BooksTaskQueue::BooksTaskQueue() :
|
shared_ptr<BooksTaskQueue> BooksTaskQueue::scaleQueue()
|
||||||
iPool(new QThreadPool)
|
|
||||||
{
|
{
|
||||||
HDEBUG("created");
|
return Private::get(&Private::gScaleQueue, Private::newScaleQueue);
|
||||||
iPool->setMaxThreadCount(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooksTaskQueue::waitForDone(int aMsecs)
|
void BooksTaskQueue::waitForDone(int aMsecs)
|
||||||
{
|
{
|
||||||
shared_ptr<BooksTaskQueue> worker = booksTaskQueueInstance;
|
Private::waitForDone(aMsecs);
|
||||||
if (!worker.isNull()) {
|
}
|
||||||
worker->iPool->waitForDone(aMsecs);
|
|
||||||
}
|
BooksTaskQueue::BooksTaskQueue(int aMaxThreadCount) :
|
||||||
|
iPool(new QThreadPool)
|
||||||
|
{
|
||||||
|
HDEBUG("created");
|
||||||
|
iPool->setMaxThreadCount(aMaxThreadCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
BooksTaskQueue::~BooksTaskQueue()
|
BooksTaskQueue::~BooksTaskQueue()
|
||||||
|
|
|
@ -45,17 +45,20 @@ class BooksTaskQueue
|
||||||
friend class shared_ptr_storage<BooksTaskQueue>;
|
friend class shared_ptr_storage<BooksTaskQueue>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static shared_ptr<BooksTaskQueue> instance();
|
static shared_ptr<BooksTaskQueue> defaultQueue();
|
||||||
|
static shared_ptr<BooksTaskQueue> scaleQueue();
|
||||||
static void waitForDone(int aMsecs = -1);
|
static void waitForDone(int aMsecs = -1);
|
||||||
|
|
||||||
void submit(BooksTask* aTask);
|
void submit(BooksTask* aTask);
|
||||||
void submit(BooksTask* aTask, QObject* aTarget, const char* aSlot);
|
void submit(BooksTask* aTask, QObject* aTarget, const char* aSlot);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BooksTaskQueue();
|
BooksTaskQueue(int aMaxThreadCount);
|
||||||
~BooksTaskQueue();
|
~BooksTaskQueue();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class Private;
|
||||||
|
friend class Private;
|
||||||
QThreadPool* iPool;
|
QThreadPool* iPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue