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