From 94de99a72f66f57e10210df7bbae177a02ac8509 Mon Sep 17 00:00:00 2001 From: Ivan Ilin Date: Tue, 7 Feb 2012 13:45:42 +0200 Subject: [PATCH] The most functionality for DnD --- src/api/UBWidgetUniboardAPI.cpp | 215 +++++++++++++++++++++++++++- src/api/UBWidgetUniboardAPI.h | 16 ++- src/board/UBBoardView.cpp | 91 +----------- src/core/UBDownloadManager.cpp | 42 +++--- src/core/UBDownloadManager.h | 24 ++-- src/domain/UBGraphicsWidgetItem.cpp | 4 + src/domain/UBGraphicsWidgetItem.h | 1 + src/network/UBHttpGet.cpp | 23 ++- src/network/UBHttpGet.h | 8 +- 9 files changed, 297 insertions(+), 127 deletions(-) diff --git a/src/api/UBWidgetUniboardAPI.cpp b/src/api/UBWidgetUniboardAPI.cpp index 43e99e7c..970095c9 100644 --- a/src/api/UBWidgetUniboardAPI.cpp +++ b/src/api/UBWidgetUniboardAPI.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "core/UB.h" #include "core/UBApplication.h" @@ -35,9 +36,35 @@ #include "UBWidgetMessageAPI.h" #include "frameworks/UBFileSystemUtils.h" +#include "core/UBDownloadManager.h" #include "core/memcheck.h" +//Known extentions for files, add if you know more supported +const QString audioExtentions = ".mp3.wma.ogg"; +const QString videoExtentions = ".avi.flv"; +const QString imageExtentions = ".png.jpg.tif.bmp.tga"; +const QString htmlExtentions = ".htm.html.xhtml"; + +//Allways use aliases instead of const char* itself +const QString imageAlias = "image"; +const QString imageAliasCap = "Image"; +const QString videoAlias = "video"; +const QString videoAliasCap = "Video"; +const QString audioAlias = "audio"; +const QString audioAliasCap = "Audio"; + +//Xml tag names +const QString tMainSection = "mimedata"; +const QString tType = "type"; +const QString tPath = "path"; +const QString tMessage = "message"; +const QString tReady = "ready"; + +const QString tMimeText = "text/plain"; + + +//Name of path inside widget to store objects const QString objectsPath = "objects"; UBWidgetUniboardAPI::UBWidgetUniboardAPI(UBGraphicsScene *pScene, UBGraphicsWidgetItem *widget) @@ -47,7 +74,7 @@ UBWidgetUniboardAPI::UBWidgetUniboardAPI(UBGraphicsScene *pScene, UBGraphicsWidg , mIsVisible(false) , mMessagesAPI(0) , mDatastoreAPI(0) -{ + { UBGraphicsW3CWidgetItem* w3CGraphicsWidget = dynamic_cast(widget); if (w3CGraphicsWidget) @@ -55,7 +82,8 @@ UBWidgetUniboardAPI::UBWidgetUniboardAPI(UBGraphicsScene *pScene, UBGraphicsWidg mMessagesAPI = new UBWidgetMessageAPI(w3CGraphicsWidget->w3cWidget()); mDatastoreAPI = new UBDatastoreAPI(w3CGraphicsWidget); } - connect(UBDownloadManager::downloadManager(), SIGNAL(downloadFinished(bool,int,QUrl,QString,QByteArray)), this, SLOT(onDownloadFinished(bool,int,QUrl,QString,QByteArray))); + + connect(UBDownloadManager::downloadManager(), SIGNAL(downloadFinished(bool,sDownloadFileDesc,QByteArray)), this, SLOT(onDownloadFinished(bool,sDownloadFileDesc,QByteArray))); } @@ -298,6 +326,11 @@ int UBWidgetUniboardAPI::currentPageNumber() return UBApplication::boardController->activeSceneIndex() + 1; } +QString UBWidgetUniboardAPI::getObjDir() +{ + return mGraphicsWidget->getOwnFolder().toLocalFile() + "/" + objectsPath + "/"; +} + void UBWidgetUniboardAPI::showMessage(const QString& message) { UBApplication::boardController->showMessage(message, false); @@ -456,6 +489,7 @@ QString UBWidgetUniboardAPI::downloadWeb(const QString &objectUrl) { // When we fall there, it means that we are dropping something from the web to the board sDownloadFileDesc desc; + desc.dest = sDownloadFileDesc::graphicsWidget; desc.modal = true; desc.url = objectUrl; desc.currentSize = 0; @@ -466,12 +500,183 @@ QString UBWidgetUniboardAPI::downloadWeb(const QString &objectUrl) return QString(); } -void UBWidgetUniboardAPI::onDownloadFinished(bool pSuccess, int id, QUrl sourceUrl, QString pContentTypeHeader, QByteArray pData) +void UBWidgetUniboardAPI::ProcessDropEvent(QDropEvent *event) +{ + const QMimeData *pMimeData = event->mimeData(); + + QString destFileName; + QString contentType; + bool downloaded = false; + + QGraphicsView *tmpView = mGraphicsWidget->scene()->views().at(0); + QPoint dropPoint(mGraphicsWidget->mapFromScene(tmpView->mapToScene(event->pos())).toPoint()); + Qt::DropActions dropActions = event->dropAction(); + Qt::MouseButtons dropMouseButtons = event->mouseButtons(); + Qt::KeyboardModifiers dropModifiers = event->keyboardModifiers(); + QMimeData dropMimeData; + + + if (pMimeData->hasHtml()) { //Dropping element from web browser + QString qsHtml = pMimeData->html(); + QString url = UBApplication::urlFromHtml(qsHtml); + + if(!url.isEmpty()) { + QString str = "test string"; + + QMimeData mimeData; + mimeData.setData(tMimeText, str.toAscii()); + + sDownloadFileDesc desc; + desc.dest = sDownloadFileDesc::graphicsWidget; + desc.modal = true; + desc.url = url; + desc.currentSize = 0; + desc.name = QFileInfo(url).fileName(); + desc.totalSize = 0; // The total size will be retrieved during the download + + desc.dropPoint = event->pos(); //Passing pure event point. No modifications + desc.dropActions = dropActions; + desc.dropMouseButtons = dropMouseButtons; + desc.dropModifiers = dropModifiers; + + registerIDWidget(UBDownloadManager::downloadManager()->addFileToDownload(desc)); + + return; + } + + } else if (pMimeData->hasUrls()) { //Local file processing + QUrl curUrl = pMimeData->urls().first(); + QString sUrl = curUrl.toString(); + + if (sUrl.startsWith("file://") || sUrl.startsWith("/")) { + QString fileName = curUrl.toLocalFile(); + QString extention = UBFileSystemUtils::extension(fileName); + contentType = UBFileSystemUtils::mimeTypeFromFileName(fileName); + + if (supportedTypeHeader(contentType)) { + destFileName = getObjDir() + QUuid::createUuid().toString() + extention; + + if (!UBFileSystemUtils::copyFile(fileName, destFileName)) { + qDebug() << "can't copy from" << fileName << "to" << destFileName; + return; + } + downloaded = true; + + } + } + } + + QString mimeText = createMimeText(downloaded, contentType, destFileName); + dropMimeData.setData(tMimeText, mimeText.toAscii()); + + QDropEvent readyEvent(dropPoint, dropActions, &dropMimeData, dropMouseButtons, dropModifiers); + //sending event to destination either it had been downloaded or not + QApplication::sendEvent(mGraphicsWidget->widgetWebView(),&readyEvent); +// readyEvent.acceptProposedAction(); +} + +void UBWidgetUniboardAPI::onDownloadFinished(bool pSuccess, sDownloadFileDesc desc, QByteArray pData) +{ + //if widget recieves is waiting for this id then process + if (!takeIDWidget(desc.id)) + return; + + if (!pSuccess) { + qDebug() << "can't download the whole data. An error occured"; + return; + } + + QString contentType = desc.contentTypeHeader; + QString extention = UBFileSystemUtils::fileExtensionFromMimeType(contentType); + + if (!supportedTypeHeader(contentType)) { + qDebug() << "actions for mime type" << contentType << "are not supported"; + return; + } + + QString objDir = getObjDir(); + if (!QDir().exists(objDir)) { + if (!QDir().mkpath(objDir)) { + qDebug() << "can't create objects directory path. Check the permissions"; + return; + } + } + + QString destFileName = objDir + QUuid::createUuid() + "." + extention; + QFile destFile(destFileName); + + if (!destFile.open(QIODevice::WriteOnly)) { + qDebug() << "can't open" << destFileName << "for wrighting"; + return; + } + + if (destFile.write(pData) == -1) { + qDebug() << "can't implement data writing"; + return; + } + + QGraphicsView *tmpView = mGraphicsWidget->scene()->views().at(0); + QPoint dropPoint(mGraphicsWidget->mapFromScene(tmpView->mapToScene(desc.dropPoint)).toPoint()); + + QMimeData dropMimeData; + QString mimeText = createMimeText(true, contentType, destFileName); + dropMimeData.setData(tMimeText, mimeText.toAscii()); + + destFile.close(); + + QDropEvent readyEvent(dropPoint, desc.dropActions, &dropMimeData, desc.dropMouseButtons, desc.dropModifiers); + //sending event to destination either it had been downloaded or not + QApplication::sendEvent(mGraphicsWidget->widgetWebView(),&readyEvent); + readyEvent.acceptProposedAction(); +} + +QString UBWidgetUniboardAPI::createMimeText(bool downloaded, const QString &mimeType, const QString &fileName) +{ + QString mimeXml; + QXmlStreamWriter writer(&mimeXml); + writer.setAutoFormatting(true); + writer.writeStartDocument(); + writer.writeStartElement(tMainSection); + + writer.writeTextElement(tReady, boolToStr(downloaded)); + + if (downloaded) { + if (!mimeType.isEmpty()) { + writer.writeTextElement(tType, mimeType); //writing type of element + } + if (!QFile::exists(fileName)) { + qDebug() << "file" << fileName << "doesn't exist"; + return QString(); + } + + QString relatedFileName = fileName; + relatedFileName = relatedFileName.remove(mGraphicsWidget->getOwnFolder().toLocalFile()); + writer.writeTextElement(tPath, relatedFileName); //writing path to created object + } + + writer.writeEndElement(); + writer.writeEndDocument(); + + return mimeXml; +} + +bool UBWidgetUniboardAPI::supportedTypeHeader(const QString &typeHeader) const { - Q_UNUSED(pData) - qDebug() << "got an ID" << id << pSuccess << sourceUrl << pContentTypeHeader; + return typeHeader.startsWith(imageAlias) || typeHeader.startsWith(imageAliasCap) + || typeHeader.startsWith(audioAlias) || typeHeader.startsWith(audioAliasCap) + || typeHeader.startsWith(videoAlias) || typeHeader.startsWith(videoAliasCap); } +bool UBWidgetUniboardAPI::takeIDWidget(int id) +{ + if (webDownloadIds.contains(id)) { + webDownloadIds.removeAll(id); + return true; + } + return false; +} + + UBDocumentDatastoreAPI::UBDocumentDatastoreAPI(UBGraphicsW3CWidgetItem *graphicsWidget) : UBW3CWebStorage(graphicsWidget) , mGraphicsW3CWidget(graphicsWidget) diff --git a/src/api/UBWidgetUniboardAPI.h b/src/api/UBWidgetUniboardAPI.h index 405c25ef..7725aee7 100644 --- a/src/api/UBWidgetUniboardAPI.h +++ b/src/api/UBWidgetUniboardAPI.h @@ -16,8 +16,10 @@ #define UBWIDGETAPI_H #include +#include #include "UBW3CWidgetAPI.h" +#include "core/UBDownloadManager.h" class UBGraphicsScene; class UBGraphicsWidgetItem; @@ -246,19 +248,15 @@ class UBWidgetUniboardAPI : public QObject */ QString downloadUrl(const QString &objectUrl, const QString &extention = ""); QString downloadWeb(const QString &objectUrl); + void ProcessDropEvent(QDropEvent *); private slots: - void onDownloadFinished(bool pSuccess, int id, QUrl sourceUrl, QString pContentTypeHeader, QByteArray pData); + void onDownloadFinished(bool pSuccess, sDownloadFileDesc desc, QByteArray pData); private: inline void registerIDWidget(int id){webDownloadIds.append(id);} - inline bool expectedID(int id) const {return webDownloadIds.contains(id);} - inline bool removeID(int id) {return webDownloadIds.removeAll(id);} - - - -// void unregister + inline bool takeIDWidget(int id); private: @@ -269,6 +267,10 @@ private: int pageCount(); int currentPageNumber(); + QString getObjDir(); + QString createMimeText(bool downloaded, const QString &mimeType, const QString &fileName); + bool supportedTypeHeader(const QString &) const; + QString boolToStr(bool value) const {return value ? "true" : "false";} UBGraphicsScene* mScene; diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp index 12cab1a3..1cf8683d 100644 --- a/src/board/UBBoardView.cpp +++ b/src/board/UBBoardView.cpp @@ -52,7 +52,6 @@ #include "core/memcheck.h" - //Known extentions for files, add if you know more supported const QString audioExtentions = ".mp3.wma.ogg"; const QString videoExtentions = ".avi.flv"; @@ -65,12 +64,6 @@ const QString videoAlias = "video"; const QString audioAlias = "audio"; const QString htmlAlias = "html"; -//Xml tag names -const QString tMainSection = "mimedata"; -const QString tType = "type"; -const QString tPath = "path"; -const QString tMessage = "message"; - UBBoardView::UBBoardView (UBBoardController* pController, QWidget* pParent) : QGraphicsView (pParent) , mController (pController) @@ -644,7 +637,6 @@ UBBoardView::forcedTabletRelease () mMouseButtonIsPressed = false; mTabletStylusIsPressed = false; mPendingStylusReleaseEvent = false; - } } @@ -767,67 +759,6 @@ void UBBoardView::dragMoveEvent (QDragMoveEvent *event) } } -QString UBBoardView::processMimeData(const QMimeData *pMimeData, UBGraphicsWidgetItem *widget) -{ - QString mimeXml; - QXmlStreamWriter writer(&mimeXml); - writer.setAutoFormatting(true); - writer.writeStartDocument(); - writer.writeStartElement(tMainSection); - - if (pMimeData->hasHtml()) { - QList urls = pMimeData->urls(); - - int index = 0; - foreach(const QUrl url, urls) { - -// QPointF pos(pPos + QPointF(index * 15, index * 15)); -// downloadURL(url, pos); - widget->downloadWeb(url.toString()); - index++; - } - writer.writeTextElement(tMessage, "Downloading content process..."); - - writer.writeEndElement(); - writer.writeEndDocument(); - return mimeXml; - } - - if (pMimeData->hasUrls()) { - QList urls = pMimeData->urls(); - - QString ext = fileExtention(urls.at(0).toLocalFile()); - if (ext.isNull()) { - qDebug() << "unknown file type"; - return QString(); - } - QString fileType = typeForExtention(ext); - if (fileType.isNull()) { - qDebug() << "unknown extention"; - return QString(); - } - - //writing type of element - writer.writeTextElement(tType, fileType); - - QString fileName = urls.at(0).toLocalFile(); - QString destName = widget->downloadUrl(fileName, ext); - - if (destName.isNull()) { - qDebug() << "error at creating destination folder"; - return QString(); - } - - //writing path to created object - writer.writeTextElement(tPath, destName); - } - - writer.writeEndElement(); - writer.writeEndDocument(); - - return mimeXml; -} - QString UBBoardView::fileExtention(const QString &filename) const { int pos = filename.lastIndexOf("."); @@ -877,24 +808,16 @@ void UBBoardView::dropEvent (QDropEvent *event) UBGraphicsWidgetItem* graphicsWidget = dynamic_cast(graphicsItemAtPos); if (graphicsWidget && graphicsWidget->acceptDrops()) { - // A new event is build to avoid problem related to different way to pass the mime type - // A parsing is done to try to provide a mimeType with only urls. - QMimeData mimeData; - QString str = processMimeData(event->mimeData(), graphicsWidget); - mimeData.setData("text/plain", str.toAscii()); - QPoint newPoint(graphicsWidget->mapFromScene(mapToScene(event->pos())).toPoint()); - QDropEvent cleanedEvent(newPoint, event->dropAction(), &mimeData, event->mouseButtons(), event->keyboardModifiers()); - QApplication::sendEvent(graphicsWidget->widgetWebView(),&cleanedEvent); - cleanedEvent.acceptProposedAction(); + + graphicsWidget->processDropEvent(event); event->acceptProposedAction(); - return; - } - qDebug() << event->source(); - if(!event->source() || dynamic_cast(event->source()) || dynamic_cast(event->source()) || dynamic_cast(event->source()) || dynamic_cast(event->source()) || dynamic_cast(event->source())) - { + } else if (!event->source() || dynamic_cast(event->source()) + || dynamic_cast(event->source()) || dynamic_cast(event->source()) + || dynamic_cast(event->source()) || dynamic_cast(event->source())) { + mController->processMimeData (event->mimeData (), mapToScene (event->pos ())); - event->acceptProposedAction (); + event->acceptProposedAction(); } } diff --git a/src/core/UBDownloadManager.cpp b/src/core/UBDownloadManager.cpp index 282d70f7..a20b0bc2 100644 --- a/src/core/UBDownloadManager.cpp +++ b/src/core/UBDownloadManager.cpp @@ -146,8 +146,7 @@ void UBDownloadManager::onUpdateDownloadLists() // If we fall here that means that there is no pending download break; } - if(-1 == mDLAvailability.at(i)) - { + if(-1 == mDLAvailability.at(i)) { // Pending downloads exist and a download 'slot' is available // Let's move the first pending download to the current download // list and fill the slot @@ -201,24 +200,27 @@ void UBDownloadManager::onDownloadFinished(int id, bool pSuccess, QUrl sourceUrl Q_UNUSED(pSize) Q_UNUSED(isBackground) - emit downloadFinished(pSuccess, id, sourceUrl, pContentTypeHeader, pData); -// for(int i=0; idownloadWeb(fileUrl); } +void UBGraphicsWidgetItem::processDropEvent(QDropEvent *event) +{ + return mUniboardAPI->ProcessDropEvent(event); +} UBGraphicsAppleWidgetItem::UBGraphicsAppleWidgetItem(const QUrl& pWidgetUrl, QGraphicsItem *parent) : UBGraphicsWidgetItem(parent) diff --git a/src/domain/UBGraphicsWidgetItem.h b/src/domain/UBGraphicsWidgetItem.h index 4ab90816..26cbb3dc 100644 --- a/src/domain/UBGraphicsWidgetItem.h +++ b/src/domain/UBGraphicsWidgetItem.h @@ -68,6 +68,7 @@ class UBGraphicsWidgetItem : public UBGraphicsProxyWidget void removeScript(); QString downloadUrl(const QString &fileUrl, const QString &extention); QString downloadWeb(const QString &fileUrl); + void processDropEvent(QDropEvent *event); virtual void setOwnFolder(const QUrl &newFolder) {ownFolder = newFolder;} virtual QUrl getOwnFolder() const {return ownFolder;} diff --git a/src/network/UBHttpGet.cpp b/src/network/UBHttpGet.cpp index c1c21bac..5b513602 100644 --- a/src/network/UBHttpGet.cpp +++ b/src/network/UBHttpGet.cpp @@ -18,9 +18,12 @@ #include #include "network/UBNetworkAccessManager.h" +#include "core/UBDownloadManager.h" #include "core/memcheck.h" +sDownloadFileDesc desc; + UBHttpGet::UBHttpGet(QObject* parent) : QObject(parent) , mReply(0) @@ -42,7 +45,6 @@ UBHttpGet::~UBHttpGet() } } - QNetworkReply* UBHttpGet::get(QUrl pUrl, QPointF pPos, QSize pSize, bool isBackground) { mPos = pPos; @@ -63,7 +65,26 @@ QNetworkReply* UBHttpGet::get(QUrl pUrl, QPointF pPos, QSize pSize, bool isBackg return mReply; } +//QNetworkReply* UBHttpGet::get(const sDownloadFileDesc &downlinfo) +//{ +// mDownloadInfo.size = downlinfo.size; +// mDownloadInfo.isBackground = downlinfo.isBackground; +// mDownloadInfo.pos = downlinfo.pos; + +// if (mReply) +// delete mReply; + +// UBNetworkAccessManager * nam = UBNetworkAccessManager::defaultAccessManager(); +// mReply = nam->get(QNetworkRequest(QUrl(downlinfo.url))); //mReply deleted by this destructor + +// mDownloadedBytes.clear(); + +// connect(mReply, SIGNAL(finished()), this, SLOT(requestFinished())); +// connect(mReply, SIGNAL(readyRead()), this, SLOT(readyRead())); +// connect(mReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgressed(qint64, qint64))); +// return mReply; +//} void UBHttpGet::readyRead() { diff --git a/src/network/UBHttpGet.h b/src/network/UBHttpGet.h index fd1eeef4..b6b4b567 100644 --- a/src/network/UBHttpGet.h +++ b/src/network/UBHttpGet.h @@ -18,24 +18,27 @@ #include #include - +#include class UBHttpGet : public QObject { - Q_OBJECT; + Q_OBJECT public: UBHttpGet(QObject* parent = 0); virtual ~UBHttpGet(); QNetworkReply* get(QUrl pUrl, QPointF pPoint = QPointF(0, 0), QSize pSize = QSize(0, 0), bool isBackground = false); +// QNetworkReply* get(const sDownloadFileDesc &downlinfo); signals: void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); void downloadFinished(bool pSuccess, QUrl sourceUrl, QString pContentTypeHeader , QByteArray pData, QPointF pPos, QSize pSize, bool isBackground); +// void downloadFinished(bool pSuccess, QUrl sourceUrl, QString pContentTypeHeader, QByteArray pData +// , sDownloadFileDesc downlInfo); private slots: @@ -54,6 +57,7 @@ class UBHttpGet : public QObject int mRequestID; int mRedirectionCount; bool mIsSelfAborting; +// sDownloadFileDesc mDownloadInfo; }; #endif /* UBHTTPGET_H_ */