openFunctions.cc 29.5 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper is free software: you can redistribute it and/or modify       *
*  it under the terms of the GNU Lesser General Public License as            *
*  published by the Free Software Foundation, either version 3 of            *
*  the License, or (at your option) any later version with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  OpenFlipper is distributed in the hope that it will be useful,            *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*  GNU Lesser General Public License for more details.                       *
*                                                                            *
*  You should have received a copy of the GNU LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
33
34
35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36
37
38
39
40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46
47
48
49





#include "Core.hh"

#include <ACG/QtWidgets/QtFileDialog.hh>
Jan Möbius's avatar
Jan Möbius committed
50
#include <ACG/Scenegraph/SceneGraphAnalysis.hh>
Jan Möbius's avatar
 
Jan Möbius committed
51
52

#include "OpenFlipper/common/GlobalOptions.hh"
53
#include <OpenFlipper/common/RecentFiles.hh>
Jan Möbius's avatar
 
Jan Möbius committed
54
55
56
57
58
#include "OpenFlipper/BasePlugin/PluginFunctions.hh"

#include "OpenFlipper/widgets/loadWidget/loadWidget.hh"
#include "OpenFlipper/widgets/addEmptyWidget/addEmptyWidget.hh"

59
60
61
#include <OpenFlipper/common/Types.hh>
#include <ObjectTypes/PolyMesh/PolyMesh.hh>

62
#include <OpenFlipper/common/DataTypes.hh>
63

64
void Core::resetScenegraph( bool _resetTrackBall  ) {
Jan Möbius's avatar
Jan Möbius committed
65

66
  if ( OpenFlipper::Options::gui() && !OpenFlipper::Options::loadingSettings() ) {
Jan Möbius's avatar
Jan Möbius committed
67

Jan Möbius's avatar
Jan Möbius committed
68
69
70
71
    unsigned int maxPases = 1;
    ACG::Vec3d bbmin,bbmax;
    ACG::SceneGraph::analyzeSceneGraph(PluginFunctions::getSceneGraphRootNode(),maxPases,bbmin,bbmax);

Jan Möbius's avatar
Jan Möbius committed
72
    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i ) {
73
      // update scene graph (get new bounding box and set projection right, including near and far plane)
74
      PluginFunctions::viewerProperties(i).lockUpdate();
Jan Möbius's avatar
Jan Möbius committed
75
      coreWidget_->examiner_widgets_[i]->sceneGraph(root_node_scenegraph_,maxPases,bbmin,bbmax, _resetTrackBall );
76
      PluginFunctions::viewerProperties(i).unLockUpdate();
Jan Möbius's avatar
Jan Möbius committed
77
78
79
      coreWidget_->examiner_widgets_[i]->updateGL();
    }

Jan Möbius's avatar
 
Jan Möbius committed
80
  }
81

Jan Möbius's avatar
Jan Möbius committed
82
  // Update the draw Modes Menu
Dirk Wilden's avatar
Dirk Wilden committed
83
84
  if ( OpenFlipper::Options::gui() )
    coreWidget_->slotUpdateGlobalDrawMenu();
Jan Möbius's avatar
 
Jan Möbius committed
85
86
87
88
89
90
91
92
}

//========================================================================================
// ===            Open/Add-Empty Functions                    ============================
//========================================================================================



93
void Core::slotGetAllFilters ( QStringList& _list){
94
  /// \todo check why the supported Type is used here!
Jan Möbius's avatar
Jan Möbius committed
95
  // Iterate over all types
96
97
  for (int i=0; i < (int)supportedTypes().size(); i++){
    QString f = supportedTypes()[i].plugin->getLoadFilters();
Jan Möbius's avatar
 
Jan Möbius committed
98
    f = f.section(")",0,0).section("(",1,1).trimmed();
99
    _list << f;
Jan Möbius's avatar
 
Jan Möbius committed
100
101
102
  }
}

103
void Core::commandLineOpen(const char* _filename, bool _asPolyMesh ){
104

Jan Möbius's avatar
Jan Möbius committed
105
  QString file(_filename);
106

107
  // Modify filename to contain full paths if they were given as relative paths
Jan Möbius's avatar
Jan Möbius committed
108
109
110
111
112
  if ( !file.startsWith("/") && !file.contains(":") ) {
    file = QDir::currentPath();
    file += OpenFlipper::Options::dirSeparator();
    file += _filename;
  }
113

Jan Möbius's avatar
Jan Möbius committed
114
  // Add to the open list
115
  commandLineFileNames_.push_back(std::pair< std::string , bool >(file.toStdString(), _asPolyMesh));
Jan Möbius's avatar
 
Jan Möbius committed
116
117
118
}

void Core::commandLineScript(const char* _filename ) {
119
120
121
122
123
124
125
126
127
128
129
130

  QString file(_filename);
  
  // Modify filename to contain full paths if they were given as relative paths
  if ( !file.startsWith("/") && !file.contains(":") ) {
    file = QDir::currentPath();
    file += OpenFlipper::Options::dirSeparator();
    file += _filename;
  }
  
  // Add to the open list
  commandLineScriptNames_.push_back(file.toStdString());
131
132
}

Jan Möbius's avatar
Jan Möbius committed
133
134
void Core::slotExecuteAfterStartup() {

Jan Möbius's avatar
Jan Möbius committed
135

136
  // Update logger
Jan Möbius's avatar
Jan Möbius committed
137
138
  if ( OpenFlipper::Options::gui())
    coreWidget_->updateInSceneLoggerGeometry();
139

Jan Möbius's avatar
Jan Möbius committed
140
141
142
143
  //check if we have scripting support:
  bool scriptingSupport = false;
  slotPluginExists("scripting",scriptingSupport);
  if ( ! scriptingSupport ) {
144
    emit log(LOGERR ,tr("No scripting support available, please check if we load a scripting plugin .. Skipping script execution on startup"));
Jan Möbius's avatar
Jan Möbius committed
145
146
  }

Jan Möbius's avatar
Jan Möbius committed
147
148
149
  // Collect all script files from the scripting subdirectory and execute them if possible.
  // You can use this directory to execute scipts that modify for example modify the ui at
  // every startup.
Jan Möbius's avatar
Jan Möbius committed
150
151
  if ( scriptingSupport ) {

Jan Möbius's avatar
Jan Möbius committed
152
    // Get the files in the directory
Jan Möbius's avatar
Jan Möbius committed
153
154
155
    QDir scriptDir = OpenFlipper::Options::scriptDir();
    QStringList scriptFiles = scriptDir.entryList(QDir::Files,QDir::Name);

Jan Möbius's avatar
Jan Möbius committed
156
    // Execute all files ending with ofs
Jan Möbius's avatar
Jan Möbius committed
157
    for ( int i = 0 ; i  < scriptFiles.size(); ++i )
158
      if ( scriptFiles[i].endsWith("ofs",Qt::CaseInsensitive) )
159
        emit executeFileScript(scriptDir.path() + "/" + scriptFiles[i]);
Jan Möbius's avatar
Jan Möbius committed
160

161
162
163
    // Clear scripting window afterexecuting the coresubdir scripts
    bool ok = false;
    slotCall( "scripting" ,"clearEditor()",ok);
Jan Möbius's avatar
Jan Möbius committed
164
165
  }

Jan Möbius's avatar
Jan Möbius committed
166
  // Open all files given at the commandline
167
  for ( uint i = 0 ; i < commandLineFileNames_.size() ; ++i ) {
168
169

    // Skip scripts here as they will be handled by a different function
170
    QString tmp = QString::fromStdString(commandLineFileNames_[i].first);
171
    if ( tmp.endsWith("ofs",Qt::CaseInsensitive) ) {
172
173
174
175
      commandLineScriptNames_.push_back(commandLineFileNames_[i].first);
      continue;
    }

Jan Möbius's avatar
Jan Möbius committed
176
    // If the file was given with the polymesh option, open them as polymeshes.
177
    if (commandLineFileNames_[i].second)
178
179
180
181
      loadObject(DATA_POLY_MESH, QString::fromStdString(commandLineFileNames_[i].first));
    else {
      loadObject(QString::fromStdString(commandLineFileNames_[i].first));
    }
Jan Möbius's avatar
 
Jan Möbius committed
182
183
  }

Jan Möbius's avatar
Jan Möbius committed
184
  // If we have scripting support, execute the scripts given at the commandline.
Jan Möbius's avatar
Jan Möbius committed
185
  if ( scriptingSupport )
186
    for ( uint i = 0 ; i < commandLineScriptNames_.size() ; ++i ) {
187
      emit executeFileScript(QString::fromStdString(commandLineScriptNames_[i]));
188
    }
189

Jan Möbius's avatar
Jan Möbius committed
190
191
  // If we don't have a gui and we are not under remote control,
  // exit the application as there would be no way to execute further commands
Dirk Wilden's avatar
Dirk Wilden committed
192
193
  if ( !OpenFlipper::Options::gui() && !OpenFlipper::Options::remoteControl())
    exitApplication();
Jan Möbius's avatar
 
Jan Möbius committed
194
195
}

196

Jan Möbius's avatar
Jan Möbius committed
197
198
199
200
201
202
203
int Core::loadObject ( QString _filename ) {
  /** \todo Check if this function is ok. It should check all plugins for the given files and do not depend
            on Triangle meshes only! 
            Rewrite function to get the plugin only and then open the file. So iterate over all plugins and find the
            matching ones. open it with this plugin.
  */
  
204
  if (_filename.endsWith(".ini",Qt::CaseInsensitive)) {
205
206

    // Load all information from the given ini file
207
    openIniFile(_filename,true,true,true);
208

Jan Möbius's avatar
 
Jan Möbius committed
209
    if ( OpenFlipper::Options::gui() )
210
      coreWidget_->addRecent(_filename, DATA_UNKNOWN);
211

Jan Möbius's avatar
 
Jan Möbius committed
212
    return -2;
213
  } else if (_filename.endsWith(".ofs",Qt::CaseInsensitive)) {
Jan Möbius's avatar
Jan Möbius committed
214
     emit log(LOGINFO ,tr("Starting script execution of %1.").arg( _filename)) ;
Jan Möbius's avatar
 
Jan Möbius committed
215
     emit executeFileScript(_filename);
Dirk Wilden's avatar
Dirk Wilden committed
216
217
218
  } else {
    
    QFileInfo fi(_filename);
219

220
    for (int i=0; i < (int)supportedTypes().size(); i++){
Dirk Wilden's avatar
Dirk Wilden committed
221

222
      QString filters = supportedTypes()[i].plugin->getLoadFilters();
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

      // Only take the parts inside the brackets
      filters = filters.section("(",1).section(")",0,0);

      // Split into blocks
      QStringList separateFilters = filters.split(" ");

      bool found = false;

      // for all filters associated with this plugin
      for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
        separateFilters[filterId] = separateFilters[filterId].trimmed();

        //check extension
        if ( separateFilters[filterId].endsWith( "*." + fi.completeSuffix() , Qt::CaseInsensitive) ) {
          found = true;
          break;
240
        }
241
242
243
244
245
246
247

        if (  separateFilters[filterId].endsWith( "*." + fi.suffix() , Qt::CaseInsensitive) ) {
          found = true;
          emit log(LOGWARN,"Found supported datatype but only the suffix is matched not the complete suffix!");
          break;
        }

Jan Möbius's avatar
Jan Möbius committed
248
      }
Dirk Wilden's avatar
Dirk Wilden committed
249

250
251
252
253
      // continue processing only if found
      if ( ! found )
        continue;

Dirk Wilden's avatar
Dirk Wilden committed
254
255
256
257
258
259
260
      if ( OpenFlipper::Options::gui() ) {
        coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
        if ( !OpenFlipper::Options::loadingSettings() )
          coreWidget_->setStatus(ApplicationStatus::PROCESSING );
      }

      //load file
261
      int id = supportedTypes()[i].plugin->loadObject(_filename);
Dirk Wilden's avatar
Dirk Wilden committed
262
263

      if ( OpenFlipper::Options::gui() ) {
264
        if ( id != -1 ) {
Dirk Wilden's avatar
Dirk Wilden committed
265
          coreWidget_->statusMessage( tr("Loading %1 ... done").arg(_filename), 4000 );
266
267
268
269
          
          // Get the object to figure out the data type
          BaseObject* object;
          PluginFunctions::getObject(id,object);
270
271
272
273
274
275
276
277
278
279

          // Security check, if object really exists         
          if ( object != 0 ) { 

            // Add to recent files with the given datatype
            if ( OpenFlipper::Options::gui() )
              coreWidget_->addRecent(_filename, object->dataType());
          } else {
            emit log(LOGERR, tr("Unable to add recent as object with id %1 could not be found!").arg(id) );
          }
280
281
          
        } else
Dirk Wilden's avatar
Dirk Wilden committed
282
283
284
285
286
287
288
289
290
291
292
          coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(_filename), 4000 );

        if ( !OpenFlipper::Options::loadingSettings() )
          coreWidget_->setStatus(ApplicationStatus::READY );
      }

      return id;
    }
  }

  emit log(LOGERR, tr("Unable to load object (type unknown). No suitable plugin found!") );
Jan Möbius's avatar
 
Jan Möbius committed
293
294
295
296
297
298

  return -1;
}

/// Function for loading a given file
int Core::loadObject( DataType _type, QString _filename) {
Jan Möbius's avatar
Jan Möbius committed
299
300
301
  /** \todo this function has to be checked. test for the plugin which can handle 
            the given file and then use it. 
  */
302
  
303
  if (_type == DATA_UNKNOWN)
Jan Möbius's avatar
 
Jan Möbius committed
304
305
    return loadObject(_filename);

Dirk Wilden's avatar
Dirk Wilden committed
306
307
  QFileInfo fi(_filename);
  
308
309
  for (int i=0; i < (int)supportedTypes().size(); i++)
    if (supportedTypes()[i].type & _type || supportedTypes()[i].type == _type) {
Jan Möbius's avatar
 
Jan Möbius committed
310

311
      QString filters = supportedTypes()[i].plugin->getLoadFilters();
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

      // Only take the parts inside the brackets
      filters = filters.section("(",1).section(")",0,0);

      // Split into blocks
      QStringList separateFilters = filters.split(" ");

      bool found = false;

      // for all filters associated with this plugin
      for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
        separateFilters[filterId] = separateFilters[filterId].trimmed();

        //check extension
        if ( separateFilters[filterId].endsWith( "*." + fi.completeSuffix() , Qt::CaseInsensitive) ) {
          found = true;
          break;
        }

        if (  separateFilters[filterId].endsWith( "*." + fi.suffix() , Qt::CaseInsensitive) ) {
          found = true;
          emit log(LOGWARN,"Found supported datatype but only the suffix is matched not the complete suffix!");
          break;
        }

      }

      // continue processing only if found
      if ( ! found )
Dirk Wilden's avatar
Dirk Wilden committed
341
342
        continue;
      
Jan Möbius's avatar
 
Jan Möbius committed
343
      if ( OpenFlipper::Options::gui() ) {
Jan Möbius's avatar
Jan Möbius committed
344
        coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
345
        if ( !OpenFlipper::Options::loadingSettings() )
Jan Möbius's avatar
 
Jan Möbius committed
346
347
348
          coreWidget_->setStatus(ApplicationStatus::PROCESSING );
      }

Dirk Wilden's avatar
Dirk Wilden committed
349
350
      int id = -1;

Jan Möbius's avatar
 
Jan Möbius committed
351
      //load file
352
353
      if ( checkSlot( supportedTypes()[i].object , "loadObject(QString,DataType)" ) )
        id = supportedTypes()[i].plugin->loadObject(_filename, _type);
Dirk Wilden's avatar
Dirk Wilden committed
354
      else
355
        id = supportedTypes()[i].plugin->loadObject(_filename);
Jan Möbius's avatar
 
Jan Möbius committed
356
357

      if ( OpenFlipper::Options::gui() ) {
358
        if ( id != -1 ) {
Jan Möbius's avatar
Jan Möbius committed
359
          coreWidget_->statusMessage( tr("Loading %1 ... done").arg(_filename), 4000 );
360
361
362
363
364
365
366
367
368
369
          
          // Get the object to figure out the data type
          BaseObject* object;
          PluginFunctions::getObject(id,object);
          
          // Add to recent files with the given datatype
          if ( OpenFlipper::Options::gui() )
            coreWidget_->addRecent(_filename, object->dataType());
          
        } else
Jan Möbius's avatar
Jan Möbius committed
370
          coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(_filename), 4000 );
Jan Möbius's avatar
 
Jan Möbius committed
371

372
        if ( !OpenFlipper::Options::loadingSettings() )
Jan Möbius's avatar
 
Jan Möbius committed
373
374
375
376
377
          coreWidget_->setStatus(ApplicationStatus::READY );
      }

      return id;
    }
Dirk Wilden's avatar
Dirk Wilden committed
378
379
380
    
  emit log(LOGERR, tr("Unable to load object. No suitable plugin found!") );
    
Jan Möbius's avatar
 
Jan Möbius committed
381
382
383
  return -1; //no plugin found
}

Jan Möbius's avatar
Jan Möbius committed
384

Jan Möbius's avatar
 
Jan Möbius committed
385
int Core::addEmptyObject( DataType _type ) {
386
  // Iterate over all plugins. The first plugin supporting the addEmpty function for the
387
388
  // specified type will be used to create the new object. If adding the object failed,
  // we iterate over the remaining plugins.
389
  
390
  // Iterate over type plugins
391
  for (int i=0; i < (int)supportedDataTypes_.size(); i++)
392
393
394
395
    if ( supportedDataTypes_[i].type & _type ) {
      int retCode = supportedDataTypes_[i].plugin->addEmpty();
      if ( retCode != -1 )
        return retCode;
Jan Möbius's avatar
Jan Möbius committed
396
    }
397
  
398
  return -1; // no plugin found
Jan Möbius's avatar
 
Jan Möbius committed
399
400
401
402
403
404
405
406
}

//========================================================================================
// ===             Open/Add-Empty Slots                       ============================
//========================================================================================

/// Slot for adding an empty object of given DataType
void Core::slotAddEmptyObject( DataType _type , int& _id ) {
407
408
409
  
  _id = addEmptyObject( _type );
  
Jan Möbius's avatar
Jan Möbius committed
410
411
412
  if ( OpenFlipper::Options::doSlotDebugging() ) {
    if ( sender() != 0 ) {
      if ( sender()->metaObject() != 0 ) {
413
        emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + "," + QString::number(_id) +  tr(" ) called by ") +
Jan Möbius's avatar
Jan Möbius committed
414
415
416
        QString( sender()->metaObject()->className() ) );
      }
    } else {
417
      emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + ","  + QString::number(_id) +  tr(" ) called by Core") );
Jan Möbius's avatar
Jan Möbius committed
418
419
    }
  }
Jan Möbius's avatar
 
Jan Möbius committed
420
421
}

422
/// Slot creating a copy of an existing object
Jan Möbius's avatar
Jan Möbius committed
423
void Core::slotCopyObject( int _oldId , int& _newId ) {
424

Jan Möbius's avatar
Jan Möbius committed
425
  if ( _oldId == -1 ) {
Jan Möbius's avatar
Jan Möbius committed
426
    emit log(LOGERR,tr("Requested copy for illegal Object id: %1").arg(_oldId) );
Jan Möbius's avatar
Jan Möbius committed
427
428
429
430
431
432
433
434
    _newId = -1;
    return;
  }

  // get the node
  BaseObject* object = objectRoot_->childExists(_oldId);

  if ( !object ) {
Jan Möbius's avatar
Jan Möbius committed
435
    emit log(LOGERR,tr("Requested copy for unknown Object id: %1 ").arg(_oldId) );
Jan Möbius's avatar
Jan Möbius committed
436
437
438
439
440
441
442
443
    _newId = -1;
    return ;
  }

  // Copy the item
  BaseObject* copy = object->copy();

  if ( copy == 0 ) {
444
    emit log(LOGERR,tr("Unable to create a copy of the object."));
Jan Möbius's avatar
Jan Möbius committed
445
446
447
448
449
450
    return;
  }

  // Integrate into object tree
  copy->setParent( object->parent() );

451
  // return the new id
Jan Möbius's avatar
Jan Möbius committed
452
  _newId = copy->id();
453

454
455
456
457
458
459
  // tell plugins that a new object has been created
  slotEmptyObjectAdded(_newId);

  // tell plugins that the object has been updated
  slotObjectUpdated(_newId);

460
461
}

Dirk Wilden's avatar
Dirk Wilden committed
462
463
464
465
466
467
468
469
470
471
/// Function for loading a given file
void Core::slotLoad(QString _filename, int _pluginID) {

  if ( OpenFlipper::Options::gui() ) {
    coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
    if ( !OpenFlipper::Options::loadingSettings() )
      coreWidget_->setStatus(ApplicationStatus::PROCESSING );
  }

  //load file
472
  int id = supportedTypes()[_pluginID].plugin->loadObject(_filename);
Dirk Wilden's avatar
Dirk Wilden committed
473
474
475
476
477
478
479
480
481
482
483

  if ( OpenFlipper::Options::gui() ) {
    if ( id != -1 )
      coreWidget_->statusMessage( tr("Loading %1 ... done").arg(_filename), 4000 );
    else
      coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(_filename), 4000 );

    if ( !OpenFlipper::Options::loadingSettings() )
      coreWidget_->setStatus(ApplicationStatus::READY );
  }
  
484
485
486
487
488
  // Initialize as unknown type
  DataType type = DATA_UNKNOWN;

  // An object has been added. Get it and do some processing!
  if ( id > 0 ) {
489

490
491
    BaseObjectData* object;
    PluginFunctions::getObject(id,object);
Dirk Wilden's avatar
Dirk Wilden committed
492
    
493
    if ( !object ) {
Dirk Wilden's avatar
Dirk Wilden committed
494
495
496
497
498
499
500
501
502
503
504

      BaseObject* baseObj = 0;
      GroupObject* group = 0;
      
      PluginFunctions::getObject(id,baseObj);
      
      if (baseObj){

        group = dynamic_cast< GroupObject* > (baseObj);

        if (group)
505
          type = DATA_GROUP;
Dirk Wilden's avatar
Dirk Wilden committed
506
507
508
509
510
511
      }
      
      if ( group == 0 ){
        emit log(LOGERR,tr("Object id returned but no object with this id has been found! Error in one of the file plugins!"));
        return;
      }
512
513
514
    }
    
    // Get the objects type
Dirk Wilden's avatar
Dirk Wilden committed
515
516
    if (object)
      type = object->dataType();
Dirk Wilden's avatar
Dirk Wilden committed
517
  }
518
519
  
  // If the id was greater than zero, add the file to the recent files.
Dirk Wilden's avatar
Dirk Wilden committed
520
521
522
523
524
  if ( id >= 0 )
    if ( OpenFlipper::Options::gui() )
      coreWidget_->addRecent(_filename, type);
}

Jan Möbius's avatar
 
Jan Möbius committed
525
526
527
/// Slot for loading a given file
void Core::slotLoad(QString _filename, DataType _type, int& _id) {
  _id = loadObject(_type,_filename);
528

Jan Möbius's avatar
 
Jan Möbius committed
529
530
531
  if ( _id < 0 )
    _id = -1;
  else
532
    if ( OpenFlipper::Options::gui() )
Jan Möbius's avatar
 
Jan Möbius committed
533
534
535
536
      coreWidget_->addRecent(_filename,_type);
}

/// Slot gets called after a file-plugin has opened an object
537
void Core::slotFileOpened ( int _id ) {
538
539
540
  if ( OpenFlipper::Options::doSlotDebugging() ) {
    if ( sender() != 0 ) {
      if ( sender()->metaObject() != 0 ) {
541
        emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by ") +
542
543
544
                  QString( sender()->metaObject()->className() ) );
      }
    } else {
545
      emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by Core") );
546
547
    }
  }
548
549

  // get the opened object
550
551
  BaseObjectData* object;
  PluginFunctions::getObject(_id,object);
552

Jan Möbius's avatar
Jan Möbius committed
553
554
  // ================================================================================
  // Recompute bounding box and scenegraph info
555
  // Reset scene center here to include new object
Jan Möbius's avatar
Jan Möbius committed
556
  // ================================================================================
557
  resetScenegraph(true);
Jan Möbius's avatar
 
Jan Möbius committed
558

Jan Möbius's avatar
Jan Möbius committed
559
560
561
  // ================================================================================
  // Tell plugins, that a file has been opened
  // ================================================================================
562
  emit openedFile( _id );
563
564
565
566
567
  
  // ================================================================================
  // Print Info to logger
  // ================================================================================
  emit log( LOGINFO ,object->getObjectinfo() );
Jan Möbius's avatar
 
Jan Möbius committed
568

Jan Möbius's avatar
Jan Möbius committed
569
570
571
  // ================================================================================
  // Tell plugins, that the Object is updated and the active object has changed
  // ================================================================================
Jan Möbius's avatar
Jan Möbius committed
572
573
  emit signalObjectUpdated(_id );
  emit signalObjectUpdated(_id, UPDATE_ALL);
Jan Möbius's avatar
 
Jan Möbius committed
574

Jan Möbius's avatar
Jan Möbius committed
575
576
577
  // ================================================================================
  // Create initial backup
  // ================================================================================
578
  emit createBackup(_id,"Original Object");
Jan Möbius's avatar
 
Jan Möbius committed
579

580
581
582
  // ================================================================================
  // Add the file to the recent files menu
  // ================================================================================
583
584
585
  QString filename = object->path() + OpenFlipper::Options::dirSeparator() + object->name();
  BaseObject* object2;
  PluginFunctions::getObject(_id,object2);
Jan Möbius's avatar
 
Jan Möbius committed
586

Jan Möbius's avatar
Jan Möbius committed
587
588
589
  // ================================================================================
  // if this is the first object opend, reset the global view
  // ================================================================================
590
  if ( PluginFunctions::objectCount() == 1 && OpenFlipper::Options::gui() && !OpenFlipper::Options::loadingSettings() )
591
592
593
    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i ) {
      coreWidget_->examiner_widgets_[i]->viewAll();
    }
594

Jan Möbius's avatar
 
Jan Möbius committed
595
  // objectRoot_->dumpTree();
596
}
Jan Möbius's avatar
 
Jan Möbius committed
597
598

 /// Slot gets called after a file-plugin has opened an object
599
void Core::slotEmptyObjectAdded ( int _id ) {
600

601
602
603
  if ( OpenFlipper::Options::doSlotDebugging() ) {
    if ( sender() != 0 ) {
      if ( sender()->metaObject() != 0 ) {
604
        emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by ") +
605
606
607
                  QString( sender()->metaObject()->className() ) );
      }
    } else {
608
      emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by Core") );
609
610
611
    }
  }

612
613
614
615
  // get the opened object
  BaseObjectData* object;
  PluginFunctions::getObject(_id,object);

616
  
617
  emit emptyObjectAdded( _id );
618

Jan Möbius's avatar
 
Jan Möbius committed
619
  // Tell the Plugins that the Object List and the active object have changed
620
  emit signalObjectUpdated(_id);
Jan Möbius's avatar
Jan Möbius committed
621
  emit signalObjectUpdated(_id,UPDATE_ALL);
Jan Möbius's avatar
 
Jan Möbius committed
622

623
624
  resetScenegraph(false);

625
  ///@todo : set a default path for new objects
Jan Möbius's avatar
 
Jan Möbius committed
626
627
628
//    QString filename = object->path() + OpenFlipper::Options::dirSeparator() + object->name();

//    addRecent(filename);
629
}
Jan Möbius's avatar
 
Jan Möbius committed
630
631
632
633
634
635
636

//========================================================================================
// ===             Menu Slots                                 ============================
//========================================================================================

/// Opens AddEmpty-Object widget
void Core::slotAddEmptyObjectMenu() {
637
638
639
640
641
642
643
644
645
646
647
648
649
  std::vector< DataType > types;
  QStringList             typeNames;
  
  DataType currentType = 2;
  
  // Iterate over all Types known to the core
  // Start at 2:
  // 0 type is defined as DATA_UNKNOWN
  // 1 type is defined as DATA_GROUP
  // Therefore we have two types less then reported
  // 
  for ( uint i = 0 ; i < typeCount() - 2  ; ++i) {
    
650
    // Iterate over all supported types (created from plugins on load)
651
652
    // Check if a plugin supports addEmpty for the current type.
    // Only if the type is supported, add it to the addEmpty Dialog
653
654
655
    
    // typePlugin
    for ( uint j = 0 ; j < supportedDataTypes_.size(); j++) {
656
      
657
658
      // Check if a plugin supports the current type
      if ( supportedDataTypes_[j].type & currentType ) {
659
660
661
662
663
        types.push_back(currentType);
        typeNames.push_back( typeName( currentType ) );
        
        // Stop here as we need only one plugin supporting addEmpty for a given type
        break;
Jan Möbius's avatar
   
Jan Möbius committed
664
      }
665
666
    }
    
667
    // filePlugin
668
    for ( uint j = 0 ; j < supportedTypes().size(); j++) {
669
670
      
      // Check if a plugin supports the current Type
671
      if ( supportedTypes()[j].type & currentType ) {
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
	
	// Avoid duplicates
	bool duplicate = false;
	for(std::vector< DataType >::iterator it = types.begin(); it != types.end(); ++it) {
	  if(*it == currentType) {
	    duplicate = true;
	    break;
	  }
	}
	  
	if(!duplicate) {
	  types.push_back(currentType);
	  typeNames.push_back( typeName( currentType ) );
        
	  // Stop here as we need only one plugin supporting addEmpty for a given type
	  break;
	}
      }
    }
    
692
693
    // Advance to next type ( Indices are bits so multiply by two to get next bit)
    ++currentType;
694
695
696
697
  }
  
  static addEmptyWidget* widget = 0;
  
698
  if (supportedTypes().size() != 0) {
699
700
    
    if ( !widget ){
Jan Möbius's avatar
 
Jan Möbius committed
701
      widget = new addEmptyWidget(types,typeNames);
702
      widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
Jan Möbius's avatar
 
Jan Möbius committed
703
704
      connect(widget,SIGNAL(chosen(DataType, int&)),this,SLOT(slotAddEmptyObject(DataType, int&)));
    }
705
    
Jan Möbius's avatar
 
Jan Möbius committed
706
    widget->show();
707
708
709
710
    
  } else
    emit log(LOGERR,tr("Could not show 'add Empty' dialog. Missing file-plugins ?"));
  
Jan Möbius's avatar
 
Jan Möbius committed
711
712
}

713
714
715
716
//========================================================================================
// ===             Public Slots                                 ============================
//========================================================================================

Jan Möbius's avatar
 
Jan Möbius committed
717
/// Open Load-Object Widget
718
719
720
721
void Core::loadObject() {

  if ( OpenFlipper::Options::gui() ){

722
723
    if (supportedTypes().size() != 0){
      LoadWidget* widget = new LoadWidget(supportedTypes());
Dirk Wilden's avatar
Dirk Wilden committed
724
725
      connect(widget,SIGNAL(load(QString, int)),this,SLOT(slotLoad(QString, int)));
      connect(widget,SIGNAL(save(int, QString, int)),this,SLOT(saveObject(int, QString, int)));
Jan Möbius's avatar
Jan Möbius committed
726

727
728
      widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );

729
      widget->showLoad();
730
731
732
733

      widget->disconnect();
      delete widget;

734
    }else
735
      emit log(LOGERR,tr("Could not show 'load objects' dialog. Missing file-plugins."));
Jan Möbius's avatar
 
Jan Möbius committed
736

737
  }
Jan Möbius's avatar
 
Jan Möbius committed
738
739
}

740
741
742
743
744
745
/// Load settings from file
void Core::loadSettings(){

  if ( OpenFlipper::Options::gui() ){

    QString complete_name;
Jan Möbius's avatar
Jan Möbius committed
746

747
748
749

    QFileDialog fileDialog( coreWidget_,
                            tr("Load Settings"),
750
                            OpenFlipperSettings().value("Core/CurrentDir").toString(),
751
                            tr("INI files (*.ini)") );
752

753
    fileDialog.setOption (QFileDialog::DontUseNativeDialog, true);
754
755
756
757
758
759
760
    fileDialog.setAcceptMode ( QFileDialog::AcceptOpen );
    fileDialog.setFileMode ( QFileDialog::AnyFile );

    QGridLayout *layout = (QGridLayout*)fileDialog.layout();

    QGroupBox* optionsBox = new QGroupBox( &fileDialog ) ;
    optionsBox->setSizePolicy( QSizePolicy ( QSizePolicy::Expanding , QSizePolicy::Preferred ) );
761
    optionsBox->setTitle(tr("Options"));
762
763
764
    layout->addWidget( optionsBox, layout->rowCount() , 0 , 1,layout->columnCount() );

    QCheckBox *loadProgramSettings = new QCheckBox(optionsBox);
765
766
    loadProgramSettings->setText(tr("Load program settings"));
    loadProgramSettings->setToolTip(tr("Load all current program settings from the file ( This will include view settings, colors,...) "));
767
768
769
    loadProgramSettings->setCheckState( Qt::Unchecked );

    QCheckBox *loadPluginSettings = new QCheckBox(optionsBox);
770
771
    loadPluginSettings->setText(tr("Load per Plugin Settings"));
    loadPluginSettings->setToolTip(tr("Plugins should load their current global settings from the file"));
772
773
774
    loadPluginSettings->setCheckState( Qt::Checked );

    QCheckBox *loadObjectInfo = new QCheckBox(optionsBox);
775
776
    loadObjectInfo->setText(tr("Load all objects defined in the file"));
    loadObjectInfo->setToolTip(tr("Load all objects which are defined in the file"));
777
778
779
780
781
782
783
784
    loadObjectInfo->setCheckState( Qt::Checked );

    QBoxLayout* frameLayout = new QBoxLayout(QBoxLayout::TopToBottom,optionsBox);
    frameLayout->addWidget( loadProgramSettings , 0 , 0);
    frameLayout->addWidget( loadPluginSettings  , 1 , 0);
    frameLayout->addWidget( loadObjectInfo      , 2 , 0);
    frameLayout->addStretch();

Jan Möbius's avatar
Jan Möbius committed
785
786
    fileDialog.resize(550 ,500);

787
788
789
790
791
792
793
794
795
796
797
798
    // ========================================================================================
    // show the saveSettings-Dialog and get the target file
    // ========================================================================================
    QStringList fileNames;
    if (fileDialog.exec()) {
      fileNames = fileDialog.selectedFiles();
    } else {
      return;
    }

    if ( fileNames.size() > 1 ) {
      std::cerr << "Too many save filenames selected" << std::endl;
799
      return;
800
801
802
803
    }

    complete_name = fileNames[0];

Jan Möbius's avatar
Jan Möbius committed
804

805
    QString newpath = complete_name.section(OpenFlipper::Options::dirSeparator(),0,-2);
806
    OpenFlipperSettings().setValue("Core/CurrentDir", newpath);
Jan Möbius's avatar
Jan Möbius committed
807

808
    if ( complete_name.endsWith("ini",Qt::CaseInsensitive) ) {
809
810
811
812
      openIniFile( complete_name,
                   loadProgramSettings->isChecked(),
                   loadPluginSettings->isChecked(),
                   loadObjectInfo->isChecked());
813
814
      if ( loadProgramSettings->isChecked() )
        applyOptions();
815
816
    } 
    
817
    coreWidget_->addRecent(complete_name, DATA_UNKNOWN);
818
819
  }
}
Jan Möbius's avatar
 
Jan Möbius committed
820

821
822
/// Load settings from file
void Core::loadSettings(QString _filename){
Jan Möbius's avatar
Jan Möbius committed
823

824
  if ( !QFile(_filename).exists() )
Jan Möbius's avatar
 
Jan Möbius committed
825
826
    return;

827
  QString newpath = _filename.section(OpenFlipper::Options::dirSeparator(),0,-2);
828
  OpenFlipperSettings().setValue("Core/CurrentDir", newpath);
Jan Möbius's avatar
 
Jan Möbius committed
829

830
  if ( _filename.endsWith("ini",Qt::CaseInsensitive) ) {
831
    // Loaded function for recent files. Load everything.
832
    openIniFile(_filename,true,true,true);
Jan Möbius's avatar
 
Jan Möbius committed
833
    applyOptions();
834
  } else if ( _filename.endsWith("obj",Qt::CaseInsensitive) ) {
Dirk Wilden's avatar
Dirk Wilden committed
835
    loadObject(_filename);
Jan Möbius's avatar
 
Jan Möbius committed
836
837
838
839
    applyOptions();
  }

}