diff --git a/src/adaptors/UBCFFSubsetAdaptor.cpp b/src/adaptors/UBCFFSubsetAdaptor.cpp index 349b6380..3c462c91 100644 --- a/src/adaptors/UBCFFSubsetAdaptor.cpp +++ b/src/adaptors/UBCFFSubsetAdaptor.cpp @@ -1078,7 +1078,7 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::persistCurrentScene() { if (mCurrentScene != 0 && mCurrentScene->isModified()) { - UBThumbnailAdaptor::persistScene(mProxy->persistencePath(), mCurrentScene, mProxy->pageCount() - 1); + UBThumbnailAdaptor::persistScene(mProxy, mCurrentScene, mProxy->pageCount() - 1); UBSvgSubsetAdaptor::persistScene(mProxy, mCurrentScene, mProxy->pageCount() - 1); mCurrentScene->setModified(false); @@ -1102,7 +1102,7 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::persistScenes() UBSvgSubsetAdaptor::persistScene(mProxy, mCurrentScene, i); UBGraphicsScene *tmpScene = UBSvgSubsetAdaptor::loadScene(mProxy, i); tmpScene->setModified(true); - UBThumbnailAdaptor::persistScene(mProxy->persistencePath(), tmpScene, i); + UBThumbnailAdaptor::persistScene(mProxy, tmpScene, i); delete tmpScene; mCurrentScene->setModified(false); diff --git a/src/adaptors/UBSvgSubsetAdaptor.cpp b/src/adaptors/UBSvgSubsetAdaptor.cpp index 822f1ba2..08e51c03 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.cpp +++ b/src/adaptors/UBSvgSubsetAdaptor.cpp @@ -56,6 +56,8 @@ #include "interfaces/IDataStorage.h" +#include "document/UBDocumentContainer.h" + #include "pdf/PDFRenderer.h" #include "core/memcheck.h" @@ -313,7 +315,7 @@ QString UBSvgSubsetAdaptor::readTeacherGuideNode(int sceneIndex) { QString result; - QString fileName = UBApplication::boardController->activeDocument()->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", sceneIndex); + QString fileName = UBApplication::boardController->selectedDocument()->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", sceneIndex); QFile file(fileName); file.open(QIODevice::ReadOnly); QByteArray fileByteArray=file.readAll(); diff --git a/src/adaptors/UBThumbnailAdaptor.cpp b/src/adaptors/UBThumbnailAdaptor.cpp index b414ac90..5d0e6436 100644 --- a/src/adaptors/UBThumbnailAdaptor.cpp +++ b/src/adaptors/UBThumbnailAdaptor.cpp @@ -1,186 +1,231 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "UBThumbnailAdaptor.h" - -#include - -#include "frameworks/UBFileSystemUtils.h" - -#include "core/UBPersistenceManager.h" -#include "core/UBApplication.h" -#include "core/UBSettings.h" - -#include "board/UBBoardController.h" - -#include "document/UBDocumentProxy.h" - -#include "domain/UBGraphicsScene.h" - -#include "UBSvgSubsetAdaptor.h" - -#include "core/memcheck.h" - -void UBThumbnailAdaptor::generateMissingThumbnails(UBDocumentProxy* proxy) -{ - int existingPageCount = proxy->pageCount(); - - for (int iPageNo = 0; iPageNo < existingPageCount; ++iPageNo) - { - QString thumbFileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", iPageNo); - - QFile thumbFile(thumbFileName); - - if (!thumbFile.exists()) - { - bool displayMessage = (existingPageCount > 5); - - int thumbCount = 0; - - UBGraphicsScene* scene = UBSvgSubsetAdaptor::loadScene(proxy, iPageNo); - - if (scene) - { - thumbCount++; - - if (displayMessage && thumbCount == 1) - UBApplication::showMessage(tr("Generating preview thumbnails ...")); - - persistScene(proxy->persistencePath(), scene, iPageNo); - } - - if (displayMessage && thumbCount > 0) - UBApplication::showMessage(tr("%1 thumbnails generated ...").arg(thumbCount)); - - } - } -} - -QList UBThumbnailAdaptor::load(UBDocumentProxy* proxy) -{ - QList thumbnails; - - if (!proxy || proxy->persistencePath().isEmpty()) - return thumbnails; - - //compatibility with older formats (<= 4.0.b.2.0) : generate missing thumbnails - generateMissingThumbnails(proxy); - - //end compatibility with older format - - bool moreToProcess = true; - int pageCount = UBApplication::boardController->sceneIndexFromPage(0); - - while (moreToProcess) { - pageCount++; - QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageCount); - - QFile file(fileName); - if (file.exists()) { - QPixmap pix; - //Warning. Works only with modified Qt -#ifdef Q_WS_X11 - //pix.load(fileName, 0, Qt::AutoColor); - pix.load(fileName, 0); -#else - pix.load(fileName, 0, Qt::AutoColor, false); -#endif - thumbnails.append(pix); - } else { - moreToProcess = false; - } - } - return thumbnails; -} - -QPixmap UBThumbnailAdaptor::load(UBDocumentProxy* proxy, int index) -{ - int existingPageCount = proxy->pageCount(); - - if (!proxy || proxy->persistencePath().size() == 0 || index < 0 || index > existingPageCount) - return QPixmap(); - //compatibility with older formats (<= 4.0.b.2.0) : generate missing thumbnails - generateMissingThumbnails(proxy); - - //end compatibility with older format - QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", index); - - QFile file(fileName); - if (file.exists()) - { - QPixmap pix; - //Warning. Works only with modified Qt -#ifdef Q_WS_X11 - pix.load(fileName, 0, Qt::AutoColor); -#else - pix.load(fileName, 0, Qt::AutoColor, false); -#endif - return pix; - } - return QPixmap(); -} - -void UBThumbnailAdaptor::persistScene(const QString& pDocPath, UBGraphicsScene* pScene, int pageIndex, bool overrideModified) -{ - QString fileName = pDocPath + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); - - QFile thumbFile(fileName); - - if (pScene->isModified() || overrideModified || !thumbFile.exists()) - { - qreal nominalWidth = pScene->nominalSize().width(); - qreal nominalHeight = pScene->nominalSize().height(); - qreal ratio = nominalWidth / nominalHeight; - QRectF sceneRect = pScene->normalizedSceneRect(ratio); - - qreal width = UBSettings::maxThumbnailWidth; - qreal height = width / ratio; - - QImage thumb(width, height, QImage::Format_ARGB32); - - QRectF imageRect(0, 0, width, height); - - QPainter painter(&thumb); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setRenderHint(QPainter::SmoothPixmapTransform, true); - - if (pScene->isDarkBackground()) - { - painter.fillRect(imageRect, Qt::black); - } - else - { - painter.fillRect(imageRect, Qt::white); - } - - pScene->setRenderingContext(UBGraphicsScene::NonScreen); - pScene->setRenderingQuality(UBItem::RenderingQualityHigh); - - pScene->render(&painter, imageRect, sceneRect, Qt::KeepAspectRatio); - - pScene->setRenderingContext(UBGraphicsScene::Screen); - pScene->setRenderingQuality(UBItem::RenderingQualityNormal); - - thumb.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation).save(fileName, "JPG"); - } -} - - -QUrl UBThumbnailAdaptor::thumbnailUrl(UBDocumentProxy* proxy, int pageIndex) -{ - QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); - - return QUrl::fromLocalFile(fileName); -} +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "UBThumbnailAdaptor.h" + +#include + +#include "frameworks/UBFileSystemUtils.h" + +#include "core/UBPersistenceManager.h" +#include "core/UBApplication.h" +#include "core/UBSettings.h" + +#include "board/UBBoardController.h" + +#include "document/UBDocumentProxy.h" + +#include "domain/UBGraphicsScene.h" + +#include "UBSvgSubsetAdaptor.h" + +#include "core/memcheck.h" + +void UBThumbnailAdaptor::generateMissingThumbnails(UBDocumentProxy* proxy) +{ + int existingPageCount = proxy->pageCount(); + + for (int iPageNo = 0; iPageNo < existingPageCount; ++iPageNo) + { + QString thumbFileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", iPageNo); + + QFile thumbFile(thumbFileName); + + if (!thumbFile.exists()) + { + bool displayMessage = (existingPageCount > 5); + + int thumbCount = 0; + + UBGraphicsScene* scene = UBSvgSubsetAdaptor::loadScene(proxy, iPageNo); + + if (scene) + { + thumbCount++; + + if (displayMessage && thumbCount == 1) + UBApplication::showMessage(tr("Generating preview thumbnails ...")); + + persistScene(proxy, scene, iPageNo); + } + + if (displayMessage && thumbCount > 0) + UBApplication::showMessage(tr("%1 thumbnails generated ...").arg(thumbCount)); + + } + } +} + +const QPixmap* UBThumbnailAdaptor::get(UBDocumentProxy* proxy, int pageIndex) +{ + QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); + + QFile file(fileName); + if (!file.exists()) + { + generateMissingThumbnails(proxy); + } + + if (file.exists()) + { + QPixmap* pix = new QPixmap(); + //Warning. Works only with modified Qt +#ifdef Q_WS_X11 + pix->load(fileName, 0, Qt::AutoColor); +#else + pix->load(fileName, 0, Qt::AutoColor, false); +#endif + return pix; + } + return NULL; +} + +void UBThumbnailAdaptor::load(UBDocumentProxy* proxy, QList& list) +{ + generateMissingThumbnails(proxy); + + foreach(const QPixmap* pm, list) + delete pm; + list.clear(); + for(int i=0; ipageCount(); i++) + list.append(get(proxy, i)); +} + + +/* +QList UBThumbnailAdaptor::load(UBDocumentProxy* proxy) +{ + QList thumbnails; + + qDebug() << "Loadinf thumbnails for " << proxy->name(); + + if (!proxy || proxy->persistencePath().isEmpty()) + return thumbnails; + + //compatibility with older formats (<= 4.0.b.2.0) : generate missing thumbnails + generateMissingThumbnails(proxy); + + //end compatibility with older format + + bool moreToProcess = true; + int pageCount = UBApplication::boardController->sceneIndexFromPage(0); + + while (moreToProcess) { + pageCount++; + QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageCount); + + QFile file(fileName); + if (file.exists()) { + QPixmap pix; + //Warning. Works only with modified Qt +#ifdef Q_WS_X11 + //pix.load(fileName, 0, Qt::AutoColor); + pix.load(fileName, 0); +#else + pix.load(fileName, 0, Qt::AutoColor, false); +#endif + thumbnails.append(pix); + } else { + moreToProcess = false; + } + } + return thumbnails; +} + +QPixmap UBThumbnailAdaptor::load(UBDocumentProxy* proxy, int index) +{ + qDebug() << "Loadinf thumbnails for " << proxy->name(); + + int existingPageCount = proxy->pageCount(); + + if (!proxy || proxy->persistencePath().size() == 0 || index < 0 || index > existingPageCount) + return QPixmap(); + //compatibility with older formats (<= 4.0.b.2.0) : generate missing thumbnails + generateMissingThumbnails(proxy); + + //end compatibility with older format + QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", index); + + QFile file(fileName); + if (file.exists()) + { + QPixmap pix; + //Warning. Works only with modified Qt +#ifdef Q_WS_X11 + pix.load(fileName, 0, Qt::AutoColor); +#else + pix.load(fileName, 0, Qt::AutoColor, false); +#endif + return pix; + } + return QPixmap(); +} +*/ + +void UBThumbnailAdaptor::persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, int pageIndex, bool overrideModified) +{ + + qDebug() << "Persiste scene on path " << proxy->persistencePath() << ", index " << pageIndex; + + QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); + + QFile thumbFile(fileName); + + if (pScene->isModified() || overrideModified || !thumbFile.exists()) + { + qreal nominalWidth = pScene->nominalSize().width(); + qreal nominalHeight = pScene->nominalSize().height(); + qreal ratio = nominalWidth / nominalHeight; + QRectF sceneRect = pScene->normalizedSceneRect(ratio); + + qreal width = UBSettings::maxThumbnailWidth; + qreal height = width / ratio; + + QImage thumb(width, height, QImage::Format_ARGB32); + + QRectF imageRect(0, 0, width, height); + + QPainter painter(&thumb); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHint(QPainter::SmoothPixmapTransform, true); + + if (pScene->isDarkBackground()) + { + painter.fillRect(imageRect, Qt::black); + } + else + { + painter.fillRect(imageRect, Qt::white); + } + + pScene->setRenderingContext(UBGraphicsScene::NonScreen); + pScene->setRenderingQuality(UBItem::RenderingQualityHigh); + + pScene->render(&painter, imageRect, sceneRect, Qt::KeepAspectRatio); + + pScene->setRenderingContext(UBGraphicsScene::Screen); + pScene->setRenderingQuality(UBItem::RenderingQualityNormal); + + thumb.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation).save(fileName, "JPG"); + } +} + + +QUrl UBThumbnailAdaptor::thumbnailUrl(UBDocumentProxy* proxy, int pageIndex) +{ + QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); + + return QUrl::fromLocalFile(fileName); +} diff --git a/src/adaptors/UBThumbnailAdaptor.h b/src/adaptors/UBThumbnailAdaptor.h index 58616ee7..c53f120b 100644 --- a/src/adaptors/UBThumbnailAdaptor.h +++ b/src/adaptors/UBThumbnailAdaptor.h @@ -1,39 +1,42 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef UBTHUMBNAILADAPTOR_H -#define UBTHUMBNAILADAPTOR_H - -#include - -class UBDocument; -class UBDocumentProxy; -class UBGraphicsScene; - -class UBThumbnailAdaptor //static class -{ - Q_DECLARE_TR_FUNCTIONS(UBThumbnailAdaptor) - -private: UBThumbnailAdaptor() {} -public: - static void persistScene(const QString& pDocPath, UBGraphicsScene* pScene, int pageIndex, bool overrideModified = false); - - static void generateMissingThumbnails(UBDocumentProxy* proxy); - static QList load(UBDocumentProxy* proxy); - static QPixmap load(UBDocumentProxy* proxy, int index); - - static QUrl thumbnailUrl(UBDocumentProxy* proxy, int pageIndex); -}; - -#endif // UBTHUMBNAILADAPTOR_H +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef UBTHUMBNAILADAPTOR_H +#define UBTHUMBNAILADAPTOR_H + +#include + +class UBDocument; +class UBDocumentProxy; +class UBGraphicsScene; + +class UBThumbnailAdaptor //static class +{ + Q_DECLARE_TR_FUNCTIONS(UBThumbnailAdaptor) + +public: + static QUrl thumbnailUrl(UBDocumentProxy* proxy, int pageIndex); + + static void persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, int pageIndex, bool overrideModified = false); + + static const QPixmap* get(UBDocumentProxy* proxy, int index); + static void load(UBDocumentProxy* proxy, QList& list); + +private: + static void generateMissingThumbnails(UBDocumentProxy* proxy); + + UBThumbnailAdaptor() {} +}; + +#endif // UBTHUMBNAILADAPTOR_H diff --git a/src/adaptors/publishing/UBDocumentPublisher.cpp b/src/adaptors/publishing/UBDocumentPublisher.cpp index d341388a..1c360a1f 100644 --- a/src/adaptors/publishing/UBDocumentPublisher.cpp +++ b/src/adaptors/publishing/UBDocumentPublisher.cpp @@ -1,825 +1,823 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include - -#include "UBDocumentPublisher.h" - -#include "frameworks/UBPlatformUtils.h" -#include "frameworks/UBFileSystemUtils.h" -#include "frameworks/UBStringUtils.h" - -#include "network/UBNetworkAccessManager.h" -#include "network/UBServerXMLHttpRequest.h" - -#include "core/UBDocumentManager.h" -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBApplicationController.h" - -#include "board/UBBoardController.h" - -#include "gui/UBMainWindow.h" - -#include "document/UBDocumentProxy.h" - -#include "domain/UBGraphicsWidgetItem.h" - -#include "globals/UBGlobals.h" - -THIRD_PARTY_WARNINGS_DISABLE -#include "quazip.h" -#include "quazipfile.h" -THIRD_PARTY_WARNINGS_ENABLE - -#include "adaptors/UBExportFullPDF.h" -#include "adaptors/UBExportDocument.h" -#include "adaptors/UBSvgSubsetAdaptor.h" - -#include "UBSvgSubsetRasterizer.h" - -#include "../../core/UBApplication.h" - -#include "core/memcheck.h" - - -UBDocumentPublisher::UBDocumentPublisher(UBDocumentProxy* pDocument, QObject *parent) - : QObject(parent) - , mSourceDocument(pDocument) - , mPublishingDocument(0) - , mUsername("") - , mPassword("") - , bLoginCookieSet(false) -{ - //NOOP - init(); -} - - -UBDocumentPublisher::~UBDocumentPublisher() -{ - if(mPublishingDocument){ - delete mPublishingDocument; - mPublishingDocument = NULL; - } -} - - -void UBDocumentPublisher::publish() -{ - //check that the username and password are stored on preferences - UBSettings* settings = UBSettings::settings(); - - if(settings->communityUsername().isEmpty() || settings->communityPassword().isEmpty()){ - UBApplication::showMessage(tr("Credentials has to not been filled out yet.")); - qDebug() << "trying to connect to community without the required credentials"; - return; - } - - mUsername = settings->communityUsername(); - mPassword = settings->communityPassword(); - - UBPublicationDlg dlg; - if(QDialog::Accepted == dlg.exec()) - { - mDocInfos.title = dlg.title(); - mDocInfos.description = dlg.description(); - - buildUbwFile(); - - UBApplication::showMessage(tr("Uploading Sankore File on Web.")); - - sendUbw(mUsername, mPassword); - } -} - -void UBDocumentPublisher::buildUbwFile() -{ - QDir d; - d.mkpath(UBFileSystemUtils::defaultTempDirPath()); - - QString tmpDir = UBFileSystemUtils::createTempDir(); - - if (UBFileSystemUtils::copyDir(mSourceDocument->persistencePath(), tmpDir)) - { - QUuid publishingUuid = QUuid::createUuid(); - - mPublishingDocument = new UBDocumentProxy(tmpDir); - mPublishingDocument->setPageCount(mSourceDocument->pageCount()); - - rasterizeScenes(); - - upgradeDocumentForPublishing(); - - UBExportFullPDF pdfExporter; - pdfExporter.setVerbode(false); - pdfExporter.persistsDocument(mSourceDocument, mPublishingDocument->persistencePath() + "/" + UBStringUtils::toCanonicalUuid(publishingUuid) + ".pdf"); - - UBExportDocument ubzExporter; - ubzExporter.setVerbode(false); - ubzExporter.persistsDocument(mSourceDocument, mPublishingDocument->persistencePath() + "/" + UBStringUtils::toCanonicalUuid(publishingUuid) + ".ubz"); - - // remove all useless files - - for (int pageIndex = 0; pageIndex < mPublishingDocument->pageCount(); pageIndex++) { - QString filename = mPublishingDocument->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg",pageIndex); - - QFile::remove(filename); - } - - UBFileSystemUtils::deleteDir(mPublishingDocument->persistencePath() + "/" + UBPersistenceManager::imageDirectory); - UBFileSystemUtils::deleteDir(mPublishingDocument->persistencePath() + "/" + UBPersistenceManager::objectDirectory); - UBFileSystemUtils::deleteDir(mPublishingDocument->persistencePath() + "/" + UBPersistenceManager::videoDirectory); - UBFileSystemUtils::deleteDir(mPublishingDocument->persistencePath() + "/" + UBPersistenceManager::audioDirectory); - - mTmpZipFile = UBFileSystemUtils::defaultTempDirPath() + "/" + UBStringUtils::toCanonicalUuid(QUuid::createUuid()) + ".ubw~"; - - QuaZip zip(mTmpZipFile); - zip.setFileNameCodec("UTF-8"); - if (!zip.open(QuaZip::mdCreate)) - { - qWarning() << "Export failed. Cause: zip.open(): " << zip.getZipError() << "," << mTmpZipFile; - QApplication::restoreOverrideCursor(); - return; - } - - QuaZipFile outFile(&zip); - - if (!UBFileSystemUtils::compressDirInZip(mPublishingDocument->persistencePath(), "", &outFile, true)) - { - qWarning("Export failed. compressDirInZip failed ..."); - zip.close(); - UBApplication::showMessage(tr("Export failed.")); - QApplication::restoreOverrideCursor(); - return; - } - - if (zip.getZipError() != 0) - { - qWarning("Export failed. Cause: zip.close(): %d", zip.getZipError()); - zip.close(); - UBApplication::showMessage(tr("Export failed.")); - QApplication::restoreOverrideCursor(); - return; - } - - zip.close(); - - } - else - { - UBApplication::showMessage(tr("Export canceled ...")); - QApplication::restoreOverrideCursor(); - } -} - -void UBDocumentPublisher::rasterizeScenes() -{ - - for (int pageIndex = 0; pageIndex < mPublishingDocument->pageCount(); pageIndex++) - { - UBApplication::showMessage(tr("Converting page %1/%2 ...").arg(UBApplication::boardController->pageFromSceneIndex(pageIndex)).arg(mPublishingDocument->pageCount()), true); - - UBSvgSubsetRasterizer rasterizer(mPublishingDocument, pageIndex); - - QString filename = mPublishingDocument->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.jpg",pageIndex); - - rasterizer.rasterizeToFile(filename); - - } -} - - -void UBDocumentPublisher::updateGoogleMapApiKey() -{ - QDir widgestDir(mPublishingDocument->persistencePath() + "/" + UBPersistenceManager::widgetDirectory); - - QString uniboardWebGoogleMapApiKey = UBSettings::settings()->uniboardWebGoogleMapApiKey->get().toString(); - - foreach(QFileInfo dirInfo, widgestDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) - { - QString config = UBFileSystemUtils::readTextFile(dirInfo.absoluteFilePath() + "/config.xml").toLower(); - - if (config.contains("google") && config.contains("map")) - { - QDir widgetDir(dirInfo.absoluteFilePath()); - - foreach(QFileInfo fileInfo, widgetDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot)) - { - QFile file(fileInfo.absoluteFilePath()); - - if (file.open(QIODevice::ReadWrite)) - { - QTextStream stream(&file); - QString content = stream.readAll(); - - if (content.contains("ABQIAAAA6vtVqAUu8kZ_eTz7c8kwSBT9UCAhw_xm0LNFHsWmQxTJAdp5lxSY_5r-lZriY_7sACaMnl80JcX6Og")) - { - content.replace("ABQIAAAA6vtVqAUu8kZ_eTz7c8kwSBT9UCAhw_xm0LNFHsWmQxTJAdp5lxSY_5r-lZriY_7sACaMnl80JcX6Og", - uniboardWebGoogleMapApiKey); - - file.resize(0); - file.write(content.toUtf8()); - } - file.close(); - } - } - } - } -} - - -void UBDocumentPublisher::upgradeDocumentForPublishing() -{ - for (int pageIndex = 0; pageIndex < mPublishingDocument->pageCount(); pageIndex++) - { - UBGraphicsScene *scene = UBSvgSubsetAdaptor::loadScene(mPublishingDocument, pageIndex); - - QList widgets; - - foreach(QGraphicsItem* item, scene->items()){ - UBGraphicsW3CWidgetItem *widgetItem = dynamic_cast(item); - - if(widgetItem){ - generateWidgetPropertyScript(widgetItem, UBApplication::boardController->pageFromSceneIndex(pageIndex)); - widgets << widgetItem; - } - } - - QString filename = mPublishingDocument->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.json",pageIndex); - - QFile jsonFile(filename); - if (jsonFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) - { - jsonFile.write("{\n"); - jsonFile.write(QString(" \"scene\": {\n").toUtf8()); - jsonFile.write(QString(" \"x\": %1,\n").arg(scene->normalizedSceneRect().x()).toUtf8()); - jsonFile.write(QString(" \"y\": %1,\n").arg(scene->normalizedSceneRect().y()).toUtf8()); - jsonFile.write(QString(" \"width\": %1,\n").arg(scene->normalizedSceneRect().width()).toUtf8()); - jsonFile.write(QString(" \"height\": %1\n").arg(scene->normalizedSceneRect().height()).toUtf8()); - jsonFile.write(QString(" },\n").toUtf8()); - - jsonFile.write(QString(" \"widgets\": [\n").toUtf8()); - - bool first = true; - - foreach(UBGraphicsW3CWidgetItem* widget, widgets) - { - if (!first) - jsonFile.write(QString(" ,\n").toUtf8()); - - jsonFile.write(QString(" {\n").toUtf8()); - jsonFile.write(QString(" \"uuid\": \"%1\",\n").arg(UBStringUtils::toCanonicalUuid(widget->uuid())).toUtf8()); - jsonFile.write(QString(" \"id\": \"%1\",\n").arg(widget->metadatas().id).toUtf8()); - - jsonFile.write(QString(" \"name\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().name).toUtf8()); - jsonFile.write(QString(" \"description\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().description).toUtf8()); - jsonFile.write(QString(" \"author\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().author).toUtf8()); - jsonFile.write(QString(" \"authorEmail\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().authorEmail).toUtf8()); - jsonFile.write(QString(" \"authorHref\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().authorHref).toUtf8()); - jsonFile.write(QString(" \"version\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().authorHref).toUtf8()); - - jsonFile.write(QString(" \"x\": %1,\n").arg(widget->sceneBoundingRect().x()).toUtf8()); - jsonFile.write(QString(" \"y\": %1,\n").arg(widget->sceneBoundingRect().y()).toUtf8()); - jsonFile.write(QString(" \"width\": %1,\n").arg(widget->sceneBoundingRect().width()).toUtf8()); - jsonFile.write(QString(" \"height\": %1,\n").arg(widget->sceneBoundingRect().height()).toUtf8()); - - jsonFile.write(QString(" \"nominalWidth\": %1,\n").arg(widget->boundingRect().width()).toUtf8()); - jsonFile.write(QString(" \"nominalHeight\": %1,\n").arg(widget->boundingRect().height()).toUtf8()); - - QString url = UBPersistenceManager::widgetDirectory + "/" + widget->uuid().toString() + ".wgt"; - jsonFile.write(QString(" \"src\": \"%1\",\n").arg(url).toUtf8()); - QString startFile = widget->w3cWidget()->mainHtmlFileName(); - jsonFile.write(QString(" \"startFile\": \"%1\",\n").arg(startFile).toUtf8()); - - QMap preferences = widget->preferences(); - - jsonFile.write(QString(" \"preferences\": {\n").toUtf8()); - - foreach(QString key, preferences.keys()) - { - QString sep = ","; - if (key == preferences.keys().last()) - sep = ""; - - jsonFile.write(QString(" \"%1\": \"%2\"%3\n") - .arg(key) - .arg(preferences.value(key)) - .arg(sep) - .toUtf8()); - } - jsonFile.write(QString(" },\n").toUtf8()); - - jsonFile.write(QString(" \"datastore\": {\n").toUtf8()); - - QMap datastoreEntries = widget->datastoreEntries(); - - foreach(QString entry, datastoreEntries.keys()) - { - QString sep = ","; - if (entry == datastoreEntries.keys().last()) - sep = ""; - - jsonFile.write(QString(" \"%1\": \"%2\"%3\n") - .arg(entry) - .arg(datastoreEntries.value(entry)) - .arg(sep) - .toUtf8()); - } - jsonFile.write(QString(" }\n").toUtf8()); - - jsonFile.write(QString(" }\n").toUtf8()); - - first = false; - } - - jsonFile.write(" ]\n"); - jsonFile.write("}\n"); - } - else - { - qWarning() << "Cannot open file" << filename << "for saving page state"; - } - - delete scene; - } - - updateGoogleMapApiKey(); -} - - -void UBDocumentPublisher::generateWidgetPropertyScript(UBGraphicsW3CWidgetItem *widgetItem, int pageNumber) -{ - - QMap preferences = widgetItem->preferences(); - QMap datastoreEntries = widgetItem->datastoreEntries(); - - QString startFileName = widgetItem->w3cWidget()->mainHtmlFileName(); - - if (!startFileName.startsWith("http://")) - { - QString startFilePath = mPublishingDocument->persistencePath() + "/" + UBPersistenceManager::widgetDirectory + "/" + widgetItem->uuid().toString() + ".wgt/" + startFileName; - - QFile startFile(startFilePath); - - if (startFile.exists()) - { - if (startFile.open(QIODevice::ReadWrite)) - { - QTextStream stream(&startFile); - QStringList lines; - - bool addedJs = false; - - QString line; - do - { - line = stream.readLine(); - if (!line.isNull()) - { - lines << line; - - if (!addedJs && line.contains("") ) // TODO UB 4.6, this is naive ... the HEAD tag may be on several lines - { - lines << ""; - lines << " "; - lines << ""; - - addedJs = true; - } - } - } - while (!line.isNull()); - - startFile.resize(0); - startFile.write(lines.join("\n").toUtf8()); // TODO UB 4.x detect real html encoding - - startFile.close(); - } - } - } - else{ - qWarning() << "Remote Widget start file, cannot inject widget preferences and datastore entries"; - } -} - -void UBDocumentPublisher::init() -{ - mCrlf=0x0d; - mCrlf+=0x0a; - mDocInfos.title = ""; - mDocInfos.description = ""; - - mpCookieJar = new QNetworkCookieJar(); - mpNetworkMgr = new QNetworkAccessManager(this); - - connect(mpNetworkMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*))); -} - -void UBDocumentPublisher::onFinished(QNetworkReply *reply) -{ - QVariant cookieHeader = reply->rawHeader("Set-Cookie"); - // First we concatenate all the Set-Cookie values (the packet can contains many of them) - QStringList qslCookie = cookieHeader.toString().split("\n"); - QString qsCookieValue = qslCookie.at(0); - for (int i = 1; i < qslCookie.size(); i++) { - qsCookieValue += "; " +qslCookie.at(i); - } - - // Now we isolate every cookie value - QStringList qslCookieVals = qsCookieValue.split("; "); - - bool bTransferOk = false; - - for(int j = 0; j < qslCookieVals.size(); j++) - { - qDebug() << j; - if(qslCookieVals.at(j).startsWith("assetStatus")) - { - QStringList qslAsset = qslCookieVals.at(j).split("="); - if(qslAsset.at(1) == "UPLOADED") - { - bTransferOk = true; - break; - } - } - } - - if(bTransferOk) - { - UBApplication::showMessage(tr("Document uploaded correctly on the web.")); - } - else - { - UBApplication::showMessage(tr("Failed to upload document on the web.")); - } - - reply->deleteLater(); -} - -void UBDocumentPublisher::sendUbw(QString username, QString password) -{ - if (QFile::exists(mTmpZipFile)) - { - QFile f(mTmpZipFile); - if (f.open(QIODevice::ReadOnly)) - { - QFileInfo fi(f); - QByteArray ba = f.readAll(); - QString boundary,data, multipartHeader; - QByteArray datatoSend; - - boundary = "---WebKitFormBoundaryDKBTgA53MiyWrzLY"; - multipartHeader = "multipart/form-data; boundary="+boundary; - - data="--"+boundary+mCrlf; - data+="Content-Disposition: form-data; name=\"title\"" + mCrlf + mCrlf + mDocInfos.title + mCrlf; - data+="--"+boundary+mCrlf; - data+="Content-Disposition: form-data; name=\"description\"" + mCrlf + mCrlf + mDocInfos.description.remove("\n") + mCrlf; - data+="--"+boundary+mCrlf; - data+="Content-Disposition: form-data; name=\"file\"; filename=\""+ fi.fileName() +"\""+mCrlf; - data+="Content-Type: application/octet-stream"+mCrlf+mCrlf; - datatoSend=data.toAscii(); // convert data string to byte array for request - datatoSend += ba; - datatoSend += mCrlf; - datatoSend += QString("--%0--%1").arg(boundary).arg(mCrlf); - - QNetworkRequest request(QUrl(QString(DOCPUBLICATION_URL).toAscii().constData())); - - request.setHeader(QNetworkRequest::ContentTypeHeader, multipartHeader); - request.setHeader(QNetworkRequest::ContentLengthHeader,datatoSend.size()); - QString b64Auth = getBase64Of(QString("%0:%1").arg(username).arg(password)); - request.setRawHeader("Authorization", QString("Basic %0").arg(b64Auth).toAscii().constData()); - request.setRawHeader("Host", "planete.sankore.org"); - request.setRawHeader("Accept", "*/*"); - request.setRawHeader("Accept-Language", "en-US,*"); - - mpCookieJar->setCookiesFromUrl(mCookies, QUrl(DOCPUBLICATION_URL)); - mpNetworkMgr->setCookieJar(mpCookieJar); - - // Send the file - mpNetworkMgr->post(request,datatoSend); - } - } -} - -QString UBDocumentPublisher::getBase64Of(QString stringToEncode) -{ - return stringToEncode.toAscii().toBase64(); -} - -// --------------------------------------------------------- -UBProxyLoginDlg::UBProxyLoginDlg(QWidget *parent, const char *name):QDialog(parent) - , mpLayout(NULL) - , mpUserLayout(NULL) - , mpPasswordLayout(NULL) - , mpButtons(NULL) - , mpUserLabel(NULL) - , mpPasswordLabel(NULL) - , mpUsername(NULL) - , mpPassword(NULL) -{ - setObjectName(name); - setFixedSize(400, 150); - setWindowTitle(tr("Proxy Login")); - - mpLayout = new QVBoxLayout(); - setLayout(mpLayout); - mpUserLayout = new QHBoxLayout(); - mpLayout->addLayout(mpUserLayout); - mpPasswordLayout = new QHBoxLayout(); - mpLayout->addLayout(mpPasswordLayout); - - mpUserLabel = new QLabel(tr("Username:"), this); - mpUsername = new QLineEdit(this); - mpUserLayout->addWidget(mpUserLabel, 0); - mpUserLayout->addWidget(mpUsername, 1); - - mpPasswordLabel = new QLabel(tr("Password:"), this); - mpPassword = new QLineEdit(this); - mpPasswordLayout->addWidget(mpPasswordLabel, 0); - mpPasswordLayout->addWidget(mpPassword, 1); - - mpButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); - mpLayout->addWidget(mpButtons); - - connect(mpButtons, SIGNAL(accepted()), this, SLOT(accept())); - connect(mpButtons, SIGNAL(rejected()), this, SLOT(reject())); - -} - -UBProxyLoginDlg::~UBProxyLoginDlg() -{ - if(NULL != mpLayout) - { - delete mpLayout; - mpLayout = NULL; - } - if(NULL != mpButtons) - { - delete mpButtons; - mpButtons = NULL; - } - if(NULL != mpUserLabel) - { - delete mpUserLabel; - mpUserLabel = NULL; - } - if(NULL != mpPasswordLabel) - { - delete mpPasswordLabel; - mpPasswordLabel = NULL; - } - if(NULL != mpUsername) - { - delete mpUsername; - mpUsername = NULL; - } - if(NULL != mpPassword) - { - delete mpPassword; - mpPassword = NULL; - } -} - -// --------------------------------------------------------- -UBPublicationDlg::UBPublicationDlg(QWidget *parent, const char *name):QDialog(parent) - , mpLayout(NULL) - , mpTitleLayout(NULL) - , mpTitleLabel(NULL) - , mpTitle(NULL) - , mpDescLabel(NULL) - , mpDescription(NULL) - , mpButtons(NULL) -{ - setObjectName(name); - setWindowTitle(tr("Publish document on the web")); - - resize(500, 300); - - mpLayout = new QVBoxLayout(); - setLayout(mpLayout); - - mpTitleLabel = new QLabel(tr("Title:"), this); - mpTitle = new QLineEdit(this); - mpTitleLayout = new QHBoxLayout(); - mpTitleLayout->addWidget(mpTitleLabel, 0); - mpTitleLayout->addWidget(mpTitle, 1); - mpLayout->addLayout(mpTitleLayout, 0); - - mpDescLabel = new QLabel(tr("Description:"), this); - mpLayout->addWidget(mpDescLabel, 0); - - mpDescription = new QTextEdit(this); - mpLayout->addWidget(mpDescription, 1); - - mpButtons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); - mpButtons->button(QDialogButtonBox::Ok)->setText(tr("Publish")); - mpLayout->addWidget(mpButtons); - - mpButtons->button(QDialogButtonBox::Ok)->setEnabled(false); - - connect(mpButtons, SIGNAL(accepted()), this, SLOT(accept())); - connect(mpButtons, SIGNAL(rejected()), this, SLOT(reject())); - connect(mpTitle, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged())); - connect(mpDescription, SIGNAL(textChanged()), this, SLOT(onTextChanged())); -} - -UBPublicationDlg::~UBPublicationDlg() -{ - if(NULL != mpTitleLabel) - { - delete mpTitleLabel; - mpTitleLabel = NULL; - } - if(NULL != mpTitle) - { - delete mpTitle; - mpTitle = NULL; - } - if(NULL != mpDescLabel) - { - delete mpDescLabel; - mpDescLabel = NULL; - } - if(NULL != mpDescription) - { - delete mpDescription; - mpDescription = NULL; - } - if(NULL != mpButtons) - { - delete mpButtons; - mpButtons = NULL; - } - if(NULL != mpTitleLayout) - { - delete mpTitleLayout; - mpTitleLayout = NULL; - } - if(NULL != mpLayout) - { - delete mpLayout; - mpLayout = NULL; - } -} - -void UBPublicationDlg::onTextChanged() -{ - bool bPublishButtonState = false; - if(mpTitle->text() != "" && mpDescription->document()->toPlainText() != "") - { - bPublishButtonState = true; - } - else - { - bPublishButtonState = false; - } - - mpButtons->button(QDialogButtonBox::Ok)->setEnabled(bPublishButtonState); -} +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +#include "UBDocumentPublisher.h" + +#include "frameworks/UBPlatformUtils.h" +#include "frameworks/UBFileSystemUtils.h" +#include "frameworks/UBStringUtils.h" + +#include "network/UBNetworkAccessManager.h" +#include "network/UBServerXMLHttpRequest.h" + +#include "core/UBDocumentManager.h" +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBApplicationController.h" + +#include "board/UBBoardController.h" + +#include "gui/UBMainWindow.h" + +#include "document/UBDocumentProxy.h" +#include "document/UBDocumentContainer.h" + +#include "domain/UBGraphicsWidgetItem.h" + +#include "globals/UBGlobals.h" + +THIRD_PARTY_WARNINGS_DISABLE +#include "quazip.h" +#include "quazipfile.h" +THIRD_PARTY_WARNINGS_ENABLE + +#include "adaptors/UBExportFullPDF.h" +#include "adaptors/UBExportDocument.h" +#include "adaptors/UBSvgSubsetAdaptor.h" + +#include "UBSvgSubsetRasterizer.h" + +#include "../../core/UBApplication.h" + +#include "core/memcheck.h" + + +UBDocumentPublisher::UBDocumentPublisher(UBDocumentProxy* pDocument, QObject *parent) + : QObject(parent) + , mSourceDocument(pDocument) + , mUsername("") + , mPassword("") + , bLoginCookieSet(false) +{ + //NOOP + init(); +} + + +UBDocumentPublisher::~UBDocumentPublisher() +{ +} + + +void UBDocumentPublisher::publish() +{ + //check that the username and password are stored on preferences + UBSettings* settings = UBSettings::settings(); + + if(settings->communityUsername().isEmpty() || settings->communityPassword().isEmpty()){ + UBApplication::showMessage(tr("Credentials has to not been filled out yet.")); + qDebug() << "trying to connect to community without the required credentials"; + return; + } + + mUsername = settings->communityUsername(); + mPassword = settings->communityPassword(); + + UBPublicationDlg dlg; + if(QDialog::Accepted == dlg.exec()) + { + mDocInfos.title = dlg.title(); + mDocInfos.description = dlg.description(); + + buildUbwFile(); + + UBApplication::showMessage(tr("Uploading Sankore File on Web.")); + + sendUbw(mUsername, mPassword); + } +} + +void UBDocumentPublisher::buildUbwFile() +{ + QDir d; + d.mkpath(UBFileSystemUtils::defaultTempDirPath()); + + QString tmpDir = UBFileSystemUtils::createTempDir(); + + if (UBFileSystemUtils::copyDir(mSourceDocument->persistencePath(), tmpDir)) + { + QUuid publishingUuid = QUuid::createUuid(); + + mPublishingPath = tmpDir; + mPublishingSize = mSourceDocument->pageCount(); + + rasterizeScenes(); + + upgradeDocumentForPublishing(); + + UBExportFullPDF pdfExporter; + pdfExporter.setVerbode(false); + pdfExporter.persistsDocument(mSourceDocument, mPublishingPath + "/" + UBStringUtils::toCanonicalUuid(publishingUuid) + ".pdf"); + + UBExportDocument ubzExporter; + ubzExporter.setVerbode(false); + ubzExporter.persistsDocument(mSourceDocument, mPublishingPath + "/" + UBStringUtils::toCanonicalUuid(publishingUuid) + ".ubz"); + + // remove all useless files + + for (int pageIndex = 0; pageIndex < mPublishingSize; pageIndex++) { + QString filename = mPublishingPath + UBFileSystemUtils::digitFileFormat("/page%1.svg",pageIndex); + + QFile::remove(filename); + } + + UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::imageDirectory); + UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::objectDirectory); + UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::videoDirectory); + UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::audioDirectory); + + mTmpZipFile = UBFileSystemUtils::defaultTempDirPath() + "/" + UBStringUtils::toCanonicalUuid(QUuid::createUuid()) + ".ubw~"; + + QuaZip zip(mTmpZipFile); + zip.setFileNameCodec("UTF-8"); + if (!zip.open(QuaZip::mdCreate)) + { + qWarning() << "Export failed. Cause: zip.open(): " << zip.getZipError() << "," << mTmpZipFile; + QApplication::restoreOverrideCursor(); + return; + } + + QuaZipFile outFile(&zip); + + if (!UBFileSystemUtils::compressDirInZip(mPublishingPath, "", &outFile, true)) + { + qWarning("Export failed. compressDirInZip failed ..."); + zip.close(); + UBApplication::showMessage(tr("Export failed.")); + QApplication::restoreOverrideCursor(); + return; + } + + if (zip.getZipError() != 0) + { + qWarning("Export failed. Cause: zip.close(): %d", zip.getZipError()); + zip.close(); + UBApplication::showMessage(tr("Export failed.")); + QApplication::restoreOverrideCursor(); + return; + } + + zip.close(); + + } + else + { + UBApplication::showMessage(tr("Export canceled ...")); + QApplication::restoreOverrideCursor(); + } +} + +void UBDocumentPublisher::rasterizeScenes() +{ + + for (int pageIndex = 0; pageIndex < mPublishingSize; pageIndex++) + { + UBApplication::showMessage(tr("Converting page %1/%2 ...").arg(UBDocumentContainer::pageFromSceneIndex(pageIndex)).arg(mPublishingSize), true); + + UBDocumentProxy publishingDocument(mPublishingPath); + UBSvgSubsetRasterizer rasterizer(&publishingDocument, pageIndex); + + QString filename = mPublishingPath + UBFileSystemUtils::digitFileFormat("/page%1.jpg",pageIndex); + + rasterizer.rasterizeToFile(filename); + + } +} + + +void UBDocumentPublisher::updateGoogleMapApiKey() +{ + QDir widgestDir(mPublishingPath + "/" + UBPersistenceManager::widgetDirectory); + + QString uniboardWebGoogleMapApiKey = UBSettings::settings()->uniboardWebGoogleMapApiKey->get().toString(); + + foreach(QFileInfo dirInfo, widgestDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) + { + QString config = UBFileSystemUtils::readTextFile(dirInfo.absoluteFilePath() + "/config.xml").toLower(); + + if (config.contains("google") && config.contains("map")) + { + QDir widgetDir(dirInfo.absoluteFilePath()); + + foreach(QFileInfo fileInfo, widgetDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot)) + { + QFile file(fileInfo.absoluteFilePath()); + + if (file.open(QIODevice::ReadWrite)) + { + QTextStream stream(&file); + QString content = stream.readAll(); + + if (content.contains("ABQIAAAA6vtVqAUu8kZ_eTz7c8kwSBT9UCAhw_xm0LNFHsWmQxTJAdp5lxSY_5r-lZriY_7sACaMnl80JcX6Og")) + { + content.replace("ABQIAAAA6vtVqAUu8kZ_eTz7c8kwSBT9UCAhw_xm0LNFHsWmQxTJAdp5lxSY_5r-lZriY_7sACaMnl80JcX6Og", + uniboardWebGoogleMapApiKey); + + file.resize(0); + file.write(content.toUtf8()); + } + file.close(); + } + } + } + } +} + + +void UBDocumentPublisher::upgradeDocumentForPublishing() +{ + for (int pageIndex = 0; pageIndex < mPublishingSize; pageIndex++) + { + UBDocumentProxy publishingDocument(mPublishingPath); + UBGraphicsScene *scene = UBSvgSubsetAdaptor::loadScene(&publishingDocument, pageIndex); + + QList widgets; + + foreach(QGraphicsItem* item, scene->items()){ + UBGraphicsW3CWidgetItem *widgetItem = dynamic_cast(item); + + if(widgetItem){ + generateWidgetPropertyScript(widgetItem, UBDocumentContainer::pageFromSceneIndex(pageIndex)); + widgets << widgetItem; + } + } + + QString filename = mPublishingPath + UBFileSystemUtils::digitFileFormat("/page%1.json",pageIndex); + + QFile jsonFile(filename); + if (jsonFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + jsonFile.write("{\n"); + jsonFile.write(QString(" \"scene\": {\n").toUtf8()); + jsonFile.write(QString(" \"x\": %1,\n").arg(scene->normalizedSceneRect().x()).toUtf8()); + jsonFile.write(QString(" \"y\": %1,\n").arg(scene->normalizedSceneRect().y()).toUtf8()); + jsonFile.write(QString(" \"width\": %1,\n").arg(scene->normalizedSceneRect().width()).toUtf8()); + jsonFile.write(QString(" \"height\": %1\n").arg(scene->normalizedSceneRect().height()).toUtf8()); + jsonFile.write(QString(" },\n").toUtf8()); + + jsonFile.write(QString(" \"widgets\": [\n").toUtf8()); + + bool first = true; + + foreach(UBGraphicsW3CWidgetItem* widget, widgets) + { + if (!first) + jsonFile.write(QString(" ,\n").toUtf8()); + + jsonFile.write(QString(" {\n").toUtf8()); + jsonFile.write(QString(" \"uuid\": \"%1\",\n").arg(UBStringUtils::toCanonicalUuid(widget->uuid())).toUtf8()); + jsonFile.write(QString(" \"id\": \"%1\",\n").arg(widget->metadatas().id).toUtf8()); + + jsonFile.write(QString(" \"name\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().name).toUtf8()); + jsonFile.write(QString(" \"description\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().description).toUtf8()); + jsonFile.write(QString(" \"author\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().author).toUtf8()); + jsonFile.write(QString(" \"authorEmail\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().authorEmail).toUtf8()); + jsonFile.write(QString(" \"authorHref\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().authorHref).toUtf8()); + jsonFile.write(QString(" \"version\": \"%1\",\n").arg(widget->w3cWidget()->metadatas().authorHref).toUtf8()); + + jsonFile.write(QString(" \"x\": %1,\n").arg(widget->sceneBoundingRect().x()).toUtf8()); + jsonFile.write(QString(" \"y\": %1,\n").arg(widget->sceneBoundingRect().y()).toUtf8()); + jsonFile.write(QString(" \"width\": %1,\n").arg(widget->sceneBoundingRect().width()).toUtf8()); + jsonFile.write(QString(" \"height\": %1,\n").arg(widget->sceneBoundingRect().height()).toUtf8()); + + jsonFile.write(QString(" \"nominalWidth\": %1,\n").arg(widget->boundingRect().width()).toUtf8()); + jsonFile.write(QString(" \"nominalHeight\": %1,\n").arg(widget->boundingRect().height()).toUtf8()); + + QString url = UBPersistenceManager::widgetDirectory + "/" + widget->uuid().toString() + ".wgt"; + jsonFile.write(QString(" \"src\": \"%1\",\n").arg(url).toUtf8()); + QString startFile = widget->w3cWidget()->mainHtmlFileName(); + jsonFile.write(QString(" \"startFile\": \"%1\",\n").arg(startFile).toUtf8()); + + QMap preferences = widget->preferences(); + + jsonFile.write(QString(" \"preferences\": {\n").toUtf8()); + + foreach(QString key, preferences.keys()) + { + QString sep = ","; + if (key == preferences.keys().last()) + sep = ""; + + jsonFile.write(QString(" \"%1\": \"%2\"%3\n") + .arg(key) + .arg(preferences.value(key)) + .arg(sep) + .toUtf8()); + } + jsonFile.write(QString(" },\n").toUtf8()); + + jsonFile.write(QString(" \"datastore\": {\n").toUtf8()); + + QMap datastoreEntries = widget->datastoreEntries(); + + foreach(QString entry, datastoreEntries.keys()) + { + QString sep = ","; + if (entry == datastoreEntries.keys().last()) + sep = ""; + + jsonFile.write(QString(" \"%1\": \"%2\"%3\n") + .arg(entry) + .arg(datastoreEntries.value(entry)) + .arg(sep) + .toUtf8()); + } + jsonFile.write(QString(" }\n").toUtf8()); + + jsonFile.write(QString(" }\n").toUtf8()); + + first = false; + } + + jsonFile.write(" ]\n"); + jsonFile.write("}\n"); + } + else + { + qWarning() << "Cannot open file" << filename << "for saving page state"; + } + + delete scene; + } + + updateGoogleMapApiKey(); +} + + +void UBDocumentPublisher::generateWidgetPropertyScript(UBGraphicsW3CWidgetItem *widgetItem, int pageNumber) +{ + + QMap preferences = widgetItem->preferences(); + QMap datastoreEntries = widgetItem->datastoreEntries(); + + QString startFileName = widgetItem->w3cWidget()->mainHtmlFileName(); + + if (!startFileName.startsWith("http://")) + { + QString startFilePath = mPublishingPath + "/" + UBPersistenceManager::widgetDirectory + "/" + widgetItem->uuid().toString() + ".wgt/" + startFileName; + + QFile startFile(startFilePath); + + if (startFile.exists()) + { + if (startFile.open(QIODevice::ReadWrite)) + { + QTextStream stream(&startFile); + QStringList lines; + + bool addedJs = false; + + QString line; + do + { + line = stream.readLine(); + if (!line.isNull()) + { + lines << line; + + if (!addedJs && line.contains("") ) // TODO UB 4.6, this is naive ... the HEAD tag may be on several lines + { + lines << ""; + lines << " "; + lines << ""; + + addedJs = true; + } + } + } + while (!line.isNull()); + + startFile.resize(0); + startFile.write(lines.join("\n").toUtf8()); // TODO UB 4.x detect real html encoding + + startFile.close(); + } + } + } + else{ + qWarning() << "Remote Widget start file, cannot inject widget preferences and datastore entries"; + } +} + +void UBDocumentPublisher::init() +{ + mCrlf=0x0d; + mCrlf+=0x0a; + mDocInfos.title = ""; + mDocInfos.description = ""; + + mpCookieJar = new QNetworkCookieJar(); + mpNetworkMgr = new QNetworkAccessManager(this); + + connect(mpNetworkMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*))); +} + +void UBDocumentPublisher::onFinished(QNetworkReply *reply) +{ + QVariant cookieHeader = reply->rawHeader("Set-Cookie"); + // First we concatenate all the Set-Cookie values (the packet can contains many of them) + QStringList qslCookie = cookieHeader.toString().split("\n"); + QString qsCookieValue = qslCookie.at(0); + for (int i = 1; i < qslCookie.size(); i++) { + qsCookieValue += "; " +qslCookie.at(i); + } + + // Now we isolate every cookie value + QStringList qslCookieVals = qsCookieValue.split("; "); + + bool bTransferOk = false; + + for(int j = 0; j < qslCookieVals.size(); j++) + { + qDebug() << j; + if(qslCookieVals.at(j).startsWith("assetStatus")) + { + QStringList qslAsset = qslCookieVals.at(j).split("="); + if(qslAsset.at(1) == "UPLOADED") + { + bTransferOk = true; + break; + } + } + } + + if(bTransferOk) + { + UBApplication::showMessage(tr("Document uploaded correctly on the web.")); + } + else + { + UBApplication::showMessage(tr("Failed to upload document on the web.")); + } + + reply->deleteLater(); +} + +void UBDocumentPublisher::sendUbw(QString username, QString password) +{ + if (QFile::exists(mTmpZipFile)) + { + QFile f(mTmpZipFile); + if (f.open(QIODevice::ReadOnly)) + { + QFileInfo fi(f); + QByteArray ba = f.readAll(); + QString boundary,data, multipartHeader; + QByteArray datatoSend; + + boundary = "---WebKitFormBoundaryDKBTgA53MiyWrzLY"; + multipartHeader = "multipart/form-data; boundary="+boundary; + + data="--"+boundary+mCrlf; + data+="Content-Disposition: form-data; name=\"title\"" + mCrlf + mCrlf + mDocInfos.title + mCrlf; + data+="--"+boundary+mCrlf; + data+="Content-Disposition: form-data; name=\"description\"" + mCrlf + mCrlf + mDocInfos.description.remove("\n") + mCrlf; + data+="--"+boundary+mCrlf; + data+="Content-Disposition: form-data; name=\"file\"; filename=\""+ fi.fileName() +"\""+mCrlf; + data+="Content-Type: application/octet-stream"+mCrlf+mCrlf; + datatoSend=data.toAscii(); // convert data string to byte array for request + datatoSend += ba; + datatoSend += mCrlf; + datatoSend += QString("--%0--%1").arg(boundary).arg(mCrlf); + + QNetworkRequest request(QUrl(QString(DOCPUBLICATION_URL).toAscii().constData())); + + request.setHeader(QNetworkRequest::ContentTypeHeader, multipartHeader); + request.setHeader(QNetworkRequest::ContentLengthHeader,datatoSend.size()); + QString b64Auth = getBase64Of(QString("%0:%1").arg(username).arg(password)); + request.setRawHeader("Authorization", QString("Basic %0").arg(b64Auth).toAscii().constData()); + request.setRawHeader("Host", "planete.sankore.org"); + request.setRawHeader("Accept", "*/*"); + request.setRawHeader("Accept-Language", "en-US,*"); + + mpCookieJar->setCookiesFromUrl(mCookies, QUrl(DOCPUBLICATION_URL)); + mpNetworkMgr->setCookieJar(mpCookieJar); + + // Send the file + mpNetworkMgr->post(request,datatoSend); + } + } +} + +QString UBDocumentPublisher::getBase64Of(QString stringToEncode) +{ + return stringToEncode.toAscii().toBase64(); +} + +// --------------------------------------------------------- +UBProxyLoginDlg::UBProxyLoginDlg(QWidget *parent, const char *name):QDialog(parent) + , mpLayout(NULL) + , mpUserLayout(NULL) + , mpPasswordLayout(NULL) + , mpButtons(NULL) + , mpUserLabel(NULL) + , mpPasswordLabel(NULL) + , mpUsername(NULL) + , mpPassword(NULL) +{ + setObjectName(name); + setFixedSize(400, 150); + setWindowTitle(tr("Proxy Login")); + + mpLayout = new QVBoxLayout(); + setLayout(mpLayout); + mpUserLayout = new QHBoxLayout(); + mpLayout->addLayout(mpUserLayout); + mpPasswordLayout = new QHBoxLayout(); + mpLayout->addLayout(mpPasswordLayout); + + mpUserLabel = new QLabel(tr("Username:"), this); + mpUsername = new QLineEdit(this); + mpUserLayout->addWidget(mpUserLabel, 0); + mpUserLayout->addWidget(mpUsername, 1); + + mpPasswordLabel = new QLabel(tr("Password:"), this); + mpPassword = new QLineEdit(this); + mpPasswordLayout->addWidget(mpPasswordLabel, 0); + mpPasswordLayout->addWidget(mpPassword, 1); + + mpButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); + mpLayout->addWidget(mpButtons); + + connect(mpButtons, SIGNAL(accepted()), this, SLOT(accept())); + connect(mpButtons, SIGNAL(rejected()), this, SLOT(reject())); + +} + +UBProxyLoginDlg::~UBProxyLoginDlg() +{ + if(NULL != mpLayout) + { + delete mpLayout; + mpLayout = NULL; + } + if(NULL != mpButtons) + { + delete mpButtons; + mpButtons = NULL; + } + if(NULL != mpUserLabel) + { + delete mpUserLabel; + mpUserLabel = NULL; + } + if(NULL != mpPasswordLabel) + { + delete mpPasswordLabel; + mpPasswordLabel = NULL; + } + if(NULL != mpUsername) + { + delete mpUsername; + mpUsername = NULL; + } + if(NULL != mpPassword) + { + delete mpPassword; + mpPassword = NULL; + } +} + +// --------------------------------------------------------- +UBPublicationDlg::UBPublicationDlg(QWidget *parent, const char *name):QDialog(parent) + , mpLayout(NULL) + , mpTitleLayout(NULL) + , mpTitleLabel(NULL) + , mpTitle(NULL) + , mpDescLabel(NULL) + , mpDescription(NULL) + , mpButtons(NULL) +{ + setObjectName(name); + setWindowTitle(tr("Publish document on the web")); + + resize(500, 300); + + mpLayout = new QVBoxLayout(); + setLayout(mpLayout); + + mpTitleLabel = new QLabel(tr("Title:"), this); + mpTitle = new QLineEdit(this); + mpTitleLayout = new QHBoxLayout(); + mpTitleLayout->addWidget(mpTitleLabel, 0); + mpTitleLayout->addWidget(mpTitle, 1); + mpLayout->addLayout(mpTitleLayout, 0); + + mpDescLabel = new QLabel(tr("Description:"), this); + mpLayout->addWidget(mpDescLabel, 0); + + mpDescription = new QTextEdit(this); + mpLayout->addWidget(mpDescription, 1); + + mpButtons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); + mpButtons->button(QDialogButtonBox::Ok)->setText(tr("Publish")); + mpLayout->addWidget(mpButtons); + + mpButtons->button(QDialogButtonBox::Ok)->setEnabled(false); + + connect(mpButtons, SIGNAL(accepted()), this, SLOT(accept())); + connect(mpButtons, SIGNAL(rejected()), this, SLOT(reject())); + connect(mpTitle, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged())); + connect(mpDescription, SIGNAL(textChanged()), this, SLOT(onTextChanged())); +} + +UBPublicationDlg::~UBPublicationDlg() +{ + if(NULL != mpTitleLabel) + { + delete mpTitleLabel; + mpTitleLabel = NULL; + } + if(NULL != mpTitle) + { + delete mpTitle; + mpTitle = NULL; + } + if(NULL != mpDescLabel) + { + delete mpDescLabel; + mpDescLabel = NULL; + } + if(NULL != mpDescription) + { + delete mpDescription; + mpDescription = NULL; + } + if(NULL != mpButtons) + { + delete mpButtons; + mpButtons = NULL; + } + if(NULL != mpTitleLayout) + { + delete mpTitleLayout; + mpTitleLayout = NULL; + } + if(NULL != mpLayout) + { + delete mpLayout; + mpLayout = NULL; + } +} + +void UBPublicationDlg::onTextChanged() +{ + bool bPublishButtonState = false; + if(mpTitle->text() != "" && mpDescription->document()->toPlainText() != "") + { + bPublishButtonState = true; + } + else + { + bPublishButtonState = false; + } + + mpButtons->button(QDialogButtonBox::Ok)->setEnabled(bPublishButtonState); +} diff --git a/src/adaptors/publishing/UBDocumentPublisher.h b/src/adaptors/publishing/UBDocumentPublisher.h index e9f2e88c..4babbec8 100644 --- a/src/adaptors/publishing/UBDocumentPublisher.h +++ b/src/adaptors/publishing/UBDocumentPublisher.h @@ -1,128 +1,133 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef UBDOCUMENTPUBLISHER_H -#define UBDOCUMENTPUBLISHER_H - -#include -#include - -#include "ui_webPublishing.h" - -#define DOCPUBLICATION_URL "http://planete.sankore.org/xwiki/bin/view/CreateResources/UniboardUpload?xpage=plain&outputSyntax=plain" - -typedef struct -{ - QString title; - QString description; -} sDocumentInfos; - -class UBDocumentProxy; -class UBServerXMLHttpRequest; -class UBGraphicsW3CWidgetItem; -class QWebView; - -class UBProxyLoginDlg : public QDialog -{ - Q_OBJECT -public: - UBProxyLoginDlg(QWidget* parent=0, const char* name="ProxyLoginDlg"); - ~UBProxyLoginDlg(); - - QString username(){return mpUsername->text();} - QString password(){return mpPassword->text();} - -private: - QVBoxLayout* mpLayout; - QHBoxLayout* mpUserLayout; - QHBoxLayout* mpPasswordLayout; - QDialogButtonBox* mpButtons; - QLabel* mpUserLabel; - QLabel* mpPasswordLabel; - QLineEdit* mpUsername; - QLineEdit* mpPassword; -}; - -class UBPublicationDlg : public QDialog -{ - Q_OBJECT -public: - UBPublicationDlg(QWidget* parent=0, const char* name="UBPublicationDlg"); - ~UBPublicationDlg(); - - QString title(){return mpTitle->text();} - QString description(){return mpDescription->document()->toPlainText();} - -private slots: - void onTextChanged(); - -private: - QVBoxLayout* mpLayout; - QHBoxLayout* mpTitleLayout; - QLabel* mpTitleLabel; - QLineEdit* mpTitle; - QLabel* mpDescLabel; - QTextEdit* mpDescription; - QDialogButtonBox* mpButtons; -}; - - -class UBDocumentPublisher : public QObject -{ - Q_OBJECT; - -public: - explicit UBDocumentPublisher(UBDocumentProxy* sourceDocument, QObject *parent = 0); - virtual ~UBDocumentPublisher(); - - void publish(); - -signals: - - void loginDone(); - -protected: - - virtual void updateGoogleMapApiKey(); - virtual void rasterizeScenes(); - virtual void upgradeDocumentForPublishing(); - virtual void generateWidgetPropertyScript(UBGraphicsW3CWidgetItem *widgetItem, int pageNumber); - -private slots: - - void onFinished(QNetworkReply* reply); - -private: - - UBDocumentProxy *mSourceDocument; - UBDocumentProxy *mPublishingDocument; - void init(); - void sendUbw(QString username, QString password); - QString getBase64Of(QString stringToEncode); - - QHBoxLayout* mpLayout; - QNetworkAccessManager* mpNetworkMgr; - QNetworkCookieJar* mpCookieJar; - QString mUsername; - QString mPassword; - QString mCrlf; - bool bLoginCookieSet; - - void buildUbwFile(); - QString mTmpZipFile; - QList mCookies; - sDocumentInfos mDocInfos; - -}; -#endif // UBDOCUMENTPUBLISHER_H +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef UBDOCUMENTPUBLISHER_H +#define UBDOCUMENTPUBLISHER_H + +#include +#include + +#include "ui_webPublishing.h" + +#define DOCPUBLICATION_URL "http://planete.sankore.org/xwiki/bin/view/CreateResources/UniboardUpload?xpage=plain&outputSyntax=plain" + +typedef struct +{ + QString title; + QString description; +} sDocumentInfos; + +class UBDocumentProxy; +class UBServerXMLHttpRequest; +class UBGraphicsW3CWidgetItem; +class QWebView; + +class UBProxyLoginDlg : public QDialog +{ + Q_OBJECT +public: + UBProxyLoginDlg(QWidget* parent=0, const char* name="ProxyLoginDlg"); + ~UBProxyLoginDlg(); + + QString username(){return mpUsername->text();} + QString password(){return mpPassword->text();} + +private: + QVBoxLayout* mpLayout; + QHBoxLayout* mpUserLayout; + QHBoxLayout* mpPasswordLayout; + QDialogButtonBox* mpButtons; + QLabel* mpUserLabel; + QLabel* mpPasswordLabel; + QLineEdit* mpUsername; + QLineEdit* mpPassword; +}; + +class UBPublicationDlg : public QDialog +{ + Q_OBJECT +public: + UBPublicationDlg(QWidget* parent=0, const char* name="UBPublicationDlg"); + ~UBPublicationDlg(); + + QString title(){return mpTitle->text();} + QString description(){return mpDescription->document()->toPlainText();} + +private slots: + void onTextChanged(); + +private: + QVBoxLayout* mpLayout; + QHBoxLayout* mpTitleLayout; + QLabel* mpTitleLabel; + QLineEdit* mpTitle; + QLabel* mpDescLabel; + QTextEdit* mpDescription; + QDialogButtonBox* mpButtons; +}; + + +class UBDocumentPublisher : public QObject +{ + Q_OBJECT; + +public: + explicit UBDocumentPublisher(UBDocumentProxy* sourceDocument, QObject *parent = 0); + virtual ~UBDocumentPublisher(); + + void publish(); + +signals: + + void loginDone(); + +protected: + + virtual void updateGoogleMapApiKey(); + virtual void rasterizeScenes(); + virtual void upgradeDocumentForPublishing(); + virtual void generateWidgetPropertyScript(UBGraphicsW3CWidgetItem *widgetItem, int pageNumber); + +private slots: + + void onFinished(QNetworkReply* reply); + +private: + + UBDocumentProxy *mSourceDocument; + + //UBDocumentProxy *mPublishingDocument; + QString mPublishingPath; + int mPublishingSize; + + + void init(); + void sendUbw(QString username, QString password); + QString getBase64Of(QString stringToEncode); + + QHBoxLayout* mpLayout; + QNetworkAccessManager* mpNetworkMgr; + QNetworkCookieJar* mpCookieJar; + QString mUsername; + QString mPassword; + QString mCrlf; + bool bLoginCookieSet; + + void buildUbwFile(); + QString mTmpZipFile; + QList mCookies; + sDocumentInfos mDocInfos; + +}; +#endif // UBDOCUMENTPUBLISHER_H diff --git a/src/api/UBWidgetUniboardAPI.cpp b/src/api/UBWidgetUniboardAPI.cpp index 49dba492..87d8b97d 100644 --- a/src/api/UBWidgetUniboardAPI.cpp +++ b/src/api/UBWidgetUniboardAPI.cpp @@ -346,7 +346,7 @@ QString UBWidgetUniboardAPI::pageThumbnail(const int pageNumber) if (UBApplication::boardController->activeScene() != mScene) return ""; - UBDocumentProxy *doc = UBApplication::boardController->activeDocument(); + UBDocumentProxy *doc = UBApplication::boardController->selectedDocument(); if (!doc) return ""; diff --git a/src/board/UBBoardController.cpp b/src/board/UBBoardController.cpp index 7739ae1c..7092cf10 100644 --- a/src/board/UBBoardController.cpp +++ b/src/board/UBBoardController.cpp @@ -1,2247 +1,2260 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "UBBoardController.h" - -#include -#include - -#include "frameworks/UBFileSystemUtils.h" -#include "frameworks/UBPlatformUtils.h" - -#include "core/UBApplication.h" -#include "core/UBSettings.h" -#include "core/UBSetting.h" -#include "core/UBPersistenceManager.h" -#include "core/UBApplicationController.h" -#include "core/UBDocumentManager.h" -#include "core/UBMimeData.h" -#include "core/UBDownloadManager.h" - -#include "network/UBHttpGet.h" - -#include "gui/UBMessageWindow.h" -#include "gui/UBResources.h" -#include "gui/UBToolbarButtonGroup.h" -#include "gui/UBMainWindow.h" -#include "gui/UBToolWidget.h" -#include "gui/UBKeyboardPalette.h" -#include "gui/UBMagnifer.h" - -#include "domain/UBGraphicsPixmapItem.h" -#include "domain/UBGraphicsItemUndoCommand.h" -#include "domain/UBGraphicsProxyWidget.h" -#include "domain/UBGraphicsSvgItem.h" -#include "domain/UBGraphicsWidgetItem.h" -#include "domain/UBGraphicsMediaItem.h" -#include "domain/UBGraphicsPDFItem.h" -#include "domain/UBW3CWidget.h" -#include "domain/UBGraphicsTextItem.h" -#include "domain/UBPageSizeUndoCommand.h" -#include "domain/UBGraphicsGroupContainerItem.h" - -#include "tools/UBToolsManager.h" - -#include "document/UBDocumentProxy.h" -#include "document/UBDocumentController.h" - -#include "board/UBDrawingController.h" -#include "board/UBBoardView.h" - -#include "podcast/UBPodcastController.h" - -#include "adaptors/UBMetadataDcSubsetAdaptor.h" -#include "adaptors/UBSvgSubsetAdaptor.h" - -#include "UBBoardPaletteManager.h" - -#include "core/UBSettings.h" - -#include "core/memcheck.h" -//#include - -UBBoardController::UBBoardController(UBMainWindow* mainWindow) - : QObject(mainWindow->centralWidget()) - , mMainWindow(mainWindow) - , mActiveDocument(0) - , mActiveScene(0) - , mActiveSceneIndex(-1) - , mPaletteManager(0) - , mSoftwareUpdateDialog(0) - , mMessageWindow(0) - , mControlView(0) - , mDisplayView(0) - , mControlContainer(0) - , mControlLayout(0) - , mZoomFactor(1.0) - , mIsClosing(false) - , mSystemScaleFactor(1.0) - , mCleanupDone(false) - , mCacheWidgetIsEnabled(false) -{ - mZoomFactor = UBSettings::settings()->boardZoomFactor->get().toDouble(); - - int penColorIndex = UBSettings::settings()->penColorIndex(); - int markerColorIndex = UBSettings::settings()->markerColorIndex(); - - mPenColorOnDarkBackground = UBSettings::settings()->penColors(true).at(penColorIndex); - mPenColorOnLightBackground = UBSettings::settings()->penColors(false).at(penColorIndex); - mMarkerColorOnDarkBackground = UBSettings::settings()->markerColors(true).at(markerColorIndex); - mMarkerColorOnLightBackground = UBSettings::settings()->markerColors(false).at(markerColorIndex); -} - - -void UBBoardController::init() -{ - setupViews(); - setupToolbar(); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentWillBeDeleted(UBDocumentProxy*)) - , this, SLOT(documentWillBeDeleted(UBDocumentProxy*))); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneCreated(UBDocumentProxy*, int)) - , this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneDeleted(UBDocumentProxy*, int)) - , this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneMoved(UBDocumentProxy*, int)) - , this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); - - connect(UBApplication::undoStack, SIGNAL(canUndoChanged(bool)) - , this, SLOT(undoRedoStateChange(bool))); - - connect(UBApplication::undoStack, SIGNAL(canRedoChanged (bool)) - , this, SLOT(undoRedoStateChange(bool))); - - connect(UBDrawingController::drawingController(), SIGNAL(stylusToolChanged(int)) - , this, SLOT(setToolCursor(int))); - - connect(UBDrawingController::drawingController(), SIGNAL(stylusToolChanged(int)) - , this, SLOT(stylusToolChanged(int))); - - connect(UBApplication::app(), SIGNAL(lastWindowClosed()) - , this, SLOT(lastWindowClosed())); - - connect(UBDownloadManager::downloadManager(), SIGNAL(downloadModalFinished()), this, SLOT(onDownloadModalFinished())); - connect(UBDownloadManager::downloadManager(), SIGNAL(addDownloadedFileToBoard(bool,QUrl,QString,QByteArray,QPointF,QSize,bool)), this, SLOT(downloadFinished(bool,QUrl,QString,QByteArray,QPointF,QSize,bool))); - - UBDocumentProxy* doc = UBPersistenceManager::persistenceManager()->createDocument(); - - setActiveDocumentScene(doc); - - connect(UBApplication::mainWindow->actionGroupItems, SIGNAL(triggered()), this, SLOT(groupButtonClicked())); - - undoRedoStateChange(true); -} - - -UBBoardController::~UBBoardController() -{ - delete mDisplayView; -} - - -int UBBoardController::currentPage() -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return mActiveSceneIndex; - return mActiveSceneIndex + 1; -} - -int UBBoardController::pageFromSceneIndex(int sceneIndex) -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return sceneIndex; - return sceneIndex+1; -} - -int UBBoardController::sceneIndexFromPage(int page) -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return page-1; - return page; -} - -void UBBoardController::setupViews() -{ - mControlContainer = new QWidget(mMainWindow->centralWidget()); - - mControlLayout = new QHBoxLayout(mControlContainer); - mControlLayout->setContentsMargins(0, 0, 0, 0); - - mControlView = new UBBoardView(this, mControlContainer); - mControlView->setInteractive(true); - mControlView->setMouseTracking(true); - - mControlView->grabGesture(Qt::SwipeGesture); - - mControlView->setTransformationAnchor(QGraphicsView::NoAnchor); - - mControlLayout->addWidget(mControlView); - mControlContainer->setObjectName("ubBoardControlContainer"); - mMainWindow->addBoardWidget(mControlContainer); - - connect(mControlView, SIGNAL(resized(QResizeEvent*)), this, SLOT(boardViewResized(QResizeEvent*))); - - // TODO UB 4.x Optimization do we have to create the display view even if their is - // only 1 screen - // - mDisplayView = new UBBoardView(this, UBItemLayerType::FixedBackground, UBItemLayerType::Tool, 0); - mDisplayView->setInteractive(false); - mDisplayView->setTransformationAnchor(QGraphicsView::NoAnchor); - - mMessageWindow = new UBMessageWindow(mControlView); - mMessageWindow->hide(); - - mPaletteManager = new UBBoardPaletteManager(mControlContainer, this); - connect(this, SIGNAL(activeSceneChanged()), mPaletteManager, SLOT(activeSceneChanged())); - -} - - -void UBBoardController::setupLayout() -{ - if(mPaletteManager) - mPaletteManager->setupLayout(); -} - - -void UBBoardController::setBoxing(QRect displayRect) -{ - if (displayRect.isNull()) - { - mControlLayout->setContentsMargins(0, 0, 0, 0); - return; - } - - qreal controlWidth = (qreal)mMainWindow->centralWidget()->width(); - qreal controlHeight = (qreal)mMainWindow->centralWidget()->height(); - qreal displayWidth = (qreal)displayRect.width(); - qreal displayHeight = (qreal)displayRect.height(); - - qreal displayRatio = displayWidth / displayHeight; - qreal controlRatio = controlWidth / controlHeight; - - if (displayRatio < controlRatio) - { - // Pillarboxing - int boxWidth = (controlWidth - (displayWidth * (controlHeight / displayHeight))) / 2; - mControlLayout->setContentsMargins(boxWidth, 0, boxWidth, 0); - } - else if (displayRatio > controlRatio) - { - // Letterboxing - int boxHeight = (controlHeight - (displayHeight * (controlWidth / displayWidth))) / 2; - mControlLayout->setContentsMargins(0, boxHeight, 0, boxHeight); - } - else - { - // No boxing - mControlLayout->setContentsMargins(0, 0, 0, 0); - } -} - - -QSize UBBoardController::displayViewport() -{ - return mDisplayView->geometry().size(); -} - - -QSize UBBoardController::controlViewport() -{ - return mControlView->geometry().size(); -} - - -QRectF UBBoardController::controlGeometry() -{ - return mControlView->geometry(); -} - - -void UBBoardController::setupToolbar() -{ - UBSettings *settings = UBSettings::settings(); - - // Setup color choice widget - QList colorActions; - colorActions.append(mMainWindow->actionColor0); - colorActions.append(mMainWindow->actionColor1); - colorActions.append(mMainWindow->actionColor2); - colorActions.append(mMainWindow->actionColor3); - - UBToolbarButtonGroup *colorChoice = - new UBToolbarButtonGroup(mMainWindow->boardToolBar, colorActions); - - mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, colorChoice); - - connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), colorChoice, SLOT(displayText(QVariant))); - connect(colorChoice, SIGNAL(activated(int)), this, SLOT(setColorIndex(int))); - connect(UBDrawingController::drawingController(), SIGNAL(colorIndexChanged(int)), colorChoice, SLOT(setCurrentIndex(int))); - connect(UBDrawingController::drawingController(), SIGNAL(colorPaletteChanged()), colorChoice, SLOT(colorPaletteChanged())); - connect(UBDrawingController::drawingController(), SIGNAL(colorPaletteChanged()), this, SLOT(colorPaletteChanged())); - - colorChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); - colorChoice->colorPaletteChanged(); - - // Setup line width choice widget - QList lineWidthActions; - lineWidthActions.append(mMainWindow->actionLineSmall); - lineWidthActions.append(mMainWindow->actionLineMedium); - lineWidthActions.append(mMainWindow->actionLineLarge); - - UBToolbarButtonGroup *lineWidthChoice = - new UBToolbarButtonGroup(mMainWindow->boardToolBar, lineWidthActions); - - connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), lineWidthChoice, SLOT(displayText(QVariant))); - - connect(lineWidthChoice, SIGNAL(activated(int)) - , UBDrawingController::drawingController(), SLOT(setLineWidthIndex(int))); - - connect(UBDrawingController::drawingController(), SIGNAL(lineWidthIndexChanged(int)) - , lineWidthChoice, SLOT(setCurrentIndex(int))); - - lineWidthChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); - - mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineWidthChoice); - - //-----------------------------------------------------------// - // Setup eraser width choice widget - - QList eraserWidthActions; - eraserWidthActions.append(mMainWindow->actionEraserSmall); - eraserWidthActions.append(mMainWindow->actionEraserMedium); - eraserWidthActions.append(mMainWindow->actionEraserLarge); - - UBToolbarButtonGroup *eraserWidthChoice = - new UBToolbarButtonGroup(mMainWindow->boardToolBar, eraserWidthActions); - - mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, eraserWidthChoice); - - connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), eraserWidthChoice, SLOT(displayText(QVariant))); - connect(eraserWidthChoice, SIGNAL(activated(int)), UBDrawingController::drawingController(), SLOT(setEraserWidthIndex(int))); - - eraserWidthChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); - eraserWidthChoice->setCurrentIndex(settings->eraserWidthIndex()); - - mMainWindow->boardToolBar->insertSeparator(mMainWindow->actionBackgrounds); - - //-----------------------------------------------------------// - - UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBoard); - UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->tutorialToolBar, mMainWindow->actionBoard); - - UBApplication::app()->decorateActionMenu(mMainWindow->actionMenu); - - mMainWindow->actionBoard->setVisible(false); - - mMainWindow->webToolBar->hide(); - mMainWindow->documentToolBar->hide(); - mMainWindow->tutorialToolBar->hide(); - - connectToolbar(); - initToolbarTexts(); -} - - -void UBBoardController::setToolCursor(int tool) -{ - if (mActiveScene) - { - mActiveScene->setToolCursor(tool); - } - - mControlView->setToolCursor(tool); -} - - -void UBBoardController::connectToolbar() -{ - connect(mMainWindow->actionAdd, SIGNAL(triggered()), this, SLOT(addItem())); - connect(mMainWindow->actionNewPage, SIGNAL(triggered()), this, SLOT(addScene())); - connect(mMainWindow->actionDuplicatePage, SIGNAL(triggered()), this, SLOT(duplicateScene())); - - connect(mMainWindow->actionClearPage, SIGNAL(triggered()), this, SLOT(clearScene())); - connect(mMainWindow->actionEraseItems, SIGNAL(triggered()), this, SLOT(clearSceneItems())); - connect(mMainWindow->actionEraseAnnotations, SIGNAL(triggered()), this, SLOT(clearSceneAnnotation())); - connect(mMainWindow->actionEraseBackground,SIGNAL(triggered()),this,SLOT(clearSceneBackground())); - - connect(mMainWindow->actionUndo, SIGNAL(triggered()), UBApplication::undoStack, SLOT(undo())); - connect(mMainWindow->actionRedo, SIGNAL(triggered()), UBApplication::undoStack, SLOT(redo())); - connect(mMainWindow->actionRedo, SIGNAL(triggered()), this, SLOT(startScript())); - connect(mMainWindow->actionBack, SIGNAL( triggered()), this, SLOT(previousScene())); - connect(mMainWindow->actionForward, SIGNAL(triggered()), this, SLOT(nextScene())); - connect(mMainWindow->actionSleep, SIGNAL(triggered()), this, SLOT(stopScript())); - connect(mMainWindow->actionSleep, SIGNAL(triggered()), this, SLOT(blackout())); - connect(mMainWindow->actionVirtualKeyboard, SIGNAL(triggered(bool)), this, SLOT(showKeyboard(bool))); - connect(mMainWindow->actionImportPage, SIGNAL(triggered()), this, SLOT(importPage())); -} - -void UBBoardController::startScript() -{ - freezeW3CWidgets(false); -} - -void UBBoardController::stopScript() -{ - freezeW3CWidgets(true); -} - -bool UBBoardController::cacheIsVisible() -{ - return mCacheWidgetIsEnabled; -} - -void UBBoardController::initToolbarTexts() -{ - QList allToolbarActions; - - allToolbarActions << mMainWindow->boardToolBar->actions(); - allToolbarActions << mMainWindow->webToolBar->actions(); - allToolbarActions << mMainWindow->documentToolBar->actions(); - - foreach(QAction* action, allToolbarActions) - { - QString nominalText = action->text(); - QString shortText = truncate(nominalText, 48); - QPair texts(nominalText, shortText); - - mActionTexts.insert(action, texts); - } -} - - -void UBBoardController::setToolbarTexts() -{ - bool highResolution = mMainWindow->width() > 1024; - QSize iconSize; - - if (highResolution) - iconSize = QSize(48, 32); - else - iconSize = QSize(32, 32); - - mMainWindow->boardToolBar->setIconSize(iconSize); - mMainWindow->webToolBar->setIconSize(iconSize); - mMainWindow->documentToolBar->setIconSize(iconSize); - - foreach(QAction* action, mActionTexts.keys()) - { - QPair texts = mActionTexts.value(action); - - if (highResolution) - action->setText(texts.first); - else - { - action->setText(texts.second); - } - - action->setToolTip(texts.first); - } -} - - -QString UBBoardController::truncate(QString text, int maxWidth) -{ - QFontMetricsF fontMetrics(mMainWindow->font()); - return fontMetrics.elidedText(text, Qt::ElideRight, maxWidth); -} - - -void UBBoardController::stylusToolDoubleClicked(int tool) -{ - if (tool == UBStylusTool::ZoomIn || tool == UBStylusTool::ZoomOut) - { - zoomRestore(); - } - else if (tool == UBStylusTool::Hand) - { - centerRestore(); - } -} - - - -void UBBoardController::addScene() -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - - UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mActiveDocument, mActiveSceneIndex + 1); - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - setActiveDocumentScene(mActiveDocument, mActiveSceneIndex + 1); - QApplication::restoreOverrideCursor(); - emit newPageAdded(); -} - - -void UBBoardController::addScene(UBGraphicsScene* scene, bool replaceActiveIfEmpty) -{ - if (scene) - { - UBGraphicsScene* clone = scene->sceneDeepCopy(); - - if (scene->document() && (scene->document() != mActiveDocument)) - { - foreach(QUrl relativeFile, scene->relativeDependencies()) - { - QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); - QString target = mActiveDocument->persistencePath() + "/" + relativeFile.toString(); - - QFileInfo fi(target); - QDir d = fi.dir(); - - d.mkpath(d.absolutePath()); - QFile::copy(source, target); - } - } - - if (replaceActiveIfEmpty && mActiveScene->isEmpty()) - { - UBPersistenceManager::persistenceManager()->persistDocumentScene(mActiveDocument, clone, mActiveSceneIndex); - setActiveDocumentScene(mActiveDocument, mActiveSceneIndex); - } - else - { - persistCurrentScene(); - UBPersistenceManager::persistenceManager()->insertDocumentSceneAt(mActiveDocument, clone, mActiveSceneIndex + 1); - setActiveDocumentScene(mActiveDocument, mActiveSceneIndex + 1); - } - - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - } -} - - -void UBBoardController::addScene(UBDocumentProxy* proxy, int sceneIndex, bool replaceActiveIfEmpty) -{ - UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(proxy, sceneIndex); - - if (scene) - { - addScene(scene, replaceActiveIfEmpty); - } -} - - -void UBBoardController::duplicateScene() -{ - if (UBApplication::applicationController->displayMode() != UBApplicationController::Board) - return; - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - - UBPersistenceManager::persistenceManager()->duplicateDocumentScene(mActiveDocument, mActiveSceneIndex); - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - setActiveDocumentScene(mActiveDocument, mActiveSceneIndex + 1); - QApplication::restoreOverrideCursor(); - - emit pageChanged(); -} - - -void UBBoardController::clearScene() -{ - if (mActiveScene) - { - freezeW3CWidgets(true); - mActiveScene->clearItemsAndAnnotations(); - updateActionStates(); - } -} - - -void UBBoardController::clearSceneItems() -{ - if (mActiveScene) - { - freezeW3CWidgets(true); - mActiveScene->clearItems(); - updateActionStates(); - } -} - - -void UBBoardController::clearSceneAnnotation() -{ - if (mActiveScene) - { - mActiveScene->clearAnnotations(); - updateActionStates(); - } -} - -void UBBoardController::clearSceneBackground() -{ - if (mActiveScene) - { - mActiveScene->clearBackground(); - updateActionStates(); - } -} - -void UBBoardController::showDocumentsDialog() -{ - if (mActiveDocument) - persistCurrentScene(); - - UBApplication::mainWindow->actionLibrary->setChecked(false); - -} - -void UBBoardController::libraryDialogClosed(int ret) -{ - Q_UNUSED(ret); - - mMainWindow->actionLibrary->setChecked(false); -} - - -void UBBoardController::blackout() -{ - UBApplication::applicationController->blackout(); -} - - -void UBBoardController::showKeyboard(bool show) -{ - if(show) - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - mPaletteManager->showVirtualKeyboard(show); -} - - -void UBBoardController::zoomIn(QPointF scenePoint) -{ - if (mControlView->transform().m11() > UB_MAX_ZOOM) - { - qApp->beep(); - return; - } - zoom(mZoomFactor, scenePoint); -} - - -void UBBoardController::zoomOut(QPointF scenePoint) -{ - if ((mControlView->horizontalScrollBar()->maximum() == 0) && (mControlView->verticalScrollBar()->maximum() == 0)) - { - // Do not zoom out if we reached the maximum - qApp->beep(); - return; - } - - qreal newZoomFactor = 1 / mZoomFactor; - - zoom(newZoomFactor, scenePoint); -} - - -void UBBoardController::zoomRestore() -{ - QTransform tr; - - tr.scale(mSystemScaleFactor, mSystemScaleFactor); - mControlView->setTransform(tr); - - centerRestore(); - - foreach(QGraphicsItem *gi, mActiveScene->selectedItems ()) - { - //force item to redraw the frame (for the anti scale calculation) - gi->setSelected(false); - gi->setSelected(true); - } - - emit zoomChanged(1.0); -} - - -void UBBoardController::centerRestore() -{ - centerOn(QPointF(0,0)); -} - - -void UBBoardController::centerOn(QPointF scenePoint) -{ - mControlView->centerOn(scenePoint); - UBApplication::applicationController->adjustDisplayView(); -} - - -void UBBoardController::zoom(const qreal ratio, QPointF scenePoint) -{ - - QPointF viewCenter = mControlView->mapToScene(QRect(0, 0, mControlView->width(), mControlView->height()).center()); - QPointF offset = scenePoint - viewCenter; - QPointF scalledOffset = offset / ratio; - - mControlView->scale(ratio, ratio); - - qreal currentZoom = mControlView->viewportTransform().m11() / mSystemScaleFactor; - - QPointF newCenter = scenePoint - scalledOffset; - - mControlView->centerOn(newCenter); - - emit zoomChanged(currentZoom); - UBApplication::applicationController->adjustDisplayView(); - - emit controlViewportChanged(); - mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11()); -} - - -void UBBoardController::handScroll(qreal dx, qreal dy) -{ - mControlView->translate(dx, dy); - - UBApplication::applicationController->adjustDisplayView(); - - emit controlViewportChanged(); -} - - -void UBBoardController::previousScene() -{ - if (mActiveSceneIndex > 0) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - setActiveDocumentScene(mActiveDocument, mActiveSceneIndex - 1); - QApplication::restoreOverrideCursor(); - } - - updateActionStates(); - emit pageChanged(); -} - - -void UBBoardController::nextScene() -{ - if (mActiveSceneIndex < mActiveDocument->pageCount() - 1) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - setActiveDocumentScene(mActiveDocument, mActiveSceneIndex + 1); - QApplication::restoreOverrideCursor(); - } - - updateActionStates(); - emit pageChanged(); -} - - -void UBBoardController::firstScene() -{ - if (mActiveSceneIndex > 0) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - setActiveDocumentScene(mActiveDocument, 0); - QApplication::restoreOverrideCursor(); - } - - updateActionStates(); - emit pageChanged(); -} - - -void UBBoardController::lastScene() -{ - if (mActiveSceneIndex < mActiveDocument->pageCount() - 1) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - setActiveDocumentScene(mActiveDocument, mActiveDocument->pageCount() - 1); - QApplication::restoreOverrideCursor(); - } - - updateActionStates(); - emit pageChanged(); -} - -void UBBoardController::groupButtonClicked() -{ - QAction *groupAction = UBApplication::mainWindow->actionGroupItems; - QList selItems = activeScene()->selectedItems(); - if (!selItems.count()) { - qDebug() << "Got grouping request when there is no any selected item on the scene"; - return; - } - - if (groupAction->text() == UBSettings::settings()->actionGroupText) { //The only way to get information from item, considering using smth else - UBGraphicsGroupContainerItem *groupItem = activeScene()->createGroup(selItems); - groupItem->setSelected(true); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - - } else if (groupAction->text() == UBSettings::settings()->actionUngroupText) { - //Considering one selected item and it's a group - if (selItems.count() > 1) { - qDebug() << "can't make sense of ungrouping more then one item. Grouping action should be performed for that purpose"; - return; - } - UBGraphicsGroupContainerItem *currentGroup = dynamic_cast(selItems.first()); - if (currentGroup) { - currentGroup->destroy(); - } - } -} - -void UBBoardController::downloadURL(const QUrl& url, const QPointF& pPos, const QSize& pSize, bool isBackground) -{ - qDebug() << "something has been dropped on the board! Url is: " << url.toString(); - QString sUrl = url.toString(); - - if(sUrl.startsWith("uniboardTool://")) - { - downloadFinished(true, url, "application/vnd.mnemis-uniboard-tool", QByteArray(), pPos, pSize, isBackground); - } - else if (sUrl.startsWith("file://") || sUrl.startsWith("/")) - { - QString fileName = url.toLocalFile(); - - QString contentType = UBFileSystemUtils::mimeTypeFromFileName(fileName); - - bool shouldLoadFileData = - contentType.startsWith("image") - || contentType.startsWith("application/widget") - || contentType.startsWith("application/vnd.apple-widget"); - - QFile file(fileName); - - if (shouldLoadFileData) - file.open(QIODevice::ReadOnly); - - downloadFinished(true, url, contentType, file.readAll(), pPos, pSize, isBackground); - - if (shouldLoadFileData) - file.close(); - } - else - { - // When we fall there, it means that we are dropping something from the web to the board - sDownloadFileDesc desc; - desc.modal = true; - desc.url = url.toString(); - desc.currentSize = 0; - desc.name = QFileInfo(url.toString()).fileName(); - desc.totalSize = 0; // The total size will be retrieved during the download - desc.pos = pPos; - desc.size = pSize; - desc.isBackground = isBackground; - - UBDownloadManager::downloadManager()->addFileToDownload(desc); - } -} - - -void UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QString pContentTypeHeader, QByteArray pData, QPointF pPos, QSize pSize, bool isBackground) -{ - QGraphicsItem *oldBackgroundObject = NULL; - if (isBackground) - oldBackgroundObject = mActiveScene->backgroundObject(); - - QString mimeType = pContentTypeHeader; - - // In some cases "image/jpeg;charset=" is returned by the drag-n-drop. That is - // why we will check if an ; exists and take the first part (the standard allows this kind of mimetype) - int position=mimeType.indexOf(";"); - if(position != -1) - mimeType=mimeType.left(position); - - if (!pSuccess) - { - UBApplication::showMessage(tr("Downloading content %1 failed").arg(sourceUrl.toString())); - return; - } - - if (!sourceUrl.toString().startsWith("file://") && !sourceUrl.toString().startsWith("uniboardTool://")) - UBApplication::showMessage(tr("Download finished")); - - if (mimeType == "image/jpeg" - || mimeType == "image/png" - || mimeType == "image/gif" - || mimeType == "image/tiff" - || mimeType == "image/bmp") - { - - qDebug() << "accepting mime type" << mimeType << "as raster image"; - - QImage img; - img.loadFromData(pData); - QPixmap pix = QPixmap::fromImage(img); - - UBGraphicsPixmapItem* pixItem = mActiveScene->addPixmap(pix, NULL, pPos, 1.); - pixItem->setSourceUrl(sourceUrl); - - if (isBackground) - { - mActiveScene->setAsBackgroundObject(pixItem, true); - } - else - { - mActiveScene->scaleToFitDocumentSize(pixItem, true, UBSettings::objectInControlViewMargin); - pixItem->setSelected(true); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - } - else if (mimeType == "image/svg+xml") - { - qDebug() << "accepting mime type" << mimeType << "as vecto image"; - - UBGraphicsSvgItem* svgItem = mActiveScene->addSvg(sourceUrl, pPos); - svgItem->setSourceUrl(sourceUrl); - - if (isBackground) - { - mActiveScene->setAsBackgroundObject(svgItem); - } - else - { - mActiveScene->scaleToFitDocumentSize(svgItem, true, UBSettings::objectInControlViewMargin); - svgItem->setSelected(true); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - } - else if (mimeType == "application/vnd.apple-widget") //mime type invented by us :-( - { - qDebug() << "accepting mime type" << mimeType << "as Apple widget"; - - QUrl widgetUrl = sourceUrl; - - if (pData.length() > 0) - { - widgetUrl = expandWidgetToTempDir(pData, "wdgt"); - } - - UBGraphicsWidgetItem* appleWidgetItem = mActiveScene->addAppleWidget(widgetUrl, pPos); - - appleWidgetItem->setSourceUrl(sourceUrl); - - if (isBackground) - { - mActiveScene->setAsBackgroundObject(appleWidgetItem); - } - else - { - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - } - else if (mimeType == "application/widget") - { - qDebug() << "accepting mime type" << mimeType << "as W3C widget"; - QUrl widgetUrl = sourceUrl; - - if (pData.length() > 0) - { - widgetUrl = expandWidgetToTempDir(pData); - } - - UBGraphicsWidgetItem *w3cWidgetItem = addW3cWidget(widgetUrl, pPos); - - if (isBackground) - { - mActiveScene->setAsBackgroundObject(w3cWidgetItem); - } - else - { - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - } - else if (mimeType.startsWith("video/")) - { - qDebug() << "accepting mime type" << mimeType << "as video"; - - UBGraphicsMediaItem *mediaVideoItem = 0; - - if (pData.length() > 0) - { - QUuid uuid = QUuid::createUuid(); - - QUrl url = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager() - ->addVideoFileToDocument(mActiveDocument, sourceUrl, pData, uuid)); - - mediaVideoItem = mActiveScene->addMedia(url, false, pPos); - - mediaVideoItem->setSourceUrl(sourceUrl); - mediaVideoItem->setUuid(uuid); - } - else - { - mediaVideoItem = addVideo(sourceUrl, false, pPos); - } - - if(mediaVideoItem){ - connect(this, SIGNAL(activeSceneChanged()), mediaVideoItem, SLOT(activeSceneChanged())); - } - - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (mimeType.startsWith("audio/")) - { - qDebug() << "accepting mime type" << mimeType << "as audio"; - - UBGraphicsMediaItem *audioMediaItem = 0; - - if (pData.length() > 0) - { - QUuid uuid = QUuid::createUuid(); - - QUrl url = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager() - ->addVideoFileToDocument(mActiveDocument, sourceUrl, pData, uuid)); - - audioMediaItem = mActiveScene->addMedia(url, false, pPos); - audioMediaItem->setSourceUrl(sourceUrl); - audioMediaItem->setUuid(uuid); - } - else - { - audioMediaItem = addAudio(sourceUrl, false, pPos); - } - - if(audioMediaItem){ - connect(this, SIGNAL(activeSceneChanged()), audioMediaItem, SLOT(activeSceneChanged())); - } - - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - - else if (mimeType.startsWith("application/x-shockwave-flash")) - { - - qDebug() << "accepting mime type" << mimeType << "as flash"; - - QString sUrl = sourceUrl.toString(); - - if (sUrl.startsWith("file://") || sUrl.startsWith("/")) - { - sUrl = sourceUrl.toLocalFile(); - } - - QTemporaryFile* eduMediaFile = 0; - - if (sUrl.toLower().contains("edumedia-sciences.com")) - { - eduMediaFile = new QTemporaryFile("XXXXXX.swf"); - if (eduMediaFile->open()) - { - eduMediaFile->write(pData); - QFileInfo fi(*eduMediaFile); - sUrl = fi.absoluteFilePath(); - } - } - - QSize size; - - if (pSize.height() > 0 && pSize.width() > 0) - size = pSize; - else - size = mActiveScene->nominalSize() * .8; - - QString widgetUrl = UBW3CWidget::createNPAPIWrapper(sUrl, mimeType, size); - - if (widgetUrl.length() > 0) - { - UBGraphicsWidgetItem *widgetItem = mActiveScene->addW3CWidget(QUrl::fromLocalFile(widgetUrl), pPos); - - widgetItem->setSourceUrl(sourceUrl); - - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - - if (eduMediaFile) - delete eduMediaFile; - - } - else if (mimeType.startsWith("application/pdf")) - { - qDebug() << "accepting mime type" << mimeType << "as PDF"; - qDebug() << "pdf data length: " << pData.size(); - qDebug() << "sourceurl : " + sourceUrl.toString(); - int result = 0; - if(!sourceUrl.isEmpty()){ - QFile sourceFile(sourceUrl.toLocalFile()); - result = UBDocumentManager::documentManager()->addFileToDocument(mActiveDocument, sourceFile); - } - else if(pData.size()){ - QTemporaryFile pdfFile("XXXXXX.pdf"); - if (pdfFile.open()) - { - pdfFile.write(pData); - result = UBDocumentManager::documentManager()->addFileToDocument(mActiveDocument, pdfFile); - pdfFile.close(); - } - } - - if (result){ - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - } - } - else if (mimeType.startsWith("application/vnd.mnemis-uniboard-tool")) - { - qDebug() << "accepting mime type" << mimeType << "as Uniboard Tool"; - - if (sourceUrl.toString() == UBToolsManager::manager()->compass.id) - { - mActiveScene->addCompass(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->ruler.id) - { - mActiveScene->addRuler(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->protractor.id) - { - mActiveScene->addProtractor(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->triangle.id) - { - mActiveScene->addTriangle(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->cache.id) - { - mActiveScene->addCache(); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->magnifier.id) - { - UBMagnifierParams params; - params.x = controlContainer()->geometry().width() / 2; - params.y = controlContainer()->geometry().height() / 2; - params.zoom = 2; - params.sizePercentFromScene = 20; - mActiveScene->addMagnifier(params); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->mask.id) - { - mActiveScene->addMask(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else - { - UBApplication::showMessage(tr("Unknown tool type %1").arg(sourceUrl.toString())); - } - } - else if (sourceUrl.toString().contains("edumedia-sciences.com")) - { - qDebug() << "accepting url " << sourceUrl.toString() << "as eduMedia content"; - - QTemporaryFile eduMediaZipFile("XXXXXX.edumedia"); - if (eduMediaZipFile.open()) - { - eduMediaZipFile.write(pData); - eduMediaZipFile.close(); - - QString tempDir = UBFileSystemUtils::createTempDir("uniboard-edumedia"); - - UBFileSystemUtils::expandZipToDir(eduMediaZipFile, tempDir); - - QDir appDir(tempDir); - - foreach(QString subDirName, appDir.entryList(QDir::AllDirs)) - { - QDir subDir(tempDir + "/" + subDirName + "/contents"); - - foreach(QString fileName, subDir.entryList(QDir::Files)) - { - if (fileName.toLower().endsWith(".swf")) - { - QString swfFile = tempDir + "/" + subDirName + "/contents/" + fileName; - - QSize size; - - if (pSize.height() > 0 && pSize.width() > 0) - size = pSize; - else - size = mActiveScene->nominalSize() * .8; - - QString widgetUrl = UBW3CWidget::createNPAPIWrapper(swfFile, "application/x-shockwave-flash", size); - - if (widgetUrl.length() > 0) - { - UBGraphicsWidgetItem *widgetItem = mActiveScene->addW3CWidget(QUrl::fromLocalFile(widgetUrl), pPos); - - widgetItem->setSourceUrl(sourceUrl); - - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - } - } - } - } - } - else - { - UBApplication::showMessage(tr("Unknown content type %1").arg(pContentTypeHeader)); - qWarning() << "ignoring mime type" << pContentTypeHeader ; - } - - if (isBackground && oldBackgroundObject != mActiveScene->backgroundObject()) - { - if (mActiveScene->isURStackIsEnabled()) { //should be deleted after scene own undo stack implemented - UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(mActiveScene, oldBackgroundObject, mActiveScene->backgroundObject()); - UBApplication::undoStack->push(uc); - } - - } -} - - -void UBBoardController::setActiveDocumentScene(UBDocumentProxy* pDocumentProxy, const int pSceneIndex) -{ - saveViewState(); - - bool documentChange = mActiveDocument != pDocumentProxy; - - int index = pSceneIndex; - int sceneCount = pDocumentProxy->pageCount(); - if (index >= sceneCount && sceneCount > 0) - index = sceneCount - 1; - - UBGraphicsScene* targetScene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocumentProxy, index); - - bool sceneChange = targetScene != mActiveScene; - - if (targetScene) - { - freezeW3CWidgets(true); - - if(sceneChange) - emit activeSceneWillChange(); - - ClearUndoStack(); - - mActiveScene = targetScene; - mActiveDocument = pDocumentProxy; - mActiveSceneIndex = index; - - updateSystemScaleFactor(); - - mControlView->setScene(mActiveScene); - mDisplayView->setScene(mActiveScene); - mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11()); - pDocumentProxy->setDefaultDocumentSize(mActiveScene->nominalSize()); - updatePageSizeState(); - - adjustDisplayViews(); - - UBSettings::settings()->setDarkBackground(mActiveScene->isDarkBackground()); - UBSettings::settings()->setCrossedBackground(mActiveScene->isCrossedBackground()); - - freezeW3CWidgets(false); - } - - selectionChanged(); - - updateBackgroundActionsState(mActiveScene->isDarkBackground(), mActiveScene->isCrossedBackground()); - updateBackgroundState(); - - if(documentChange) - { - emit activeDocumentChanged(); - // Notify the navigator palette that the document has changed - emit setDocOnPageNavigator(pDocumentProxy); - UBGraphicsTextItem::lastUsedTextColor = QColor(); - } - - - if (sceneChange) - { - emit activeSceneChanged(); - emit pageChanged(); - } -} - -void UBBoardController::ClearUndoStack() -{ - QSet uniqueItems; - // go through all stack command - for(int i = 0; i < UBApplication::undoStack->count(); i++) - { - - UBAbstractUndoCommand *abstractCmd = (UBAbstractUndoCommand*)UBApplication::undoStack->command(i); - if(abstractCmd->getType() != UBAbstractUndoCommand::undotype_GRAPHICITEM) - continue; - - UBGraphicsItemUndoCommand *cmd = (UBGraphicsItemUndoCommand*)UBApplication::undoStack->command(i); - - // go through all added and removed objects, for create list of unique objects - QSetIterator itAdded(cmd->GetAddedList()); - while (itAdded.hasNext()) - { - QGraphicsItem* item = itAdded.next(); - if( !uniqueItems.contains(item) ) - uniqueItems.insert(item); - } - - QSetIterator itRemoved(cmd->GetRemovedList()); - while (itRemoved.hasNext()) - { - QGraphicsItem* item = itRemoved.next(); - if( !uniqueItems.contains(item) ) - uniqueItems.insert(item); - } - } - - // clear stack, and command list - UBApplication::undoStack->clear(); - - // go through all unique items, and check, ot on scene, or not. - // if not on scene, than item can be deleted - - QSetIterator itUniq(uniqueItems); - while (itUniq.hasNext()) - { - QGraphicsItem* item = itUniq.next(); - if (item->scene()) { - UBGraphicsScene *scene = dynamic_cast(item->scene()); - if(!scene) - { - mActiveScene->deleteItem(item); - } - } - } - -} - -void UBBoardController::adjustDisplayViews() -{ - if (UBApplication::applicationController) - { - UBApplication::applicationController->adjustDisplayView(); - UBApplication::applicationController->adjustPreviousViews(mActiveSceneIndex, mActiveDocument); - } -} - - -void UBBoardController::changeBackground(bool isDark, bool isCrossed) -{ - bool currentIsDark = mActiveScene->isDarkBackground(); - bool currentIsCrossed = mActiveScene->isCrossedBackground(); - - if ((isDark != currentIsDark) || (currentIsCrossed != isCrossed)) - { - UBSettings::settings()->setDarkBackground(isDark); - UBSettings::settings()->setCrossedBackground(isCrossed); - - mActiveScene->setBackground(isDark, isCrossed); - - updateBackgroundState(); - - emit backgroundChanged(); - } -} - - -void UBBoardController::boardViewResized(QResizeEvent* event) -{ - Q_UNUSED(event); - - int innerMargin = UBSettings::boardMargin; - int userHeight = mControlContainer->height() - (2 * innerMargin); - - mMessageWindow->move(innerMargin, innerMargin + userHeight - mMessageWindow->height()); - mMessageWindow->adjustSizeAndPosition(); - - UBApplication::applicationController->initViewState( - mControlView->horizontalScrollBar()->value(), - mControlView->verticalScrollBar()->value()); - - updateSystemScaleFactor(); - - mControlView->centerOn(0,0); - - mPaletteManager->containerResized(); - - -} - - -void UBBoardController::documentWillBeDeleted(UBDocumentProxy* pProxy) -{ - if (mActiveDocument == pProxy) - { - if (!mIsClosing) - setActiveDocumentScene(UBPersistenceManager::persistenceManager()->createDocument()); - } -} - - -void UBBoardController::showMessage(const QString& message, bool showSpinningWheel) -{ - mMessageWindow->showMessage(message, showSpinningWheel); -} - - -void UBBoardController::hideMessage() -{ - mMessageWindow->hideMessage(); -} - - -void UBBoardController::setDisabled(bool disable) -{ - mMainWindow->boardToolBar->setDisabled(disable); - mControlView->setDisabled(disable); -} - - -void UBBoardController::selectionChanged() -{ - updateActionStates(); -} - - -void UBBoardController::undoRedoStateChange(bool canUndo) -{ - Q_UNUSED(canUndo); - - mMainWindow->actionUndo->setEnabled(UBApplication::undoStack->canUndo()); - mMainWindow->actionRedo->setEnabled(UBApplication::undoStack->canRedo()); - - updateActionStates(); -} - - -void UBBoardController::updateActionStates() -{ - mMainWindow->actionBack->setEnabled(mActiveDocument && (mActiveSceneIndex > 0)); - mMainWindow->actionForward->setEnabled(mActiveDocument && (mActiveSceneIndex < mActiveDocument->pageCount() - 1)); - mMainWindow->actionErase->setEnabled(mActiveScene && !mActiveScene->isEmpty()); -} - - -UBDocumentProxy* UBBoardController::activeDocument() const -{ - return mActiveDocument; -} - - -UBGraphicsScene* UBBoardController::activeScene() const -{ - return mActiveScene; -} - - -int UBBoardController::activeSceneIndex() const -{ - return mActiveSceneIndex; -} - - -void UBBoardController::documentSceneChanged(UBDocumentProxy* pDocumentProxy, int pIndex) -{ - Q_UNUSED(pIndex); - - if(mActiveDocument == pDocumentProxy) - { - setActiveDocumentScene(mActiveDocument, mActiveSceneIndex); - } -} - -void UBBoardController::closing() -{ - mIsClosing = true; - ClearUndoStack(); - lastWindowClosed(); -} - -void UBBoardController::lastWindowClosed() -{ - if (!mCleanupDone) - { - if (mActiveDocument->pageCount() == 1 && (!mActiveScene || mActiveScene->isEmpty())) - { - UBPersistenceManager::persistenceManager()->deleteDocument(mActiveDocument); - } - else - { - persistCurrentScene(); - } - - UBPersistenceManager::persistenceManager()->purgeEmptyDocuments(); - - mCleanupDone = true; - } -} - - - -void UBBoardController::setColorIndex(int pColorIndex) -{ - UBDrawingController::drawingController()->setColorIndex(pColorIndex); - - if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Marker && - UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Line && - UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Text && - UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Selector) - { - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Pen); - } - - if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Pen || - UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line || - UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Text || - UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) - { - mPenColorOnDarkBackground = UBSettings::settings()->penColors(true).at(pColorIndex); - mPenColorOnLightBackground = UBSettings::settings()->penColors(false).at(pColorIndex); - - if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) - { - // If we are in mode board, then do that - if(UBApplication::applicationController->displayMode() == UBApplicationController::Board) - { - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Pen); - mMainWindow->actionPen->setChecked(true); - } - } - - emit penColorChanged(); - } - else if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Marker) - { - mMarkerColorOnDarkBackground = UBSettings::settings()->markerColors(true).at(pColorIndex); - mMarkerColorOnLightBackground = UBSettings::settings()->markerColors(false).at(pColorIndex); - } -} - -void UBBoardController::colorPaletteChanged() -{ - mPenColorOnDarkBackground = UBSettings::settings()->penColor(true); - mPenColorOnLightBackground = UBSettings::settings()->penColor(false); - mMarkerColorOnDarkBackground = UBSettings::settings()->markerColor(true); - mMarkerColorOnLightBackground = UBSettings::settings()->markerColor(false); -} - - -qreal UBBoardController::currentZoom() -{ - if (mControlView) - return mControlView->viewportTransform().m11() / mSystemScaleFactor; - else - return 1.0; -} - - -UBToolWidget* UBBoardController::addTool(const QUrl& toolUrl) -{ - return addTool(toolUrl, mControlView->mapToScene(mControlView->rect().center())); -} - - -UBToolWidget* UBBoardController::addTool(const QUrl& toolUrl, QPointF scenePos) -{ - UBToolWidget *toolWidget = new UBToolWidget(toolUrl, mMainWindow); // Deleted in UBBoardController::removeTool - QPoint pos = mControlView->mapToGlobal(mControlView->mapFromScene(scenePos)); - pos -= QPoint(toolWidget->width() / 2, toolWidget->height() / 2); - - toolWidget->move(pos); - - mTools.append(toolWidget); - - toolWidget->show(); - - return toolWidget; -} - - -void UBBoardController::removeTool(UBToolWidget* toolWidget) -{ - toolWidget->hide(); - - mTools.removeAll(toolWidget); - - delete toolWidget; -} - - -void UBBoardController::hide() -{ - UBApplication::mainWindow->actionLibrary->setChecked(false); - - controlViewHidden(); -} - - -void UBBoardController::show() -{ - UBApplication::mainWindow->actionLibrary->setChecked(false); - - controlViewShown(); -} - - -void UBBoardController::persistCurrentScene() -{ - if(UBPersistenceManager::persistenceManager() - && mActiveDocument && mActiveScene - && (mActiveSceneIndex >= 0)) - { - emit activeSceneWillBePersisted(); - - UBPersistenceManager::persistenceManager()->persistDocumentScene(mActiveDocument, mActiveScene, mActiveSceneIndex); - UBMetadataDcSubsetAdaptor::persist(mActiveDocument); - } -} - - -void UBBoardController::updateSystemScaleFactor() -{ - qreal newScaleFactor = 1.0; - - if (mActiveScene) - { - QSize pageNominalSize = mActiveScene->nominalSize(); - //we're going to keep scale factor untouched if the size is custom - QMap sizesMap = UBSettings::settings()->documentSizes; - if(pageNominalSize == sizesMap.value(DocumentSizeRatio::Ratio16_9) || pageNominalSize == sizesMap.value(DocumentSizeRatio::Ratio4_3)) - { - QSize controlSize = controlViewport(); - - qreal hFactor = ((qreal)controlSize.width()) / ((qreal)pageNominalSize.width()); - qreal vFactor = ((qreal)controlSize.height()) / ((qreal)pageNominalSize.height()); - - newScaleFactor = qMin(hFactor, vFactor); - } - } - - if (mSystemScaleFactor != newScaleFactor) - { - mSystemScaleFactor = newScaleFactor; - emit systemScaleFactorChanged(newScaleFactor); - } - - UBGraphicsScene::SceneViewState viewState = mActiveScene->viewState(); - - QTransform scalingTransform; - - qreal scaleFactor = viewState.zoomFactor * mSystemScaleFactor; - scalingTransform.scale(scaleFactor, scaleFactor); - - mControlView->setTransform(scalingTransform); - mControlView->horizontalScrollBar()->setValue(viewState.horizontalPosition); - mControlView->verticalScrollBar()->setValue(viewState.verticalPostition); - mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11());} - - -void UBBoardController::setWidePageSize(bool checked) -{ - Q_UNUSED(checked); - QSize newSize = UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio16_9); - - if (mActiveScene->nominalSize() != newSize) - { - UBPageSizeUndoCommand* uc = new UBPageSizeUndoCommand(mActiveScene, mActiveScene->nominalSize(), newSize); - UBApplication::undoStack->push(uc); - - setPageSize(newSize); - } -} - - -void UBBoardController::setRegularPageSize(bool checked) -{ - Q_UNUSED(checked); - QSize newSize = UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio4_3); - - if (mActiveScene->nominalSize() != newSize) - { - UBPageSizeUndoCommand* uc = new UBPageSizeUndoCommand(mActiveScene, mActiveScene->nominalSize(), newSize); - UBApplication::undoStack->push(uc); - - setPageSize(newSize); - } -} - - -void UBBoardController::setPageSize(QSize newSize) -{ - if (mActiveScene->nominalSize() != newSize) - { - mActiveScene->setNominalSize(newSize); - - saveViewState(); - - updateSystemScaleFactor(); - updatePageSizeState(); - adjustDisplayViews(); - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - UBSettings::settings()->pageSize->set(newSize); - } -} - -void UBBoardController::notifyCache(bool visible) -{ - if(visible) - { - emit cacheEnabled(); - } - else - { - emit cacheDisabled(); - } - - mCacheWidgetIsEnabled = visible; -} - -void UBBoardController::updatePageSizeState() -{ - if (mActiveScene->nominalSize() == UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio16_9)) - { - mMainWindow->actionWidePageSize->setChecked(true); - } - else if(mActiveScene->nominalSize() == UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio4_3)) - { - mMainWindow->actionRegularPageSize->setChecked(true); - } - else - { - mMainWindow->actionCustomPageSize->setChecked(true); - } -} - - -void UBBoardController::saveViewState() -{ - if (mActiveScene) - { - mActiveScene->setViewState(UBGraphicsScene::SceneViewState(currentZoom(), - mControlView->horizontalScrollBar()->value(), - mControlView->verticalScrollBar()->value())); - } -} - - -void UBBoardController::updateBackgroundState() -{ - //adjust background style - QString newBackgroundStyle; - - if (mActiveScene && mActiveScene->isDarkBackground()) - { - newBackgroundStyle ="QWidget {background-color: #0E0E0E}"; - } - else - { - newBackgroundStyle ="QWidget {background-color: #F1F1F1}"; - } -} - -void UBBoardController::stylusToolChanged(int tool) -{ - if (UBPlatformUtils::hasVirtualKeyboard() && mPaletteManager->mKeyboardPalette) - { - UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool; - if(eTool != UBStylusTool::Selector && eTool != UBStylusTool::Text) - { - if(mPaletteManager->mKeyboardPalette->m_isVisible) - UBApplication::mainWindow->actionVirtualKeyboard->activate(QAction::Trigger); - } - } - - updateBackgroundState(); -} - - -QUrl UBBoardController::expandWidgetToTempDir(const QByteArray& pZipedData, const QString& ext) -{ - QUrl widgetUrl; - QTemporaryFile tmp; - - if (tmp.open()) - { - tmp.write(pZipedData); - tmp.flush(); - tmp.close(); - - QString tmpDir = UBFileSystemUtils::createTempDir() + "." + ext; - - if (UBFileSystemUtils::expandZipToDir(tmp, tmpDir)) - { - widgetUrl = QUrl::fromLocalFile(tmpDir); - } - } - - return widgetUrl; -} - - -void UBBoardController::grabScene(const QRectF& pSceneRect) -{ - if (mActiveScene) - { - QImage image(pSceneRect.width(), pSceneRect.height(), QImage::Format_ARGB32); - image.fill(Qt::transparent); - - QRectF targetRect(0, 0, pSceneRect.width(), pSceneRect.height()); - QPainter painter(&image); - painter.setRenderHint(QPainter::SmoothPixmapTransform); - painter.setRenderHint(QPainter::Antialiasing); - - mActiveScene->setRenderingContext(UBGraphicsScene::NonScreen); - mActiveScene->setRenderingQuality(UBItem::RenderingQualityHigh); - - mActiveScene->render(&painter, targetRect, pSceneRect); - - mActiveScene->setRenderingContext(UBGraphicsScene::Screen); - mActiveScene->setRenderingQuality(UBItem::RenderingQualityNormal); - - mPaletteManager->addItem(QPixmap::fromImage(image)); - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - } -} - - -void UBBoardController::controlViewHidden() -{ - foreach(UBToolWidget* tool, mTools) - { - tool->hide(); - } -} - - -void UBBoardController::controlViewShown() -{ - foreach(UBToolWidget* tool, mTools) - { - tool->show(); - } -} - - -UBGraphicsMediaItem* UBBoardController::addVideo(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos) -{ - QUuid uuid = QUuid::createUuid(); - QUrl concreteUrl = pSourceUrl; - - concreteUrl = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager() - ->addVideoFileToDocument(mActiveDocument, pSourceUrl.toLocalFile(), uuid)); - - UBGraphicsMediaItem* vi = mActiveScene->addMedia(concreteUrl, startPlay, pos); - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - if (vi) { - vi->setUuid(uuid); - vi->setSourceUrl(pSourceUrl); - } - - return vi; - -} - -UBGraphicsMediaItem* UBBoardController::addAudio(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos) -{ - QUuid uuid = QUuid::createUuid(); - QUrl concreteUrl = pSourceUrl; - - concreteUrl = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager() - ->addAudioFileToDocument(mActiveDocument, pSourceUrl.toLocalFile(), uuid)); - - UBGraphicsMediaItem* ai = mActiveScene->addMedia(concreteUrl, startPlay, pos); - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - if (ai){ - ai->setUuid(uuid); - ai->setSourceUrl(pSourceUrl); - } - - return ai; - -} - -UBGraphicsWidgetItem *UBBoardController::addW3cWidget(const QUrl &pUrl, const QPointF &pos) -{ - UBGraphicsWidgetItem* w3cWidgetItem = 0; - - QUuid uuid = QUuid::createUuid(); - QUrl newUrl = pUrl; - - newUrl = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager()->addGraphicsWidgteToDocument(mActiveDocument, pUrl.toLocalFile(), uuid)); - - w3cWidgetItem = mActiveScene->addW3CWidget(newUrl, pos); - - if (w3cWidgetItem) { - w3cWidgetItem->setUuid(uuid); - w3cWidgetItem->setOwnFolder(newUrl); - w3cWidgetItem->setSourceUrl(pUrl); - - QString struuid = UBStringUtils::toCanonicalUuid(uuid); - QString snapshotPath = mActiveDocument->persistencePath() + "/" + UBPersistenceManager::widgetDirectory + "/" + struuid + ".png"; - w3cWidgetItem->setSnapshotPath(QUrl::fromLocalFile(snapshotPath)); - UBGraphicsWidgetItem *tmpItem = dynamic_cast(w3cWidgetItem); - if (tmpItem) - tmpItem->widgetWebView()->takeSnapshot().save(snapshotPath, "PNG"); - - } - return w3cWidgetItem; -} - -void UBBoardController::cut() -{ - //---------------------------------------------------------// - - QList selectedItems; - foreach(QGraphicsItem* gi, mActiveScene->selectedItems()) - selectedItems << gi; - - //---------------------------------------------------------// - - QList selected; - foreach(QGraphicsItem* gi, selectedItems) - { - gi->setSelected(false); - - UBItem* ubItem = dynamic_cast(gi); - UBGraphicsItem *ubGi = dynamic_cast(gi); - - if (ubItem && ubGi && !mActiveScene->tools().contains(gi)) - { - selected << ubItem->deepCopy(); - ubGi->remove(); - } - } - - //---------------------------------------------------------// - - if (selected.size() > 0) - { - QClipboard *clipboard = QApplication::clipboard(); - - UBMimeDataGraphicsItem* mimeGi = new UBMimeDataGraphicsItem(selected); - - mimeGi->setData(UBApplication::mimeTypeUniboardPageItem, QByteArray()); - clipboard->setMimeData(mimeGi); - - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - } - - //---------------------------------------------------------// -} - - -void UBBoardController::copy() -{ - QList selected; - - foreach(QGraphicsItem* gi, mActiveScene->selectedItems()) - { - UBItem* ubItem = dynamic_cast(gi); - - if (ubItem && !mActiveScene->tools().contains(gi)) - selected << ubItem->deepCopy(); - } - - if (selected.size() > 0) - { - QClipboard *clipboard = QApplication::clipboard(); - - UBMimeDataGraphicsItem* mimeGi = new UBMimeDataGraphicsItem(selected); - - mimeGi->setData(UBApplication::mimeTypeUniboardPageItem, QByteArray()); - clipboard->setMimeData(mimeGi); - - } -} - - -void UBBoardController::paste() -{ - QClipboard *clipboard = QApplication::clipboard(); - QPointF pos(0, 0); - processMimeData(clipboard->mimeData(), pos); - - mActiveDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); -} - - -void UBBoardController::processMimeData(const QMimeData* pMimeData, const QPointF& pPos) -{ - if (pMimeData->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - const UBMimeData* mimeData = qobject_cast (pMimeData); - - if (mimeData) - { - int previousActiveSceneIndex = activeSceneIndex(); - int previousPageCount = activeDocument()->pageCount(); - - foreach (UBMimeDataItem sourceItem, mimeData->items()) - addScene(sourceItem.documentProxy(), sourceItem.sceneIndex(), true); - - if (activeDocument()->pageCount() < previousPageCount + mimeData->items().count()) - setActiveDocumentScene(activeDocument(), previousActiveSceneIndex); - else - setActiveDocumentScene(activeDocument(), previousActiveSceneIndex + 1); - - return; - } - } - - if (pMimeData->hasFormat(UBApplication::mimeTypeUniboardPageItem)) - { - const UBMimeDataGraphicsItem* mimeData = qobject_cast (pMimeData); - - if (mimeData) - { - foreach(UBItem* item, mimeData->items()) - { - QGraphicsItem* gi = dynamic_cast(item->deepCopy()); - - if (gi) - { - mActiveScene->addItem(gi); - gi->setPos(gi->pos() + QPointF(50, 50)); - } - } - - return; - } - } - - if(pMimeData->hasHtml()) - { - QString qsHtml = pMimeData->html(); - QString url = UBApplication::urlFromHtml(qsHtml); - - if("" != url) - { - downloadURL(url, pPos); - } - else - { - mActiveScene->addTextHtml(qsHtml, pPos); - } - return; - } - - if (pMimeData->hasUrls()) - { - QList urls = pMimeData->urls(); - - int index = 0; - - foreach(const QUrl url, urls){ - QPointF pos(pPos + QPointF(index * 15, index * 15)); - downloadURL(url, pos); - index++; - } - - return; - } - - if (pMimeData->hasImage()) - { - QImage img = qvariant_cast (pMimeData->imageData()); - QPixmap pix = QPixmap::fromImage(img); - - // validate that the image is really an image, webkit does not fill properly the image mime data - if (pix.width() != 0 && pix.height() != 0) - { - mActiveScene->addPixmap(pix, NULL, pPos, 1.); - return; - } - } - - if (pMimeData->hasText()) - { - if("" != pMimeData->text()){ - // Sometimes, it is possible to have an URL as text. we check here if it is the case - QString qsTmp = pMimeData->text().remove(QRegExp("[\\0]")); - if(qsTmp.startsWith("http://") || qsTmp.startsWith("https://")){ - downloadURL(QUrl(qsTmp), pPos); - } - else{ - mActiveScene->addTextHtml(pMimeData->text(), pPos); - } - } - else{ -#ifdef Q_WS_MACX - // With Safari, in 95% of the drops, the mime datas are hidden in Apple Web Archive pasteboard type. - // This is due to the way Safari is working so we have to dig into the pasteboard in order to retrieve - // the data. - QString qsUrl = UBPlatformUtils::urlFromClipboard(); - if("" != qsUrl){ - // We finally got the url of the dropped ressource! Let's import it! - downloadURL(qsUrl, pPos); - return; - } -#endif - } - } -} - - -void UBBoardController::togglePodcast(bool checked) -{ - if (UBPodcastController::instance()) - UBPodcastController::instance()->toggleRecordingPalette(checked); -} - - -void UBBoardController::moveGraphicsWidgetToControlView(UBGraphicsWidgetItem* graphicsWidget) -{ - QPoint controlViewPos = mControlView->mapFromScene(graphicsWidget->sceneBoundingRect().center()); - - graphicsWidget->setSelected(false); - - UBAbstractWidget *aw = graphicsWidget->widgetWebView(); - graphicsWidget->setWidget(0); - - UBToolWidget *toolWidget = new UBToolWidget(aw, mControlContainer); - - graphicsWidget->scene()->removeItem(graphicsWidget); // TODO UB 4.6 probably leaking the frame - - toolWidget->centerOn(mControlView->mapTo(mControlContainer, controlViewPos)); - - toolWidget->show(); -} - - -void UBBoardController::moveToolWidgetToScene(UBToolWidget* toolWidget) -{ - int xIsOdd = toolWidget->width() % 2; - int yIsOdd = toolWidget->height() % 2; - - QPoint mainWindowCenter = toolWidget->mapTo(mMainWindow, QPoint(toolWidget->width(), toolWidget->height()) / 2); - - UBAbstractWidget* webWidget = toolWidget->webWidget(); - webWidget->setParent(0); - - UBGraphicsWidgetItem* graphicsWidget = 0; - - UBW3CWidget* w3cWidget = qobject_cast(webWidget); - if (w3cWidget) - { - graphicsWidget = new UBGraphicsW3CWidgetItem(w3cWidget); - } - else - { - UBAppleWidget* appleWidget = qobject_cast(webWidget); - if (appleWidget) - { - graphicsWidget = new UBGraphicsAppleWidgetItem(appleWidget); - } - } - - QPoint controlViewCenter = mControlView->mapFrom(mMainWindow, mainWindowCenter); - QPointF scenePos = mControlView->mapToScene(controlViewCenter) + QPointF(xIsOdd * 0.5, yIsOdd * 0.5); - - mActiveScene->addGraphicsWidget(graphicsWidget, scenePos); - - toolWidget->hide(); - toolWidget->deleteLater(); -} - - -void UBBoardController::updateBackgroundActionsState(bool isDark, bool isCrossed) -{ - if (isDark && !isCrossed) - mMainWindow->actionPlainDarkBackground->setChecked(true); - else if (isDark && isCrossed) - mMainWindow->actionCrossedDarkBackground->setChecked(true); - else if (!isDark && isCrossed) - mMainWindow->actionCrossedLightBackground->setChecked(true); - else - mMainWindow->actionPlainLightBackground->setChecked(true); -} - - -void UBBoardController::addItem() -{ - QString defaultPath = UBSettings::settings()->lastImportToLibraryPath->get().toString(); - - QString extensions; - foreach(QString ext, UBSettings::imageFileExtensions) - { - extensions += " *."; - extensions += ext; - } - - QString filename = QFileDialog::getOpenFileName(mControlContainer, tr("Add Item"), - defaultPath, - tr("All Supported (%1)").arg(extensions), NULL, QFileDialog::DontUseNativeDialog); - - if (filename.length() > 0) - { - mPaletteManager->addItem(QUrl::fromLocalFile(filename)); - QFileInfo source(filename); - UBSettings::settings()->lastImportToLibraryPath->set(QVariant(source.absolutePath())); - } -} - -void UBBoardController::importPage() -{ - int pageCount = mActiveDocument->pageCount(); - - if (UBApplication::documentController->addFileToDocument(mActiveDocument)) - { - setActiveDocumentScene(mActiveDocument, pageCount); - } -} - -void UBBoardController::notifyPageChanged() -{ - emit pageChanged(); -} - -void UBBoardController::onDownloadModalFinished() -{ - -} - -void UBBoardController::displayMetaData(QMap metadatas) -{ - emit displayMetadata(metadatas); -} - -void UBBoardController::freezeW3CWidgets(bool freeze) -{ - if (mActiveSceneIndex >= 0) - { - QList list = UBApplication::boardController->activeScene()->getFastAccessItems(); - foreach(QGraphicsItem *item, list) - { - freezeW3CWidget(item, freeze); - } - } -} - -void UBBoardController::freezeW3CWidget(QGraphicsItem *item, bool freeze) -{ - if(item->type() == UBGraphicsW3CWidgetItem::Type) - { - UBGraphicsW3CWidgetItem* item_casted = dynamic_cast(item); - if (0 == item_casted) - return; - - if (freeze) { - item_casted->widgetWebView()->page()->mainFrame()->setContent(UBW3CWidget::freezedWidgetPage().toAscii()); - } else - item_casted->widgetWebView()->loadMainHtml(); - } -} +/* + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "UBBoardController.h" + +#include +#include + +#include "frameworks/UBFileSystemUtils.h" +#include "frameworks/UBPlatformUtils.h" + +#include "core/UBApplication.h" +#include "core/UBSettings.h" +#include "core/UBSetting.h" +#include "core/UBPersistenceManager.h" +#include "core/UBApplicationController.h" +#include "core/UBDocumentManager.h" +#include "core/UBMimeData.h" +#include "core/UBDownloadManager.h" + +#include "network/UBHttpGet.h" + +#include "gui/UBMessageWindow.h" +#include "gui/UBResources.h" +#include "gui/UBToolbarButtonGroup.h" +#include "gui/UBMainWindow.h" +#include "gui/UBToolWidget.h" +#include "gui/UBKeyboardPalette.h" +#include "gui/UBMagnifer.h" + +#include "domain/UBGraphicsPixmapItem.h" +#include "domain/UBGraphicsItemUndoCommand.h" +#include "domain/UBGraphicsProxyWidget.h" +#include "domain/UBGraphicsSvgItem.h" +#include "domain/UBGraphicsWidgetItem.h" +#include "domain/UBGraphicsMediaItem.h" +#include "domain/UBGraphicsPDFItem.h" +#include "domain/UBW3CWidget.h" +#include "domain/UBGraphicsTextItem.h" +#include "domain/UBPageSizeUndoCommand.h" +#include "domain/UBGraphicsGroupContainerItem.h" + +#include "tools/UBToolsManager.h" + +#include "document/UBDocumentProxy.h" +#include "document/UBDocumentController.h" + +#include "board/UBDrawingController.h" +#include "board/UBBoardView.h" + +#include "podcast/UBPodcastController.h" + +#include "adaptors/UBMetadataDcSubsetAdaptor.h" +#include "adaptors/UBSvgSubsetAdaptor.h" + +#include "UBBoardPaletteManager.h" + +#include "core/UBSettings.h" + +#include "core/memcheck.h" +//#include + +UBBoardController::UBBoardController(UBMainWindow* mainWindow) + : UBDocumentContainer(mainWindow->centralWidget()) + , mMainWindow(mainWindow) + , mActiveScene(0) + , mActiveSceneIndex(-1) + , mPaletteManager(0) + , mSoftwareUpdateDialog(0) + , mMessageWindow(0) + , mControlView(0) + , mDisplayView(0) + , mControlContainer(0) + , mControlLayout(0) + , mZoomFactor(1.0) + , mIsClosing(false) + , mSystemScaleFactor(1.0) + , mCleanupDone(false) +{ + mZoomFactor = UBSettings::settings()->boardZoomFactor->get().toDouble(); + + int penColorIndex = UBSettings::settings()->penColorIndex(); + int markerColorIndex = UBSettings::settings()->markerColorIndex(); + + mPenColorOnDarkBackground = UBSettings::settings()->penColors(true).at(penColorIndex); + mPenColorOnLightBackground = UBSettings::settings()->penColors(false).at(penColorIndex); + mMarkerColorOnDarkBackground = UBSettings::settings()->markerColors(true).at(markerColorIndex); + mMarkerColorOnLightBackground = UBSettings::settings()->markerColors(false).at(markerColorIndex); +} + + +void UBBoardController::init() +{ + setupViews(); + setupToolbar(); + + //connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentWillBeDeleted(UBDocumentProxy*)) + // , this, SLOT(documentWillBeDeleted(UBDocumentProxy*))); + + //connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneCreated(UBDocumentProxy*, int)) + // , this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); + + //connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneDeleted(UBDocumentProxy*, int)) + // , this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); + + //connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneMoved(UBDocumentProxy*, int)) + // , this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); + + connect(UBApplication::undoStack, SIGNAL(canUndoChanged(bool)) + , this, SLOT(undoRedoStateChange(bool))); + + connect(UBApplication::undoStack, SIGNAL(canRedoChanged (bool)) + , this, SLOT(undoRedoStateChange(bool))); + + connect(UBDrawingController::drawingController(), SIGNAL(stylusToolChanged(int)) + , this, SLOT(setToolCursor(int))); + + connect(UBDrawingController::drawingController(), SIGNAL(stylusToolChanged(int)) + , this, SLOT(stylusToolChanged(int))); + + connect(UBApplication::app(), SIGNAL(lastWindowClosed()) + , this, SLOT(lastWindowClosed())); + + connect(UBDownloadManager::downloadManager(), SIGNAL(downloadModalFinished()), this, SLOT(onDownloadModalFinished())); + connect(UBDownloadManager::downloadManager(), SIGNAL(addDownloadedFileToBoard(bool,QUrl,QString,QByteArray,QPointF,QSize,bool)), this, SLOT(downloadFinished(bool,QUrl,QString,QByteArray,QPointF,QSize,bool))); + + UBDocumentProxy* doc = UBPersistenceManager::persistenceManager()->createDocument(); + + setActiveDocumentScene(doc); + + connect(UBApplication::mainWindow->actionGroupItems, SIGNAL(triggered()), this, SLOT(groupButtonClicked())); + + undoRedoStateChange(true); +} + + +UBBoardController::~UBBoardController() +{ + delete mDisplayView; +} + + +int UBBoardController::currentPage() +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return mActiveSceneIndex; + return mActiveSceneIndex + 1; +} + +void UBBoardController::setupViews() +{ + mControlContainer = new QWidget(mMainWindow->centralWidget()); + + mControlLayout = new QHBoxLayout(mControlContainer); + mControlLayout->setContentsMargins(0, 0, 0, 0); + + mControlView = new UBBoardView(this, mControlContainer); + mControlView->setInteractive(true); + mControlView->setMouseTracking(true); + + mControlView->grabGesture(Qt::SwipeGesture); + + mControlView->setTransformationAnchor(QGraphicsView::NoAnchor); + + mControlLayout->addWidget(mControlView); + mControlContainer->setObjectName("ubBoardControlContainer"); + mMainWindow->addBoardWidget(mControlContainer); + + connect(mControlView, SIGNAL(resized(QResizeEvent*)), this, SLOT(boardViewResized(QResizeEvent*))); + + // TODO UB 4.x Optimization do we have to create the display view even if their is + // only 1 screen + // + mDisplayView = new UBBoardView(this, UBItemLayerType::FixedBackground, UBItemLayerType::Tool, 0); + mDisplayView->setInteractive(false); + mDisplayView->setTransformationAnchor(QGraphicsView::NoAnchor); + + mMessageWindow = new UBMessageWindow(mControlView); + mMessageWindow->hide(); + + mPaletteManager = new UBBoardPaletteManager(mControlContainer, this); + connect(this, SIGNAL(activeSceneChanged()), mPaletteManager, SLOT(activeSceneChanged())); + +} + + +void UBBoardController::setupLayout() +{ + if(mPaletteManager) + mPaletteManager->setupLayout(); +} + + +void UBBoardController::setBoxing(QRect displayRect) +{ + if (displayRect.isNull()) + { + mControlLayout->setContentsMargins(0, 0, 0, 0); + return; + } + + qreal controlWidth = (qreal)mMainWindow->centralWidget()->width(); + qreal controlHeight = (qreal)mMainWindow->centralWidget()->height(); + qreal displayWidth = (qreal)displayRect.width(); + qreal displayHeight = (qreal)displayRect.height(); + + qreal displayRatio = displayWidth / displayHeight; + qreal controlRatio = controlWidth / controlHeight; + + if (displayRatio < controlRatio) + { + // Pillarboxing + int boxWidth = (controlWidth - (displayWidth * (controlHeight / displayHeight))) / 2; + mControlLayout->setContentsMargins(boxWidth, 0, boxWidth, 0); + } + else if (displayRatio > controlRatio) + { + // Letterboxing + int boxHeight = (controlHeight - (displayHeight * (controlWidth / displayWidth))) / 2; + mControlLayout->setContentsMargins(0, boxHeight, 0, boxHeight); + } + else + { + // No boxing + mControlLayout->setContentsMargins(0, 0, 0, 0); + } +} + + +QSize UBBoardController::displayViewport() +{ + return mDisplayView->geometry().size(); +} + + +QSize UBBoardController::controlViewport() +{ + return mControlView->geometry().size(); +} + + +QRectF UBBoardController::controlGeometry() +{ + return mControlView->geometry(); +} + + +void UBBoardController::setupToolbar() +{ + UBSettings *settings = UBSettings::settings(); + + // Setup color choice widget + QList colorActions; + colorActions.append(mMainWindow->actionColor0); + colorActions.append(mMainWindow->actionColor1); + colorActions.append(mMainWindow->actionColor2); + colorActions.append(mMainWindow->actionColor3); + + UBToolbarButtonGroup *colorChoice = + new UBToolbarButtonGroup(mMainWindow->boardToolBar, colorActions); + + mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, colorChoice); + + connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), colorChoice, SLOT(displayText(QVariant))); + connect(colorChoice, SIGNAL(activated(int)), this, SLOT(setColorIndex(int))); + connect(UBDrawingController::drawingController(), SIGNAL(colorIndexChanged(int)), colorChoice, SLOT(setCurrentIndex(int))); + connect(UBDrawingController::drawingController(), SIGNAL(colorPaletteChanged()), colorChoice, SLOT(colorPaletteChanged())); + connect(UBDrawingController::drawingController(), SIGNAL(colorPaletteChanged()), this, SLOT(colorPaletteChanged())); + + colorChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); + colorChoice->colorPaletteChanged(); + + // Setup line width choice widget + QList lineWidthActions; + lineWidthActions.append(mMainWindow->actionLineSmall); + lineWidthActions.append(mMainWindow->actionLineMedium); + lineWidthActions.append(mMainWindow->actionLineLarge); + + UBToolbarButtonGroup *lineWidthChoice = + new UBToolbarButtonGroup(mMainWindow->boardToolBar, lineWidthActions); + + connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), lineWidthChoice, SLOT(displayText(QVariant))); + + connect(lineWidthChoice, SIGNAL(activated(int)) + , UBDrawingController::drawingController(), SLOT(setLineWidthIndex(int))); + + connect(UBDrawingController::drawingController(), SIGNAL(lineWidthIndexChanged(int)) + , lineWidthChoice, SLOT(setCurrentIndex(int))); + + lineWidthChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); + + mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineWidthChoice); + + //-----------------------------------------------------------// + // Setup eraser width choice widget + + QList eraserWidthActions; + eraserWidthActions.append(mMainWindow->actionEraserSmall); + eraserWidthActions.append(mMainWindow->actionEraserMedium); + eraserWidthActions.append(mMainWindow->actionEraserLarge); + + UBToolbarButtonGroup *eraserWidthChoice = + new UBToolbarButtonGroup(mMainWindow->boardToolBar, eraserWidthActions); + + mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, eraserWidthChoice); + + connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), eraserWidthChoice, SLOT(displayText(QVariant))); + connect(eraserWidthChoice, SIGNAL(activated(int)), UBDrawingController::drawingController(), SLOT(setEraserWidthIndex(int))); + + eraserWidthChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); + eraserWidthChoice->setCurrentIndex(settings->eraserWidthIndex()); + + mMainWindow->boardToolBar->insertSeparator(mMainWindow->actionBackgrounds); + + //-----------------------------------------------------------// + + UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBoard); + UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->tutorialToolBar, mMainWindow->actionBoard); + + UBApplication::app()->decorateActionMenu(mMainWindow->actionMenu); + + mMainWindow->actionBoard->setVisible(false); + + mMainWindow->webToolBar->hide(); + mMainWindow->documentToolBar->hide(); + mMainWindow->tutorialToolBar->hide(); + + connectToolbar(); + initToolbarTexts(); +} + + +void UBBoardController::setToolCursor(int tool) +{ + if (mActiveScene) + { + mActiveScene->setToolCursor(tool); + } + + mControlView->setToolCursor(tool); +} + + +void UBBoardController::connectToolbar() +{ + connect(mMainWindow->actionAdd, SIGNAL(triggered()), this, SLOT(addItem())); + connect(mMainWindow->actionNewPage, SIGNAL(triggered()), this, SLOT(addScene())); + connect(mMainWindow->actionDuplicatePage, SIGNAL(triggered()), this, SLOT(duplicateScene())); + + connect(mMainWindow->actionClearPage, SIGNAL(triggered()), this, SLOT(clearScene())); + connect(mMainWindow->actionEraseItems, SIGNAL(triggered()), this, SLOT(clearSceneItems())); + connect(mMainWindow->actionEraseAnnotations, SIGNAL(triggered()), this, SLOT(clearSceneAnnotation())); + connect(mMainWindow->actionEraseBackground,SIGNAL(triggered()),this,SLOT(clearSceneBackground())); + + connect(mMainWindow->actionUndo, SIGNAL(triggered()), UBApplication::undoStack, SLOT(undo())); + connect(mMainWindow->actionRedo, SIGNAL(triggered()), UBApplication::undoStack, SLOT(redo())); + connect(mMainWindow->actionRedo, SIGNAL(triggered()), this, SLOT(startScript())); + connect(mMainWindow->actionBack, SIGNAL( triggered()), this, SLOT(previousScene())); + connect(mMainWindow->actionForward, SIGNAL(triggered()), this, SLOT(nextScene())); + connect(mMainWindow->actionSleep, SIGNAL(triggered()), this, SLOT(stopScript())); + connect(mMainWindow->actionSleep, SIGNAL(triggered()), this, SLOT(blackout())); + connect(mMainWindow->actionVirtualKeyboard, SIGNAL(triggered(bool)), this, SLOT(showKeyboard(bool))); + connect(mMainWindow->actionImportPage, SIGNAL(triggered()), this, SLOT(importPage())); +} + +void UBBoardController::startScript() +{ + freezeW3CWidgets(false); +} + +void UBBoardController::stopScript() +{ + freezeW3CWidgets(true); +} + +void UBBoardController::initToolbarTexts() +{ + QList allToolbarActions; + + allToolbarActions << mMainWindow->boardToolBar->actions(); + allToolbarActions << mMainWindow->webToolBar->actions(); + allToolbarActions << mMainWindow->documentToolBar->actions(); + + foreach(QAction* action, allToolbarActions) + { + QString nominalText = action->text(); + QString shortText = truncate(nominalText, 48); + QPair texts(nominalText, shortText); + + mActionTexts.insert(action, texts); + } +} + + +void UBBoardController::setToolbarTexts() +{ + bool highResolution = mMainWindow->width() > 1024; + QSize iconSize; + + if (highResolution) + iconSize = QSize(48, 32); + else + iconSize = QSize(32, 32); + + mMainWindow->boardToolBar->setIconSize(iconSize); + mMainWindow->webToolBar->setIconSize(iconSize); + mMainWindow->documentToolBar->setIconSize(iconSize); + + foreach(QAction* action, mActionTexts.keys()) + { + QPair texts = mActionTexts.value(action); + + if (highResolution) + action->setText(texts.first); + else + { + action->setText(texts.second); + } + + action->setToolTip(texts.first); + } +} + + +QString UBBoardController::truncate(QString text, int maxWidth) +{ + QFontMetricsF fontMetrics(mMainWindow->font()); + return fontMetrics.elidedText(text, Qt::ElideRight, maxWidth); +} + + +void UBBoardController::stylusToolDoubleClicked(int tool) +{ + if (tool == UBStylusTool::ZoomIn || tool == UBStylusTool::ZoomOut) + { + zoomRestore(); + } + else if (tool == UBStylusTool::Hand) + { + centerRestore(); + } +} + + + +void UBBoardController::addScene() +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + + UBDocumentContainer::addPage(mActiveSceneIndex + 1); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + setActiveDocumentScene(mActiveSceneIndex + 1); + QApplication::restoreOverrideCursor(); +} + + +void UBBoardController::addScene(UBGraphicsScene* scene, bool replaceActiveIfEmpty) +{ + if (scene) + { + UBGraphicsScene* clone = scene->sceneDeepCopy(); + + if (scene->document() && (scene->document() != selectedDocument())) + { + foreach(QUrl relativeFile, scene->relativeDependencies()) + { + QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); + QString target = selectedDocument()->persistencePath() + "/" + relativeFile.toString(); + + QFileInfo fi(target); + QDir d = fi.dir(); + + d.mkpath(d.absolutePath()); + QFile::copy(source, target); + } + } + + if (replaceActiveIfEmpty && mActiveScene->isEmpty()) + { + setActiveDocumentScene(mActiveSceneIndex); + } + else + { + persistCurrentScene(); + UBPersistenceManager::persistenceManager()->insertDocumentSceneAt(selectedDocument(), clone, mActiveSceneIndex + 1); + setActiveDocumentScene(mActiveSceneIndex + 1); + } + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + } +} + + +void UBBoardController::addScene(UBDocumentProxy* proxy, int sceneIndex, bool replaceActiveIfEmpty) +{ + UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(proxy, sceneIndex); + + if (scene) + { + addScene(scene, replaceActiveIfEmpty); + } +} + +void UBBoardController::duplicateScene(int nIndex) +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + + QList scIndexes; + scIndexes << nIndex; + duplicatePages(scIndexes); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + setActiveDocumentScene(nIndex + 1); + QApplication::restoreOverrideCursor(); + + emit pageChanged(); +} + +void UBBoardController::duplicateScene() +{ + if (UBApplication::applicationController->displayMode() != UBApplicationController::Board) + return; + duplicateScene(mActiveSceneIndex); +} + +void UBBoardController::deleteScene(int nIndex) +{ + if (selectedDocument()->pageCount()>2) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + + QList scIndexes; + scIndexes << nIndex; + deletePages(scIndexes); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + + if (nIndex >= pageCount()) + nIndex = pageCount()-1; + setActiveDocumentScene(nIndex); + QApplication::restoreOverrideCursor(); + } +} + + +void UBBoardController::clearScene() +{ + if (mActiveScene) + { + freezeW3CWidgets(true); + mActiveScene->clearItemsAndAnnotations(); + updateActionStates(); + } +} + + +void UBBoardController::clearSceneItems() +{ + if (mActiveScene) + { + freezeW3CWidgets(true); + mActiveScene->clearItems(); + updateActionStates(); + } +} + + +void UBBoardController::clearSceneAnnotation() +{ + if (mActiveScene) + { + mActiveScene->clearAnnotations(); + updateActionStates(); + } +} + +void UBBoardController::clearSceneBackground() +{ + if (mActiveScene) + { + mActiveScene->clearBackground(); + updateActionStates(); + } +} + +void UBBoardController::showDocumentsDialog() +{ + if (selectedDocument()) + persistCurrentScene(); + + UBApplication::mainWindow->actionLibrary->setChecked(false); + +} + +void UBBoardController::libraryDialogClosed(int ret) +{ + Q_UNUSED(ret); + + mMainWindow->actionLibrary->setChecked(false); +} + + +void UBBoardController::blackout() +{ + UBApplication::applicationController->blackout(); +} + + +void UBBoardController::showKeyboard(bool show) +{ + if(show) + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + mPaletteManager->showVirtualKeyboard(show); +} + + +void UBBoardController::zoomIn(QPointF scenePoint) +{ + if (mControlView->transform().m11() > UB_MAX_ZOOM) + { + qApp->beep(); + return; + } + zoom(mZoomFactor, scenePoint); +} + + +void UBBoardController::zoomOut(QPointF scenePoint) +{ + if ((mControlView->horizontalScrollBar()->maximum() == 0) && (mControlView->verticalScrollBar()->maximum() == 0)) + { + // Do not zoom out if we reached the maximum + qApp->beep(); + return; + } + + qreal newZoomFactor = 1 / mZoomFactor; + + zoom(newZoomFactor, scenePoint); +} + + +void UBBoardController::zoomRestore() +{ + QTransform tr; + + tr.scale(mSystemScaleFactor, mSystemScaleFactor); + mControlView->setTransform(tr); + + centerRestore(); + + foreach(QGraphicsItem *gi, mActiveScene->selectedItems ()) + { + //force item to redraw the frame (for the anti scale calculation) + gi->setSelected(false); + gi->setSelected(true); + } + + emit zoomChanged(1.0); +} + + +void UBBoardController::centerRestore() +{ + centerOn(QPointF(0,0)); +} + + +void UBBoardController::centerOn(QPointF scenePoint) +{ + mControlView->centerOn(scenePoint); + UBApplication::applicationController->adjustDisplayView(); +} + + +void UBBoardController::zoom(const qreal ratio, QPointF scenePoint) +{ + + QPointF viewCenter = mControlView->mapToScene(QRect(0, 0, mControlView->width(), mControlView->height()).center()); + QPointF offset = scenePoint - viewCenter; + QPointF scalledOffset = offset / ratio; + + mControlView->scale(ratio, ratio); + + qreal currentZoom = mControlView->viewportTransform().m11() / mSystemScaleFactor; + + QPointF newCenter = scenePoint - scalledOffset; + + mControlView->centerOn(newCenter); + + emit zoomChanged(currentZoom); + UBApplication::applicationController->adjustDisplayView(); + + emit controlViewportChanged(); + mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11()); +} + + +void UBBoardController::handScroll(qreal dx, qreal dy) +{ + mControlView->translate(dx, dy); + + UBApplication::applicationController->adjustDisplayView(); + + emit controlViewportChanged(); +} + + +void UBBoardController::previousScene() +{ + if (mActiveSceneIndex > 0) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + setActiveDocumentScene(mActiveSceneIndex - 1); + QApplication::restoreOverrideCursor(); + } + + updateActionStates(); + emit pageChanged(); +} + + +void UBBoardController::nextScene() +{ + if (mActiveSceneIndex < selectedDocument()->pageCount() - 1) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + setActiveDocumentScene(mActiveSceneIndex + 1); + QApplication::restoreOverrideCursor(); + } + + updateActionStates(); + emit pageChanged(); +} + + +void UBBoardController::firstScene() +{ + if (mActiveSceneIndex > 0) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + setActiveDocumentScene(0); + QApplication::restoreOverrideCursor(); + } + + updateActionStates(); + emit pageChanged(); +} + + +void UBBoardController::lastScene() +{ + if (mActiveSceneIndex < selectedDocument()->pageCount() - 1) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + setActiveDocumentScene(selectedDocument()->pageCount() - 1); + QApplication::restoreOverrideCursor(); + } + + updateActionStates(); + emit pageChanged(); +} + +void UBBoardController::groupButtonClicked() +{ + QAction *groupAction = UBApplication::mainWindow->actionGroupItems; + QList selItems = activeScene()->selectedItems(); + if (!selItems.count()) { + qDebug() << "Got grouping request when there is no any selected item on the scene"; + return; + } + + if (groupAction->text() == UBSettings::settings()->actionGroupText) { //The only way to get information from item, considering using smth else + UBGraphicsGroupContainerItem *groupItem = activeScene()->createGroup(selItems); + groupItem->setSelected(true); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + + } else if (groupAction->text() == UBSettings::settings()->actionUngroupText) { + //Considering one selected item and it's a group + if (selItems.count() > 1) { + qDebug() << "can't make sense of ungrouping more then one item. Grouping action should be performed for that purpose"; + return; + } + UBGraphicsGroupContainerItem *currentGroup = dynamic_cast(selItems.first()); + if (currentGroup) { + currentGroup->destroy(); + } + } +} + +void UBBoardController::downloadURL(const QUrl& url, const QPointF& pPos, const QSize& pSize, bool isBackground) +{ + qDebug() << "something has been dropped on the board! Url is: " << url.toString(); + QString sUrl = url.toString(); + + if(sUrl.startsWith("uniboardTool://")) + { + downloadFinished(true, url, "application/vnd.mnemis-uniboard-tool", QByteArray(), pPos, pSize, isBackground); + } + else if (sUrl.startsWith("file://") || sUrl.startsWith("/")) + { + QString fileName = url.toLocalFile(); + + QString contentType = UBFileSystemUtils::mimeTypeFromFileName(fileName); + + bool shouldLoadFileData = + contentType.startsWith("image") + || contentType.startsWith("application/widget") + || contentType.startsWith("application/vnd.apple-widget"); + + QFile file(fileName); + + if (shouldLoadFileData) + file.open(QIODevice::ReadOnly); + + downloadFinished(true, url, contentType, file.readAll(), pPos, pSize, isBackground); + + if (shouldLoadFileData) + file.close(); + } + else + { + // When we fall there, it means that we are dropping something from the web to the board + sDownloadFileDesc desc; + desc.modal = true; + desc.url = url.toString(); + desc.currentSize = 0; + desc.name = QFileInfo(url.toString()).fileName(); + desc.totalSize = 0; // The total size will be retrieved during the download + desc.pos = pPos; + desc.size = pSize; + desc.isBackground = isBackground; + + UBDownloadManager::downloadManager()->addFileToDownload(desc); + } +} + + +void UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QString pContentTypeHeader, QByteArray pData, QPointF pPos, QSize pSize, bool isBackground) +{ + QString mimeType = pContentTypeHeader; + + // In some cases "image/jpeg;charset=" is retourned by the drag-n-drop. That is + // why we will check if an ; exists and take the first part (the standard allows this kind of mimetype) + int position=mimeType.indexOf(";"); + if(position != -1) + mimeType=mimeType.left(position); + + if (!pSuccess) + { + UBApplication::showMessage(tr("Downloading content %1 failed").arg(sourceUrl.toString())); + return; + } + + if (!sourceUrl.toString().startsWith("file://") && !sourceUrl.toString().startsWith("uniboardTool://")) + UBApplication::showMessage(tr("Download finished")); + + if (mimeType == "image/jpeg" + || mimeType == "image/png" + || mimeType == "image/gif" + || mimeType == "image/tiff" + || mimeType == "image/bmp") + { + + qDebug() << "accepting mime type" << mimeType << "as raster image"; + + QImage img; + img.loadFromData(pData); + QPixmap pix = QPixmap::fromImage(img); + + UBGraphicsPixmapItem* pixItem = mActiveScene->addPixmap(pix, NULL, pPos, 1.); + pixItem->setSourceUrl(sourceUrl); + + if (isBackground) + { + mActiveScene->setAsBackgroundObject(pixItem, true); + } + else + { + mActiveScene->scaleToFitDocumentSize(pixItem, true, UBSettings::objectInControlViewMargin); + pixItem->setSelected(true); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + } + else if (mimeType == "image/svg+xml") + { + qDebug() << "accepting mime type" << mimeType << "as vecto image"; + + UBGraphicsSvgItem* svgItem = mActiveScene->addSvg(sourceUrl, pPos); + svgItem->setSourceUrl(sourceUrl); + + if (isBackground) + { + mActiveScene->setAsBackgroundObject(svgItem); + } + else + { + mActiveScene->scaleToFitDocumentSize(svgItem, true, UBSettings::objectInControlViewMargin); + svgItem->setSelected(true); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + } + else if (mimeType == "application/vnd.apple-widget") //mime type invented by us :-( + { + qDebug() << "accepting mime type" << mimeType << "as Apple widget"; + + QUrl widgetUrl = sourceUrl; + + if (pData.length() > 0) + { + widgetUrl = expandWidgetToTempDir(pData, "wdgt"); + } + + UBGraphicsWidgetItem* appleWidgetItem = mActiveScene->addAppleWidget(widgetUrl, pPos); + + appleWidgetItem->setSourceUrl(sourceUrl); + + if (isBackground) + { + mActiveScene->setAsBackgroundObject(appleWidgetItem); + } + else + { + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + } + else if (mimeType == "application/widget") + { + qDebug() << "accepting mime type" << mimeType << "as W3C widget"; + QUrl widgetUrl = sourceUrl; + + if (pData.length() > 0) + { + widgetUrl = expandWidgetToTempDir(pData); + } + + UBGraphicsWidgetItem *w3cWidgetItem = addW3cWidget(widgetUrl, pPos); + + if (isBackground) + { + mActiveScene->setAsBackgroundObject(w3cWidgetItem); + } + else + { + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + } + else if (mimeType.startsWith("video/")) + { + qDebug() << "accepting mime type" << mimeType << "as video"; + + UBGraphicsMediaItem *mediaVideoItem = 0; + + if (pData.length() > 0) + { + QUuid uuid = QUuid::createUuid(); + + QUrl url = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager() + ->addVideoFileToDocument(selectedDocument(), sourceUrl, pData, uuid)); + + mediaVideoItem = mActiveScene->addMedia(url, false, pPos); + + mediaVideoItem->setSourceUrl(sourceUrl); + mediaVideoItem->setUuid(uuid); + } + else + { + mediaVideoItem = addVideo(sourceUrl, false, pPos); + } + + if(mediaVideoItem){ + connect(this, SIGNAL(activeSceneChanged()), mediaVideoItem, SLOT(activeSceneChanged())); + } + + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (mimeType.startsWith("audio/")) + { + qDebug() << "accepting mime type" << mimeType << "as audio"; + + UBGraphicsMediaItem *audioMediaItem = 0; + + if (pData.length() > 0) + { + QUuid uuid = QUuid::createUuid(); + + QUrl url = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager() + ->addVideoFileToDocument(selectedDocument(), sourceUrl, pData, uuid)); + + audioMediaItem = mActiveScene->addMedia(url, false, pPos); + + audioMediaItem->setSourceUrl(sourceUrl); + audioMediaItem->setUuid(uuid); + } + else + { + audioMediaItem = addAudio(sourceUrl, false, pPos); + } + + if(audioMediaItem){ + connect(this, SIGNAL(activeSceneChanged()), audioMediaItem, SLOT(activeSceneChanged())); + } + + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + + else if (mimeType.startsWith("application/x-shockwave-flash")) + { + + qDebug() << "accepting mime type" << mimeType << "as flash"; + + QString sUrl = sourceUrl.toString(); + + if (sUrl.startsWith("file://") || sUrl.startsWith("/")) + { + sUrl = sourceUrl.toLocalFile(); + } + + QTemporaryFile* eduMediaFile = 0; + + if (sUrl.toLower().contains("edumedia-sciences.com")) + { + eduMediaFile = new QTemporaryFile("XXXXXX.swf"); + if (eduMediaFile->open()) + { + eduMediaFile->write(pData); + QFileInfo fi(*eduMediaFile); + sUrl = fi.absoluteFilePath(); + } + } + + QSize size; + + if (pSize.height() > 0 && pSize.width() > 0) + size = pSize; + else + size = mActiveScene->nominalSize() * .8; + + QString widgetUrl = UBW3CWidget::createNPAPIWrapper(sUrl, mimeType, size); + + if (widgetUrl.length() > 0) + { + UBGraphicsWidgetItem *widgetItem = mActiveScene->addW3CWidget(QUrl::fromLocalFile(widgetUrl), pPos); + + widgetItem->setSourceUrl(sourceUrl); + + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + + if (eduMediaFile) + delete eduMediaFile; + + } + else if (mimeType.startsWith("application/pdf")) + { + qDebug() << "accepting mime type" << mimeType << "as PDF"; + qDebug() << "pdf data length: " << pData.size(); + qDebug() << "sourceurl : " + sourceUrl.toString(); + int result = 0; + if(!sourceUrl.isEmpty()){ + QFile sourceFile(sourceUrl.toLocalFile()); + result = UBDocumentManager::documentManager()->addFileToDocument(selectedDocument(), sourceFile); + } + else if(pData.size()){ + QTemporaryFile pdfFile("XXXXXX.pdf"); + if (pdfFile.open()) + { + pdfFile.write(pData); + result = UBDocumentManager::documentManager()->addFileToDocument(selectedDocument(), pdfFile); + pdfFile.close(); + } + } + + if (result){ + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + } + } + else if (mimeType.startsWith("application/vnd.mnemis-uniboard-tool")) + { + qDebug() << "accepting mime type" << mimeType << "as Uniboard Tool"; + + if (sourceUrl.toString() == UBToolsManager::manager()->compass.id) + { + mActiveScene->addCompass(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->ruler.id) + { + mActiveScene->addRuler(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->protractor.id) + { + mActiveScene->addProtractor(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->triangle.id) + { + mActiveScene->addTriangle(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->cache.id) + { + mActiveScene->addCache(); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->magnifier.id) + { + UBMagnifierParams params; + params.x = controlContainer()->geometry().width() / 2; + params.y = controlContainer()->geometry().height() / 2; + params.zoom = 2; + params.sizePercentFromScene = 20; + mActiveScene->addMagnifier(params); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->mask.id) + { + mActiveScene->addMask(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else + { + UBApplication::showMessage(tr("Unknown tool type %1").arg(sourceUrl.toString())); + } + } + else if (sourceUrl.toString().contains("edumedia-sciences.com")) + { + qDebug() << "accepting url " << sourceUrl.toString() << "as eduMedia content"; + + QTemporaryFile eduMediaZipFile("XXXXXX.edumedia"); + if (eduMediaZipFile.open()) + { + eduMediaZipFile.write(pData); + eduMediaZipFile.close(); + + QString tempDir = UBFileSystemUtils::createTempDir("uniboard-edumedia"); + + UBFileSystemUtils::expandZipToDir(eduMediaZipFile, tempDir); + + QDir appDir(tempDir); + + foreach(QString subDirName, appDir.entryList(QDir::AllDirs)) + { + QDir subDir(tempDir + "/" + subDirName + "/contents"); + + foreach(QString fileName, subDir.entryList(QDir::Files)) + { + if (fileName.toLower().endsWith(".swf")) + { + QString swfFile = tempDir + "/" + subDirName + "/contents/" + fileName; + + QSize size; + + if (pSize.height() > 0 && pSize.width() > 0) + size = pSize; + else + size = mActiveScene->nominalSize() * .8; + + QString widgetUrl = UBW3CWidget::createNPAPIWrapper(swfFile, "application/x-shockwave-flash", size); + + if (widgetUrl.length() > 0) + { + UBGraphicsWidgetItem *widgetItem = mActiveScene->addW3CWidget(QUrl::fromLocalFile(widgetUrl), pPos); + + widgetItem->setSourceUrl(sourceUrl); + + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + } + } + } + } + } + else + { + UBApplication::showMessage(tr("Unknown content type %1").arg(pContentTypeHeader)); + qWarning() << "ignoring mime type" << pContentTypeHeader ; + } +} + +void UBBoardController::setActiveDocumentScene(int pSceneIndex) +{ + setActiveDocumentScene(selectedDocument(), pSceneIndex); +} + +void UBBoardController::setActiveDocumentScene(UBDocumentProxy* pDocumentProxy, const int pSceneIndex, bool forceReload) +{ + saveViewState(); + + bool documentChange = selectedDocument() != pDocumentProxy; + + int index = pSceneIndex; + int sceneCount = pDocumentProxy->pageCount(); + if (index >= sceneCount && sceneCount > 0) + index = sceneCount - 1; + + UBGraphicsScene* targetScene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocumentProxy, index); + + bool sceneChange = targetScene != mActiveScene; + + if (targetScene) + { + freezeW3CWidgets(true); + + if(sceneChange) + emit activeSceneWillChange(); + + persistCurrentScene(); + + ClearUndoStack(); + + mActiveScene = targetScene; + mActiveSceneIndex = index; + setDocument(pDocumentProxy, forceReload); + + + updateSystemScaleFactor(); + + mControlView->setScene(mActiveScene); + mDisplayView->setScene(mActiveScene); + mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11()); + pDocumentProxy->setDefaultDocumentSize(mActiveScene->nominalSize()); + updatePageSizeState(); + + adjustDisplayViews(); + + UBSettings::settings()->setDarkBackground(mActiveScene->isDarkBackground()); + UBSettings::settings()->setCrossedBackground(mActiveScene->isCrossedBackground()); + + freezeW3CWidgets(false); + } + + selectionChanged(); + + updateBackgroundActionsState(mActiveScene->isDarkBackground(), mActiveScene->isCrossedBackground()); + updateBackgroundState(); + + if(documentChange) + { + UBGraphicsTextItem::lastUsedTextColor = QColor(); + } + + + if (sceneChange) + { + emit activeSceneChanged(); + emit pageChanged(); + } +} + + +void UBBoardController::moveSceneToIndex(int source, int target) +{ + if (selectedDocument()) + { + persistCurrentScene(); + + UBDocumentContainer::movePageToIndex(source, target); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(selectedDocument()); + + setActiveDocumentScene(target); + } +} + +void UBBoardController::ClearUndoStack() +{ + QSet uniqueItems; + // go through all stack command + for(int i = 0; i < UBApplication::undoStack->count(); i++) + { + + UBAbstractUndoCommand *abstractCmd = (UBAbstractUndoCommand*)UBApplication::undoStack->command(i); + if(abstractCmd->getType() != UBAbstractUndoCommand::undotype_GRAPHICITEM) + continue; + + UBGraphicsItemUndoCommand *cmd = (UBGraphicsItemUndoCommand*)UBApplication::undoStack->command(i); + + // go through all added and removed objects, for create list of unique objects + QSetIterator itAdded(cmd->GetAddedList()); + while (itAdded.hasNext()) + { + QGraphicsItem* item = itAdded.next(); + if( !uniqueItems.contains(item) ) + uniqueItems.insert(item); + } + + QSetIterator itRemoved(cmd->GetRemovedList()); + while (itRemoved.hasNext()) + { + QGraphicsItem* item = itRemoved.next(); + if( !uniqueItems.contains(item) ) + uniqueItems.insert(item); + } + } + + // clear stack, and command list + UBApplication::undoStack->clear(); + + // go through all unique items, and check, ot on scene, or not. + // if not on scene, than item can be deleted + + QSetIterator itUniq(uniqueItems); + while (itUniq.hasNext()) + { + QGraphicsItem* item = itUniq.next(); + if (item->scene()) { + UBGraphicsScene *scene = dynamic_cast(item->scene()); + if(!scene) + { + mActiveScene->deleteItem(item); + } + } + } + +} + +void UBBoardController::adjustDisplayViews() +{ + if (UBApplication::applicationController) + { + UBApplication::applicationController->adjustDisplayView(); + UBApplication::applicationController->adjustPreviousViews(mActiveSceneIndex, selectedDocument()); + } +} + + +void UBBoardController::changeBackground(bool isDark, bool isCrossed) +{ + bool currentIsDark = mActiveScene->isDarkBackground(); + bool currentIsCrossed = mActiveScene->isCrossedBackground(); + + if ((isDark != currentIsDark) || (currentIsCrossed != isCrossed)) + { + UBSettings::settings()->setDarkBackground(isDark); + UBSettings::settings()->setCrossedBackground(isCrossed); + + mActiveScene->setBackground(isDark, isCrossed); + + updateBackgroundState(); + + emit backgroundChanged(); + } +} + + +void UBBoardController::boardViewResized(QResizeEvent* event) +{ + Q_UNUSED(event); + + int innerMargin = UBSettings::boardMargin; + int userHeight = mControlContainer->height() - (2 * innerMargin); + + mMessageWindow->move(innerMargin, innerMargin + userHeight - mMessageWindow->height()); + mMessageWindow->adjustSizeAndPosition(); + + UBApplication::applicationController->initViewState( + mControlView->horizontalScrollBar()->value(), + mControlView->verticalScrollBar()->value()); + + updateSystemScaleFactor(); + + mControlView->centerOn(0,0); + + mPaletteManager->containerResized(); + + +} + + +void UBBoardController::documentWillBeDeleted(UBDocumentProxy* pProxy) +{ + if (selectedDocument() == pProxy) + { + if (!mIsClosing) + setActiveDocumentScene(UBPersistenceManager::persistenceManager()->createDocument()); + } +} + + +void UBBoardController::showMessage(const QString& message, bool showSpinningWheel) +{ + mMessageWindow->showMessage(message, showSpinningWheel); +} + + +void UBBoardController::hideMessage() +{ + mMessageWindow->hideMessage(); +} + + +void UBBoardController::setDisabled(bool disable) +{ + mMainWindow->boardToolBar->setDisabled(disable); + mControlView->setDisabled(disable); +} + + +void UBBoardController::selectionChanged() +{ + updateActionStates(); + emit pageSelectionChanged(activeSceneIndex()); +} + + +void UBBoardController::undoRedoStateChange(bool canUndo) +{ + Q_UNUSED(canUndo); + + mMainWindow->actionUndo->setEnabled(UBApplication::undoStack->canUndo()); + mMainWindow->actionRedo->setEnabled(UBApplication::undoStack->canRedo()); + + updateActionStates(); +} + + +void UBBoardController::updateActionStates() +{ + mMainWindow->actionBack->setEnabled(selectedDocument() && (mActiveSceneIndex > 0)); + mMainWindow->actionForward->setEnabled(selectedDocument() && (mActiveSceneIndex < selectedDocument()->pageCount() - 1)); + mMainWindow->actionErase->setEnabled(mActiveScene && !mActiveScene->isEmpty()); +} + + +UBGraphicsScene* UBBoardController::activeScene() const +{ + return mActiveScene; +} + + +int UBBoardController::activeSceneIndex() const +{ + return mActiveSceneIndex; +} + + +void UBBoardController::documentSceneChanged(UBDocumentProxy* pDocumentProxy, int pIndex) +{ + Q_UNUSED(pIndex); + + if(selectedDocument() == pDocumentProxy) + { + setActiveDocumentScene(mActiveSceneIndex); + } +} + +void UBBoardController::closing() +{ + mIsClosing = true; + ClearUndoStack(); + lastWindowClosed(); +} + +void UBBoardController::lastWindowClosed() +{ + if (!mCleanupDone) + { + if (selectedDocument()->pageCount() == 1 && (!mActiveScene || mActiveScene->isEmpty())) + { + UBPersistenceManager::persistenceManager()->deleteDocument(selectedDocument()); + } + else + { + persistCurrentScene(); + } + + UBPersistenceManager::persistenceManager()->purgeEmptyDocuments(); + + mCleanupDone = true; + } +} + + + +void UBBoardController::setColorIndex(int pColorIndex) +{ + UBDrawingController::drawingController()->setColorIndex(pColorIndex); + + if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Marker && + UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Line && + UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Text && + UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Selector) + { + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Pen); + } + + if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Pen || + UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line || + UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Text || + UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) + { + mPenColorOnDarkBackground = UBSettings::settings()->penColors(true).at(pColorIndex); + mPenColorOnLightBackground = UBSettings::settings()->penColors(false).at(pColorIndex); + + if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) + { + // If we are in mode board, then do that + if(UBApplication::applicationController->displayMode() == UBApplicationController::Board) + { + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Pen); + mMainWindow->actionPen->setChecked(true); + } + } + + emit penColorChanged(); + } + else if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Marker) + { + mMarkerColorOnDarkBackground = UBSettings::settings()->markerColors(true).at(pColorIndex); + mMarkerColorOnLightBackground = UBSettings::settings()->markerColors(false).at(pColorIndex); + } +} + +void UBBoardController::colorPaletteChanged() +{ + mPenColorOnDarkBackground = UBSettings::settings()->penColor(true); + mPenColorOnLightBackground = UBSettings::settings()->penColor(false); + mMarkerColorOnDarkBackground = UBSettings::settings()->markerColor(true); + mMarkerColorOnLightBackground = UBSettings::settings()->markerColor(false); +} + + +qreal UBBoardController::currentZoom() +{ + if (mControlView) + return mControlView->viewportTransform().m11() / mSystemScaleFactor; + else + return 1.0; +} + + +UBToolWidget* UBBoardController::addTool(const QUrl& toolUrl) +{ + return addTool(toolUrl, mControlView->mapToScene(mControlView->rect().center())); +} + + +UBToolWidget* UBBoardController::addTool(const QUrl& toolUrl, QPointF scenePos) +{ + UBToolWidget *toolWidget = new UBToolWidget(toolUrl, mMainWindow); // Deleted in UBBoardController::removeTool + QPoint pos = mControlView->mapToGlobal(mControlView->mapFromScene(scenePos)); + pos -= QPoint(toolWidget->width() / 2, toolWidget->height() / 2); + + toolWidget->move(pos); + + mTools.append(toolWidget); + + toolWidget->show(); + + return toolWidget; +} + + +void UBBoardController::removeTool(UBToolWidget* toolWidget) +{ + toolWidget->hide(); + + mTools.removeAll(toolWidget); + + delete toolWidget; +} + + +void UBBoardController::hide() +{ + UBApplication::mainWindow->actionLibrary->setChecked(false); + + controlViewHidden(); +} + + +void UBBoardController::show() +{ + UBApplication::mainWindow->actionLibrary->setChecked(false); + + controlViewShown(); +} + + +void UBBoardController::persistCurrentScene() +{ + if(UBPersistenceManager::persistenceManager() + && selectedDocument() && mActiveScene + && (mActiveSceneIndex >= 0) + && mActiveScene->isModified()) + { + emit activeSceneWillBePersisted(); + + UBPersistenceManager::persistenceManager()->persistDocumentScene(selectedDocument(), mActiveScene, mActiveSceneIndex); + updatePage(mActiveSceneIndex); + } +} + + +void UBBoardController::updateSystemScaleFactor() +{ + qreal newScaleFactor = 1.0; + + if (mActiveScene) + { + QSize pageNominalSize = mActiveScene->nominalSize(); + //we're going to keep scale factor untouched if the size is custom + QMap sizesMap = UBSettings::settings()->documentSizes; + if(pageNominalSize == sizesMap.value(DocumentSizeRatio::Ratio16_9) || pageNominalSize == sizesMap.value(DocumentSizeRatio::Ratio4_3)) + { + QSize controlSize = controlViewport(); + + qreal hFactor = ((qreal)controlSize.width()) / ((qreal)pageNominalSize.width()); + qreal vFactor = ((qreal)controlSize.height()) / ((qreal)pageNominalSize.height()); + + newScaleFactor = qMin(hFactor, vFactor); + } + } + + if (mSystemScaleFactor != newScaleFactor) + { + mSystemScaleFactor = newScaleFactor; + emit systemScaleFactorChanged(newScaleFactor); + } + + UBGraphicsScene::SceneViewState viewState = mActiveScene->viewState(); + + QTransform scalingTransform; + + qreal scaleFactor = viewState.zoomFactor * mSystemScaleFactor; + scalingTransform.scale(scaleFactor, scaleFactor); + + mControlView->setTransform(scalingTransform); + mControlView->horizontalScrollBar()->setValue(viewState.horizontalPosition); + mControlView->verticalScrollBar()->setValue(viewState.verticalPostition); + mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11());} + + +void UBBoardController::setWidePageSize(bool checked) +{ + Q_UNUSED(checked); + QSize newSize = UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio16_9); + + if (mActiveScene->nominalSize() != newSize) + { + UBPageSizeUndoCommand* uc = new UBPageSizeUndoCommand(mActiveScene, mActiveScene->nominalSize(), newSize); + UBApplication::undoStack->push(uc); + + setPageSize(newSize); + } +} + + +void UBBoardController::setRegularPageSize(bool checked) +{ + Q_UNUSED(checked); + QSize newSize = UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio4_3); + + if (mActiveScene->nominalSize() != newSize) + { + UBPageSizeUndoCommand* uc = new UBPageSizeUndoCommand(mActiveScene, mActiveScene->nominalSize(), newSize); + UBApplication::undoStack->push(uc); + + setPageSize(newSize); + } +} + + +void UBBoardController::setPageSize(QSize newSize) +{ + if (mActiveScene->nominalSize() != newSize) + { + mActiveScene->setNominalSize(newSize); + + saveViewState(); + + updateSystemScaleFactor(); + updatePageSizeState(); + adjustDisplayViews(); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + UBSettings::settings()->pageSize->set(newSize); + } +} + +void UBBoardController::notifyCache(bool visible) +{ + if(visible) + { + emit cacheEnabled(); + } + else + { + emit cacheDisabled(); + } +} + +void UBBoardController::updatePageSizeState() +{ + if (mActiveScene->nominalSize() == UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio16_9)) + { + mMainWindow->actionWidePageSize->setChecked(true); + } + else if(mActiveScene->nominalSize() == UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio4_3)) + { + mMainWindow->actionRegularPageSize->setChecked(true); + } + else + { + mMainWindow->actionCustomPageSize->setChecked(true); + } +} + + +void UBBoardController::saveViewState() +{ + if (mActiveScene) + { + mActiveScene->setViewState(UBGraphicsScene::SceneViewState(currentZoom(), + mControlView->horizontalScrollBar()->value(), + mControlView->verticalScrollBar()->value())); + } +} + + +void UBBoardController::updateBackgroundState() +{ + //adjust background style + QString newBackgroundStyle; + + if (mActiveScene && mActiveScene->isDarkBackground()) + { + newBackgroundStyle ="QWidget {background-color: #0E0E0E}"; + } + else + { + newBackgroundStyle ="QWidget {background-color: #F1F1F1}"; + } +} + +void UBBoardController::stylusToolChanged(int tool) +{ + if (UBPlatformUtils::hasVirtualKeyboard() && mPaletteManager->mKeyboardPalette) + { + UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool; + if(eTool != UBStylusTool::Selector && eTool != UBStylusTool::Text) + { + if(mPaletteManager->mKeyboardPalette->m_isVisible) + UBApplication::mainWindow->actionVirtualKeyboard->activate(QAction::Trigger); + } + } + + updateBackgroundState(); +} + + +QUrl UBBoardController::expandWidgetToTempDir(const QByteArray& pZipedData, const QString& ext) +{ + QUrl widgetUrl; + QTemporaryFile tmp; + + if (tmp.open()) + { + tmp.write(pZipedData); + tmp.flush(); + tmp.close(); + + QString tmpDir = UBFileSystemUtils::createTempDir() + "." + ext; + + if (UBFileSystemUtils::expandZipToDir(tmp, tmpDir)) + { + widgetUrl = QUrl::fromLocalFile(tmpDir); + } + } + + return widgetUrl; +} + + +void UBBoardController::grabScene(const QRectF& pSceneRect) +{ + if (mActiveScene) + { + QImage image(pSceneRect.width(), pSceneRect.height(), QImage::Format_ARGB32); + image.fill(Qt::transparent); + + QRectF targetRect(0, 0, pSceneRect.width(), pSceneRect.height()); + QPainter painter(&image); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.setRenderHint(QPainter::Antialiasing); + + mActiveScene->setRenderingContext(UBGraphicsScene::NonScreen); + mActiveScene->setRenderingQuality(UBItem::RenderingQualityHigh); + + mActiveScene->render(&painter, targetRect, pSceneRect); + + mActiveScene->setRenderingContext(UBGraphicsScene::Screen); + mActiveScene->setRenderingQuality(UBItem::RenderingQualityNormal); + + mPaletteManager->addItem(QPixmap::fromImage(image)); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + } +} + + +void UBBoardController::controlViewHidden() +{ + foreach(UBToolWidget* tool, mTools) + { + tool->hide(); + } +} + + +void UBBoardController::controlViewShown() +{ + foreach(UBToolWidget* tool, mTools) + { + tool->show(); + } +} + + +UBGraphicsMediaItem* UBBoardController::addVideo(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos) +{ + QUuid uuid = QUuid::createUuid(); + QUrl concreteUrl = pSourceUrl; + +#ifdef Q_WS_X11 + concreteUrl = QUrl::fromLocalFile(mActiveDocument->persistencePath() + "/" + UBPersistenceManager::persistenceManager() + ->addVideoFileToDocument(mActiveDocument, pSourceUrl.toLocalFile(), uuid)); +#else + concreteUrl = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager() + ->addVideoFileToDocument(selectedDocument(), pSourceUrl.toLocalFile(), uuid)); +#endif + + UBGraphicsMediaItem* vi = mActiveScene->addMedia(concreteUrl, startPlay, pos); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + if (vi) { + vi->setUuid(uuid); + vi->setSourceUrl(pSourceUrl); + } + + return vi; + +} + +UBGraphicsMediaItem* UBBoardController::addAudio(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos) +{ + QUuid uuid = QUuid::createUuid(); + QUrl concreteUrl = pSourceUrl; + +#ifdef Q_WS_X11 + concreteUrl = QUrl::fromLocalFile(mActiveDocument->persistencePath() + "/" + UBPersistenceManager::persistenceManager() + ->addAudioFileToDocument(mActiveDocument, pSourceUrl.toLocalFile(), uuid)); +#else + concreteUrl = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager() + ->addAudioFileToDocument(selectedDocument(), pSourceUrl.toLocalFile(), uuid)); +#endif + + UBGraphicsMediaItem* ai = mActiveScene->addMedia(concreteUrl, startPlay, pos); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + if (ai){ + ai->setUuid(uuid); + ai->setSourceUrl(pSourceUrl); + } + + return ai; + +} + +UBGraphicsWidgetItem *UBBoardController::addW3cWidget(const QUrl &pUrl, const QPointF &pos) +{ + UBGraphicsWidgetItem* w3cWidgetItem = 0; + + QUuid uuid = QUuid::createUuid(); + QUrl newUrl = pUrl; + + newUrl = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager()->addGraphicsWidgteToDocument(selectedDocument(), pUrl.toLocalFile(), uuid)); + + w3cWidgetItem = mActiveScene->addW3CWidget(newUrl, pos); + + if (w3cWidgetItem) { + w3cWidgetItem->setUuid(uuid); + w3cWidgetItem->setOwnFolder(newUrl); + w3cWidgetItem->setSourceUrl(pUrl); + + QString struuid = UBStringUtils::toCanonicalUuid(uuid); + QString snapshotPath = selectedDocument()->persistencePath() + "/" + UBPersistenceManager::widgetDirectory + "/" + struuid + ".png"; + w3cWidgetItem->setSnapshotPath(QUrl::fromLocalFile(snapshotPath)); + UBGraphicsWidgetItem *tmpItem = dynamic_cast(w3cWidgetItem); + if (tmpItem) + tmpItem->widgetWebView()->takeSnapshot().save(snapshotPath, "PNG"); + + } + + return 0; +} + +void UBBoardController::cut() +{ + //---------------------------------------------------------// + + QList selectedItems; + foreach(QGraphicsItem* gi, mActiveScene->selectedItems()) + selectedItems << gi; + + //---------------------------------------------------------// + + QList selected; + foreach(QGraphicsItem* gi, selectedItems) + { + gi->setSelected(false); + + UBItem* ubItem = dynamic_cast(gi); + UBGraphicsItem *ubGi = dynamic_cast(gi); + + if (ubItem && ubGi && !mActiveScene->tools().contains(gi)) + { + selected << ubItem->deepCopy(); + ubGi->remove(); + } + } + + //---------------------------------------------------------// + + if (selected.size() > 0) + { + QClipboard *clipboard = QApplication::clipboard(); + + UBMimeDataGraphicsItem* mimeGi = new UBMimeDataGraphicsItem(selected); + + mimeGi->setData(UBApplication::mimeTypeUniboardPageItem, QByteArray()); + clipboard->setMimeData(mimeGi); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + } + + //---------------------------------------------------------// +} + + +void UBBoardController::copy() +{ + QList selected; + + foreach(QGraphicsItem* gi, mActiveScene->selectedItems()) + { + UBItem* ubItem = dynamic_cast(gi); + + if (ubItem && !mActiveScene->tools().contains(gi)) + selected << ubItem->deepCopy(); + } + + if (selected.size() > 0) + { + QClipboard *clipboard = QApplication::clipboard(); + + UBMimeDataGraphicsItem* mimeGi = new UBMimeDataGraphicsItem(selected); + + mimeGi->setData(UBApplication::mimeTypeUniboardPageItem, QByteArray()); + clipboard->setMimeData(mimeGi); + + } +} + + +void UBBoardController::paste() +{ + QClipboard *clipboard = QApplication::clipboard(); + QPointF pos(0, 0); + processMimeData(clipboard->mimeData(), pos); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); +} + + +void UBBoardController::processMimeData(const QMimeData* pMimeData, const QPointF& pPos) +{ + if (pMimeData->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + const UBMimeData* mimeData = qobject_cast (pMimeData); + + if (mimeData) + { + int previousActiveSceneIndex = activeSceneIndex(); + int previousPageCount = selectedDocument()->pageCount(); + + foreach (UBMimeDataItem sourceItem, mimeData->items()) + addScene(sourceItem.documentProxy(), sourceItem.sceneIndex(), true); + + if (selectedDocument()->pageCount() < previousPageCount + mimeData->items().count()) + setActiveDocumentScene(previousActiveSceneIndex); + else + setActiveDocumentScene(previousActiveSceneIndex + 1); + + return; + } + } + + if (pMimeData->hasFormat(UBApplication::mimeTypeUniboardPageItem)) + { + const UBMimeDataGraphicsItem* mimeData = qobject_cast (pMimeData); + + if (mimeData) + { + foreach(UBItem* item, mimeData->items()) + { + QGraphicsItem* gi = dynamic_cast(item->deepCopy()); + + if (gi) + { + mActiveScene->addItem(gi); + gi->setPos(gi->pos() + QPointF(50, 50)); + } + } + + return; + } + } + + if(pMimeData->hasHtml()) + { + QString qsHtml = pMimeData->html(); + QString url = UBApplication::urlFromHtml(qsHtml); + + if("" != url) + { + downloadURL(url, pPos); + return; + } + } + + if (pMimeData->hasUrls()) + { + QList urls = pMimeData->urls(); + + int index = 0; + + foreach(const QUrl url, urls){ + QPointF pos(pPos + QPointF(index * 15, index * 15)); + downloadURL(url, pos); + index++; + } + + return; + } + + if (pMimeData->hasImage()) + { + QImage img = qvariant_cast (pMimeData->imageData()); + QPixmap pix = QPixmap::fromImage(img); + + // validate that the image is really an image, webkit does not fill properly the image mime data + if (pix.width() != 0 && pix.height() != 0) + { + mActiveScene->addPixmap(pix, NULL, pPos, 1.); + return; + } + } + + if (pMimeData->hasText()) + { + if("" != pMimeData->text()){ + // Sometimes, it is possible to have an URL as text. we check here if it is the case + QString qsTmp = pMimeData->text().remove(QRegExp("[\\0]")); + if(qsTmp.startsWith("http")){ + downloadURL(QUrl(qsTmp), pPos); + } + else{ + mActiveScene->addTextHtml(pMimeData->html(), pPos); + } + } + else{ +#ifdef Q_WS_MACX + // With Safari, in 95% of the drops, the mime datas are hidden in Apple Web Archive pasteboard type. + // This is due to the way Safari is working so we have to dig into the pasteboard in order to retrieve + // the data. + QString qsUrl = UBPlatformUtils::urlFromClipboard(); + if("" != qsUrl){ + // We finally got the url of the dropped ressource! Let's import it! + downloadURL(qsUrl, pPos); + return; + } +#endif + } + } +} + + +void UBBoardController::togglePodcast(bool checked) +{ + if (UBPodcastController::instance()) + UBPodcastController::instance()->toggleRecordingPalette(checked); +} + + +void UBBoardController::moveGraphicsWidgetToControlView(UBGraphicsWidgetItem* graphicsWidget) +{ + QPoint controlViewPos = mControlView->mapFromScene(graphicsWidget->sceneBoundingRect().center()); + + graphicsWidget->setSelected(false); + + UBAbstractWidget *aw = graphicsWidget->widgetWebView(); + graphicsWidget->setWidget(0); + + UBToolWidget *toolWidget = new UBToolWidget(aw, mControlContainer); + + graphicsWidget->scene()->removeItem(graphicsWidget); // TODO UB 4.6 probably leaking the frame + + toolWidget->centerOn(mControlView->mapTo(mControlContainer, controlViewPos)); + + toolWidget->show(); +} + + +void UBBoardController::moveToolWidgetToScene(UBToolWidget* toolWidget) +{ + int xIsOdd = toolWidget->width() % 2; + int yIsOdd = toolWidget->height() % 2; + + QPoint mainWindowCenter = toolWidget->mapTo(mMainWindow, QPoint(toolWidget->width(), toolWidget->height()) / 2); + + UBAbstractWidget* webWidget = toolWidget->webWidget(); + webWidget->setParent(0); + + UBGraphicsWidgetItem* graphicsWidget = 0; + + UBW3CWidget* w3cWidget = qobject_cast(webWidget); + if (w3cWidget) + { + graphicsWidget = new UBGraphicsW3CWidgetItem(w3cWidget); + } + else + { + UBAppleWidget* appleWidget = qobject_cast(webWidget); + if (appleWidget) + { + graphicsWidget = new UBGraphicsAppleWidgetItem(appleWidget); + } + } + + QPoint controlViewCenter = mControlView->mapFrom(mMainWindow, mainWindowCenter); + QPointF scenePos = mControlView->mapToScene(controlViewCenter) + QPointF(xIsOdd * 0.5, yIsOdd * 0.5); + + mActiveScene->addGraphicsWidget(graphicsWidget, scenePos); + + toolWidget->hide(); + toolWidget->deleteLater(); +} + + +void UBBoardController::updateBackgroundActionsState(bool isDark, bool isCrossed) +{ + if (isDark && !isCrossed) + mMainWindow->actionPlainDarkBackground->setChecked(true); + else if (isDark && isCrossed) + mMainWindow->actionCrossedDarkBackground->setChecked(true); + else if (!isDark && isCrossed) + mMainWindow->actionCrossedLightBackground->setChecked(true); + else + mMainWindow->actionPlainLightBackground->setChecked(true); +} + + +void UBBoardController::addItem() +{ + QString defaultPath = UBSettings::settings()->lastImportToLibraryPath->get().toString(); + + QString extensions; + foreach(QString ext, UBSettings::imageFileExtensions) + { + extensions += " *."; + extensions += ext; + } + + QString filename = QFileDialog::getOpenFileName(mControlContainer, tr("Add Item"), + defaultPath, + tr("All Supported (%1)").arg(extensions), NULL, QFileDialog::DontUseNativeDialog); + + if (filename.length() > 0) + { + mPaletteManager->addItem(QUrl::fromLocalFile(filename)); + QFileInfo source(filename); + UBSettings::settings()->lastImportToLibraryPath->set(QVariant(source.absolutePath())); + } +} + +void UBBoardController::importPage() +{ + int pageCount = selectedDocument()->pageCount(); + + if (UBApplication::documentController->addFileToDocument(selectedDocument())) + { + setActiveDocumentScene(pageCount); + } +} + +void UBBoardController::notifyPageChanged() +{ + emit pageChanged(); +} + +void UBBoardController::onDownloadModalFinished() +{ + +} + +void UBBoardController::displayMetaData(QMap metadatas) +{ + emit displayMetadata(metadatas); +} + +void UBBoardController::freezeW3CWidgets(bool freeze) +{ + if (mActiveSceneIndex >= 0) + { + QList list = UBApplication::boardController->activeScene()->getFastAccessItems(); + foreach(QGraphicsItem *item, list) + { + freezeW3CWidget(item, freeze); + } + } +} + +void UBBoardController::freezeW3CWidget(QGraphicsItem *item, bool freeze) +{ + if(item->type() == UBGraphicsW3CWidgetItem::Type) + { + UBGraphicsW3CWidgetItem* item_casted = dynamic_cast(item); + if (0 == item_casted) + return; + + if (freeze) { + item_casted->widgetWebView()->page()->mainFrame()->setContent(UBW3CWidget::freezedWidgetPage().toAscii()); + } else + item_casted->widgetWebView()->loadMainHtml(); + } +} diff --git a/src/board/UBBoardController.h b/src/board/UBBoardController.h index 2c8dcf26..70888db7 100644 --- a/src/board/UBBoardController.h +++ b/src/board/UBBoardController.h @@ -19,6 +19,7 @@ #include #include +#include "document/UBDocumentContainer.h" class UBMainWindow; class UBApplication; @@ -40,7 +41,7 @@ class UBGraphicsWidgetItem; class UBBoardPaletteManager; -class UBBoardController : public QObject +class UBBoardController : public UBDocumentContainer { Q_OBJECT @@ -50,7 +51,7 @@ class UBBoardController : public QObject void init(); void setupLayout(); - UBDocumentProxy* activeDocument() const; + UBGraphicsScene* activeScene() const; int activeSceneIndex() const; QSize displayViewport(); @@ -60,14 +61,6 @@ class UBBoardController : public QObject int currentPage(); - int pageFromSceneIndex(int sceneIndex); - int sceneIndexFromPage(int page); - - UBDocumentProxy* activeDocument() - { - return mActiveDocument; - } - QWidget* controlContainer() { return mControlContainer; @@ -158,10 +151,15 @@ class UBBoardController : public QObject void displayMetaData(QMap metadatas); void ClearUndoStack(); - void emitScrollSignal() { emit scrollToSelectedPage(); } + + void setActiveDocumentScene(UBDocumentProxy* pDocumentProxy, int pSceneIndex = 0, bool forceReload = false); + void setActiveDocumentScene(int pSceneIndex); + + void moveSceneToIndex(int source, int target); + void duplicateScene(int index); + void deleteScene(int index); public slots: - void setActiveDocumentScene(UBDocumentProxy* pDocumentProxy, int pSceneIndex = 0); void showDocumentsDialog(); void showKeyboard(bool show); void togglePodcast(bool checked); @@ -222,14 +220,12 @@ class UBBoardController : public QObject void freezeW3CWidget(QGraphicsItem* item, bool freeze); void startScript(); void stopScript(); - bool cacheIsVisible(); signals: void newPageAdded(); void activeSceneWillBePersisted(); void activeSceneWillChange(); void activeSceneChanged(); - void activeDocumentChanged(); void zoomChanged(qreal pZoomFactor); void systemScaleFactorChanged(qreal pSystemScaleFactor); void penColorChanged(); @@ -238,10 +234,9 @@ class UBBoardController : public QObject void cacheEnabled(); void cacheDisabled(); void pageChanged(); - void setDocOnPageNavigator(UBDocumentProxy* doc); void documentReorganized(int index); void displayMetadata(QMap metadata); - void scrollToSelectedPage(); + void pageSelectionChanged(int index); protected: void setupViews(); @@ -263,7 +258,6 @@ class UBBoardController : public QObject void adjustDisplayViews(); UBMainWindow *mMainWindow; - UBDocumentProxy* mActiveDocument; UBGraphicsScene* mActiveScene; int mActiveSceneIndex; UBBoardPaletteManager *mPaletteManager; @@ -283,7 +277,6 @@ class UBBoardController : public QObject qreal mSystemScaleFactor; bool mCleanupDone; QMap > mActionTexts; - bool mCacheWidgetIsEnabled; private slots: void stylusToolDoubleClicked(int tool); diff --git a/src/board/UBBoardPaletteManager.cpp b/src/board/UBBoardPaletteManager.cpp index 94169ec4..1b349661 100644 --- a/src/board/UBBoardPaletteManager.cpp +++ b/src/board/UBBoardPaletteManager.cpp @@ -134,8 +134,6 @@ void UBBoardPaletteManager::setupDockPaletteWidgets() //------------------------------------------------// // Create the widgets for the dock palettes - mpPageNavigWidget = new UBPageNavigationWidget(); - #ifdef USE_WEB_WIDGET mpLibWidget = new UBLibWidget(); #endif @@ -352,7 +350,7 @@ void UBBoardPaletteManager::pagePaletteButtonReleased() QListpageActions; pageActions << UBApplication::mainWindow->actionNewPage; UBBoardController* boardController = UBApplication::boardController; - if(UBApplication::documentController->pageCanBeDuplicated(boardController->pageFromSceneIndex(boardController->activeSceneIndex()))) + if(UBApplication::documentController->pageCanBeDuplicated(UBDocumentContainer::pageFromSceneIndex(boardController->activeSceneIndex()))) pageActions << UBApplication::mainWindow->actionDuplicatePage; pageActions << UBApplication::mainWindow->actionImportPage; @@ -568,7 +566,7 @@ void UBBoardPaletteManager::activeSceneChanged() if (mpPageNavigWidget) { - mpPageNavigWidget->setPageNumber(UBApplication::boardController->pageFromSceneIndex(pageIndex), activeScene->document()->pageCount()); + mpPageNavigWidget->setPageNumber(UBDocumentContainer::pageFromSceneIndex(pageIndex), activeScene->document()->pageCount()); } if (mZoomPalette) diff --git a/src/board/UBLibraryController.cpp b/src/board/UBLibraryController.cpp index d874a829..efc7e393 100644 --- a/src/board/UBLibraryController.cpp +++ b/src/board/UBLibraryController.cpp @@ -562,7 +562,7 @@ void UBLibraryController::removeBackground() UBGraphicsScene* UBLibraryController::activeScene() { - if (mBoardController->activeDocument()) + if (mBoardController->selectedDocument()) return mBoardController->activeScene(); return 0; diff --git a/src/core/UBApplicationController.cpp b/src/core/UBApplicationController.cpp index a8769af4..f744bfcf 100644 --- a/src/core/UBApplicationController.cpp +++ b/src/core/UBApplicationController.cpp @@ -340,8 +340,7 @@ void UBApplicationController::showBoard() int selectedSceneIndex = UBApplication::documentController->getSelectedItemIndex(); if (selectedSceneIndex != -1) { - UBApplication::boardController->setActiveDocumentScene(UBApplication::documentController->getCurrentDocument(), selectedSceneIndex); - UBApplication::boardController->emitScrollSignal(); + UBApplication::boardController->setActiveDocumentScene(UBApplication::documentController->selectedDocument(), selectedSceneIndex, true); } } diff --git a/src/core/UBPersistenceManager.cpp b/src/core/UBPersistenceManager.cpp index 153fa788..a46d8ed7 100644 --- a/src/core/UBPersistenceManager.cpp +++ b/src/core/UBPersistenceManager.cpp @@ -608,10 +608,10 @@ void UBPersistenceManager::persistDocumentScene(UBDocumentProxy* pDocumentProxy, if (pScene->isModified()) { - UBThumbnailAdaptor::persistScene(pDocumentProxy->persistencePath(), pScene, pSceneIndex); - UBSvgSubsetAdaptor::persistScene(pDocumentProxy, pScene, pSceneIndex); + UBThumbnailAdaptor::persistScene(pDocumentProxy, pScene, pSceneIndex); + pScene->setModified(false); } diff --git a/src/document/UBDocumentContainer.cpp b/src/document/UBDocumentContainer.cpp new file mode 100644 index 00000000..a8d806f0 --- /dev/null +++ b/src/document/UBDocumentContainer.cpp @@ -0,0 +1,127 @@ +/* + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "UBDocumentContainer.h" +#include "adaptors/UBThumbnailAdaptor.h" +#include "core/UBPersistenceManager.h" +#include "core/memcheck.h" + + +UBDocumentContainer::UBDocumentContainer(QObject * parent) + :QObject(parent) + ,mCurrentDocument(NULL) +{} + +UBDocumentContainer::~UBDocumentContainer() +{ + foreach(const QPixmap* pm, mDocumentThumbs) + delete pm; +} + +void UBDocumentContainer::setDocument(UBDocumentProxy* document, bool forceReload) +{ + if (mCurrentDocument != document || forceReload) + { + mCurrentDocument = document; + reloadThumbnails(); + emit documentSet(mCurrentDocument); + } +} + +void UBDocumentContainer::duplicatePages(QList& pageIndexes) +{ + int offset = 0; + foreach(int sceneIndex, pageIndexes) + { + UBPersistenceManager::persistenceManager()->duplicateDocumentScene(mCurrentDocument, sceneIndex + offset); + insertThumbPage(sceneIndex + offset); + offset++; + } + emit documentThumbnailsUpdated(this); +} + +void UBDocumentContainer::movePageToIndex(int source, int target) +{ + UBPersistenceManager::persistenceManager()->moveSceneToIndex(mCurrentDocument, source, target); + deleteThumbPage(source); + insertThumbPage(target); + emit documentThumbnailsUpdated(this); +} + +void UBDocumentContainer::deletePages(QList& pageIndexes) +{ + UBPersistenceManager::persistenceManager()->deleteDocumentScenes(mCurrentDocument, pageIndexes); + int offset = 0; + foreach(int index, pageIndexes) + { + deleteThumbPage(index - offset); + offset++; + } + emit documentThumbnailsUpdated(this); +} + +void UBDocumentContainer::addPage(int index) +{ + UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mCurrentDocument, index); + insertThumbPage(index); + emit documentThumbnailsUpdated(this); +} + +void UBDocumentContainer::updatePage(int index) +{ + updateThumbPage(index); + emit documentThumbnailsUpdated(this); +} + +void UBDocumentContainer::deleteThumbPage(int index) +{ + mDocumentThumbs.removeAt(index); + emit documentPageDeleted(index); +} + +void UBDocumentContainer::updateThumbPage(int index) +{ + mDocumentThumbs[index] = UBThumbnailAdaptor::get(mCurrentDocument, index); + emit documentPageUpdated(index); +} + +void UBDocumentContainer::insertThumbPage(int index) +{ + mDocumentThumbs.insert(index, UBThumbnailAdaptor::get(mCurrentDocument, index)); + emit documentPageAdded(index); +} + +void UBDocumentContainer::reloadThumbnails() +{ + if (mCurrentDocument) + { + UBThumbnailAdaptor::load(mCurrentDocument, mDocumentThumbs); + emit documentThumbnailsUpdated(this); + } +} + +int UBDocumentContainer::pageFromSceneIndex(int sceneIndex) +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return sceneIndex; + return sceneIndex+1; +} + +int UBDocumentContainer::sceneIndexFromPage(int page) +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return page; + return page-1; +} diff --git a/src/document/UBDocumentContainer.h b/src/document/UBDocumentContainer.h new file mode 100644 index 00000000..54e95f37 --- /dev/null +++ b/src/document/UBDocumentContainer.h @@ -0,0 +1,67 @@ +/* + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef UBDOCUMENTCONTAINER_H_ +#define UBDOCUMENTCONTAINER_H_ + +#include +#include "UBDocumentProxy.h" + +class UBDocumentContainer : public QObject +{ + Q_OBJECT + + public: + UBDocumentContainer(QObject * parent = 0); + virtual ~UBDocumentContainer(); + + void setDocument(UBDocumentProxy* document, bool forceReload = false); + + UBDocumentProxy* selectedDocument(){return mCurrentDocument;} + int pageCount(){return mDocumentThumbs.size();} + const QPixmap* pageAt(int index){return mDocumentThumbs[index];} + + static int pageFromSceneIndex(int sceneIndex); + static int sceneIndexFromPage(int sceneIndex); + + void duplicatePages(QList& pageIndexes); + void movePageToIndex(int source, int target); + void deletePages(QList& pageIndexes); + void addPage(int index); + void updatePage(int index); + + private: + void deleteThumbPage(int index); + void updateThumbPage(int index); + void insertThumbPage(int index); + + + UBDocumentProxy* mCurrentDocument; + QList mDocumentThumbs; + + + protected: + void reloadThumbnails(); + + signals: + void documentSet(UBDocumentProxy* document); + void documentPageAdded(int index); + void documentPageDeleted(int index); + void documentPageUpdated(int index); + void documentThumbnailsUpdated(UBDocumentContainer* source); +}; + + +#endif /* UBDOCUMENTPROXY_H_ */ diff --git a/src/document/UBDocumentController.cpp b/src/document/UBDocumentController.cpp index 9be1de41..46f8cf32 100644 --- a/src/document/UBDocumentController.cpp +++ b/src/document/UBDocumentController.cpp @@ -1,1697 +1,1659 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "UBDocumentController.h" - -#include -#include - -#include "frameworks/UBFileSystemUtils.h" -#include "frameworks/UBStringUtils.h" -#include "frameworks/UBPlatformUtils.h" - -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBDocumentManager.h" -#include "core/UBApplicationController.h" -#include "core/UBSettings.h" -#include "core/UBSetting.h" - -#include "adaptors/UBExportPDF.h" -#include "adaptors/UBThumbnailAdaptor.h" - -#include "adaptors/UBMetadataDcSubsetAdaptor.h" - -#include "board/UBBoardController.h" -#include "board/UBBoardPaletteManager.h" -#include "board/UBDrawingController.h" - - -#include "gui/UBThumbnailView.h" -#include "gui/UBDocumentTreeWidget.h" -#include "gui/UBMousePressFilter.h" -#include "gui/UBMessageWindow.h" -#include "gui/UBMainWindow.h" -#include "gui/UBDocumentToolsPalette.h" - -#include "domain/UBGraphicsScene.h" -#include "domain/UBGraphicsSvgItem.h" -#include "domain/UBGraphicsPixmapItem.h" - -#include "document/UBDocumentProxy.h" - -#include "ui_documents.h" -#include "ui_mainWindow.h" - -#include "core/memcheck.h" - -UBDocumentController::UBDocumentController(UBMainWindow* mainWindow) - : QObject(mainWindow->centralWidget()) - , mSelectionType(None) - , mParentWidget(mainWindow->centralWidget()) - , mBoardController(UBApplication::boardController) - , mDocumentUI(0) - , mMainWindow(mainWindow) - , mDocumentWidget(0) - , mIsClosing(false) - , mToolsPalette(0) - , mToolsPalettePositionned(false) - , mTrashTi(0) -{ - setupViews(); - setupToolbar(); - this->selectDocument(UBApplication::boardController->activeDocument()); - connect(this, SIGNAL(exportDone()), mMainWindow, SLOT(onExportDone())); - connect(mMainWindow->actionNewPage, SIGNAL(triggered()), this, SLOT(reloadThumbs())); -} - -void UBDocumentController::reloadThumbs() -{ - mDocumentThumbs = UBThumbnailAdaptor::load(selectedDocumentProxy()); -} - -UBDocumentController::~UBDocumentController() -{ - if (mDocumentUI) - delete mDocumentUI; -} - - -void UBDocumentController::createNewDocument() -{ - UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); - - if (group) - { - UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument(group->groupName()); - - selectDocument(document); - } -} - - -UBDocumentProxyTreeItem* UBDocumentController::findDocument(UBDocumentProxy* proxy) -{ - QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); - - while (*it) - { - UBDocumentProxyTreeItem *treeItem = dynamic_cast((*it)); - - if (treeItem && treeItem->proxy() == proxy) - return treeItem; - - ++it; - } - - return 0; -} - - -void UBDocumentController::selectDocument(UBDocumentProxy* proxy, bool setAsCurrentDocument) -{ - if (!proxy) - return; - - QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); - - mDocumentUI->documentTreeWidget->clearSelection(); - mDocumentUI->documentTreeWidget->setCurrentItem(0); - - UBDocumentProxyTreeItem* selected = 0; - - while (*it) - { - UBDocumentProxyTreeItem* pi = dynamic_cast((*it)); - - if (pi) - { - if (setAsCurrentDocument) - pi->setIcon(0, QIcon("")); - - pi->setSelected(false); - - if (pi->proxy() == proxy) - { - selected = pi; - } - } - - ++it; - } - - if (selected) - { - selected->setSelected(true); - - selected->parent()->setExpanded(true); - selected->setText(0, proxy->name()); - - if (setAsCurrentDocument) - { - selected->setIcon(0, QIcon(":/images/currentDocument.png")); - if (proxy != mBoardController->activeDocument()) - mBoardController->setActiveDocumentScene(proxy); - } - - mDocumentUI->documentTreeWidget->setCurrentItem(selected); - - mDocumentUI->documentTreeWidget->scrollToItem(selected); - - mDocumentThumbs = UBThumbnailAdaptor::load(selectedDocumentProxy()); - refreshDocumentThumbnailsView(); - - mSelectionType = Document; - } -} - - -void UBDocumentController::createNewDocumentGroup() -{ - UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0); // deleted by the tree widget - int i = 1; - QString newFolderName = tr("New Folder"); - while (allGroupNames().contains(newFolderName)) - { - newFolderName = tr("New Folder") + " " + QVariant(i++).toString(); - } - docGroupItem->setGroupName(newFolderName); - - int trashIndex = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(mTrashTi); - - mDocumentUI->documentTreeWidget->insertTopLevelItem(trashIndex, docGroupItem); - mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); - mDocumentUI->documentTreeWidget->expandItem(docGroupItem); -} - - -UBDocumentProxy* UBDocumentController::selectedDocumentProxy() -{ - UBDocumentProxyTreeItem* proxyItem = selectedDocumentProxyTreeItem(); - return proxyItem ? proxyItem->proxy() : 0; -} - - -UBDocumentProxyTreeItem* UBDocumentController::selectedDocumentProxyTreeItem() -{ - if (mDocumentUI && mDocumentUI->documentTreeWidget) - { - QList selectedItems = mDocumentUI->documentTreeWidget->selectedItems(); - - foreach (QTreeWidgetItem * item, selectedItems) - { - UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); - - if (proxyItem) - { - return proxyItem; - } - } - } - - return 0; -} - - -UBDocumentGroupTreeItem* UBDocumentController::selectedDocumentGroupTreeItem() -{ - QList selectedItems = mDocumentUI->documentTreeWidget->selectedItems(); - - foreach (QTreeWidgetItem * item, selectedItems) - { - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - - if (groupItem) - { - return groupItem; - } - else - { - UBDocumentGroupTreeItem* parent = dynamic_cast(item->parent()); - if (parent) - { - return parent; - } - } - } - - return 0; -} - - -void UBDocumentController::itemSelectionChanged() -{ - refreshDocumentThumbnailsView(); - - if (selectedDocumentProxy()) - mSelectionType = Document; - else if (selectedDocumentGroupTreeItem()) - mSelectionType = Folder; - else - mSelectionType = None; - - selectionChanged(); -} - - -void UBDocumentController::refreshDocumentThumbnailsView() -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - QList items; - QList itemsPath; - - UBDocumentProxy *proxy = selectedDocumentProxy(); - QGraphicsPixmapItem *selection = 0; - - QStringList labels; - - if (proxy) - { - mCurrentDocument = proxy; - - for (int i = 0; i < mDocumentThumbs.count(); i++) - { - QPixmap pix = mDocumentThumbs.at(i); - QGraphicsPixmapItem *pixmapItem = new UBSceneThumbnailPixmap(pix, proxy, i); // deleted by the tree widget - - if (proxy == mBoardController->activeDocument() && mBoardController->activeSceneIndex() == i) - { - selection = pixmapItem; - } - - items << pixmapItem; - labels << tr("Page %1").arg(UBApplication::boardController->pageFromSceneIndex(i)); - - itemsPath.append(QUrl::fromLocalFile(proxy->persistencePath() + QString("/pages/%1").arg(UBApplication::boardController->pageFromSceneIndex(i)))); - } - } - - mDocumentUI->thumbnailWidget->setGraphicsItems(items, itemsPath, labels, UBApplication::mimeTypeUniboardPage); - - UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); - if (proxyTi && (proxyTi->parent() == mTrashTi)) - mDocumentUI->thumbnailWidget->setDragEnabled(false); - else - mDocumentUI->thumbnailWidget->setDragEnabled(true); - - mDocumentUI->thumbnailWidget->ensureVisible(0, 0, 10, 10); - - if (selection) { - disconnect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); - UBSceneThumbnailPixmap *currentScene = dynamic_cast(selection); - if (currentScene) - mDocumentUI->thumbnailWidget->hightlightItem(currentScene->sceneIndex()); - connect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); - } - - emit refreshThumbnails(); - QApplication::restoreOverrideCursor(); -} - - -void UBDocumentController::setupViews() -{ - - if (!mDocumentWidget) - { - mDocumentWidget = new QWidget(mMainWindow->centralWidget()); - mMainWindow->addDocumentsWidget(mDocumentWidget); - - mDocumentUI = new Ui::documents(); - - mDocumentUI->setupUi(mDocumentWidget); - - int thumbWidth = UBSettings::settings()->documentThumbnailWidth->get().toInt(); - - mDocumentUI->documentZoomSlider->setValue(thumbWidth); - mDocumentUI->thumbnailWidget->setThumbnailWidth(thumbWidth); - - connect(mDocumentUI->documentZoomSlider, SIGNAL(valueChanged(int)), this, - SLOT(documentZoomSliderValueChanged(int))); - - connect(mMainWindow->actionOpen, SIGNAL(triggered()), this, SLOT(openSelectedItem())); - connect(mMainWindow->actionNewFolder, SIGNAL(triggered()), this, SLOT(createNewDocumentGroup())); - connect(mMainWindow->actionNewDocument, SIGNAL(triggered()), this, SLOT(createNewDocument())); - - connect(mMainWindow->actionImport, SIGNAL(triggered(bool)), this, SLOT(importFile())); - - QMenu* addMenu = new QMenu(mDocumentWidget); - mAddFolderOfImagesAction = addMenu->addAction(tr("Add Folder of Images")); - mAddImagesAction = addMenu->addAction(tr("Add Images")); - mAddFileToDocumentAction = addMenu->addAction(tr("Add Pages from File")); - - connect(mAddFolderOfImagesAction, SIGNAL(triggered(bool)), this, SLOT(addFolderOfImages())); - connect(mAddFileToDocumentAction, SIGNAL(triggered(bool)), this, SLOT(addFileToDocument())); - connect(mAddImagesAction, SIGNAL(triggered(bool)), this, SLOT(addImages())); - - foreach (QWidget* menuWidget, mMainWindow->actionDocumentAdd->associatedWidgets()) - { - QToolButton *tb = qobject_cast(menuWidget); - - if (tb && !tb->menu()) - { - tb->setObjectName("ubButtonMenu"); - tb->setPopupMode(QToolButton::InstantPopup); - - QMenu* menu = new QMenu(mDocumentWidget); - - menu->addAction(mAddFolderOfImagesAction); - menu->addAction(mAddImagesAction); - menu->addAction(mAddFileToDocumentAction); - - tb->setMenu(menu); - } - } - - QMenu* exportMenu = new QMenu(mDocumentWidget); - - UBDocumentManager *documentManager = UBDocumentManager::documentManager(); - for (int i = 0; i < documentManager->supportedExportAdaptors().length(); i++) - { - UBExportAdaptor* adaptor = documentManager->supportedExportAdaptors()[i]; - QAction *currentExportAction = exportMenu->addAction(adaptor->exportName()); - currentExportAction->setData(i); - connect(currentExportAction, SIGNAL(triggered (bool)), this, SLOT(exportDocument())); - exportMenu->addAction(currentExportAction); - } - - foreach (QWidget* menuWidget, mMainWindow->actionExport->associatedWidgets()) - { - QToolButton *tb = qobject_cast(menuWidget); - - if (tb && !tb->menu()) - { - tb->setObjectName("ubButtonMenu"); - tb->setPopupMode(QToolButton::InstantPopup); - - tb->setMenu(exportMenu); - } - } - -#ifdef Q_WS_MAC - mMainWindow->actionDelete->setShortcut(QKeySequence(Qt::Key_Backspace)); -#endif - - connect(mMainWindow->actionDelete, SIGNAL(triggered()), this, SLOT(deleteSelectedItem())); - connect(mMainWindow->actionDuplicate, SIGNAL(triggered()), this, SLOT(duplicateSelectedItem())); - connect(mMainWindow->actionRename, SIGNAL(triggered()), this, SLOT(renameSelectedItem())); - connect(mMainWindow->actionAddToWorkingDocument, SIGNAL(triggered()), this, SLOT(addToDocument())); - - loadDocumentProxies(); - - mDocumentUI->documentTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); - mDocumentUI->documentTreeWidget->setDragEnabled(true); - mDocumentUI->documentTreeWidget->viewport()->setAcceptDrops(true); - mDocumentUI->documentTreeWidget->setDropIndicatorShown(true); - mDocumentUI->documentTreeWidget->setIndentation(18); // 1.5 * /resources/style/treeview-branch-closed.png width - mDocumentUI->documentTreeWidget->setDragDropMode(QAbstractItemView::InternalMove); - - connect(mDocumentUI->documentTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); - connect(mDocumentUI->documentTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(itemChanged(QTreeWidgetItem *, int))); - connect(mDocumentUI->documentTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *, int))); - - connect(mDocumentUI->thumbnailWidget, SIGNAL(sceneDropped(UBDocumentProxy*, int, int)), this, SLOT(moveSceneToIndex ( UBDocumentProxy*, int, int))); - connect(mDocumentUI->thumbnailWidget, SIGNAL(resized()), this, SLOT(thumbnailViewResized())); - connect(mDocumentUI->thumbnailWidget, SIGNAL(mouseDoubleClick(QGraphicsItem*, int)), - this, SLOT(pageDoubleClicked(QGraphicsItem*, int))); - connect(mDocumentUI->thumbnailWidget, SIGNAL(mouseClick(QGraphicsItem*, int)), - this, SLOT(pageClicked(QGraphicsItem*, int))); - - connect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), - this, SLOT(pageSelectionChanged())); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentCreated(UBDocumentProxy*)), - this, SLOT(addDocumentInTree(UBDocumentProxy*))); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), - this, SLOT(updateDocumentInTree(UBDocumentProxy*))); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneCreated(UBDocumentProxy*, int)), - this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneWillBeDeleted(UBDocumentProxy*, int)), - this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); - - mDocumentUI->thumbnailWidget->setBackgroundBrush(UBSettings::documentViewLightColor); - - mMessageWindow = new UBMessageWindow(mDocumentUI->thumbnailWidget); - mMessageWindow->hide(); - - } -} - - -QWidget* UBDocumentController::controlView() -{ - return mDocumentWidget; -} - - -void UBDocumentController::setupToolbar() -{ - UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->documentToolBar, mMainWindow->actionBoard); - connect(mMainWindow->actionDocumentTools, SIGNAL(triggered()), this, SLOT(toggleDocumentToolsPalette())); -} - -void UBDocumentController::setupPalettes() -{ - - mToolsPalette = new UBDocumentToolsPalette(controlView()); - - mToolsPalette->hide(); - - bool showToolsPalette = !mToolsPalette->isEmpty(); - mMainWindow->actionDocumentTools->setVisible(showToolsPalette); - - if (showToolsPalette) - { - mMainWindow->actionDocumentTools->trigger(); - } -} - - -void UBDocumentController::show() -{ - selectDocument(mBoardController->activeDocument()); - - selectionChanged(); - - if(!mToolsPalette) - setupPalettes(); -} - - -void UBDocumentController::hide() -{ - // NOOP -} - - -void UBDocumentController::openSelectedItem() -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - - if (selectedItems.count() > 0) - { - UBSceneThumbnailPixmap* thumb = dynamic_cast (selectedItems.last()); - - if (thumb) - { - UBDocumentProxy* proxy = thumb->proxy(); - - if (proxy && isOKToOpenDocument(proxy)) - { - UBApplication::applicationController->showBoard(); - } - } - } - else - { - UBDocumentProxy* proxy = selectedDocumentProxy(); - - if (proxy && isOKToOpenDocument(proxy)) - { - mBoardController->setActiveDocumentScene(proxy); - UBApplication::applicationController->showBoard(); - } - } - - QApplication::restoreOverrideCursor(); -} - -void UBDocumentController::duplicateSelectedItem() -{ - if (UBApplication::applicationController->displayMode() != UBApplicationController::Document) - return; - - if (mSelectionType == Page) - { - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - QList selectedSceneIndexes; - foreach (QGraphicsItem *item, selectedItems) - { - UBSceneThumbnailPixmap *thumb = dynamic_cast(item); - if (thumb) - { - UBDocumentProxy *proxy = thumb->proxy(); - - if (proxy) - { - int sceneIndex = thumb->sceneIndex(); - selectedSceneIndexes << sceneIndex; - } - } - } - if (selectedSceneIndexes.count() > 0) - { - UBSceneThumbnailPixmap *thumb = dynamic_cast(selectedItems.at(0)); - UBDocumentProxy *proxy = thumb->proxy(); - int offset = 0; - if (proxy) - { - foreach (int sceneIndex, selectedSceneIndexes) - { - UBPersistenceManager::persistenceManager()->duplicateDocumentScene(proxy, sceneIndex + offset); - mDocumentThumbs.insert(sceneIndex + offset, mDocumentThumbs.at(sceneIndex + offset)); - offset++; - } - } - refreshDocumentThumbnailsView(); - proxy->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(proxy); - mDocumentUI->thumbnailWidget->selectItemAt(selectedSceneIndexes.last() + offset); - } - } - else - { - UBDocumentProxy* source = selectedDocumentProxy(); - UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); - - if (source && group) - { - QString docName = source->metaData(UBSettings::documentName).toString(); - - showMessage(tr("Duplicating Document %1").arg(docName), true); - - UBDocumentProxy* duplicatedDoc = UBPersistenceManager::persistenceManager()->duplicateDocument(source); - duplicatedDoc->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(duplicatedDoc); - - selectDocument(duplicatedDoc, false); - - showMessage(tr("Document %1 copied").arg(docName), false); - } - } -} - - -void UBDocumentController::deleteSelectedItem() -{ - if (mSelectionType == Page) - { - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - - deletePages(selectedItems); - } - else - { - - UBDocumentProxyTreeItem *proxyTi = selectedDocumentProxyTreeItem(); - - UBDocumentGroupTreeItem* groupTi = selectedDocumentGroupTreeItem(); - - if (proxyTi && proxyTi->proxy() && proxyTi->parent()) - { - if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Document"), tr("Are you sure you want to remove the document '%1'?").arg(proxyTi->proxy()->metaData(UBSettings::documentName).toString()))) - { - if (proxyTi->parent() == mTrashTi) - { - int index = proxyTi->parent()->indexOfChild(proxyTi); - index --; - - if (index >= 0) - { - if (proxyTi->proxy() == mBoardController->activeDocument()) - { - selectDocument(((UBDocumentProxyTreeItem*)proxyTi->parent()->child(index))->proxy()); - } - else - proxyTi->parent()->child(index)->setSelected(true); - } - else if (proxyTi->parent()->childCount() > 1) - { - if (proxyTi->proxy() == mBoardController->activeDocument()) - { - selectDocument(((UBDocumentProxyTreeItem*)proxyTi->parent()->child(1))->proxy()); - } - else - proxyTi->parent()->child(1)->setSelected(true); - } - else - { - if (proxyTi->proxy() == mBoardController->activeDocument()) - { - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (groupItem != selectedDocumentGroupTreeItem() && groupItem->childCount() > 0) - { - selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(0))->proxy()); - break; - } - } - } - else - proxyTi->parent()->setSelected(true); - } - - proxyTi->parent()->removeChild(proxyTi); - - UBPersistenceManager::persistenceManager()->deleteDocument(proxyTi->proxy()); - - refreshDocumentThumbnailsView(); - } - else - { - // Move document to trash - QString oldGroupName = proxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); - proxyTi->proxy()->setMetaData(UBSettings::documentGroupName, UBSettings::trashedDocumentGroupNamePrefix + oldGroupName); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyTi->proxy()); - - proxyTi->parent()->removeChild(proxyTi); - mTrashTi->addChild(proxyTi); - proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); - } - } - } - else if (groupTi) - { - if (groupTi == mTrashTi) - { - if(UBApplication::mainWindow->yesNoQuestion(tr("Empty Trash"), tr("Are you sure you want to empty trash?"))) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - QList toBeDeleted; - - for (int i = 0; i < groupTi->childCount(); i++) - { - UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); - if (proxyTi && proxyTi->proxy()) - toBeDeleted << proxyTi; - } - - UBApplication::showMessage(tr("Emptying trash")); - - for (int i = 0; i < toBeDeleted.count(); i++) - { - UBDocumentProxyTreeItem* proxyTi = toBeDeleted.at(i); - - proxyTi->parent()->removeChild(proxyTi); - UBPersistenceManager::persistenceManager()->deleteDocument(proxyTi->proxy()); - } - - UBApplication::showMessage(tr("Emptied trash")); - - QApplication::restoreOverrideCursor(); - mMainWindow->actionDelete->setEnabled(false); - } - } - else - { - if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Folder"), tr("Are you sure you want to remove the folder '%1' and all its content?").arg(groupTi->groupName()))) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - bool changeCurrentDocument = false; - for (int i = 0; i < groupTi->childCount(); i++) - { - UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); - if (proxyTi && proxyTi->proxy() && proxyTi->proxy() == mBoardController->activeDocument()) - { - changeCurrentDocument = true; - break; - } - } - - if (changeCurrentDocument) - { - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (groupItem != groupTi && groupItem->childCount() > 0) - { - selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(0))->proxy()); - break; - } - } - } - - QList toBeDeleted; - - for (int i = 0; i < groupTi->childCount(); i++) - { - UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); - if (proxyTi && proxyTi->proxy()) - toBeDeleted << proxyTi; - } - - for (int i = 0; i < toBeDeleted.count(); i++) - { - UBDocumentProxyTreeItem* proxyTi = toBeDeleted.at(i); - - UBApplication::showMessage(QString("Deleting %1").arg(proxyTi->proxy()->metaData(UBSettings::documentName).toString())); - // Move document to trash - QString oldGroupName = proxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); - proxyTi->proxy()->setMetaData(UBSettings::documentGroupName, UBSettings::trashedDocumentGroupNamePrefix + oldGroupName); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyTi->proxy()); - - groupTi->removeChild(proxyTi); - mTrashTi->addChild(proxyTi); - proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); - - UBApplication::showMessage(QString("%1 deleted").arg(groupTi->groupName())); - } - - // dont remove default group - if (!groupTi->isDefaultFolder()) - { - int index = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(groupTi); - - if (index >= 0) - { - mDocumentUI->documentTreeWidget->takeTopLevelItem(index); - } - } - - refreshDocumentThumbnailsView(); - - QApplication::restoreOverrideCursor(); - } - } - } - } -} - - -void UBDocumentController::exportDocument() -{ - QAction *currentExportAction = qobject_cast(sender()); - QVariant actionData = currentExportAction->data(); - UBExportAdaptor* selectedExportAdaptor = UBDocumentManager::documentManager()->supportedExportAdaptors()[actionData.toInt()]; - - UBDocumentProxy* proxy = selectedDocumentProxy(); - - if (proxy) - { - selectedExportAdaptor->persist(proxy); - emit exportDone(); - } - else - { - UBApplication::showMessage(tr("No document selected!")); - } -} - - -void UBDocumentController::documentZoomSliderValueChanged (int value) -{ - mDocumentUI->thumbnailWidget->setThumbnailWidth(value); - - UBSettings::settings()->documentThumbnailWidth->set(value); -} - - -UBGraphicsScene* UBDocumentController::activeScene() -{ - if (mBoardController->activeDocument()) - { - return mBoardController->activeScene(); - } - else - { - return 0; - } -} - - -void UBDocumentController::loadDocumentProxies() -{ - QList > proxies = UBPersistenceManager::persistenceManager()->documentProxies; - - QStringList emptyGroupNames = UBSettings::settings()->value("Document/EmptyGroupNames", QStringList()).toStringList(); - - mDocumentUI->documentTreeWidget->clear(); - - QMap groupNamesMap; - - UBDocumentGroupTreeItem* emptyGroupNameTi = 0; - - mTrashTi = new UBDocumentGroupTreeItem(0, false); // deleted by the tree widget - mTrashTi->setGroupName(UBSettings::documentTrashGroupName); - mTrashTi->setIcon(0, QIcon(":/images/trash.png")); - - foreach (QPointer proxy, proxies) - { - if (proxy) - { - QString docGroup = proxy->metaData(UBSettings::documentGroupName).toString(); - - bool isEmptyGroupName = false; - bool isInTrash = false; - - if (docGroup.isEmpty()) // #see https://trac.assembla.com/uniboard/ticket/426 - { - docGroup = UBSettings::defaultDocumentGroupName; - isEmptyGroupName = true; - } - else if (docGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) - { - isInTrash = true; - } - - QString docName = proxy->metaData(UBSettings::documentName).toString(); - - if (emptyGroupNames.contains(docGroup)) - emptyGroupNames.removeAll(docGroup); - - if (!groupNamesMap.contains(docGroup) && !isInTrash) - { - UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0, !isEmptyGroupName); // deleted by the tree widget - groupNamesMap.insert(docGroup, docGroupItem); - docGroupItem->setGroupName(docGroup); - - if (isEmptyGroupName) - emptyGroupNameTi = docGroupItem; - } - - UBDocumentGroupTreeItem* docGroupItem; - if (isInTrash) - docGroupItem = mTrashTi; - else - docGroupItem = groupNamesMap.value(docGroup); - - QTreeWidgetItem* docItem = new UBDocumentProxyTreeItem(docGroupItem, proxy, !isInTrash); - docItem->setText(0, docName); - - if (mBoardController->activeDocument() == proxy) - { - mDocumentUI->documentTreeWidget->expandItem(docGroupItem); - mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); - } - } - } - - foreach (const QString emptyGroupName, emptyGroupNames) - { - UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0); // deleted by the tree widget - groupNamesMap.insert(emptyGroupName, docGroupItem); - docGroupItem->setGroupName(emptyGroupName); - } - - QList groupNamesList = groupNamesMap.keys(); - qSort(groupNamesList); - - foreach (const QString groupName, groupNamesList) - { - UBDocumentGroupTreeItem* ti = groupNamesMap.value(groupName); - - if (ti != emptyGroupNameTi) - mDocumentUI->documentTreeWidget->addTopLevelItem(ti); - } - - if (emptyGroupNameTi) - mDocumentUI->documentTreeWidget->addTopLevelItem(emptyGroupNameTi); - - mDocumentUI->documentTreeWidget->addTopLevelItem(mTrashTi); -} - - -void UBDocumentController::itemClicked(QTreeWidgetItem * item, int column ) -{ - Q_UNUSED(item); - Q_UNUSED(column); - - selectDocument(selectedDocumentProxy(), false); - itemSelectionChanged(); -} - - -void UBDocumentController::itemChanged(QTreeWidgetItem * item, int column) -{ - UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); - - disconnect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)) - , this, SLOT(updateDocumentInTree(UBDocumentProxy*))); - - if (proxyItem) - { - if (proxyItem->proxy()->metaData(UBSettings::documentName).toString() != item->text(column)) - { - proxyItem->proxy()->setMetaData(UBSettings::documentName, item->text(column)); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyItem->proxy()); - } - } - else - { - // it is a group - UBDocumentGroupTreeItem* editedGroup = dynamic_cast(item); - if (editedGroup) - { - for (int i = 0; i < item->childCount(); i++) - { - UBDocumentProxyTreeItem* childItem = dynamic_cast(item->child(i)); - - if (childItem) - { - QString groupName; - if (0 != (item->flags() & Qt::ItemIsEditable)) - { - childItem->proxy()->setMetaData(UBSettings::documentGroupName, item->text(column)); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(childItem->proxy()); - } - } - } - } - } - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), - this, SLOT(updateDocumentInTree(UBDocumentProxy*))); -} - - -void UBDocumentController::importFile() -{ - UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); - UBDocumentManager *docManager = UBDocumentManager::documentManager(); - - if (group) - { - QString defaultPath = UBSettings::settings()->lastImportFilePath->get().toString(); - QString filePath = QFileDialog::getOpenFileName(mParentWidget, tr("Open Supported File"), - defaultPath, docManager->importFileFilter()); - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - QApplication::processEvents(); - QFileInfo fileInfo(filePath); - UBSettings::settings()->lastImportFilePath->set(QVariant(fileInfo.absolutePath())); - - if (filePath.length() > 0) - { - UBDocumentProxy* createdDocument = 0; - QApplication::processEvents(); - QFile selectedFile(filePath); - - QString groupName = group->groupName(); - - if (groupName == UBSettings::defaultDocumentGroupName) - groupName = ""; - - UBApplication::showMessage(tr("Importing file %1...").arg(fileInfo.baseName()), true); - - createdDocument = docManager->importFile(selectedFile, groupName); - - if (createdDocument) - { - selectDocument(createdDocument, false); - } - else - { - UBApplication::showMessage(tr("Failed to import file ... ")); - } - } - - QApplication::restoreOverrideCursor(); - } -} - -void UBDocumentController::addFolderOfImages() -{ - UBDocumentProxy* document = selectedDocumentProxy(); - - if (document) - { - QString defaultPath = UBSettings::settings()->lastImportFolderPath->get().toString(); - - QString imagesDir = QFileDialog::getExistingDirectory(mParentWidget, tr("Import all Images from Folder"), defaultPath); - QDir parentImageDir(imagesDir); - parentImageDir.cdUp(); - - UBSettings::settings()->lastImportFolderPath->set(QVariant(parentImageDir.absolutePath())); - - if (imagesDir.length() > 0) - { - QDir dir(imagesDir); - - int importedImageNumber - = UBDocumentManager::documentManager()->addImageDirToDocument(dir, document); - - if (importedImageNumber == 0) - { - UBApplication::showMessage(tr("Folder does not contain any image files!")); - UBApplication::applicationController->showDocument(); - } - else - { - document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(document); - mDocumentThumbs = UBThumbnailAdaptor::load(selectedDocumentProxy()); - refreshDocumentThumbnailsView(); - } - } - } -} - - -void UBDocumentController::addFileToDocument() -{ - UBDocumentProxy* document = selectedDocumentProxy(); - - if (document) - { - addFileToDocument(document); - mDocumentThumbs = UBThumbnailAdaptor::load(document); - refreshDocumentThumbnailsView(); - } -} - - -bool UBDocumentController::addFileToDocument(UBDocumentProxy* document) -{ - QString defaultPath = UBSettings::settings()->lastImportFilePath->get().toString(); - QString filePath = QFileDialog::getOpenFileName(mParentWidget, tr("Open Supported File") - , defaultPath, UBDocumentManager::documentManager()->importFileFilter()); - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - QApplication::processEvents(); - - QFileInfo fileInfo(filePath); - UBSettings::settings()->lastImportFilePath->set(QVariant(fileInfo.absolutePath())); - - bool success = false; - - if (filePath.length() > 0) - { - QApplication::processEvents(); - QFile selectedFile(filePath); - - UBApplication::showMessage(tr("Importing file %1...").arg(fileInfo.baseName()), true); - - success = UBDocumentManager::documentManager()->addFileToDocument(document, selectedFile); - - if (success) - { - document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(document); - } - else - { - UBApplication::showMessage(tr("Failed to import file ... ")); - } - } - - QApplication::restoreOverrideCursor(); - - return success; -} - - -void UBDocumentController::moveSceneToIndex(UBDocumentProxy* proxy, int source, int target) -{ - UBPersistenceManager::persistenceManager()->moveSceneToIndex(proxy, source, target); - - proxy->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(proxy); - mDocumentThumbs.insert(target, mDocumentThumbs.takeAt(source)); - refreshDocumentThumbnailsView(); - mDocumentUI->thumbnailWidget->hightlightItem(target); -} - - -void UBDocumentController::thumbnailViewResized() -{ - int maxWidth = qMin(UBSettings::maxThumbnailWidth, mDocumentUI->thumbnailWidget->width()); - - mDocumentUI->documentZoomSlider->setMaximum(maxWidth); -} - - -void UBDocumentController::pageSelectionChanged() -{ - if (mIsClosing) - return; - - bool pageSelected = mDocumentUI->thumbnailWidget->selectedItems().count() > 0; - - if (pageSelected) - mSelectionType = Page; - else - mSelectionType = None; - - selectionChanged(); -} - - -void UBDocumentController::selectionChanged() -{ - if (mIsClosing) - return; - - int pageCount = -1; - - UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); - - if (proxyTi && proxyTi->proxy()) - pageCount = proxyTi->proxy()->pageCount(); - - bool pageSelected = (mSelectionType == Page); - bool groupSelected = (mSelectionType == Folder); - bool docSelected = (mSelectionType == Document); - - bool trashSelected = false; - if (groupSelected && selectedDocumentGroupTreeItem()) - trashSelected = selectedDocumentGroupTreeItem()->isTrashFolder(); - - if ((docSelected || pageSelected) && proxyTi) - trashSelected = dynamic_cast(proxyTi->parent())->isTrashFolder(); - - bool defaultGroupSelected = false; - if (groupSelected && selectedDocumentGroupTreeItem()) - defaultGroupSelected = selectedDocumentGroupTreeItem()->isDefaultFolder(); - - mMainWindow->actionNewDocument->setEnabled((groupSelected || docSelected || pageSelected) && !trashSelected); - mMainWindow->actionExport->setEnabled((docSelected || pageSelected) && !trashSelected); - bool firstSceneSelected = false; - if(docSelected) - mMainWindow->actionDuplicate->setEnabled(!trashSelected); - else if(pageSelected){ - QList selection = mDocumentUI->thumbnailWidget->selectedItems(); - if(pageCount == 1) - mMainWindow->actionDuplicate->setEnabled(!trashSelected && pageCanBeDuplicated(UBApplication::boardController->pageFromSceneIndex(0))); - else{ - for(int i = 0; i < selection.count() && !firstSceneSelected; i += 1){ - if(dynamic_cast(selection.at(i))->sceneIndex() == 0){ - mMainWindow->actionDuplicate->setEnabled(!trashSelected && pageCanBeDuplicated(UBApplication::boardController->pageFromSceneIndex(0))); - firstSceneSelected = true; - } - } - if(!firstSceneSelected) - mMainWindow->actionDuplicate->setEnabled(!trashSelected); - } - } - else - mMainWindow->actionDuplicate->setEnabled(false); - - mMainWindow->actionOpen->setEnabled((docSelected || pageSelected) && !trashSelected); - mMainWindow->actionRename->setEnabled((groupSelected || docSelected) && !trashSelected && !defaultGroupSelected); - - mMainWindow->actionAddToWorkingDocument->setEnabled(pageSelected - && !(selectedDocumentProxy() == mBoardController->activeDocument()) && !trashSelected); - - bool deleteEnabled = false; - if (trashSelected) - { - if (docSelected) - deleteEnabled = true; - else if (groupSelected && selectedDocumentGroupTreeItem()) - { - if (selectedDocumentGroupTreeItem()->childCount() > 0) - deleteEnabled = true; - } - } - else - { - deleteEnabled = groupSelected || docSelected || pageSelected; - } - - if (pageSelected && (pageCount == mDocumentUI->thumbnailWidget->selectedItems().count())) - { - deleteEnabled = false; - } - - if(pageSelected && firstSceneSelected) - deleteEnabled = false; - - mMainWindow->actionDelete->setEnabled(deleteEnabled); - - if (trashSelected) - { - if (docSelected) - { - mMainWindow->actionDelete->setIcon(QIcon(":/images/toolbar/deleteDocument.png")); - mMainWindow->actionDelete->setText(tr("Delete")); - } - else - { - mMainWindow->actionDelete->setIcon(QIcon(":/images/trash.png")); - mMainWindow->actionDelete->setText(tr("Empty")); - } - } - else - { - mMainWindow->actionDelete->setIcon(QIcon(":/images/trash.png")); - mMainWindow->actionDelete->setText(tr("Trash")); - } - - mMainWindow->actionDocumentAdd->setEnabled((docSelected || pageSelected) && !trashSelected); - mMainWindow->actionImport->setEnabled(!trashSelected); - -} - - -void UBDocumentController::documentSceneChanged(UBDocumentProxy* proxy, int pSceneIndex) -{ - Q_UNUSED(pSceneIndex); - - if (proxy == selectedDocumentProxy()) - { - refreshDocumentThumbnailsView(); - } -} - - -void UBDocumentController::pageDoubleClicked(QGraphicsItem* item, int index) -{ - Q_UNUSED(item); - Q_UNUSED(index); - - bool pageSelected = (mSelectionType == Page); - bool groupSelected = (mSelectionType == Folder); - bool docSelected = (mSelectionType == Document); - - bool trashSelected = false; - if (groupSelected && selectedDocumentGroupTreeItem()) - trashSelected = selectedDocumentGroupTreeItem()->isTrashFolder(); - UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); - if ((docSelected || pageSelected) && proxyTi) - trashSelected = dynamic_cast(proxyTi->parent())->isTrashFolder(); - if (trashSelected) return; - - openSelectedItem(); -} - - -void UBDocumentController::pageClicked(QGraphicsItem* item, int index) -{ - Q_UNUSED(item); - Q_UNUSED(index); - - pageSelectionChanged(); -} - - -void UBDocumentController::closing() -{ - mIsClosing = true; - - QStringList emptyGroups; - - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - - if (item->childCount() == 0) - { - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (groupItem) - { - QString groupName = groupItem->groupName(); - if (!emptyGroups.contains(groupName) && groupName != UBSettings::documentTrashGroupName) - emptyGroups << groupName; - } - } - } - - UBSettings::settings()->setValue("Document/EmptyGroupNames", emptyGroups); - -} - -void UBDocumentController::addToDocument() -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - - if (selectedItems.count() > 0) - { - int oldActiveSceneIndex = mBoardController->activeSceneIndex(); - - QList > pageInfoList; - - foreach (QGraphicsItem* item, selectedItems) - { - UBSceneThumbnailPixmap* thumb = dynamic_cast (item); - - if (thumb && thumb->proxy()) - { - QPair pageInfo(thumb->proxy(), thumb->sceneIndex()); - pageInfoList << pageInfo; - } - } - - for (int i = 0; i < pageInfoList.length(); i++) - { - mBoardController->addScene(pageInfoList.at(i).first, pageInfoList.at(i).second, true); - } - - int newActiveSceneIndex = selectedItems.count() == mBoardController->activeDocument()->pageCount() ? 0 : oldActiveSceneIndex + 1; - mDocumentUI->thumbnailWidget->selectItemAt(newActiveSceneIndex, false); - selectDocument(mBoardController->activeDocument()); - mBoardController->activeDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(mBoardController->activeDocument()); - - UBApplication::applicationController->showBoard(); - } - - QApplication::restoreOverrideCursor(); -} - - -void UBDocumentController::addDocumentInTree(UBDocumentProxy* pDocument) -{ - QString documentName = pDocument->name(); - QString documentGroup = pDocument->groupName(); - if (documentGroup.isEmpty()) - { - documentGroup = UBSettings::defaultDocumentGroupName; - } - UBDocumentGroupTreeItem* group = 0; - if (documentGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) - { - group = mTrashTi; - } - else - { - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (groupItem->groupName() == documentGroup) - { - group = groupItem; - break; - } - } - } - - if (group == 0) - { - group = new UBDocumentGroupTreeItem(0); // deleted by the tree widget - group->setGroupName(documentGroup); - mDocumentUI->documentTreeWidget->addTopLevelItem(group); - } - - UBDocumentProxyTreeItem *ti = new UBDocumentProxyTreeItem(group, pDocument, !group->isTrashFolder()); - ti->setText(0, documentName); -} - - -void UBDocumentController::updateDocumentInTree(UBDocumentProxy* pDocument) -{ - QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); - while (*it) - { - UBDocumentProxyTreeItem* pi = dynamic_cast((*it)); - - if (pi && pi->proxy() == pDocument) - { - pi->setText(0, pDocument->name()); - break; - } - ++it; - } -} - - -QStringList UBDocumentController::allGroupNames() -{ - QStringList result; - - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - result << groupItem->groupName(); - } - - return result; -} - - -void UBDocumentController::renameSelectedItem() -{ - if (mDocumentUI->documentTreeWidget->selectedItems().count() > 0) - mDocumentUI->documentTreeWidget->editItem(mDocumentUI->documentTreeWidget->selectedItems().at(0)); -} - - -bool UBDocumentController::isOKToOpenDocument(UBDocumentProxy* proxy) -{ - //check version - QString docVersion = proxy->metaData(UBSettings::documentVersion).toString(); - - if (docVersion.isEmpty() || docVersion.startsWith("4.1") || docVersion.startsWith("4.2") - || docVersion.startsWith("4.3") || docVersion.startsWith("4.4") || docVersion.startsWith("4.5") - || docVersion.startsWith("4.6")) // TODO UB 4.7 update if necessary - { - return true; - } - else - { - if (UBApplication::mainWindow->yesNoQuestion(tr("Open Document"), - tr("The document '%1' has been generated with a newer version of Sankore (%2). By opening it, you may lose some information. Do you want to proceed?") - .arg(proxy->metaData(UBSettings::documentName).toString()) - .arg(docVersion))) - { - return true; - } - else - { - return false; - } - } -} - - -void UBDocumentController::showMessage(const QString& message, bool showSpinningWheel) -{ - int margin = UBSettings::boardMargin; - - QRect newSize = mDocumentUI->thumbnailWidget->geometry(); - - if (mMessageWindow) - { - mMessageWindow->move(margin, newSize.height() - mMessageWindow->height() - margin); - mMessageWindow->showMessage(message, showSpinningWheel); - } -} - - -void UBDocumentController::hideMessage() -{ - if (mMessageWindow) - mMessageWindow->hideMessage(); -} - - -void UBDocumentController::addImages() -{ - UBDocumentProxy* document = selectedDocumentProxy(); - - if (document) - { - QString defaultPath = UBSettings::settings()->lastImportFolderPath->get().toString(); - - QString extensions; - - foreach (QString ext, UBSettings::settings()->imageFileExtensions) - { - extensions += " *."; - extensions += ext; - } - - QStringList images = QFileDialog::getOpenFileNames(mParentWidget, tr("Add all Images to Document"), - defaultPath, tr("All Images (%1)").arg(extensions)); - - if (images.length() > 0) - { - QFileInfo firstImage(images.at(0)); - - UBSettings::settings()->lastImportFolderPath->set(QVariant(firstImage.absoluteDir().absolutePath())); - - int importedImageNumber - = UBDocumentManager::documentManager()->addImageAsPageToDocument(images, document); - - if (importedImageNumber == 0) - { - UBApplication::showMessage(tr("Selection does not contain any image files!")); - UBApplication::applicationController->showDocument(); - } - else - { - document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(document); - mDocumentThumbs = UBThumbnailAdaptor::load(selectedDocumentProxy()); - refreshDocumentThumbnailsView(); - } - } - } -} - - -void UBDocumentController::toggleDocumentToolsPalette() -{ - if (!mToolsPalette->isVisible() && !mToolsPalettePositionned) - { - mToolsPalette->adjustSizeAndPosition(); - int left = controlView()->width() - 20 - mToolsPalette->width(); - int top = (controlView()->height() - mToolsPalette->height()) / 2; - - mToolsPalette->setCustomPosition(true); - mToolsPalette->move(left, top); - - mToolsPalettePositionned = true; - } - - bool visible = mToolsPalette->isVisible(); - mToolsPalette->setVisible(!visible); -} - - -void UBDocumentController::cut() -{ - // TODO - implemented me -} - - -void UBDocumentController::copy() -{ - // TODO - implemented me -} - - -void UBDocumentController::paste() -{ - // TODO - implemented me -} - - -void UBDocumentController::focusChanged(QWidget *old, QWidget *current) -{ - Q_UNUSED(old); - - if (current == mDocumentUI->thumbnailWidget) - { - if (mDocumentUI->thumbnailWidget->selectedItems().count() > 0) - mSelectionType = Page; - else - mSelectionType = None; - } - else if (current == mDocumentUI->documentTreeWidget) - { - if (selectedDocumentProxy()) - mSelectionType = Document; - else if (selectedDocumentGroupTreeItem()) - mSelectionType = Folder; - else - mSelectionType = None; - } - else if (current == mDocumentUI->documentZoomSlider) - { - if (mDocumentUI->thumbnailWidget->selectedItems().count() > 0) - mSelectionType = Page; - else - mSelectionType = None; - } - else - { - if (old != mDocumentUI->thumbnailWidget && - old != mDocumentUI->documentTreeWidget && - old != mDocumentUI->documentZoomSlider) - { - mSelectionType = None; - } - } - - selectionChanged(); -} - -void UBDocumentController::deletePages(QList itemsToDelete) -{ - if (itemsToDelete.count() > 0) - { - QList sceneIndexes; - UBDocumentProxy* proxy = 0; - - foreach (QGraphicsItem* item, itemsToDelete) - { - UBSceneThumbnailPixmap* thumb = dynamic_cast (item); - - if (thumb) - { - proxy = thumb->proxy(); - if (proxy) - { - sceneIndexes.append(thumb->sceneIndex()); - } - } - } - - if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Page"), tr("Are you sure you want to remove %n page(s) from the selected document '%1'?", "", sceneIndexes.count()).arg(proxy->metaData(UBSettings::documentName).toString()))) - { - UBPersistenceManager::persistenceManager()->deleteDocumentScenes(proxy, sceneIndexes); - proxy->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(proxy); - - int offset = 0; - foreach(int index, sceneIndexes) - { - mDocumentThumbs.removeAt(index - offset); - offset++; - } - refreshDocumentThumbnailsView(); - - int minIndex = proxy->pageCount() - 1; - - foreach (int i, sceneIndexes) - minIndex = qMin(i, minIndex); - - mDocumentUI->thumbnailWidget->selectItemAt(minIndex); - } - } -} - -int UBDocumentController::getSelectedItemIndex() -{ - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - - if (selectedItems.count() > 0) - { - UBSceneThumbnailPixmap* thumb = dynamic_cast (selectedItems.last()); - return thumb->sceneIndex(); - } - else return -1; -} - -bool UBDocumentController::pageCanBeMovedUp(int page) -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return page >= 2; - else - return page >= 1; -} - -bool UBDocumentController::pageCanBeMovedDown(int page) -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return page != 0 && page < mCurrentDocument->pageCount() - 1; - else - return page < mCurrentDocument->pageCount() - 1; -} - -bool UBDocumentController::pageCanBeDuplicated(int page) -{ - return page != 0; -} - -bool UBDocumentController::pageCanBeDeleted(int page) -{ - return page != 0; -} - +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "UBDocumentController.h" + +#include +#include + +#include "frameworks/UBFileSystemUtils.h" +#include "frameworks/UBStringUtils.h" +#include "frameworks/UBPlatformUtils.h" + +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBDocumentManager.h" +#include "core/UBApplicationController.h" +#include "core/UBSettings.h" +#include "core/UBSetting.h" + +#include "adaptors/UBExportPDF.h" +#include "adaptors/UBThumbnailAdaptor.h" + +#include "adaptors/UBMetadataDcSubsetAdaptor.h" + +#include "board/UBBoardController.h" +#include "board/UBBoardPaletteManager.h" +#include "board/UBDrawingController.h" + + +#include "gui/UBThumbnailView.h" +#include "gui/UBDocumentTreeWidget.h" +#include "gui/UBMousePressFilter.h" +#include "gui/UBMessageWindow.h" +#include "gui/UBMainWindow.h" +#include "gui/UBDocumentToolsPalette.h" + +#include "domain/UBGraphicsScene.h" +#include "domain/UBGraphicsSvgItem.h" +#include "domain/UBGraphicsPixmapItem.h" + +#include "document/UBDocumentProxy.h" + +#include "ui_documents.h" +#include "ui_mainWindow.h" + +#include "core/memcheck.h" + +UBDocumentController::UBDocumentController(UBMainWindow* mainWindow) + : UBDocumentContainer(mainWindow->centralWidget()) + , mSelectionType(None) + , mParentWidget(mainWindow->centralWidget()) + , mBoardController(UBApplication::boardController) + , mDocumentUI(0) + , mMainWindow(mainWindow) + , mDocumentWidget(0) + , mIsClosing(false) + , mToolsPalette(0) + , mToolsPalettePositionned(false) + , mTrashTi(0) +{ + setupViews(); + setupToolbar(); + this->selectDocument(UBApplication::boardController->selectedDocument()); + connect(this, SIGNAL(exportDone()), mMainWindow, SLOT(onExportDone())); + //connect(mMainWindow->actionNewPage, SIGNAL(triggered()), this, SLOT(reloadThumbs())); + connect(this, SIGNAL(documentThumbnailsUpdated(UBDocumentContainer*)), this, SLOT(refreshDocumentThumbnailsView(UBDocumentContainer*))); +} + +//void UBDocumentController::reloadThumbs() +//{ +// UBThumbnailAdaptor::load(selectedDocumentProxy(), mDocumentThumbs); +//} + +UBDocumentController::~UBDocumentController() +{ + if (mDocumentUI) + delete mDocumentUI; +} + + +void UBDocumentController::createNewDocument() +{ + UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); + + if (group) + { + UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument(group->groupName()); + + selectDocument(document); + } +} + + +UBDocumentProxyTreeItem* UBDocumentController::findDocument(UBDocumentProxy* proxy) +{ + QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); + + while (*it) + { + UBDocumentProxyTreeItem *treeItem = dynamic_cast((*it)); + + if (treeItem && treeItem->proxy() == proxy) + return treeItem; + + ++it; + } + + return 0; +} + + +void UBDocumentController::selectDocument(UBDocumentProxy* proxy, bool setAsCurrentDocument) +{ + if (!proxy) + return; + + QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); + + mDocumentUI->documentTreeWidget->clearSelection(); + mDocumentUI->documentTreeWidget->setCurrentItem(0); + + UBDocumentProxyTreeItem* selected = 0; + + while (*it) + { + UBDocumentProxyTreeItem* pi = dynamic_cast((*it)); + + if (pi) + { + if (setAsCurrentDocument) + pi->setIcon(0, QIcon("")); + + pi->setSelected(false); + + if (pi->proxy() == proxy) + { + selected = pi; + } + } + + ++it; + } + + if (selected) + { + setDocument(proxy); + + selected->setSelected(true); + + selected->parent()->setExpanded(true); + selected->setText(0, proxy->name()); + + if (setAsCurrentDocument) + { + selected->setIcon(0, QIcon(":/images/currentDocument.png")); + if (proxy != mBoardController->selectedDocument()) + mBoardController->setActiveDocumentScene(proxy); + } + + mDocumentUI->documentTreeWidget->setCurrentItem(selected); + + mDocumentUI->documentTreeWidget->scrollToItem(selected); + + mSelectionType = Document; + } +} + + +void UBDocumentController::createNewDocumentGroup() +{ + UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0); // deleted by the tree widget + int i = 1; + QString newFolderName = tr("New Folder"); + while (allGroupNames().contains(newFolderName)) + { + newFolderName = tr("New Folder") + " " + QVariant(i++).toString(); + } + docGroupItem->setGroupName(newFolderName); + + int trashIndex = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(mTrashTi); + + mDocumentUI->documentTreeWidget->insertTopLevelItem(trashIndex, docGroupItem); + mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); + mDocumentUI->documentTreeWidget->expandItem(docGroupItem); +} + + +UBDocumentProxy* UBDocumentController::selectedDocumentProxy() +{ + UBDocumentProxyTreeItem* proxyItem = selectedDocumentProxyTreeItem(); + return proxyItem ? proxyItem->proxy() : 0; +} + + +UBDocumentProxyTreeItem* UBDocumentController::selectedDocumentProxyTreeItem() +{ + if (mDocumentUI && mDocumentUI->documentTreeWidget) + { + QList selectedItems = mDocumentUI->documentTreeWidget->selectedItems(); + + foreach (QTreeWidgetItem * item, selectedItems) + { + UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); + + if (proxyItem) + { + return proxyItem; + } + } + } + + return 0; +} + + +UBDocumentGroupTreeItem* UBDocumentController::selectedDocumentGroupTreeItem() +{ + QList selectedItems = mDocumentUI->documentTreeWidget->selectedItems(); + + foreach (QTreeWidgetItem * item, selectedItems) + { + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + + if (groupItem) + { + return groupItem; + } + else + { + UBDocumentGroupTreeItem* parent = dynamic_cast(item->parent()); + if (parent) + { + return parent; + } + } + } + + return 0; +} + + +void UBDocumentController::itemSelectionChanged() +{ + reloadThumbnails(); + + if (selectedDocumentProxy()) + mSelectionType = Document; + else if (selectedDocumentGroupTreeItem()) + mSelectionType = Folder; + else + mSelectionType = None; + + selectionChanged(); +} + + +void UBDocumentController::setupViews() +{ + + if (!mDocumentWidget) + { + mDocumentWidget = new QWidget(mMainWindow->centralWidget()); + mMainWindow->addDocumentsWidget(mDocumentWidget); + + mDocumentUI = new Ui::documents(); + + mDocumentUI->setupUi(mDocumentWidget); + + int thumbWidth = UBSettings::settings()->documentThumbnailWidth->get().toInt(); + + mDocumentUI->documentZoomSlider->setValue(thumbWidth); + mDocumentUI->thumbnailWidget->setThumbnailWidth(thumbWidth); + + connect(mDocumentUI->documentZoomSlider, SIGNAL(valueChanged(int)), this, + SLOT(documentZoomSliderValueChanged(int))); + + connect(mMainWindow->actionOpen, SIGNAL(triggered()), this, SLOT(openSelectedItem())); + connect(mMainWindow->actionNewFolder, SIGNAL(triggered()), this, SLOT(createNewDocumentGroup())); + connect(mMainWindow->actionNewDocument, SIGNAL(triggered()), this, SLOT(createNewDocument())); + + connect(mMainWindow->actionImport, SIGNAL(triggered(bool)), this, SLOT(importFile())); + + QMenu* addMenu = new QMenu(mDocumentWidget); + mAddFolderOfImagesAction = addMenu->addAction(tr("Add Folder of Images")); + mAddImagesAction = addMenu->addAction(tr("Add Images")); + mAddFileToDocumentAction = addMenu->addAction(tr("Add Pages from File")); + + connect(mAddFolderOfImagesAction, SIGNAL(triggered(bool)), this, SLOT(addFolderOfImages())); + connect(mAddFileToDocumentAction, SIGNAL(triggered(bool)), this, SLOT(addFileToDocument())); + connect(mAddImagesAction, SIGNAL(triggered(bool)), this, SLOT(addImages())); + + foreach (QWidget* menuWidget, mMainWindow->actionDocumentAdd->associatedWidgets()) + { + QToolButton *tb = qobject_cast(menuWidget); + + if (tb && !tb->menu()) + { + tb->setObjectName("ubButtonMenu"); + tb->setPopupMode(QToolButton::InstantPopup); + + QMenu* menu = new QMenu(mDocumentWidget); + + menu->addAction(mAddFolderOfImagesAction); + menu->addAction(mAddImagesAction); + menu->addAction(mAddFileToDocumentAction); + + tb->setMenu(menu); + } + } + + QMenu* exportMenu = new QMenu(mDocumentWidget); + + UBDocumentManager *documentManager = UBDocumentManager::documentManager(); + for (int i = 0; i < documentManager->supportedExportAdaptors().length(); i++) + { + UBExportAdaptor* adaptor = documentManager->supportedExportAdaptors()[i]; + QAction *currentExportAction = exportMenu->addAction(adaptor->exportName()); + currentExportAction->setData(i); + connect(currentExportAction, SIGNAL(triggered (bool)), this, SLOT(exportDocument())); + exportMenu->addAction(currentExportAction); + } + + foreach (QWidget* menuWidget, mMainWindow->actionExport->associatedWidgets()) + { + QToolButton *tb = qobject_cast(menuWidget); + + if (tb && !tb->menu()) + { + tb->setObjectName("ubButtonMenu"); + tb->setPopupMode(QToolButton::InstantPopup); + + tb->setMenu(exportMenu); + } + } + +#ifdef Q_WS_MAC + mMainWindow->actionDelete->setShortcut(QKeySequence(Qt::Key_Backspace)); +#endif + + connect(mMainWindow->actionDelete, SIGNAL(triggered()), this, SLOT(deleteSelectedItem())); + connect(mMainWindow->actionDuplicate, SIGNAL(triggered()), this, SLOT(duplicateSelectedItem())); + connect(mMainWindow->actionRename, SIGNAL(triggered()), this, SLOT(renameSelectedItem())); + connect(mMainWindow->actionAddToWorkingDocument, SIGNAL(triggered()), this, SLOT(addToDocument())); + + loadDocumentProxies(); + + mDocumentUI->documentTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); + mDocumentUI->documentTreeWidget->setDragEnabled(true); + mDocumentUI->documentTreeWidget->viewport()->setAcceptDrops(true); + mDocumentUI->documentTreeWidget->setDropIndicatorShown(true); + mDocumentUI->documentTreeWidget->setIndentation(18); // 1.5 * /resources/style/treeview-branch-closed.png width + mDocumentUI->documentTreeWidget->setDragDropMode(QAbstractItemView::InternalMove); + + connect(mDocumentUI->documentTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); + connect(mDocumentUI->documentTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(itemChanged(QTreeWidgetItem *, int))); + connect(mDocumentUI->documentTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *, int))); + + connect(mDocumentUI->thumbnailWidget, SIGNAL(sceneDropped(UBDocumentProxy*, int, int)), this, SLOT(moveSceneToIndex ( UBDocumentProxy*, int, int))); + connect(mDocumentUI->thumbnailWidget, SIGNAL(resized()), this, SLOT(thumbnailViewResized())); + connect(mDocumentUI->thumbnailWidget, SIGNAL(mouseDoubleClick(QGraphicsItem*, int)), + this, SLOT(pageDoubleClicked(QGraphicsItem*, int))); + connect(mDocumentUI->thumbnailWidget, SIGNAL(mouseClick(QGraphicsItem*, int)), + this, SLOT(pageClicked(QGraphicsItem*, int))); + + connect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), + this, SLOT(pageSelectionChanged())); + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentCreated(UBDocumentProxy*)), + this, SLOT(addDocumentInTree(UBDocumentProxy*))); + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), + this, SLOT(updateDocumentInTree(UBDocumentProxy*))); + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneCreated(UBDocumentProxy*, int)), + this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneWillBeDeleted(UBDocumentProxy*, int)), + this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); + + mDocumentUI->thumbnailWidget->setBackgroundBrush(UBSettings::documentViewLightColor); + + mMessageWindow = new UBMessageWindow(mDocumentUI->thumbnailWidget); + mMessageWindow->hide(); + + } +} + + +QWidget* UBDocumentController::controlView() +{ + return mDocumentWidget; +} + + +void UBDocumentController::setupToolbar() +{ + UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->documentToolBar, mMainWindow->actionBoard); + connect(mMainWindow->actionDocumentTools, SIGNAL(triggered()), this, SLOT(toggleDocumentToolsPalette())); +} + +void UBDocumentController::setupPalettes() +{ + + mToolsPalette = new UBDocumentToolsPalette(controlView()); + + mToolsPalette->hide(); + + bool showToolsPalette = !mToolsPalette->isEmpty(); + mMainWindow->actionDocumentTools->setVisible(showToolsPalette); + + if (showToolsPalette) + { + mMainWindow->actionDocumentTools->trigger(); + } +} + + +void UBDocumentController::show() +{ + selectDocument(mBoardController->selectedDocument()); + + selectionChanged(); + + if(!mToolsPalette) + setupPalettes(); +} + + +void UBDocumentController::hide() +{ + // NOOP +} + + +void UBDocumentController::openSelectedItem() +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + + if (selectedItems.count() > 0) + { + UBSceneThumbnailPixmap* thumb = dynamic_cast (selectedItems.last()); + + if (thumb) + { + UBDocumentProxy* proxy = thumb->proxy(); + + if (proxy && isOKToOpenDocument(proxy)) + { + UBApplication::applicationController->showBoard(); + } + } + } + else + { + UBDocumentProxy* proxy = selectedDocumentProxy(); + + if (proxy && isOKToOpenDocument(proxy)) + { + mBoardController->setActiveDocumentScene(proxy); + UBApplication::applicationController->showBoard(); + } + } + + QApplication::restoreOverrideCursor(); +} + +void UBDocumentController::duplicateSelectedItem() +{ + if (UBApplication::applicationController->displayMode() != UBApplicationController::Document) + return; + + if (mSelectionType == Page) + { + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + QList selectedSceneIndexes; + foreach (QGraphicsItem *item, selectedItems) + { + UBSceneThumbnailPixmap *thumb = dynamic_cast(item); + if (thumb) + { + UBDocumentProxy *proxy = thumb->proxy(); + + if (proxy) + { + int sceneIndex = thumb->sceneIndex(); + selectedSceneIndexes << sceneIndex; + } + } + } + if (selectedSceneIndexes.count() > 0) + { + duplicatePages(selectedSceneIndexes); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(selectedDocument()); + mDocumentUI->thumbnailWidget->selectItemAt(selectedSceneIndexes.last() + selectedSceneIndexes.size()); + } + } + else + { + UBDocumentProxy* source = selectedDocumentProxy(); + UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); + + if (source && group) + { + QString docName = source->metaData(UBSettings::documentName).toString(); + + showMessage(tr("Duplicating Document %1").arg(docName), true); + + UBDocumentProxy* duplicatedDoc = UBPersistenceManager::persistenceManager()->duplicateDocument(source); + duplicatedDoc->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(duplicatedDoc); + + selectDocument(duplicatedDoc, false); + + showMessage(tr("Document %1 copied").arg(docName), false); + } + } +} + + +void UBDocumentController::deleteSelectedItem() +{ + if (mSelectionType == Page) + { + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + + deletePages(selectedItems); + } + else + { + + UBDocumentProxyTreeItem *proxyTi = selectedDocumentProxyTreeItem(); + + UBDocumentGroupTreeItem* groupTi = selectedDocumentGroupTreeItem(); + + if (proxyTi && proxyTi->proxy() && proxyTi->parent()) + { + if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Document"), tr("Are you sure you want to remove the document '%1'?").arg(proxyTi->proxy()->metaData(UBSettings::documentName).toString()))) + { + if (proxyTi->parent() == mTrashTi) + { + int index = proxyTi->parent()->indexOfChild(proxyTi); + index --; + + if (index >= 0) + { + if (proxyTi->proxy() == mBoardController->selectedDocument()) + { + selectDocument(((UBDocumentProxyTreeItem*)proxyTi->parent()->child(index))->proxy()); + } + else + proxyTi->parent()->child(index)->setSelected(true); + } + else if (proxyTi->parent()->childCount() > 1) + { + if (proxyTi->proxy() == mBoardController->selectedDocument()) + { + selectDocument(((UBDocumentProxyTreeItem*)proxyTi->parent()->child(1))->proxy()); + } + else + proxyTi->parent()->child(1)->setSelected(true); + } + else + { + if (proxyTi->proxy() == mBoardController->selectedDocument()) + { + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if (groupItem != selectedDocumentGroupTreeItem() && groupItem->childCount() > 0) + { + selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(0))->proxy()); + break; + } + } + } + else + proxyTi->parent()->setSelected(true); + } + + proxyTi->parent()->removeChild(proxyTi); + + UBPersistenceManager::persistenceManager()->deleteDocument(proxyTi->proxy()); + + reloadThumbnails(); + } + else + { + // Move document to trash + QString oldGroupName = proxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); + proxyTi->proxy()->setMetaData(UBSettings::documentGroupName, UBSettings::trashedDocumentGroupNamePrefix + oldGroupName); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyTi->proxy()); + + proxyTi->parent()->removeChild(proxyTi); + mTrashTi->addChild(proxyTi); + proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); + } + } + } + else if (groupTi) + { + if (groupTi == mTrashTi) + { + if(UBApplication::mainWindow->yesNoQuestion(tr("Empty Trash"), tr("Are you sure you want to empty trash?"))) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QList toBeDeleted; + + for (int i = 0; i < groupTi->childCount(); i++) + { + UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); + if (proxyTi && proxyTi->proxy()) + toBeDeleted << proxyTi; + } + + UBApplication::showMessage(tr("Emptying trash")); + + for (int i = 0; i < toBeDeleted.count(); i++) + { + UBDocumentProxyTreeItem* proxyTi = toBeDeleted.at(i); + + proxyTi->parent()->removeChild(proxyTi); + UBPersistenceManager::persistenceManager()->deleteDocument(proxyTi->proxy()); + } + + UBApplication::showMessage(tr("Emptied trash")); + + QApplication::restoreOverrideCursor(); + mMainWindow->actionDelete->setEnabled(false); + } + } + else + { + if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Folder"), tr("Are you sure you want to remove the folder '%1' and all its content?").arg(groupTi->groupName()))) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + bool changeCurrentDocument = false; + for (int i = 0; i < groupTi->childCount(); i++) + { + UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); + if (proxyTi && proxyTi->proxy() && proxyTi->proxy() == mBoardController->selectedDocument()) + { + changeCurrentDocument = true; + break; + } + } + + if (changeCurrentDocument) + { + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if (groupItem != groupTi && groupItem->childCount() > 0) + { + selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(0))->proxy()); + break; + } + } + } + + QList toBeDeleted; + + for (int i = 0; i < groupTi->childCount(); i++) + { + UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); + if (proxyTi && proxyTi->proxy()) + toBeDeleted << proxyTi; + } + + for (int i = 0; i < toBeDeleted.count(); i++) + { + UBDocumentProxyTreeItem* proxyTi = toBeDeleted.at(i); + + UBApplication::showMessage(QString("Deleting %1").arg(proxyTi->proxy()->metaData(UBSettings::documentName).toString())); + // Move document to trash + QString oldGroupName = proxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); + proxyTi->proxy()->setMetaData(UBSettings::documentGroupName, UBSettings::trashedDocumentGroupNamePrefix + oldGroupName); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyTi->proxy()); + + groupTi->removeChild(proxyTi); + mTrashTi->addChild(proxyTi); + proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); + + UBApplication::showMessage(QString("%1 deleted").arg(groupTi->groupName())); + } + + // dont remove default group + if (!groupTi->isDefaultFolder()) + { + int index = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(groupTi); + + if (index >= 0) + { + mDocumentUI->documentTreeWidget->takeTopLevelItem(index); + } + } + + reloadThumbnails(); + + QApplication::restoreOverrideCursor(); + } + } + } + } +} + + +void UBDocumentController::exportDocument() +{ + QAction *currentExportAction = qobject_cast(sender()); + QVariant actionData = currentExportAction->data(); + UBExportAdaptor* selectedExportAdaptor = UBDocumentManager::documentManager()->supportedExportAdaptors()[actionData.toInt()]; + + UBDocumentProxy* proxy = selectedDocumentProxy(); + + if (proxy) + { + selectedExportAdaptor->persist(proxy); + emit exportDone(); + } + else + { + UBApplication::showMessage(tr("No document selected!")); + } +} + + +void UBDocumentController::documentZoomSliderValueChanged (int value) +{ + mDocumentUI->thumbnailWidget->setThumbnailWidth(value); + + UBSettings::settings()->documentThumbnailWidth->set(value); +} + + +void UBDocumentController::loadDocumentProxies() +{ + QList > proxies = UBPersistenceManager::persistenceManager()->documentProxies; + + QStringList emptyGroupNames = UBSettings::settings()->value("Document/EmptyGroupNames", QStringList()).toStringList(); + + mDocumentUI->documentTreeWidget->clear(); + + QMap groupNamesMap; + + UBDocumentGroupTreeItem* emptyGroupNameTi = 0; + + mTrashTi = new UBDocumentGroupTreeItem(0, false); // deleted by the tree widget + mTrashTi->setGroupName(UBSettings::documentTrashGroupName); + mTrashTi->setIcon(0, QIcon(":/images/trash.png")); + + foreach (QPointer proxy, proxies) + { + if (proxy) + { + QString docGroup = proxy->metaData(UBSettings::documentGroupName).toString(); + + bool isEmptyGroupName = false; + bool isInTrash = false; + + if (docGroup.isEmpty()) // #see https://trac.assembla.com/uniboard/ticket/426 + { + docGroup = UBSettings::defaultDocumentGroupName; + isEmptyGroupName = true; + } + else if (docGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) + { + isInTrash = true; + } + + QString docName = proxy->metaData(UBSettings::documentName).toString(); + + if (emptyGroupNames.contains(docGroup)) + emptyGroupNames.removeAll(docGroup); + + if (!groupNamesMap.contains(docGroup) && !isInTrash) + { + UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0, !isEmptyGroupName); // deleted by the tree widget + groupNamesMap.insert(docGroup, docGroupItem); + docGroupItem->setGroupName(docGroup); + + if (isEmptyGroupName) + emptyGroupNameTi = docGroupItem; + } + + UBDocumentGroupTreeItem* docGroupItem; + if (isInTrash) + docGroupItem = mTrashTi; + else + docGroupItem = groupNamesMap.value(docGroup); + + QTreeWidgetItem* docItem = new UBDocumentProxyTreeItem(docGroupItem, proxy, !isInTrash); + docItem->setText(0, docName); + + if (mBoardController->selectedDocument() == proxy) + { + mDocumentUI->documentTreeWidget->expandItem(docGroupItem); + mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); + } + } + } + + foreach (const QString emptyGroupName, emptyGroupNames) + { + UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0); // deleted by the tree widget + groupNamesMap.insert(emptyGroupName, docGroupItem); + docGroupItem->setGroupName(emptyGroupName); + } + + QList groupNamesList = groupNamesMap.keys(); + qSort(groupNamesList); + + foreach (const QString groupName, groupNamesList) + { + UBDocumentGroupTreeItem* ti = groupNamesMap.value(groupName); + + if (ti != emptyGroupNameTi) + mDocumentUI->documentTreeWidget->addTopLevelItem(ti); + } + + if (emptyGroupNameTi) + mDocumentUI->documentTreeWidget->addTopLevelItem(emptyGroupNameTi); + + mDocumentUI->documentTreeWidget->addTopLevelItem(mTrashTi); +} + + +void UBDocumentController::itemClicked(QTreeWidgetItem * item, int column ) +{ + Q_UNUSED(item); + Q_UNUSED(column); + + selectDocument(selectedDocumentProxy(), false); + itemSelectionChanged(); +} + + +void UBDocumentController::itemChanged(QTreeWidgetItem * item, int column) +{ + UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); + + disconnect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)) + , this, SLOT(updateDocumentInTree(UBDocumentProxy*))); + + if (proxyItem) + { + if (proxyItem->proxy()->metaData(UBSettings::documentName).toString() != item->text(column)) + { + proxyItem->proxy()->setMetaData(UBSettings::documentName, item->text(column)); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyItem->proxy()); + } + } + else + { + // it is a group + UBDocumentGroupTreeItem* editedGroup = dynamic_cast(item); + if (editedGroup) + { + for (int i = 0; i < item->childCount(); i++) + { + UBDocumentProxyTreeItem* childItem = dynamic_cast(item->child(i)); + + if (childItem) + { + QString groupName; + if (0 != (item->flags() & Qt::ItemIsEditable)) + { + childItem->proxy()->setMetaData(UBSettings::documentGroupName, item->text(column)); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(childItem->proxy()); + } + } + } + } + } + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), + this, SLOT(updateDocumentInTree(UBDocumentProxy*))); +} + + +void UBDocumentController::importFile() +{ + UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); + UBDocumentManager *docManager = UBDocumentManager::documentManager(); + + if (group) + { + QString defaultPath = UBSettings::settings()->lastImportFilePath->get().toString(); + QString filePath = QFileDialog::getOpenFileName(mParentWidget, tr("Open Supported File"), + defaultPath, docManager->importFileFilter()); + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QApplication::processEvents(); + QFileInfo fileInfo(filePath); + UBSettings::settings()->lastImportFilePath->set(QVariant(fileInfo.absolutePath())); + + if (filePath.length() > 0) + { + UBDocumentProxy* createdDocument = 0; + QApplication::processEvents(); + QFile selectedFile(filePath); + + QString groupName = group->groupName(); + + if (groupName == UBSettings::defaultDocumentGroupName) + groupName = ""; + + UBApplication::showMessage(tr("Importing file %1...").arg(fileInfo.baseName()), true); + + createdDocument = docManager->importFile(selectedFile, groupName); + + if (createdDocument) + { + selectDocument(createdDocument, false); + } + else + { + UBApplication::showMessage(tr("Failed to import file ... ")); + } + } + + QApplication::restoreOverrideCursor(); + } +} + +void UBDocumentController::addFolderOfImages() +{ + UBDocumentProxy* document = selectedDocumentProxy(); + + if (document) + { + QString defaultPath = UBSettings::settings()->lastImportFolderPath->get().toString(); + + QString imagesDir = QFileDialog::getExistingDirectory(mParentWidget, tr("Import all Images from Folder"), defaultPath); + QDir parentImageDir(imagesDir); + parentImageDir.cdUp(); + + UBSettings::settings()->lastImportFolderPath->set(QVariant(parentImageDir.absolutePath())); + + if (imagesDir.length() > 0) + { + QDir dir(imagesDir); + + int importedImageNumber + = UBDocumentManager::documentManager()->addImageDirToDocument(dir, document); + + if (importedImageNumber == 0) + { + UBApplication::showMessage(tr("Folder does not contain any image files!")); + UBApplication::applicationController->showDocument(); + } + else + { + document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(document); + reloadThumbnails(); + } + } + } +} + + +void UBDocumentController::addFileToDocument() +{ + UBDocumentProxy* document = selectedDocumentProxy(); + + if (document) + { + addFileToDocument(document); + reloadThumbnails(); + } +} + + +bool UBDocumentController::addFileToDocument(UBDocumentProxy* document) +{ + QString defaultPath = UBSettings::settings()->lastImportFilePath->get().toString(); + QString filePath = QFileDialog::getOpenFileName(mParentWidget, tr("Open Supported File") + , defaultPath, UBDocumentManager::documentManager()->importFileFilter()); + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QApplication::processEvents(); + + QFileInfo fileInfo(filePath); + UBSettings::settings()->lastImportFilePath->set(QVariant(fileInfo.absolutePath())); + + bool success = false; + + if (filePath.length() > 0) + { + QApplication::processEvents(); + QFile selectedFile(filePath); + + UBApplication::showMessage(tr("Importing file %1...").arg(fileInfo.baseName()), true); + + success = UBDocumentManager::documentManager()->addFileToDocument(document, selectedFile); + + if (success) + { + document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(document); + } + else + { + UBApplication::showMessage(tr("Failed to import file ... ")); + } + } + + QApplication::restoreOverrideCursor(); + + return success; +} + + +void UBDocumentController::moveSceneToIndex(UBDocumentProxy* proxy, int source, int target) +{ + UBDocumentContainer::movePageToIndex(source, target); + + proxy->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(proxy); + + mDocumentUI->thumbnailWidget->hightlightItem(target); +} + + +void UBDocumentController::thumbnailViewResized() +{ + int maxWidth = qMin(UBSettings::maxThumbnailWidth, mDocumentUI->thumbnailWidget->width()); + + mDocumentUI->documentZoomSlider->setMaximum(maxWidth); +} + + +void UBDocumentController::pageSelectionChanged() +{ + if (mIsClosing) + return; + + bool pageSelected = mDocumentUI->thumbnailWidget->selectedItems().count() > 0; + + if (pageSelected) + mSelectionType = Page; + else + mSelectionType = None; + + selectionChanged(); +} + + +void UBDocumentController::selectionChanged() +{ + if (mIsClosing) + return; + + int pageCount = -1; + + UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); + + if (proxyTi && proxyTi->proxy()) + pageCount = proxyTi->proxy()->pageCount(); + + bool pageSelected = (mSelectionType == Page); + bool groupSelected = (mSelectionType == Folder); + bool docSelected = (mSelectionType == Document); + + bool trashSelected = false; + if (groupSelected && selectedDocumentGroupTreeItem()) + trashSelected = selectedDocumentGroupTreeItem()->isTrashFolder(); + + if ((docSelected || pageSelected) && proxyTi) + trashSelected = dynamic_cast(proxyTi->parent())->isTrashFolder(); + + bool defaultGroupSelected = false; + if (groupSelected && selectedDocumentGroupTreeItem()) + defaultGroupSelected = selectedDocumentGroupTreeItem()->isDefaultFolder(); + + mMainWindow->actionNewDocument->setEnabled((groupSelected || docSelected || pageSelected) && !trashSelected); + mMainWindow->actionExport->setEnabled((docSelected || pageSelected) && !trashSelected); + bool firstSceneSelected = false; + if(docSelected) + mMainWindow->actionDuplicate->setEnabled(!trashSelected); + else if(pageSelected){ + QList selection = mDocumentUI->thumbnailWidget->selectedItems(); + if(pageCount == 1) + mMainWindow->actionDuplicate->setEnabled(!trashSelected && pageCanBeDuplicated(UBDocumentContainer::pageFromSceneIndex(0))); + else{ + for(int i = 0; i < selection.count() && !firstSceneSelected; i += 1){ + if(dynamic_cast(selection.at(i))->sceneIndex() == 0){ + mMainWindow->actionDuplicate->setEnabled(!trashSelected && pageCanBeDuplicated(UBDocumentContainer::pageFromSceneIndex(0))); + firstSceneSelected = true; + } + } + if(!firstSceneSelected) + mMainWindow->actionDuplicate->setEnabled(!trashSelected); + } + } + else + mMainWindow->actionDuplicate->setEnabled(false); + + mMainWindow->actionOpen->setEnabled((docSelected || pageSelected) && !trashSelected); + mMainWindow->actionRename->setEnabled((groupSelected || docSelected) && !trashSelected && !defaultGroupSelected); + + mMainWindow->actionAddToWorkingDocument->setEnabled(pageSelected + && !(selectedDocumentProxy() == mBoardController->selectedDocument()) && !trashSelected); + + bool deleteEnabled = false; + if (trashSelected) + { + if (docSelected) + deleteEnabled = true; + else if (groupSelected && selectedDocumentGroupTreeItem()) + { + if (selectedDocumentGroupTreeItem()->childCount() > 0) + deleteEnabled = true; + } + } + else + { + deleteEnabled = groupSelected || docSelected || pageSelected; + } + + if (pageSelected && (pageCount == mDocumentUI->thumbnailWidget->selectedItems().count())) + { + deleteEnabled = false; + } + + if(pageSelected && firstSceneSelected) + deleteEnabled = false; + + mMainWindow->actionDelete->setEnabled(deleteEnabled); + + if (trashSelected) + { + if (docSelected) + { + mMainWindow->actionDelete->setIcon(QIcon(":/images/toolbar/deleteDocument.png")); + mMainWindow->actionDelete->setText(tr("Delete")); + } + else + { + mMainWindow->actionDelete->setIcon(QIcon(":/images/trash.png")); + mMainWindow->actionDelete->setText(tr("Empty")); + } + } + else + { + mMainWindow->actionDelete->setIcon(QIcon(":/images/trash.png")); + mMainWindow->actionDelete->setText(tr("Trash")); + } + + mMainWindow->actionDocumentAdd->setEnabled((docSelected || pageSelected) && !trashSelected); + mMainWindow->actionImport->setEnabled(!trashSelected); + +} + + +void UBDocumentController::documentSceneChanged(UBDocumentProxy* proxy, int pSceneIndex) +{ + Q_UNUSED(pSceneIndex); + + if (proxy == selectedDocumentProxy()) + { + reloadThumbnails(); + } +} + + +void UBDocumentController::pageDoubleClicked(QGraphicsItem* item, int index) +{ + Q_UNUSED(item); + Q_UNUSED(index); + + bool pageSelected = (mSelectionType == Page); + bool groupSelected = (mSelectionType == Folder); + bool docSelected = (mSelectionType == Document); + + bool trashSelected = false; + if (groupSelected && selectedDocumentGroupTreeItem()) + trashSelected = selectedDocumentGroupTreeItem()->isTrashFolder(); + UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); + if ((docSelected || pageSelected) && proxyTi) + trashSelected = dynamic_cast(proxyTi->parent())->isTrashFolder(); + if (trashSelected) return; + + openSelectedItem(); +} + + +void UBDocumentController::pageClicked(QGraphicsItem* item, int index) +{ + Q_UNUSED(item); + Q_UNUSED(index); + + pageSelectionChanged(); +} + + +void UBDocumentController::closing() +{ + mIsClosing = true; + + QStringList emptyGroups; + + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + + if (item->childCount() == 0) + { + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if (groupItem) + { + QString groupName = groupItem->groupName(); + if (!emptyGroups.contains(groupName) && groupName != UBSettings::documentTrashGroupName) + emptyGroups << groupName; + } + } + } + + UBSettings::settings()->setValue("Document/EmptyGroupNames", emptyGroups); + +} + +void UBDocumentController::addToDocument() +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + + if (selectedItems.count() > 0) + { + int oldActiveSceneIndex = mBoardController->activeSceneIndex(); + + QList > pageInfoList; + + foreach (QGraphicsItem* item, selectedItems) + { + UBSceneThumbnailPixmap* thumb = dynamic_cast (item); + + if (thumb && thumb->proxy()) + { + QPair pageInfo(thumb->proxy(), thumb->sceneIndex()); + pageInfoList << pageInfo; + } + } + + for (int i = 0; i < pageInfoList.length(); i++) + { + mBoardController->addScene(pageInfoList.at(i).first, pageInfoList.at(i).second, true); + } + + int newActiveSceneIndex = selectedItems.count() == mBoardController->selectedDocument()->pageCount() ? 0 : oldActiveSceneIndex + 1; + mDocumentUI->thumbnailWidget->selectItemAt(newActiveSceneIndex, false); + selectDocument(mBoardController->selectedDocument()); + mBoardController->selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(mBoardController->selectedDocument()); + + UBApplication::applicationController->showBoard(); + } + + QApplication::restoreOverrideCursor(); +} + + +void UBDocumentController::addDocumentInTree(UBDocumentProxy* pDocument) +{ + QString documentName = pDocument->name(); + QString documentGroup = pDocument->groupName(); + if (documentGroup.isEmpty()) + { + documentGroup = UBSettings::defaultDocumentGroupName; + } + UBDocumentGroupTreeItem* group = 0; + if (documentGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) + { + group = mTrashTi; + } + else + { + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if (groupItem->groupName() == documentGroup) + { + group = groupItem; + break; + } + } + } + + if (group == 0) + { + group = new UBDocumentGroupTreeItem(0); // deleted by the tree widget + group->setGroupName(documentGroup); + mDocumentUI->documentTreeWidget->addTopLevelItem(group); + } + + UBDocumentProxyTreeItem *ti = new UBDocumentProxyTreeItem(group, pDocument, !group->isTrashFolder()); + ti->setText(0, documentName); +} + + +void UBDocumentController::updateDocumentInTree(UBDocumentProxy* pDocument) +{ + QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); + while (*it) + { + UBDocumentProxyTreeItem* pi = dynamic_cast((*it)); + + if (pi && pi->proxy() == pDocument) + { + pi->setText(0, pDocument->name()); + break; + } + ++it; + } +} + + +QStringList UBDocumentController::allGroupNames() +{ + QStringList result; + + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + result << groupItem->groupName(); + } + + return result; +} + + +void UBDocumentController::renameSelectedItem() +{ + if (mDocumentUI->documentTreeWidget->selectedItems().count() > 0) + mDocumentUI->documentTreeWidget->editItem(mDocumentUI->documentTreeWidget->selectedItems().at(0)); +} + + +bool UBDocumentController::isOKToOpenDocument(UBDocumentProxy* proxy) +{ + //check version + QString docVersion = proxy->metaData(UBSettings::documentVersion).toString(); + + if (docVersion.isEmpty() || docVersion.startsWith("4.1") || docVersion.startsWith("4.2") + || docVersion.startsWith("4.3") || docVersion.startsWith("4.4") || docVersion.startsWith("4.5") + || docVersion.startsWith("4.6")) // TODO UB 4.7 update if necessary + { + return true; + } + else + { + if (UBApplication::mainWindow->yesNoQuestion(tr("Open Document"), + tr("The document '%1' has been generated with a newer version of Sankore (%2). By opening it, you may lose some information. Do you want to proceed?") + .arg(proxy->metaData(UBSettings::documentName).toString()) + .arg(docVersion))) + { + return true; + } + else + { + return false; + } + } +} + + +void UBDocumentController::showMessage(const QString& message, bool showSpinningWheel) +{ + int margin = UBSettings::boardMargin; + + QRect newSize = mDocumentUI->thumbnailWidget->geometry(); + + if (mMessageWindow) + { + mMessageWindow->move(margin, newSize.height() - mMessageWindow->height() - margin); + mMessageWindow->showMessage(message, showSpinningWheel); + } +} + + +void UBDocumentController::hideMessage() +{ + if (mMessageWindow) + mMessageWindow->hideMessage(); +} + + +void UBDocumentController::addImages() +{ + UBDocumentProxy* document = selectedDocumentProxy(); + + if (document) + { + QString defaultPath = UBSettings::settings()->lastImportFolderPath->get().toString(); + + QString extensions; + + foreach (QString ext, UBSettings::settings()->imageFileExtensions) + { + extensions += " *."; + extensions += ext; + } + + QStringList images = QFileDialog::getOpenFileNames(mParentWidget, tr("Add all Images to Document"), + defaultPath, tr("All Images (%1)").arg(extensions)); + + if (images.length() > 0) + { + QFileInfo firstImage(images.at(0)); + + UBSettings::settings()->lastImportFolderPath->set(QVariant(firstImage.absoluteDir().absolutePath())); + + int importedImageNumber + = UBDocumentManager::documentManager()->addImageAsPageToDocument(images, document); + + if (importedImageNumber == 0) + { + UBApplication::showMessage(tr("Selection does not contain any image files!")); + UBApplication::applicationController->showDocument(); + } + else + { + document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(document); + reloadThumbnails(); + } + } + } +} + + +void UBDocumentController::toggleDocumentToolsPalette() +{ + if (!mToolsPalette->isVisible() && !mToolsPalettePositionned) + { + mToolsPalette->adjustSizeAndPosition(); + int left = controlView()->width() - 20 - mToolsPalette->width(); + int top = (controlView()->height() - mToolsPalette->height()) / 2; + + mToolsPalette->setCustomPosition(true); + mToolsPalette->move(left, top); + + mToolsPalettePositionned = true; + } + + bool visible = mToolsPalette->isVisible(); + mToolsPalette->setVisible(!visible); +} + + +void UBDocumentController::cut() +{ + // TODO - implemented me +} + + +void UBDocumentController::copy() +{ + // TODO - implemented me +} + + +void UBDocumentController::paste() +{ + // TODO - implemented me +} + + +void UBDocumentController::focusChanged(QWidget *old, QWidget *current) +{ + Q_UNUSED(old); + + if (current == mDocumentUI->thumbnailWidget) + { + if (mDocumentUI->thumbnailWidget->selectedItems().count() > 0) + mSelectionType = Page; + else + mSelectionType = None; + } + else if (current == mDocumentUI->documentTreeWidget) + { + if (selectedDocumentProxy()) + mSelectionType = Document; + else if (selectedDocumentGroupTreeItem()) + mSelectionType = Folder; + else + mSelectionType = None; + } + else if (current == mDocumentUI->documentZoomSlider) + { + if (mDocumentUI->thumbnailWidget->selectedItems().count() > 0) + mSelectionType = Page; + else + mSelectionType = None; + } + else + { + if (old != mDocumentUI->thumbnailWidget && + old != mDocumentUI->documentTreeWidget && + old != mDocumentUI->documentZoomSlider) + { + mSelectionType = None; + } + } + + selectionChanged(); +} + +void UBDocumentController::deletePages(QList itemsToDelete) +{ + if (itemsToDelete.count() > 0) + { + QList sceneIndexes; + UBDocumentProxy* proxy = 0; + + foreach (QGraphicsItem* item, itemsToDelete) + { + UBSceneThumbnailPixmap* thumb = dynamic_cast (item); + + if (thumb) + { + proxy = thumb->proxy(); + if (proxy) + { + sceneIndexes.append(thumb->sceneIndex()); + } + } + } + + if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Page"), tr("Are you sure you want to remove %n page(s) from the selected document '%1'?", "", sceneIndexes.count()).arg(proxy->metaData(UBSettings::documentName).toString()))) + { + UBDocumentContainer::deletePages(sceneIndexes); + + proxy->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(proxy); + + int minIndex = proxy->pageCount() - 1; + foreach (int i, sceneIndexes) + minIndex = qMin(i, minIndex); + + mDocumentUI->thumbnailWidget->selectItemAt(minIndex); + } + } +} + +int UBDocumentController::getSelectedItemIndex() +{ + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + + if (selectedItems.count() > 0) + { + UBSceneThumbnailPixmap* thumb = dynamic_cast (selectedItems.last()); + return thumb->sceneIndex(); + } + else return -1; +} + +bool UBDocumentController::pageCanBeMovedUp(int page) +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return page >= 2; + else + return page >= 1; +} + +bool UBDocumentController::pageCanBeMovedDown(int page) +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return page != 0 && page < selectedDocument()->pageCount() - 1; + else + return page < selectedDocument()->pageCount() - 1; +} + +bool UBDocumentController::pageCanBeDuplicated(int page) +{ + return page != 0; +} + +bool UBDocumentController::pageCanBeDeleted(int page) +{ + return page != 0; +} + +void UBDocumentController::refreshDocumentThumbnailsView(UBDocumentContainer*) +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + QList items; + QList itemsPath; + + UBDocumentProxy *proxy = selectedDocumentProxy(); + QGraphicsPixmapItem *selection = 0; + + QStringList labels; + + if (proxy) + { + setDocument(proxy); + + for (int i = 0; i < selectedDocument()->pageCount(); i++) + { + const QPixmap* pix = pageAt(i); + QGraphicsPixmapItem *pixmapItem = new UBSceneThumbnailPixmap(*pix, proxy, i); // deleted by the tree widget + + if (proxy == mBoardController->selectedDocument() && mBoardController->activeSceneIndex() == i) + { + selection = pixmapItem; + } + + items << pixmapItem; + labels << tr("Page %1").arg(pageFromSceneIndex(i)); + + itemsPath.append(QUrl::fromLocalFile(proxy->persistencePath() + QString("/pages/%1").arg(UBDocumentContainer::pageFromSceneIndex(i)))); + } + } + + mDocumentUI->thumbnailWidget->setGraphicsItems(items, itemsPath, labels, UBApplication::mimeTypeUniboardPage); + + UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); + if (proxyTi && (proxyTi->parent() == mTrashTi)) + mDocumentUI->thumbnailWidget->setDragEnabled(false); + else + mDocumentUI->thumbnailWidget->setDragEnabled(true); + + mDocumentUI->thumbnailWidget->ensureVisible(0, 0, 10, 10); + + if (selection) { + disconnect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); + UBSceneThumbnailPixmap *currentScene = dynamic_cast(selection); + if (currentScene) + mDocumentUI->thumbnailWidget->hightlightItem(currentScene->sceneIndex()); + connect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); + } + + //emit refreshThumbnails(); + QApplication::restoreOverrideCursor(); +} diff --git a/src/document/UBDocumentController.h b/src/document/UBDocumentController.h index 57a94669..4d58b87c 100644 --- a/src/document/UBDocumentController.h +++ b/src/document/UBDocumentController.h @@ -1,145 +1,142 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef UBDOCUMENTCONTROLLER_H_ -#define UBDOCUMENTCONTROLLER_H_ - -#include - -namespace Ui -{ - class documents; -} - -#include "gui/UBMessageWindow.h" - -class UBGraphicsScene; -class QDialog; -class UBDocumentProxy; -class UBBoardController; -class UBThumbnailsScene; -class UBDocumentGroupTreeItem; -class UBDocumentProxyTreeItem; -class UBMainWindow; -class UBDocumentToolsPalette; - -class UBDocumentController : public QObject -{ - Q_OBJECT; - - public: - UBDocumentController(UBMainWindow* mainWindow); - virtual ~UBDocumentController(); - - void closing(); - QWidget* controlView(); - UBDocumentProxyTreeItem* findDocument(UBDocumentProxy* proxy); - bool addFileToDocument(UBDocumentProxy* document); - UBDocumentProxy* getCurrentDocument() { return mCurrentDocument; }; - void deletePages(QList itemsToDelete); - int getSelectedItemIndex(); - - bool pageCanBeMovedUp(int page); - bool pageCanBeMovedDown(int page); - bool pageCanBeDuplicated(int page); - bool pageCanBeDeleted(int page); - - signals: - void refreshThumbnails(); - void exportDone(); - void movedToIndex(int index); - - public slots: - void createNewDocument(); - void createNewDocumentGroup(); - void deleteSelectedItem(); - void renameSelectedItem(); - void openSelectedItem(); - void duplicateSelectedItem(); - void importFile(); - void moveSceneToIndex(UBDocumentProxy* proxy, int source, int target); - void selectDocument(UBDocumentProxy* proxy, bool setAsCurrentDocument = true); - void show(); - void hide(); - void showMessage(const QString& message, bool showSpinningWheel); - void hideMessage(); - void toggleDocumentToolsPalette(); - void cut(); - void copy(); - void paste(); - void focusChanged(QWidget *old, QWidget *current); - void reloadThumbs(); - - protected: - virtual void setupViews(); - virtual void setupToolbar(); - void setupPalettes(); - bool isOKToOpenDocument(UBDocumentProxy* proxy); - UBGraphicsScene* activeScene(); - UBDocumentProxy* selectedDocumentProxy(); - UBDocumentProxyTreeItem* selectedDocumentProxyTreeItem(); - UBDocumentGroupTreeItem* selectedDocumentGroupTreeItem(); - QStringList allGroupNames(); - - enum LastSelectedElementType - { - None = 0, Folder, Document, Page - }; - - LastSelectedElementType mSelectionType; - - private: - QWidget *mParentWidget; - UBBoardController *mBoardController; - Ui::documents* mDocumentUI; - UBMainWindow* mMainWindow; - QWidget *mDocumentWidget; - QPointer mMessageWindow; - QAction* mAddFolderOfImagesAction; - QAction* mAddFileToDocumentAction; - QAction* mAddImagesAction; - bool mIsClosing; - UBDocumentToolsPalette *mToolsPalette; - bool mToolsPalettePositionned; - UBDocumentGroupTreeItem* mTrashTi; - UBDocumentProxy* mCurrentDocument; - QList mDocumentThumbs; - - private slots: - void documentZoomSliderValueChanged (int value); - void loadDocumentProxies(); - void itemSelectionChanged(); - void refreshDocumentThumbnailsView(); - void exportDocument(); - void itemChanged(QTreeWidgetItem * item, int column); - void thumbnailViewResized(); - void pageSelectionChanged(); - void selectionChanged(); - void documentSceneChanged(UBDocumentProxy* proxy, int pSceneIndex); - void pageDoubleClicked(QGraphicsItem* item, int index); - void pageClicked(QGraphicsItem* item, int index); - void itemClicked(QTreeWidgetItem * item, int column ); - void addToDocument(); - void addDocumentInTree(UBDocumentProxy* pDocument); - void updateDocumentInTree(UBDocumentProxy* pDocument); - void addFolderOfImages(); - void addFileToDocument(); - void addImages(); - -}; - - - -#endif /* UBDOCUMENTCONTROLLER_H_ */ +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef UBDOCUMENTCONTROLLER_H_ +#define UBDOCUMENTCONTROLLER_H_ + +#include +#include "document/UBDocumentContainer.h" + +namespace Ui +{ + class documents; +} + +#include "gui/UBMessageWindow.h" + +class UBGraphicsScene; +class QDialog; +class UBDocumentProxy; +class UBBoardController; +class UBThumbnailsScene; +class UBDocumentGroupTreeItem; +class UBDocumentProxyTreeItem; +class UBMainWindow; +class UBDocumentToolsPalette; + +class UBDocumentController : public UBDocumentContainer +{ + Q_OBJECT; + + public: + UBDocumentController(UBMainWindow* mainWindow); + virtual ~UBDocumentController(); + + void closing(); + QWidget* controlView(); + UBDocumentProxyTreeItem* findDocument(UBDocumentProxy* proxy); + bool addFileToDocument(UBDocumentProxy* document); + void deletePages(QList itemsToDelete); + int getSelectedItemIndex(); + + bool pageCanBeMovedUp(int page); + bool pageCanBeMovedDown(int page); + bool pageCanBeDuplicated(int page); + bool pageCanBeDeleted(int page); + + signals: + //void refreshThumbnails(); + void exportDone(); + //void movedToIndex(int index); + + public slots: + void createNewDocument(); + void createNewDocumentGroup(); + void deleteSelectedItem(); + void renameSelectedItem(); + void openSelectedItem(); + void duplicateSelectedItem(); + void importFile(); + void moveSceneToIndex(UBDocumentProxy* proxy, int source, int target); + void selectDocument(UBDocumentProxy* proxy, bool setAsCurrentDocument = true); + void show(); + void hide(); + void showMessage(const QString& message, bool showSpinningWheel); + void hideMessage(); + void toggleDocumentToolsPalette(); + void cut(); + void copy(); + void paste(); + void focusChanged(QWidget *old, QWidget *current); + //void reloadThumbs(); + + protected: + virtual void setupViews(); + virtual void setupToolbar(); + void setupPalettes(); + bool isOKToOpenDocument(UBDocumentProxy* proxy); + UBDocumentProxy* selectedDocumentProxy(); + UBDocumentProxyTreeItem* selectedDocumentProxyTreeItem(); + UBDocumentGroupTreeItem* selectedDocumentGroupTreeItem(); + QStringList allGroupNames(); + + enum LastSelectedElementType + { + None = 0, Folder, Document, Page + }; + + LastSelectedElementType mSelectionType; + + private: + QWidget *mParentWidget; + UBBoardController *mBoardController; + Ui::documents* mDocumentUI; + UBMainWindow* mMainWindow; + QWidget *mDocumentWidget; + QPointer mMessageWindow; + QAction* mAddFolderOfImagesAction; + QAction* mAddFileToDocumentAction; + QAction* mAddImagesAction; + bool mIsClosing; + UBDocumentToolsPalette *mToolsPalette; + bool mToolsPalettePositionned; + UBDocumentGroupTreeItem* mTrashTi; + + private slots: + void documentZoomSliderValueChanged (int value); + void loadDocumentProxies(); + void itemSelectionChanged(); + void exportDocument(); + void itemChanged(QTreeWidgetItem * item, int column); + void thumbnailViewResized(); + void pageSelectionChanged(); + void selectionChanged(); + void documentSceneChanged(UBDocumentProxy* proxy, int pSceneIndex); + void pageDoubleClicked(QGraphicsItem* item, int index); + void pageClicked(QGraphicsItem* item, int index); + void itemClicked(QTreeWidgetItem * item, int column ); + void addToDocument(); + void addDocumentInTree(UBDocumentProxy* pDocument); + void updateDocumentInTree(UBDocumentProxy* pDocument); + void addFolderOfImages(); + void addFileToDocument(); + void addImages(); + + void refreshDocumentThumbnailsView(UBDocumentContainer* source); +}; + + + +#endif /* UBDOCUMENTCONTROLLER_H_ */ diff --git a/src/document/UBDocumentProxy.cpp b/src/document/UBDocumentProxy.cpp index e86a78fa..04119a4a 100644 --- a/src/document/UBDocumentProxy.cpp +++ b/src/document/UBDocumentProxy.cpp @@ -1,232 +1,232 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "UBDocumentProxy.h" - -#include "frameworks/UBStringUtils.h" - -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBSettings.h" -#include "core/UBDocumentManager.h" - -#include "core/memcheck.h" - -UBDocumentProxy::UBDocumentProxy() - : mPageCount(0) -{ - init(); -} - - -UBDocumentProxy::UBDocumentProxy(const QString& pPersistancePath) - : mPageCount(0) -{ - init(); - setPersistencePath(pPersistancePath); -} - - -void UBDocumentProxy::init() -{ - setMetaData(UBSettings::documentGroupName, ""); - - QDateTime now = QDateTime::currentDateTime(); - setMetaData(UBSettings::documentName, now.toString(Qt::SystemLocaleShortDate)); - - setUuid(QUuid::createUuid()); - - setDefaultDocumentSize(UBSettings::settings()->pageSize->get().toSize()); - - //teacherGuide metadata - setMetaData(UBSettings::sessionTitle,""); - setMetaData(UBSettings::sessionAuthors,""); - setMetaData(UBSettings::sessionObjectives,""); - setMetaData(UBSettings::sessionKeywords,""); - setMetaData(UBSettings::sessionGradeLevel,""); - setMetaData(UBSettings::sessionSubjects,""); - setMetaData(UBSettings::sessionType,""); - setMetaData(UBSettings::sessionLicence,""); -} - - -UBDocumentProxy::~UBDocumentProxy() -{ - // NOOP -} - - -int UBDocumentProxy::pageCount() -{ - return mPageCount; -} - - -void UBDocumentProxy::setPageCount(int pPageCount) -{ - mPageCount = pPageCount; -} - - -int UBDocumentProxy::incPageCount() -{ - if (mPageCount <= 0) - { - mPageCount = 1; - } - else - { - mPageCount++; - } - - return mPageCount; - -} - - -int UBDocumentProxy::decPageCount() -{ - mPageCount --; - - if (mPageCount < 0) - { - mPageCount = 0; - } - - return mPageCount; -} - -QString UBDocumentProxy::persistencePath() const -{ - return mPersistencePath; -} - -void UBDocumentProxy::setPersistencePath(const QString& pPersistencePath) -{ - if (pPersistencePath != mPersistencePath) - { - mIsModified = true; - mPersistencePath = pPersistencePath; - } -} - -void UBDocumentProxy::setMetaData(const QString& pKey, const QVariant& pValue) -{ - if (mMetaDatas.contains(pKey) && mMetaDatas.value(pKey) == pValue) - return; - else - { - mIsModified = true; - mMetaDatas.insert(pKey, pValue); - if (pKey == UBSettings::documentUpdatedAt) - { - UBDocumentManager *documentManager = UBDocumentManager::documentManager(); - if (documentManager) - documentManager->emitDocumentUpdated(this); - } - } -} - -QVariant UBDocumentProxy::metaData(const QString& pKey) const -{ - if (mMetaDatas.contains(pKey)) - { - return mMetaDatas.value(pKey); - } - else - { - qDebug() << "Unknown metadata key" << pKey; - return QString(""); // failsafe - } -} - -QHash UBDocumentProxy::metaDatas() const -{ - return mMetaDatas; -} - -QString UBDocumentProxy::name() const -{ - return metaData(UBSettings::documentName).toString(); -} - -QString UBDocumentProxy::groupName() const -{ - return metaData(UBSettings::documentGroupName).toString(); -} - -QSize UBDocumentProxy::defaultDocumentSize() const -{ - if (mMetaDatas.contains(UBSettings::documentSize)) - return metaData(UBSettings::documentSize).toSize(); - else - return UBSettings::settings()->pageSize->get().toSize(); -} - -void UBDocumentProxy::setDefaultDocumentSize(QSize pSize) -{ - if (defaultDocumentSize() != pSize) - { - setMetaData(UBSettings::documentSize, QVariant(pSize)); - emit defaultDocumentSizeChanged(); - - mIsModified = true; - } -} - -void UBDocumentProxy::setDefaultDocumentSize(int pWidth, int pHeight) -{ - setDefaultDocumentSize(QSize(pWidth, pHeight)); -} - - -QUuid UBDocumentProxy::uuid() const -{ - QString id = metaData(UBSettings::documentIdentifer).toString(); - QString sUuid = id.replace(UBSettings::uniboardDocumentNamespaceUri + "/", ""); - - return QUuid(sUuid); -} - -void UBDocumentProxy::setUuid(const QUuid& uuid) -{ - setMetaData(UBSettings::documentIdentifer, - UBSettings::uniboardDocumentNamespaceUri + "/" + UBStringUtils::toCanonicalUuid(uuid)); -} - - -QDateTime UBDocumentProxy::documentDate() -{ - if(mMetaDatas.contains(UBSettings::documentDate)) - return UBStringUtils::fromUtcIsoDate(metaData(UBSettings::documentDate).toString()); - return QDateTime::currentDateTime(); -} - -QDateTime UBDocumentProxy::lastUpdate() -{ - if(mMetaDatas.contains(UBSettings::documentUpdatedAt)) - return UBStringUtils::fromUtcIsoDate(metaData(UBSettings::documentUpdatedAt).toString()); - return QDateTime().currentDateTime(); -} - -bool UBDocumentProxy::isModified() const -{ - return mIsModified; -} - - - - - +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "UBDocumentProxy.h" + +#include "frameworks/UBStringUtils.h" + +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBSettings.h" +#include "core/UBDocumentManager.h" + +#include "core/memcheck.h" + +UBDocumentProxy::UBDocumentProxy() + : mPageCount(0) +{ + init(); +} + + +UBDocumentProxy::UBDocumentProxy(const QString& pPersistancePath) + : mPageCount(0) +{ + init(); + setPersistencePath(pPersistancePath); +} + + +void UBDocumentProxy::init() +{ + setMetaData(UBSettings::documentGroupName, ""); + + QDateTime now = QDateTime::currentDateTime(); + setMetaData(UBSettings::documentName, now.toString(Qt::SystemLocaleShortDate)); + + setUuid(QUuid::createUuid()); + + setDefaultDocumentSize(UBSettings::settings()->pageSize->get().toSize()); + + //teacherGuide metadata + setMetaData(UBSettings::sessionTitle,""); + setMetaData(UBSettings::sessionAuthors,""); + setMetaData(UBSettings::sessionObjectives,""); + setMetaData(UBSettings::sessionKeywords,""); + setMetaData(UBSettings::sessionGradeLevel,""); + setMetaData(UBSettings::sessionSubjects,""); + setMetaData(UBSettings::sessionType,""); + setMetaData(UBSettings::sessionLicence,""); +} + + +UBDocumentProxy::~UBDocumentProxy() +{ + // NOOP +} + + +int UBDocumentProxy::pageCount() +{ + return mPageCount; +} + + +void UBDocumentProxy::setPageCount(int pPageCount) +{ + mPageCount = pPageCount; +} + + +int UBDocumentProxy::incPageCount() +{ + if (mPageCount <= 0) + { + mPageCount = 1; + } + else + { + mPageCount++; + } + + return mPageCount; + +} + + +int UBDocumentProxy::decPageCount() +{ + mPageCount --; + + if (mPageCount < 0) + { + mPageCount = 0; + } + + return mPageCount; +} + +QString UBDocumentProxy::persistencePath() const +{ + return mPersistencePath; +} + +void UBDocumentProxy::setPersistencePath(const QString& pPersistencePath) +{ + if (pPersistencePath != mPersistencePath) + { + mIsModified = true; + mPersistencePath = pPersistencePath; + } +} + +void UBDocumentProxy::setMetaData(const QString& pKey, const QVariant& pValue) +{ + if (mMetaDatas.contains(pKey) && mMetaDatas.value(pKey) == pValue) + return; + else + { + mIsModified = true; + mMetaDatas.insert(pKey, pValue); + if (pKey == UBSettings::documentUpdatedAt) + { + UBDocumentManager *documentManager = UBDocumentManager::documentManager(); + if (documentManager) + documentManager->emitDocumentUpdated(this); + } + } +} + +QVariant UBDocumentProxy::metaData(const QString& pKey) const +{ + if (mMetaDatas.contains(pKey)) + { + return mMetaDatas.value(pKey); + } + else + { + qDebug() << "Unknown metadata key" << pKey; + return QString(""); // failsafe + } +} + +QHash UBDocumentProxy::metaDatas() const +{ + return mMetaDatas; +} + +QString UBDocumentProxy::name() const +{ + return metaData(UBSettings::documentName).toString(); +} + +QString UBDocumentProxy::groupName() const +{ + return metaData(UBSettings::documentGroupName).toString(); +} + +QSize UBDocumentProxy::defaultDocumentSize() const +{ + if (mMetaDatas.contains(UBSettings::documentSize)) + return metaData(UBSettings::documentSize).toSize(); + else + return UBSettings::settings()->pageSize->get().toSize(); +} + +void UBDocumentProxy::setDefaultDocumentSize(QSize pSize) +{ + if (defaultDocumentSize() != pSize) + { + setMetaData(UBSettings::documentSize, QVariant(pSize)); + emit defaultDocumentSizeChanged(); + + mIsModified = true; + } +} + +void UBDocumentProxy::setDefaultDocumentSize(int pWidth, int pHeight) +{ + setDefaultDocumentSize(QSize(pWidth, pHeight)); +} + + +QUuid UBDocumentProxy::uuid() const +{ + QString id = metaData(UBSettings::documentIdentifer).toString(); + QString sUuid = id.replace(UBSettings::uniboardDocumentNamespaceUri + "/", ""); + + return QUuid(sUuid); +} + +void UBDocumentProxy::setUuid(const QUuid& uuid) +{ + setMetaData(UBSettings::documentIdentifer, + UBSettings::uniboardDocumentNamespaceUri + "/" + UBStringUtils::toCanonicalUuid(uuid)); +} + + +QDateTime UBDocumentProxy::documentDate() +{ + if(mMetaDatas.contains(UBSettings::documentDate)) + return UBStringUtils::fromUtcIsoDate(metaData(UBSettings::documentDate).toString()); + return QDateTime::currentDateTime(); +} + +QDateTime UBDocumentProxy::lastUpdate() +{ + if(mMetaDatas.contains(UBSettings::documentUpdatedAt)) + return UBStringUtils::fromUtcIsoDate(metaData(UBSettings::documentUpdatedAt).toString()); + return QDateTime().currentDateTime(); +} + +bool UBDocumentProxy::isModified() const +{ + return mIsModified; +} + + + + + diff --git a/src/document/UBDocumentProxy.h b/src/document/UBDocumentProxy.h index ce9da0ee..330a63fa 100644 --- a/src/document/UBDocumentProxy.h +++ b/src/document/UBDocumentProxy.h @@ -1,95 +1,99 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef UBDOCUMENTPROXY_H_ -#define UBDOCUMENTPROXY_H_ - -#include - -#include "frameworks/UBStringUtils.h" - -#include "core/UBSettings.h" - -class UBGraphicsScene; - -class UBDocumentProxy : public QObject -{ - Q_OBJECT; - - public: - - UBDocumentProxy(); - UBDocumentProxy(const QString& pPersistencePath); - - virtual ~UBDocumentProxy(); - - QString persistencePath() const; - - void setPersistencePath(const QString& pPersistencePath); - - void setMetaData(const QString& pKey , const QVariant& pValue); - QVariant metaData(const QString& pKey) const; - QHash metaDatas() const; - - QString name() const; - QString groupName() const; - QDateTime documentDate(); - - QDateTime lastUpdate(); - - - QSize defaultDocumentSize() const; - void setDefaultDocumentSize(QSize pSize); - void setDefaultDocumentSize(int pWidth, int pHeight); - - QUuid uuid() const; - void setUuid(const QUuid& uuid); - - bool isModified() const; - - int pageCount(); - void setPageCount(int pPageCount); - int incPageCount(); - int decPageCount(); - - signals: - void defaultDocumentSizeChanged(); - - private: - - void init(); - - QString mPersistencePath; - - QHash mMetaDatas; - - bool mIsModified; - - int mPageCount; - -}; - -inline bool operator==(const UBDocumentProxy &proxy1, const UBDocumentProxy &proxy2) -{ - return proxy1.persistencePath() == proxy2.persistencePath(); -} - -inline uint qHash(const UBDocumentProxy &key) -{ - return qHash(key.persistencePath()); -} - - -#endif /* UBDOCUMENTPROXY_H_ */ +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef UBDOCUMENTPROXY_H_ +#define UBDOCUMENTPROXY_H_ + +#include + +#include "frameworks/UBStringUtils.h" + +#include "core/UBSettings.h" + +class UBGraphicsScene; + +class UBDocumentProxy : public QObject +{ + Q_OBJECT + + friend class UBPersistenceManager; + + public: + + UBDocumentProxy(); + UBDocumentProxy(const QString& pPersistencePath); + + virtual ~UBDocumentProxy(); + + QString persistencePath() const; + + void setPersistencePath(const QString& pPersistencePath); + + void setMetaData(const QString& pKey , const QVariant& pValue); + QVariant metaData(const QString& pKey) const; + QHash metaDatas() const; + + QString name() const; + QString groupName() const; + QDateTime documentDate(); + + QDateTime lastUpdate(); + + + QSize defaultDocumentSize() const; + void setDefaultDocumentSize(QSize pSize); + void setDefaultDocumentSize(int pWidth, int pHeight); + + QUuid uuid() const; + void setUuid(const QUuid& uuid); + + bool isModified() const; + + int pageCount(); + + protected: + void setPageCount(int pPageCount); + int incPageCount(); + int decPageCount(); + + signals: + void defaultDocumentSizeChanged(); + + private: + + void init(); + + QString mPersistencePath; + + QHash mMetaDatas; + + bool mIsModified; + + int mPageCount; + +}; + +inline bool operator==(const UBDocumentProxy &proxy1, const UBDocumentProxy &proxy2) +{ + return proxy1.persistencePath() == proxy2.persistencePath(); +} + +inline uint qHash(const UBDocumentProxy &key) +{ + return qHash(key.persistencePath()); +} + + +#endif /* UBDOCUMENTPROXY_H_ */ diff --git a/src/document/document.pri b/src/document/document.pri index 85b8293d..b632666a 100644 --- a/src/document/document.pri +++ b/src/document/document.pri @@ -1,6 +1,8 @@ HEADERS += src/document/UBDocumentController.h \ + src/document/UBDocumentContainer.h \ src/document/UBDocumentProxy.h -SOURCES += src/document/UBDocumentController.cpp \ +SOURCES += src/document/UBDocumentController.cpp \ + src/document/UBDocumentContainer.cpp \ src/document/UBDocumentProxy.cpp \ No newline at end of file diff --git a/src/frameworks/UBFileSystemUtils.cpp b/src/frameworks/UBFileSystemUtils.cpp index 2fe09af4..79b24701 100644 --- a/src/frameworks/UBFileSystemUtils.cpp +++ b/src/frameworks/UBFileSystemUtils.cpp @@ -20,6 +20,7 @@ #include "core/UBApplication.h" #include "board/UBBoardController.h" +#include "document/UBDocumentContainer.h" #include "globals/UBGlobals.h" @@ -334,7 +335,7 @@ QString UBFileSystemUtils::normalizeFilePath(const QString& pFilePath) QString UBFileSystemUtils::digitFileFormat(const QString& s, int digit) { - int pageDigit = UBApplication::boardController->pageFromSceneIndex(digit); + int pageDigit = UBDocumentContainer::pageFromSceneIndex(digit); return s.arg(pageDigit, 3, 10, QLatin1Char('0')); } diff --git a/src/gui/UBDocumentNavigator.cpp b/src/gui/UBDocumentNavigator.cpp index 3e3aff32..bdb6f713 100644 --- a/src/gui/UBDocumentNavigator.cpp +++ b/src/gui/UBDocumentNavigator.cpp @@ -1,384 +1,274 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/UBApplication.h" -#include "UBDocumentNavigator.h" -#include "board/UBBoardController.h" -#include "adaptors/UBThumbnailAdaptor.h" -#include "adaptors/UBSvgSubsetAdaptor.h" -#include "document/UBDocumentController.h" -#include "domain/UBGraphicsScene.h" -#include "board/UBBoardPaletteManager.h" -#include "core/UBApplicationController.h" - -#include "core/memcheck.h" - -/** - * \brief Constructor - * @param parent as the parent widget - * @param name as the object name - */ -UBDocumentNavigator::UBDocumentNavigator(QWidget *parent, const char *name):QGraphicsView(parent) - , mScene(NULL) - , mCrntItem(NULL) - , mCrntDoc(NULL) - , mNbColumns(1) - , mThumbnailWidth(0) - , mThumbnailMinWidth(100) - , bNavig(false) -{ - setObjectName(name); - mScene = new QGraphicsScene(this); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setScene(mScene); - mThumbnailWidth = width() - 2*border(); - - setFrameShadow(QFrame::Plain); - - connect(UBApplication::boardController, SIGNAL(activeSceneChanged()), this, SLOT(generateThumbnails())); - connect(UBApplication::boardController, SIGNAL(newPageAdded()), this, SLOT(addNewPage())); - connect(mScene, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); - connect(UBApplication::boardController, SIGNAL(documentReorganized(int)), this, SLOT(onMovedToIndex(int))); - connect(UBApplication::boardController, SIGNAL(scrollToSelectedPage()), this, SLOT(onScrollToSelectedPage())); -} - -/** - * \brief Destructor - */ -UBDocumentNavigator::~UBDocumentNavigator() -{ - if(NULL != mCrntItem) - { - delete mCrntItem; - mCrntItem = NULL; - } - - if(NULL != mScene) - { - delete mScene; - mScene = NULL; - } -} - -/** - * \brief Set the current document - * @param document as the new document - */ -void UBDocumentNavigator::setDocument(UBDocumentProxy *document) -{ - // Here we set a new document to the navigator. We must clear the current - // content and add all the pages of the given document. - if(document) - { - mCrntDoc = document; - } -} - -/** - * \brief Generate the thumbnails - */ -void UBDocumentNavigator::generateThumbnails() -{ - // Get the thumbnails - QList thumbs = UBThumbnailAdaptor::load(mCrntDoc); - - mThumbsWithLabels.clear(); - foreach(QGraphicsItem* it, mScene->items()) - { - mScene->removeItem(it); - delete it; - } - - for(int i = 0; i < thumbs.count(); i++) - { - QPixmap pix = thumbs.at(i); - QGraphicsPixmapItem* pixmapItem = new UBSceneThumbnailNavigPixmap(pix, mCrntDoc, i); - UBThumbnailTextItem *labelItem = new UBThumbnailTextItem(tr("Page %0").arg(UBApplication::boardController->pageFromSceneIndex(i))); - - UBImgTextThumbnailElement thumbWithText(pixmapItem, labelItem); - thumbWithText.setBorder(border()); - mThumbsWithLabels.append(thumbWithText); - - mScene->addItem(pixmapItem); - mScene->addItem(labelItem); - - // Get the selected item - if(UBApplication::boardController->activeSceneIndex() == i) - { - mCrntItem = dynamic_cast(pixmapItem); - mCrntItem->setSelected(true); - } - } - - // Draw the items - refreshScene(); -} - -/** - * \brief Refresh the given thumbnail - * @param iPage as the given page related thumbnail - */ -void UBDocumentNavigator::updateSpecificThumbnail(int iPage) -{ - // Generate the new thumbnail - UBGraphicsScene* pScene = UBApplication::boardController->activeScene(); - - if(NULL != pScene) - { - // Save the current state of the scene - pScene->setModified(true); - if(UBApplication::boardController) - { - UBApplication::boardController->persistCurrentScene(); - }else - { - UBThumbnailAdaptor::persistScene(mCrntDoc->persistencePath(), pScene, iPage); - } - - // Load it - QPixmap pix = UBThumbnailAdaptor::load(mCrntDoc, iPage); - UBSceneThumbnailNavigPixmap* pixmapItem = new UBSceneThumbnailNavigPixmap(pix, mCrntDoc, iPage); - if(pixmapItem) - { - // Get the old thumbnail - QGraphicsItem* pItem = mThumbsWithLabels.at(iPage).getThumbnail(); - if(NULL != pItem) - { - mScene->removeItem(pItem); - mScene->addItem(pixmapItem); - mThumbsWithLabels[iPage].setThumbnail(pixmapItem); - delete pItem; - } - } - } -} - -/** - * \brief Add a new page to the thumbnails list - * - * This method is called automatically by the board controller each time the user - * adds a new page, duplicates a page or imports a document. - */ -void UBDocumentNavigator::addNewPage() -{ - if(!bNavig) - { - generateThumbnails(); - if(NULL != mCrntItem) - { - mCrntItem->setSelected(true); - } - } -} - -/** - * \brief Put the element in the right place in the scene. - */ -void UBDocumentNavigator::refreshScene() -{ - qreal thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio; - - for(int i = 0; i < mThumbsWithLabels.size(); i++) - { - // Get the item - UBImgTextThumbnailElement& item = mThumbsWithLabels[i]; - int columnIndex = i % mNbColumns; - int rowIndex = i / mNbColumns; - item.Place(rowIndex, columnIndex, mThumbnailWidth, thumbnailHeight); - } -} - -/** - * \brief Set the number of thumbnails columns - * @param nbColumns as the number of columns - */ -void UBDocumentNavigator::setNbColumns(int nbColumns) -{ - mNbColumns = nbColumns; -} - -/** - * \brief Get the number of columns - * @return the number of thumbnails columns - */ -int UBDocumentNavigator::nbColumns() -{ - return mNbColumns; -} - -/** - * \brief Set the thumbnails minimum width - * @param width as the minimum width - */ -void UBDocumentNavigator::setThumbnailMinWidth(int width) -{ - mThumbnailMinWidth = width; -} - -/** - * \brief Get the thumbnails minimum width - * @return the minimum thumbnails width - */ -int UBDocumentNavigator::thumbnailMinWidth() -{ - return mThumbnailMinWidth; -} - -/** - * \brief Get the border size - * @return the border size in pixels - */ -int UBDocumentNavigator::border() -{ - return 20; -} - -/** - * \brief Handle the resize event - * @param event as the resize event - */ -void UBDocumentNavigator::resizeEvent(QResizeEvent *event) -{ - Q_UNUSED(event); - - // Update the thumbnails width - mThumbnailWidth = (width() > mThumbnailMinWidth) ? width() - 2*border() : mThumbnailMinWidth; - - // Refresh the scene - refreshScene(); -} - -/** - * \brief Handle the mouse press event - * @param event as the mouse event - */ -void UBDocumentNavigator::mousePressEvent(QMouseEvent *event) -{ - QGraphicsItem* pClickedItem = itemAt(event->pos()); - if(NULL != pClickedItem) - { - bNavig = true; - - // First, select the clicked item - UBSceneThumbnailNavigPixmap* pCrntItem = dynamic_cast(pClickedItem); - - if(NULL == pCrntItem) - { - // If we fall here we may have clicked on the label instead of the thumbnail - UBThumbnailTextItem* pTextItem = dynamic_cast(pClickedItem); - if(NULL != pTextItem) - { - for(int i = 0; i < mThumbsWithLabels.size(); i++) - { - const UBImgTextThumbnailElement& el = mThumbsWithLabels.at(i); - if(el.getCaption() == pTextItem) - { - pCrntItem = dynamic_cast(el.getThumbnail()); - break; - } - } - } - } - else - { - if(NULL != mCrntItem && mCrntItem != pCrntItem) - { - // Unselect the previous item - mCrntItem->setSelected(false); - int iOldPage = -1; - for(int i = 0; i < mThumbsWithLabels.size(); i++) - if (mThumbsWithLabels.at(i).getThumbnail() == mCrntItem) - { - iOldPage = i; - break; - } - updateSpecificThumbnail(iOldPage); - mCrntItem = pCrntItem; - - // Then display the related page - emit changeCurrentPage(); - refreshScene(); - } - } - - bNavig = false; - } - QGraphicsView::mousePressEvent(event); -} - -/** - * \brief Get the selected page number - * @return the selected page number - */ -int UBDocumentNavigator::selectedPageNumber() -{ - int nbr = NO_PAGESELECTED; - - if(NULL != mCrntItem) - { - for(int i = 0; i < mThumbsWithLabels.size(); i++) - if (mThumbsWithLabels.at(i).getThumbnail() == mCrntItem) - { - nbr = i; - break; - } - } - - return nbr; -} - -/** - * \brief Get the current document - * @return the current document - */ -UBDocumentProxy* UBDocumentNavigator::currentDoc() -{ - return mCrntDoc; -} - -/** - * \brief Occurs when the selection changed - */ -void UBDocumentNavigator::onSelectionChanged() -{ - // QList qlItems = mScene->selectedItems(); - // qDebug() << "The number of selected items is " << qlItems.count(); -} - -/** - * \brief Occurs when a page has been moved to another index in the document - * @param index as the new index - */ -void UBDocumentNavigator::onMovedToIndex(int index) -{ - if(index < mThumbsWithLabels.size()){ - UBSceneThumbnailNavigPixmap* pItem = dynamic_cast(mThumbsWithLabels.at(index).getThumbnail()); - if(NULL != pItem) - { - if(mCrntItem) mCrntItem->setSelected(false);//deselecting previous one - mCrntItem = pItem; - mCrntItem->setSelected(true); - centerOn(mCrntItem); - } - } -} +/* + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core/UBApplication.h" +#include "UBDocumentNavigator.h" +#include "board/UBBoardController.h" +#include "adaptors/UBThumbnailAdaptor.h" +#include "adaptors/UBSvgSubsetAdaptor.h" +#include "document/UBDocumentController.h" +#include "domain/UBGraphicsScene.h" +#include "board/UBBoardPaletteManager.h" +#include "core/UBApplicationController.h" + +#include "core/memcheck.h" + +/** + * \brief Constructor + * @param parent as the parent widget + * @param name as the object name + */ +UBDocumentNavigator::UBDocumentNavigator(QWidget *parent, const char *name):QGraphicsView(parent) + , mScene(NULL) + , mNbColumns(1) + , mThumbnailWidth(0) + , mThumbnailMinWidth(100) +{ + setObjectName(name); + mScene = new QGraphicsScene(this); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setScene(mScene); + mThumbnailWidth = width() - 2*border(); + + setFrameShadow(QFrame::Plain); + + connect(UBApplication::boardController, SIGNAL(documentThumbnailsUpdated(UBDocumentContainer*)), this, SLOT(generateThumbnails(UBDocumentContainer*))); + connect(UBApplication::boardController, SIGNAL(documentPageUpdated(int)), this, SLOT(updateSpecificThumbnail(int))); + connect(UBApplication::boardController, SIGNAL(pageSelectionChanged(int)), this, SLOT(onScrollToSelectedPage(int))); +} + +/** + * \brief Destructor + */ +UBDocumentNavigator::~UBDocumentNavigator() +{ + if(NULL != mScene) + { + delete mScene; + mScene = NULL; + } +} + +/** + * \brief Generate the thumbnails + */ +void UBDocumentNavigator::generateThumbnails(UBDocumentContainer* source) +{ + + mThumbsWithLabels.clear(); + foreach(QGraphicsItem* it, mScene->items()) + { + mScene->removeItem(it); + delete it; + } + + for(int i = 0; i < source->selectedDocument()->pageCount(); i++) + { + const QPixmap* pix = source->pageAt(i); + UBSceneThumbnailNavigPixmap* pixmapItem = new UBSceneThumbnailNavigPixmap(*pix, source->selectedDocument(), i); + UBThumbnailTextItem *labelItem = new UBThumbnailTextItem(tr("Page %0").arg(UBDocumentContainer::pageFromSceneIndex(i))); + + UBImgTextThumbnailElement thumbWithText(pixmapItem, labelItem); + thumbWithText.setBorder(border()); + mThumbsWithLabels.append(thumbWithText); + + mScene->addItem(pixmapItem); + mScene->addItem(labelItem); + + // Get the selected item + if(UBApplication::boardController->activeSceneIndex() == i) + { + pixmapItem->setSelected(true); + } + } + + // Draw the items + refreshScene(); +} + +void UBDocumentNavigator::onScrollToSelectedPage(int index) +{ + int c = 0; + foreach(UBImgTextThumbnailElement el, mThumbsWithLabels) + { + if (c==index) + { + el.getThumbnail()->setSelected(true); + centerOn(el.getThumbnail()); + } + else + { + el.getThumbnail()->setSelected(false); + } + c++; + } + refreshScene(); +} + +/** + * \brief Refresh the given thumbnail + * @param iPage as the given page related thumbnail + */ +void UBDocumentNavigator::updateSpecificThumbnail(int iPage) +{ + // Generate the new thumbnail + //UBGraphicsScene* pScene = UBApplication::boardController->activeScene(); + + const QPixmap* pix = UBApplication::boardController->pageAt(iPage); + UBSceneThumbnailNavigPixmap* newItem = new UBSceneThumbnailNavigPixmap(*pix, + UBApplication::boardController->selectedDocument(), iPage); + + // Get the old thumbnail + UBSceneThumbnailNavigPixmap* oldItem = mThumbsWithLabels.at(iPage).getThumbnail(); + if(NULL != oldItem) + { + mScene->removeItem(oldItem); + mScene->addItem(newItem); + mThumbsWithLabels[iPage].setThumbnail(newItem); + delete oldItem; + } + +} + +/** + * \brief Put the element in the right place in the scene. + */ +void UBDocumentNavigator::refreshScene() +{ + qreal thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio; + + for(int i = 0; i < mThumbsWithLabels.size(); i++) + { + // Get the item + UBImgTextThumbnailElement& item = mThumbsWithLabels[i]; + int columnIndex = i % mNbColumns; + int rowIndex = i / mNbColumns; + item.Place(rowIndex, columnIndex, mThumbnailWidth, thumbnailHeight); + } +} + +/** + * \brief Set the number of thumbnails columns + * @param nbColumns as the number of columns + */ +void UBDocumentNavigator::setNbColumns(int nbColumns) +{ + mNbColumns = nbColumns; +} + +/** + * \brief Get the number of columns + * @return the number of thumbnails columns + */ +int UBDocumentNavigator::nbColumns() +{ + return mNbColumns; +} + +/** + * \brief Set the thumbnails minimum width + * @param width as the minimum width + */ +void UBDocumentNavigator::setThumbnailMinWidth(int width) +{ + mThumbnailMinWidth = width; +} + +/** + * \brief Get the thumbnails minimum width + * @return the minimum thumbnails width + */ +int UBDocumentNavigator::thumbnailMinWidth() +{ + return mThumbnailMinWidth; +} + +/** + * \brief Get the border size + * @return the border size in pixels + */ +int UBDocumentNavigator::border() +{ + return 20; +} + +/** + * \brief Handle the resize event + * @param event as the resize event + */ +void UBDocumentNavigator::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + + // Update the thumbnails width + mThumbnailWidth = (width() > mThumbnailMinWidth) ? width() - 2*border() : mThumbnailMinWidth; + + // Refresh the scene + refreshScene(); +} + +/** + * \brief Handle the mouse press event + * @param event as the mouse event + */ +void UBDocumentNavigator::mousePressEvent(QMouseEvent *event) +{ + QGraphicsItem* pClickedItem = itemAt(event->pos()); + if(NULL != pClickedItem) + { + + // First, select the clicked item + UBSceneThumbnailNavigPixmap* pCrntItem = dynamic_cast(pClickedItem); + + if(NULL == pCrntItem) + { + // If we fall here we may have clicked on the label instead of the thumbnail + UBThumbnailTextItem* pTextItem = dynamic_cast(pClickedItem); + if(NULL != pTextItem) + { + for(int i = 0; i < mThumbsWithLabels.size(); i++) + { + const UBImgTextThumbnailElement& el = mThumbsWithLabels.at(i); + if(el.getCaption() == pTextItem) + { + pCrntItem = el.getThumbnail(); + break; + } + } + } + } + + int index = 0; + for(int i = 0; i < mThumbsWithLabels.size(); i++) + { + if (mThumbsWithLabels.at(i).getThumbnail() == pCrntItem) + { + index = i; + break; + } + } + UBApplication::boardController->setActiveDocumentScene(index); + } + QGraphicsView::mousePressEvent(event); +} + diff --git a/src/gui/UBDocumentNavigator.h b/src/gui/UBDocumentNavigator.h index f347f794..6e7db437 100644 --- a/src/gui/UBDocumentNavigator.h +++ b/src/gui/UBDocumentNavigator.h @@ -1,84 +1,71 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef UBDOCUMENTNAVIGATOR_H -#define UBDOCUMENTNAVIGATOR_H - -#include -#include -#include -#include -#include - -#include "document/UBDocumentProxy.h" -#include "UBThumbnailWidget.h" - -#define NO_PAGESELECTED -1 - -class UBDocumentNavigator : public QGraphicsView -{ - Q_OBJECT -public: - UBDocumentNavigator(QWidget* parent=0, const char* name="documentNavigator"); - ~UBDocumentNavigator(); - - void setDocument(UBDocumentProxy* document); - void setNbColumns(int nbColumns); - int nbColumns(); - void setThumbnailMinWidth(int width); - int thumbnailMinWidth(); - int selectedPageNumber(); - UBDocumentProxy* currentDoc(); - -signals: - void changeCurrentPage(); - -public slots: - void onMovedToIndex(int index); - void onScrollToSelectedPage() { centerOn(mCrntItem); } - -protected: - virtual void resizeEvent(QResizeEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - -private slots: - void addNewPage(); - void onSelectionChanged(); - void generateThumbnails(); - -private: - void refreshScene(); - void updateSpecificThumbnail(int iPage); - int border(); - - - /** The scene */ - QGraphicsScene* mScene; - /** The current selected item */ - UBSceneThumbnailNavigPixmap* mCrntItem; - /** The current document */ - UBDocumentProxy* mCrntDoc; - /** The list of current thumbnails with labels*/ - QList mThumbsWithLabels; - /** The current number of columns */ - int mNbColumns; - /** The current thumbnails width */ - int mThumbnailWidth; - /** The current thumbnails minimum width */ - int mThumbnailMinWidth; - /** A flag indicating that a thumbnail refresh is in progress */ - bool bNavig; -}; - -#endif // UBDOCUMENTNAVIGATOR_H +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef UBDOCUMENTNAVIGATOR_H +#define UBDOCUMENTNAVIGATOR_H + +#include +#include +#include +#include +#include + +#include "document/UBDocumentProxy.h" +#include "document/UBDocumentContainer.h" +#include "UBThumbnailWidget.h" + +#define NO_PAGESELECTED -1 + +class UBDocumentNavigator : public QGraphicsView +{ + Q_OBJECT +public: + UBDocumentNavigator(QWidget* parent=0, const char* name="documentNavigator"); + ~UBDocumentNavigator(); + + void setNbColumns(int nbColumns); + int nbColumns(); + void setThumbnailMinWidth(int width); + int thumbnailMinWidth(); + +public slots: + void onScrollToSelectedPage(int index);// { if (mCrntItem) centerOn(mCrntItem); } + void generateThumbnails(UBDocumentContainer* source); + void updateSpecificThumbnail(int iPage); + +protected: + virtual void resizeEvent(QResizeEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + +private: + + void refreshScene(); + int border(); + + + /** The scene */ + QGraphicsScene* mScene; + /** The current selected item */ + //UBSceneThumbnailNavigPixmap* mCrntItem; + /** The list of current thumbnails with labels*/ + QList mThumbsWithLabels; + /** The current number of columns */ + int mNbColumns; + /** The current thumbnails width */ + int mThumbnailWidth; + /** The current thumbnails minimum width */ + int mThumbnailMinWidth; +}; + +#endif // UBDOCUMENTNAVIGATOR_H diff --git a/src/gui/UBDocumentThumbnailWidget.cpp b/src/gui/UBDocumentThumbnailWidget.cpp index c00c3802..dc361259 100644 --- a/src/gui/UBDocumentThumbnailWidget.cpp +++ b/src/gui/UBDocumentThumbnailWidget.cpp @@ -1,316 +1,315 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "UBDocumentThumbnailWidget.h" - -#include "core/UBApplication.h" -#include "core/UBMimeData.h" -#include "core/UBSettings.h" - -#include "board/UBBoardController.h" - -#include "document/UBDocumentController.h" - -#include "core/memcheck.h" - - -UBDocumentThumbnailWidget::UBDocumentThumbnailWidget(QWidget* parent) - : UBThumbnailWidget(parent) - , mDropCaretRectItem(0) - , mClosestDropItem(0) - , mDragEnabled(true) - , mScrollMagnitude(0) -{ - bCanDrag = false; - mScrollTimer = new QTimer(this); - connect(mScrollTimer, SIGNAL(timeout()), this, SLOT(autoScroll())); -} - - -UBDocumentThumbnailWidget::~UBDocumentThumbnailWidget() -{ - // NOOP -} - - -void UBDocumentThumbnailWidget::mouseMoveEvent(QMouseEvent *event) -{ - if (!dragEnabled()) - { - event->ignore(); - return; - } - - if (!(event->buttons() & Qt::LeftButton)) - return; - - if ((event->pos() - mMousePressPos).manhattanLength() < QApplication::startDragDistance()) - return; - - QList graphicsItems = items(mMousePressPos); - - UBSceneThumbnailPixmap* sceneItem = 0; - - while (!graphicsItems.isEmpty() && !sceneItem) - sceneItem = dynamic_cast(graphicsItems.takeFirst()); - - if (sceneItem) - { - int pageIndex = UBApplication::boardController->pageFromSceneIndex(sceneItem->sceneIndex()); - if(pageIndex != 0){ - QDrag *drag = new QDrag(this); - QList mimeDataItems; - foreach (QGraphicsItem *item, selectedItems()) - mimeDataItems.append(UBMimeDataItem(sceneItem->proxy(), mGraphicItems.indexOf(item))); - - UBMimeData *mime = new UBMimeData(mimeDataItems); - drag->setMimeData(mime); - - drag->setPixmap(sceneItem->pixmap().scaledToWidth(100)); - drag->setHotSpot(QPoint(drag->pixmap().width()/2, drag->pixmap().height() / 2)); - - drag->exec(Qt::MoveAction); - } - } - - UBThumbnailWidget::mouseMoveEvent(event); -} - -void UBDocumentThumbnailWidget::dragEnterEvent(QDragEnterEvent *event) -{ - if (!event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - event->setDropAction(Qt::IgnoreAction); - event->ignore(); - return; - } - - UBThumbnailWidget::dragEnterEvent(event); -} - -void UBDocumentThumbnailWidget::dragLeaveEvent(QDragLeaveEvent *event) -{ - Q_UNUSED(event); - if (mScrollTimer->isActive()) - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - deleteDropCaret(); - UBThumbnailWidget::dragLeaveEvent(event); -} - -void UBDocumentThumbnailWidget::autoScroll() -{ - this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() + mScrollMagnitude); -} - -void UBDocumentThumbnailWidget::dragMoveEvent(QDragMoveEvent *event) -{ - QRect boundingFrame = frameRect(); - //setting up automatic scrolling - const int SCROLL_DISTANCE = 16; - int bottomDist = boundingFrame.bottom() - event->pos().y(), topDist = boundingFrame.top() - event->pos().y(); - if(qAbs(bottomDist) <= SCROLL_DISTANCE) - { - mScrollMagnitude = (SCROLL_DISTANCE - bottomDist)*4; - if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); - } - else if(qAbs(topDist) <= SCROLL_DISTANCE) - { - mScrollMagnitude = (- SCROLL_DISTANCE - topDist)*4; - if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); - } - else - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - - QList pixmapItems; - foreach (QGraphicsItem *item, scene()->items(mapToScene(boundingFrame))) - { - UBSceneThumbnailPixmap* sceneItem = dynamic_cast(item); - if (sceneItem) - pixmapItems.append(sceneItem); - } - - int minDistance = 0; - QGraphicsItem *underlyingItem = itemAt(event->pos()); - mClosestDropItem = dynamic_cast(underlyingItem); - - int pageIndex = -1; - if(mClosestDropItem){ - pageIndex = UBApplication::boardController->pageFromSceneIndex(mClosestDropItem->sceneIndex()); - if(pageIndex == 0){ - event->acceptProposedAction(); - return; - } - } - if (!mClosestDropItem) - { - foreach (UBSceneThumbnailPixmap *item, pixmapItems) - { - qreal scale = item->transform().m11(); - QPointF itemCenter( - item->pos().x() + item->boundingRect().width() * scale / 2, - item->pos().y() + item->boundingRect().height() * scale / 2); - - int distance = (itemCenter.toPoint() - mapToScene(event->pos()).toPoint()).manhattanLength(); - if (!mClosestDropItem || distance < minDistance) - { - mClosestDropItem = item; - minDistance = distance; - pageIndex = UBApplication::boardController->pageFromSceneIndex(mClosestDropItem->sceneIndex()); - } - } - } - - if (mClosestDropItem && pageIndex != 0) - { - qreal scale = mClosestDropItem->transform().m11(); - - QPointF itemCenter( - mClosestDropItem->pos().x() + mClosestDropItem->boundingRect().width() * scale / 2, - mClosestDropItem->pos().y() + mClosestDropItem->boundingRect().height() * scale / 2); - - mDropIsRight = mapToScene(event->pos()).x() > itemCenter.x(); - - if (!mDropCaretRectItem && selectedItems().count() < mGraphicItems.count()) - { - mDropCaretRectItem = new QGraphicsRectItem(0, scene()); - mDropCaretRectItem->setPen(QPen(Qt::darkGray)); - mDropCaretRectItem->setBrush(QBrush(Qt::lightGray)); - } - - QRectF dropCaretRect( - mDropIsRight ? mClosestDropItem->pos().x() + mClosestDropItem->boundingRect().width() * scale + spacing() / 2 - 1 : mClosestDropItem->pos().x() - spacing() / 2 - 1, - mClosestDropItem->pos().y(), - 3, - mClosestDropItem->boundingRect().height() * scale); - - if (mDropCaretRectItem) - mDropCaretRectItem->setRect(dropCaretRect); - } - - event->acceptProposedAction(); -} - - -void UBDocumentThumbnailWidget::dropEvent(QDropEvent *event) -{ - if (mScrollTimer->isActive()) - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - deleteDropCaret(); - - if (mClosestDropItem) - { - int targetIndex = mDropIsRight ? mGraphicItems.indexOf(mClosestDropItem) + 1 : mGraphicItems.indexOf(mClosestDropItem); - if(UBApplication::boardController->pageFromSceneIndex(targetIndex) == 0){ - event->ignore(); - return; - } - - QList mimeDataItems; - if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - const UBMimeData* mimeData = qobject_cast(event->mimeData()); - if (mimeData) - mimeDataItems = mimeData->items(); - } - - if (1 == mimeDataItems.count() && - (mimeDataItems.at(0).sceneIndex() == mGraphicItems.indexOf(mClosestDropItem) || - targetIndex == mimeDataItems.at(0).sceneIndex() || - targetIndex == mimeDataItems.at(0).sceneIndex() + 1)) - { - return; - } - - int sourceIndexOffset = 0; - int actualTargetIndex = targetIndex; - for (int i = mimeDataItems.count() - 1; i >= 0; i--) - { - UBMimeDataItem sourceItem = mimeDataItems.at(i); - int actualSourceIndex = sourceItem.sceneIndex(); - if (sourceItem.sceneIndex() >= targetIndex) - actualSourceIndex += sourceIndexOffset; - - //event->acceptProposedAction(); - if (sourceItem.sceneIndex() < targetIndex) - { - if (actualSourceIndex != actualTargetIndex - 1) - emit sceneDropped(sourceItem.documentProxy(), actualSourceIndex, actualTargetIndex - 1); - actualTargetIndex -= 1; - } - else - { - if (actualSourceIndex != actualTargetIndex) - emit sceneDropped(sourceItem.documentProxy(), actualSourceIndex, actualTargetIndex); - sourceIndexOffset += 1; - } - } - } - UBThumbnailWidget::dropEvent(event); -} - -void UBDocumentThumbnailWidget::deleteDropCaret() -{ - if (mDropCaretRectItem && scene()) - { - scene()->removeItem(mDropCaretRectItem); - delete mDropCaretRectItem; - mDropCaretRectItem = 0; - } -} - - -void UBDocumentThumbnailWidget::setGraphicsItems(const QList& pGraphicsItems, - const QList& pItemPaths, const QStringList pLabels, - const QString& pMimeType) -{ - deleteDropCaret(); - - UBThumbnailWidget::setGraphicsItems(pGraphicsItems, pItemPaths, pLabels, pMimeType); -} - -void UBDocumentThumbnailWidget::setDragEnabled(bool enabled) -{ - mDragEnabled = enabled; -} - -bool UBDocumentThumbnailWidget::dragEnabled() const -{ - return mDragEnabled; -} - -void UBDocumentThumbnailWidget::hightlightItem(int index) -{ - if (0 <= index && index < mLabelsItems.length()) - { - mLabelsItems.at(index)->highlight(); - } - if (0 <= index && index < mGraphicItems.length()) - { - UBSceneThumbnailPixmap *thumbnail = dynamic_cast(mGraphicItems.at(index)); - if (thumbnail) - thumbnail->highlight(); - } - - selectItemAt(index); -} +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "UBDocumentThumbnailWidget.h" + +#include "core/UBApplication.h" +#include "core/UBMimeData.h" +#include "core/UBSettings.h" + +#include "board/UBBoardController.h" + +#include "document/UBDocumentController.h" + +#include "core/memcheck.h" + + +UBDocumentThumbnailWidget::UBDocumentThumbnailWidget(QWidget* parent) + : UBThumbnailWidget(parent) + , mDropCaretRectItem(0) + , mClosestDropItem(0) + , mDragEnabled(true) + , mScrollMagnitude(0) +{ + bCanDrag = false; + mScrollTimer = new QTimer(this); + connect(mScrollTimer, SIGNAL(timeout()), this, SLOT(autoScroll())); +} + + +UBDocumentThumbnailWidget::~UBDocumentThumbnailWidget() +{ + // NOOP +} + + +void UBDocumentThumbnailWidget::mouseMoveEvent(QMouseEvent *event) +{ + if (!dragEnabled()) + { + event->ignore(); + return; + } + + if (!(event->buttons() & Qt::LeftButton)) + return; + + if ((event->pos() - mMousePressPos).manhattanLength() < QApplication::startDragDistance()) + return; + + QList graphicsItems = items(mMousePressPos); + + UBSceneThumbnailPixmap* sceneItem = 0; + + while (!graphicsItems.isEmpty() && !sceneItem) + sceneItem = dynamic_cast(graphicsItems.takeFirst()); + + if (sceneItem) + { + int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneItem->sceneIndex()); + if(pageIndex != 0){ + QDrag *drag = new QDrag(this); + QList mimeDataItems; + foreach (QGraphicsItem *item, selectedItems()) + mimeDataItems.append(UBMimeDataItem(sceneItem->proxy(), mGraphicItems.indexOf(item))); + + UBMimeData *mime = new UBMimeData(mimeDataItems); + drag->setMimeData(mime); + + drag->setPixmap(sceneItem->pixmap().scaledToWidth(100)); + drag->setHotSpot(QPoint(drag->pixmap().width()/2, drag->pixmap().height() / 2)); + + drag->exec(Qt::MoveAction); + } + } + + UBThumbnailWidget::mouseMoveEvent(event); +} + +void UBDocumentThumbnailWidget::dragEnterEvent(QDragEnterEvent *event) +{ + if (!event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + event->setDropAction(Qt::IgnoreAction); + event->ignore(); + return; + } + + UBThumbnailWidget::dragEnterEvent(event); +} + +void UBDocumentThumbnailWidget::dragLeaveEvent(QDragLeaveEvent *event) +{ + Q_UNUSED(event); + if (mScrollTimer->isActive()) + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + deleteDropCaret(); + UBThumbnailWidget::dragLeaveEvent(event); +} + +void UBDocumentThumbnailWidget::autoScroll() +{ + this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() + mScrollMagnitude); +} + +void UBDocumentThumbnailWidget::dragMoveEvent(QDragMoveEvent *event) +{ + QRect boundingFrame = frameRect(); + //setting up automatic scrolling + const int SCROLL_DISTANCE = 16; + int bottomDist = boundingFrame.bottom() - event->pos().y(), topDist = boundingFrame.top() - event->pos().y(); + if(qAbs(bottomDist) <= SCROLL_DISTANCE) + { + mScrollMagnitude = (SCROLL_DISTANCE - bottomDist)*4; + if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); + } + else if(qAbs(topDist) <= SCROLL_DISTANCE) + { + mScrollMagnitude = (- SCROLL_DISTANCE - topDist)*4; + if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); + } + else + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + + QList pixmapItems; + foreach (QGraphicsItem *item, scene()->items(mapToScene(boundingFrame))) + { + UBSceneThumbnailPixmap* sceneItem = dynamic_cast(item); + if (sceneItem) + pixmapItems.append(sceneItem); + } + + int minDistance = 0; + QGraphicsItem *underlyingItem = itemAt(event->pos()); + mClosestDropItem = dynamic_cast(underlyingItem); + + int pageIndex = -1; + if(mClosestDropItem){ + pageIndex = UBDocumentContainer::pageFromSceneIndex(mClosestDropItem->sceneIndex()); + if(pageIndex == 0){ + event->acceptProposedAction(); + return; + } + } + if (!mClosestDropItem) + { + foreach (UBSceneThumbnailPixmap *item, pixmapItems) + { + qreal scale = item->transform().m11(); + QPointF itemCenter( + item->pos().x() + item->boundingRect().width() * scale / 2, + item->pos().y() + item->boundingRect().height() * scale / 2); + + int distance = (itemCenter.toPoint() - mapToScene(event->pos()).toPoint()).manhattanLength(); + if (!mClosestDropItem || distance < minDistance) + { + mClosestDropItem = item; + minDistance = distance; + pageIndex = UBDocumentContainer::pageFromSceneIndex(mClosestDropItem->sceneIndex()); + } + } + } + + if (mClosestDropItem && pageIndex != 0) + { + qreal scale = mClosestDropItem->transform().m11(); + + QPointF itemCenter( + mClosestDropItem->pos().x() + mClosestDropItem->boundingRect().width() * scale / 2, + mClosestDropItem->pos().y() + mClosestDropItem->boundingRect().height() * scale / 2); + + mDropIsRight = mapToScene(event->pos()).x() > itemCenter.x(); + + if (!mDropCaretRectItem && selectedItems().count() < mGraphicItems.count()) + { + mDropCaretRectItem = new QGraphicsRectItem(0, scene()); + mDropCaretRectItem->setPen(QPen(Qt::darkGray)); + mDropCaretRectItem->setBrush(QBrush(Qt::lightGray)); + } + + QRectF dropCaretRect( + mDropIsRight ? mClosestDropItem->pos().x() + mClosestDropItem->boundingRect().width() * scale + spacing() / 2 - 1 : mClosestDropItem->pos().x() - spacing() / 2 - 1, + mClosestDropItem->pos().y(), + 3, + mClosestDropItem->boundingRect().height() * scale); + + if (mDropCaretRectItem) + mDropCaretRectItem->setRect(dropCaretRect); + } + + event->acceptProposedAction(); +} + + +void UBDocumentThumbnailWidget::dropEvent(QDropEvent *event) +{ + if (mScrollTimer->isActive()) + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + deleteDropCaret(); + + if (mClosestDropItem) + { + int targetIndex = mDropIsRight ? mGraphicItems.indexOf(mClosestDropItem) + 1 : mGraphicItems.indexOf(mClosestDropItem); + if(UBDocumentContainer::pageFromSceneIndex(targetIndex) == 0){ + event->ignore(); + return; + } + + QList mimeDataItems; + if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + const UBMimeData* mimeData = qobject_cast(event->mimeData()); + if (mimeData) + mimeDataItems = mimeData->items(); + } + + if (1 == mimeDataItems.count() && + (mimeDataItems.at(0).sceneIndex() == mGraphicItems.indexOf(mClosestDropItem) || + targetIndex == mimeDataItems.at(0).sceneIndex() || + targetIndex == mimeDataItems.at(0).sceneIndex() + 1)) + { + return; + } + + int sourceIndexOffset = 0; + int actualTargetIndex = targetIndex; + for (int i = mimeDataItems.count() - 1; i >= 0; i--) + { + UBMimeDataItem sourceItem = mimeDataItems.at(i); + int actualSourceIndex = sourceItem.sceneIndex(); + if (sourceItem.sceneIndex() >= targetIndex) + actualSourceIndex += sourceIndexOffset; + + //event->acceptProposedAction(); + if (sourceItem.sceneIndex() < targetIndex) + { + if (actualSourceIndex != actualTargetIndex - 1) + emit sceneDropped(sourceItem.documentProxy(), actualSourceIndex, actualTargetIndex - 1); + actualTargetIndex -= 1; + } + else + { + if (actualSourceIndex != actualTargetIndex) + emit sceneDropped(sourceItem.documentProxy(), actualSourceIndex, actualTargetIndex); + sourceIndexOffset += 1; + } + } + } + UBThumbnailWidget::dropEvent(event); +} + +void UBDocumentThumbnailWidget::deleteDropCaret() +{ + if (mDropCaretRectItem && scene()) + { + scene()->removeItem(mDropCaretRectItem); + delete mDropCaretRectItem; + mDropCaretRectItem = 0; + } +} + +void UBDocumentThumbnailWidget::setGraphicsItems(const QList& pGraphicsItems, + const QList& pItemPaths, const QStringList pLabels, + const QString& pMimeType) +{ + deleteDropCaret(); + + UBThumbnailWidget::setGraphicsItems(pGraphicsItems, pItemPaths, pLabels, pMimeType); +} + +void UBDocumentThumbnailWidget::setDragEnabled(bool enabled) +{ + mDragEnabled = enabled; +} + +bool UBDocumentThumbnailWidget::dragEnabled() const +{ + return mDragEnabled; +} + +void UBDocumentThumbnailWidget::hightlightItem(int index) +{ + if (0 <= index && index < mLabelsItems.length()) + { + mLabelsItems.at(index)->highlight(); + } + if (0 <= index && index < mGraphicItems.length()) + { + UBSceneThumbnailPixmap *thumbnail = dynamic_cast(mGraphicItems.at(index)); + if (thumbnail) + thumbnail->highlight(); + } + + selectItemAt(index); +} diff --git a/src/gui/UBDocumentTreeWidget.cpp b/src/gui/UBDocumentTreeWidget.cpp index 6a5a48a5..4369833d 100644 --- a/src/gui/UBDocumentTreeWidget.cpp +++ b/src/gui/UBDocumentTreeWidget.cpp @@ -1,455 +1,457 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "UBDocumentTreeWidget.h" - -#include "document/UBDocumentProxy.h" - -#include "core/UBSettings.h" -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBMimeData.h" -#include "core/UBApplicationController.h" -#include "core/UBDocumentManager.h" -#include "document/UBDocumentController.h" - -#include "adaptors/UBThumbnailAdaptor.h" -#include "adaptors/UBSvgSubsetAdaptor.h" -#include "frameworks/UBFileSystemUtils.h" - -#include "core/memcheck.h" - -UBDocumentTreeWidget::UBDocumentTreeWidget(QWidget * parent) - : QTreeWidget(parent) - , mSelectedProxyTi(0) - , mDropTargetProxyTi(0) -{ - setDragDropMode(QAbstractItemView::InternalMove); - setAutoScroll(true); - - mScrollTimer = new QTimer(this); - connect(UBDocumentManager::documentManager(), SIGNAL(documentUpdated(UBDocumentProxy*)) - , this, SLOT(documentUpdated(UBDocumentProxy*))); - - connect(this, SIGNAL(itemChanged(QTreeWidgetItem *, int)) - , this, SLOT(itemChangedValidation(QTreeWidgetItem *, int))); - connect(mScrollTimer, SIGNAL(timeout()) - , this, SLOT(autoScroll())); -} - - -UBDocumentTreeWidget::~UBDocumentTreeWidget() -{ - // NOOP -} - - -void UBDocumentTreeWidget::itemChangedValidation(QTreeWidgetItem * item, int column) -{ - if (column == 0) - { - UBDocumentGroupTreeItem *group = dynamic_cast< UBDocumentGroupTreeItem *>(item); - - if (group) - { - QString name = group->text(0); - - for(int i = 0; i < topLevelItemCount (); i++) - { - QTreeWidgetItem *someTopLevelItem = topLevelItem(i); - - if (someTopLevelItem != group && - someTopLevelItem->text(0) == name) - { - group->setText(0, tr("%1 (copy)").arg(name)); - } - } - } - } -} - - -Qt::DropActions UBDocumentTreeWidget::supportedDropActions() const -{ - return Qt::MoveAction | Qt::CopyAction; -} - - -void UBDocumentTreeWidget::mousePressEvent(QMouseEvent *event) -{ - QTreeWidgetItem* twItem = this->itemAt(event->pos()); - - mSelectedProxyTi = dynamic_cast(twItem); - - QTreeWidget::mousePressEvent(event); -} - - -void UBDocumentTreeWidget::dragEnterEvent(QDragEnterEvent *event) -{ - event->acceptProposedAction(); -} - - -void UBDocumentTreeWidget::dragLeaveEvent(QDragLeaveEvent *event) -{ - Q_UNUSED(event); - - if (mScrollTimer->isActive()) - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - - if (mDropTargetProxyTi) - { - mDropTargetProxyTi->setBackground(0, mBackground); - mDropTargetProxyTi = 0; - } -} - - -void UBDocumentTreeWidget::dragMoveEvent(QDragMoveEvent *event) -{ - QRect boundingFrame = frameRect(); - //setting up automatic scrolling - const int SCROLL_DISTANCE = 4; - int bottomDist = boundingFrame.bottom() - event->pos().y(), topDist = boundingFrame.top() - event->pos().y(); - if(qAbs(bottomDist) <= SCROLL_DISTANCE) - { - mScrollMagnitude = (SCROLL_DISTANCE - bottomDist)*4; - if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); - } - else if(qAbs(topDist) <= SCROLL_DISTANCE) - { - mScrollMagnitude = (- SCROLL_DISTANCE - topDist)*4; - if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); - } - else - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - - - QTreeWidgetItem* underlyingItem = this->itemAt(event->pos()); - - if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - UBDocumentProxyTreeItem *targetProxyTreeItem = dynamic_cast(underlyingItem); - if (targetProxyTreeItem && targetProxyTreeItem != mSelectedProxyTi) - { - event->setDropAction(Qt::CopyAction); - event->accept(); - } - else - { - event->ignore(); - } - } - else - { - UBDocumentGroupTreeItem *groupItem = dynamic_cast(underlyingItem); - - if (groupItem && mSelectedProxyTi && groupItem != mSelectedProxyTi->parent()) - event->acceptProposedAction(); - else - event->ignore(); - } - - if (event->isAccepted()) - { - if (mDropTargetProxyTi) - { - if (underlyingItem != mDropTargetProxyTi) - { - mBackground = underlyingItem->background(0); - mDropTargetProxyTi->setBackground(0, mBackground); - mDropTargetProxyTi = underlyingItem; - mDropTargetProxyTi->setBackground(0, QBrush(QColor("#6682b5"))); - } - } - else - { - mBackground = underlyingItem->background(0); - mDropTargetProxyTi = underlyingItem; - mDropTargetProxyTi->setBackground(0, QBrush(QColor("#6682b5"))); - } - } - else if (mDropTargetProxyTi) - { - mDropTargetProxyTi->setBackground(0, mBackground); - mDropTargetProxyTi = 0; - } -} - - -void UBDocumentTreeWidget::focusInEvent(QFocusEvent *event) -{ - Q_UNUSED(event); - - itemSelectionChanged(); - QTreeWidget::focusInEvent(event); -} - - -void UBDocumentTreeWidget::dropEvent(QDropEvent *event) -{ - if (mDropTargetProxyTi) - { - mDropTargetProxyTi->setBackground(0, mBackground); - mDropTargetProxyTi = 0; - } - - QTreeWidgetItem* underlyingItem = this->itemAt(event->pos()); - - UBDocumentGroupTreeItem *groupItem = dynamic_cast(underlyingItem); - - if (groupItem && mSelectedProxyTi && mSelectedProxyTi->proxy()) - { - UBDocumentGroupTreeItem *sourceGroupItem = dynamic_cast(mSelectedProxyTi->parent()); - bool isTrashItem = sourceGroupItem && sourceGroupItem->isTrashFolder(); - if ((isTrashItem && !groupItem->isTrashFolder()) || - (!isTrashItem && mSelectedProxyTi->proxy()->groupName() != groupItem->groupName())) - { - QString groupName; - if (groupItem->isTrashFolder()) - { - QString oldGroupName = mSelectedProxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); - groupName = UBSettings::trashedDocumentGroupNamePrefix + oldGroupName; - } - else - { - if (groupItem->groupName() == UBSettings::defaultDocumentGroupName) - groupName = ""; - else - groupName = groupItem->groupName(); - } - mSelectedProxyTi->proxy()->setMetaData(UBSettings::documentGroupName, groupName); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(mSelectedProxyTi->proxy()); - - mSelectedProxyTi->parent()->removeChild(mSelectedProxyTi); - - int i = 0; - for (i = 0; i < groupItem->childCount(); i++) - { - QTreeWidgetItem *ti = groupItem->child(i); - UBDocumentProxyTreeItem* pi = dynamic_cast(ti); - if (pi) - { - if (mSelectedProxyTi->proxy()->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) - { - break; - } - } - } - groupItem->insertChild(i, mSelectedProxyTi); - - if (isTrashItem) - mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() | Qt::ItemIsEditable); - - if (groupItem->isTrashFolder()) - mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() ^ Qt::ItemIsEditable); - - //clearSelection(); - expandItem(groupItem); - scrollToItem(mSelectedProxyTi); - - // disabled, as those 2 calls are buggy on windows, the item disappears if we selected them - // - setCurrentItem(mSelectedProxyTi); - mSelectedProxyTi->setSelected(true); - - event->setDropAction(Qt::IgnoreAction); - event->accept(); - } - } - else - { - QTreeWidgetItem* underlyingTreeItem = this->itemAt(event->pos()); - - UBDocumentProxyTreeItem *targetProxyTreeItem = dynamic_cast(underlyingTreeItem); - if (targetProxyTreeItem && targetProxyTreeItem != mSelectedProxyTi) - { - if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - event->setDropAction(Qt::CopyAction); - event->accept(); - - const UBMimeData *mimeData = qobject_cast (event->mimeData()); - - if (mimeData && mimeData->items().size() > 0) - { - int count = 0; - int total = mimeData->items().size(); - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - foreach (UBMimeDataItem sourceItem, mimeData->items()) - { - count++; - - UBApplication::applicationController->showMessage(tr("Copying page %1/%2").arg(count).arg(total), true); - - // TODO UB 4.x Move following code to some controller class - UBGraphicsScene *scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(sourceItem.documentProxy(), sourceItem.sceneIndex()); - if (scene) - { - UBGraphicsScene* sceneClone = scene->sceneDeepCopy(); - - UBDocumentProxy *targetDocProxy = targetProxyTreeItem->proxy(); - - foreach (QUrl relativeFile, scene->relativeDependencies()) - { - QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); - QString target = targetDocProxy->persistencePath() + "/" + relativeFile.toString(); - - QFileInfo fi(target); - QDir d = fi.dir(); - - d.mkpath(d.absolutePath()); - QFile::copy(source, target); - } - - UBPersistenceManager::persistenceManager()->insertDocumentSceneAt(targetDocProxy, sceneClone, targetDocProxy->pageCount()); - - //due to incorrect generation of thumbnails of invisible scene I've used direct copying of thumbnail files - //it's not universal and good way but it's faster - QString from = sourceItem.documentProxy()->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceItem.sceneIndex()); - QString to = targetDocProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetDocProxy->pageCount()); - QFile::remove(to); - QFile::copy(from, to); - } - } - - QApplication::restoreOverrideCursor(); - - UBApplication::applicationController->showMessage(tr("%1 pages copied", "", total).arg(total), false); - } - } - else - { - event->setDropAction(Qt::IgnoreAction); - event->ignore(); - } - } - } -} - - -void UBDocumentTreeWidget::documentUpdated(UBDocumentProxy *pDocument) -{ - UBDocumentProxyTreeItem *treeItem = UBApplication::documentController->findDocument(pDocument); - if (treeItem) - { - QTreeWidgetItem * parent = treeItem->parent(); - - if (parent) - { - for (int i = 0; i < parent->indexOfChild(treeItem); i++) - { - QTreeWidgetItem *ti = parent->child(i); - UBDocumentProxyTreeItem* pi = dynamic_cast(ti); - if (pi) - { - if (pDocument->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) - { - bool selected = treeItem->isSelected(); - parent->removeChild(treeItem); - parent->insertChild(i, treeItem); - for (int j = 0; j < selectedItems().count(); j++) - selectedItems().at(j)->setSelected(false); - if (selected) - treeItem->setSelected(true); - break; - } - } - } - } - } -} - - -UBDocumentProxyTreeItem::UBDocumentProxyTreeItem(QTreeWidgetItem * parent, UBDocumentProxy* proxy, bool isEditable) - : QTreeWidgetItem() - , mProxy(proxy) -{ - Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; - - if (isEditable) - flags |= Qt::ItemIsEditable; - - setFlags(flags); - - int i = 0; - for (i = 0; i < parent->childCount(); i++) - { - QTreeWidgetItem *ti = parent->child(i); - UBDocumentProxyTreeItem* pi = dynamic_cast(ti); - if (pi) - { - if (proxy->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) - { - break; - } - } - } - parent->insertChild(i, this); -} - - -UBDocumentGroupTreeItem::UBDocumentGroupTreeItem(QTreeWidgetItem *parent, bool isEditable) - : QTreeWidgetItem(parent) -{ - Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; - if (isEditable) - flags |= Qt::ItemIsEditable; - setFlags(flags); -} - - -UBDocumentGroupTreeItem::~UBDocumentGroupTreeItem() -{ - // NOOP -} - - -void UBDocumentGroupTreeItem::setGroupName(const QString& groupName) -{ - setText(0, groupName); -} - - -QString UBDocumentGroupTreeItem::groupName() const -{ - return text(0); -} - - -bool UBDocumentGroupTreeItem::isTrashFolder() const -{ - return (0 == (flags() & Qt::ItemIsEditable)) && (groupName() == UBSettings::documentTrashGroupName); -} - -bool UBDocumentGroupTreeItem::isDefaultFolder() const -{ - return (0 == (flags() & Qt::ItemIsEditable)) && (groupName() == UBSettings::defaultDocumentGroupName); -} - - -void UBDocumentTreeWidget::autoScroll() -{ - this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() + mScrollMagnitude); -} +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "UBDocumentTreeWidget.h" + +#include "document/UBDocumentProxy.h" + +#include "core/UBSettings.h" +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBMimeData.h" +#include "core/UBApplicationController.h" +#include "core/UBDocumentManager.h" +#include "document/UBDocumentController.h" + +#include "adaptors/UBThumbnailAdaptor.h" +#include "adaptors/UBSvgSubsetAdaptor.h" +#include "frameworks/UBFileSystemUtils.h" + +#include "core/memcheck.h" + +UBDocumentTreeWidget::UBDocumentTreeWidget(QWidget * parent) + : QTreeWidget(parent) + , mSelectedProxyTi(0) + , mDropTargetProxyTi(0) +{ + setDragDropMode(QAbstractItemView::InternalMove); + setAutoScroll(true); + + mScrollTimer = new QTimer(this); + connect(UBDocumentManager::documentManager(), SIGNAL(documentUpdated(UBDocumentProxy*)) + , this, SLOT(documentUpdated(UBDocumentProxy*))); + + connect(this, SIGNAL(itemChanged(QTreeWidgetItem *, int)) + , this, SLOT(itemChangedValidation(QTreeWidgetItem *, int))); + connect(mScrollTimer, SIGNAL(timeout()) + , this, SLOT(autoScroll())); +} + + +UBDocumentTreeWidget::~UBDocumentTreeWidget() +{ + // NOOP +} + + +void UBDocumentTreeWidget::itemChangedValidation(QTreeWidgetItem * item, int column) +{ + if (column == 0) + { + UBDocumentGroupTreeItem *group = dynamic_cast< UBDocumentGroupTreeItem *>(item); + + if (group) + { + QString name = group->text(0); + + for(int i = 0; i < topLevelItemCount (); i++) + { + QTreeWidgetItem *someTopLevelItem = topLevelItem(i); + + if (someTopLevelItem != group && + someTopLevelItem->text(0) == name) + { + group->setText(0, tr("%1 (copy)").arg(name)); + } + } + } + } +} + + +Qt::DropActions UBDocumentTreeWidget::supportedDropActions() const +{ + return Qt::MoveAction | Qt::CopyAction; +} + + +void UBDocumentTreeWidget::mousePressEvent(QMouseEvent *event) +{ + QTreeWidgetItem* twItem = this->itemAt(event->pos()); + + mSelectedProxyTi = dynamic_cast(twItem); + + QTreeWidget::mousePressEvent(event); +} + + +void UBDocumentTreeWidget::dragEnterEvent(QDragEnterEvent *event) +{ + event->acceptProposedAction(); +} + + +void UBDocumentTreeWidget::dragLeaveEvent(QDragLeaveEvent *event) +{ + Q_UNUSED(event); + + if (mScrollTimer->isActive()) + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + + if (mDropTargetProxyTi) + { + mDropTargetProxyTi->setBackground(0, mBackground); + mDropTargetProxyTi = 0; + } +} + + +void UBDocumentTreeWidget::dragMoveEvent(QDragMoveEvent *event) +{ + QRect boundingFrame = frameRect(); + //setting up automatic scrolling + const int SCROLL_DISTANCE = 4; + int bottomDist = boundingFrame.bottom() - event->pos().y(), topDist = boundingFrame.top() - event->pos().y(); + if(qAbs(bottomDist) <= SCROLL_DISTANCE) + { + mScrollMagnitude = (SCROLL_DISTANCE - bottomDist)*4; + if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); + } + else if(qAbs(topDist) <= SCROLL_DISTANCE) + { + mScrollMagnitude = (- SCROLL_DISTANCE - topDist)*4; + if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); + } + else + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + + + QTreeWidgetItem* underlyingItem = this->itemAt(event->pos()); + + if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + UBDocumentProxyTreeItem *targetProxyTreeItem = dynamic_cast(underlyingItem); + if (targetProxyTreeItem && targetProxyTreeItem != mSelectedProxyTi) + { + event->setDropAction(Qt::CopyAction); + event->accept(); + } + else + { + event->ignore(); + } + } + else + { + UBDocumentGroupTreeItem *groupItem = dynamic_cast(underlyingItem); + + if (groupItem && mSelectedProxyTi && groupItem != mSelectedProxyTi->parent()) + event->acceptProposedAction(); + else + event->ignore(); + } + + if (event->isAccepted()) + { + if (mDropTargetProxyTi) + { + if (underlyingItem != mDropTargetProxyTi) + { + mBackground = underlyingItem->background(0); + mDropTargetProxyTi->setBackground(0, mBackground); + mDropTargetProxyTi = underlyingItem; + mDropTargetProxyTi->setBackground(0, QBrush(QColor("#6682b5"))); + } + } + else + { + mBackground = underlyingItem->background(0); + mDropTargetProxyTi = underlyingItem; + mDropTargetProxyTi->setBackground(0, QBrush(QColor("#6682b5"))); + } + } + else if (mDropTargetProxyTi) + { + mDropTargetProxyTi->setBackground(0, mBackground); + mDropTargetProxyTi = 0; + } +} + + +void UBDocumentTreeWidget::focusInEvent(QFocusEvent *event) +{ + Q_UNUSED(event); + + // Tolik + //itemSelectionChanged(); + + QTreeWidget::focusInEvent(event); +} + + +void UBDocumentTreeWidget::dropEvent(QDropEvent *event) +{ + if (mDropTargetProxyTi) + { + mDropTargetProxyTi->setBackground(0, mBackground); + mDropTargetProxyTi = 0; + } + + QTreeWidgetItem* underlyingItem = this->itemAt(event->pos()); + + UBDocumentGroupTreeItem *groupItem = dynamic_cast(underlyingItem); + + if (groupItem && mSelectedProxyTi && mSelectedProxyTi->proxy()) + { + UBDocumentGroupTreeItem *sourceGroupItem = dynamic_cast(mSelectedProxyTi->parent()); + bool isTrashItem = sourceGroupItem && sourceGroupItem->isTrashFolder(); + if ((isTrashItem && !groupItem->isTrashFolder()) || + (!isTrashItem && mSelectedProxyTi->proxy()->groupName() != groupItem->groupName())) + { + QString groupName; + if (groupItem->isTrashFolder()) + { + QString oldGroupName = mSelectedProxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); + groupName = UBSettings::trashedDocumentGroupNamePrefix + oldGroupName; + } + else + { + if (groupItem->groupName() == UBSettings::defaultDocumentGroupName) + groupName = ""; + else + groupName = groupItem->groupName(); + } + mSelectedProxyTi->proxy()->setMetaData(UBSettings::documentGroupName, groupName); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(mSelectedProxyTi->proxy()); + + mSelectedProxyTi->parent()->removeChild(mSelectedProxyTi); + + int i = 0; + for (i = 0; i < groupItem->childCount(); i++) + { + QTreeWidgetItem *ti = groupItem->child(i); + UBDocumentProxyTreeItem* pi = dynamic_cast(ti); + if (pi) + { + if (mSelectedProxyTi->proxy()->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) + { + break; + } + } + } + groupItem->insertChild(i, mSelectedProxyTi); + + if (isTrashItem) + mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() | Qt::ItemIsEditable); + + if (groupItem->isTrashFolder()) + mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() ^ Qt::ItemIsEditable); + + //clearSelection(); + expandItem(groupItem); + scrollToItem(mSelectedProxyTi); + + // disabled, as those 2 calls are buggy on windows, the item disappears if we selected them + // + setCurrentItem(mSelectedProxyTi); + mSelectedProxyTi->setSelected(true); + + event->setDropAction(Qt::IgnoreAction); + event->accept(); + } + } + else + { + QTreeWidgetItem* underlyingTreeItem = this->itemAt(event->pos()); + + UBDocumentProxyTreeItem *targetProxyTreeItem = dynamic_cast(underlyingTreeItem); + if (targetProxyTreeItem && targetProxyTreeItem != mSelectedProxyTi) + { + if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + event->setDropAction(Qt::CopyAction); + event->accept(); + + const UBMimeData *mimeData = qobject_cast (event->mimeData()); + + if (mimeData && mimeData->items().size() > 0) + { + int count = 0; + int total = mimeData->items().size(); + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + foreach (UBMimeDataItem sourceItem, mimeData->items()) + { + count++; + + UBApplication::applicationController->showMessage(tr("Copying page %1/%2").arg(count).arg(total), true); + + // TODO UB 4.x Move following code to some controller class + UBGraphicsScene *scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(sourceItem.documentProxy(), sourceItem.sceneIndex()); + if (scene) + { + UBGraphicsScene* sceneClone = scene->sceneDeepCopy(); + + UBDocumentProxy *targetDocProxy = targetProxyTreeItem->proxy(); + + foreach (QUrl relativeFile, scene->relativeDependencies()) + { + QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); + QString target = targetDocProxy->persistencePath() + "/" + relativeFile.toString(); + + QFileInfo fi(target); + QDir d = fi.dir(); + + d.mkpath(d.absolutePath()); + QFile::copy(source, target); + } + + UBPersistenceManager::persistenceManager()->insertDocumentSceneAt(targetDocProxy, sceneClone, targetDocProxy->pageCount()); + + //due to incorrect generation of thumbnails of invisible scene I've used direct copying of thumbnail files + //it's not universal and good way but it's faster + QString from = sourceItem.documentProxy()->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceItem.sceneIndex()); + QString to = targetDocProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetDocProxy->pageCount()); + QFile::remove(to); + QFile::copy(from, to); + } + } + + QApplication::restoreOverrideCursor(); + + UBApplication::applicationController->showMessage(tr("%1 pages copied", "", total).arg(total), false); + } + } + else + { + event->setDropAction(Qt::IgnoreAction); + event->ignore(); + } + } + } +} + + +void UBDocumentTreeWidget::documentUpdated(UBDocumentProxy *pDocument) +{ + UBDocumentProxyTreeItem *treeItem = UBApplication::documentController->findDocument(pDocument); + if (treeItem) + { + QTreeWidgetItem * parent = treeItem->parent(); + + if (parent) + { + for (int i = 0; i < parent->indexOfChild(treeItem); i++) + { + QTreeWidgetItem *ti = parent->child(i); + UBDocumentProxyTreeItem* pi = dynamic_cast(ti); + if (pi) + { + if (pDocument->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) + { + bool selected = treeItem->isSelected(); + parent->removeChild(treeItem); + parent->insertChild(i, treeItem); + for (int j = 0; j < selectedItems().count(); j++) + selectedItems().at(j)->setSelected(false); + if (selected) + treeItem->setSelected(true); + break; + } + } + } + } + } +} + + +UBDocumentProxyTreeItem::UBDocumentProxyTreeItem(QTreeWidgetItem * parent, UBDocumentProxy* proxy, bool isEditable) + : QTreeWidgetItem() + , mProxy(proxy) +{ + Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; + + if (isEditable) + flags |= Qt::ItemIsEditable; + + setFlags(flags); + + int i = 0; + for (i = 0; i < parent->childCount(); i++) + { + QTreeWidgetItem *ti = parent->child(i); + UBDocumentProxyTreeItem* pi = dynamic_cast(ti); + if (pi) + { + if (proxy->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) + { + break; + } + } + } + parent->insertChild(i, this); +} + + +UBDocumentGroupTreeItem::UBDocumentGroupTreeItem(QTreeWidgetItem *parent, bool isEditable) + : QTreeWidgetItem(parent) +{ + Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; + if (isEditable) + flags |= Qt::ItemIsEditable; + setFlags(flags); +} + + +UBDocumentGroupTreeItem::~UBDocumentGroupTreeItem() +{ + // NOOP +} + + +void UBDocumentGroupTreeItem::setGroupName(const QString& groupName) +{ + setText(0, groupName); +} + + +QString UBDocumentGroupTreeItem::groupName() const +{ + return text(0); +} + + +bool UBDocumentGroupTreeItem::isTrashFolder() const +{ + return (0 == (flags() & Qt::ItemIsEditable)) && (groupName() == UBSettings::documentTrashGroupName); +} + +bool UBDocumentGroupTreeItem::isDefaultFolder() const +{ + return (0 == (flags() & Qt::ItemIsEditable)) && (groupName() == UBSettings::defaultDocumentGroupName); +} + + +void UBDocumentTreeWidget::autoScroll() +{ + this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() + mScrollMagnitude); +} diff --git a/src/gui/UBNavigatorPalette.cpp b/src/gui/UBNavigatorPalette.cpp index 92814ed1..b14ae9ed 100644 --- a/src/gui/UBNavigatorPalette.cpp +++ b/src/gui/UBNavigatorPalette.cpp @@ -1,167 +1,144 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "UBNavigatorPalette.h" -#include "core/UBApplication.h" -#include "board/UBBoardController.h" - -#include "core/memcheck.h" - -/** - * \brief Constructor - * @param parent as the parent widget - * @param name as the object name - */ -UBNavigatorPalette::UBNavigatorPalette(QWidget *parent, const char *name): - UBDockPalette(eUBDockPaletteType_LEFT, parent, name) - , mNavigator(NULL) - , mLayout(NULL) - , mHLayout(NULL) - , mPageNbr(NULL) - , mClock(NULL) -{ - // Build the gui - mLayout = new QVBoxLayout(this); - mLayout->setContentsMargins(customMargin(), customMargin(), 2*border() + customMargin(), customMargin()); - setLayout(mLayout); - - mNavigator = new UBDocumentNavigator(this); - mNavigator->setStyleSheet(QString("background-color : transparent;")); - mLayout->addWidget(mNavigator, 1); - - mHLayout = new QHBoxLayout(); - mLayout->addLayout(mHLayout, 0); - - mPageNbr = new QLabel(this); - mClock = new QLabel(this); - mHLayout->addWidget(mPageNbr); - mHLayout->addWidget(mClock); - - // Configure the page number indicator - mPageNbr->setStyleSheet(QString("QLabel { color: white; background-color: transparent; border: none; font-family: Arial; font-weight: bold; font-size: 20px }")); - setPageNumber(0, 0); - mPageNbr->setAlignment(Qt::AlignHCenter); - - // Configure the clock - mClock->setStyleSheet(QString("QLabel {color: white; background-color: transparent; text-align: center; font-family: Arial; font-weight: bold; font-size: 20px}")); - mTimeFormat = QLocale::system().timeFormat(QLocale::ShortFormat); - mClock->setAlignment(Qt::AlignHCenter); - - //strip seconds - mTimeFormat = mTimeFormat.remove(":ss"); - mTimeFormat = mTimeFormat.remove(":s"); - mTimerID = startTimer(1000); - - connect(mNavigator, SIGNAL(changeCurrentPage()), this, SLOT(changeCurrentPage())); -} - -/** - * \brief Destructor - */ -UBNavigatorPalette::~UBNavigatorPalette() -{ - killTimer(mTimerID); - - if(NULL != mClock) - { - delete mClock; - mClock = NULL; - } - if(NULL != mPageNbr) - { - delete mPageNbr; - mPageNbr = NULL; - } - if(NULL != mHLayout) - { - delete mHLayout; - mHLayout = NULL; - } - if(NULL != mLayout) - { - delete mLayout; - mLayout = NULL; - } - if(NULL != mNavigator) - { - delete mNavigator; - mNavigator = NULL; - } -} - -/** - * \brief Set the current document in the navigator - * @param document as the given document - */ -void UBNavigatorPalette::setDocument(UBDocumentProxy *document) -{ - if(mNavigator->currentDoc() != document) - { - mNavigator->setDocument(document); - } -} - -/** - * \brief Change the current page - */ -void UBNavigatorPalette::changeCurrentPage() -{ - // Get the index of the page to display - int iPage = mNavigator->selectedPageNumber(); - if(NO_PAGESELECTED != iPage) - { - // Display the selected page - UBApplication::boardController->setActiveDocumentScene(mNavigator->currentDoc(), iPage); - } -} - -/** - * \brief Refresh the thumbnails widget - */ -void UBNavigatorPalette::refresh() -{ - mNavigator->setDocument(UBApplication::boardController->activeDocument()); -} - -/** - * \brief Handle the resize event - * @param event as the resize event - */ -void UBNavigatorPalette::resizeEvent(QResizeEvent *event) -{ - UBDockPalette::resizeEvent(event); - if(NULL != mNavigator) - { - mNavigator->setMinimumHeight(height() - 2*border()); - } -} - -void UBNavigatorPalette::timerEvent(QTimerEvent *event) -{ - Q_UNUSED(event); - updateTime(); -} - -void UBNavigatorPalette::updateTime() -{ - if (mClock) - { - mClock->setText(QLocale::system().toString (QTime::currentTime(), mTimeFormat)); - } -} - -void UBNavigatorPalette::setPageNumber(int current, int total) -{ - mPageNbr->setText(QString("%1 / %2").arg(current).arg(total)); -} +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "UBNavigatorPalette.h" +#include "core/UBApplication.h" +#include "board/UBBoardController.h" + +#include "core/memcheck.h" + +/** + * \brief Constructor + * @param parent as the parent widget + * @param name as the object name + */ +UBNavigatorPalette::UBNavigatorPalette(QWidget *parent, const char *name): + UBDockPalette(eUBDockPaletteType_LEFT, parent, name) + , mNavigator(NULL) + , mLayout(NULL) + , mHLayout(NULL) + , mPageNbr(NULL) + , mClock(NULL) +{ + // Build the gui + mLayout = new QVBoxLayout(this); + mLayout->setContentsMargins(customMargin(), customMargin(), 2*border() + customMargin(), customMargin()); + setLayout(mLayout); + + mNavigator = new UBDocumentNavigator(this); + mNavigator->setStyleSheet(QString("background-color : transparent;")); + mLayout->addWidget(mNavigator, 1); + + mHLayout = new QHBoxLayout(); + mLayout->addLayout(mHLayout, 0); + + mPageNbr = new QLabel(this); + mClock = new QLabel(this); + mHLayout->addWidget(mPageNbr); + mHLayout->addWidget(mClock); + + // Configure the page number indicator + mPageNbr->setStyleSheet(QString("QLabel { color: white; background-color: transparent; border: none; font-family: Arial; font-weight: bold; font-size: 20px }")); + setPageNumber(0, 0); + mPageNbr->setAlignment(Qt::AlignHCenter); + + // Configure the clock + mClock->setStyleSheet(QString("QLabel {color: white; background-color: transparent; text-align: center; font-family: Arial; font-weight: bold; font-size: 20px}")); + mTimeFormat = QLocale::system().timeFormat(QLocale::ShortFormat); + mClock->setAlignment(Qt::AlignHCenter); + + //strip seconds + mTimeFormat = mTimeFormat.remove(":ss"); + mTimeFormat = mTimeFormat.remove(":s"); + mTimerID = startTimer(1000); + +} + +/** + * \brief Destructor + */ +UBNavigatorPalette::~UBNavigatorPalette() +{ + killTimer(mTimerID); + + if(NULL != mClock) + { + delete mClock; + mClock = NULL; + } + if(NULL != mPageNbr) + { + delete mPageNbr; + mPageNbr = NULL; + } + if(NULL != mHLayout) + { + delete mHLayout; + mHLayout = NULL; + } + if(NULL != mLayout) + { + delete mLayout; + mLayout = NULL; + } + if(NULL != mNavigator) + { + delete mNavigator; + mNavigator = NULL; + } +} + +/** + * \brief Set the current document in the navigator + * @param document as the given document + */ + +/** + * \brief Refresh the thumbnails widget + */ +void UBNavigatorPalette::refresh() +{ +} + +/** + * \brief Handle the resize event + * @param event as the resize event + */ +void UBNavigatorPalette::resizeEvent(QResizeEvent *event) +{ + UBDockPalette::resizeEvent(event); + if(NULL != mNavigator) + { + mNavigator->setMinimumHeight(height() - 2*border()); + } +} + +void UBNavigatorPalette::timerEvent(QTimerEvent *event) +{ + Q_UNUSED(event); + updateTime(); +} + +void UBNavigatorPalette::updateTime() +{ + if (mClock) + { + mClock->setText(QLocale::system().toString (QTime::currentTime(), mTimeFormat)); + } +} + +void UBNavigatorPalette::setPageNumber(int current, int total) +{ + mPageNbr->setText(QString("%1 / %2").arg(current).arg(total)); +} diff --git a/src/gui/UBNavigatorPalette.h b/src/gui/UBNavigatorPalette.h index 0f2cbb96..ccc0756d 100644 --- a/src/gui/UBNavigatorPalette.h +++ b/src/gui/UBNavigatorPalette.h @@ -1,66 +1,64 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef UBNAVIGATORPALETTE_H -#define UBNAVIGATORPALETTE_H - -#include -#include -#include -#include -#include -#include -#include - -#include "UBDockPalette.h" -#include "UBDocumentNavigator.h" -#include "document/UBDocumentProxy.h" - - -class UBNavigatorPalette : public UBDockPalette -{ - Q_OBJECT -public: - UBNavigatorPalette(QWidget* parent=0, const char* name="navigatorPalette"); - ~UBNavigatorPalette(); - - void setDocument(UBDocumentProxy* document); - void refresh(); - -public slots: - void setPageNumber(int current, int total); - -protected: - virtual void resizeEvent(QResizeEvent *event); - virtual void timerEvent(QTimerEvent *event); - -private: - void updateTime(); - - /** The thumbnails navigator widget */ - UBDocumentNavigator* mNavigator; - /** The layout */ - QVBoxLayout* mLayout; - QHBoxLayout* mHLayout; - QLabel* mPageNbr; - QLabel* mClock; - QString mTimeFormat; - int mTimerID; - -private slots: - void changeCurrentPage(); -}; - - -#endif // UBNAVIGATORPALETTE_H +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef UBNAVIGATORPALETTE_H +#define UBNAVIGATORPALETTE_H + +#include +#include +#include +#include +#include +#include +#include + +#include "UBDockPalette.h" +#include "UBDocumentNavigator.h" +#include "document/UBDocumentProxy.h" + + +class UBNavigatorPalette : public UBDockPalette +{ + Q_OBJECT +public: + UBNavigatorPalette(QWidget* parent=0, const char* name="navigatorPalette"); + ~UBNavigatorPalette(); + + void setDocument(UBDocumentProxy* document); + void refresh(); + +public slots: + void setPageNumber(int current, int total); + +protected: + virtual void resizeEvent(QResizeEvent *event); + virtual void timerEvent(QTimerEvent *event); + +private: + void updateTime(); + + /** The thumbnails navigator widget */ + UBDocumentNavigator* mNavigator; + /** The layout */ + QVBoxLayout* mLayout; + QHBoxLayout* mHLayout; + QLabel* mPageNbr; + QLabel* mClock; + QString mTimeFormat; + int mTimerID; + +}; + + +#endif // UBNAVIGATORPALETTE_H diff --git a/src/gui/UBPageNavigationWidget.cpp b/src/gui/UBPageNavigationWidget.cpp index 5f8d824a..0cd9a7ab 100644 --- a/src/gui/UBPageNavigationWidget.cpp +++ b/src/gui/UBPageNavigationWidget.cpp @@ -1,206 +1,173 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "UBPageNavigationWidget.h" -#include "core/UBApplication.h" - -#include "board/UBBoardController.h" - -#include "globals/UBGlobals.h" - -#include "core/memcheck.h" - -/** - * \brief Constructor - * @param parent as the parent widget - * @param name as the object name - */ -UBPageNavigationWidget::UBPageNavigationWidget(QWidget *parent, const char *name):UBDockPaletteWidget(parent) - , mNavigator(NULL) - , mLayout(NULL) - , mHLayout(NULL) - , mPageNbr(NULL) - , mClock(NULL) -{ - setObjectName(name); - mName = "PageNavigator"; - mVisibleState = true; - - SET_STYLE_SHEET(); - - mIconToRight = QPixmap(":images/pages_open.png"); - mIconToLeft = QPixmap(":images/pages_close.png"); - - // Build the gui - mLayout = new QVBoxLayout(this); - setLayout(mLayout); - - mNavigator = new UBDocumentNavigator(this); - mLayout->addWidget(mNavigator, 1); - - mHLayout = new QHBoxLayout(); - mLayout->addLayout(mHLayout, 0); - - mPageNbr = new QLabel(this); - mClock = new QLabel(this); - mHLayout->addWidget(mPageNbr); - mHLayout->addWidget(mClock); - - // Configure the page number indicator - mPageNbr->setStyleSheet(QString("QLabel { color: white; background-color: transparent; border: none; font-family: Arial; font-weight: bold; font-size: 20px }")); - setPageNumber(0, 0); - mPageNbr->setAlignment(Qt::AlignHCenter); - - // Configure the clock - mClock->setStyleSheet(QString("QLabel {color: white; background-color: transparent; text-align: center; font-family: Arial; font-weight: bold; font-size: 20px}")); - mTimeFormat = QLocale::system().timeFormat(QLocale::ShortFormat); - mClock->setAlignment(Qt::AlignHCenter); - - //strip seconds - mTimeFormat = mTimeFormat.remove(":ss"); - mTimeFormat = mTimeFormat.remove(":s"); - mTimerID = startTimer(1000); - - connect(mNavigator, SIGNAL(changeCurrentPage()), this, SLOT(changeCurrentPage())); - connect(UBApplication::boardController, SIGNAL(setDocOnPageNavigator(UBDocumentProxy*)), this, SLOT(onSetDocOnPageNavigator(UBDocumentProxy*))); -} - -/** - * \brief Destructor - */ -UBPageNavigationWidget::~UBPageNavigationWidget() -{ - killTimer(mTimerID); - - if(NULL != mClock) - { - delete mClock; - mClock = NULL; - } - if(NULL != mPageNbr) - { - delete mPageNbr; - mPageNbr = NULL; - } - if(NULL != mHLayout) - { - delete mHLayout; - mHLayout = NULL; - } - if(NULL != mLayout) - { - delete mLayout; - mLayout = NULL; - } - if(NULL != mNavigator) - { - delete mNavigator; - mNavigator = NULL; - } -} - -/** - * \brief Set the current document in the navigator - * @param document as the given document - */ -void UBPageNavigationWidget::setDocument(UBDocumentProxy *document) -{ - if(mNavigator->currentDoc() != document) - { - mNavigator->setDocument(document); - } -} - -/** - * \brief Change the current page - */ -void UBPageNavigationWidget::changeCurrentPage() -{ - // Get the index of the page to display - int iPage = mNavigator->selectedPageNumber(); - if(NO_PAGESELECTED != iPage) - { - // Display the selected page - UBApplication::boardController->setActiveDocumentScene(mNavigator->currentDoc(), iPage); - - // emit here the signal to indicate that page change - UBApplication::boardController->notifyPageChanged(); - } -} - -/** - * \brief Refresh the thumbnails widget - */ -void UBPageNavigationWidget::refresh() -{ - mNavigator->setDocument(UBApplication::boardController->activeDocument()); -} - -/** - * \brief Notify a timer event - * @param event as the timer event - */ -void UBPageNavigationWidget::timerEvent(QTimerEvent *event) -{ - Q_UNUSED(event); - updateTime(); -} - -/** - * \brief Update the current time - */ -void UBPageNavigationWidget::updateTime() -{ - if (mClock) - { - mClock->setText(QLocale::system().toString (QTime::currentTime(), mTimeFormat)); - } -} - -/** - * \brief Set the page number - * @param current as the current page - * @param total as the total number of pages - */ -void UBPageNavigationWidget::setPageNumber(int current, int total) -{ - mPageNbr->setText(QString("%1 / %2").arg(current).arg(UBApplication::boardController->sceneIndexFromPage(total))); -} - -/** - * \brief Get the custom margin value - * @return the custom margin value - */ -int UBPageNavigationWidget::customMargin() -{ - return 5; -} - -/** - * \brief Get the border value - * @return the border value - */ -int UBPageNavigationWidget::border() -{ - return 15; -} - -/** - * \brief Set the current document - * @param doc as the current document - */ -void UBPageNavigationWidget::onSetDocOnPageNavigator(UBDocumentProxy *doc) -{ - setDocument(doc); -} +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "UBPageNavigationWidget.h" +#include "core/UBApplication.h" + +#include "board/UBBoardController.h" + +#include "document/UBDocumentContainer.h" + +#include "globals/UBGlobals.h" + +#include "core/memcheck.h" + +/** + * \brief Constructor + * @param parent as the parent widget + * @param name as the object name + */ +UBPageNavigationWidget::UBPageNavigationWidget(QWidget *parent, const char *name):UBDockPaletteWidget(parent) + , mNavigator(NULL) + , mLayout(NULL) + , mHLayout(NULL) + , mPageNbr(NULL) + , mClock(NULL) +{ + setObjectName(name); + mName = "PageNavigator"; + mVisibleState = true; + + SET_STYLE_SHEET(); + + mIconToRight = QPixmap(":images/pages_open.png"); + mIconToLeft = QPixmap(":images/pages_close.png"); + + // Build the gui + mLayout = new QVBoxLayout(this); + setLayout(mLayout); + + mNavigator = new UBDocumentNavigator(this); + mLayout->addWidget(mNavigator, 1); + + mHLayout = new QHBoxLayout(); + mLayout->addLayout(mHLayout, 0); + + mPageNbr = new QLabel(this); + mClock = new QLabel(this); + mHLayout->addWidget(mPageNbr); + mHLayout->addWidget(mClock); + + // Configure the page number indicator + mPageNbr->setStyleSheet(QString("QLabel { color: white; background-color: transparent; border: none; font-family: Arial; font-weight: bold; font-size: 20px }")); + setPageNumber(0, 0); + mPageNbr->setAlignment(Qt::AlignHCenter); + + // Configure the clock + mClock->setStyleSheet(QString("QLabel {color: white; background-color: transparent; text-align: center; font-family: Arial; font-weight: bold; font-size: 20px}")); + mTimeFormat = QLocale::system().timeFormat(QLocale::ShortFormat); + mClock->setAlignment(Qt::AlignHCenter); + + //strip seconds + mTimeFormat = mTimeFormat.remove(":ss"); + mTimeFormat = mTimeFormat.remove(":s"); + mTimerID = startTimer(1000); + + //connect(mNavigator, SIGNAL(changeCurrentPage()), this, SLOT(changeCurrentPage())); + //connect(UBApplication::boardController, SIGNAL(setDocOnPageNavigator(UBDocumentProxy*)), this, SLOT(onSetDocOnPageNavigator(UBDocumentProxy*))); +} + +/** + * \brief Destructor + */ +UBPageNavigationWidget::~UBPageNavigationWidget() +{ + killTimer(mTimerID); + + if(NULL != mClock) + { + delete mClock; + mClock = NULL; + } + if(NULL != mPageNbr) + { + delete mPageNbr; + mPageNbr = NULL; + } + if(NULL != mHLayout) + { + delete mHLayout; + mHLayout = NULL; + } + if(NULL != mLayout) + { + delete mLayout; + mLayout = NULL; + } + if(NULL != mNavigator) + { + delete mNavigator; + mNavigator = NULL; + } +} + + +/** + * \brief Refresh the thumbnails widget + */ +void UBPageNavigationWidget::refresh() +{ + // TOLIK!!! + // mNavigator->setDocument(UBApplication::boardController->activeDocument()); +} + +/** + * \brief Notify a timer event + * @param event as the timer event + */ +void UBPageNavigationWidget::timerEvent(QTimerEvent *event) +{ + Q_UNUSED(event); + updateTime(); +} + +/** + * \brief Update the current time + */ +void UBPageNavigationWidget::updateTime() +{ + if (mClock) + { + mClock->setText(QLocale::system().toString (QTime::currentTime(), mTimeFormat)); + } +} + +/** + * \brief Set the page number + * @param current as the current page + * @param total as the total number of pages + */ +void UBPageNavigationWidget::setPageNumber(int current, int total) +{ + mPageNbr->setText(QString("%1 / %2").arg(current).arg(UBDocumentContainer::sceneIndexFromPage(total))); +} + +/** + * \brief Get the custom margin value + * @return the custom margin value + */ +int UBPageNavigationWidget::customMargin() +{ + return 5; +} + +/** + * \brief Get the border value + * @return the border value + */ +int UBPageNavigationWidget::border() +{ + return 15; +} + diff --git a/src/gui/UBPageNavigationWidget.h b/src/gui/UBPageNavigationWidget.h index fdf80952..92501c44 100644 --- a/src/gui/UBPageNavigationWidget.h +++ b/src/gui/UBPageNavigationWidget.h @@ -1,75 +1,71 @@ -/* - * 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 - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef UBPAGENAVIGATIONWIDGET_H -#define UBPAGENAVIGATIONWIDGET_H - -#include -#include -#include -#include -#include -#include -#include - -#include "UBDocumentNavigator.h" -#include "UBDockPaletteWidget.h" -#include "document/UBDocumentProxy.h" - -class UBPageNavigationWidget : public UBDockPaletteWidget -{ - Q_OBJECT -public: - UBPageNavigationWidget(QWidget* parent=0, const char* name="UBPageNavigationWidget"); - ~UBPageNavigationWidget(); - void setDocument(UBDocumentProxy* document); - void refresh(); - - bool visibleInMode(eUBDockPaletteWidgetMode mode) - { - return mode == eUBDockPaletteWidget_BOARD; - } - -signals: - void resizeRequest(QResizeEvent* event); - -public slots: - void setPageNumber(int current, int total); - -protected: - virtual void timerEvent(QTimerEvent *event); - -private slots: - void onSetDocOnPageNavigator(UBDocumentProxy* doc); - -private: - void updateTime(); - int customMargin(); - int border(); - - /** The thumbnails navigator widget */ - UBDocumentNavigator* mNavigator; - /** The layout */ - QVBoxLayout* mLayout; - QHBoxLayout* mHLayout; - QLabel* mPageNbr; - QLabel* mClock; - QString mTimeFormat; - int mTimerID; - -private slots: - void changeCurrentPage(); -}; - -#endif // UBPAGENAVIGATIONWIDGET_H +/* + * 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 + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef UBPAGENAVIGATIONWIDGET_H +#define UBPAGENAVIGATIONWIDGET_H + +#include +#include +#include +#include +#include +#include +#include + +#include "UBDocumentNavigator.h" +#include "UBDockPaletteWidget.h" +#include "document/UBDocumentProxy.h" + +class UBPageNavigationWidget : public UBDockPaletteWidget +{ + Q_OBJECT +public: + UBPageNavigationWidget(QWidget* parent=0, const char* name="UBPageNavigationWidget"); + ~UBPageNavigationWidget(); + //void setDocument(UBDocumentProxy* document); + void refresh(); + + bool visibleInMode(eUBDockPaletteWidgetMode mode) + { + return mode == eUBDockPaletteWidget_BOARD; + } + +signals: + void resizeRequest(QResizeEvent* event); + +public slots: + void setPageNumber(int current, int total); + +protected: + virtual void timerEvent(QTimerEvent *event); + + +private: + void updateTime(); + int customMargin(); + int border(); + + /** The thumbnails navigator widget */ + UBDocumentNavigator* mNavigator; + /** The layout */ + QVBoxLayout* mLayout; + QHBoxLayout* mHLayout; + QLabel* mPageNbr; + QLabel* mClock; + QString mTimeFormat; + int mTimerID; + +}; + +#endif // UBPAGENAVIGATIONWIDGET_H diff --git a/src/gui/UBThumbnailWidget.cpp b/src/gui/UBThumbnailWidget.cpp index 92ea2940..bf2f69f5 100644 --- a/src/gui/UBThumbnailWidget.cpp +++ b/src/gui/UBThumbnailWidget.cpp @@ -211,7 +211,7 @@ void UBThumbnailWidget::mousePressEvent(QMouseEvent *event) UBSceneThumbnailPixmap* sceneItem = dynamic_cast(itemAt(mMousePressPos)); if(sceneItem){ - int pageIndex = UBApplication::boardController->pageFromSceneIndex(sceneItem->sceneIndex()); + int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneItem->sceneIndex()); if(pageIndex == 0){ event->ignore(); return; @@ -761,7 +761,7 @@ UBSceneThumbnailNavigPixmap::UBSceneThumbnailNavigPixmap(const QPixmap& pix, UBD , bCanMoveDown(false) , bCanDuplicate(false) { - if(0 <= UBApplication::boardController->pageFromSceneIndex(pSceneIndex)){ + if(0 <= UBDocumentContainer::pageFromSceneIndex(pSceneIndex)){ setAcceptsHoverEvents(true); setFlag(QGraphicsItem::ItemIsSelectable, true); } @@ -839,7 +839,7 @@ void UBSceneThumbnailNavigPixmap::updateButtonsState() bCanDuplicate = false; if(proxy()){ - int pageIndex = UBApplication::boardController->pageFromSceneIndex(sceneIndex()); + int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneIndex()); UBDocumentController* documentController = UBApplication::documentController; bCanDelete = documentController->pageCanBeDeleted(pageIndex); bCanMoveUp = documentController->pageCanBeMovedUp(pageIndex); @@ -853,25 +853,24 @@ void UBSceneThumbnailNavigPixmap::updateButtonsState() void UBSceneThumbnailNavigPixmap::deletePage() { - QList itemsToDelete; - itemsToDelete << this; - - UBApplication::documentController->deletePages(itemsToDelete); + UBApplication::boardController->deleteScene(sceneIndex()); } void UBSceneThumbnailNavigPixmap::duplicatePage() { - UBApplication::boardController->duplicateScene(); + UBApplication::boardController->duplicateScene(sceneIndex()); } void UBSceneThumbnailNavigPixmap::moveUpPage() { - UBApplication::documentController->moveSceneToIndex(proxy(), sceneIndex(), sceneIndex() - 1); + if (sceneIndex()!=0) + UBApplication::boardController->moveSceneToIndex(sceneIndex(), sceneIndex() - 1); } void UBSceneThumbnailNavigPixmap::moveDownPage() { - UBApplication::documentController->moveSceneToIndex(proxy(), sceneIndex(), sceneIndex() + 1); + if (sceneIndex() < UBApplication::boardController->selectedDocument()->pageCount()-1) + UBApplication::boardController->moveSceneToIndex(sceneIndex(), sceneIndex() + 1); } void UBImgTextThumbnailElement::Place(int row, int col, qreal width, qreal height) diff --git a/src/gui/UBThumbnailWidget.h b/src/gui/UBThumbnailWidget.h index 90f5025c..b6a94822 100644 --- a/src/gui/UBThumbnailWidget.h +++ b/src/gui/UBThumbnailWidget.h @@ -400,19 +400,19 @@ class UBThumbnailTextItem : public QGraphicsTextItem class UBImgTextThumbnailElement { private: - QGraphicsItem* thumbnail; + UBSceneThumbnailNavigPixmap* thumbnail; UBThumbnailTextItem* caption; int border; public: - UBImgTextThumbnailElement(QGraphicsItem* thumb, UBThumbnailTextItem* text): border(0) + UBImgTextThumbnailElement(UBSceneThumbnailNavigPixmap* thumb, UBThumbnailTextItem* text): border(0) { this->thumbnail = thumb; this->caption = text; } - QGraphicsItem* getThumbnail() const { return this->thumbnail; } - void setThumbnail(QGraphicsItem* newGItem) { this->thumbnail = newGItem; } + UBSceneThumbnailNavigPixmap* getThumbnail() const { return this->thumbnail; } + void setThumbnail(UBSceneThumbnailNavigPixmap* newGItem) { this->thumbnail = newGItem; } UBThumbnailTextItem* getCaption() const { return this->caption; } void setCaption(UBThumbnailTextItem* newcaption) { this->caption = newcaption; }