mirror of https://github.com/CGAL/cgal
1319 lines
38 KiB
C++
1319 lines
38 KiB
C++
#include "config.h"
|
|
#include "MainWindow.h"
|
|
#include "Scene.h"
|
|
#include "Scene_item.h"
|
|
#include <CGAL/Qt/debug.h>
|
|
|
|
#include <QtDebug>
|
|
#include <QFileDialog>
|
|
#include <QFileInfo>
|
|
#include <QSettings>
|
|
#include <QHeaderView>
|
|
#include <QMenu>
|
|
#include <QMenuBar>
|
|
#include <QChar>
|
|
#include <QAction>
|
|
#include <QLibrary>
|
|
#include <QPluginLoader>
|
|
#include <QMessageBox>
|
|
#include <QScrollBar>
|
|
#include <QColor>
|
|
#include <QColorDialog>
|
|
#include <QClipboard>
|
|
#include <QCloseEvent>
|
|
#include <QInputDialog>
|
|
#include <QTreeView>
|
|
#include <QMap>
|
|
#include <QStandardItemModel>
|
|
#include <QStandardItem>
|
|
|
|
#include <stdexcept>
|
|
|
|
#ifdef QT_SCRIPT_LIB
|
|
# include <QScriptValue>
|
|
# ifdef QT_SCRIPTTOOLS_LIB
|
|
# include <QScriptEngineDebugger>
|
|
# endif
|
|
#endif
|
|
|
|
#include "Polyhedron_demo_plugin_interface.h"
|
|
#include "Polyhedron_demo_io_plugin_interface.h"
|
|
|
|
#include "ui_MainWindow.h"
|
|
#include "ui_Preferences.h"
|
|
|
|
#include "Show_point_dialog.h"
|
|
#include "File_loader_dialog.h"
|
|
|
|
#ifdef QT_SCRIPT_LIB
|
|
# include <QScriptEngine>
|
|
# include <QScriptValue>
|
|
|
|
QScriptValue
|
|
myScene_itemToScriptValue(QScriptEngine *engine,
|
|
Scene_item* const &in)
|
|
{
|
|
return engine->newQObject(in);
|
|
}
|
|
|
|
void myScene_itemFromScriptValue(const QScriptValue &object,
|
|
Scene_item* &out)
|
|
{
|
|
out = qobject_cast<Scene_item*>(object.toQObject());
|
|
}
|
|
#endif // QT_SCRIPT_LIB
|
|
|
|
#ifdef QT_SCRIPT_LIB
|
|
# ifdef QT_SCRIPTTOOLS_LIB
|
|
|
|
const QScriptEngineDebugger::DebuggerWidget debug_widgets[9] = {
|
|
QScriptEngineDebugger::ConsoleWidget,
|
|
QScriptEngineDebugger::StackWidget,
|
|
QScriptEngineDebugger::ScriptsWidget,
|
|
QScriptEngineDebugger::LocalsWidget,
|
|
QScriptEngineDebugger::CodeWidget,
|
|
QScriptEngineDebugger::CodeFinderWidget,
|
|
QScriptEngineDebugger::BreakpointsWidget,
|
|
QScriptEngineDebugger::DebugOutputWidget,
|
|
QScriptEngineDebugger::ErrorLogWidget
|
|
};
|
|
const QString debug_widgets_names[9] = {
|
|
"Script console",
|
|
"Stack",
|
|
"Scripts",
|
|
"Locals",
|
|
"Code",
|
|
"CodeFinder",
|
|
"Breakpoints",
|
|
"DebugOutput",
|
|
"ErrorLog"
|
|
};
|
|
|
|
# endif
|
|
#endif
|
|
|
|
QScriptValue myPrintFunction(QScriptContext *context, QScriptEngine *engine)
|
|
{
|
|
MainWindow* mw = qobject_cast<MainWindow*>(engine->parent());
|
|
QString result;
|
|
for (int i = 0; i < context->argumentCount(); ++i) {
|
|
if (i > 0)
|
|
result.append(" ");
|
|
result.append(context->argument(i).toString());
|
|
}
|
|
|
|
if(mw) mw->message(QString("QtScript: ") + result, "");
|
|
|
|
return engine->undefinedValue();
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
MainWindow::MainWindow(QWidget* parent)
|
|
: CGAL::Qt::DemosMainWindow(parent)
|
|
{
|
|
ui = new Ui::MainWindow;
|
|
ui->setupUi(this);
|
|
|
|
// remove the Load Script menu entry, when the demo has not been compiled with QT_SCRIPT_LIB
|
|
#if !defined(QT_SCRIPT_LIB)
|
|
ui->menuBar->removeAction(ui->actionLoad_Script);
|
|
#endif
|
|
|
|
// Save some pointers from ui, for latter use.
|
|
sceneView = ui->sceneView;
|
|
viewer = ui->viewer;
|
|
|
|
// do not save the state of the viewer (anoying)
|
|
viewer->setStateFileName(QString::null);
|
|
|
|
// setup scene
|
|
scene = new Scene(this);
|
|
viewer->setScene(scene);
|
|
sceneView->setModel(scene);
|
|
|
|
// setup the sceneview: delegation and columns sizing...
|
|
sceneView->setItemDelegate(new SceneDelegate(this));
|
|
|
|
sceneView->header()->setStretchLastSection(false);
|
|
sceneView->header()->setResizeMode(Scene::NameColumn, QHeaderView::Stretch);
|
|
sceneView->header()->setResizeMode(Scene::NameColumn, QHeaderView::Stretch);
|
|
sceneView->header()->setResizeMode(Scene::ColorColumn, QHeaderView::ResizeToContents);
|
|
sceneView->header()->setResizeMode(Scene::RenderingModeColumn, QHeaderView::Fixed);
|
|
sceneView->header()->setResizeMode(Scene::ABColumn, QHeaderView::Fixed);
|
|
sceneView->header()->setResizeMode(Scene::VisibleColumn, QHeaderView::Fixed);
|
|
|
|
sceneView->resizeColumnToContents(Scene::ColorColumn);
|
|
sceneView->resizeColumnToContents(Scene::RenderingModeColumn);
|
|
sceneView->resizeColumnToContents(Scene::ABColumn);
|
|
sceneView->resizeColumnToContents(Scene::VisibleColumn);
|
|
|
|
// setup connections
|
|
connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )),
|
|
this, SLOT(updateInfo()));
|
|
|
|
|
|
connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )),
|
|
this, SLOT(updateDisplayInfo()));
|
|
|
|
connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )),
|
|
viewer, SLOT(updateGL()));
|
|
|
|
connect(scene, SIGNAL(updated()),
|
|
viewer, SLOT(update()));
|
|
|
|
connect(scene, SIGNAL(updated()),
|
|
this, SLOT(selectionChanged()));
|
|
|
|
connect(scene, SIGNAL(itemAboutToBeDestroyed(Scene_item*)),
|
|
this, SLOT(removeManipulatedFrame(Scene_item*)));
|
|
|
|
connect(scene, SIGNAL(updated_bbox()),
|
|
this, SLOT(updateViewerBBox()));
|
|
|
|
connect(sceneView->selectionModel(),
|
|
SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & ) ),
|
|
this, SLOT(updateInfo()));
|
|
|
|
connect(sceneView->selectionModel(),
|
|
SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & ) ),
|
|
this, SLOT(updateDisplayInfo()));
|
|
|
|
connect(sceneView->selectionModel(),
|
|
SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & ) ),
|
|
this, SLOT(selectionChanged()));
|
|
|
|
sceneView->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
connect(sceneView, SIGNAL(customContextMenuRequested(const QPoint & )),
|
|
this, SLOT(showSceneContextMenu(const QPoint &)));
|
|
|
|
connect(viewer, SIGNAL(selected(int)),
|
|
this, SLOT(selectSceneItem(int)));
|
|
connect(viewer, SIGNAL(selectedPoint(double, double, double)),
|
|
this, SLOT(showSelectedPoint(double, double, double)));
|
|
|
|
connect(viewer, SIGNAL(selectionRay(double, double, double,
|
|
double, double, double)),
|
|
scene, SIGNAL(selectionRay(double, double, double,
|
|
double, double, double)));
|
|
|
|
connect(viewer, SIGNAL(requestContextMenu(QPoint)),
|
|
this, SLOT(contextMenuRequested(QPoint)));
|
|
|
|
// The contextMenuPolicy of infoLabel is now the default one, so that one
|
|
// can easily copy-paste its text.
|
|
// connect(ui->infoLabel, SIGNAL(customContextMenuRequested(const QPoint & )),
|
|
// this, SLOT(showSceneContextMenu(const QPoint &)));
|
|
|
|
connect(ui->actionRecenterScene, SIGNAL(triggered()),
|
|
viewer->camera(), SLOT(interpolateToFitScene()));
|
|
connect(ui->actionRecenterScene, SIGNAL(triggered()),
|
|
viewer, SLOT(update()));
|
|
|
|
connect(ui->actionAntiAliasing, SIGNAL(toggled(bool)),
|
|
viewer, SLOT(setAntiAliasing(bool)));
|
|
|
|
connect(ui->actionDraw_two_sides, SIGNAL(toggled(bool)),
|
|
viewer, SLOT(setTwoSides(bool)));
|
|
|
|
// add the "About CGAL..." and "About demo..." entries
|
|
this->addAboutCGAL();
|
|
this->addAboutDemo(":/cgal/Polyhedron_3/about.html");
|
|
|
|
// Connect the button "addButton" with actionLoad
|
|
ui->addButton->setDefaultAction(ui->actionLoad);
|
|
// Same with "removeButton" and "duplicateButton"
|
|
ui->removeButton->setDefaultAction(ui->actionErase);
|
|
ui->duplicateButton->setDefaultAction(ui->actionDuplicate);
|
|
|
|
// Connect actionQuit (Ctrl+Q) and qApp->quit()
|
|
connect(ui->actionQuit, SIGNAL(triggered()),
|
|
this, SLOT(quit()));
|
|
|
|
// Connect "Select all items"
|
|
connect(ui->actionSelect_all_items, SIGNAL(triggered()),
|
|
this, SLOT(selectAll()));
|
|
|
|
// Recent files menu
|
|
this->addRecentFiles(ui->menuFile, ui->actionQuit);
|
|
connect(this, SIGNAL(openRecentFile(QString)),
|
|
this, SLOT(open(QString)));
|
|
|
|
// Reset the "Operation menu"
|
|
clearMenu(ui->menuOperations);
|
|
|
|
#ifdef QT_SCRIPT_LIB
|
|
std::cerr << "Enable scripts.\n";
|
|
script_engine = new QScriptEngine(this);
|
|
qScriptRegisterMetaType<Scene_item*>(script_engine,
|
|
myScene_itemToScriptValue,
|
|
myScene_itemFromScriptValue);
|
|
# ifdef QT_SCRIPTTOOLS_LIB
|
|
QScriptEngineDebugger* debugger = new QScriptEngineDebugger(this);
|
|
debugger->setObjectName("qt script debugger");
|
|
QAction* debuggerMenuAction =
|
|
menuBar()->addMenu(debugger->createStandardMenu());
|
|
debuggerMenuAction->setText(tr("Qt Script &debug"));
|
|
for(unsigned int i = 0; i < 9; ++i)
|
|
{
|
|
QDockWidget* dock = new QDockWidget(debug_widgets_names[i], this);
|
|
dock->setObjectName(debug_widgets_names[i]);
|
|
dock->setWidget(debugger->widget(debug_widgets[i]));
|
|
this->addDockWidget(Qt::BottomDockWidgetArea, dock);
|
|
dock->hide();
|
|
}
|
|
debugger->setAutoShowStandardWindow(false);
|
|
debugger->attachTo(script_engine);
|
|
# endif // QT_SCRIPTTOOLS_LIB
|
|
QScriptValue fun = script_engine->newFunction(myPrintFunction);
|
|
script_engine->globalObject().setProperty("print", fun);
|
|
|
|
// evaluate_script("print('hello', 'world', 'from QtScript!')");
|
|
QScriptValue mainWindowObjectValue = script_engine->newQObject(this);
|
|
script_engine->globalObject().setProperty("main_window", mainWindowObjectValue);
|
|
|
|
QScriptValue sceneObjectValue = script_engine->newQObject(scene);
|
|
mainWindowObjectValue.setProperty("scene", sceneObjectValue);
|
|
script_engine->globalObject().setProperty("scene", sceneObjectValue);
|
|
|
|
QScriptValue viewerObjectValue = script_engine->newQObject(viewer);
|
|
mainWindowObjectValue.setProperty("viewer", viewerObjectValue);
|
|
script_engine->globalObject().setProperty("viewer", viewerObjectValue);
|
|
|
|
QScriptValue cameraObjectValue = script_engine->newQObject(viewer->camera());
|
|
viewerObjectValue.setProperty("camera", cameraObjectValue);
|
|
script_engine->globalObject().setProperty("camera", cameraObjectValue);
|
|
|
|
evaluate_script("var plugins = new Array();");
|
|
# ifdef QT_SCRIPTTOOLS_LIB
|
|
QScriptValue debuggerObjectValue = script_engine->newQObject(debugger);
|
|
script_engine->globalObject().setProperty("debugger", debuggerObjectValue);
|
|
# endif
|
|
#endif
|
|
|
|
readSettings(); // Among other things, the column widths are stored.
|
|
|
|
// Load plugins, and re-enable actions that need it.
|
|
loadPlugins();
|
|
|
|
// Setup the submenu of the View menu that can toggle the dockwidgets
|
|
Q_FOREACH(QDockWidget* widget, findChildren<QDockWidget*>()) {
|
|
ui->menuDockWindows->addAction(widget->toggleViewAction());
|
|
}
|
|
ui->menuDockWindows->removeAction(ui->dummyAction);
|
|
|
|
|
|
#ifdef QT_SCRIPT_LIB
|
|
// evaluate_script("print(plugins);");
|
|
Q_FOREACH(QAction* action, findChildren<QAction*>()) {
|
|
if(action->objectName() != "") {
|
|
QScriptValue objectValue = script_engine->newQObject(action);
|
|
script_engine->globalObject().setProperty(action->objectName(),
|
|
objectValue);
|
|
}
|
|
}
|
|
// debugger->action(QScriptEngineDebugger::InterruptAction)->trigger();
|
|
#endif
|
|
|
|
// setup menu filtering
|
|
connect(ui->menuOperations, SIGNAL(aboutToShow()), this, SLOT(filterOperations()));
|
|
}
|
|
|
|
void MainWindow::filterOperations()
|
|
{
|
|
Q_FOREACH(const PluginNamePair& p, plugins) {
|
|
if(p.first->applicable()) {
|
|
Q_FOREACH(QAction* action, p.first->actions()) {
|
|
action->setVisible(true);
|
|
}
|
|
} else {
|
|
Q_FOREACH(QAction* action, p.first->actions()) {
|
|
action->setVisible(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// do a pass over all menus in Operations and hide them when they are empty
|
|
Q_FOREACH(QAction* action, ui->menuOperations->actions()) {
|
|
if(QMenu* menu = action->menu()) {
|
|
action->setVisible(!(menu->isEmpty()));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef QT_SCRIPT_LIB
|
|
void MainWindow::evaluate_script(QString script,
|
|
const QString& filename,
|
|
const bool quiet) {
|
|
QScriptValue value = script_engine->evaluate(script, filename);
|
|
if(script_engine->hasUncaughtException()) {
|
|
QTextStream err(stderr);
|
|
err << "Qt Script exception:\n"
|
|
<< script_engine->uncaughtException().toString()
|
|
<< "\nBacktrace:\n";
|
|
Q_FOREACH(QString line, script_engine->uncaughtExceptionBacktrace()) {
|
|
err << " " << line << "\n";
|
|
}
|
|
}
|
|
else if(!quiet && !value.isNull() && !value.isUndefined()) {
|
|
QTextStream(stderr) << "Qt Script evaluated to \""
|
|
<< value.toString() << "\"\n";
|
|
}
|
|
}
|
|
|
|
void MainWindow::evaluate_script_quiet(QString script,
|
|
const QString& filename)
|
|
{
|
|
evaluate_script(script, filename, true);
|
|
}
|
|
#endif
|
|
|
|
void MainWindow::enableScriptDebugger(bool b /* = true */)
|
|
{
|
|
Q_UNUSED(b);
|
|
#ifdef QT_SCRIPT_LIB
|
|
# ifdef QT_SCRIPTTOOLS_LIB
|
|
QScriptEngineDebugger* debugger =
|
|
findChild<QScriptEngineDebugger*>("qt script debugger");
|
|
if(debugger) {
|
|
if(b) {
|
|
debugger->action(QScriptEngineDebugger::InterruptAction)->trigger();
|
|
}
|
|
}
|
|
return;
|
|
# endif
|
|
#endif
|
|
// If we are here, then the debugger is not available
|
|
this->error(tr("Your version of Qt is too old, and for that reason "
|
|
"the Qt Script Debugger is not available."));
|
|
}
|
|
|
|
namespace {
|
|
bool actionsByName(QAction* x, QAction* y) {
|
|
return x->text() < y->text();
|
|
}
|
|
}
|
|
|
|
void MainWindow::loadPlugins()
|
|
{
|
|
Q_FOREACH(QObject *obj, QPluginLoader::staticInstances())
|
|
{
|
|
initPlugin(obj);
|
|
initIOPlugin(obj);
|
|
}
|
|
|
|
QList<QDir> plugins_directories;
|
|
plugins_directories << qApp->applicationDirPath();
|
|
QString env_path = qgetenv("POLYHEDRON_DEMO_PLUGINS_PATH");
|
|
if(!env_path.isEmpty()) {
|
|
Q_FOREACH (QString pluginsDir,
|
|
env_path.split(":", QString::SkipEmptyParts)) {
|
|
QDir dir(pluginsDir);
|
|
if(dir.isReadable())
|
|
plugins_directories << dir;
|
|
}
|
|
}
|
|
Q_FOREACH (QDir pluginsDir, plugins_directories) {
|
|
qDebug("# Looking for plugins in directory \"%s\"...",
|
|
qPrintable(pluginsDir.absolutePath()));
|
|
Q_FOREACH (QString fileName, pluginsDir.entryList(QDir::Files)) {
|
|
if(fileName.contains("plugin") && QLibrary::isLibrary(fileName)) {
|
|
//set plugin name
|
|
QString name = fileName;
|
|
name.remove(QRegExp("^lib"));
|
|
name.remove(QRegExp("\\..*"));
|
|
//do not load it if it is in the blacklist
|
|
if ( plugin_blacklist.contains(name) ){
|
|
qDebug("### Ignoring plugin \"%s\".", qPrintable(fileName));
|
|
continue;
|
|
}
|
|
qDebug("### Loading \"%s\"...", qPrintable(fileName));
|
|
QPluginLoader loader;
|
|
loader.setFileName(pluginsDir.absoluteFilePath(fileName));
|
|
QObject *obj = loader.instance();
|
|
if(obj) {
|
|
obj->setObjectName(name);
|
|
initPlugin(obj);
|
|
initIOPlugin(obj);
|
|
}
|
|
else {
|
|
qDebug("Error loading \"%s\": %s",
|
|
qPrintable(fileName),
|
|
qPrintable(loader.errorString()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// sort the operations menu by name
|
|
QList<QAction*> actions = ui->menuOperations->actions();
|
|
qSort(actions.begin(), actions.end(), actionsByName);
|
|
ui->menuOperations->clear();
|
|
ui->menuOperations->addActions(actions);
|
|
}
|
|
|
|
|
|
bool MainWindow::hasPlugin(const QString& pluginName) const
|
|
{
|
|
Q_FOREACH(const PluginNamePair& p, plugins) {
|
|
if(p.second == pluginName) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool MainWindow::initPlugin(QObject* obj)
|
|
{
|
|
QObjectList childs = this->children();
|
|
Polyhedron_demo_plugin_interface* plugin =
|
|
qobject_cast<Polyhedron_demo_plugin_interface*>(obj);
|
|
if(plugin) {
|
|
// Call plugin's init() method
|
|
obj->setParent(this);
|
|
plugin->init(this, this->scene, this);
|
|
plugins << qMakePair(plugin, obj->objectName());
|
|
#ifdef QT_SCRIPT_LIB
|
|
QScriptValue objectValue =
|
|
script_engine->newQObject(obj);
|
|
script_engine->globalObject().setProperty(obj->objectName(), objectValue);
|
|
evaluate_script_quiet(QString("plugins.push(%1);").arg(obj->objectName()));
|
|
#endif
|
|
|
|
Q_FOREACH(QAction* action, plugin->actions()) {
|
|
// If action does not belong to the menus, add it to "Operations" menu
|
|
if(!childs.contains(action)) {
|
|
ui->menuOperations->addAction(action);
|
|
}
|
|
// Show and enable menu item
|
|
addAction(action);
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool MainWindow::initIOPlugin(QObject* obj)
|
|
{
|
|
Polyhedron_demo_io_plugin_interface* plugin =
|
|
qobject_cast<Polyhedron_demo_io_plugin_interface*>(obj);
|
|
if(plugin) {
|
|
io_plugins << plugin;
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void MainWindow::clearMenu(QMenu* menu)
|
|
{
|
|
Q_FOREACH(QAction* action, menu->actions())
|
|
{
|
|
QMenu* menu = action->menu();
|
|
if(menu) {
|
|
clearMenu(menu);
|
|
}
|
|
action->setVisible(false);
|
|
}
|
|
menu->menuAction()->setEnabled(false);
|
|
}
|
|
|
|
void MainWindow::addAction(QAction* action)
|
|
{
|
|
if(!action) return;
|
|
|
|
action->setVisible(true);
|
|
action->setEnabled(true);
|
|
Q_FOREACH(QWidget* widget, action->associatedWidgets())
|
|
{
|
|
// qDebug() << QString("%1 (%2)\n")
|
|
// .arg(widget->objectName())
|
|
// .arg(widget->metaObject()->className());
|
|
QMenu* menu = qobject_cast<QMenu*>(widget);
|
|
if(menu)
|
|
{
|
|
addAction(menu->menuAction());
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::addAction(QString actionName,
|
|
QString actionText,
|
|
QString menuName) {
|
|
QMenu* menu = 0;
|
|
Q_FOREACH(QAction* action, findChildren<QAction*>()) {
|
|
if(!action->menu()) continue;
|
|
QString menuText = action->menu()->title();
|
|
if(menuText != menuName) continue;
|
|
menu = action->menu();
|
|
}
|
|
if(menu == 0) {
|
|
menu = new QMenu(menuName, this);
|
|
menuBar()->insertMenu(ui->menuView->menuAction(), menu);
|
|
}
|
|
QAction* action = new QAction(actionText, this);
|
|
action->setObjectName(actionName);
|
|
menu->addAction(action);
|
|
#ifdef QT_SCRIPT_LIB
|
|
QScriptValue objectValue = script_engine->newQObject(action);
|
|
script_engine->globalObject().setProperty(action->objectName(),
|
|
objectValue);
|
|
#endif
|
|
}
|
|
|
|
void MainWindow::viewerShow(float x, float y, float z) {
|
|
viewer->camera()->setRevolveAroundPoint(qglviewer::Vec(x, y, z));
|
|
// viewer->camera()->lookAt(qglviewer::Vec(x, y, z));
|
|
|
|
qglviewer::ManipulatedCameraFrame backup_frame(*viewer->camera()->frame());
|
|
viewer->camera()->fitSphere(qglviewer::Vec(x, y, z),
|
|
viewer->camera()->sceneRadius()/100);
|
|
qglviewer::ManipulatedCameraFrame new_frame(*viewer->camera()->frame());
|
|
*viewer->camera()->frame() = backup_frame;
|
|
viewer->camera()->interpolateTo(new_frame, 1.f);
|
|
viewer->setVisualHintsMask(1);
|
|
}
|
|
|
|
void MainWindow::message(QString message, QString colorName, QString font) {
|
|
if (message.endsWith('\n')) {
|
|
message.remove(message.length()-1, 1);
|
|
}
|
|
std::cerr << qPrintable(message) << std::endl;
|
|
statusBar()->showMessage(message, 5000);
|
|
message = "<font color=\"" + colorName + "\" style=\"font-style: " + font + ";\" >" +
|
|
message + "</font><br>";
|
|
message = "[" + QTime::currentTime().toString() + "] " + message;
|
|
ui->consoleTextEdit->insertHtml(message);
|
|
ui->consoleTextEdit->verticalScrollBar()->setValue(ui->consoleTextEdit->verticalScrollBar()->maximum());
|
|
}
|
|
|
|
void MainWindow::information(QString text) {
|
|
this->message("INFO: " + text, "");
|
|
}
|
|
|
|
void MainWindow::warning(QString text) {
|
|
this->message("WARNING: " + text, "blue");
|
|
}
|
|
|
|
void MainWindow::error(QString text) {
|
|
this->message("ERROR: " + text, "red");
|
|
}
|
|
|
|
void MainWindow::updateViewerBBox()
|
|
{
|
|
const Scene::Bbox bbox = scene->bbox();
|
|
const double xmin = bbox.xmin;
|
|
const double ymin = bbox.ymin;
|
|
const double zmin = bbox.zmin;
|
|
const double xmax = bbox.xmax;
|
|
const double ymax = bbox.ymax;
|
|
const double zmax = bbox.zmax;
|
|
// qDebug() << QString("Bounding box: (%1, %2, %3) - (%4, %5, %6)\n")
|
|
// .arg(xmin).arg(ymin).arg(zmin).arg(xmax).arg(ymax).arg(zmax);
|
|
qglviewer::Vec
|
|
vec_min(xmin, ymin, zmin),
|
|
vec_max(xmax, ymax, zmax);
|
|
viewer->setSceneBoundingBox(vec_min,
|
|
vec_max);
|
|
viewer->camera()->showEntireScene();
|
|
}
|
|
|
|
void MainWindow::reload_item() {
|
|
QAction* sender_action = qobject_cast<QAction*>(sender());
|
|
if(!sender_action) return;
|
|
|
|
bool ok;
|
|
int item_index = sender_action->data().toInt(&ok);
|
|
QObject* item_object = scene->item(item_index);
|
|
if(!ok || !item_object || sender_action->data().type() != QVariant::Int) {
|
|
std::cerr << "Cannot reload item: "
|
|
<< "the reload action has not item attached\n";
|
|
return;
|
|
}
|
|
Scene_item* item = qobject_cast<Scene_item*>(item_object);
|
|
if(!item) {
|
|
std::cerr << "Cannot reload item: "
|
|
<< "the reload action has a QObject* pointer attached\n"
|
|
<< "that is not a Scene_item*\n";
|
|
return;
|
|
}
|
|
QString filename = item->property("source filename").toString();
|
|
QString loader_name = item->property("loader_name").toString();
|
|
if(filename.isEmpty() || loader_name.isEmpty()) {
|
|
std::cerr << "Cannot reload item: "
|
|
<< "the item has no \"source filename\" or no \"loader_name\" attached attached\n";
|
|
return;
|
|
}
|
|
|
|
Polyhedron_demo_io_plugin_interface* fileloader = find_loader(loader_name);
|
|
QFileInfo fileinfo(filename);
|
|
|
|
Scene_item* new_item = load_item(fileinfo, fileloader);
|
|
|
|
new_item->setName(item->name());
|
|
new_item->setColor(item->color());
|
|
new_item->setRenderingMode(item->renderingMode());
|
|
new_item->setVisible(item->visible());
|
|
new_item->changed();
|
|
scene->replaceItem(item_index, new_item);
|
|
delete item;
|
|
}
|
|
|
|
Polyhedron_demo_io_plugin_interface* MainWindow::find_loader(const QString& loader_name) const {
|
|
Q_FOREACH(Polyhedron_demo_io_plugin_interface* io_plugin,
|
|
io_plugins) {
|
|
if(io_plugin->name() == loader_name) {
|
|
return io_plugin;
|
|
}
|
|
}
|
|
throw std::invalid_argument(QString("No loader found with the name %1 available")
|
|
.arg(loader_name).toStdString()) ;
|
|
}
|
|
|
|
void MainWindow::open(QString filename)
|
|
{
|
|
QFileInfo fileinfo(filename);
|
|
QString filename_striped=fileinfo.fileName();
|
|
|
|
#ifdef QT_SCRIPT_LIB
|
|
// Handles the loading of script file from the command line arguments,
|
|
// and the special command line arguments that start with "javascript:"
|
|
// or "qtscript:"
|
|
QString program;
|
|
if(filename.startsWith("javascript:")) {
|
|
program=filename.right(filename.size() - 11);
|
|
}
|
|
if(filename.startsWith("qtscript:")) {
|
|
program=filename.right(filename.size() - 9);
|
|
}
|
|
if(filename.endsWith(".js")) {
|
|
load_script(fileinfo);
|
|
return;
|
|
}
|
|
if(!program.isEmpty())
|
|
{
|
|
{
|
|
QTextStream(stderr) << "Execution of script \""
|
|
<< filename << "\"\n";
|
|
// << filename << "\", with following content:\n"
|
|
// << program;
|
|
}
|
|
evaluate_script(program, filename);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if ( !fileinfo.exists() ){
|
|
QMessageBox::warning(this,
|
|
tr("Cannot open file"),
|
|
tr("File %1 does not exist.")
|
|
.arg(filename));
|
|
return;
|
|
}
|
|
|
|
|
|
QStringList selected_items;
|
|
QStringList all_items;
|
|
|
|
QMap<QString,QString>::iterator dfs_it =
|
|
default_plugin_selection.find( fileinfo.completeSuffix() );
|
|
|
|
if ( dfs_it==default_plugin_selection.end() )
|
|
{
|
|
//match all filters between ()
|
|
QRegExp all_filters_rx("\\((.*)\\)");
|
|
// collect all io_plugins and offer them to load if the file extension match one name filter
|
|
// also collect all available plugin in case of a no extension match
|
|
Q_FOREACH(Polyhedron_demo_io_plugin_interface* io_plugin, io_plugins) {
|
|
all_items << io_plugin->name();
|
|
QStringList split_filters = io_plugin->nameFilters().split(";;");
|
|
bool stop=false;
|
|
Q_FOREACH(const QString& filter, split_filters) {
|
|
//extract filters
|
|
if ( all_filters_rx.indexIn(filter)!=-1 ){
|
|
Q_FOREACH(const QString& pattern,all_filters_rx.cap(1).split(' ')){
|
|
QRegExp rx(pattern);
|
|
rx.setPatternSyntax(QRegExp::Wildcard);
|
|
if ( rx.exactMatch(filename_striped) ){
|
|
selected_items << io_plugin->name();
|
|
stop=true;
|
|
break;
|
|
}
|
|
}
|
|
if (stop) break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
selected_items << *dfs_it;
|
|
|
|
bool ok;
|
|
std::pair<QString, bool> load_pair;
|
|
|
|
switch( selected_items.size() )
|
|
{
|
|
case 1:
|
|
load_pair = std::make_pair(selected_items.first(), false);
|
|
ok=true;
|
|
break;
|
|
case 0:
|
|
load_pair = File_loader_dialog::getItem(fileinfo.fileName(), all_items, &ok);
|
|
break;
|
|
default:
|
|
load_pair = File_loader_dialog::getItem(fileinfo.fileName(), selected_items, &ok);
|
|
}
|
|
|
|
if(!ok || load_pair.first.isEmpty()) { return; }
|
|
|
|
if (load_pair.second)
|
|
default_plugin_selection[fileinfo.completeSuffix()]=load_pair.first;
|
|
|
|
|
|
QSettings settings;
|
|
settings.setValue("OFF open directory",
|
|
fileinfo.absoluteDir().absolutePath());
|
|
|
|
Scene_item* scene_item = load_item(fileinfo, find_loader(load_pair.first));
|
|
selectSceneItem(scene->addItem(scene_item));
|
|
}
|
|
|
|
bool MainWindow::open(QString filename, QString loader_name) {
|
|
QFileInfo fileinfo(filename);
|
|
Scene_item* item;
|
|
try {
|
|
item = load_item(fileinfo, find_loader(loader_name));
|
|
}
|
|
catch(std::logic_error e) {
|
|
std::cerr << e.what() << std::endl;
|
|
return false;
|
|
}
|
|
selectSceneItem(scene->addItem(item));
|
|
return true;
|
|
}
|
|
|
|
|
|
Scene_item* MainWindow::load_item(QFileInfo fileinfo, Polyhedron_demo_io_plugin_interface* loader) {
|
|
Scene_item* item = NULL;
|
|
if(!fileinfo.isFile() || !fileinfo.isReadable()) {
|
|
throw std::invalid_argument(QString("File %1 is not a readable file.")
|
|
.arg(fileinfo.absoluteFilePath()).toStdString());
|
|
}
|
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
item = loader->load(fileinfo);
|
|
QApplication::restoreOverrideCursor();
|
|
if(!item) {
|
|
throw std::logic_error(QString("Could not load item from file %1 using plugin %2")
|
|
.arg(fileinfo.absoluteFilePath()).arg(loader->name()).toStdString());
|
|
}
|
|
|
|
item->setProperty("source filename", fileinfo.absoluteFilePath());
|
|
item->setProperty("loader_name", loader->name());
|
|
return item;
|
|
}
|
|
|
|
void MainWindow::selectSceneItem(int i)
|
|
{
|
|
if(i < 0 || i >= scene->numberOfEntries()) {
|
|
sceneView->selectionModel()->clearSelection();
|
|
updateInfo();
|
|
updateDisplayInfo();
|
|
}
|
|
else {
|
|
sceneView->selectionModel()->select(scene->createSelection(i),
|
|
QItemSelectionModel::ClearAndSelect);
|
|
}
|
|
}
|
|
|
|
|
|
void MainWindow::showSelectedPoint(double x, double y, double z)
|
|
{
|
|
information(QString("Selected point: (%1, %2, %3)").
|
|
arg(x, 0, 'g', 10).
|
|
arg(y, 0, 'g', 10).
|
|
arg(z, 0, 'g', 10));
|
|
}
|
|
|
|
void MainWindow::unSelectSceneItem(int i)
|
|
{
|
|
removeSceneItemFromSelection(i);
|
|
}
|
|
|
|
void MainWindow::addSceneItemInSelection(int i)
|
|
{
|
|
sceneView->selectionModel()->select(scene->createSelection(i),
|
|
QItemSelectionModel::Select);
|
|
scene->itemChanged(i);
|
|
}
|
|
|
|
void MainWindow::removeSceneItemFromSelection(int i)
|
|
{
|
|
sceneView->selectionModel()->select(scene->createSelection(i),
|
|
QItemSelectionModel::Deselect);
|
|
scene->itemChanged(i);
|
|
}
|
|
|
|
void MainWindow::selectAll()
|
|
{
|
|
sceneView->selectionModel()->select(scene->createSelectionAll(),
|
|
QItemSelectionModel::ClearAndSelect);
|
|
}
|
|
|
|
int MainWindow::getSelectedSceneItemIndex() const
|
|
{
|
|
QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows();
|
|
if(selectedRows.size() != 1)
|
|
return -1;
|
|
else
|
|
return selectedRows.first().row();
|
|
}
|
|
|
|
QList<int> MainWindow::getSelectedSceneItemIndices() const
|
|
{
|
|
QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows();
|
|
QList<int> result;
|
|
Q_FOREACH(QModelIndex index, selectedRows) {
|
|
result << index.row();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void MainWindow::selectionChanged()
|
|
{
|
|
scene->setSelectedItem(getSelectedSceneItemIndex());
|
|
scene->setSelectedItemsList(getSelectedSceneItemIndices());
|
|
Scene_item* item = scene->item(getSelectedSceneItemIndex());
|
|
if(item != NULL && item->manipulatable()) {
|
|
viewer->setManipulatedFrame(item->manipulatedFrame());
|
|
} else {
|
|
viewer->setManipulatedFrame(0);
|
|
}
|
|
if(viewer->manipulatedFrame() == 0) {
|
|
Q_FOREACH(Scene_item* item, scene->entries()) {
|
|
if(item->manipulatable() && item->manipulatedFrame() != 0) {
|
|
if(viewer->manipulatedFrame() != 0) {
|
|
// there are at least two possible frames
|
|
viewer->setManipulatedFrame(0);
|
|
break;
|
|
} else {
|
|
viewer->setManipulatedFrame(item->manipulatedFrame());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(viewer->manipulatedFrame() != 0) {
|
|
connect(viewer->manipulatedFrame(), SIGNAL(modified()),
|
|
this, SLOT(updateInfo()));
|
|
}
|
|
viewer->updateGL();
|
|
}
|
|
|
|
void MainWindow::contextMenuRequested(const QPoint& global_pos) {
|
|
int index = scene->mainSelectionIndex();
|
|
showSceneContextMenu(index, global_pos);
|
|
}
|
|
|
|
void MainWindow::showSceneContextMenu(int selectedItemIndex,
|
|
const QPoint& global_pos)
|
|
{
|
|
Scene_item* item = scene->item(selectedItemIndex);
|
|
if(!item) return;
|
|
|
|
const char* prop_name = "Menu modified by MainWindow.";
|
|
|
|
QMenu* menu = item->contextMenu();
|
|
if(menu && !item->property("source filename").toString().isEmpty()) {
|
|
bool menuChanged = menu->property(prop_name).toBool();
|
|
if(!menuChanged) {
|
|
menu->addSeparator();
|
|
QAction* reload = menu->addAction(tr("Reload item from file"));
|
|
reload->setData(qVariantFromValue(selectedItemIndex));
|
|
connect(reload, SIGNAL(triggered()),
|
|
this, SLOT(reload_item()));
|
|
menu->setProperty(prop_name, true);
|
|
}
|
|
}
|
|
if(menu)
|
|
menu->exec(global_pos);
|
|
}
|
|
|
|
void MainWindow::showSceneContextMenu(const QPoint& p) {
|
|
QWidget* sender = qobject_cast<QWidget*>(this->sender());
|
|
if(!sender) return;
|
|
|
|
int index = -1;
|
|
if(sender == sceneView) {
|
|
QModelIndex modelIndex = sceneView->indexAt(p);
|
|
if(!modelIndex.isValid()) return;
|
|
|
|
index = modelIndex.row();
|
|
}
|
|
else {
|
|
index = scene->mainSelectionIndex();
|
|
}
|
|
|
|
showSceneContextMenu(index, sender->mapToGlobal(p));
|
|
}
|
|
|
|
void MainWindow::removeManipulatedFrame(Scene_item* item)
|
|
{
|
|
if(item->manipulatable() &&
|
|
item->manipulatedFrame() == viewer->manipulatedFrame()) {
|
|
viewer->setManipulatedFrame(0);
|
|
}
|
|
}
|
|
|
|
void MainWindow::updateInfo() {
|
|
Scene_item* item = scene->item(getSelectedSceneItemIndex());
|
|
if(item) {
|
|
QString item_text = item->toolTip();
|
|
QString item_filename = item->property("source filename").toString();
|
|
if(!item_filename.isEmpty()) {
|
|
item_text += QString("<br /><i>File: %1").arg(item_filename);
|
|
}
|
|
ui->infoLabel->setText(item_text);
|
|
}
|
|
else
|
|
ui->infoLabel->clear();
|
|
}
|
|
|
|
void MainWindow::updateDisplayInfo() {
|
|
Scene_item* item = scene->item(getSelectedSceneItemIndex());
|
|
if(item)
|
|
ui->displayLabel->setPixmap(item->graphicalToolTip());
|
|
else
|
|
ui->displayLabel->clear();
|
|
}
|
|
|
|
void MainWindow::readSettings()
|
|
{
|
|
{
|
|
QSettings settings;
|
|
// enable anti-aliasing
|
|
ui->actionAntiAliasing->setChecked(settings.value("antialiasing", false).toBool());
|
|
// read plugin blacklist
|
|
QStringList blacklist=settings.value("plugin_blacklist",QStringList()).toStringList();
|
|
Q_FOREACH(QString name,blacklist){ plugin_blacklist.insert(name); }
|
|
}
|
|
this->readState("MainWindow", Size|State);
|
|
}
|
|
|
|
void MainWindow::writeSettings()
|
|
{
|
|
this->writeState("MainWindow");
|
|
{
|
|
QSettings settings;
|
|
settings.setValue("antialiasing",
|
|
ui->actionAntiAliasing->isChecked());
|
|
//setting plugin blacklist
|
|
QStringList blacklist;
|
|
Q_FOREACH(QString name,plugin_blacklist){ blacklist << name; }
|
|
if ( !blacklist.isEmpty() ) settings.setValue("plugin_blacklist",blacklist);
|
|
else settings.remove("plugin_blacklist");
|
|
}
|
|
std::cerr << "Write setting... done.\n";
|
|
}
|
|
|
|
void MainWindow::quit()
|
|
{
|
|
close();
|
|
}
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event)
|
|
{
|
|
writeSettings();
|
|
event->accept();
|
|
}
|
|
|
|
bool MainWindow::load_script(QString filename)
|
|
{
|
|
QFileInfo fileinfo(filename);
|
|
return load_script(fileinfo);
|
|
}
|
|
|
|
bool MainWindow::load_script(QFileInfo info)
|
|
{
|
|
#if defined(QT_SCRIPT_LIB)
|
|
QString program;
|
|
QString filename = info.absoluteFilePath();
|
|
QFile script_file(filename);
|
|
script_file.open(QIODevice::ReadOnly);
|
|
program = script_file.readAll();
|
|
if(!program.isEmpty())
|
|
{
|
|
QTextStream(stderr)
|
|
<< "Execution of script \""
|
|
<< filename << "\"\n";
|
|
evaluate_script(program, filename);
|
|
return true;
|
|
}
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
void MainWindow::on_actionLoad_Script_triggered()
|
|
{
|
|
#if defined(QT_SCRIPT_LIB)
|
|
QString filename = QFileDialog::getOpenFileName(
|
|
this,
|
|
tr("Select a script to run..."),
|
|
".",
|
|
"QTScripts (*.js);;All Files (*)");
|
|
|
|
load_script(QFileInfo(filename));
|
|
#endif
|
|
}
|
|
|
|
void MainWindow::on_actionLoad_triggered()
|
|
{
|
|
QStringList filters;
|
|
// we need to special case our way out of this
|
|
filters << "All Files (*)";
|
|
|
|
QStringList extensions;
|
|
|
|
typedef QMap<QString, Polyhedron_demo_io_plugin_interface*> FilterPluginMap;
|
|
FilterPluginMap filterPluginMap;
|
|
|
|
Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, io_plugins) {
|
|
QStringList split_filters = plugin->nameFilters().split(";;");
|
|
Q_FOREACH(const QString& filter, split_filters) {
|
|
FilterPluginMap::iterator it = filterPluginMap.find(filter);
|
|
if(it != filterPluginMap.end()) {
|
|
qDebug() << "Duplicate Filter: " << it.value();
|
|
qDebug() << "This filter will not be available.";
|
|
} else {
|
|
filterPluginMap[filter] = plugin;
|
|
}
|
|
filters << filter;
|
|
}
|
|
}
|
|
|
|
QSettings settings;
|
|
QString directory = settings.value("OFF open directory",
|
|
QDir::current().dirName()).toString();
|
|
|
|
QFileDialog dialog(this);
|
|
dialog.setDirectory(directory);
|
|
dialog.setNameFilters(filters);
|
|
dialog.setFileMode(QFileDialog::ExistingFiles);
|
|
|
|
if(dialog.exec() != QDialog::Accepted) { return; }
|
|
|
|
FilterPluginMap::iterator it =
|
|
filterPluginMap.find(dialog.selectedNameFilter());
|
|
|
|
Polyhedron_demo_io_plugin_interface* selectedPlugin = NULL;
|
|
|
|
if(it != filterPluginMap.end()) {
|
|
selectedPlugin = it.value();
|
|
}
|
|
|
|
Q_FOREACH(const QString& filename, dialog.selectedFiles()) {
|
|
Scene_item* item = NULL;
|
|
if(selectedPlugin) {
|
|
QFileInfo info(filename);
|
|
item = load_item(info, selectedPlugin);
|
|
Scene::Item_id index = scene->addItem(item);
|
|
selectSceneItem(index);
|
|
this->addToRecentFiles(filename);
|
|
} else {
|
|
open(filename);
|
|
this->addToRecentFiles(filename);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::on_actionSaveAs_triggered()
|
|
{
|
|
QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows();
|
|
if(selectedRows.size() != 1)
|
|
return;
|
|
Scene_item* item = scene->item(getSelectedSceneItemIndex());
|
|
|
|
if(!item)
|
|
return;
|
|
|
|
QVector<Polyhedron_demo_io_plugin_interface*> canSavePlugins;
|
|
QStringList filters;
|
|
Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, io_plugins) {
|
|
if(plugin->canSave(item)) {
|
|
canSavePlugins << plugin;
|
|
filters += plugin->nameFilters();
|
|
}
|
|
}
|
|
filters << tr("All files (*)");
|
|
|
|
if(canSavePlugins.isEmpty()) {
|
|
QMessageBox::warning(this,
|
|
tr("Cannot save"),
|
|
tr("The selected object %1 cannot be saved.")
|
|
.arg(item->name()));
|
|
return;
|
|
}
|
|
|
|
QString filename =
|
|
QFileDialog::getSaveFileName(this,
|
|
tr("Save to File..."),
|
|
QString(),
|
|
filters.join(";;"));
|
|
save(filename, item);
|
|
}
|
|
|
|
void MainWindow::save(QString filename, Scene_item* item) {
|
|
QFileInfo fileinfo(filename);
|
|
|
|
Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, io_plugins) {
|
|
if(plugin->canSave(item)) {
|
|
if(plugin->save(item, fileinfo))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool MainWindow::on_actionErase_triggered()
|
|
{
|
|
int next_index = scene->erase(scene->selectionIndices());
|
|
selectSceneItem(next_index);
|
|
return next_index >= 0;
|
|
}
|
|
|
|
void MainWindow::on_actionEraseAll_triggered()
|
|
{
|
|
while(on_actionErase_triggered()) {
|
|
}
|
|
}
|
|
|
|
void MainWindow::on_actionDuplicate_triggered()
|
|
{
|
|
int index = scene->duplicate(getSelectedSceneItemIndex());
|
|
selectSceneItem(index);
|
|
}
|
|
|
|
void MainWindow::on_actionShowHide_triggered()
|
|
{
|
|
Q_FOREACH(QModelIndex index, sceneView->selectionModel()->selectedRows())
|
|
{
|
|
int i = index.row();
|
|
Scene_item* item = scene->item(i);
|
|
item->setVisible(!item->visible());
|
|
scene->itemChanged(i);
|
|
}
|
|
}
|
|
|
|
void MainWindow::on_actionSetPolyhedronA_triggered()
|
|
{
|
|
int i = getSelectedSceneItemIndex();
|
|
scene->setItemA(i);
|
|
}
|
|
|
|
void MainWindow::on_actionSetPolyhedronB_triggered()
|
|
{
|
|
int i = getSelectedSceneItemIndex();
|
|
scene->setItemB(i);
|
|
}
|
|
void MainWindow::on_actionPreferences_triggered()
|
|
{
|
|
QDialog dialog(this);
|
|
Ui::PreferencesDialog prefdiag;
|
|
prefdiag.setupUi(&dialog);
|
|
|
|
|
|
QStandardItemModel* iStandardModel = new QStandardItemModel(this);
|
|
//add blacklisted plugins
|
|
Q_FOREACH(QString name, plugin_blacklist)
|
|
{
|
|
QStandardItem* item = new QStandardItem(name);
|
|
item->setCheckable(true);
|
|
item->setCheckState(Qt::Checked);
|
|
iStandardModel->appendRow(item);
|
|
}
|
|
|
|
//add operations plugins
|
|
Q_FOREACH(PluginNamePair pair,plugins){
|
|
QStandardItem* item = new QStandardItem(pair.second);
|
|
item->setCheckable(true);
|
|
iStandardModel->appendRow(item);
|
|
}
|
|
|
|
//add io-plugins
|
|
Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, io_plugins)
|
|
{
|
|
QStandardItem* item = new QStandardItem(plugin->name());
|
|
item->setCheckable(true);
|
|
if ( plugin_blacklist.contains(plugin->name()) ) item->setCheckState(Qt::Checked);
|
|
iStandardModel->appendRow(item);
|
|
}
|
|
|
|
//Setting the model
|
|
prefdiag.listView->setModel(iStandardModel);
|
|
|
|
dialog.exec();
|
|
|
|
if ( dialog.result() )
|
|
{
|
|
plugin_blacklist.clear();
|
|
for (int k=0,k_end=iStandardModel->rowCount();k<k_end;++k)
|
|
{
|
|
QStandardItem* item=iStandardModel->item(k);
|
|
if (item->checkState()==Qt::Checked)
|
|
plugin_blacklist.insert(item->text());
|
|
}
|
|
}
|
|
|
|
for (int k=0,k_end=iStandardModel->rowCount();k<k_end;++k) delete iStandardModel->item(k);
|
|
delete iStandardModel;
|
|
}
|
|
|
|
void MainWindow::on_actionSetBackgroundColor_triggered()
|
|
{
|
|
QColor c = QColorDialog::getColor();
|
|
if(c.isValid()) {
|
|
viewer->setBackgroundColor(c);
|
|
}
|
|
}
|
|
|
|
void MainWindow::on_action_Look_at_triggered()
|
|
{
|
|
Show_point_dialog dialog(this);
|
|
int i = dialog.exec();
|
|
if( i == QDialog::Accepted &&
|
|
dialog.has_correct_coordinates() )
|
|
{
|
|
viewerShow((float)dialog.get_x(),
|
|
(float)dialog.get_y(),
|
|
(float)dialog.get_z());
|
|
}
|
|
}
|
|
|
|
QString MainWindow::camera_string() const
|
|
{
|
|
return viewer->dumpCameraCoordinates();
|
|
}
|
|
|
|
void MainWindow::on_actionDumpCamera_triggered()
|
|
{
|
|
information(QString("Camera: %1")
|
|
.arg(camera_string()));
|
|
}
|
|
|
|
void MainWindow::on_action_Copy_camera_triggered()
|
|
{
|
|
qApp->clipboard()->setText(this->camera_string());
|
|
}
|
|
|
|
void MainWindow::on_action_Paste_camera_triggered()
|
|
{
|
|
QString s = qApp->clipboard()->text();
|
|
viewer->moveCameraToCoordinates(s, 0.5f);
|
|
}
|
|
|
|
void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m)
|
|
{
|
|
viewer->setAddKeyFrameKeyboardModifiers(m);
|
|
}
|