Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 }
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
bool saveObject(int _id, QString _filename)
Save an object.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
void signalObjectUpdated(int)
When this Signal is emitted all Plugins are informed that the object list changed.
BaseObject * parent()
Get the parent item ( 0 if rootitem )
Definition: BaseObject.cc:477
void slotCopyObject(int _oldId, int &_newId)
Slot copying an object.
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 slotFileOpened(int _id)
Called when a file has been opened.
void slotAddEmptyObject(DataType _type, int &_id)
Slot adding empty object of a given type.
virtual QString getObjectinfo()
Get all Info for the Object as a string.
Definition: BaseObject.cc:255
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)
int addEmptyObject(DataType _type)
const DataType DATA_UNKNOWN(0)
None of the other Objects.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
bool getObject(int _identifier, BSplineCurveObject *&_object)
const DataType DATA_GROUP(1)
Items used for Grouping.
void commandLineOpen(const char *_filename, bool _asPolyMesh)
Load an object from the commandline on application start.
BaseObject * objectRoot_
Pointer to the data rootNode;.
Definition: Core.hh:1550
void slotExecuteAfterStartup()
Executed after loading core completly to load files from commandline.
void slotFinishJob(QString _jobId)
A job state has been finished by a plugin.
Definition: process.cc:244
DLLEXPORT size_t typeCount()
Get the number of registered types.
Definition: Types.cc:186
void slotAddEmptyObjectMenu()
Open the add Empty dialog.
LoggerWidget * logWidget_
Textedit at the bottom for log messages.
Definition: CoreWidget.hh:678
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.
Definition: Types.cc:165
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
void loadObject()
Open Load Widget.
int showLoad()
show Widget for loading Files
Definition: loadWidget.cc:372
void resetScenegraph(bool _resetTrackBall)
void slotGetAllFilters(QStringList &_list)
Called when a plugin requests a list of file-filters.
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:192
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 log(Logtype _type, QString _message)
Logg with OUT,WARN or ERR as type.
void setParent(BaseObject *_parent)
Set the parent pointer.
Definition: BaseObject.cc:488
BaseObject * childExists(int _objectId)
Check if the element exists in the subtree of this element.
Definition: BaseObject.cc:527
Status is processing but system will allow interaction (yellow light)
void openedFile(int _id)
Tell the plugins that a file has been opened ( -> Database)
void analyzeSceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int &_maxPasses, ACG::Vec3d &_bbmin, ACG::Vec3d &_bbmax)
Analyze the SceneGraph
#define DATA_POLY_MESH
Definition: PolyMesh.hh:65
std::vector< std::string > commandLineScriptNames_
Vector storing filenames from commandline to be opened after application startup (script files) ...
Definition: Core.hh:867
void addRecent(QString _filename, DataType _type)
Add a recent file and update menu.
Definition: CoreWidget.cc:893
void executeFileScript(QString _filename)
Core scripting engine.
void applyOptions()
after ini-files have been loaded and core is up or if options have been changed -> apply Options ...
void emptyObjectAdded(int _id)
Tell the plugins that an empty object has been added.
CoreWidget * coreWidget_
The main applications widget ( only created in gui mode )
Definition: Core.hh:1553
void commandLineScript(const char *_filename)
Load a script from the commandline on application start.
void loadObjectFinished(QString _filename)
Vector storing filenames from commandline to be opened after application startup (objects) ...
void exitApplication()
exit the current application
Definition: Core.cc:1000
void updateInSceneLoggerGeometry()
Set in-scene logger geometry right.
virtual BaseObject * copy()
Returns a full copy of the object.
Definition: BaseObject.cc:780
Status is ready (green light)
std::vector< dataTypes > supportedDataTypes_
Type-Plugins.
Definition: Core.hh:1546
Predefined datatypes.
Definition: DataTypes.hh:96
void unLockUpdate()
Unlock display locked by updateLock().
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void slotSetJobState(QString _jobId, int _value)
A job state has been updated by a plugin.
Definition: process.cc:147
void startProcessing()
start processing
void slotLoad(QString _filename, DataType _type, int &_id)
A plugin wants to load a given file.
bool checkSlot(QObject *_plugin, const char *_slotSignature)
Check if a plugin has a slot.
QString name() const
Return the name of this type as text.
Definition: Types.cc:427
void loadSettings()
Load status from file.
void updateView()
Called when a plugin requests an update in the viewer.
Definition: Core.cc:887
SeparatorNode * root_node_scenegraph_
Scenegraphs root node.
Definition: Core.hh:1049
void slotPluginExists(QString _pluginName, bool &_exists)
Check if a plugin exists.
Definition: RPC.cc:69
void viewAll(int _viewer)
View the whole scene.
void openIniFile(QString _filename, bool _coreSettings, bool _perPluginSettings, bool _loadObjects)
Load information from an ini file.
Definition: ParseIni.cc:406
void createBackup(int _objectid, QString _name, UpdateType _type=UPDATE_ALL)
Tell backup-plugin to create a backup.
void slotEmptyObjectAdded(int _id)
Called when an empty object has been Added.
int id() const
Definition: BaseObject.cc:201
std::vector< glViewer * > examiner_widgets_
Examiner Widget.
Definition: CoreWidget.hh:669
void slotCall(QString _pluginName, QString _functionName, bool &_success)
Definition: RPC.cc:100