Commit c4e771c8 authored by Anatoly Mihalchenko's avatar Anatoly Mihalchenko

SANKORE-429

parent b6604dce
/* /*
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "UBImportDocument.h" #include "UBImportDocument.h"
#include "document/UBDocumentProxy.h" #include "document/UBDocumentProxy.h"
#include "frameworks/UBFileSystemUtils.h" #include "frameworks/UBFileSystemUtils.h"
#include "core/UBApplication.h" #include "core/UBApplication.h"
#include "core/UBSettings.h" #include "core/UBSettings.h"
#include "core/UBPersistenceManager.h" #include "core/UBPersistenceManager.h"
#include "globals/UBGlobals.h" #include "globals/UBGlobals.h"
THIRD_PARTY_WARNINGS_DISABLE THIRD_PARTY_WARNINGS_DISABLE
#include "quazip.h" #include "quazip.h"
#include "quazipfile.h" #include "quazipfile.h"
#include "quazipfileinfo.h" #include "quazipfileinfo.h"
THIRD_PARTY_WARNINGS_ENABLE THIRD_PARTY_WARNINGS_ENABLE
#include "core/memcheck.h" #include "core/memcheck.h"
UBImportDocument::UBImportDocument(QObject *parent) UBImportDocument::UBImportDocument(QObject *parent)
:UBImportAdaptor(parent) :UBImportAdaptor(parent)
{ {
// NOOP // NOOP
} }
UBImportDocument::~UBImportDocument() UBImportDocument::~UBImportDocument()
{ {
// NOOP // NOOP
} }
QStringList UBImportDocument::supportedExtentions() QStringList UBImportDocument::supportedExtentions()
{ {
return QStringList("ubz"); return QStringList("ubz");
} }
QString UBImportDocument::importFileFilter() QString UBImportDocument::importFileFilter()
{ {
return tr("Open-Sankore (*.ubz)"); return tr("Open-Sankore (*.ubz)");
} }
QString UBImportDocument::expandFileToDir(const QFile& pZipFile, const QString& pDir) QString UBImportDocument::expandFileToDir(const QFile& pZipFile, const QString& pDir)
{ {
QDir rootDir(pDir); QDir rootDir(pDir);
QuaZip zip(pZipFile.fileName()); QuaZip zip(pZipFile.fileName());
if(!zip.open(QuaZip::mdUnzip)) if(!zip.open(QuaZip::mdUnzip))
{ {
qWarning() << "Import failed. Cause zip.open(): " << zip.getZipError(); qWarning() << "Import failed. Cause zip.open(): " << zip.getZipError();
return ""; return "";
} }
zip.setFileNameCodec("UTF-8"); zip.setFileNameCodec("UTF-8");
QuaZipFileInfo info; QuaZipFileInfo info;
QuaZipFile file(&zip); QuaZipFile file(&zip);
// TODO UB 4.x implement a mechanism that can replace an existing // TODO UB 4.x implement a mechanism that can replace an existing
// document based on the UID of the document. // document based on the UID of the document.
bool createNewDocument = true; bool createNewDocument = true;
QString documentRootFolder; QString documentRootFolder;
// first we search the metadata.rdf to check the document properties // first we search the metadata.rdf to check the document properties
for(bool more = zip.goToFirstFile(); more; more = zip.goToNextFile()) for(bool more = zip.goToFirstFile(); more; more = zip.goToNextFile())
{ {
if(!zip.getCurrentFileInfo(&info)) if(!zip.getCurrentFileInfo(&info))
{ {
qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError(); qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError();
return ""; return "";
} }
QFileInfo currentFileInfo(pDir + "/" + file.getActualFileName()); QFileInfo currentFileInfo(pDir + "/" + file.getActualFileName());
} }
if (createNewDocument) if (createNewDocument)
documentRootFolder = UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath(); documentRootFolder = UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath();
QFile out; QFile out;
char c; char c;
for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile())
{ {
if(!zip.getCurrentFileInfo(&info)) if(!zip.getCurrentFileInfo(&info))
{ {
//TOD UB 4.3 O display error to user or use crash reporter //TOD UB 4.3 O display error to user or use crash reporter
qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError(); qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError();
return ""; return "";
} }
if(!file.open(QIODevice::ReadOnly)) if(!file.open(QIODevice::ReadOnly))
{ {
qWarning() << "Import failed. Cause: file.open(): " << zip.getZipError(); qWarning() << "Import failed. Cause: file.open(): " << zip.getZipError();
return ""; return "";
} }
if(file.getZipError()!= UNZ_OK) if(file.getZipError()!= UNZ_OK)
{ {
qWarning() << "Import failed. Cause: file.getFileName(): " << zip.getZipError(); qWarning() << "Import failed. Cause: file.getFileName(): " << zip.getZipError();
return ""; return "";
} }
QString newFileName = documentRootFolder + "/" + file.getActualFileName(); QString newFileName = documentRootFolder + "/" + file.getActualFileName();
QFileInfo newFileInfo(newFileName); QFileInfo newFileInfo(newFileName);
rootDir.mkpath(newFileInfo.absolutePath()); rootDir.mkpath(newFileInfo.absolutePath());
out.setFileName(newFileName); out.setFileName(newFileName);
out.open(QIODevice::WriteOnly); out.open(QIODevice::WriteOnly);
// Slow like hell (on GNU/Linux at least), but it is not my fault. // Slow like hell (on GNU/Linux at least), but it is not my fault.
// Not ZIP/UNZIP package's fault either. // Not ZIP/UNZIP package's fault either.
// The slowest thing here is out.putChar(c). // The slowest thing here is out.putChar(c).
QByteArray outFileContent = file.readAll(); QByteArray outFileContent = file.readAll();
if (out.write(outFileContent) == -1) if (out.write(outFileContent) == -1)
{ {
qWarning() << "Import failed. Cause: Unable to write file"; qWarning() << "Import failed. Cause: Unable to write file";
out.close(); out.close();
return ""; return "";
} }
while(file.getChar(&c)) while(file.getChar(&c))
out.putChar(c); out.putChar(c);
out.close(); out.close();
if(file.getZipError()!=UNZ_OK) if(file.getZipError()!=UNZ_OK)
{ {
qWarning() << "Import failed. Cause: " << zip.getZipError(); qWarning() << "Import failed. Cause: " << zip.getZipError();
return ""; return "";
} }
if(!file.atEnd()) if(!file.atEnd())
{ {
qWarning() << "Import failed. Cause: read all but not EOF"; qWarning() << "Import failed. Cause: read all but not EOF";
return ""; return "";
} }
file.close(); file.close();
if(file.getZipError()!=UNZ_OK) if(file.getZipError()!=UNZ_OK)
{ {
qWarning() << "Import failed. Cause: file.close(): " << file.getZipError(); qWarning() << "Import failed. Cause: file.close(): " << file.getZipError();
return ""; return "";
} }
} }
zip.close(); zip.close();
if(zip.getZipError()!=UNZ_OK) if(zip.getZipError()!=UNZ_OK)
{ {
qWarning() << "Import failed. Cause: zip.close(): " << zip.getZipError(); qWarning() << "Import failed. Cause: zip.close(): " << zip.getZipError();
return ""; return "";
} }
return documentRootFolder; return documentRootFolder;
} }
UBDocumentProxy* UBImportDocument::importFile(const QFile& pFile, const QString& pGroup) UBDocumentProxy* UBImportDocument::importFile(const QFile& pFile, const QString& pGroup)
{ {
Q_UNUSED(pGroup); // group is defined in the imported file Q_UNUSED(pGroup); // group is defined in the imported file
QFileInfo fi(pFile); QFileInfo fi(pFile);
UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true); UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true);
// first unzip the file to the correct place // first unzip the file to the correct place
QString path = UBSettings::settings()->uniboardDocumentDirectory(); QString path = UBSettings::settings()->uniboardDocumentDirectory();
QString documentRootFolder = expandFileToDir(pFile, path); QString documentRootFolder = expandFileToDir(pFile, path);
if(!documentRootFolder.length()){ if(!documentRootFolder.length()){
UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName())); UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName()));
return 0; return 0;
} }
else{ else{
UBDocumentProxy* newDocument = UBPersistenceManager::persistenceManager()->createDocumentFromDir(documentRootFolder); UBDocumentProxy* newDocument = UBPersistenceManager::persistenceManager()->createDocumentFromDir(documentRootFolder, pGroup);
UBApplication::showMessage(tr("Import successful."));
return newDocument; UBApplication::showMessage(tr("Import successful."));
}
} return newDocument;
}
}
bool UBImportDocument::addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile)
{
QFileInfo fi(pFile); bool UBImportDocument::addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile)
UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true); {
QFileInfo fi(pFile);
QString path = UBFileSystemUtils::createTempDir(); UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true);
QString documentRootFolder = expandFileToDir(pFile, path); QString path = UBFileSystemUtils::createTempDir();
UBPersistenceManager::persistenceManager()->addDirectoryContentToDocument(documentRootFolder, pDocument); QString documentRootFolder = expandFileToDir(pFile, path);
UBFileSystemUtils::deleteDir(path); UBPersistenceManager::persistenceManager()->addDirectoryContentToDocument(documentRootFolder, pDocument);
UBApplication::showMessage(tr("Import successful.")); UBFileSystemUtils::deleteDir(path);
return true; UBApplication::showMessage(tr("Import successful."));
}
return true;
}
/* /*
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "UBPersistenceManager.h" #include "UBPersistenceManager.h"
#include "gui/UBMainWindow.h" #include "gui/UBMainWindow.h"
#include <QtXml> #include <QtXml>
#include "frameworks/UBPlatformUtils.h" #include "frameworks/UBPlatformUtils.h"
#include "frameworks/UBFileSystemUtils.h" #include "frameworks/UBFileSystemUtils.h"
#include "core/UBApplication.h" #include "core/UBApplication.h"
#include "core/UBSettings.h" #include "core/UBSettings.h"
#include "core/UBSetting.h" #include "core/UBSetting.h"
#include "document/UBDocumentProxy.h" #include "document/UBDocumentProxy.h"
#include "adaptors/UBExportPDF.h" #include "adaptors/UBExportPDF.h"
#include "adaptors/UBSvgSubsetAdaptor.h" #include "adaptors/UBSvgSubsetAdaptor.h"
#include "adaptors/UBThumbnailAdaptor.h" #include "adaptors/UBThumbnailAdaptor.h"
#include "adaptors/UBMetadataDcSubsetAdaptor.h" #include "adaptors/UBMetadataDcSubsetAdaptor.h"
#include "core/memcheck.h" #include "core/memcheck.h"
const QString UBPersistenceManager::imageDirectory = "images"; // added to UBPersistenceManager::mAllDirectories const QString UBPersistenceManager::imageDirectory = "images"; // added to UBPersistenceManager::mAllDirectories
const QString UBPersistenceManager::objectDirectory = "objects"; // added to UBPersistenceManager::mAllDirectories const QString UBPersistenceManager::objectDirectory = "objects"; // added to UBPersistenceManager::mAllDirectories
const QString UBPersistenceManager::widgetDirectory = "widgets"; // added to UBPersistenceManager::mAllDirectories const QString UBPersistenceManager::widgetDirectory = "widgets"; // added to UBPersistenceManager::mAllDirectories
const QString UBPersistenceManager::videoDirectory = "videos"; // added to UBPersistenceManager::mAllDirectories const QString UBPersistenceManager::videoDirectory = "videos"; // added to UBPersistenceManager::mAllDirectories
const QString UBPersistenceManager::audioDirectory = "audios"; // added to const QString UBPersistenceManager::audioDirectory = "audios"; // added to
UBPersistenceManager * UBPersistenceManager::sSingleton = 0; UBPersistenceManager * UBPersistenceManager::sSingleton = 0;
UBPersistenceManager::UBPersistenceManager(QObject *pParent) UBPersistenceManager::UBPersistenceManager(QObject *pParent)
: QObject(pParent) : QObject(pParent)
, mHasPurgedDocuments(false) , mHasPurgedDocuments(false)
{ {
mDocumentSubDirectories << imageDirectory; mDocumentSubDirectories << imageDirectory;
mDocumentSubDirectories << objectDirectory; mDocumentSubDirectories << objectDirectory;
mDocumentSubDirectories << widgetDirectory; mDocumentSubDirectories << widgetDirectory;
mDocumentSubDirectories << videoDirectory; mDocumentSubDirectories << videoDirectory;
mDocumentSubDirectories << audioDirectory; mDocumentSubDirectories << audioDirectory;
documentProxies = allDocumentProxies(); documentProxies = allDocumentProxies();
emit proxyListChanged(); emit proxyListChanged();
} }
UBPersistenceManager* UBPersistenceManager::persistenceManager() UBPersistenceManager* UBPersistenceManager::persistenceManager()
{ {
if (!sSingleton) if (!sSingleton)
{ {
sSingleton = new UBPersistenceManager(UBApplication::staticMemoryCleaner); sSingleton = new UBPersistenceManager(UBApplication::staticMemoryCleaner);
} }
return sSingleton; return sSingleton;
} }
void UBPersistenceManager::destroy() void UBPersistenceManager::destroy()
{ {
if (sSingleton) if (sSingleton)
delete sSingleton; delete sSingleton;
sSingleton = NULL; sSingleton = NULL;
} }
UBPersistenceManager::~UBPersistenceManager() UBPersistenceManager::~UBPersistenceManager()
{ {
foreach(QPointer<UBDocumentProxy> proxyGuard, documentProxies) foreach(QPointer<UBDocumentProxy> proxyGuard, documentProxies)
{ {
if (!proxyGuard.isNull()) if (!proxyGuard.isNull())
delete proxyGuard.data(); delete proxyGuard.data();
} }
} }
QList<QPointer<UBDocumentProxy> > UBPersistenceManager::allDocumentProxies() QList<QPointer<UBDocumentProxy> > UBPersistenceManager::allDocumentProxies()
{ {
mDocumentRepositoryPath = UBSettings::settings()->uniboardDocumentDirectory(); mDocumentRepositoryPath = UBSettings::settings()->uniboardDocumentDirectory();
QDir rootDir(mDocumentRepositoryPath); QDir rootDir(mDocumentRepositoryPath);
rootDir.mkpath(rootDir.path()); rootDir.mkpath(rootDir.path());
QFileSystemWatcher* watcher = new QFileSystemWatcher(this); QFileSystemWatcher* watcher = new QFileSystemWatcher(this);
watcher->addPath(mDocumentRepositoryPath); watcher->addPath(mDocumentRepositoryPath);
connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(documentRepositoryChanged(const QString&))); connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(documentRepositoryChanged(const QString&)));
QList<QPointer<UBDocumentProxy> > proxies; QList<QPointer<UBDocumentProxy> > proxies;
foreach(QString path, rootDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, foreach(QString path, rootDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot,
QDir::Time | QDir::Reversed)) QDir::Time | QDir::Reversed))
{ {
QString fullPath = rootDir.path() + "/" + path; QString fullPath = rootDir.path() + "/" + path;
QDir dir(fullPath); QDir dir(fullPath);
if (dir.entryList(QDir::Files | QDir::NoDotAndDotDot).size() > 0) if (dir.entryList(QDir::Files | QDir::NoDotAndDotDot).size() > 0)
{ {
UBDocumentProxy* proxy = new UBDocumentProxy(fullPath); // deleted in UBPersistenceManager::destructor UBDocumentProxy* proxy = new UBDocumentProxy(fullPath); // deleted in UBPersistenceManager::destructor
QMap<QString, QVariant> metadatas = UBMetadataDcSubsetAdaptor::load(fullPath); QMap<QString, QVariant> metadatas = UBMetadataDcSubsetAdaptor::load(fullPath);
foreach(QString key, metadatas.keys()) foreach(QString key, metadatas.keys())
{ {
proxy->setMetaData(key, metadatas.value(key)); proxy->setMetaData(key, metadatas.value(key));
} }
proxy->setPageCount(sceneCount(proxy)); proxy->setPageCount(sceneCount(proxy));
proxies << QPointer<UBDocumentProxy>(proxy); proxies << QPointer<UBDocumentProxy>(proxy);
} }
} }
return proxies; return proxies;
} }
QStringList UBPersistenceManager::allShapes() QStringList UBPersistenceManager::allShapes()
{ {
QString shapeLibraryPath = UBSettings::settings()->uniboardShapeLibraryDirectory(); QString shapeLibraryPath = UBSettings::settings()->uniboardShapeLibraryDirectory();
QDir dir(shapeLibraryPath); QDir dir(shapeLibraryPath);
if (!dir.exists()) if (!dir.exists())
dir.mkpath(shapeLibraryPath); dir.mkpath(shapeLibraryPath);
QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name); QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
QStringList paths; QStringList paths;
foreach(QString file, files) foreach(QString file, files)
{ {
paths.append(shapeLibraryPath + QString("/") + file); paths.append(shapeLibraryPath + QString("/") + file);
} }
return paths; return paths;
} }
QStringList UBPersistenceManager::allGips() QStringList UBPersistenceManager::allGips()
{ {
QString gipLibraryPath = UBSettings::settings()->uniboardGipLibraryDirectory(); QString gipLibraryPath = UBSettings::settings()->uniboardGipLibraryDirectory();
QDir dir(gipLibraryPath); QDir dir(gipLibraryPath);
QStringList files = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); QStringList files = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
QStringList paths; QStringList paths;
foreach(QString file, files) foreach(QString file, files)
{ {
QFileInfo fi(file); QFileInfo fi(file);
if (UBSettings::settings()->widgetFileExtensions.contains(fi.suffix())) if (UBSettings::settings()->widgetFileExtensions.contains(fi.suffix()))
paths.append(dir.path() + QString("/") + file); paths.append(dir.path() + QString("/") + file);
} }
return paths; return paths;
} }
QStringList UBPersistenceManager::allSounds() QStringList UBPersistenceManager::allSounds()
{ {
QString soundLibraryPath = QDesktopServices::storageLocation(QDesktopServices::MusicLocation); QString soundLibraryPath = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
QDir dir(soundLibraryPath); QDir dir(soundLibraryPath);
QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name); QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
QStringList paths; QStringList paths;
foreach(QString file, files) foreach(QString file, files)
{ {
QFileInfo fi(file); QFileInfo fi(file);
paths.append(dir.path() + QString("/") + file); paths.append(dir.path() + QString("/") + file);
} }
return paths; return paths;
} }
QStringList UBPersistenceManager::allImages(const QDir& dir) QStringList UBPersistenceManager::allImages(const QDir& dir)
{ {
if (!dir.exists()) if (!dir.exists())
dir.mkpath(dir.path()); dir.mkpath(dir.path());
QStringList files = dir.entryList(QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDir::Name); QStringList files = dir.entryList(QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDir::Name);
QStringList paths; QStringList paths;
foreach(QString file, files) foreach(QString file, files)
{ {
paths.append(dir.path() + QString("/") + file); paths.append(dir.path() + QString("/") + file);
} }
return paths; return paths;
} }
QStringList UBPersistenceManager::allVideos(const QDir& dir) QStringList UBPersistenceManager::allVideos(const QDir& dir)
{ {
if (!dir.exists()) if (!dir.exists())
dir.mkpath(dir.path()); dir.mkpath(dir.path());
QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name); QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
QStringList paths; QStringList paths;
foreach(QString file, files) foreach(QString file, files)
{ {
paths.append(dir.path() + QString("/") + file); paths.append(dir.path() + QString("/") + file);
} }
return paths; return paths;
} }
QStringList UBPersistenceManager::allWidgets(const QDir& dir) QStringList UBPersistenceManager::allWidgets(const QDir& dir)
{ {
if (!dir.exists()) if (!dir.exists())
dir.mkpath(dir.path()); dir.mkpath(dir.path());
QStringList files = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); QStringList files = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
QStringList paths; QStringList paths;
foreach(QString file, files) foreach(QString file, files)
{ {
QFileInfo fi(file); QFileInfo fi(file);
if (UBSettings::settings()->widgetFileExtensions.contains(fi.suffix())) if (UBSettings::settings()->widgetFileExtensions.contains(fi.suffix()))
paths.append(dir.path() + QString("/") + file); paths.append(dir.path() + QString("/") + file);
} }
return paths; return paths;
} }
UBDocumentProxy* UBPersistenceManager::createDocument(const QString& pGroupName, const QString& pName, bool withEmptyPage) UBDocumentProxy* UBPersistenceManager::createDocument(const QString& pGroupName, const QString& pName, bool withEmptyPage)
{ {
checkIfDocumentRepositoryExists(); checkIfDocumentRepositoryExists();
UBDocumentProxy *doc = new UBDocumentProxy(); // deleted in UBPersistenceManager::destructor UBDocumentProxy *doc = new UBDocumentProxy(); // deleted in UBPersistenceManager::destructor
if (pGroupName.length() > 0) if (pGroupName.length() > 0)
{ {
doc->setMetaData(UBSettings::documentGroupName, pGroupName); doc->setMetaData(UBSettings::documentGroupName, pGroupName);
} }
if (pName.length() > 0) if (pName.length() > 0)
{ {
doc->setMetaData(UBSettings::documentName, pName); doc->setMetaData(UBSettings::documentName, pName);
} }
doc->setMetaData(UBSettings::documentVersion, UBSettings::currentFileVersion); doc->setMetaData(UBSettings::documentVersion, UBSettings::currentFileVersion);
doc->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); doc->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime()));
if (withEmptyPage) createDocumentSceneAt(doc, 0); if (withEmptyPage) createDocumentSceneAt(doc, 0);
documentProxies.insert(0, QPointer<UBDocumentProxy>(doc)); documentProxies.insert(0, QPointer<UBDocumentProxy>(doc));
emit proxyListChanged(); emit proxyListChanged();
emit documentCreated(doc); emit documentCreated(doc);
mDocumentCreatedDuringSession << doc; mDocumentCreatedDuringSession << doc;
return doc; return doc;
} }
UBDocumentProxy* UBPersistenceManager::createDocumentFromDir(const QString& pDocumentDirectory, const QString& pGroupName, const QString& pName, bool withEmptyPage)
UBDocumentProxy* UBPersistenceManager::createDocumentFromDir(const QString& pDocumentDirectory) {
{ checkIfDocumentRepositoryExists();
checkIfDocumentRepositoryExists();
UBDocumentProxy* doc = new UBDocumentProxy(pDocumentDirectory); // deleted in UBPersistenceManager::destructor
UBDocumentProxy* doc = new UBDocumentProxy(pDocumentDirectory); // deleted in UBPersistenceManager::destructor
if (pGroupName.length() > 0)
QMap<QString, QVariant> metadatas = UBMetadataDcSubsetAdaptor::load(pDocumentDirectory); {
doc->setMetaData(UBSettings::documentGroupName, pGroupName);
foreach(QString key, metadatas.keys()) }
{
doc->setMetaData(key, metadatas.value(key)); if (pName.length() > 0)
} {
doc->setMetaData(UBSettings::documentName, pName);
doc->setUuid(QUuid::createUuid()); }
doc->setPageCount(sceneCount(doc)); if (withEmptyPage) createDocumentSceneAt(doc, 0);
UBMetadataDcSubsetAdaptor::persist(doc); QMap<QString, QVariant> metadatas = UBMetadataDcSubsetAdaptor::load(pDocumentDirectory);
for(int i = 0; i < doc->pageCount(); i++) foreach(QString key, metadatas.keys())
{ {
UBSvgSubsetAdaptor::setSceneUuid(doc, i, QUuid::createUuid()); doc->setMetaData(key, metadatas.value(key));
} }
documentProxies << QPointer<UBDocumentProxy>(doc); doc->setUuid(QUuid::createUuid());
doc->setPageCount(sceneCount(doc));
emit proxyListChanged();
UBMetadataDcSubsetAdaptor::persist(doc);
emit documentCreated(doc);
for(int i = 0; i < doc->pageCount(); i++)
return doc; {
} UBSvgSubsetAdaptor::setSceneUuid(doc, i, QUuid::createUuid());
}
void UBPersistenceManager::deleteDocument(UBDocumentProxy* pDocumentProxy) documentProxies << QPointer<UBDocumentProxy>(doc);
{
checkIfDocumentRepositoryExists(); emit proxyListChanged();
emit documentWillBeDeleted(pDocumentProxy); emit documentCreated(doc);
UBFileSystemUtils::deleteDir(pDocumentProxy->persistencePath()); return doc;
}
documentProxies.removeAll(QPointer<UBDocumentProxy>(pDocumentProxy));
mDocumentCreatedDuringSession.removeAll(pDocumentProxy);
void UBPersistenceManager::deleteDocument(UBDocumentProxy* pDocumentProxy)
mSceneCache.removeAllScenes(pDocumentProxy); {
checkIfDocumentRepositoryExists();
pDocumentProxy->deleteLater();
emit documentWillBeDeleted(pDocumentProxy);
emit proxyListChanged();
UBFileSystemUtils::deleteDir(pDocumentProxy->persistencePath());
}
documentProxies.removeAll(QPointer<UBDocumentProxy>(pDocumentProxy));
mDocumentCreatedDuringSession.removeAll(pDocumentProxy);
UBDocumentProxy* UBPersistenceManager::duplicateDocument(UBDocumentProxy* pDocumentProxy)
{ mSceneCache.removeAllScenes(pDocumentProxy);
checkIfDocumentRepositoryExists();
pDocumentProxy->deleteLater();
UBDocumentProxy *copy = new UBDocumentProxy(); // deleted in UBPersistenceManager::destructor
emit proxyListChanged();
generatePathIfNeeded(copy);
}
UBFileSystemUtils::copyDir(pDocumentProxy->persistencePath(), copy->persistencePath());
// regenerate scenes UUIDs UBDocumentProxy* UBPersistenceManager::duplicateDocument(UBDocumentProxy* pDocumentProxy)
for(int i = 0; i < pDocumentProxy->pageCount(); i++) {
{ checkIfDocumentRepositoryExists();
UBSvgSubsetAdaptor::setSceneUuid(pDocumentProxy, i, QUuid::createUuid());
} UBDocumentProxy *copy = new UBDocumentProxy(); // deleted in UBPersistenceManager::destructor
foreach(QString key, pDocumentProxy->metaDatas().keys()) generatePathIfNeeded(copy);
{
copy->setMetaData(key, pDocumentProxy->metaDatas().value(key)); UBFileSystemUtils::copyDir(pDocumentProxy->persistencePath(), copy->persistencePath());
}
// regenerate scenes UUIDs
copy->setMetaData(UBSettings::documentName, for(int i = 0; i < pDocumentProxy->pageCount(); i++)
pDocumentProxy->metaData(UBSettings::documentName).toString() + " " + tr("(copy)")); {
UBSvgSubsetAdaptor::setSceneUuid(pDocumentProxy, i, QUuid::createUuid());
copy->setUuid(QUuid::createUuid()); }
persistDocumentMetadata(copy); foreach(QString key, pDocumentProxy->metaDatas().keys())
{
copy->setPageCount(sceneCount(copy)); copy->setMetaData(key, pDocumentProxy->metaDatas().value(key));
}
documentProxies << QPointer<UBDocumentProxy>(copy);
copy->setMetaData(UBSettings::documentName,
emit proxyListChanged(); pDocumentProxy->metaData(UBSettings::documentName).toString() + " " + tr("(copy)"));
emit documentCreated(copy); copy->setUuid(QUuid::createUuid());
return copy; persistDocumentMetadata(copy);
} copy->setPageCount(sceneCount(copy));
documentProxies << QPointer<UBDocumentProxy>(copy);
void UBPersistenceManager::deleteDocumentScenes(UBDocumentProxy* proxy, const QList<int>& indexes)
{ emit proxyListChanged();
checkIfDocumentRepositoryExists();
emit documentCreated(copy);
int pageCount = UBPersistenceManager::persistenceManager()->sceneCount(proxy);
return copy;
QList<int> compactedIndexes;
}
foreach(int index, indexes)
{
if (!compactedIndexes.contains(index)) void UBPersistenceManager::deleteDocumentScenes(UBDocumentProxy* proxy, const QList<int>& indexes)
compactedIndexes.append(index); {
} checkIfDocumentRepositoryExists();
if (compactedIndexes.size() == pageCount) int pageCount = UBPersistenceManager::persistenceManager()->sceneCount(proxy);
{
deleteDocument(proxy); QList<int> compactedIndexes;
return;
} foreach(int index, indexes)
{
if (compactedIndexes.size() == 0) if (!compactedIndexes.contains(index))
return; compactedIndexes.append(index);
}
foreach(int index, compactedIndexes)
{ if (compactedIndexes.size() == pageCount)
emit documentSceneWillBeDeleted(proxy, index); {
} deleteDocument(proxy);
return;
QString sourceGroupName = proxy->metaData(UBSettings::documentGroupName).toString(); }
QString sourceName = proxy->metaData(UBSettings::documentName).toString();
UBDocumentProxy *trashDocProxy = createDocument(UBSettings::trashedDocumentGroupNamePrefix + sourceGroupName, sourceName, false); if (compactedIndexes.size() == 0)
return;
foreach(int index, compactedIndexes)
{ foreach(int index, compactedIndexes)
UBGraphicsScene *scene = loadDocumentScene(proxy, index); {
if (scene) emit documentSceneWillBeDeleted(proxy, index);
{ }
//scene is about to move into new document
foreach (QUrl relativeFile, scene->relativeDependencies()) QString sourceGroupName = proxy->metaData(UBSettings::documentGroupName).toString();
{ QString sourceName = proxy->metaData(UBSettings::documentName).toString();
QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); UBDocumentProxy *trashDocProxy = createDocument(UBSettings::trashedDocumentGroupNamePrefix + sourceGroupName, sourceName, false);
QString target = trashDocProxy->persistencePath() + "/" + relativeFile.toString();
foreach(int index, compactedIndexes)
QFileInfo fi(target); {
QDir d = fi.dir(); UBGraphicsScene *scene = loadDocumentScene(proxy, index);
if (scene)
d.mkpath(d.absolutePath()); {
QFile::copy(source, target); //scene is about to move into new document
} foreach (QUrl relativeFile, scene->relativeDependencies())
{
insertDocumentSceneAt(trashDocProxy, scene, trashDocProxy->pageCount()); QString source = scene->document()->persistencePath() + "/" + relativeFile.toString();
} QString target = trashDocProxy->persistencePath() + "/" + relativeFile.toString();
}
QFileInfo fi(target);
for (int i = 1; i < pageCount; i++) QDir d = fi.dir();
{
renamePage(trashDocProxy, i , i - 1); d.mkpath(d.absolutePath());
} QFile::copy(source, target);
}
foreach(int index, compactedIndexes)
{ insertDocumentSceneAt(trashDocProxy, scene, trashDocProxy->pageCount());
QString svgFileName = proxy->persistencePath() + }
UBFileSystemUtils::digitFileFormat("/page%1.svg", index + 1); }
QFile::remove(svgFileName); for (int i = 1; i < pageCount; i++)
{
QString thumbFileName = proxy->persistencePath() + renamePage(trashDocProxy, i , i - 1);
UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", index + 1); }
QFile::remove(thumbFileName); foreach(int index, compactedIndexes)
{
mSceneCache.removeScene(proxy, index); QString svgFileName = proxy->persistencePath() +
UBFileSystemUtils::digitFileFormat("/page%1.svg", index + 1);
proxy->decPageCount();
QFile::remove(svgFileName);
}
QString thumbFileName = proxy->persistencePath() +
qSort(compactedIndexes); UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", index + 1);
int offset = 1; QFile::remove(thumbFileName);
for (int i = compactedIndexes.at(0) + 1; i < pageCount; i++) mSceneCache.removeScene(proxy, index);
{
if(compactedIndexes.contains(i)) proxy->decPageCount();
{
offset++; }
}
else qSort(compactedIndexes);
{
renamePage(proxy, i , i - offset); int offset = 1;
mSceneCache.moveScene(proxy, i, i - offset); for (int i = compactedIndexes.at(0) + 1; i < pageCount; i++)
{
} if(compactedIndexes.contains(i))
} {
offset++;
foreach(int index, compactedIndexes) }
{ else
emit documentSceneDeleted(proxy, index); {
} renamePage(proxy, i , i - offset);
}
mSceneCache.moveScene(proxy, i, i - offset);
void UBPersistenceManager::duplicateDocumentScene(UBDocumentProxy* proxy, int index) }
{ }
checkIfDocumentRepositoryExists();
foreach(int index, compactedIndexes)
int pageCount = UBPersistenceManager::persistenceManager()->sceneCount(proxy); {
emit documentSceneDeleted(proxy, index);
for (int i = pageCount; i > index + 1; i--) }
{ }
renamePage(proxy, i - 1 , i);
mSceneCache.moveScene(proxy, i - 1, i); void UBPersistenceManager::duplicateDocumentScene(UBDocumentProxy* proxy, int index)
{
} checkIfDocumentRepositoryExists();
copyPage(proxy, index , index + 1); int pageCount = UBPersistenceManager::persistenceManager()->sceneCount(proxy);
proxy->incPageCount(); for (int i = pageCount; i > index + 1; i--)
{
//due to architectural peculiarity we need to save teacher bar info, otherwise we'll see not exactly what we expect renamePage(proxy, i - 1 , i);
sTeacherBarInfos properInfo = getTeacherBarInfos(proxy, index + 1);
//after the call below mSceneCache.moveScene(proxy, i - 1, i);
emit documentSceneCreated(proxy, index + 1);
//restoring info }
persistTeacherBar(proxy, index + 1, properInfo);
} copyPage(proxy, index , index + 1);
proxy->incPageCount();
UBGraphicsScene* UBPersistenceManager::createDocumentSceneAt(UBDocumentProxy* proxy, int index)
{ //due to architectural peculiarity we need to save teacher bar info, otherwise we'll see not exactly what we expect
int count = sceneCount(proxy); sTeacherBarInfos properInfo = getTeacherBarInfos(proxy, index + 1);
//after the call below
for(int i = count - 1; i >= index; i--) emit documentSceneCreated(proxy, index + 1);
{ //restoring info
renamePage(proxy, i , i + 1); persistTeacherBar(proxy, index + 1, properInfo);
} }
mSceneCache.shiftUpScenes(proxy, index, count -1);
UBGraphicsScene* UBPersistenceManager::createDocumentSceneAt(UBDocumentProxy* proxy, int index)
UBGraphicsScene *newScene = mSceneCache.createScene(proxy, index); {
int count = sceneCount(proxy);
newScene->setBackground(UBSettings::settings()->isDarkBackground(),
UBSettings::settings()->UBSettings::isCrossedBackground()); for(int i = count - 1; i >= index; i--)
{
persistDocumentScene(proxy, newScene, index); renamePage(proxy, i , i + 1);
}
proxy->incPageCount();
mSceneCache.shiftUpScenes(proxy, index, count -1);
emit documentSceneCreated(proxy, index);
UBGraphicsScene *newScene = mSceneCache.createScene(proxy, index);
return newScene;
} newScene->setBackground(UBSettings::settings()->isDarkBackground(),
UBSettings::settings()->UBSettings::isCrossedBackground());
void UBPersistenceManager::insertDocumentSceneAt(UBDocumentProxy* proxy, UBGraphicsScene* scene, int index) persistDocumentScene(proxy, newScene, index);
{
scene->setDocument(proxy); proxy->incPageCount();
int count = sceneCount(proxy); emit documentSceneCreated(proxy, index);
for(int i = count - 1; i >= index; i--) return newScene;
{ }
renamePage(proxy, i , i + 1);
}
void UBPersistenceManager::insertDocumentSceneAt(UBDocumentProxy* proxy, UBGraphicsScene* scene, int index)
mSceneCache.shiftUpScenes(proxy, index, count -1); {
scene->setDocument(proxy);
mSceneCache.insert(proxy, index, scene);
int count = sceneCount(proxy);
persistDocumentScene(proxy, scene, index);
for(int i = count - 1; i >= index; i--)
proxy->incPageCount(); {
renamePage(proxy, i , i + 1);
emit documentSceneCreated(proxy, index); }
} mSceneCache.shiftUpScenes(proxy, index, count -1);
mSceneCache.insert(proxy, index, scene);
void UBPersistenceManager::moveSceneToIndex(UBDocumentProxy* proxy, int source, int target)
{ persistDocumentScene(proxy, scene, index);
checkIfDocumentRepositoryExists();
proxy->incPageCount();
if (source == target)
return; emit documentSceneCreated(proxy, index);
QFile svgTmp(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", source + 1)); }
svgTmp.rename(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.tmp", target + 1));
QFile thumbTmp(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", source + 1)); void UBPersistenceManager::moveSceneToIndex(UBDocumentProxy* proxy, int source, int target)
thumbTmp.rename(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.tmp", target + 1)); {
checkIfDocumentRepositoryExists();
if (source < target)
{ if (source == target)
for (int i = source + 1; i <= target; i++) return;
{
renamePage(proxy, i , i - 1); QFile svgTmp(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", source + 1));
} svgTmp.rename(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.tmp", target + 1));
}
else QFile thumbTmp(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", source + 1));
{ thumbTmp.rename(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.tmp", target + 1));
for (int i = source - 1; i >= target; i--)
{ if (source < target)
renamePage(proxy, i , i + 1); {
} for (int i = source + 1; i <= target; i++)
} {
renamePage(proxy, i , i - 1);
QFile svg(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.tmp", target + 1)); }
svg.rename(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", target + 1)); }
else
QFile thumb(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.tmp", target + 1)); {
thumb.rename(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", target + 1)); for (int i = source - 1; i >= target; i--)
{
mSceneCache.moveScene(proxy, source, target); renamePage(proxy, i , i + 1);
}
emit documentSceneMoved(proxy, target); }
}
QFile svg(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.tmp", target + 1));
svg.rename(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", target + 1));
UBGraphicsScene* UBPersistenceManager::loadDocumentScene(UBDocumentProxy* proxy, int sceneIndex)
{ QFile thumb(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.tmp", target + 1));
if (mSceneCache.contains(proxy, sceneIndex)) thumb.rename(proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", target + 1));
{
//qDebug() << "scene" << sceneIndex << "retrieved from cache ..."; mSceneCache.moveScene(proxy, source, target);
return mSceneCache.value(proxy, sceneIndex);
} emit documentSceneMoved(proxy, target);
else }
{
UBGraphicsScene* scene = UBSvgSubsetAdaptor::loadScene(proxy, sceneIndex);
UBGraphicsScene* UBPersistenceManager::loadDocumentScene(UBDocumentProxy* proxy, int sceneIndex)
if (scene) {
mSceneCache.insert(proxy, sceneIndex, scene); if (mSceneCache.contains(proxy, sceneIndex))
{
return scene; //qDebug() << "scene" << sceneIndex << "retrieved from cache ...";
} return mSceneCache.value(proxy, sceneIndex);
} }
else
{
void UBPersistenceManager::persistDocumentScene(UBDocumentProxy* pDocumentProxy, UBGraphicsScene* pScene, const int pSceneIndex) UBGraphicsScene* scene = UBSvgSubsetAdaptor::loadScene(proxy, sceneIndex);
{
checkIfDocumentRepositoryExists(); if (scene)
mSceneCache.insert(proxy, sceneIndex, scene);
pScene->deselectAllItems();
return scene;
generatePathIfNeeded(pDocumentProxy); }
}
QDir dir(pDocumentProxy->persistencePath());
dir.mkpath(pDocumentProxy->persistencePath());
void UBPersistenceManager::persistDocumentScene(UBDocumentProxy* pDocumentProxy, UBGraphicsScene* pScene, const int pSceneIndex)
if (pDocumentProxy->isModified()) {
UBMetadataDcSubsetAdaptor::persist(pDocumentProxy); checkIfDocumentRepositoryExists();
if (pScene->isModified()) pScene->deselectAllItems();
{
UBThumbnailAdaptor::persistScene(pDocumentProxy->persistencePath(), pScene, pSceneIndex); generatePathIfNeeded(pDocumentProxy);
UBSvgSubsetAdaptor::persistScene(pDocumentProxy, pScene, pSceneIndex); QDir dir(pDocumentProxy->persistencePath());
dir.mkpath(pDocumentProxy->persistencePath());
pScene->setModified(false);
} if (pDocumentProxy->isModified())
UBMetadataDcSubsetAdaptor::persist(pDocumentProxy);
mSceneCache.insert(pDocumentProxy, pSceneIndex, pScene);
if (pScene->isModified())
emit documentCommitted(pDocumentProxy); {
UBThumbnailAdaptor::persistScene(pDocumentProxy->persistencePath(), pScene, pSceneIndex);
}
UBSvgSubsetAdaptor::persistScene(pDocumentProxy, pScene, pSceneIndex);
UBDocumentProxy* UBPersistenceManager::persistDocumentMetadata(UBDocumentProxy* pDocumentProxy) pScene->setModified(false);
{ }
UBMetadataDcSubsetAdaptor::persist(pDocumentProxy);
mSceneCache.insert(pDocumentProxy, pSceneIndex, pScene);
emit documentMetadataChanged(pDocumentProxy);
emit documentCommitted(pDocumentProxy);
return pDocumentProxy;
} }
void UBPersistenceManager::renamePage(UBDocumentProxy* pDocumentProxy, const int sourceIndex, const int targetIndex) UBDocumentProxy* UBPersistenceManager::persistDocumentMetadata(UBDocumentProxy* pDocumentProxy)
{ {
QFile svg(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", sourceIndex + 1)); UBMetadataDcSubsetAdaptor::persist(pDocumentProxy);
svg.rename(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", targetIndex + 1));
emit documentMetadataChanged(pDocumentProxy);
QFile thumb(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceIndex + 1));
thumb.rename(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetIndex + 1)); return pDocumentProxy;
} }
void UBPersistenceManager::copyPage(UBDocumentProxy* pDocumentProxy, const int sourceIndex, const int targetIndex) void UBPersistenceManager::renamePage(UBDocumentProxy* pDocumentProxy, const int sourceIndex, const int targetIndex)
{ {
QFile svg(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", sourceIndex + 1)); QFile svg(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", sourceIndex + 1));
svg.copy(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", targetIndex + 1)); svg.rename(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", targetIndex + 1));
UBSvgSubsetAdaptor::setSceneUuid(pDocumentProxy, targetIndex, QUuid::createUuid()); QFile thumb(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceIndex + 1));
thumb.rename(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetIndex + 1));
QFile thumb(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceIndex + 1)); }
thumb.copy(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetIndex + 1));
}
void UBPersistenceManager::copyPage(UBDocumentProxy* pDocumentProxy, const int sourceIndex, const int targetIndex)
{
int UBPersistenceManager::sceneCount(const UBDocumentProxy* proxy) QFile svg(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", sourceIndex + 1));
{ svg.copy(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", targetIndex + 1));
return sceneCountInDir(proxy->persistencePath());
} UBSvgSubsetAdaptor::setSceneUuid(pDocumentProxy, targetIndex, QUuid::createUuid());
int UBPersistenceManager::sceneCountInDir(const QString& pPath) QFile thumb(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceIndex + 1));
{ thumb.copy(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetIndex + 1));
int pageIndex = 0; }
bool moreToProcess = true;
while (moreToProcess) int UBPersistenceManager::sceneCount(const UBDocumentProxy* proxy)
{ {
QString fileName = pPath + UBFileSystemUtils::digitFileFormat("/page%1.svg", pageIndex + 1); return sceneCountInDir(proxy->persistencePath());
}
QFile file(fileName);
int UBPersistenceManager::sceneCountInDir(const QString& pPath)
if (file.exists()) {
{ int pageIndex = 0;
pageIndex++; bool moreToProcess = true;
}
else while (moreToProcess)
{ {
moreToProcess = false; QString fileName = pPath + UBFileSystemUtils::digitFileFormat("/page%1.svg", pageIndex + 1);
}
} QFile file(fileName);
return pageIndex; if (file.exists())
} {
pageIndex++;
}
QString UBPersistenceManager::generateUniqueDocumentPath() else
{ {
QString ubPath = UBSettings::settings()->uniboardDocumentDirectory(); moreToProcess = false;
}
QDateTime now = QDateTime::currentDateTime(); }
QString dirName = now.toString("yyyy-MM-dd hh-mm-ss.zzz");
return pageIndex;
return ubPath + QString("/Sankore Document %1").arg(dirName); }
}
QString UBPersistenceManager::generateUniqueDocumentPath()
void UBPersistenceManager::generatePathIfNeeded(UBDocumentProxy* pDocumentProxy) {
{ QString ubPath = UBSettings::settings()->uniboardDocumentDirectory();
if (pDocumentProxy->persistencePath().length() == 0)
{ QDateTime now = QDateTime::currentDateTime();
pDocumentProxy->setPersistencePath(generateUniqueDocumentPath()); QString dirName = now.toString("yyyy-MM-dd hh-mm-ss.zzz");
}
} return ubPath + QString("/Sankore Document %1").arg(dirName);
}
void UBPersistenceManager::addDirectoryContentToDocument(const QString& documentRootFolder, UBDocumentProxy* pDocument)
{ void UBPersistenceManager::generatePathIfNeeded(UBDocumentProxy* pDocumentProxy)
int sourcePageCount = sceneCountInDir(documentRootFolder); {
if (pDocumentProxy->persistencePath().length() == 0)
int targetPageCount = pDocument->pageCount(); {
pDocumentProxy->setPersistencePath(generateUniqueDocumentPath());
for(int sourceIndex = 0 ; sourceIndex < sourcePageCount; sourceIndex++) }
{ }
int targetIndex = targetPageCount + sourceIndex;
QFile svg(documentRootFolder + UBFileSystemUtils::digitFileFormat("/page%1.svg", sourceIndex + 1)); void UBPersistenceManager::addDirectoryContentToDocument(const QString& documentRootFolder, UBDocumentProxy* pDocument)
svg.copy(pDocument->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", targetIndex + 1)); {
int sourcePageCount = sceneCountInDir(documentRootFolder);
UBSvgSubsetAdaptor::setSceneUuid(pDocument, targetIndex, QUuid::createUuid());
int targetPageCount = pDocument->pageCount();
QFile thumb(documentRootFolder + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceIndex + 1));
thumb.copy(pDocument->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetIndex + 1)); for(int sourceIndex = 0 ; sourceIndex < sourcePageCount; sourceIndex++)
} {
int targetIndex = targetPageCount + sourceIndex;
foreach(QString dir, mDocumentSubDirectories)
{ QFile svg(documentRootFolder + UBFileSystemUtils::digitFileFormat("/page%1.svg", sourceIndex + 1));
qDebug() << "copying " << documentRootFolder << "/" << dir << " to " << pDocument->persistencePath() << "/" + dir; svg.copy(pDocument->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", targetIndex + 1));
UBFileSystemUtils::copyDir(documentRootFolder + "/" + dir, pDocument->persistencePath() + "/" + dir); UBSvgSubsetAdaptor::setSceneUuid(pDocument, targetIndex, QUuid::createUuid());
}
QFile thumb(documentRootFolder + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceIndex + 1));
pDocument->setPageCount(sceneCount(pDocument)); thumb.copy(pDocument->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetIndex + 1));
}
}
foreach(QString dir, mDocumentSubDirectories)
{
void UBPersistenceManager::upgradeDocumentIfNeeded(UBDocumentProxy* pDocumentProxy) qDebug() << "copying " << documentRootFolder << "/" << dir << " to " << pDocument->persistencePath() << "/" + dir;
{
int pageCount = pDocumentProxy->pageCount(); UBFileSystemUtils::copyDir(documentRootFolder + "/" + dir, pDocument->persistencePath() + "/" + dir);
}
for(int index = 0 ; index < pageCount; index++)
{ pDocument->setPageCount(sceneCount(pDocument));
UBSvgSubsetAdaptor::upgradeScene(pDocumentProxy, index);
} }
pDocumentProxy->setMetaData(UBSettings::documentVersion, UBSettings::currentFileVersion);
void UBPersistenceManager::upgradeDocumentIfNeeded(UBDocumentProxy* pDocumentProxy)
UBMetadataDcSubsetAdaptor::persist(pDocumentProxy); {
} int pageCount = pDocumentProxy->pageCount();
for(int index = 0 ; index < pageCount; index++)
void UBPersistenceManager::upgradeAllDocumentsIfNeeded() {
{ UBSvgSubsetAdaptor::upgradeScene(pDocumentProxy, index);
foreach(QPointer<UBDocumentProxy> proxy, documentProxies) }
{
upgradeDocumentIfNeeded(proxy); pDocumentProxy->setMetaData(UBSettings::documentVersion, UBSettings::currentFileVersion);
}
} UBMetadataDcSubsetAdaptor::persist(pDocumentProxy);
}
UBDocumentProxy* UBPersistenceManager::documentByUuid(const QUuid& pUuid) void UBPersistenceManager::upgradeAllDocumentsIfNeeded()
{ {
for(int i = 0 ; i < documentProxies.length(); i++) foreach(QPointer<UBDocumentProxy> proxy, documentProxies)
{ {
UBDocumentProxy* proxy = documentProxies.at(i); upgradeDocumentIfNeeded(proxy);
}
if (proxy && proxy->uuid() == pUuid) }
{
return proxy;
}
} UBDocumentProxy* UBPersistenceManager::documentByUuid(const QUuid& pUuid)
{
return 0; for(int i = 0 ; i < documentProxies.length(); i++)
{
} UBDocumentProxy* proxy = documentProxies.at(i);
if (proxy && proxy->uuid() == pUuid)
bool UBPersistenceManager::isEmpty(UBDocumentProxy* pDocumentProxy) {
{ return proxy;
if(!pDocumentProxy) }
return true; }
if (pDocumentProxy->pageCount() > 1) return 0;
return false;
}
UBGraphicsScene *theSoleScene = UBSvgSubsetAdaptor::loadScene(pDocumentProxy, 0);
bool empty = false; bool UBPersistenceManager::isEmpty(UBDocumentProxy* pDocumentProxy)
{
if (theSoleScene) if(!pDocumentProxy)
{ return true;
empty = theSoleScene->isEmpty();
delete theSoleScene; if (pDocumentProxy->pageCount() > 1)
} return false;
else
{ UBGraphicsScene *theSoleScene = UBSvgSubsetAdaptor::loadScene(pDocumentProxy, 0);
empty = true;
} bool empty = false;
return empty; if (theSoleScene)
} {
empty = theSoleScene->isEmpty();
delete theSoleScene;
void UBPersistenceManager::purgeEmptyDocuments() }
{ else
if(!mHasPurgedDocuments) // hack to workaround the fact that app closing is called twice :-( {
{ empty = true;
QList<UBDocumentProxy*> toBeDeleted; }
foreach(UBDocumentProxy* docProxy, mDocumentCreatedDuringSession) return empty;
{ }
if (isEmpty(docProxy))
{
toBeDeleted << docProxy; void UBPersistenceManager::purgeEmptyDocuments()
} {
} if(!mHasPurgedDocuments) // hack to workaround the fact that app closing is called twice :-(
{
foreach(UBDocumentProxy* docProxy, toBeDeleted) QList<UBDocumentProxy*> toBeDeleted;
{
deleteDocument(docProxy); foreach(UBDocumentProxy* docProxy, mDocumentCreatedDuringSession)
} {
if (isEmpty(docProxy))
mHasPurgedDocuments = true; {
} toBeDeleted << docProxy;
} }
}
QString UBPersistenceManager::addVideoFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid) foreach(UBDocumentProxy* docProxy, toBeDeleted)
{ {
QFileInfo fi(path); deleteDocument(docProxy);
}
if (!fi.exists() || !pDocumentProxy || objectUuid.isNull())
return ""; mHasPurgedDocuments = true;
}
QString fileName = UBPersistenceManager::videoDirectory + "/" + objectUuid.toString() + "." + fi.suffix(); }
QString destPath = pDocumentProxy->persistencePath() + "/" + fileName;
QString UBPersistenceManager::addVideoFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid)
if (!QFile::exists(destPath)) {
{ QFileInfo fi(path);
QDir dir;
dir.mkdir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::videoDirectory); if (!fi.exists() || !pDocumentProxy || objectUuid.isNull())
return "";
QFile source(path);
QString fileName = UBPersistenceManager::videoDirectory + "/" + objectUuid.toString() + "." + fi.suffix();
source.copy(destPath);
QString destPath = pDocumentProxy->persistencePath() + "/" + fileName;
}
if (!QFile::exists(destPath))
return fileName; {
QDir dir;
} dir.mkdir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::videoDirectory);
QFile source(path);
QString UBPersistenceManager::addVideoFileToDocument(UBDocumentProxy* pDocumentProxy, QUrl sourceUrl, QByteArray pPayload, QUuid objectUuid)
{ source.copy(destPath);
if (!pDocumentProxy || objectUuid.isNull())
return ""; }
QString urlPath = sourceUrl.path(); return fileName;
int lastDot = urlPath.lastIndexOf(".");
QString suffix = urlPath.right(urlPath.length() - lastDot - 1); }
QString fileName = UBPersistenceManager::videoDirectory + "/" + objectUuid.toString() + "." + suffix;
QString destPath = pDocumentProxy->persistencePath() + "/" + fileName; QString UBPersistenceManager::addVideoFileToDocument(UBDocumentProxy* pDocumentProxy, QUrl sourceUrl, QByteArray pPayload, QUuid objectUuid)
{
if (!QFile::exists(destPath)) if (!pDocumentProxy || objectUuid.isNull())
{ return "";
QDir dir;
dir.mkdir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::videoDirectory); QString urlPath = sourceUrl.path();
int lastDot = urlPath.lastIndexOf(".");
QFile newFile(destPath); QString suffix = urlPath.right(urlPath.length() - lastDot - 1);
if (newFile.open(QIODevice::WriteOnly)) QString fileName = UBPersistenceManager::videoDirectory + "/" + objectUuid.toString() + "." + suffix;
{ QString destPath = pDocumentProxy->persistencePath() + "/" + fileName;
newFile.write(pPayload);
newFile.flush(); if (!QFile::exists(destPath))
newFile.close(); {
} QDir dir;
} dir.mkdir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::videoDirectory);
return fileName; QFile newFile(destPath);
} if (newFile.open(QIODevice::WriteOnly))
{
newFile.write(pPayload);
newFile.flush();
QString UBPersistenceManager::addAudioFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid) newFile.close();
{ }
QFileInfo fi(path); }
if (!fi.exists() || !pDocumentProxy || objectUuid.isNull()) return fileName;
return "";
}
QString fileName = UBPersistenceManager::audioDirectory + "/" + objectUuid.toString() + "." + fi.suffix();
QString destPath = pDocumentProxy->persistencePath() + "/" + fileName;
QString UBPersistenceManager::addAudioFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid)
if (!QFile::exists(destPath)) {
{ QFileInfo fi(path);
QDir dir;
dir.mkdir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::audioDirectory); if (!fi.exists() || !pDocumentProxy || objectUuid.isNull())
return "";
QFile source(path);
QString fileName = UBPersistenceManager::audioDirectory + "/" + objectUuid.toString() + "." + fi.suffix();
source.copy(destPath);
QString destPath = pDocumentProxy->persistencePath() + "/" + fileName;
}
if (!QFile::exists(destPath))
return fileName; {
QDir dir;
} dir.mkdir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::audioDirectory);
QFile source(path);
QString UBPersistenceManager::addAudioFileToDocument(UBDocumentProxy* pDocumentProxy, QUrl sourceUrl, QByteArray pPayload, QUuid objectUuid)
{ source.copy(destPath);
if (!pDocumentProxy || objectUuid.isNull())
return ""; }
QString urlPath = sourceUrl.path(); return fileName;
int lastDot = urlPath.lastIndexOf(".");
QString suffix = urlPath.right(urlPath.length() - lastDot - 1); }
QString fileName = UBPersistenceManager::audioDirectory + "/" + objectUuid.toString() + "." + suffix;
QString destPath = pDocumentProxy->persistencePath() + "/" + fileName; QString UBPersistenceManager::addAudioFileToDocument(UBDocumentProxy* pDocumentProxy, QUrl sourceUrl, QByteArray pPayload, QUuid objectUuid)
{
if (!QFile::exists(destPath)) if (!pDocumentProxy || objectUuid.isNull())
{ return "";
QDir dir;
dir.mkdir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::audioDirectory); QString urlPath = sourceUrl.path();
int lastDot = urlPath.lastIndexOf(".");
QFile newFile(destPath); QString suffix = urlPath.right(urlPath.length() - lastDot - 1);
if (newFile.open(QIODevice::WriteOnly)) QString fileName = UBPersistenceManager::audioDirectory + "/" + objectUuid.toString() + "." + suffix;
{ QString destPath = pDocumentProxy->persistencePath() + "/" + fileName;
newFile.write(pPayload);
newFile.flush(); if (!QFile::exists(destPath))
newFile.close(); {
} QDir dir;
} dir.mkdir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::audioDirectory);
return fileName; QFile newFile(destPath);
} if (newFile.open(QIODevice::WriteOnly))
{
newFile.write(pPayload);
QString UBPersistenceManager::addPdfFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid) newFile.flush();
{ newFile.close();
QFileInfo fi(path); }
}
if (!fi.exists() || !pDocumentProxy || objectUuid.isNull())
return ""; return fileName;
QString fileName = UBPersistenceManager::objectDirectory + "/" + objectUuid.toString() + "." + fi.suffix(); }
QString destPath = pDocumentProxy->persistencePath() + "/" + fileName;
if (!QFile::exists(destPath)) QString UBPersistenceManager::addPdfFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid)
{ {
QDir dir; QFileInfo fi(path);
dir.mkpath(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::objectDirectory);
if (!fi.exists() || !pDocumentProxy || objectUuid.isNull())
QFile source(path); return "";
source.copy(destPath);
} QString fileName = UBPersistenceManager::objectDirectory + "/" + objectUuid.toString() + "." + fi.suffix();
QString destPath = pDocumentProxy->persistencePath() + "/" + fileName;
return fileName;
} if (!QFile::exists(destPath))
QString UBPersistenceManager::addGraphicsWidgteToDocument(UBDocumentProxy *pDocumentProxy, QString path, QUuid objectUuid) {
{ QDir dir;
QFileInfo fi(path); dir.mkpath(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::objectDirectory);
if (!fi.exists() || !pDocumentProxy || objectUuid.isNull()) QFile source(path);
return ""; source.copy(destPath);
}
QString widgetRootDir = path;
QString extension = QFileInfo(widgetRootDir).suffix(); return fileName;
}
QString widgetTargetDir = pDocumentProxy->persistencePath() + "/" + widgetDirectory + "/" + objectUuid.toString() + "." + extension; QString UBPersistenceManager::addGraphicsWidgteToDocument(UBDocumentProxy *pDocumentProxy, QString path, QUuid objectUuid)
{
if (!QFile::exists(widgetTargetDir)) { QFileInfo fi(path);
QDir dir;
dir.mkpath(widgetTargetDir); if (!fi.exists() || !pDocumentProxy || objectUuid.isNull())
UBFileSystemUtils::copyDir(widgetRootDir, widgetTargetDir); return "";
}
QString widgetRootDir = path;
if (!QFile::exists(widgetTargetDir)) QString extension = QFileInfo(widgetRootDir).suffix();
widgetTargetDir = QString();
QString widgetTargetDir = pDocumentProxy->persistencePath() + "/" + widgetDirectory + "/" + objectUuid.toString() + "." + extension;
return widgetTargetDir;
} if (!QFile::exists(widgetTargetDir)) {
QDir dir;
dir.mkpath(widgetTargetDir);
void UBPersistenceManager::documentRepositoryChanged(const QString& path) UBFileSystemUtils::copyDir(widgetRootDir, widgetTargetDir);
{ }
Q_UNUSED(path);
checkIfDocumentRepositoryExists(); if (!QFile::exists(widgetTargetDir))
} widgetTargetDir = QString();
return widgetTargetDir;
void UBPersistenceManager::checkIfDocumentRepositoryExists() }
{
QDir rp(mDocumentRepositoryPath);
void UBPersistenceManager::documentRepositoryChanged(const QString& path)
if (!rp.exists()) {
{ Q_UNUSED(path);
// we have lost the document repository .. checkIfDocumentRepositoryExists();
}
QString humanPath = QDir::cleanPath(mDocumentRepositoryPath);
humanPath = QDir::toNativeSeparators(humanPath);
void UBPersistenceManager::checkIfDocumentRepositoryExists()
UBApplication::mainWindow->warning(tr("Document Repository Loss"),tr("Sankore has lost access to the document repository '%1'. Unfortunately the application must shut down to avoid data corruption. Latest changes may be lost as well.").arg(humanPath)); {
QDir rp(mDocumentRepositoryPath);
UBApplication::quit();
} if (!rp.exists())
} {
// we have lost the document repository ..
bool UBPersistenceManager::mayHaveVideo(UBDocumentProxy* pDocumentProxy) QString humanPath = QDir::cleanPath(mDocumentRepositoryPath);
{ humanPath = QDir::toNativeSeparators(humanPath);
QDir videoDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::videoDirectory);
UBApplication::mainWindow->warning(tr("Document Repository Loss"),tr("Sankore has lost access to the document repository '%1'. Unfortunately the application must shut down to avoid data corruption. Latest changes may be lost as well.").arg(humanPath));
return videoDir.exists() && videoDir.entryInfoList().length() > 0;
} UBApplication::quit();
}
bool UBPersistenceManager::mayHaveAudio(UBDocumentProxy* pDocumentProxy) }
{
QDir audioDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::audioDirectory);
bool UBPersistenceManager::mayHaveVideo(UBDocumentProxy* pDocumentProxy)
return audioDir.exists() && audioDir.entryInfoList().length() > 0; {
} QDir videoDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::videoDirectory);
bool UBPersistenceManager::mayHavePDF(UBDocumentProxy* pDocumentProxy) return videoDir.exists() && videoDir.entryInfoList().length() > 0;
{ }
QDir objectDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::objectDirectory);
bool UBPersistenceManager::mayHaveAudio(UBDocumentProxy* pDocumentProxy)
QStringList filters; {
filters << "*.pdf"; QDir audioDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::audioDirectory);
return objectDir.exists() && objectDir.entryInfoList(filters).length() > 0; return audioDir.exists() && audioDir.entryInfoList().length() > 0;
} }
bool UBPersistenceManager::mayHavePDF(UBDocumentProxy* pDocumentProxy)
bool UBPersistenceManager::mayHaveSVGImages(UBDocumentProxy* pDocumentProxy) {
{ QDir objectDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::objectDirectory);
QDir imageDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::imageDirectory);
QStringList filters;
QStringList filters; filters << "*.pdf";
filters << "*.svg";
return objectDir.exists() && objectDir.entryInfoList(filters).length() > 0;
return imageDir.exists() && imageDir.entryInfoList(filters).length() > 0; }
}
bool UBPersistenceManager::mayHaveSVGImages(UBDocumentProxy* pDocumentProxy)
bool UBPersistenceManager::mayHaveWidget(UBDocumentProxy* pDocumentProxy) {
{ QDir imageDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::imageDirectory);
QDir widgetDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::widgetDirectory);
QStringList filters;
return widgetDir.exists() && widgetDir.entryInfoList(QDir::Dirs).length() > 0; filters << "*.svg";
}
return imageDir.exists() && imageDir.entryInfoList(filters).length() > 0;
void UBPersistenceManager::persistTeacherBar(UBDocumentProxy* pDocumentProxy, int page, sTeacherBarInfos infos) }
{
if(NULL != pDocumentProxy)
{ bool UBPersistenceManager::mayHaveWidget(UBDocumentProxy* pDocumentProxy)
QFile f(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", page + 1)); {
if(f.exists()) QDir widgetDir(pDocumentProxy->persistencePath() + "/" + UBPersistenceManager::widgetDirectory);
{
if(f.open(QIODevice::ReadOnly)) return widgetDir.exists() && widgetDir.entryInfoList(QDir::Dirs).length() > 0;
{ }
QDomDocument domDoc;
if(domDoc.setContent(f.readAll())) void UBPersistenceManager::persistTeacherBar(UBDocumentProxy* pDocumentProxy, int page, sTeacherBarInfos infos)
{ {
f.close(); if(NULL != pDocumentProxy)
if(f.open(QIODevice::WriteOnly)) {
{ QFile f(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", page + 1));
QDomElement rootElem = domDoc.documentElement(); if(f.exists())
QDomNode teacherBarNode = rootElem.namedItem("teacherBar"); {
if(teacherBarNode.isNull()) if(f.open(QIODevice::ReadOnly))
{ {
// Create the element QDomDocument domDoc;
QDomElement teacherElem = domDoc.createElement("teacherBar"); if(domDoc.setContent(f.readAll()))
rootElem.appendChild(teacherElem); {
teacherBarNode = teacherElem; f.close();
} if(f.open(QIODevice::WriteOnly))
{
// Set the <teacherBar> element values QDomElement rootElem = domDoc.documentElement();
QDomElement teacherBarElem = teacherBarNode.toElement(); QDomNode teacherBarNode = rootElem.namedItem("teacherBar");
teacherBarElem.setAttribute("title", infos.title); if(teacherBarNode.isNull())
{
QString qsAct; // Create the element
for(int i=0; i<infos.actions.size(); i++){ QDomElement teacherElem = domDoc.createElement("teacherBar");
if(0 != i){ rootElem.appendChild(teacherElem);
qsAct.append('@'); teacherBarNode = teacherElem;
} }
qsAct.append(infos.actions.at(i));
} // Set the <teacherBar> element values
teacherBarElem.setAttribute("actions", qsAct); QDomElement teacherBarElem = teacherBarNode.toElement();
teacherBarElem.setAttribute("title", infos.title);
QString qsMedias;
for(int j=0; j<infos.medias.size(); j++){ QString qsAct;
if(0 != j){ for(int i=0; i<infos.actions.size(); i++){
qsMedias.append('@'); if(0 != i){
} qsAct.append('@');
qsMedias.append(infos.medias.at(j)); }
} qsAct.append(infos.actions.at(i));
teacherBarElem.setAttribute("medias", qsMedias); }
teacherBarElem.setAttribute("actions", qsAct);
QString qsUrls;
for(int k=0; k<infos.urls.size(); k++){ QString qsMedias;
if(0 != k){ for(int j=0; j<infos.medias.size(); j++){
qsUrls.append('@'); if(0 != j){
} qsMedias.append('@');
qsUrls.append(infos.urls.at(k)); }
} qsMedias.append(infos.medias.at(j));
teacherBarElem.setAttribute("links", qsUrls); }
teacherBarElem.setAttribute("medias", qsMedias);
teacherBarElem.setAttribute("comments", infos.comments);
QString qsUrls;
// Save the file for(int k=0; k<infos.urls.size(); k++){
f.write(domDoc.toString().toAscii()); if(0 != k){
f.close(); qsUrls.append('@');
} }
} qsUrls.append(infos.urls.at(k));
f.close(); }
} teacherBarElem.setAttribute("links", qsUrls);
}
} teacherBarElem.setAttribute("comments", infos.comments);
}
// Save the file
sTeacherBarInfos UBPersistenceManager::getTeacherBarInfos(UBDocumentProxy* pDocumentProxy, int page) f.write(domDoc.toString().toAscii());
{ f.close();
sTeacherBarInfos infos; }
}
if(NULL != pDocumentProxy) f.close();
{ }
QFile f(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", page + 1)); }
if(f.exists()) }
{ }
if(f.open(QIODevice::ReadWrite))
{ sTeacherBarInfos UBPersistenceManager::getTeacherBarInfos(UBDocumentProxy* pDocumentProxy, int page)
QDomDocument domDoc; {
if(domDoc.setContent(f.readAll())) sTeacherBarInfos infos;
{
QDomElement rootElem = domDoc.documentElement(); if(NULL != pDocumentProxy)
QDomNode teacherBarNode = rootElem.namedItem("teacherBar"); {
QFile f(pDocumentProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", page + 1));
infos.title = teacherBarNode.toElement().attributeNode("title").value(); if(f.exists())
infos.actions = teacherBarNode.toElement().attributeNode("actions").value().split("@"); {
infos.medias = teacherBarNode.toElement().attributeNode("medias").value().split("@"); if(f.open(QIODevice::ReadWrite))
infos.urls = teacherBarNode.toElement().attributeNode("links").value().split("@"); {
infos.comments = teacherBarNode.toElement().attributeNode("comments").value(); QDomDocument domDoc;
} if(domDoc.setContent(f.readAll()))
f.close(); {
} QDomElement rootElem = domDoc.documentElement();
} QDomNode teacherBarNode = rootElem.namedItem("teacherBar");
}
infos.title = teacherBarNode.toElement().attributeNode("title").value();
return infos; infos.actions = teacherBarNode.toElement().attributeNode("actions").value().split("@");
} infos.medias = teacherBarNode.toElement().attributeNode("medias").value().split("@");
infos.urls = teacherBarNode.toElement().attributeNode("links").value().split("@");
infos.comments = teacherBarNode.toElement().attributeNode("comments").value();
}
f.close();
}
}
}
return infos;
}
/* /*
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef UBPERSISTENCEMANAGER_H_ #ifndef UBPERSISTENCEMANAGER_H_
#define UBPERSISTENCEMANAGER_H_ #define UBPERSISTENCEMANAGER_H_
#include <QtCore> #include <QtCore>
#include "UBSceneCache.h" #include "UBSceneCache.h"
struct sTeacherBarInfos struct sTeacherBarInfos
{ {
QString title; QString title;
QStringList actions; QStringList actions;
QStringList medias; QStringList medias;
QStringList urls; QStringList urls;
QString comments; QString comments;
}; };
class UBDocument; class UBDocument;
class UBDocumentProxy; class UBDocumentProxy;
class UBGraphicsScene; class UBGraphicsScene;
class UBPersistenceManager : public QObject class UBPersistenceManager : public QObject
{ {
Q_OBJECT Q_OBJECT
private: private:
UBPersistenceManager(QObject *pParent = 0); UBPersistenceManager(QObject *pParent = 0);
static UBPersistenceManager* sSingleton; static UBPersistenceManager* sSingleton;
public: public:
virtual ~UBPersistenceManager(); virtual ~UBPersistenceManager();
static const QString imageDirectory; static const QString imageDirectory;
static const QString objectDirectory; static const QString objectDirectory;
static const QString videoDirectory; static const QString videoDirectory;
static const QString audioDirectory; static const QString audioDirectory;
static const QString widgetDirectory; static const QString widgetDirectory;
static UBPersistenceManager* persistenceManager(); static UBPersistenceManager* persistenceManager();
static void destroy(); static void destroy();
virtual UBDocumentProxy* createDocument(const QString& pGroupName = "", const QString& pName = "", bool withEmptyPage = true); virtual UBDocumentProxy* createDocument(const QString& pGroupName = "", const QString& pName = "", bool withEmptyPage = true);
virtual UBDocumentProxy* createDocumentFromDir(const QString& pDocumentDirectory); virtual UBDocumentProxy* createDocumentFromDir(const QString& pDocumentDirectory, const QString& pGroupName = "", const QString& pName = "", bool withEmptyPage = false);
virtual UBDocumentProxy* persistDocumentMetadata(UBDocumentProxy* pDocumentProxy); virtual UBDocumentProxy* persistDocumentMetadata(UBDocumentProxy* pDocumentProxy);
virtual UBDocumentProxy* duplicateDocument(UBDocumentProxy* pDocumentProxy); virtual UBDocumentProxy* duplicateDocument(UBDocumentProxy* pDocumentProxy);
virtual void deleteDocument(UBDocumentProxy* pDocumentProxy); virtual void deleteDocument(UBDocumentProxy* pDocumentProxy);
virtual void deleteDocumentScenes(UBDocumentProxy* pDocumentProxy, const QList<int>& indexes); virtual void deleteDocumentScenes(UBDocumentProxy* pDocumentProxy, const QList<int>& indexes);
virtual void duplicateDocumentScene(UBDocumentProxy* pDocumentProxy, int index); virtual void duplicateDocumentScene(UBDocumentProxy* pDocumentProxy, int index);
virtual void persistDocumentScene(UBDocumentProxy* pDocumentProxy, virtual void persistDocumentScene(UBDocumentProxy* pDocumentProxy,
UBGraphicsScene* pScene, const int pSceneIndex); UBGraphicsScene* pScene, const int pSceneIndex);
virtual void persistTeacherBar(UBDocumentProxy* pDocumentProxy, int page, sTeacherBarInfos infos); virtual void persistTeacherBar(UBDocumentProxy* pDocumentProxy, int page, sTeacherBarInfos infos);
sTeacherBarInfos getTeacherBarInfos(UBDocumentProxy* pDocumentProxy, int page); sTeacherBarInfos getTeacherBarInfos(UBDocumentProxy* pDocumentProxy, int page);
virtual UBGraphicsScene* createDocumentSceneAt(UBDocumentProxy* pDocumentProxy, int index); virtual UBGraphicsScene* createDocumentSceneAt(UBDocumentProxy* pDocumentProxy, int index);
virtual void insertDocumentSceneAt(UBDocumentProxy* pDocumentProxy, UBGraphicsScene* scene, int index); virtual void insertDocumentSceneAt(UBDocumentProxy* pDocumentProxy, UBGraphicsScene* scene, int index);
virtual void moveSceneToIndex(UBDocumentProxy* pDocumentProxy, int source, int target); virtual void moveSceneToIndex(UBDocumentProxy* pDocumentProxy, int source, int target);
virtual UBGraphicsScene* loadDocumentScene(UBDocumentProxy* pDocumentProxy, int sceneIndex); virtual UBGraphicsScene* loadDocumentScene(UBDocumentProxy* pDocumentProxy, int sceneIndex);
UBGraphicsScene *getDocumentScene(UBDocumentProxy* pDocumentProxy, int sceneIndex) {return mSceneCache.value(pDocumentProxy, sceneIndex);} UBGraphicsScene *getDocumentScene(UBDocumentProxy* pDocumentProxy, int sceneIndex) {return mSceneCache.value(pDocumentProxy, sceneIndex);}
QList<QPointer<UBDocumentProxy> > documentProxies; QList<QPointer<UBDocumentProxy> > documentProxies;
virtual QStringList allShapes(); virtual QStringList allShapes();
virtual QStringList allGips(); virtual QStringList allGips();
virtual QStringList allSounds(); virtual QStringList allSounds();
virtual QStringList allImages(const QDir& dir); virtual QStringList allImages(const QDir& dir);
virtual QStringList allVideos(const QDir& dir); virtual QStringList allVideos(const QDir& dir);
virtual QStringList allWidgets(const QDir& dir); virtual QStringList allWidgets(const QDir& dir);
virtual QString generateUniqueDocumentPath(); virtual QString generateUniqueDocumentPath();
virtual void addDirectoryContentToDocument(const QString& documentRootFolder, UBDocumentProxy* pDocument); virtual void addDirectoryContentToDocument(const QString& documentRootFolder, UBDocumentProxy* pDocument);
virtual void upgradeDocumentIfNeeded(UBDocumentProxy* pDocumentProxy); virtual void upgradeDocumentIfNeeded(UBDocumentProxy* pDocumentProxy);
virtual void upgradeAllDocumentsIfNeeded(); virtual void upgradeAllDocumentsIfNeeded();
virtual UBDocumentProxy* documentByUuid(const QUuid& pUuid); virtual UBDocumentProxy* documentByUuid(const QUuid& pUuid);
QStringList documentSubDirectories() QStringList documentSubDirectories()
{ {
return mDocumentSubDirectories; return mDocumentSubDirectories;
} }
virtual bool isEmpty(UBDocumentProxy* pDocumentProxy); virtual bool isEmpty(UBDocumentProxy* pDocumentProxy);
virtual void purgeEmptyDocuments(); virtual void purgeEmptyDocuments();
virtual QString addVideoFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid); virtual QString addVideoFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid);
virtual QString addVideoFileToDocument(UBDocumentProxy* pDocumentProxy, QUrl sourceUrl, QByteArray pPayload, QUuid objectUuid); virtual QString addVideoFileToDocument(UBDocumentProxy* pDocumentProxy, QUrl sourceUrl, QByteArray pPayload, QUuid objectUuid);
virtual QString addAudioFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid); virtual QString addAudioFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid);
virtual QString addAudioFileToDocument(UBDocumentProxy* pDocumentProxy, QUrl sourceUrl, QByteArray pPayload, QUuid objectUuid); virtual QString addAudioFileToDocument(UBDocumentProxy* pDocumentProxy, QUrl sourceUrl, QByteArray pPayload, QUuid objectUuid);
virtual QString addPdfFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid); virtual QString addPdfFileToDocument(UBDocumentProxy* pDocumentProxy, QString path, QUuid objectUuid);
virtual QString addGraphicsWidgteToDocument(UBDocumentProxy *mDocumentProxy, QString path, QUuid objectUuid); virtual QString addGraphicsWidgteToDocument(UBDocumentProxy *mDocumentProxy, QString path, QUuid objectUuid);
bool mayHaveVideo(UBDocumentProxy* pDocumentProxy); bool mayHaveVideo(UBDocumentProxy* pDocumentProxy);
bool mayHaveAudio(UBDocumentProxy* pDocumentProxy); bool mayHaveAudio(UBDocumentProxy* pDocumentProxy);
bool mayHavePDF(UBDocumentProxy* pDocumentProxy); bool mayHavePDF(UBDocumentProxy* pDocumentProxy);
bool mayHaveSVGImages(UBDocumentProxy* pDocumentProxy); bool mayHaveSVGImages(UBDocumentProxy* pDocumentProxy);
bool mayHaveWidget(UBDocumentProxy* pDocumentProxy); bool mayHaveWidget(UBDocumentProxy* pDocumentProxy);
signals: signals:
void proxyListChanged(); void proxyListChanged();
void documentCreated(UBDocumentProxy* pDocumentProxy); void documentCreated(UBDocumentProxy* pDocumentProxy);
void documentMetadataChanged(UBDocumentProxy* pDocumentProxy); void documentMetadataChanged(UBDocumentProxy* pDocumentProxy);
void documentCommitted(UBDocumentProxy* pDocumentProxy); void documentCommitted(UBDocumentProxy* pDocumentProxy);
void documentWillBeDeleted(UBDocumentProxy* pDocumentProxy); void documentWillBeDeleted(UBDocumentProxy* pDocumentProxy);
void documentSceneCreated(UBDocumentProxy* pDocumentProxy, int pIndex); void documentSceneCreated(UBDocumentProxy* pDocumentProxy, int pIndex);
void documentSceneMoved(UBDocumentProxy* pDocumentProxy, int pIndex); void documentSceneMoved(UBDocumentProxy* pDocumentProxy, int pIndex);
void documentSceneWillBeDeleted(UBDocumentProxy* pDocumentProxy, int pIndex); void documentSceneWillBeDeleted(UBDocumentProxy* pDocumentProxy, int pIndex);
void documentSceneDeleted(UBDocumentProxy* pDocumentProxy, int pDeletedIndex); void documentSceneDeleted(UBDocumentProxy* pDocumentProxy, int pDeletedIndex);
private: private:
int sceneCount(const UBDocumentProxy* pDocumentProxy); int sceneCount(const UBDocumentProxy* pDocumentProxy);
int sceneCountInDir(const QString& pPath); int sceneCountInDir(const QString& pPath);
QList<QPointer<UBDocumentProxy> > allDocumentProxies(); QList<QPointer<UBDocumentProxy> > allDocumentProxies();
void renamePage(UBDocumentProxy* pDocumentProxy, void renamePage(UBDocumentProxy* pDocumentProxy,
const int sourceIndex, const int targetIndex); const int sourceIndex, const int targetIndex);
void copyPage(UBDocumentProxy* pDocumentProxy, void copyPage(UBDocumentProxy* pDocumentProxy,
const int sourceIndex, const int targetIndex); const int sourceIndex, const int targetIndex);
void generatePathIfNeeded(UBDocumentProxy* pDocumentProxy); void generatePathIfNeeded(UBDocumentProxy* pDocumentProxy);
void checkIfDocumentRepositoryExists(); void checkIfDocumentRepositoryExists();
UBSceneCache mSceneCache; UBSceneCache mSceneCache;
QStringList mDocumentSubDirectories; QStringList mDocumentSubDirectories;
QMutex mDeletedListMutex; QMutex mDeletedListMutex;
bool mHasPurgedDocuments; bool mHasPurgedDocuments;
QList<UBDocumentProxy*> mDocumentCreatedDuringSession; QList<UBDocumentProxy*> mDocumentCreatedDuringSession;
QString mDocumentRepositoryPath; QString mDocumentRepositoryPath;
private slots: private slots:
void documentRepositoryChanged(const QString& path); void documentRepositoryChanged(const QString& path);
}; };
#endif /* UBPERSISTENCEMANAGER_H_ */ #endif /* UBPERSISTENCEMANAGER_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment