importVoxels() JS override: specify file and location

This commit is contained in:
Bennett Goble 2014-08-03 14:01:37 -04:00
parent 8be42bf305
commit bd409f2de4
9 changed files with 217 additions and 162 deletions

View file

@ -245,28 +245,28 @@
<context>
<name>QObject</name>
<message>
<location filename="src/ui/ImportDialog.cpp" line="22"/>
<location filename="src/ui/ImportDialog.cpp" line="23"/>
<location filename="src/ui/VoxelImportDialog.cpp" line="22"/>
<location filename="src/ui/VoxelImportDialog.cpp" line="23"/>
<source>Import Voxels</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/ImportDialog.cpp" line="24"/>
<location filename="src/ui/VoxelImportDialog.cpp" line="24"/>
<source>Loading ...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/ImportDialog.cpp" line="25"/>
<location filename="src/ui/VoxelImportDialog.cpp" line="25"/>
<source>Place voxels</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/ImportDialog.cpp" line="26"/>
<location filename="src/ui/VoxelImportDialog.cpp" line="26"/>
<source>&lt;b&gt;Import&lt;/b&gt; %1 as voxels</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/ImportDialog.cpp" line="27"/>
<location filename="src/ui/VoxelImportDialog.cpp" line="27"/>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>

View file

@ -137,7 +137,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_frameCount(0),
_fps(60.0f),
_justStarted(true),
_voxelImporter(NULL),
_voxelImportDialog(NULL),
_voxelImporter(),
_importSucceded(false),
_sharedVoxelSystem(TREE_SCALE, DEFAULT_MAX_VOXELS_PER_SYSTEM, &_clipboard),
_wantToKillLocalVoxels(false),
@ -428,7 +429,7 @@ Application::~Application() {
delete idleTimer;
_sharedVoxelSystem.changeTree(new VoxelTree);
delete _voxelImporter;
delete _voxelImportDialog;
// let the avatar mixer know we're out
MyAvatar::sendKillAvatar();
@ -463,8 +464,8 @@ void Application::saveSettings() {
Menu::getInstance()->saveSettings();
_rearMirrorTools->saveSettings(_settings);
if (_voxelImporter) {
_voxelImporter->saveSettings(_settings);
if (_voxelImportDialog) {
_voxelImportDialog->saveSettings(_settings);
}
_settings->sync();
_numChangedSettings = 0;
@ -1568,17 +1569,17 @@ void Application::exportVoxels(const VoxelDetail& sourceVoxel) {
void Application::importVoxels() {
_importSucceded = false;
if (!_voxelImporter) {
_voxelImporter = new VoxelImporter(_window);
_voxelImporter->loadSettings(_settings);
if (!_voxelImportDialog) {
_voxelImportDialog = new VoxelImportDialog(_window);
_voxelImportDialog->loadSettings(_settings);
}
if (!_voxelImporter->exec()) {
if (!_voxelImportDialog->exec()) {
qDebug() << "Import succeeded." << endl;
_importSucceded = true;
} else {
qDebug() << "Import failed." << endl;
if (_sharedVoxelSystem.getTree() == _voxelImporter->getVoxelTree()) {
if (_sharedVoxelSystem.getTree() == _voxelImporter.getVoxelTree()) {
_sharedVoxelSystem.killLocalVoxels();
_sharedVoxelSystem.changeTree(&_clipboard);
}
@ -1680,7 +1681,7 @@ void Application::init() {
// Cleanup of the original shared tree
_sharedVoxelSystem.init();
_voxelImporter = new VoxelImporter(_window);
_voxelImportDialog = new VoxelImportDialog(_window);
_environment.init();

View file

@ -86,6 +86,7 @@
#include "ui/overlays/Overlays.h"
#include "ui/ApplicationOverlay.h"
#include "ui/RunningScriptsWidget.h"
#include "ui/VoxelImportDialog.h"
#include "voxels/VoxelFade.h"
#include "voxels/VoxelHideShowThread.h"
#include "voxels/VoxelImporter.h"
@ -192,6 +193,7 @@ public:
Camera* getCamera() { return &_myCamera; }
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; }
VoxelImporter* getVoxelImporter() { return &_voxelImporter; }
VoxelSystem* getVoxels() { return &_voxels; }
VoxelTree* getVoxelTree() { return _voxels.getTree(); }
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
@ -453,7 +455,8 @@ private:
VoxelSystem _voxels;
VoxelTree _clipboard; // if I copy/paste
VoxelImporter* _voxelImporter;
VoxelImportDialog* _voxelImportDialog;
VoxelImporter _voxelImporter;
bool _importSucceded;
VoxelSystem _sharedVoxelSystem;
ViewFrustum _sharedVoxelSystemViewFrustum;

View file

@ -87,6 +87,37 @@ bool ClipboardScriptingInterface::importVoxels() {
return Application::getInstance()->getImportSucceded();
}
bool ClipboardScriptingInterface::importVoxels(const QString& filename) {
qDebug() << "Importing ... ";
VoxelImporter* importer = Application::getInstance()->getVoxelImporter();
if (!importer->validImportFile(filename)) {
return false;
}
QEventLoop loop;
connect(importer, SIGNAL(importDone()), &loop, SLOT(quit()));
importer->import(filename);
loop.exec();
return true;
}
bool ClipboardScriptingInterface::importVoxels(const QString& filename, float x, float y, float z, float s) {
bool success = importVoxels(filename);
if (success) {
pasteVoxel(x, y, z, s);
}
return success;
}
bool ClipboardScriptingInterface::importVoxels(const QString& filename, const VoxelDetail& destinationVoxel) {
return importVoxels(filename, destinationVoxel.x, destinationVoxel.y, destinationVoxel.z, destinationVoxel.s);
}
void ClipboardScriptingInterface::nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec) {
nudgeVoxel(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s, nudgeVec);
}

View file

@ -39,6 +39,9 @@ public slots:
void exportVoxel(float x, float y, float z, float s);
bool importVoxels();
bool importVoxels(const QString& filename);
bool importVoxels(const QString& filename, float x, float y, float z, float s);
bool importVoxels(const QString& filename, const VoxelDetail& destinationVoxel);
void nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec);
void nudgeVoxel(float x, float y, float z, float s, const glm::vec3& nudgeVec);

View file

@ -1,5 +1,5 @@
//
// ImportDialog.cpp
// VoxelImportDialog.cpp
// interface/src/ui
//
// Created by Clement Brisset on 8/12/13.
@ -20,7 +20,11 @@
#include "Application.h"
#include "ImportDialog.h"
#include "VoxelImportDialog.h"
#include "voxels/VoxelImporter.h"
const QString SETTINGS_GROUP_NAME = "VoxelImport";
const QString IMPORT_DIALOG_SETTINGS_KEY = "VoxelImportDialogSettings";
const QString WINDOW_NAME = QObject::tr("Import Voxels");
const QString IMPORT_BUTTON_NAME = QObject::tr("Import Voxels");
@ -97,12 +101,14 @@ QString HiFiIconProvider::type(const QFileInfo &info) const {
return QFileIconProvider::type(info);
}
ImportDialog::ImportDialog(QWidget* parent) :
VoxelImportDialog::VoxelImportDialog(QWidget* parent) :
QFileDialog(parent, WINDOW_NAME, DOWNLOAD_LOCATION, NULL),
_progressBar(this),
_importButton(IMPORT_BUTTON_NAME, this),
_cancelButton(CANCEL_BUTTON_NAME, this),
_mode(importMode) {
_importButton(IMPORT_BUTTON_NAME, this),
_importer(Application::getInstance()->getVoxelImporter()),
_mode(importMode),
_progressBar(this),
_didImport(false) {
setOption(QFileDialog::DontUseNativeDialog, true);
setFileMode(QFileDialog::ExistingFile);
@ -113,41 +119,54 @@ ImportDialog::ImportDialog(QWidget* parent) :
_progressBar.setRange(0, 100);
connect(&_importButton, SIGNAL(pressed()), SLOT(accept()));
connect(&_cancelButton, SIGNAL(pressed()), SIGNAL(canceled()));
connect(&_importButton, SIGNAL(pressed()), this, SLOT(accept()));
connect(&_cancelButton, SIGNAL(pressed()), this, SLOT(cancel()));
connect(this, SIGNAL(currentChanged(QString)), SLOT(saveCurrentFile(QString)));
}
void ImportDialog::reset() {
setMode(importMode);
_progressBar.setValue(0);
void VoxelImportDialog::cancel() {
switch (getMode()) {
case importMode:
_importer->cancel();
close();
break;
default:
_importer->reset();
setMode(importMode);
break;
}
emit canceled();
}
void ImportDialog::setMode(dialogMode mode) {
void VoxelImportDialog::saveSettings(QSettings* settings) {
settings->beginGroup(SETTINGS_GROUP_NAME);
settings->setValue(IMPORT_DIALOG_SETTINGS_KEY, saveState());
settings->endGroup();
}
void VoxelImportDialog::loadSettings(QSettings* settings) {
settings->beginGroup(SETTINGS_GROUP_NAME);
restoreState(settings->value(IMPORT_DIALOG_SETTINGS_KEY).toByteArray());
settings->endGroup();
}
bool VoxelImportDialog::prompt() {
reset();
exec();
return _didImport;
}
void VoxelImportDialog::reset() {
setMode(importMode);
_didImport = false;
}
void VoxelImportDialog::setMode(dialogMode mode) {
dialogMode previousMode = _mode;
_mode = mode;
switch (_mode) {
case loadingMode:
_importButton.setEnabled(false);
_importButton.setText(LOADING_BUTTON_NAME);
findChild<QWidget*>("sidebar")->setEnabled(false);
findChild<QWidget*>("treeView")->setEnabled(false);
findChild<QWidget*>("backButton")->setEnabled(false);
findChild<QWidget*>("forwardButton")->setEnabled(false);
findChild<QWidget*>("toParentButton")->setEnabled(false);
break;
case placeMode:
_progressBar.setValue(100);
_importButton.setEnabled(true);
_importButton.setText(PLACE_BUTTON_NAME);
findChild<QWidget*>("sidebar")->setEnabled(false);
findChild<QWidget*>("treeView")->setEnabled(false);
findChild<QWidget*>("backButton")->setEnabled(false);
findChild<QWidget*>("forwardButton")->setEnabled(false);
findChild<QWidget*>("toParentButton")->setEnabled(false);
break;
case importMode:
default:
_progressBar.setValue(0);
_importButton.setEnabled(true);
_importButton.setText(IMPORT_BUTTON_NAME);
@ -157,22 +176,60 @@ void ImportDialog::setMode(dialogMode mode) {
findChild<QWidget*>("forwardButton")->setEnabled(true);
findChild<QWidget*>("toParentButton")->setEnabled(true);
break;
case loadingMode:
// Connect to VoxelImporter signals
connect(_importer, SIGNAL(importProgress(int)), this, SLOT(updateProgressBar(int)));
connect(_importer, SIGNAL(importDone()), this, SLOT(afterImport()));
_importButton.setEnabled(false);
_importButton.setText(LOADING_BUTTON_NAME);
findChild<QWidget*>("sidebar")->setEnabled(false);
findChild<QWidget*>("treeView")->setEnabled(false);
findChild<QWidget*>("backButton")->setEnabled(false);
findChild<QWidget*>("forwardButton")->setEnabled(false);
findChild<QWidget*>("toParentButton")->setEnabled(false);
break;
case finishedMode:
if (previousMode == loadingMode) {
// Disconnect from VoxelImporter signals
disconnect(_importer, SIGNAL(importProgress(int)), this, SLOT(setProgressBarValue(int)));
disconnect(_importer, SIGNAL(importDone()), this, SLOT(afterImport()));
}
setMode(importMode);
break;
}
}
void ImportDialog::setProgressBarValue(int value) {
void VoxelImportDialog::setProgressBarValue(int value) {
_progressBar.setValue(value);
}
void ImportDialog::accept() {
emit accepted();
void VoxelImportDialog::accept() {
if (getMode() == importMode) {
QString filename = getCurrentFile();
// If file is invalid we ignore the call
if (!_importer->validImportFile(filename)) {
return;
}
// Let's prepare the dialog window for import
setMode(loadingMode);
_importer->import(filename);
}
}
void ImportDialog::saveCurrentFile(QString filename) {
void VoxelImportDialog::afterImport() {
setMode(finishedMode);
_didImport = true;
close();
}
void VoxelImportDialog::saveCurrentFile(QString filename) {
_currentFile = QFileInfo(filename).isFile() ? filename : "";
}
void ImportDialog::setLayout() {
void VoxelImportDialog::setLayout() {
QGridLayout* gridLayout = (QGridLayout*) layout();
gridLayout->addWidget(&_progressBar, 2, 0, 2, 1);
gridLayout->addWidget(&_cancelButton, 2, 1, 2, 1);
@ -258,7 +315,7 @@ void ImportDialog::setLayout() {
}
void ImportDialog::setImportTypes() {
void VoxelImportDialog::setImportTypes() {
QFile config(Application::resourcesPath() + "config/config.json");
config.open(QFile::ReadOnly | QFile::Text);
QJsonDocument document = QJsonDocument::fromJson(config.readAll());

View file

@ -1,5 +1,5 @@
//
// ImportDialog.h
// VoxelImportDialog.h
// interface/src/ui
//
// Created by Clement Brisset on 8/12/13.
@ -9,8 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_ImportDialog_h
#define hifi_ImportDialog_h
#ifndef hifi_VoxelImportDialog_h
#define hifi_VoxelImportDialog_h
#include "InterfaceConfig.h"
@ -23,6 +23,8 @@
#include <SharedUtil.h>
#include "voxels/VoxelImporter.h"
class HiFiIconProvider : public QFileIconProvider {
public:
HiFiIconProvider(const QHash<QString, QString> map) { iconsMap = map; };
@ -35,39 +37,45 @@ public:
enum dialogMode {
importMode,
loadingMode,
placeMode
finishedMode
};
class ImportDialog : public QFileDialog {
class VoxelImportDialog : public QFileDialog {
Q_OBJECT
public:
ImportDialog(QWidget* parent = NULL);
void reset();
VoxelImportDialog(QWidget* parent = NULL);
QString getCurrentFile() const { return _currentFile; }
dialogMode getMode() const { return _mode; }
void setMode(dialogMode mode);
void reset();
bool prompt();
void loadSettings(QSettings* settings);
void saveSettings(QSettings* settings);
signals:
void canceled();
public slots:
void setProgressBarValue(int value);
private slots:
void setProgressBarValue(int value);
void accept();
void cancel();
void saveCurrentFile(QString filename);
void afterImport();
private:
QString _currentFile;
QProgressBar _progressBar;
QPushButton _importButton;
QPushButton _cancelButton;
QString _currentFile;
QPushButton _importButton;
VoxelImporter* _importer;
dialogMode _mode;
QProgressBar _progressBar;
bool _didImport;
void setLayout();
void setImportTypes();
};
#endif // hifi_ImportDialog_h
#endif // hifi_VoxelImportDialog_h

View file

@ -20,8 +20,7 @@
#include "voxels/VoxelImporter.h"
const QString SETTINGS_GROUP_NAME = "VoxelImport";
const QString IMPORT_DIALOG_SETTINGS_KEY = "ImportDialogSettings";
const QStringList SUPPORTED_EXTENSIONS = QStringList() << "png" << "svo" << "schematic";
class ImportTask : public QObject, public QRunnable {
public:
@ -32,104 +31,46 @@ private:
QString _filename;
};
VoxelImporter::VoxelImporter(QWidget* parent) :
QObject(parent),
VoxelImporter::VoxelImporter() :
_voxelTree(true),
_importDialog(parent),
_task(NULL),
_didImport(false)
_task(NULL)
{
LocalVoxelsList::getInstance()->addPersistantTree(IMPORT_TREE_NAME, &_voxelTree);
connect(&_voxelTree, SIGNAL(importProgress(int)), &_importDialog, SLOT(setProgressBarValue(int)));
connect(&_importDialog, SIGNAL(canceled()), this, SLOT(cancel()));
connect(&_importDialog, SIGNAL(accepted()), this, SLOT(import()));
}
void VoxelImporter::saveSettings(QSettings* settings) {
settings->beginGroup(SETTINGS_GROUP_NAME);
settings->setValue(IMPORT_DIALOG_SETTINGS_KEY, _importDialog.saveState());
settings->endGroup();
}
void VoxelImporter::loadSettings(QSettings* settings) {
settings->beginGroup(SETTINGS_GROUP_NAME);
_importDialog.restoreState(settings->value(IMPORT_DIALOG_SETTINGS_KEY).toByteArray());
settings->endGroup();
connect(&_voxelTree, SIGNAL(importProgress(int)), this, SIGNAL(importProgress(int)));
}
VoxelImporter::~VoxelImporter() {
cleanupTask();
}
void VoxelImporter::cancel() {
if (_task) {
disconnect(_task, 0, 0, 0);
}
reset();
}
void VoxelImporter::reset() {
_voxelTree.eraseAllOctreeElements();
_importDialog.reset();
cleanupTask();
}
int VoxelImporter::exec() {
reset();
_importDialog.exec();
if (!_didImport) {
// if the import is rejected, we make sure to cleanup before leaving
void VoxelImporter::import(const QString& filename) {
// If present, abort existing import
if (_task) {
cleanupTask();
return 1;
} else {
_didImport = false;
return 0;
}
}
void VoxelImporter::import() {
switch (_importDialog.getMode()) {
case loadingMode:
_importDialog.setMode(placeMode);
return;
case placeMode:
// Means the user chose to import
_didImport = true;
_importDialog.close();
return;
case importMode:
default:
QString filename = _importDialog.getCurrentFile();
// if it's not a file, we ignore the call
if (!QFileInfo(filename).isFile()) {
return;
}
// Let's prepare the dialog window for import
_importDialog.setMode(loadingMode);
// If not already done, we switch to the local tree
if (Application::getInstance()->getSharedVoxelSystem()->getTree() != &_voxelTree) {
Application::getInstance()->getSharedVoxelSystem()->changeTree(&_voxelTree);
}
// Creation and launch of the import task on the thread pool
_task = new ImportTask(filename);
connect(_task, SIGNAL(destroyed()), SLOT(import()));
QThreadPool::globalInstance()->start(_task);
break;
// If not already done, we switch to the local tree
if (Application::getInstance()->getSharedVoxelSystem()->getTree() != &_voxelTree) {
Application::getInstance()->getSharedVoxelSystem()->changeTree(&_voxelTree);
}
}
void VoxelImporter::cancel() {
switch (_importDialog.getMode()) {
case loadingMode:
disconnect(_task, 0, 0, 0);
cleanupTask();
case placeMode:
_importDialog.setMode(importMode);
break;
case importMode:
default:
_importDialog.close();
break;
}
// Creation and launch of the import task on the thread pool
_task = new ImportTask(filename);
connect(_task, SIGNAL(destroyed()), SLOT(finishImport()));
QThreadPool::globalInstance()->start(_task);
}
void VoxelImporter::cleanupTask() {
@ -140,6 +81,16 @@ void VoxelImporter::cleanupTask() {
}
}
void VoxelImporter::finishImport() {
cleanupTask();
emit importDone();
}
bool VoxelImporter::validImportFile(const QString& filename) {
QFileInfo fileInfo = QFileInfo(filename);
return fileInfo.isFile() && SUPPORTED_EXTENSIONS.indexOf(fileInfo.suffix().toLower()) != -1;
}
ImportTask::ImportTask(const QString &filename)
: _filename(filename)
{
@ -151,7 +102,7 @@ void ImportTask::run() {
// We start by cleaning up the shared voxel system just in case
voxelSystem->killLocalVoxels();
// Then we call the righ method for the job
// Then we call the right method for the job
if (_filename.endsWith(".png", Qt::CaseInsensitive)) {
voxelSystem->getTree()->readFromSquareARGB32Pixels(_filename.toLocal8Bit().data());
} else if (_filename.endsWith(".svo", Qt::CaseInsensitive)) {
@ -163,6 +114,6 @@ void ImportTask::run() {
qDebug() << "[ERROR] Invalid file extension." << endl;
}
// Here we reaverage the tree so that he is ready for preview
// Here we reaverage the tree so that it is ready for preview
voxelSystem->getTree()->reaverageOctreeElements();
}

View file

@ -14,8 +14,8 @@
#include <QThread>
#include <QRunnable>
#include <QStringList>
#include "ui/ImportDialog.h"
#include "voxels/VoxelSystem.h"
class ImportTask;
@ -23,28 +23,29 @@ class ImportTask;
class VoxelImporter : public QObject {
Q_OBJECT
public:
VoxelImporter(QWidget* parent = NULL);
VoxelImporter();
~VoxelImporter();
void reset();
void loadSettings(QSettings* settings);
void saveSettings(QSettings* settings);
void cancel();
VoxelTree* getVoxelTree() { return &_voxelTree; }
bool validImportFile(const QString& filename);
public slots:
int exec();
void import();
void cancel();
void import(const QString& filename);
signals:
void importDone();
void importProgress(int);
private:
VoxelTree _voxelTree;
ImportDialog _importDialog;
ImportTask* _task;
bool _didImport;
void cleanupTask();
private slots:
void finishImport();
};
#endif // hifi_VoxelImporter_h