Developer Documentation
openFunctions.cc
1/*===========================================================================*\
2* *
3* OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39* *
40\*===========================================================================*/
41
42
43
44
45
46
47
48#include "Core.hh"
49
50#include <ACG/QtWidgets/QtFileDialog.hh>
52
53#include <OpenFlipper/common/RecentFiles.hh>
54
55#include "OpenFlipper/widgets/loadWidget/loadWidget.hh"
56#include "OpenFlipper/widgets/addEmptyWidget/addEmptyWidget.hh"
57
58#include "OpenFunctionThread.hh"
59
60#include <ACG/Scenegraph/SeparatorNode.hh>
61
62void Core::resetScenegraph( bool _resetTrackBall ) {
63
64 if ( OpenFlipper::Options::gui() && !OpenFlipper::Options::sceneGraphUpdatesBlocked() ) {
65
66 unsigned int maxPases = 1;
67 ACG::Vec3d bbmin,bbmax;
69
70 for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i ) {
71 // update scene graph (get new bounding box and set projection right, including near and far plane)
73 coreWidget_->examiner_widgets_[i]->sceneGraph(root_node_scenegraph_,maxPases,bbmin,bbmax, _resetTrackBall );
75 coreWidget_->examiner_widgets_[i]->updateGL();
76 }
77
78 }
79
80}
81
82//========================================================================================
83// === Open/Add-Empty Functions ============================
84//========================================================================================
85
86
87
88void Core::slotGetAllFilters ( QStringList& _list){
90 // Iterate over all types
91 for (int i=0; i < (int)supportedTypes().size(); i++){
92 QString f = supportedTypes()[i].plugin->getLoadFilters();
93 f = f.section(")",0,0).section("(",1,1).trimmed();
94 _list << f;
95 }
96}
97
98void Core::commandLineOpen(const QString& _filename, bool _asPolyMesh ){
99
100 QString file = _filename;
101
102 // Modify filename to contain full paths if they were given as relative paths
103 if ( !file.startsWith("/") && !file.contains(":") ) {
104 file = QDir::currentPath();
105 file += OpenFlipper::Options::dirSeparator();
106 file += _filename;
107 }
108
109 // Add to the open list
110 commandLineFileNames_.push_back(std::pair< QString , bool >(file, _asPolyMesh));
111}
112
113void Core::commandLineScript(const QString& _filename ) {
114
115 QString file = _filename;
116
117 // Modify filename to contain full paths if they were given as relative paths
118 if ( !file.startsWith("/") && !file.contains(":") ) {
119 file = QDir::currentPath();
120 file += OpenFlipper::Options::dirSeparator();
121 file += _filename;
122 }
123
124 // Add to the open list
125 commandLineScriptNames_.push_back(file);
126}
127
129
130
131 // Update logger
132 if ( OpenFlipper::Options::gui())
134
135
136 bool qtScriptSupport = false;
137 slotPluginExists("scripting",qtScriptSupport);
138
139 #ifdef PYTHON_ENABLED
140 bool pythonScriptSupport = true;
141 #else
142 bool pythonScriptSupport = false;
143 #endif
144
145
146 // Collect all script files from the scripting subdirectory and execute them if possible.
147 // You can use this directory to execute scipts that modify for example modify the ui at
148 // every startup.
149
150 // Get the files in the directory
151 QDir scriptDir = OpenFlipper::Options::scriptDir();
152 QStringList scriptFiles = scriptDir.entryList(QDir::Files,QDir::Name);
153
154 // Execute all files ending with ofs
155 for ( int i = 0 ; i < scriptFiles.size(); ++i ) {
156 if ( scriptFiles[i].endsWith("ofs",Qt::CaseInsensitive) ) {
157 if ( qtScriptSupport ) {
158 emit executeFileScript(scriptDir.path() + "/" + scriptFiles[i]);
159 } else {
160 emit log(LOGERR,"No Qt Script support. Unable to execute: " + scriptDir.path() + "/" + scriptFiles[i] );
161 }
162 }
163
164 if ( scriptFiles[i].endsWith("ofp",Qt::CaseInsensitive) ) {
165 #ifdef PYTHON_ENABLED
166 executePythonScriptFile(scriptDir.path() + "/" + scriptFiles[i]);
167 #else
168 emit log(LOGERR,"No Python Script support. Unable to execute: " + scriptDir.path() + "/" + scriptFiles[i] );
169 #endif
170 }
171
172
173 }
174
175 #if QT_VERSION_MAJOR < 6
176 // Clear scripting window afterexecuting the coresubdir scripts
177 if ( qtScriptSupport ) {
178 bool ok = false;
179 slotCall( "scripting" ,"clearEditor()",ok);
180 }
181 #endif
182
183 OpenFlipper::Options::blockSceneGraphUpdates();
184
185 // Open all files given at the commandline
186 for ( uint i = 0 ; i < commandLineFileNames_.size() ; ++i ) {
187
188 // Skip scripts here as they will be handled by a different function
189 QString tmp = commandLineFileNames_[i].first;
190 if ( tmp.endsWith(".ofs",Qt::CaseInsensitive) || tmp.endsWith(".ofp",Qt::CaseInsensitive) ) {
192 continue;
193 }
194
195 // If the file was given with the polymesh option, open them as polymeshes.
196 if (commandLineFileNames_[i].second)
197 loadObject(typeId("PolyMesh"), commandLineFileNames_[i].first);
198 else {
200 }
201 }
202
203 OpenFlipper::Options::unblockSceneGraphUpdates();
204
205 // Reset the scenegraph once to make sure everything is fine
206 resetScenegraph( true );
207
208 // If we have scripting support, execute the scripts given at the commandline.
209 for ( unsigned int i = 0 ; i < commandLineScriptNames_.size() ; ++i ) {
210
211 if ( commandLineScriptNames_[i].endsWith("ofs",Qt::CaseInsensitive) ) {
212
213 if ( qtScriptSupport ) {
215 } else {
216 emit log(LOGERR,"No Qt Script support. Unable to execute: " + commandLineScriptNames_[i] );
217 }
218 }
219
220 if ( commandLineScriptNames_[i].endsWith("ofp",Qt::CaseInsensitive) ) {
221 #ifdef PYTHON_ENABLED
223
224 if ( !OpenFlipper::Options::nogui() ) {
225 if ( coreWidget_->pythonWidget_ == nullptr) {
227 }
228
229 coreWidget_->pythonWidget_->loadScriptFromFile(commandLineScriptNames_[i]);
230 }
231 #else
232 emit log(LOGERR,"No Python Script support. Unable to execute: " + commandLineScriptNames_[i] );
233 #endif
234 }
235
236 }
237
238 // If we don't have a gui and we are not under remote control,
239 // exit the application as there would be no way to execute further commands
240 if ( !OpenFlipper::Options::gui() && !OpenFlipper::Options::remoteControl())
242}
243
244void Core::loadObjectFinished(const QString& _threadId)
245{
246 if ( OpenFlipper::Options::gui() ) {
247 LoadFromPluginThread* thread = dynamic_cast<LoadFromPluginThread*>(sender());
248 if (!thread)
249 return;
250
251 int id = thread->getObjId(0);
252 QString filename = thread->getFilename(0);
253
254 if ( id != -1 ) {
255 coreWidget_->statusMessage( tr("Loading %1 ... done").arg(filename), 4000 );
256
257 // Get the object to figure out the data type
258 BaseObject* object;
260
261 // Security check, if object really exists
262 if ( object != 0 ) {
263
264 // Add to recent files with the given datatype
265 if ( OpenFlipper::Options::gui() )
266 coreWidget_->addRecent(filename, object->dataType());
267 } else {
268 emit log(LOGERR, tr("Unable to add recent as object with id %1 could not be found!").arg(id) );
269 }
270
271 } else
272 coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(filename), 4000 );
273
274 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
276 }
277
278}
279
280
281int Core::loadObject ( QString _filename ) {
288 if (_filename.endsWith(".ini",Qt::CaseInsensitive)) {
289
290 // Load all information from the given ini file
291 openIniFile(_filename,true,true,true);
292
293 if ( OpenFlipper::Options::gui() )
295
296 return -2;
297 } else if (_filename.endsWith(".ofs",Qt::CaseInsensitive)) {
298 emit log(LOGINFO ,tr("Starting script execution of OpenFlipper Script %1.").arg( _filename)) ;
299 emit executeFileScript(_filename);
300 } else if (_filename.endsWith(".ofp",Qt::CaseInsensitive)) {
301 emit log(LOGINFO ,tr("Starting script execution of Python script %1.").arg( _filename)) ;
302 executePythonScriptFile(_filename);
303 } else {
304
305 QFileInfo fi(_filename);
306
307 for (int i=0; i < (int)supportedTypes().size(); i++){
308
309 QString filters = supportedTypes()[i].loadFilters;
310
311 // Only take the parts inside the brackets
312 filters = filters.section("(",1).section(")",0,0);
313
314 // Split into blocks
315 QStringList separateFilters = filters.split(" ");
316
317 bool found = false;
318
319 // for all filters associated with this plugin
320 for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
321 separateFilters[filterId] = separateFilters[filterId].trimmed();
322
323 //check extension
324 if ( separateFilters[filterId].endsWith( "*." + fi.completeSuffix() , Qt::CaseInsensitive) ) {
325 found = true;
326 break;
327 }
328
329 if ( separateFilters[filterId].endsWith( "*." + fi.suffix() , Qt::CaseInsensitive) ) {
330 found = true;
331 emit log(LOGWARN,"Found supported datatype but only the suffix is matched not the complete suffix!");
332 break;
333 }
334
335 }
336
337 // continue processing only if found
338 if ( ! found )
339 continue;
340
341 if ( OpenFlipper::Options::gui() ) {
342 coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
343 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
345 }
346
347 QString jobId = QString("Loading_"+_filename);
348 QVector<LoadFromPluginThread::LoadInfos> infos;
349 infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _filename));
350 LoadFromPluginThread* thread = new LoadFromPluginThread(infos, jobId);
351
352 connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
353 connect(thread, SIGNAL(finished(QString)), this, SLOT(loadObjectFinished(QString)));
354
355 if ( OpenFlipper::Options::gui() )
356 {
357 connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
358
359 slotStartJob(jobId , QString("Loading %1").arg(_filename) , 0, 0, true);
360 thread->start();
361 thread->startProcessing();
362
363
364 while(thread->isRunning())
365 QApplication::processEvents();
366 // process last events
367 QApplication::processEvents();
368 }
369 else
370 {
371 thread->loadFromPlugin();
372 }
373
374 int objId = thread->getObjId(0);
375
376 return objId;
377 }
378 }
379
380 emit log(LOGERR, tr("Unable to load object (type unknown). No suitable plugin found!") );
381
382 return -1;
383}
384
385
387int Core::loadObject( DataType _type, QString _filename) {
392 if (_type == DATA_UNKNOWN)
393 return loadObject(_filename);
394
395 QFileInfo fi(_filename);
396
397 std::vector<int> typeIds;
398 for (int i=0; i < (int)supportedTypes().size(); i++) {
399 if (supportedTypes()[i].type & _type || supportedTypes()[i].type == _type) {
400
401 QString filters = supportedTypes()[i].loadFilters;
402
403 // Only take the parts inside the brackets
404 filters = filters.section("(",1).section(")",0,0);
405
406 // Split into blocks
407 QStringList separateFilters = filters.split(" ");
408
409 // for all filters associated with this plugin
410 for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
411 separateFilters[filterId] = separateFilters[filterId].trimmed();
412
413 //check extension
414 if ( separateFilters[filterId].endsWith( "*." + fi.completeSuffix() , Qt::CaseInsensitive) ) {
415 typeIds.push_back(i);
416 continue;
417 }
418
419 if ( separateFilters[filterId].endsWith( "*." + fi.suffix() , Qt::CaseInsensitive) ) {
420 typeIds.push_back(i);
421 emit log(LOGWARN,"Found supported datatype but only the suffix is matched not the complete suffix!");
422 continue;
423 }
424 }
425 }
426 }
427
428 // load file with plugins
429 size_t nPlugins = typeIds.size();
430 if (nPlugins > 0) {
431
432 int i = -1;
433
434 // several plugins can load this type
435 if (nPlugins > 1) {
436 // let the user choose the plugin for loading
437 if ( OpenFlipper::Options::gui() ) {
438 QStringList items;
439 for (size_t j = 0; j < nPlugins; ++j) {
440 // only add the plugin name if it does not already exist in the itemlist
441 if (items.indexOf(supportedTypes()[typeIds[j]].name) == -1)
442 items << supportedTypes()[typeIds[j]].name;
443 }
444
445 bool ok;
446 QString item = QInputDialog::getItem(coreWidget_, tr("File Plugins"),
447 tr("Please choose a plugin for loading:"), items, 0, false, &ok);
448 if (!ok) {
449 emit log(LOGERR, tr("Unable to load object. No suitable plugin found!") );
450 return -1; //no plugin found
451 } else
452 i = typeIds[items.indexOf(item)];
453 }
454 // if there is no gui just take the first one for now
455 else {
456 i = 0;
457 }
458 } else
459 i = typeIds[0];
460
461 if ( OpenFlipper::Options::gui() ) {
462 coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
463 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
465 }
466
467 //load file
468 QString jobId = QString("Loading_"+_filename);
469 QVector<LoadFromPluginThread::LoadInfos> infos;
470
471 if ( checkSlot( supportedTypes()[i].object , "loadObject(QString,DataType)" ) )
472 infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _type,_filename));
473 else
474 infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _filename));
475
476 LoadFromPluginThread* thread = new LoadFromPluginThread(infos, jobId);
477
478 connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
479 connect(thread, SIGNAL(finished(QString)), this, SLOT(loadObjectFinished(QString)));
480
481 if ( OpenFlipper::Options::gui() )
482 {
483 connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
484
485 slotStartJob(jobId , QString("Loading %1").arg(_filename) , 0, 0, true);
486 thread->start();
487 thread->startProcessing();
488
489
490 while(thread->isRunning())
491 QApplication::processEvents();
492 // process last events
493 QApplication::processEvents();
494 }
495 else
496 {
497 thread->loadFromPlugin();
498 }
499
500 int objId = thread->getObjId(0);
501
502 return objId;
503
504 } else {
505
506 emit log(LOGERR, tr("Unable to load object. No suitable plugin found!") );
507
508 return -1; //no plugin found
509 }
510}
511
512
514 // Iterate over all plugins. The first plugin supporting the addEmpty function for the
515 // specified type will be used to create the new object. If adding the object failed,
516 // we iterate over the remaining plugins.
517
518 // Iterate over type plugins
519 for (int i=0; i < (int)supportedDataTypes_.size(); i++)
520 if ( supportedDataTypes_[i].type & _type ) {
521 int retCode = supportedDataTypes_[i].plugin->addEmpty();
522 if ( retCode != -1 )
523 return retCode;
524 }
525
526 return -1; // no plugin found
527}
528
529//========================================================================================
530// === Open/Add-Empty Slots ============================
531//========================================================================================
532
533void Core::slotAddEmptyObject( DataType _type, int* _id)
534{
535 slotAddEmptyObject(_type,*_id);
536}
537
538void Core::slotAddEmptyObject( DataType _type , int& _id ) {
539
540
541 if (QThread::currentThread() != QApplication::instance()->thread())
542 {
543 //execute method in main thread
544 QMetaObject::invokeMethod(this,"slotAddEmptyObject",Qt::BlockingQueuedConnection, Q_ARG(DataType, _type), Q_ARG(int*, &_id));
545 }
546 else
547 {
548 _id = addEmptyObject( _type );
549 if ( OpenFlipper::Options::doSlotDebugging() ) {
550 if ( sender() != 0 ) {
551 if ( sender()->metaObject() != 0 ) {
552 emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + "," + QString::number(_id) + tr(" ) called by ") +
553 QString( sender()->metaObject()->className() ) );
554 }
555 } else {
556 emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + "," + QString::number(_id) + tr(" ) called by Core") );
557 }
558 }
559 }
560}
561
563void Core::slotCopyObject( int _oldId , int& _newId ) {
564
565 if ( _oldId == -1 ) {
566 emit log(LOGERR,tr("Requested copy for illegal Object id: %1").arg(_oldId) );
567 _newId = -1;
568 return;
569 }
570
571 // get the node
572 BaseObject* object = objectRoot_->childExists(_oldId);
573
574 if ( !object ) {
575 emit log(LOGERR,tr("Requested copy for unknown Object id: %1 ").arg(_oldId) );
576 _newId = -1;
577 return ;
578 }
579
580 // Copy the item
581 BaseObject* copy = object->copy();
582
583 if ( copy == 0 ) {
584 emit log(LOGERR,tr("Unable to create a copy of the object."));
585 return;
586 }
587
588 // Integrate into object tree
589 copy->setParent( object->parent() );
590
591 // return the new id
592 _newId = copy->id();
593
594 // tell plugins that a new object has been created
595 slotEmptyObjectAdded(_newId);
596
597 // tell plugins that the object has been updated
598 slotObjectUpdated(_newId);
599
600}
601
602
604void Core::slotLoad(QStringList _filenames, IdList _pluginIDs) {
605
606
607 QString filemsg = "";
608 if (_filenames.size() > 1)
609 filemsg = QString( tr("Loading Files ...") );
610 else
611 filemsg = QString( tr("Loading %1 ...").arg(_filenames[0]) );
612
613 if ( OpenFlipper::Options::gui() ) {
614 coreWidget_->statusMessage( filemsg );
615 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
617 }
618
619 //setup thread
620 QString jobId = QString("Loading File");
621 if (_filenames.size() > 1)
622 jobId += "s";
623
624 QVector<LoadFromPluginThread::LoadInfos> loadInfos;
625 for (int i = 0; i < _filenames.size(); ++i)
626 loadInfos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[_pluginIDs[i]].plugin, _filenames[i]));
627 LoadFromPluginThread* thread = new LoadFromPluginThread(loadInfos, jobId);
628
629 connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
630 connect(thread, SIGNAL(state(QString , int )), this, SLOT(slotSetJobState(QString , int)));
631
632 if ( OpenFlipper::Options::gui() )
633 {
634 connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
635 //block log (decrease performance when loading multiple files)
636 coreWidget_->logWidget_->setUpdatesEnabled(false);
637
638 // start thread
639 if (_filenames.size() > 1)
640 slotStartJob(jobId , QString(filemsg), 0, _filenames.size(), true);
641 else
642 slotStartJob(jobId , QString(filemsg), 0, 0, true);
643
644 thread->start();
645 thread->startProcessing();
646
647 //wait thread
648 while(thread->isRunning())
649 QApplication::processEvents();
650 //process last occuring events
651 QApplication::processEvents();
652
653 //unblock and update log
654 coreWidget_->logWidget_->setUpdatesEnabled(true);
655 }
656 else
657 {
658 thread->loadFromPlugin();
659 }
660
661 // Initialize as unknown type
662 QVector<DataType> type = QVector<DataType>(_filenames.size(), DATA_UNKNOWN);
663
664 for (int i = 0; i < _filenames.size(); ++i)
665 {
666 int id = thread->getObjId(i);
667
668 if ( OpenFlipper::Options::gui() ) {
669
670 if ( id != -1 )
671 coreWidget_->statusMessage( tr("Loading %1 done").arg(_filenames[i]), 4000 );
672 else
673 coreWidget_->statusMessage( tr("Loading %1 failed").arg(_filenames[i]), 4000 );
674
675 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
677 }
678
679 if ( id > 0 ) {
680
681 BaseObjectData* object;
683
684 if ( !object ) {
685
686 BaseObject* baseObj = 0;
687 GroupObject* group = 0;
688
689 PluginFunctions::getObject(id,baseObj);
690
691 if (baseObj){
692
693 group = dynamic_cast< GroupObject* > (baseObj);
694
695 if (group)
696 type[i] = DATA_GROUP;
697
698 }
699
700 if ( group == 0 ){
701 emit log(LOGERR,tr("Object id returned but no object with this id has been found! Error in one of the file plugins!"));
702 return;
703 }
704 }
705
706 // Get the objects type
707 if (object)
708 type[i] = object->dataType();
709 }
710 }
711
712 // If the id was greater than zero, add the file to the recent files.
713 if ( OpenFlipper::Options::gui() )
714 for (int i = 0; i < _filenames.size(); ++i)
715 if ( thread->getObjId(i) >= 0 )
716 coreWidget_->addRecent(_filenames[i], type[i]);
717
718}
719
721void Core::slotLoad(QString _filename, DataType _type, int& _id) {
722 _id = loadObject(_type,_filename);
723
724 if ( _id < 0 )
725 _id = -1;
726 else
727 if ( OpenFlipper::Options::gui() )
728 coreWidget_->addRecent(_filename,_type);
729}
730
732void Core::slotFileOpened ( int _id ) {
733
734 if (QThread::currentThread() != QApplication::instance()->thread())
735 {
736 QMetaObject::invokeMethod(this,"slotFileOpened",Qt::QueuedConnection, Q_ARG(int, _id));
737 return;
738 }
739
740 if ( OpenFlipper::Options::doSlotDebugging() ) {
741 if ( sender() != 0 ) {
742 if ( sender()->metaObject() != 0 ) {
743 emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by ") +
744 QString( sender()->metaObject()->className() ) );
745 }
746 } else {
747 emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by Core") );
748 }
749 }
750
751 // get the opened object
752 BaseObjectData* object;
753 PluginFunctions::getObject(_id,object);
754
755 // ================================================================================
756 // Recompute bounding box and scenegraph info
757 // Reset scene center here to include new object
758 // ================================================================================
759 resetScenegraph(true);
760
761 // ================================================================================
762 // Tell plugins, that a file has been opened
763 // ================================================================================
764 emit openedFile( _id );
765
766 // ================================================================================
767 // Print Info to logger
768 // ================================================================================
769 emit log( LOGINFO ,object->getObjectinfo() );
770
771 // ================================================================================
772 // Tell plugins, that the Object is updated and the active object has changed
773 // ================================================================================
774 emit signalObjectUpdated(_id );
776
777 // ================================================================================
778 // Create initial backup
779 // ================================================================================
780 emit createBackup(_id,"Original Object");
781
782 // ================================================================================
783 // Add the file to the recent files menu
784 // ================================================================================
785 QString filename = object->path() + OpenFlipper::Options::dirSeparator() + object->name();
786 BaseObject* object2;
787 PluginFunctions::getObject(_id,object2);
788
789 // ================================================================================
790 // show all files
791 // ================================================================================
793
794 // objectRoot_->dumpTree();
795}
796
799
800 if ( OpenFlipper::Options::doSlotDebugging() ) {
801 if ( sender() != 0 ) {
802 if ( sender()->metaObject() != 0 ) {
803 emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by ") +
804 QString( sender()->metaObject()->className() ) );
805 }
806 } else {
807 emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by Core") );
808 }
809 }
810
811 // get the opened object
812 BaseObjectData* object;
813 PluginFunctions::getObject(_id,object);
814
815
816 emit emptyObjectAdded( _id );
817
818 // Tell the Plugins that the Object List and the active object have changed
819 emit signalObjectUpdated(_id);
821
822 resetScenegraph(false);
823
825// QString filename = object->path() + OpenFlipper::Options::dirSeparator() + object->name();
826
827// addRecent(filename);
828}
829
830//========================================================================================
831// === Menu Slots ============================
832//========================================================================================
833
836 std::vector< DataType > types;
837 QStringList typeNames;
838
839 DataType currentType = 2;
840
841 // Iterate over all Types known to the core
842 // Start at 2:
843 // 0 type is defined as DATA_UNKNOWN
844 // 1 type is defined as DATA_GROUP
845 // Therefore we have two types less then reported
846 //
847 for ( uint i = 0 ; i < typeCount() - 2 ; ++i) {
848
849 // Iterate over all supported types (created from plugins on load)
850 // Check if a plugin supports addEmpty for the current type.
851 // Only if the type is supported, add it to the addEmpty Dialog
852
853 // typePlugin
854 for ( uint j = 0 ; j < supportedDataTypes_.size(); j++) {
855
856 // Check if a plugin supports the current type
857 if ( supportedDataTypes_[j].type & currentType ) {
858 types.push_back(currentType);
859 typeNames.push_back( typeName( currentType ) );
860
861 // Stop here as we need only one plugin supporting addEmpty for a given type
862 break;
863 }
864 }
865
866 // filePlugin
867 for ( uint j = 0 ; j < supportedTypes().size(); j++) {
868
869 // Check if a plugin supports the current Type
870 if ( supportedTypes()[j].type & currentType ) {
871
872 // Avoid duplicates
873 bool duplicate = false;
874 for(std::vector< DataType >::iterator it = types.begin(); it != types.end(); ++it) {
875 if(*it == currentType) {
876 duplicate = true;
877 break;
878 }
879 }
880
881 if(!duplicate) {
882 types.push_back(currentType);
883 typeNames.push_back( typeName( currentType ) );
884
885 // Stop here as we need only one plugin supporting addEmpty for a given type
886 break;
887 }
888 }
889 }
890
891 // Advance to next type ( Indices are bits so multiply by two to get next bit)
892 ++currentType;
893 }
894
895
896
897 if (supportedTypes().size() != 0) {
898
899 static addEmptyWidget* widget = 0;
900
901 if ( !widget ){
902 widget = new addEmptyWidget(types,typeNames);
903 widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
904 connect(widget,SIGNAL(chosen(DataType, int&)),this,SLOT(slotAddEmptyObject(DataType, int&)));
905 }
906
907 widget->show();
908
909 } else
910 emit log(LOGERR,tr("Could not show 'add Empty' dialog. Missing file-plugins ?"));
911
912}
913
914//========================================================================================
915// === Public Slots ============================
916//========================================================================================
917
920
921 if ( OpenFlipper::Options::gui() ){
922
923 if (supportedTypes().size() != 0){
924 LoadWidget* widget = new LoadWidget(supportedTypes());
925 connect(widget,SIGNAL(loadFiles(QStringList, IdList)),this,SLOT(slotLoad(QStringList, IdList)));
926 connect(widget,SIGNAL(save(int, QString, int)),this,SLOT(saveObject(int, QString, int)));
927
928 widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
929
930 widget->showLoad();
931
932 widget->disconnect();
933 delete widget;
934
935 }else
936 emit log(LOGERR,tr("Could not show 'load objects' dialog. Missing file-plugins."));
937
938 }
939}
940
943
944 if ( OpenFlipper::Options::gui() ){
945
946 QString complete_name;
947
948
949 QFileDialog fileDialog( coreWidget_,
950 tr("Load Settings"),
951 OpenFlipperSettings().value("Core/CurrentDir").toString(),
952 tr("INI files (*.ini)") );
953
954 fileDialog.setOption (QFileDialog::DontUseNativeDialog, true);
955 fileDialog.setAcceptMode ( QFileDialog::AcceptOpen );
956 fileDialog.setFileMode ( QFileDialog::AnyFile );
957
958 QGridLayout *layout = (QGridLayout*)fileDialog.layout();
959
960 QGroupBox* optionsBox = new QGroupBox( &fileDialog ) ;
961 optionsBox->setSizePolicy( QSizePolicy ( QSizePolicy::Expanding , QSizePolicy::Preferred ) );
962 optionsBox->setTitle(tr("Options"));
963 layout->addWidget( optionsBox, layout->rowCount() , 0 , 1,layout->columnCount() );
964
965 QCheckBox *loadProgramSettings = new QCheckBox(optionsBox);
966 loadProgramSettings->setText(tr("Load program settings"));
967 loadProgramSettings->setToolTip(tr("Load all current program settings from the file ( This will include view settings, colors,...) "));
968 loadProgramSettings->setCheckState( Qt::Unchecked );
969
970 QCheckBox *loadPluginSettings = new QCheckBox(optionsBox);
971 loadPluginSettings->setText(tr("Load per Plugin Settings"));
972 loadPluginSettings->setToolTip(tr("Plugins should load their current global settings from the file"));
973 loadPluginSettings->setCheckState( Qt::Checked );
974
975 QCheckBox *loadObjectInfo = new QCheckBox(optionsBox);
976 loadObjectInfo->setText(tr("Load all objects defined in the file"));
977 loadObjectInfo->setToolTip(tr("Load all objects which are defined in the file"));
978 loadObjectInfo->setCheckState( Qt::Checked );
979
980 QBoxLayout* frameLayout = new QBoxLayout(QBoxLayout::TopToBottom,optionsBox);
981
982 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
983 frameLayout->addWidget( loadProgramSettings , 0 , 0);
984 frameLayout->addWidget( loadPluginSettings , 1 , 0);
985 frameLayout->addWidget( loadObjectInfo , 2 , 0);
986 #else
987 frameLayout->addWidget( loadProgramSettings , 0 , Qt::Alignment() );
988 frameLayout->addWidget( loadPluginSettings , 1 , Qt::Alignment() );
989 frameLayout->addWidget( loadObjectInfo , 2 , Qt::Alignment() );
990 #endif
991 frameLayout->addStretch();
992
993 fileDialog.resize(550 ,500);
994
995 // ========================================================================================
996 // show the saveSettings-Dialog and get the target file
997 // ========================================================================================
998 QStringList fileNames;
999 if (fileDialog.exec()) {
1000 fileNames = fileDialog.selectedFiles();
1001 } else {
1002 return;
1003 }
1004
1005 if ( fileNames.size() > 1 ) {
1006 std::cerr << "Too many save filenames selected" << std::endl;
1007 return;
1008 }
1009
1010 complete_name = fileNames[0];
1011
1012
1013 QString newpath = complete_name.section(OpenFlipper::Options::dirSeparator(),0,-2);
1014 OpenFlipperSettings().setValue("Core/CurrentDir", newpath);
1015
1016 if ( complete_name.endsWith("ini",Qt::CaseInsensitive) ) {
1017 openIniFile( complete_name,
1018 loadProgramSettings->isChecked(),
1019 loadPluginSettings->isChecked(),
1020 loadObjectInfo->isChecked());
1021 if ( loadProgramSettings->isChecked() )
1022 applyOptions();
1023 }
1024
1025 coreWidget_->addRecent(complete_name, DATA_UNKNOWN);
1026 }
1027}
1028
1030void Core::loadSettings(QString _filename){
1031
1032 if ( !QFile(_filename).exists() )
1033 return;
1034
1035 QString newpath = _filename.section(OpenFlipper::Options::dirSeparator(),0,-2);
1036 OpenFlipperSettings().setValue("Core/CurrentDir", newpath);
1037
1038 if ( _filename.endsWith("obj",Qt::CaseInsensitive) ) {
1039 loadObject(_filename);
1040 applyOptions();
1041 } else {
1042 // Loaded function for recent files. Load everything.
1043 openIniFile(_filename,true,true,true);
1044 applyOptions();
1045 }
1046}
DLLEXPORT DataType typeId(QString _name)
Given a dataType Identifier string this function will return the id of the datatype.
Definition: Types.cc:139
const DataType DATA_UNKNOWN(0)
None of the other Objects.
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.
Definition: Types.cc:154
DLLEXPORT size_t typeCount()
Get the number of registered types.
Definition: Types.cc:175
const DataType DATA_GROUP(1)
Items used for Grouping.
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:181
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
@ LOGERR
@ LOGWARN
@ LOGINFO
virtual QString getObjectinfo()
Get all Info for the Object as a string.
Definition: BaseObject.cc:242
BaseObject * parent()
Get the parent item ( 0 if rootitem )
Definition: BaseObject.cc:464
void setParent(BaseObject *_parent)
Set the parent pointer.
Definition: BaseObject.cc:475
BaseObject * childExists(int _objectId)
Check if the element exists in the subtree of this element.
Definition: BaseObject.cc:514
bool dataType(DataType _type) const
Definition: BaseObject.cc:219
virtual BaseObject * copy()
Returns a full copy of the object.
Definition: BaseObject.cc:767
int id() const
Definition: BaseObject.cc:188
void showPythonScriptInterpreter()
Pointer to the OptionsWidget.
Definition: Python.cc:3
std::vector< glViewer * > examiner_widgets_
Examiner Widget.
Definition: CoreWidget.hh:684
LoggerWidget * logWidget_
Textedit at the bottom for log messages.
Definition: CoreWidget.hh:693
void addRecent(QString _filename, DataType _type)
Add a recent file and update menu.
Definition: CoreWidget.cc:878
void updateInSceneLoggerGeometry()
Set in-scene logger geometry right.
PythonWidget * pythonWidget_
Pointer to the about widget.
Definition: CoreWidget.hh:1248
void slotGetAllFilters(QStringList &_list)
Called when a plugin requests a list of file-filters.
void executeFileScript(QString _filename)
Core scripting engine.
void commandLineOpen(const QString &_filename, bool _asPolyMesh)
Load an object from the commandline on application start.
void applyOptions()
after ini-files have been loaded and core is up or if options have been changed -> apply Options
BaseObject * objectRoot_
Pointer to the data rootNode;.
Definition: Core.hh:1649
void slotCall(const QString &_pluginName, const QString &_functionName, bool &_success)
Definition: RPC.cc:95
void emptyObjectAdded(int _id)
Tell the plugins that an empty object has been added.
void commandLineScript(const QString &_filename)
Load a script from the commandline on application start.
void slotAddEmptyObjectMenu()
Open the add Empty dialog.
std::vector< dataTypes > supportedDataTypes_
Type-Plugins.
Definition: Core.hh:1645
void openedFile(int _id)
Tell the plugins that a file has been opened ( -> Database)
void slotCopyObject(int _oldId, int &_newId)
Slot copying an object.
void slotEmptyObjectAdded(int _id)
Called when an empty object has been Added.
void slotFinishJob(QString _jobId)
A job state has been finished by a plugin.
Definition: process.cc:238
void loadObject()
Open Load Widget.
std::vector< std::pair< QString, bool > > commandLineFileNames_
Vector storing filenames from commandline to be opened after application startup (objects)
Definition: Core.hh:888
bool checkSlot(QObject *_plugin, const char *_slotSignature)
Check if a plugin has a slot.
void createBackup(int _objectid, QString _name, UpdateType _type=UPDATE_ALL)
Tell backup-plugin to create a backup.
void slotSetJobState(QString _jobId, int _value)
A job state has been updated by a plugin.
Definition: process.cc:141
void executePythonScriptFile(QString _filename)
Open the given file and execute its contents as a python script.
Definition: scripting.cc:469
void loadObjectFinished(const QString &_filename)
Vector storing filenames from commandline to be opened after application startup (objects)
void slotLoad(QString _filename, DataType _type, int &_id)
A plugin wants to load a given file.
void resetScenegraph(bool _resetTrackBall)
void slotStartJob(QString _jobId, QString _description, int _min, int _max, bool _blocking)
A job has been started by a plugin.
Definition: process.cc:64
void slotPluginExists(const QString &_pluginName, bool &_exists)
Check if a plugin exists.
Definition: RPC.cc:63
void slotExecuteAfterStartup()
Executed after loading core completly to load files from commandline.
void slotAddEmptyObject(DataType _type, int &_id)
Slot adding empty object of a given type.
SeparatorNode * root_node_scenegraph_
Scenegraphs root node.
Definition: Core.hh:1079
void slotObjectUpdated(int _identifier, const UpdateType &_type=UPDATE_ALL)
Called by the plugins if they changed something in the object list (deleted, added,...
void updateView()
Called when a plugin requests an update in the viewer.
Definition: Core.cc:966
void log(Logtype _type, QString _message)
Logg with OUT,WARN or ERR as type.
void exitApplication()
exit the current application
Definition: Core.cc:1083
void slotFileOpened(int _id)
Called when a file has been opened.
void loadSettings()
Load status from file.
bool saveObject(int _id, QString _filename)
Save an object.
void signalObjectUpdated(int)
When this Signal is emitted all Plugins are informed that the object list changed.
int addEmptyObject(DataType _type)
std::vector< QString > commandLineScriptNames_
Vector storing filenames from commandline to be opened after application startup (script files)
Definition: Core.hh:891
CoreWidget * coreWidget_
The main applications widget ( only created in gui mode )
Definition: Core.hh:1652
void openIniFile(QString _filename, bool _coreSettings, bool _perPluginSettings, bool _loadObjects)
Load information from an ini file.
Definition: ParseIni.cc:400
Predefined datatypes.
Definition: DataTypes.hh:83
QString name() const
Return the name of this type as text.
Definition: Types.cc:411
int showLoad()
show Widget for loading Files
Definition: loadWidget.cc:370
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void startProcessing()
start processing
void unLockUpdate()
Unlock display locked by updateLock().
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void analyzeSceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int &_maxPasses, ACG::Vec3d &_bbmin, ACG::Vec3d &_bbmax)
Analyze the SceneGraph <ACG/Scenegraph/SceneGraphAnalysis.hh>
@ READY
Status is ready (green light)
@ PROCESSING
Status is processing but system will allow interaction (yellow light)
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
void viewAll(int _viewer)
View the whole scene.
Struct containing all relevant information about a load operation.