openFunctions.cc 28.3 KB
Newer Older
1
2
3
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
Jan Möbius's avatar
Jan Möbius committed
4
 *      Copyright (C) 2001-2010 by Computer Graphics Group, RWTH Aachen      *
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
33
34
35
36
37
38
39
40
41
 *                           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/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision$                                                         *
 *   $Author$                                                      *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46
47
48
49
50
51





#include "Core.hh"

#include <ACG/QtWidgets/QtFileDialog.hh>

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

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

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

61
62
#include <time.h>

63
void Core::resetScenegraph( bool _resetTrackBall  ) {
64
  if ( OpenFlipper::Options::gui() && !OpenFlipper::Options::loadingSettings() ) {
Jan Möbius's avatar
Jan Möbius committed
65
66

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

Jan Möbius's avatar
 
Jan Möbius committed
74
  }
75

Jan Möbius's avatar
Jan Möbius committed
76
  // Update the draw Modes Menu
Dirk Wilden's avatar
Dirk Wilden committed
77
78
  if ( OpenFlipper::Options::gui() )
    coreWidget_->slotUpdateGlobalDrawMenu();
Jan Möbius's avatar
 
Jan Möbius committed
79
80
81
82
83
84
85
86
87
}

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


void Core::slotGetAllFilters ( QStringList& _list){

88
  /// \todo check why the supported Type is used here!
Jan Möbius's avatar
Jan Möbius committed
89
  // Iterate over all types
Jan Möbius's avatar
 
Jan Möbius committed
90
91
92
  for (int i=0; i < (int)supportedTypes_.size(); i++){
    QString f = supportedTypes_[i].plugin->getLoadFilters();
    f = f.section(")",0,0).section("(",1,1).trimmed();
93
    _list << (QString::number(supportedTypes_[i].plugin->supportedType().value()) + " " + f);
Jan Möbius's avatar
 
Jan Möbius committed
94
95
96
  }
}

97
void Core::commandLineOpen(const char* _filename, bool _asPolyMesh ){
98

Jan Möbius's avatar
Jan Möbius committed
99
  QString file(_filename);
100

101
  // Modify filename to contain full paths if they were given as relative paths
Jan Möbius's avatar
Jan Möbius committed
102
103
104
105
106
  if ( !file.startsWith("/") && !file.contains(":") ) {
    file = QDir::currentPath();
    file += OpenFlipper::Options::dirSeparator();
    file += _filename;
  }
107

Jan Möbius's avatar
Jan Möbius committed
108
  // Add to the open list
109
  commandLineFileNames_.push_back(std::pair< std::string , bool >(file.toStdString(), _asPolyMesh));
Jan Möbius's avatar
 
Jan Möbius committed
110
111
112
}

void Core::commandLineScript(const char* _filename ) {
113
114
115
116
117
118
119
120
121
122
123
124

  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());
125
126
}

Jan Möbius's avatar
Jan Möbius committed
127
128
129
130
131
132
void Core::slotExecuteAfterStartup() {

  //check if we have scripting support:
  bool scriptingSupport = false;
  slotPluginExists("scripting",scriptingSupport);
  if ( ! scriptingSupport ) {
133
    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
134
135
  }

Jan Möbius's avatar
Jan Möbius committed
136
137
138
  // 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
139
140
  if ( scriptingSupport ) {

Jan Möbius's avatar
Jan Möbius committed
141
    // Get the files in the directory
Jan Möbius's avatar
Jan Möbius committed
142
143
144
    QDir scriptDir = OpenFlipper::Options::scriptDir();
    QStringList scriptFiles = scriptDir.entryList(QDir::Files,QDir::Name);

Jan Möbius's avatar
Jan Möbius committed
145
    // Execute all files ending with ofs
Jan Möbius's avatar
Jan Möbius committed
146
    for ( int i = 0 ; i  < scriptFiles.size(); ++i )
147
      if ( scriptFiles[i].endsWith("ofs",Qt::CaseInsensitive) )
148
        emit executeFileScript(scriptDir.path() + "/" + scriptFiles[i]);
Jan Möbius's avatar
Jan Möbius committed
149
150
151

  }

Jan Möbius's avatar
Jan Möbius committed
152
  // Open all files given at the commandline
153
  for ( uint i = 0 ; i < commandLineFileNames_.size() ; ++i ) {
154
155

    // Skip scripts here as they will be handled by a different function
156
    QString tmp = QString::fromStdString(commandLineFileNames_[i].first);
157
    if ( tmp.endsWith("ofs",Qt::CaseInsensitive) ) {
158
159
160
161
      commandLineScriptNames_.push_back(commandLineFileNames_[i].first);
      continue;
    }

Jan Möbius's avatar
Jan Möbius committed
162
    // If the file was given with the polymesh option, open them as polymeshes.
163
    if (commandLineFileNames_[i].second)
164
165
166
167
      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
168
169
  }

Jan Möbius's avatar
Jan Möbius committed
170
  // If we have scripting support, execute the scripts given at the commandline.
Jan Möbius's avatar
Jan Möbius committed
171
  if ( scriptingSupport )
172
    for ( uint i = 0 ; i < commandLineScriptNames_.size() ; ++i ) {
173
      emit executeFileScript(QString::fromStdString(commandLineScriptNames_[i]));
174
    }
175

Jan Möbius's avatar
Jan Möbius committed
176
177
  // 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
178
179
  if ( !OpenFlipper::Options::gui() && !OpenFlipper::Options::remoteControl())
    exitApplication();
Jan Möbius's avatar
 
Jan Möbius committed
180
181
}

182

Jan Möbius's avatar
Jan Möbius committed
183
184
185
186
187
188
189
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.
  */
  
190
  if (_filename.endsWith(".ini",Qt::CaseInsensitive)) {
191
192

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

Jan Möbius's avatar
 
Jan Möbius committed
195
    if ( OpenFlipper::Options::gui() )
196
      coreWidget_->addRecent(_filename, DATA_UNKNOWN);
197

Jan Möbius's avatar
 
Jan Möbius committed
198
    return -2;
199
  } else if (_filename.endsWith(".ofs",Qt::CaseInsensitive)) {
Jan Möbius's avatar
Jan Möbius committed
200
     emit log(LOGINFO ,tr("Starting script execution of %1.").arg( _filename)) ;
Jan Möbius's avatar
 
Jan Möbius committed
201
     emit executeFileScript(_filename);
Dirk Wilden's avatar
Dirk Wilden committed
202
203
204
205
206
207
208
209
  } else {
    
    QFileInfo fi(_filename);
    
    for (int i=0; i < (int)supportedTypes_.size(); i++){

      QString filters = supportedTypes_[i].plugin->getLoadFilters();
      //check extension
210
      if ( ! filters.contains( "*." + fi.completeSuffix() , Qt::CaseInsensitive) )
Dirk Wilden's avatar
Dirk Wilden committed
211
212
213
214
215
216
217
218
219
220
221
222
        continue;

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

      //load file
      int id = supportedTypes_[i].plugin->loadObject(_filename);

      if ( OpenFlipper::Options::gui() ) {
223
        if ( id != -1 ) {
Dirk Wilden's avatar
Dirk Wilden committed
224
          coreWidget_->statusMessage( tr("Loading %1 ... done").arg(_filename), 4000 );
225
226
227
228
229
230
231
232
233
234
          
          // 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
Dirk Wilden's avatar
Dirk Wilden committed
235
236
237
238
239
240
241
242
243
244
245
          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
246
247
248
249
250
251

  return -1;
}

/// Function for loading a given file
int Core::loadObject( DataType _type, QString _filename) {
Jan Möbius's avatar
Jan Möbius committed
252
253
254
  /** \todo this function has to be checked. test for the plugin which can handle 
            the given file and then use it. 
  */
Jan Möbius's avatar
 
Jan Möbius committed
255

256
  if (_type == DATA_UNKNOWN)
Jan Möbius's avatar
 
Jan Möbius committed
257
258
    return loadObject(_filename);

Dirk Wilden's avatar
Dirk Wilden committed
259
260
  QFileInfo fi(_filename);
  
Jan Möbius's avatar
 
Jan Möbius committed
261
  for (int i=0; i < (int)supportedTypes_.size(); i++)
Dirk Wilden's avatar
Dirk Wilden committed
262
    if (supportedTypes_[i].type & _type || supportedTypes_[i].type == _type) {
Jan Möbius's avatar
 
Jan Möbius committed
263

Dirk Wilden's avatar
Dirk Wilden committed
264
265
      QString filters = supportedTypes_[i].plugin->getLoadFilters();
      //check extension
266
      if ( ! filters.contains( "*." + fi.suffix() ,Qt::CaseInsensitive ) )
Dirk Wilden's avatar
Dirk Wilden committed
267
268
269
        continue;
        
      
Jan Möbius's avatar
 
Jan Möbius committed
270
      if ( OpenFlipper::Options::gui() ) {
Jan Möbius's avatar
Jan Möbius committed
271
        coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
272
        if ( !OpenFlipper::Options::loadingSettings() )
Jan Möbius's avatar
 
Jan Möbius committed
273
274
275
          coreWidget_->setStatus(ApplicationStatus::PROCESSING );
      }

Dirk Wilden's avatar
Dirk Wilden committed
276
277
      int id = -1;

Jan Möbius's avatar
 
Jan Möbius committed
278
      //load file
Dirk Wilden's avatar
Dirk Wilden committed
279
280
281
282
      if ( checkSlot( supportedTypes_[i].object , "loadObject(QString,DataType)" ) )
        id = supportedTypes_[i].plugin->loadObject(_filename, _type);
      else
        id = supportedTypes_[i].plugin->loadObject(_filename);
Jan Möbius's avatar
 
Jan Möbius committed
283
284

      if ( OpenFlipper::Options::gui() ) {
285
        if ( id != -1 ) {
Jan Möbius's avatar
Jan Möbius committed
286
          coreWidget_->statusMessage( tr("Loading %1 ... done").arg(_filename), 4000 );
287
288
289
290
291
292
293
294
295
296
          
          // 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
297
          coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(_filename), 4000 );
Jan Möbius's avatar
 
Jan Möbius committed
298

299
        if ( !OpenFlipper::Options::loadingSettings() )
Jan Möbius's avatar
 
Jan Möbius committed
300
301
302
303
304
          coreWidget_->setStatus(ApplicationStatus::READY );
      }

      return id;
    }
Dirk Wilden's avatar
Dirk Wilden committed
305
306
307
    
  emit log(LOGERR, tr("Unable to load object. No suitable plugin found!") );
    
Jan Möbius's avatar
 
Jan Möbius committed
308
309
310
  return -1; //no plugin found
}

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

Jan Möbius's avatar
 
Jan Möbius committed
312
int Core::addEmptyObject( DataType _type ) {
313
314
  // Iterate over all plugins. The first plugin supporting the addEmpty function for the
  // specified type will be used to create the new object.
315
316
317
318
319
320
321
322
323
324
325
  
  int retCode = -1;
  
  // Type plugins
  for (int i=0; i < (int)supportedDataTypes_.size(); i++)
    if ( supportedDataTypes_[i].type & _type )
      retCode = supportedDataTypes_[i].plugin->addEmpty();
  
  if(retCode != -1) return retCode;
    
  // File plugins
Jan Möbius's avatar
 
Jan Möbius committed
326
  for (int i=0; i < (int)supportedTypes_.size(); i++)
Jan Möbius's avatar
Jan Möbius committed
327
    if ( supportedTypes_[i].type & _type ) {
328
      emit log(LOGERR, tr("File Plugins are not allowed to create empty objects anymore! Use the addEmpty call instead!") );
329
      retCode = supportedTypes_[i].plugin->addEmpty();
Jan Möbius's avatar
Jan Möbius committed
330
    }
331
332
  
  return retCode; // -1 if no plugin found
Jan Möbius's avatar
 
Jan Möbius committed
333
334
335
336
337
338
339
340
}

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

/// Slot for adding an empty object of given DataType
void Core::slotAddEmptyObject( DataType _type , int& _id ) {
341
342
343
  
  _id = addEmptyObject( _type );
  
Jan Möbius's avatar
Jan Möbius committed
344
345
346
  if ( OpenFlipper::Options::doSlotDebugging() ) {
    if ( sender() != 0 ) {
      if ( sender()->metaObject() != 0 ) {
347
        emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + "," + QString::number(_id) +  tr(" ) called by ") +
Jan Möbius's avatar
Jan Möbius committed
348
349
350
        QString( sender()->metaObject()->className() ) );
      }
    } else {
351
      emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + ","  + QString::number(_id) +  tr(" ) called by Core") );
Jan Möbius's avatar
Jan Möbius committed
352
353
    }
  }
Jan Möbius's avatar
 
Jan Möbius committed
354
355
}

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

Jan Möbius's avatar
Jan Möbius committed
359
  if ( _oldId == -1 ) {
Jan Möbius's avatar
Jan Möbius committed
360
    emit log(LOGERR,tr("Requested copy for illegal Object id: %1").arg(_oldId) );
Jan Möbius's avatar
Jan Möbius committed
361
362
363
364
365
366
367
368
    _newId = -1;
    return;
  }

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

  if ( !object ) {
Jan Möbius's avatar
Jan Möbius committed
369
    emit log(LOGERR,tr("Requested copy for unknown Object id: %1 ").arg(_oldId) );
Jan Möbius's avatar
Jan Möbius committed
370
371
372
373
374
375
376
377
    _newId = -1;
    return ;
  }

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

  if ( copy == 0 ) {
378
    emit log(LOGERR,tr("Unable to create a copy of the object."));
Jan Möbius's avatar
Jan Möbius committed
379
380
381
382
383
384
    return;
  }

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

385
  // return the new id
Jan Möbius's avatar
Jan Möbius committed
386
  _newId = copy->id();
387

388
389
390
391
392
393
  // tell plugins that a new object has been created
  slotEmptyObjectAdded(_newId);

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

394
395
}

Dirk Wilden's avatar
Dirk Wilden committed
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
/// 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
  int id = supportedTypes_[_pluginID].plugin->loadObject(_filename);

  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 );
  }
  
418
419
420
421
422
  // Initialize as unknown type
  DataType type = DATA_UNKNOWN;

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

424
425
    BaseObjectData* object;
    PluginFunctions::getObject(id,object);
Dirk Wilden's avatar
Dirk Wilden committed
426
    
427
    if ( !object ) {
Dirk Wilden's avatar
Dirk Wilden committed
428
429
430
431
432
433
434
435
436
437
438

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

        group = dynamic_cast< GroupObject* > (baseObj);

        if (group)
439
          type = DATA_GROUP;
Dirk Wilden's avatar
Dirk Wilden committed
440
441
442
443
444
445
      }
      
      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;
      }
446
447
448
    }
    
    // Get the objects type
Dirk Wilden's avatar
Dirk Wilden committed
449
450
    if (object)
      type = object->dataType();
Dirk Wilden's avatar
Dirk Wilden committed
451
  }
452
453
  
  // If the id was greater than zero, add the file to the recent files.
Dirk Wilden's avatar
Dirk Wilden committed
454
455
456
457
458
  if ( id >= 0 )
    if ( OpenFlipper::Options::gui() )
      coreWidget_->addRecent(_filename, type);
}

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

Jan Möbius's avatar
 
Jan Möbius committed
463
464
465
  if ( _id < 0 )
    _id = -1;
  else
466
    if ( OpenFlipper::Options::gui() )
Jan Möbius's avatar
 
Jan Möbius committed
467
468
469
470
      coreWidget_->addRecent(_filename,_type);
}

/// Slot gets called after a file-plugin has opened an object
471
472
473
474
void Core::slotObjectOpened ( int _id ) {
  if ( OpenFlipper::Options::doSlotDebugging() ) {
    if ( sender() != 0 ) {
      if ( sender()->metaObject() != 0 ) {
475
        emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by ") +
476
477
478
                  QString( sender()->metaObject()->className() ) );
      }
    } else {
479
      emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by Core") );
480
481
    }
  }
482
483

  // get the opened object
484
485
  BaseObjectData* object;
  PluginFunctions::getObject(_id,object);
486

Jan Möbius's avatar
Jan Möbius committed
487
  // ================================================================================
488
  // Set defaults for DrawMode, ViewingDirection and Projection if this is the first opened object
Jan Möbius's avatar
Jan Möbius committed
489
490
491
  // If a plugin changes the drawmode later, this setting will be overridden!
  // ================================================================================
  if ( PluginFunctions::objectCount() == 1 && OpenFlipper::Options::gui() && !OpenFlipper::Options::loadingSettings() )
492
493
    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i ){
      PluginFunctions::viewerProperties(i).drawMode( OpenFlipper::Options::defaultDrawMode(i) );
494

495
      if ( OpenFlipper::Options::defaultProjectionMode(i) == 0 )
Dirk Wilden's avatar
Dirk Wilden committed
496
        PluginFunctions::orthographicProjection(i);
497
      else
Dirk Wilden's avatar
Dirk Wilden committed
498
        PluginFunctions::perspectiveProjection(i);
499
500
501

      PluginFunctions::setFixedView(OpenFlipper::Options::defaultViewingDirection(i), i );
    }
Jan Möbius's avatar
Jan Möbius committed
502
503
504

  // ================================================================================
  // Recompute bounding box and scenegraph info
505
  // Reset scene center here to include new object
Jan Möbius's avatar
Jan Möbius committed
506
  // ================================================================================
507
  resetScenegraph(true);
Jan Möbius's avatar
 
Jan Möbius committed
508

Jan Möbius's avatar
Jan Möbius committed
509
510
511
  // ================================================================================
  // Tell plugins, that a file has been opened
  // ================================================================================
512
  emit openedFile( _id );
513
514
515
516
517
  
  // ================================================================================
  // Print Info to logger
  // ================================================================================
  emit log( LOGINFO ,object->getObjectinfo() );
Jan Möbius's avatar
 
Jan Möbius committed
518

Jan Möbius's avatar
Jan Möbius committed
519
520
521
  // ================================================================================
  // Tell plugins, that the Object is updated and the active object has changed
  // ================================================================================
Jan Möbius's avatar
Jan Möbius committed
522
523
  emit signalObjectUpdated(_id );
  emit signalObjectUpdated(_id, UPDATE_ALL);
Jan Möbius's avatar
 
Jan Möbius committed
524

Jan Möbius's avatar
Jan Möbius committed
525
526
527
  // ================================================================================
  // Create initial backup
  // ================================================================================
Jan Möbius's avatar
Jan Möbius committed
528
529
  int backupId = 0;
  slotBackup(_id,"Original Object",backupId);
Jan Möbius's avatar
 
Jan Möbius committed
530

531
532
533
  // ================================================================================
  // Add the file to the recent files menu
  // ================================================================================
534
535
536
  QString filename = object->path() + OpenFlipper::Options::dirSeparator() + object->name();
  BaseObject* object2;
  PluginFunctions::getObject(_id,object2);
Jan Möbius's avatar
 
Jan Möbius committed
537

Jan Möbius's avatar
Jan Möbius committed
538
539
540
  // ================================================================================
  // if this is the first object opend, reset the global view
  // ================================================================================
541
  if ( PluginFunctions::objectCount() == 1 && OpenFlipper::Options::gui() && !OpenFlipper::Options::loadingSettings() )
542
543
544
    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i ) {
      coreWidget_->examiner_widgets_[i]->viewAll();
    }
545

Jan Möbius's avatar
 
Jan Möbius committed
546
  // objectRoot_->dumpTree();
547
}
Jan Möbius's avatar
 
Jan Möbius committed
548
549

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

552
553
554
  if ( OpenFlipper::Options::doSlotDebugging() ) {
    if ( sender() != 0 ) {
      if ( sender()->metaObject() != 0 ) {
555
        emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by ") +
556
557
558
                  QString( sender()->metaObject()->className() ) );
      }
    } else {
559
      emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by Core") );
560
561
562
    }
  }

563
564
565
566
  // get the opened object
  BaseObjectData* object;
  PluginFunctions::getObject(_id,object);

567
  
568
  emit emptyObjectAdded( _id );
569

Jan Möbius's avatar
 
Jan Möbius committed
570
  // Tell the Plugins that the Object List and the active object have changed
571
  emit signalObjectUpdated(_id);
Jan Möbius's avatar
Jan Möbius committed
572
  emit signalObjectUpdated(_id,UPDATE_ALL);
Jan Möbius's avatar
 
Jan Möbius committed
573

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

//    addRecent(filename);
578
}
Jan Möbius's avatar
 
Jan Möbius committed
579
580
581
582
583
584
585

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

/// Opens AddEmpty-Object widget
void Core::slotAddEmptyObjectMenu() {
586
587
588
589
590
591
592
593
594
595
596
597
598
  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) {
    
599
    // Iterate over all supported types (created from plugins on load)
600
601
    // Check if a plugin supports addEmpty for the current type.
    // Only if the type is supported, add it to the addEmpty Dialog
602
603
604
    
    // typePlugin
    for ( uint j = 0 ; j < supportedDataTypes_.size(); j++) {
605
      
606
607
      // Check if a plugin supports the current type
      if ( supportedDataTypes_[j].type & currentType ) {
608
609
610
611
612
        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
613
      }
614
615
    }
    
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
    // filePlugin
    for ( uint j = 0 ; j < supportedTypes_.size(); j++) {
      
      // Check if a plugin supports the current Type
      if ( supportedTypes_[j].type & currentType ) {
	
	// 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;
	}
      }
    }
    
641
    // Advance to next type ( Indices are bits so multiply by to to get next bit)
642
    currentType++;
643
644
645
646
647
648
649
  }
  
  static addEmptyWidget* widget = 0;
  
  if (supportedTypes_.size() != 0) {
    
    if ( !widget ){
Jan Möbius's avatar
 
Jan Möbius committed
650
      widget = new addEmptyWidget(types,typeNames);
651
      widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
Jan Möbius's avatar
 
Jan Möbius committed
652
653
      connect(widget,SIGNAL(chosen(DataType, int&)),this,SLOT(slotAddEmptyObject(DataType, int&)));
    }
654
    
Jan Möbius's avatar
 
Jan Möbius committed
655
    widget->show();
656
657
658
659
    
  } else
    emit log(LOGERR,tr("Could not show 'add Empty' dialog. Missing file-plugins ?"));
  
Jan Möbius's avatar
 
Jan Möbius committed
660
661
}

662
663
664
665
//========================================================================================
// ===             Public Slots                                 ============================
//========================================================================================

Jan Möbius's avatar
 
Jan Möbius committed
666
/// Open Load-Object Widget
667
668
669
670
671
void Core::loadObject() {

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

    if (supportedTypes_.size() != 0){
672
      LoadWidget* widget = new LoadWidget(supportedTypes_);
Dirk Wilden's avatar
Dirk Wilden committed
673
674
      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
675

676
677
      widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );

678
      widget->showLoad();
679
680
681
682

      widget->disconnect();
      delete widget;

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

686
  }
Jan Möbius's avatar
 
Jan Möbius committed
687
688
}

689
690
691
692
693
694
/// Load settings from file
void Core::loadSettings(){

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

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

696
697
698

    QFileDialog fileDialog( coreWidget_,
                            tr("Load Settings"),
699
                            OpenFlipperSettings().value("Core/CurrentDir").toString(),
700
                            tr("INI files (*.ini)") );
701

702
    fileDialog.setOption (QFileDialog::DontUseNativeDialog, true);
703
704
705
706
707
708
709
    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 ) );
710
    optionsBox->setTitle(tr("Options"));
711
712
713
    layout->addWidget( optionsBox, layout->rowCount() , 0 , 1,layout->columnCount() );

    QCheckBox *loadProgramSettings = new QCheckBox(optionsBox);
714
715
    loadProgramSettings->setText(tr("Load program settings"));
    loadProgramSettings->setToolTip(tr("Load all current program settings from the file ( This will include view settings, colors,...) "));
716
717
718
    loadProgramSettings->setCheckState( Qt::Unchecked );

    QCheckBox *loadPluginSettings = new QCheckBox(optionsBox);
719
720
    loadPluginSettings->setText(tr("Load per Plugin Settings"));
    loadPluginSettings->setToolTip(tr("Plugins should load their current global settings from the file"));
721
722
723
    loadPluginSettings->setCheckState( Qt::Checked );

    QCheckBox *loadObjectInfo = new QCheckBox(optionsBox);
724
725
    loadObjectInfo->setText(tr("Load all objects defined in the file"));
    loadObjectInfo->setToolTip(tr("Load all objects which are defined in the file"));
726
727
728
729
730
731
732
733
    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
734
735
    fileDialog.resize(550 ,500);

736
737
738
739
740
741
742
743
744
745
746
747
    // ========================================================================================
    // 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;
748
      return;
749
750
751
752
    }

    complete_name = fileNames[0];

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

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

757
    if ( complete_name.endsWith("ini",Qt::CaseInsensitive) ) {
758
759
760
761
      openIniFile( complete_name,
                   loadProgramSettings->isChecked(),
                   loadPluginSettings->isChecked(),
                   loadObjectInfo->isChecked());
762
763
      if ( loadProgramSettings->isChecked() )
        applyOptions();
764
765
    } 
    
766
    coreWidget_->addRecent(complete_name, DATA_UNKNOWN);
767
768
  }
}
Jan Möbius's avatar
 
Jan Möbius committed
769

770
771
/// Load settings from file
void Core::loadSettings(QString _filename){
Jan Möbius's avatar
Jan Möbius committed
772

773
  if ( !QFile(_filename).exists() )
Jan Möbius's avatar
 
Jan Möbius committed
774
775
    return;

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

779
  if ( _filename.endsWith("ini",Qt::CaseInsensitive) ) {
780
    // Loaded function for recent files. Load everything.
781
    openIniFile(_filename,true,true,true);
Jan Möbius's avatar
 
Jan Möbius committed
782
    applyOptions();
783
  } else if ( _filename.endsWith("obj",Qt::CaseInsensitive) ) {
Dirk Wilden's avatar
Dirk Wilden committed
784
    loadObject(_filename);
Jan Möbius's avatar
 
Jan Möbius committed
785
786
787
788
    applyOptions();
  }

}