diff --git a/src/api/UBWidgetUniboardAPI.cpp b/src/api/UBWidgetUniboardAPI.cpp index b86e7aa1..e49bfe63 100644 --- a/src/api/UBWidgetUniboardAPI.cpp +++ b/src/api/UBWidgetUniboardAPI.cpp @@ -506,7 +506,7 @@ void UBWidgetUniboardAPI::ProcessDropEvent(QGraphicsSceneDragDropEvent *event) sDownloadFileDesc desc; desc.dest = sDownloadFileDesc::graphicsWidget; desc.modal = true; - desc.url = url; + desc.srcUrl = url; desc.currentSize = 0; desc.name = QFileInfo(url).fileName(); desc.totalSize = 0; // The total size will be retrieved during the download diff --git a/src/board/UBBoardController.cpp b/src/board/UBBoardController.cpp index ddc30c9e..358ce4ce 100644 --- a/src/board/UBBoardController.cpp +++ b/src/board/UBBoardController.cpp @@ -984,22 +984,36 @@ void UBBoardController::downloadURL(const QUrl& url, const QPointF& pPos, const || contentType.startsWith("application/widget") || contentType.startsWith("application/vnd.apple-widget"); - QFile file(fileName); - if (shouldLoadFileData) + { + QFile file(fileName); file.open(QIODevice::ReadOnly); - - downloadFinished(true, formedUrl, contentType, file.readAll(), pPos, pSize, isBackground, internalData); - - if (shouldLoadFileData) + downloadFinished(true, formedUrl, contentType, file.readAll(), pPos, pSize, isBackground, internalData); file.close(); + } + else + { + // media items should be copyed in separate thread + + sDownloadFileDesc desc; + desc.modal = false; + desc.srcUrl = sUrl; + 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); + } } 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.srcUrl = url.toString(); desc.currentSize = 0; desc.name = QFileInfo(url.toString()).fileName(); desc.totalSize = 0; // The total size will be retrieved during the download @@ -1157,11 +1171,9 @@ UBItem *UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QStri qDebug() << "accepting mime type" << mimeType << "as video"; UBGraphicsMediaItem *mediaVideoItem = 0; - + QUuid uuid = QUuid::createUuid(); if (pData.length() > 0) { - QUuid uuid = QUuid::createUuid(); - QString destFile; bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), sourceUrl.toString(), @@ -1178,16 +1190,16 @@ UBItem *UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QStri QUrl url = QUrl::fromLocalFile(destFile); mediaVideoItem = mActiveScene->addMedia(url, false, pPos); - - mediaVideoItem->setSourceUrl(sourceUrl); - mediaVideoItem->setUuid(uuid); } else { - mediaVideoItem = addVideo(sourceUrl, false, pPos); + qDebug() << sourceUrl.toString(); + mediaVideoItem = addVideo(sourceUrl, false, pPos, true); } if(mediaVideoItem){ + mediaVideoItem->setSourceUrl(sourceUrl); + mediaVideoItem->setUuid(uuid); connect(this, SIGNAL(activeSceneChanged()), mediaVideoItem, SLOT(activeSceneChanged())); } @@ -1201,10 +1213,9 @@ UBItem *UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QStri UBGraphicsMediaItem *audioMediaItem = 0; + QUuid uuid = QUuid::createUuid(); if (pData.length() > 0) { - QUuid uuid = QUuid::createUuid(); - QString destFile; bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), sourceUrl.toString(), @@ -1221,16 +1232,15 @@ UBItem *UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QStri QUrl url = QUrl::fromLocalFile(destFile); audioMediaItem = mActiveScene->addMedia(url, false, pPos); - - audioMediaItem->setSourceUrl(sourceUrl); - audioMediaItem->setUuid(uuid); } else { - audioMediaItem = addAudio(sourceUrl, false, pPos); + audioMediaItem = addAudio(sourceUrl, false, pPos, true); } if(audioMediaItem){ + audioMediaItem->setSourceUrl(sourceUrl); + audioMediaItem->setUuid(uuid); connect(this, SIGNAL(activeSceneChanged()), audioMediaItem, SLOT(activeSceneChanged())); } @@ -2023,23 +2033,28 @@ void UBBoardController::grabScene(const QRectF& pSceneRect) } } -UBGraphicsMediaItem* UBBoardController::addVideo(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos) +UBGraphicsMediaItem* UBBoardController::addVideo(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos, bool bUseSource) { QUuid uuid = QUuid::createUuid(); QUrl concreteUrl = pSourceUrl; - QString destFile; - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), - pSourceUrl.toLocalFile(), - UBPersistenceManager::videoDirectory, - uuid, - destFile); - if (!b) + // media file is not in document folder yet + if (!bUseSource) { - showMessage(tr("Add file operation failed: file copying error")); - return NULL; - } - concreteUrl = QUrl::fromLocalFile(destFile); + QString destFile; + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), + pSourceUrl.toLocalFile(), + UBPersistenceManager::videoDirectory, + uuid, + destFile); + if (!b) + { + showMessage(tr("Add file operation failed: file copying error")); + return NULL; + } + concreteUrl = QUrl::fromLocalFile(destFile); + }// else we just use source Url. + UBGraphicsMediaItem* vi = mActiveScene->addMedia(concreteUrl, startPlay, pos); selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); @@ -2053,23 +2068,27 @@ UBGraphicsMediaItem* UBBoardController::addVideo(const QUrl& pSourceUrl, bool st } -UBGraphicsMediaItem* UBBoardController::addAudio(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos) +UBGraphicsMediaItem* UBBoardController::addAudio(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos, bool bUseSource) { QUuid uuid = QUuid::createUuid(); QUrl concreteUrl = pSourceUrl; - QString destFile; - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), - pSourceUrl.toLocalFile(), - UBPersistenceManager::audioDirectory, - uuid, - destFile); - if (!b) + // media file is not in document folder yet + if (!bUseSource) { - showMessage(tr("Add file operation failed: file copying error")); - return NULL; - } - concreteUrl = QUrl::fromLocalFile(destFile); + QString destFile; + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), + pSourceUrl.toLocalFile(), + UBPersistenceManager::audioDirectory, + uuid, + destFile); + if (!b) + { + showMessage(tr("Add file operation failed: file copying error")); + return NULL; + } + concreteUrl = QUrl::fromLocalFile(destFile); + }// else we just use source Url. UBGraphicsMediaItem* ai = mActiveScene->addMedia(concreteUrl, startPlay, pos); selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); diff --git a/src/board/UBBoardController.h b/src/board/UBBoardController.h index a04c1a25..68468188 100644 --- a/src/board/UBBoardController.h +++ b/src/board/UBBoardController.h @@ -210,8 +210,8 @@ class UBBoardController : public UBDocumentContainer void setRegularPageSize(bool checked); void stylusToolChanged(int tool); void grabScene(const QRectF& pSceneRect); - UBGraphicsMediaItem* addVideo(const QUrl& pUrl, bool startPlay, const QPointF& pos); - UBGraphicsMediaItem* addAudio(const QUrl& pUrl, bool startPlay, const QPointF& pos); + UBGraphicsMediaItem* addVideo(const QUrl& pUrl, bool startPlay, const QPointF& pos, bool bUseSource = false); + UBGraphicsMediaItem* addAudio(const QUrl& pUrl, bool startPlay, const QPointF& pos, bool bUseSource = false); UBGraphicsWidgetItem *addW3cWidget(const QUrl& pUrl, const QPointF& pos); void cut(); diff --git a/src/core/UBDownloadManager.cpp b/src/core/UBDownloadManager.cpp index 4127851f..89e975bc 100644 --- a/src/core/UBDownloadManager.cpp +++ b/src/core/UBDownloadManager.cpp @@ -17,6 +17,7 @@ #include "gui/UBMainWindow.h" #include "board/UBBoardController.h" #include "board/UBBoardPaletteManager.h" +#include "frameworks/UBFileSystemUtils.h" #include "core/memcheck.h" @@ -209,7 +210,7 @@ void UBDownloadManager::onDownloadFinished(int id, bool pSuccess, QUrl sourceUrl desc.contentTypeHeader = pContentTypeHeader; emit downloadFinished(pSuccess, desc, pData); - } else if(desc.modal) { + } else if(desc.dest == sDownloadFileDesc::board) { // The downloaded file is modal so we must put it on the board emit addDownloadedFileToBoard(pSuccess, sourceUrl, pContentTypeHeader, pData, pPos, pSize, isBackground); } @@ -302,15 +303,24 @@ void UBDownloadManager::updateFileCurrentSize(int id, qint64 received, qint64 to */ void UBDownloadManager::startFileDownload(sDownloadFileDesc desc) { - UBDownloadHttpFile* http = new UBDownloadHttpFile(desc.id, this); - connect(http, SIGNAL(downloadProgress(int, qint64,qint64)), this, SLOT(onDownloadProgress(int,qint64,qint64))); - connect(http, SIGNAL(downloadFinished(int, bool, QUrl, QString, QByteArray, QPointF, QSize, bool)), this, SLOT(onDownloadFinished(int, bool, QUrl, QString, QByteArray, QPointF, QSize, bool))); - - //the desc.url is encoded. So we have to decode it before. - QUrl url; - url.setEncodedUrl(desc.url.toUtf8()); - // We send here the request and store its reply in order to be able to cancel it if needed - mReplies[desc.id] = http->get(url, desc.pos, desc.size, desc.isBackground); + if (desc.srcUrl.startsWith("file://") || desc.srcUrl.startsWith("/")) + { + UBAsyncLocalFileDownloader * cpHelper = new UBAsyncLocalFileDownloader(desc, this); + connect(cpHelper, SIGNAL(signal_asyncCopyFinished(int, bool, QUrl, QString, QByteArray, QPointF, QSize, bool)), this, SLOT(onDownloadFinished(int, bool, QUrl, QString, QByteArray, QPointF, QSize, bool))); + cpHelper->copyFile(QUrl(desc.srcUrl).toLocalFile(), QUrl(desc.dstUrl).toLocalFile(), true); + } + else + { + UBDownloadHttpFile* http = new UBDownloadHttpFile(desc.id, this); + connect(http, SIGNAL(downloadProgress(int, qint64,qint64)), this, SLOT(onDownloadProgress(int,qint64,qint64))); + connect(http, SIGNAL(downloadFinished(int, bool, QUrl, QString, QByteArray, QPointF, QSize, bool)), this, SLOT(onDownloadFinished(int, bool, QUrl, QString, QByteArray, QPointF, QSize, bool))); + + //the desc.srcUrl is encoded. So we have to decode it before. + QUrl url; + url.setEncodedUrl(desc.srcUrl.toUtf8()); + // We send here the request and store its reply in order to be able to cancel it if needed + mReplies[desc.id] = http->get(url, desc.pos, desc.size, desc.isBackground); + } } /** diff --git a/src/core/UBDownloadManager.h b/src/core/UBDownloadManager.h index 2b5c52c0..9e185563 100644 --- a/src/core/UBDownloadManager.h +++ b/src/core/UBDownloadManager.h @@ -52,7 +52,8 @@ struct sDownloadFileDesc int id; int totalSize; int currentSize; - QString url; + QString srcUrl; + QString dstUrl; QString contentTypeHeader; bool modal; QPointF pos; // For board drop only diff --git a/src/domain/UBGraphicsMediaItem.cpp b/src/domain/UBGraphicsMediaItem.cpp index 1faba0ce..74b378f8 100644 --- a/src/domain/UBGraphicsMediaItem.cpp +++ b/src/domain/UBGraphicsMediaItem.cpp @@ -73,7 +73,11 @@ UBGraphicsMediaItem::UBGraphicsMediaItem(const QUrl& pMediaFileUrl, QGraphicsIte mMediaObject = new Phonon::MediaObject(this); - if (pMediaFileUrl.toLocalFile().contains("videos")) + QString mediaPath = pMediaFileUrl.toString(); + if ("" == mediaPath) + mediaPath = pMediaFileUrl.toLocalFile(); + + if (mediaPath.toLower().contains("videos")) { mMediaType = mediaType_Video; @@ -91,7 +95,7 @@ UBGraphicsMediaItem::UBGraphicsMediaItem(const QUrl& pMediaFileUrl, QGraphicsIte haveLinkedImage = true; } else - if (pMediaFileUrl.toLocalFile().contains("audios")) + if (mediaPath.toLower().contains("audios")) { mMediaType = mediaType_Audio; mAudioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index cc98b307..fd5f158b 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -1216,6 +1216,11 @@ void UBGraphicsScene::textUndoCommandAdded(UBGraphicsTextItem *textItem) } UBGraphicsMediaItem* UBGraphicsScene::addMedia(const QUrl& pMediaFileUrl, bool shouldPlayAsap, const QPointF& pPos) { + qDebug() << pMediaFileUrl.toLocalFile(); + if (!QFile::exists(pMediaFileUrl.toLocalFile())) + if (!QFile::exists(pMediaFileUrl.toString())) + return NULL; + UBGraphicsMediaItem* mediaItem = new UBGraphicsMediaItem(pMediaFileUrl); if(mediaItem){ connect(UBApplication::boardController, SIGNAL(activeSceneChanged()), mediaItem, SLOT(activeSceneChanged())); diff --git a/src/frameworks/UBFileSystemUtils.cpp b/src/frameworks/UBFileSystemUtils.cpp index 36a61945..5fb3376d 100644 --- a/src/frameworks/UBFileSystemUtils.cpp +++ b/src/frameworks/UBFileSystemUtils.cpp @@ -22,6 +22,8 @@ #include "board/UBBoardController.h" #include "document/UBDocumentContainer.h" +#include "core/UBPersistenceManager.h" + #include "globals/UBGlobals.h" THIRD_PARTY_WARNINGS_DISABLE @@ -856,3 +858,91 @@ QString UBFileSystemUtils::readTextFile(QString path) return ""; } + +UBCopyThread::UBCopyThread(QObject *parent) + : QThread(parent) +{ +} + +void UBCopyThread::copyFile(const QString &source, const QString &destination, bool overwrite) +{ + if (!QFile::exists(source)) { + qDebug() << "file" << source << "does not present in fs"; + return; + } + + QString normalizedDestination = destination; + if (QFile::exists(normalizedDestination)) { + if (QFileInfo(normalizedDestination).isFile() && overwrite) { + QFile::remove(normalizedDestination); + } + } else { + normalizedDestination = normalizedDestination.replace(QString("\\"), QString("/")); + int pos = normalizedDestination.lastIndexOf("/"); + if (pos != -1) { + QString newpath = normalizedDestination.left(pos); + if (!QDir().mkpath(newpath)) { + qDebug() << "can't create a new path at " << newpath; + } + } + } + + mFrom = source; + mTo = normalizedDestination; + + start(); +} + +void UBCopyThread::run() +{ + + QString mimeType = UBFileSystemUtils::mimeTypeFromFileName(mFrom); + + int position=mimeType.indexOf(";"); + if(position != -1) + mimeType=mimeType.left(position); + + UBMimeType::Enum itemMimeType = UBFileSystemUtils::mimeTypeFromString(mimeType); + + + QString destDirectory; + if (UBMimeType::Video == itemMimeType) + destDirectory = UBPersistenceManager::videoDirectory; + else + if (UBMimeType::Audio == itemMimeType) + destDirectory = UBPersistenceManager::audioDirectory; + + QString uuid = QUuid::createUuid(); + UBPersistenceManager::persistenceManager()->addFileToDocument(UBApplication::boardController->selectedDocument(), + mFrom, + destDirectory, + uuid, + mTo, + NULL); + + emit finished(mTo); +} + + +UBAsyncLocalFileDownloader::UBAsyncLocalFileDownloader(sDownloadFileDesc desc, QObject *parent) + : QObject(parent) + , mDesc(desc) +{ + +} + +void UBAsyncLocalFileDownloader::copyFile(QString &source, QString &destination, bool bOverwrite) +{ + mFrom = source; + mTo = destination; + + UBCopyThread *cpThread = new UBCopyThread(this); // possible memory leak. Delete helper at signal_asyncCopyFinished() handler + connect(cpThread, SIGNAL(finished(QString)), this, SLOT(slot_asyncCopyFinished(QString))); + cpThread->copyFile(source, destination, bOverwrite); +} + +void UBAsyncLocalFileDownloader::slot_asyncCopyFinished(QString resUrl) +{ + emit signal_asyncCopyFinished(mDesc.id, !resUrl.isEmpty(), QUrl(resUrl), "", NULL, mDesc.pos, mDesc.size, mDesc.isBackground); + +} \ No newline at end of file diff --git a/src/frameworks/UBFileSystemUtils.h b/src/frameworks/UBFileSystemUtils.h index 13c82dbf..b5c5a961 100644 --- a/src/frameworks/UBFileSystemUtils.h +++ b/src/frameworks/UBFileSystemUtils.h @@ -17,14 +17,57 @@ #define UBFILESYSTEMUTILS_H_ #include +#include #include "core/UB.h" +#include "core/UBDownloadManager.h" + +class UBCopyThread : public QThread +{ + Q_OBJECT +public: + explicit UBCopyThread(QObject *parent = 0); + + void copyFile(const QString &source, const QString &destination, bool overwrite); + void run(); + +signals: + void finished(QString resUrl); + +private: + QString mFrom; + QString mTo; +}; + +class UBAsyncLocalFileDownloader : public QObject +{ + Q_OBJECT + +public: + UBAsyncLocalFileDownloader(sDownloadFileDesc desc, QObject *parent = 0); + + void copyFile(QString &source, QString &destination, bool bOverwrite); + +public slots: + void slot_asyncCopyFinished(QString resUrl); + +signals: + void signal_asyncCopyFinished(int id, bool pSuccess, QUrl sourceUrl, QString pContentTypeHeader, QByteArray pData, QPointF pPos, QSize pSize, bool isBackground); + +private: + QString mFrom; + QString mTo; + sDownloadFileDesc mDesc; +}; + class QuaZipFile; class UBProcessingProgressListener; -class UBFileSystemUtils +class UBFileSystemUtils : public QObject { + Q_OBJECT + public: UBFileSystemUtils(); diff --git a/src/gui/UBFeaturesWidget.cpp b/src/gui/UBFeaturesWidget.cpp index ee052027..ab965689 100644 --- a/src/gui/UBFeaturesWidget.cpp +++ b/src/gui/UBFeaturesWidget.cpp @@ -1048,8 +1048,8 @@ void UBFeatureProperties::onAddToLib() desc.modal = false; desc.name = QFileInfo( mpElement->getFullPath().toString()).fileName(); qDebug() << desc.name; - desc.url = mpElement->getFullPath().toString(); - qDebug() << desc.url; + desc.srcUrl = mpElement->getFullPath().toString(); + qDebug() << desc.srcUrl; UBDownloadManager::downloadManager()->addFileToDownload(desc); } }