diff --git a/app/mainwindow.h b/app/mainwindow.h --- a/app/mainwindow.h +++ b/app/mainwindow.h @@ -71,6 +71,9 @@ virtual void setCaption(const QString&, bool modified) Q_DECL_OVERRIDE; + void openUrl(const QUrl& url); + void openDirUrl(const QUrl&); + protected: virtual bool queryClose() Q_DECL_OVERRIDE; virtual QSize sizeHint() const Q_DECL_OVERRIDE; @@ -82,7 +85,6 @@ private Q_SLOTS: void setActiveViewModeAction(QAction* action); - void openDirUrl(const QUrl&); void slotThumbnailViewIndexActivated(const QModelIndex&); void slotStartMainPageUrlSelected(const QUrl&); @@ -112,7 +114,6 @@ void saveCurrent(); void saveCurrentAs(); void openFile(); - void openUrl(const QUrl& url); void reload(); void showDocumentInFullScreen(const QUrl&); diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -312,7 +312,7 @@ void setupViewMainPage(QWidget* parent) { - mViewMainPage = new ViewMainPage(parent, mSlideShow, q->actionCollection(), mGvCore); + mViewMainPage = new ViewMainPage(parent, q, mSlideShow, q->actionCollection(), mGvCore); connect(mViewMainPage, SIGNAL(captionUpdateRequested(QString)), q, SLOT(slotUpdateCaption(QString))); connect(mViewMainPage, SIGNAL(completed()), diff --git a/app/viewmainpage.h b/app/viewmainpage.h --- a/app/viewmainpage.h +++ b/app/viewmainpage.h @@ -37,6 +37,7 @@ namespace Gwenview { +class MainWindow; class AbstractRasterImageViewTool; class DocumentView; class GvCore; @@ -55,7 +56,7 @@ public: static const int MaxViewCount; - ViewMainPage(QWidget* parent, SlideShow*, KActionCollection*, GvCore*); + ViewMainPage(QWidget* parent, MainWindow* mainWindow, SlideShow*, KActionCollection*, GvCore*); ~ViewMainPage(); ThumbnailBarView* thumbnailBar() const; diff --git a/app/viewmainpage.cpp b/app/viewmainpage.cpp --- a/app/viewmainpage.cpp +++ b/app/viewmainpage.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include // KDE #include @@ -41,6 +43,7 @@ #include "fileoperations.h" #include #include "splitter.h" +#include "mainwindow.h" #include #include #include @@ -60,6 +63,7 @@ #include #include #include +#include namespace Gwenview { @@ -107,6 +111,7 @@ struct ViewMainPagePrivate { ViewMainPage* q; + MainWindow* mainWindow; SlideShow* mSlideShow; KActionCollection* mActionCollection; GvCore* mGvCore; @@ -210,7 +215,7 @@ QVBoxLayout* layout = new QVBoxLayout(mAdapterContainer); layout->setMargin(0); layout->setSpacing(0); - mDocumentViewContainer = new DocumentViewContainer; + mDocumentViewContainer = new DocumentViewContainer(q); mDocumentViewContainer->setAutoFillBackground(true); mDocumentViewContainer->setBackgroundRole(QPalette::Base); layout->addWidget(mDocumentViewContainer); @@ -379,12 +384,13 @@ } }; -ViewMainPage::ViewMainPage(QWidget* parent, SlideShow* slideShow, KActionCollection* actionCollection, GvCore* gvCore) +ViewMainPage::ViewMainPage(QWidget* parent, MainWindow* mainWindow, SlideShow* slideShow, KActionCollection* actionCollection, GvCore* gvCore) : QWidget(parent) , d(new ViewMainPagePrivate) { d->q = this; d->mDirModelToBarModelProxyMapper = 0; // Initialized later + d->mainWindow = mainWindow; d->mSlideShow = slideShow; d->mActionCollection = actionCollection; d->mGvCore = gvCore; @@ -752,6 +758,23 @@ bool ViewMainPage::eventFilter(QObject* watched, QEvent* event) { + // Allow dropping files/folders on the View mode viewport + // ViewMainPage is passed to d->mDocumentViewContainer so it can be installed as + // an event filter on the QGraphicsScene + if (event->type() == QEvent::GraphicsSceneDragEnter) { + QGraphicsSceneDragDropEvent* dragEnterEvent = static_cast(event); + dragEnterEvent->setAccepted(dragEnterEvent->mimeData()->hasUrls()); + } else if (event->type() == QEvent::GraphicsSceneDrop) { + QGraphicsSceneDragDropEvent* dropEvent = static_cast(event); + // Since we're capturing drops in View mode, we only support one url + QUrl urlToOpen = dropEvent->mimeData()->urls().first(); + if (UrlUtils::urlIsDirectory(urlToOpen)) { + d->mainWindow->openDirUrl(urlToOpen); + } else { + d->mainWindow->openUrl(urlToOpen); + } + } + if (event->type() == QEvent::ShortcutOverride) { const QKeyEvent* keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Escape) { diff --git a/lib/documentview/documentviewcontainer.h b/lib/documentview/documentviewcontainer.h --- a/lib/documentview/documentviewcontainer.h +++ b/lib/documentview/documentviewcontainer.h @@ -46,7 +46,7 @@ { Q_OBJECT public: - DocumentViewContainer(QWidget* parent = 0); + DocumentViewContainer(QWidget* viewMainPage); ~DocumentViewContainer(); /** diff --git a/lib/documentview/documentviewcontainer.cpp b/lib/documentview/documentviewcontainer.cpp --- a/lib/documentview/documentviewcontainer.cpp +++ b/lib/documentview/documentviewcontainer.cpp @@ -81,8 +81,8 @@ } }; -DocumentViewContainer::DocumentViewContainer(QWidget* parent) -: QGraphicsView(parent) +DocumentViewContainer::DocumentViewContainer(QWidget* viewMainPage) +: QGraphicsView(viewMainPage) , d(new DocumentViewContainerPrivate) { d->q = this; @@ -109,6 +109,9 @@ connect(d->mLayoutUpdateTimer, &QTimer::timeout, this, &DocumentViewContainer::updateLayout); connect(GwenviewConfig::self(), &GwenviewConfig::configChanged, this, &DocumentViewContainer::slotConfigChanged); + + // In order to support drop operations we need to filter events on the QGraphicsScene + d->mScene->installEventFilter(viewMainPage); } DocumentViewContainer::~DocumentViewContainer() @@ -120,6 +123,7 @@ { DocumentView* view = new DocumentView(d->mScene); view->setPalette(palette()); + view->setAcceptDrops(true); d->mAddedViews << view; view->show(); connect(view, &DocumentView::fadeInFinished, this, &DocumentViewContainer::slotFadeInFinished);