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 
62 void 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 
88 void 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 
98 void 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 
113 void 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  //check if we have scripting support:
136  bool scriptingSupport = false;
137  slotPluginExists("scripting",scriptingSupport);
138  if ( ! scriptingSupport ) {
139  emit log(LOGERR ,tr("No scripting support available, please check if we load a scripting plugin .. Skipping script execution on startup"));
140  }
141 
142  // Collect all script files from the scripting subdirectory and execute them if possible.
143  // You can use this directory to execute scipts that modify for example modify the ui at
144  // every startup.
145  if ( scriptingSupport ) {
146 
147  // Get the files in the directory
148  QDir scriptDir = OpenFlipper::Options::scriptDir();
149  QStringList scriptFiles = scriptDir.entryList(QDir::Files,QDir::Name);
150 
151  // Execute all files ending with ofs
152  for ( int i = 0 ; i < scriptFiles.size(); ++i ) {
153  if ( scriptFiles[i].endsWith("ofs",Qt::CaseInsensitive) )
154  emit executeFileScript(scriptDir.path() + "/" + scriptFiles[i]);
155 
156  if ( scriptFiles[i].endsWith("ofp",Qt::CaseInsensitive) )
157  executePythonScriptFile(scriptDir.path() + "/" + scriptFiles[i]);
158  }
159 
160  // Clear scripting window afterexecuting the coresubdir scripts
161  bool ok = false;
162  slotCall( "scripting" ,"clearEditor()",ok);
163  }
164 
165  OpenFlipper::Options::blockSceneGraphUpdates();
166 
167  // Open all files given at the commandline
168  for ( uint i = 0 ; i < commandLineFileNames_.size() ; ++i ) {
169 
170  // Skip scripts here as they will be handled by a different function
171  QString tmp = commandLineFileNames_[i].first;
172  if ( tmp.endsWith(".ofs",Qt::CaseInsensitive) || tmp.endsWith(".ofp",Qt::CaseInsensitive) ) {
174  continue;
175  }
176 
177  // If the file was given with the polymesh option, open them as polymeshes.
178  if (commandLineFileNames_[i].second)
179  loadObject(typeId("PolyMesh"), commandLineFileNames_[i].first);
180  else {
182  }
183  }
184 
185  OpenFlipper::Options::unblockSceneGraphUpdates();
186 
187  // Reset the scenegraph once to make sure everything is fine
188  resetScenegraph( true );
189 
190  // If we have scripting support, execute the scripts given at the commandline.
191  if ( scriptingSupport )
192  for ( unsigned int i = 0 ; i < commandLineScriptNames_.size() ; ++i ) {
193 
194  if ( commandLineScriptNames_[i].endsWith("ofs",Qt::CaseInsensitive) )
196 
197  if ( commandLineScriptNames_[i].endsWith("ofp",Qt::CaseInsensitive) )
199 
200  }
201 
202  // If we don't have a gui and we are not under remote control,
203  // exit the application as there would be no way to execute further commands
204  if ( !OpenFlipper::Options::gui() && !OpenFlipper::Options::remoteControl())
205  exitApplication();
206 }
207 
208 void Core::loadObjectFinished(QString _threadId)
209 {
210  if ( OpenFlipper::Options::gui() ) {
211  LoadFromPluginThread* thread = dynamic_cast<LoadFromPluginThread*>(sender());
212  if (!thread)
213  return;
214 
215  int id = thread->getObjId(0);
216  QString filename = thread->getFilename(0);
217 
218  if ( id != -1 ) {
219  coreWidget_->statusMessage( tr("Loading %1 ... done").arg(filename), 4000 );
220 
221  // Get the object to figure out the data type
222  BaseObject* object;
223  PluginFunctions::getObject(id,object);
224 
225  // Security check, if object really exists
226  if ( object != 0 ) {
227 
228  // Add to recent files with the given datatype
229  if ( OpenFlipper::Options::gui() )
230  coreWidget_->addRecent(filename, object->dataType());
231  } else {
232  emit log(LOGERR, tr("Unable to add recent as object with id %1 could not be found!").arg(id) );
233  }
234 
235  } else
236  coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(filename), 4000 );
237 
238  if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
240  }
241 
242 }
243 
244 
245 int Core::loadObject ( QString _filename ) {
252  if (_filename.endsWith(".ini",Qt::CaseInsensitive)) {
253 
254  // Load all information from the given ini file
255  openIniFile(_filename,true,true,true);
256 
257  if ( OpenFlipper::Options::gui() )
258  coreWidget_->addRecent(_filename, DATA_UNKNOWN);
259 
260  return -2;
261  } else if (_filename.endsWith(".ofs",Qt::CaseInsensitive)) {
262  emit log(LOGINFO ,tr("Starting script execution of OpenFlipper Script %1.").arg( _filename)) ;
263  emit executeFileScript(_filename);
264  } else if (_filename.endsWith(".ofp",Qt::CaseInsensitive)) {
265  emit log(LOGINFO ,tr("Starting script execution of Python script %1.").arg( _filename)) ;
266  executePythonScriptFile(_filename);
267  } else {
268 
269  QFileInfo fi(_filename);
270 
271  for (int i=0; i < (int)supportedTypes().size(); i++){
272 
273  QString filters = supportedTypes()[i].loadFilters;
274 
275  // Only take the parts inside the brackets
276  filters = filters.section("(",1).section(")",0,0);
277 
278  // Split into blocks
279  QStringList separateFilters = filters.split(" ");
280 
281  bool found = false;
282 
283  // for all filters associated with this plugin
284  for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
285  separateFilters[filterId] = separateFilters[filterId].trimmed();
286 
287  //check extension
288  if ( separateFilters[filterId].endsWith( "*." + fi.completeSuffix() , Qt::CaseInsensitive) ) {
289  found = true;
290  break;
291  }
292 
293  if ( separateFilters[filterId].endsWith( "*." + fi.suffix() , Qt::CaseInsensitive) ) {
294  found = true;
295  emit log(LOGWARN,"Found supported datatype but only the suffix is matched not the complete suffix!");
296  break;
297  }
298 
299  }
300 
301  // continue processing only if found
302  if ( ! found )
303  continue;
304 
305  if ( OpenFlipper::Options::gui() ) {
306  coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
307  if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
309  }
310 
311  QString jobId = QString("Loading_"+_filename);
312  QVector<LoadFromPluginThread::LoadInfos> infos;
313  infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _filename));
314  LoadFromPluginThread* thread = new LoadFromPluginThread(infos, jobId);
315 
316  connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
317  connect(thread, SIGNAL(finished(QString)), this, SLOT(loadObjectFinished(QString)));
318 
319  if ( OpenFlipper::Options::gui() )
320  {
321  connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
322 
323  slotStartJob(jobId , QString("Loading %1").arg(_filename) , 0, 0, true);
324  thread->start();
325  thread->startProcessing();
326 
327 
328  while(thread->isRunning())
329  QApplication::processEvents();
330  // process last events
331  QApplication::processEvents();
332  }
333  else
334  {
335  thread->loadFromPlugin();
336  }
337 
338  int objId = thread->getObjId(0);
339 
340  return objId;
341  }
342  }
343 
344  emit log(LOGERR, tr("Unable to load object (type unknown). No suitable plugin found!") );
345 
346  return -1;
347 }
348 
349 
351 int Core::loadObject( DataType _type, QString _filename) {
356  if (_type == DATA_UNKNOWN)
357  return loadObject(_filename);
358 
359  QFileInfo fi(_filename);
360 
361  std::vector<int> typeIds;
362  for (int i=0; i < (int)supportedTypes().size(); i++) {
363  if (supportedTypes()[i].type & _type || supportedTypes()[i].type == _type) {
364 
365  QString filters = supportedTypes()[i].loadFilters;
366 
367  // Only take the parts inside the brackets
368  filters = filters.section("(",1).section(")",0,0);
369 
370  // Split into blocks
371  QStringList separateFilters = filters.split(" ");
372 
373  // for all filters associated with this plugin
374  for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
375  separateFilters[filterId] = separateFilters[filterId].trimmed();
376 
377  //check extension
378  if ( separateFilters[filterId].endsWith( "*." + fi.completeSuffix() , Qt::CaseInsensitive) ) {
379  typeIds.push_back(i);
380  continue;
381  }
382 
383  if ( separateFilters[filterId].endsWith( "*." + fi.suffix() , Qt::CaseInsensitive) ) {
384  typeIds.push_back(i);
385  emit log(LOGWARN,"Found supported datatype but only the suffix is matched not the complete suffix!");
386  continue;
387  }
388  }
389  }
390  }
391 
392  // load file with plugins
393  size_t nPlugins = typeIds.size();
394  if (nPlugins > 0) {
395 
396  int i = -1;
397 
398  // several plugins can load this type
399  if (nPlugins > 1) {
400  // let the user choose the plugin for loading
401  if ( OpenFlipper::Options::gui() ) {
402  QStringList items;
403  for (size_t j = 0; j < nPlugins; ++j) {
404  // only add the plugin name if it does not already exist in the itemlist
405  if (items.indexOf(supportedTypes()[typeIds[j]].name) == -1)
406  items << supportedTypes()[typeIds[j]].name;
407  }
408 
409  bool ok;
410  QString item = QInputDialog::getItem(coreWidget_, tr("File Plugins"),
411  tr("Please choose a plugin for loading:"), items, 0, false, &ok);
412  if (!ok) {
413  emit log(LOGERR, tr("Unable to load object. No suitable plugin found!") );
414  return -1; //no plugin found
415  } else
416  i = typeIds[items.indexOf(item)];
417  }
418  // if there is no gui just take the first one for now
419  else {
420  i = 0;
421  }
422  } else
423  i = typeIds[0];
424 
425  if ( OpenFlipper::Options::gui() ) {
426  coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
427  if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
429  }
430 
431  //load file
432  QString jobId = QString("Loading_"+_filename);
433  QVector<LoadFromPluginThread::LoadInfos> infos;
434 
435  if ( checkSlot( supportedTypes()[i].object , "loadObject(QString,DataType)" ) )
436  infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _type,_filename));
437  else
438  infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _filename));
439 
440  LoadFromPluginThread* thread = new LoadFromPluginThread(infos, jobId);
441 
442  connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
443  connect(thread, SIGNAL(finished(QString)), this, SLOT(loadObjectFinished(QString)));
444 
445  if ( OpenFlipper::Options::gui() )
446  {
447  connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
448 
449  slotStartJob(jobId , QString("Loading %1").arg(_filename) , 0, 0, true);
450  thread->start();
451  thread->startProcessing();
452 
453 
454  while(thread->isRunning())
455  QApplication::processEvents();
456  // process last events
457  QApplication::processEvents();
458  }
459  else
460  {
461  thread->loadFromPlugin();
462  }
463 
464  int objId = thread->getObjId(0);
465 
466  return objId;
467 
468  } else {
469 
470  emit log(LOGERR, tr("Unable to load object. No suitable plugin found!") );
471 
472  return -1; //no plugin found
473  }
474 }
475 
476 
478  // Iterate over all plugins. The first plugin supporting the addEmpty function for the
479  // specified type will be used to create the new object. If adding the object failed,
480  // we iterate over the remaining plugins.
481 
482  // Iterate over type plugins
483  for (int i=0; i < (int)supportedDataTypes_.size(); i++)
484  if ( supportedDataTypes_[i].type & _type ) {
485  int retCode = supportedDataTypes_[i].plugin->addEmpty();
486  if ( retCode != -1 )
487  return retCode;
488  }
489 
490  return -1; // no plugin found
491 }
492 
493 //========================================================================================
494 // === Open/Add-Empty Slots ============================
495 //========================================================================================
496 
497 void Core::slotAddEmptyObject( DataType _type, int* _id)
498 {
499  slotAddEmptyObject(_type,*_id);
500 }
501 
502 void Core::slotAddEmptyObject( DataType _type , int& _id ) {
503 
504 
505  if (QThread::currentThread() != QApplication::instance()->thread())
506  {
507  //execute method in main thread
508  QMetaObject::invokeMethod(this,"slotAddEmptyObject",Qt::BlockingQueuedConnection, Q_ARG(DataType, _type), Q_ARG(int*, &_id));
509  }
510  else
511  {
512  _id = addEmptyObject( _type );
513  if ( OpenFlipper::Options::doSlotDebugging() ) {
514  if ( sender() != 0 ) {
515  if ( sender()->metaObject() != 0 ) {
516  emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + "," + QString::number(_id) + tr(" ) called by ") +
517  QString( sender()->metaObject()->className() ) );
518  }
519  } else {
520  emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + "," + QString::number(_id) + tr(" ) called by Core") );
521  }
522  }
523  }
524 }
525 
527 void Core::slotCopyObject( int _oldId , int& _newId ) {
528 
529  if ( _oldId == -1 ) {
530  emit log(LOGERR,tr("Requested copy for illegal Object id: %1").arg(_oldId) );
531  _newId = -1;
532  return;
533  }
534 
535  // get the node
536  BaseObject* object = objectRoot_->childExists(_oldId);
537 
538  if ( !object ) {
539  emit log(LOGERR,tr("Requested copy for unknown Object id: %1 ").arg(_oldId) );
540  _newId = -1;
541  return ;
542  }
543 
544  // Copy the item
545  BaseObject* copy = object->copy();
546 
547  if ( copy == 0 ) {
548  emit log(LOGERR,tr("Unable to create a copy of the object."));
549  return;
550  }
551 
552  // Integrate into object tree
553  copy->setParent( object->parent() );
554 
555  // return the new id
556  _newId = copy->id();
557 
558  // tell plugins that a new object has been created
559  slotEmptyObjectAdded(_newId);
560 
561  // tell plugins that the object has been updated
562  slotObjectUpdated(_newId);
563 
564 }
565 
566 
568 void Core::slotLoad(QStringList _filenames, IdList _pluginIDs) {
569 
570 
571  QString filemsg = "";
572  if (_filenames.size() > 1)
573  filemsg = QString( tr("Loading Files ...") );
574  else
575  filemsg = QString( tr("Loading %1 ...").arg(_filenames[0]) );
576 
577  if ( OpenFlipper::Options::gui() ) {
578  coreWidget_->statusMessage( filemsg );
579  if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
581  }
582 
583  //setup thread
584  QString jobId = QString("Loading File");
585  if (_filenames.size() > 1)
586  jobId += "s";
587 
588  QVector<LoadFromPluginThread::LoadInfos> loadInfos;
589  for (int i = 0; i < _filenames.size(); ++i)
590  loadInfos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[_pluginIDs[i]].plugin, _filenames[i]));
591  LoadFromPluginThread* thread = new LoadFromPluginThread(loadInfos, jobId);
592 
593  connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
594  connect(thread, SIGNAL(state(QString , int )), this, SLOT(slotSetJobState(QString , int)));
595 
596  if ( OpenFlipper::Options::gui() )
597  {
598  connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
599  //block log (decrease performance when loading multiple files)
600  coreWidget_->logWidget_->setUpdatesEnabled(false);
601 
602  // start thread
603  if (_filenames.size() > 1)
604  slotStartJob(jobId , QString(filemsg), 0, _filenames.size(), true);
605  else
606  slotStartJob(jobId , QString(filemsg), 0, 0, true);
607 
608  thread->start();
609  thread->startProcessing();
610 
611  //wait thread
612  while(thread->isRunning())
613  QApplication::processEvents();
614  //process last occuring events
615  QApplication::processEvents();
616 
617  //unblock and update log
618  coreWidget_->logWidget_->setUpdatesEnabled(true);
619  }
620  else
621  {
622  thread->loadFromPlugin();
623  }
624 
625  // Initialize as unknown type
626  QVector<DataType> type = QVector<DataType>(_filenames.size(), DATA_UNKNOWN);
627 
628  for (int i = 0; i < _filenames.size(); ++i)
629  {
630  int id = thread->getObjId(i);
631 
632  if ( OpenFlipper::Options::gui() ) {
633 
634  if ( id != -1 )
635  coreWidget_->statusMessage( tr("Loading %1 done").arg(_filenames[i]), 4000 );
636  else
637  coreWidget_->statusMessage( tr("Loading %1 failed").arg(_filenames[i]), 4000 );
638 
639  if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
641  }
642 
643  if ( id > 0 ) {
644 
645  BaseObjectData* object;
646  PluginFunctions::getObject(id,object);
647 
648  if ( !object ) {
649 
650  BaseObject* baseObj = 0;
651  GroupObject* group = 0;
652 
653  PluginFunctions::getObject(id,baseObj);
654 
655  if (baseObj){
656 
657  group = dynamic_cast< GroupObject* > (baseObj);
658 
659  if (group)
660  type[i] = DATA_GROUP;
661 
662  }
663 
664  if ( group == 0 ){
665  emit log(LOGERR,tr("Object id returned but no object with this id has been found! Error in one of the file plugins!"));
666  return;
667  }
668  }
669 
670  // Get the objects type
671  if (object)
672  type[i] = object->dataType();
673  }
674  }
675 
676  // If the id was greater than zero, add the file to the recent files.
677  if ( OpenFlipper::Options::gui() )
678  for (int i = 0; i < _filenames.size(); ++i)
679  if ( thread->getObjId(i) >= 0 )
680  coreWidget_->addRecent(_filenames[i], type[i]);
681 
682 }
683 
685 void Core::slotLoad(QString _filename, DataType _type, int& _id) {
686  _id = loadObject(_type,_filename);
687 
688  if ( _id < 0 )
689  _id = -1;
690  else
691  if ( OpenFlipper::Options::gui() )
692  coreWidget_->addRecent(_filename,_type);
693 }
694 
696 void Core::slotFileOpened ( int _id ) {
697 
698  if (QThread::currentThread() != QApplication::instance()->thread())
699  {
700  QMetaObject::invokeMethod(this,"slotFileOpened",Qt::QueuedConnection, Q_ARG(int, _id));
701  return;
702  }
703 
704  if ( OpenFlipper::Options::doSlotDebugging() ) {
705  if ( sender() != 0 ) {
706  if ( sender()->metaObject() != 0 ) {
707  emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by ") +
708  QString( sender()->metaObject()->className() ) );
709  }
710  } else {
711  emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by Core") );
712  }
713  }
714 
715  // get the opened object
716  BaseObjectData* object;
717  PluginFunctions::getObject(_id,object);
718 
719  // ================================================================================
720  // Recompute bounding box and scenegraph info
721  // Reset scene center here to include new object
722  // ================================================================================
723  resetScenegraph(true);
724 
725  // ================================================================================
726  // Tell plugins, that a file has been opened
727  // ================================================================================
728  emit openedFile( _id );
729 
730  // ================================================================================
731  // Print Info to logger
732  // ================================================================================
733  emit log( LOGINFO ,object->getObjectinfo() );
734 
735  // ================================================================================
736  // Tell plugins, that the Object is updated and the active object has changed
737  // ================================================================================
738  emit signalObjectUpdated(_id );
739  emit signalObjectUpdated(_id, UPDATE_ALL);
740 
741  // ================================================================================
742  // Create initial backup
743  // ================================================================================
744  emit createBackup(_id,"Original Object");
745 
746  // ================================================================================
747  // Add the file to the recent files menu
748  // ================================================================================
749  QString filename = object->path() + OpenFlipper::Options::dirSeparator() + object->name();
750  BaseObject* object2;
751  PluginFunctions::getObject(_id,object2);
752 
753  // ================================================================================
754  // show all files
755  // ================================================================================
757 
758  // objectRoot_->dumpTree();
759 }
760 
762 void Core::slotEmptyObjectAdded ( int _id ) {
763 
764  if ( OpenFlipper::Options::doSlotDebugging() ) {
765  if ( sender() != 0 ) {
766  if ( sender()->metaObject() != 0 ) {
767  emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by ") +
768  QString( sender()->metaObject()->className() ) );
769  }
770  } else {
771  emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by Core") );
772  }
773  }
774 
775  // get the opened object
776  BaseObjectData* object;
777  PluginFunctions::getObject(_id,object);
778 
779 
780  emit emptyObjectAdded( _id );
781 
782  // Tell the Plugins that the Object List and the active object have changed
783  emit signalObjectUpdated(_id);
785 
786  resetScenegraph(false);
787 
789 // QString filename = object->path() + OpenFlipper::Options::dirSeparator() + object->name();
790 
791 // addRecent(filename);
792 }
793 
794 //========================================================================================
795 // === Menu Slots ============================
796 //========================================================================================
797 
800  std::vector< DataType > types;
801  QStringList typeNames;
802 
803  DataType currentType = 2;
804 
805  // Iterate over all Types known to the core
806  // Start at 2:
807  // 0 type is defined as DATA_UNKNOWN
808  // 1 type is defined as DATA_GROUP
809  // Therefore we have two types less then reported
810  //
811  for ( uint i = 0 ; i < typeCount() - 2 ; ++i) {
812 
813  // Iterate over all supported types (created from plugins on load)
814  // Check if a plugin supports addEmpty for the current type.
815  // Only if the type is supported, add it to the addEmpty Dialog
816 
817  // typePlugin
818  for ( uint j = 0 ; j < supportedDataTypes_.size(); j++) {
819 
820  // Check if a plugin supports the current type
821  if ( supportedDataTypes_[j].type & currentType ) {
822  types.push_back(currentType);
823  typeNames.push_back( typeName( currentType ) );
824 
825  // Stop here as we need only one plugin supporting addEmpty for a given type
826  break;
827  }
828  }
829 
830  // filePlugin
831  for ( uint j = 0 ; j < supportedTypes().size(); j++) {
832 
833  // Check if a plugin supports the current Type
834  if ( supportedTypes()[j].type & currentType ) {
835 
836  // Avoid duplicates
837  bool duplicate = false;
838  for(std::vector< DataType >::iterator it = types.begin(); it != types.end(); ++it) {
839  if(*it == currentType) {
840  duplicate = true;
841  break;
842  }
843  }
844 
845  if(!duplicate) {
846  types.push_back(currentType);
847  typeNames.push_back( typeName( currentType ) );
848 
849  // Stop here as we need only one plugin supporting addEmpty for a given type
850  break;
851  }
852  }
853  }
854 
855  // Advance to next type ( Indices are bits so multiply by two to get next bit)
856  ++currentType;
857  }
858 
859 
860 
861  if (supportedTypes().size() != 0) {
862 
863  static addEmptyWidget* widget = 0;
864 
865  if ( !widget ){
866  widget = new addEmptyWidget(types,typeNames);
867  widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
868  connect(widget,SIGNAL(chosen(DataType, int&)),this,SLOT(slotAddEmptyObject(DataType, int&)));
869  }
870 
871  widget->show();
872 
873  } else
874  emit log(LOGERR,tr("Could not show 'add Empty' dialog. Missing file-plugins ?"));
875 
876 }
877 
878 //========================================================================================
879 // === Public Slots ============================
880 //========================================================================================
881 
884 
885  if ( OpenFlipper::Options::gui() ){
886 
887  if (supportedTypes().size() != 0){
888  LoadWidget* widget = new LoadWidget(supportedTypes());
889  connect(widget,SIGNAL(loadFiles(QStringList, IdList)),this,SLOT(slotLoad(QStringList, IdList)));
890  connect(widget,SIGNAL(save(int, QString, int)),this,SLOT(saveObject(int, QString, int)));
891 
892  widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
893 
894  widget->showLoad();
895 
896  widget->disconnect();
897  delete widget;
898 
899  }else
900  emit log(LOGERR,tr("Could not show 'load objects' dialog. Missing file-plugins."));
901 
902  }
903 }
904 
907 
908  if ( OpenFlipper::Options::gui() ){
909 
910  QString complete_name;
911 
912 
913  QFileDialog fileDialog( coreWidget_,
914  tr("Load Settings"),
915  OpenFlipperSettings().value("Core/CurrentDir").toString(),
916  tr("INI files (*.ini)") );
917 
918  fileDialog.setOption (QFileDialog::DontUseNativeDialog, true);
919  fileDialog.setAcceptMode ( QFileDialog::AcceptOpen );
920  fileDialog.setFileMode ( QFileDialog::AnyFile );
921 
922  QGridLayout *layout = (QGridLayout*)fileDialog.layout();
923 
924  QGroupBox* optionsBox = new QGroupBox( &fileDialog ) ;
925  optionsBox->setSizePolicy( QSizePolicy ( QSizePolicy::Expanding , QSizePolicy::Preferred ) );
926  optionsBox->setTitle(tr("Options"));
927  layout->addWidget( optionsBox, layout->rowCount() , 0 , 1,layout->columnCount() );
928 
929  QCheckBox *loadProgramSettings = new QCheckBox(optionsBox);
930  loadProgramSettings->setText(tr("Load program settings"));
931  loadProgramSettings->setToolTip(tr("Load all current program settings from the file ( This will include view settings, colors,...) "));
932  loadProgramSettings->setCheckState( Qt::Unchecked );
933 
934  QCheckBox *loadPluginSettings = new QCheckBox(optionsBox);
935  loadPluginSettings->setText(tr("Load per Plugin Settings"));
936  loadPluginSettings->setToolTip(tr("Plugins should load their current global settings from the file"));
937  loadPluginSettings->setCheckState( Qt::Checked );
938 
939  QCheckBox *loadObjectInfo = new QCheckBox(optionsBox);
940  loadObjectInfo->setText(tr("Load all objects defined in the file"));
941  loadObjectInfo->setToolTip(tr("Load all objects which are defined in the file"));
942  loadObjectInfo->setCheckState( Qt::Checked );
943 
944  QBoxLayout* frameLayout = new QBoxLayout(QBoxLayout::TopToBottom,optionsBox);
945 
946  #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
947  frameLayout->addWidget( loadProgramSettings , 0 , 0);
948  frameLayout->addWidget( loadPluginSettings , 1 , 0);
949  frameLayout->addWidget( loadObjectInfo , 2 , 0);
950  #else
951  frameLayout->addWidget( loadProgramSettings , 0 , Qt::Alignment() );
952  frameLayout->addWidget( loadPluginSettings , 1 , Qt::Alignment() );
953  frameLayout->addWidget( loadObjectInfo , 2 , Qt::Alignment() );
954  #endif
955  frameLayout->addStretch();
956 
957  fileDialog.resize(550 ,500);
958 
959  // ========================================================================================
960  // show the saveSettings-Dialog and get the target file
961  // ========================================================================================
962  QStringList fileNames;
963  if (fileDialog.exec()) {
964  fileNames = fileDialog.selectedFiles();
965  } else {
966  return;
967  }
968 
969  if ( fileNames.size() > 1 ) {
970  std::cerr << "Too many save filenames selected" << std::endl;
971  return;
972  }
973 
974  complete_name = fileNames[0];
975 
976 
977  QString newpath = complete_name.section(OpenFlipper::Options::dirSeparator(),0,-2);
978  OpenFlipperSettings().setValue("Core/CurrentDir", newpath);
979 
980  if ( complete_name.endsWith("ini",Qt::CaseInsensitive) ) {
981  openIniFile( complete_name,
982  loadProgramSettings->isChecked(),
983  loadPluginSettings->isChecked(),
984  loadObjectInfo->isChecked());
985  if ( loadProgramSettings->isChecked() )
986  applyOptions();
987  }
988 
989  coreWidget_->addRecent(complete_name, DATA_UNKNOWN);
990  }
991 }
992 
994 void Core::loadSettings(QString _filename){
995 
996  if ( !QFile(_filename).exists() )
997  return;
998 
999  QString newpath = _filename.section(OpenFlipper::Options::dirSeparator(),0,-2);
1000  OpenFlipperSettings().setValue("Core/CurrentDir", newpath);
1001 
1002  if ( _filename.endsWith("obj",Qt::CaseInsensitive) ) {
1003  loadObject(_filename);
1004  applyOptions();
1005  } else {
1006  // Loaded function for recent files. Load everything.
1007  openIniFile(_filename,true,true,true);
1008  applyOptions();
1009  }
1010 }
virtual QString getObjectinfo()
Get all Info for the Object as a string.
Definition: BaseObject.cc:244
void slotFileOpened(int _id)
Called when a file has been opened.
void slotEmptyObjectAdded(int _id)
Called when an empty object has been Added.
Status is ready (green light)
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 slotLoad(QString _filename, DataType _type, int &_id)
A plugin wants to load a given file.
void signalObjectUpdated(int)
When this Signal is emitted all Plugins are informed that the object list changed.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
int showLoad()
show Widget for loading Files
Definition: loadWidget.cc:370
std::vector< dataTypes > supportedDataTypes_
Type-Plugins.
Definition: Core.hh:1589
BaseObject * objectRoot_
Pointer to the data rootNode;.
Definition: Core.hh:1593
void openIniFile(QString _filename, bool _coreSettings, bool _perPluginSettings, bool _loadObjects)
Load information from an ini file.
Definition: ParseIni.cc:400
void createBackup(int _objectid, QString _name, UpdateType _type=UPDATE_ALL)
Tell backup-plugin to create a backup.
QString name() const
Return the name of this type as text.
Definition: Types.cc:411
void loadSettings()
Load status from file.
void emptyObjectAdded(int _id)
Tell the plugins that an empty object has been added.
void slotExecuteAfterStartup()
Executed after loading core completly to load files from commandline.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
void slotObjectUpdated(int _identifier, const UpdateType &_type=UPDATE_ALL)
Called by the plugins if they changed something in the object list (deleted, added, or other property changes)
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
LoggerWidget * logWidget_
Textedit at the bottom for log messages.
Definition: CoreWidget.hh:686
void executeFileScript(QString _filename)
Core scripting engine.
void commandLineOpen(const QString &_filename, bool _asPolyMesh)
Load an object from the commandline on application start.
const DataType DATA_GROUP(1)
Items used for Grouping.
void startProcessing()
start processing
Predefined datatypes.
Definition: DataTypes.hh:83
int addEmptyObject(DataType _type)
DLLEXPORT size_t typeCount()
Get the number of registered types.
Definition: Types.cc:175
void addRecent(QString _filename, DataType _type)
Add a recent file and update menu.
Definition: CoreWidget.cc:860
int id() const
Definition: BaseObject.cc:190
void log(Logtype _type, QString _message)
Logg with OUT,WARN or ERR as type.
void executePythonScriptFile(QString _filename)
Open the given file and execute its contents as a python script.
Definition: scripting.cc:417
void applyOptions()
after ini-files have been loaded and core is up or if options have been changed -> apply Options ...
BaseObject * childExists(int _objectId)
Check if the element exists in the subtree of this element.
Definition: BaseObject.cc:516
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:181
void loadObjectFinished(QString _filename)
Vector storing filenames from commandline to be opened after application startup (objects) ...
Struct containing all relevant information about a load operation.
CoreWidget * coreWidget_
The main applications widget ( only created in gui mode )
Definition: Core.hh:1596
BaseObject * parent()
Get the parent item ( 0 if rootitem )
Definition: BaseObject.cc:466
std::vector< std::pair< QString, bool > > commandLineFileNames_
Vector storing filenames from commandline to be opened after application startup (objects) ...
Definition: Core.hh:888
void slotCall(QString _pluginName, QString _functionName, bool &_success)
Definition: RPC.cc:94
void setParent(BaseObject *_parent)
Set the parent pointer.
Definition: BaseObject.cc:477
void slotCopyObject(int _oldId, int &_newId)
Slot copying an object.
void analyzeSceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int &_maxPasses, ACG::Vec3d &_bbmin, ACG::Vec3d &_bbmax)
Analyze the SceneGraph <ACG/Scenegraph/SceneGraphAnalysis.hh>
void exitApplication()
exit the current application
Definition: Core.cc:1058
void slotSetJobState(QString _jobId, int _value)
A job state has been updated by a plugin.
Definition: process.cc:141
void slotPluginExists(QString _pluginName, bool &_exists)
Check if a plugin exists.
Definition: RPC.cc:63
void slotGetAllFilters(QStringList &_list)
Called when a plugin requests a list of file-filters.
void slotAddEmptyObjectMenu()
Open the add Empty dialog.
void openedFile(int _id)
Tell the plugins that a file has been opened ( -> Database)
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.
Definition: Types.cc:154
std::vector< glViewer *> examiner_widgets_
Examiner Widget.
Definition: CoreWidget.hh:677
void commandLineScript(const QString &_filename)
Load a script from the commandline on application start.
void updateView()
Called when a plugin requests an update in the viewer.
Definition: Core.cc:945
void slotFinishJob(QString _jobId)
A job state has been finished by a plugin.
Definition: process.cc:238
void updateInSceneLoggerGeometry()
Set in-scene logger geometry right.
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 unLockUpdate()
Unlock display locked by updateLock().
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
bool checkSlot(QObject *_plugin, const char *_slotSignature)
Check if a plugin has a slot.
void loadObject()
Open Load Widget.
Status is processing but system will allow interaction (yellow light)
std::vector< QString > commandLineScriptNames_
Vector storing filenames from commandline to be opened after application startup (script files) ...
Definition: Core.hh:891
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
void resetScenegraph(bool _resetTrackBall)
bool saveObject(int _id, QString _filename)
Save an object.
virtual BaseObject * copy()
Returns a full copy of the object.
Definition: BaseObject.cc:769
const DataType DATA_UNKNOWN(0)
None of the other Objects.
DLLEXPORT DataType typeId(QString _name)
Given a dataType Identifier string this function will return the id of the datatype.
Definition: Types.cc:139
void viewAll(int _viewer)
View the whole scene.