diff --git a/src/mainwindow.h b/src/mainwindow.h --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -51,6 +51,8 @@ protected: void closeEvent(QCloseEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); private: GCodeEditorWidget *m_gcodeEditor; @@ -63,8 +65,10 @@ void atCoreInstanceNameChange(const QString &name); QString getTheme(); void initWidgets(); + void loadFile(const QUrl &fileName); void newAtCoreInstance(); - void openFile(); + void openActionTriggered();; + void processDropEvent(const QList &fileList); void setupActions(); void setupLateralArea(); void toggleGCodeActions(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -40,6 +40,8 @@ { initWidgets(); setupActions(); + setAcceptDrops(true); + connect(m_instances, &QTabWidget::tabCloseRequested, [this](int index) { auto tempWidget = qobject_cast(m_instances->widget(index)); if (tempWidget->isPrinting()) { @@ -78,6 +80,31 @@ disconnect(m_gcodeEditor, &GCodeEditorWidget::updateClientFactory, this, &MainWindow::updateClientFactory); } +void MainWindow::dragEnterEvent(QDragEnterEvent *event) +{ + event->accept(); +} + +void MainWindow::dropEvent(QDropEvent *event) +{ + const QMimeData *mimeData = event->mimeData(); + if (mimeData->hasUrls()) { + processDropEvent(mimeData->urls()); + } +} + +void MainWindow::processDropEvent(const QList &fileList) +{ + for (const auto &url : fileList) { + //Loop thru the urls and only load ones ending our "supported" formats + QString ext = url.toLocalFile().split('.').last(); + if (ext.contains("gcode", Qt::CaseInsensitive) + || ext.contains("gco", Qt::CaseInsensitive)) { + loadFile(url); + } + } +} + void MainWindow::initWidgets() { setupLateralArea(); @@ -186,7 +213,11 @@ m_gcodeEditor = new GCodeEditorWidget(this); connect(m_gcodeEditor, &GCodeEditorWidget::updateClientFactory, this, &MainWindow::updateClientFactory); - setupButton("3d", i18n("&3D"), QIcon::fromTheme("draw-cuboid", QIcon(QString(":/%1/3d").arg(m_theme))), new Viewer3D(this)); + + auto *viewer3D = new Viewer3D(this); + connect(viewer3D, &Viewer3D::droppedUrls, this, &MainWindow::processDropEvent); + + setupButton("3d", i18n("&3D"), QIcon::fromTheme("draw-cuboid", QIcon(QString(":/%1/3d").arg(m_theme))), viewer3D); setupButton("gcode", i18n("&GCode"), QIcon::fromTheme("accessories-text-editor", QIcon(":/icon/edit")), m_gcodeEditor); setupButton("video", i18n("&Video"), QIcon::fromTheme("camera-web", QIcon(":/icon/video")), new VideoMonitorWidget(this)); buttonLayout->addStretch(); @@ -202,7 +233,7 @@ action->setText(i18n("&Open")); actionCollection()->setDefaultShortcut(action, QKeySequence::Open); - connect(action, &QAction::triggered, this, &MainWindow::openFile); + connect(action, &QAction::triggered, this, &MainWindow::openActionTriggered); action = actionCollection()->addAction(QStringLiteral("new_instance")); action->setIcon(QIcon::fromTheme("list-add", QIcon(QString(":/%1/addTab").arg(m_theme)))); @@ -231,15 +262,21 @@ setupGUI(Default, "atelierui"); } -void MainWindow::openFile() +void MainWindow::openActionTriggered() { - QUrl fileName = QFileDialog::getOpenFileUrl( - this - , i18n("Open GCode") - , QUrl::fromLocalFile(QDir::homePath()) - , i18n("GCode(*.gco *.gcode);;All Files(*.*)") - ); + QList fileList = QFileDialog::getOpenFileUrls( + this + , i18n("Open GCode") + , QUrl::fromLocalFile(QDir::homePath()) + , i18n("GCode(*.gco *.gcode);;All Files(*.*)") + ); + for (const auto &url : fileList) { + loadFile(url); + } +} +void MainWindow::loadFile(const QUrl &fileName) +{ if (!fileName.isEmpty()) { m_lateral.get("gcode")->loadFile(fileName); diff --git a/src/widgets/3dview/viewer3d.h b/src/widgets/3dview/viewer3d.h --- a/src/widgets/3dview/viewer3d.h +++ b/src/widgets/3dview/viewer3d.h @@ -1,6 +1,7 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2017> Author: Patrick José Pereira - patrickjp@kde.org + Chris Rizzitello - rizzitello@kde.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -31,6 +32,9 @@ { Q_OBJECT +public slots: + void dropCatch(const QVariant &var); + public: explicit Viewer3D(QWidget *parent = nullptr); ~Viewer3D() override; @@ -40,4 +44,7 @@ LineMesh *_lineMesh; QQmlApplicationEngine _engine; QQuickView *_view; + +signals: + void droppedUrls(QList fileList); }; diff --git a/src/widgets/3dview/viewer3d.cpp b/src/widgets/3dview/viewer3d.cpp --- a/src/widgets/3dview/viewer3d.cpp +++ b/src/widgets/3dview/viewer3d.cpp @@ -1,6 +1,7 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2017> Author: Patrick José Pereira - patrickjp@kde.org + Chris Rizzitello - rizzitello@kde.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -50,13 +51,21 @@ _view->setSource(QUrl(QStringLiteral("qrc:/viewer3d.qml"))); QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->addWidget(QWidget::createWindowContainer(_view)); + QObject *item = _view->rootObject(); + //Connect the drop pass from the QML part. + connect(item, SIGNAL(droppedUrls(QVariant)), this, SLOT(dropCatch(QVariant))); this->setLayout(mainLayout); } Viewer3D::~Viewer3D() { } +void Viewer3D::dropCatch(const QVariant &var) +{ + emit droppedUrls(var.value >()); +} + void Viewer3D::drawModel(QString file) { QObject *object = _view->rootObject(); diff --git a/src/widgets/3dview/viewer3d.qml b/src/widgets/3dview/viewer3d.qml --- a/src/widgets/3dview/viewer3d.qml +++ b/src/widgets/3dview/viewer3d.qml @@ -6,6 +6,16 @@ id: item width: 1000 height: 1000 + signal droppedUrls (var urls) + + DropArea { + id: dropArea + anchors.fill: parent + onDropped: if(drop.hasUrls) { + droppedUrls(drop.urls) + } + } + Rectangle { id: scene anchors.fill: parent