openFunctions.cc 29.6 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::sceneGraphUpdatesBlocked() ) {
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 83 84 85 86 87 88 89
}

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



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

100
void Core::commandLineOpen(const char* _filename, bool _asPolyMesh ){
101

Jan Möbius's avatar
Jan Möbius committed
102
  QString file(_filename);
103

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

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

void Core::commandLineScript(const char* _filename ) {
116 117 118 119 120 121 122 123 124 125 126 127

  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());
128 129
}

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

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

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

Jan Möbius's avatar
Jan Möbius committed
137 138 139 140
  //check if we have scripting support:
  bool scriptingSupport = false;
  slotPluginExists("scripting",scriptingSupport);
  if ( ! scriptingSupport ) {
141
    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
142 143
  }

Jan Möbius's avatar
Jan Möbius committed
144 145 146
  // 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
147 148
  if ( scriptingSupport ) {

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

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

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

163
  OpenFlipper::Options::blockSceneGraphUpdates();
164

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

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

Jan Möbius's avatar
Jan Möbius committed
175
    // If the file was given with the polymesh option, open them as polymeshes.
176
    if (commandLineFileNames_[i].second)
177 178 179 180
      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
181 182
  }

183
  OpenFlipper::Options::unblockSceneGraphUpdates();
184

185 186 187
  // Reset the scenegraph once to make sure everything is fine
  resetScenegraph( true );

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

Jan Möbius's avatar
Jan Möbius committed
194 195
  // 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
196 197
  if ( !OpenFlipper::Options::gui() && !OpenFlipper::Options::remoteControl())
    exitApplication();
Jan Möbius's avatar
 
Jan Möbius committed
198 199
}

200

Jan Möbius's avatar
Jan Möbius committed
201 202 203 204 205 206 207
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.
  */
  
208
  if (_filename.endsWith(".ini",Qt::CaseInsensitive)) {
209 210

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

Jan Möbius's avatar
 
Jan Möbius committed
213
    if ( OpenFlipper::Options::gui() )
214
      coreWidget_->addRecent(_filename, DATA_UNKNOWN);
215

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

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

226
      QString filters = supportedTypes()[i].plugin->getLoadFilters();
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

      // 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;
244
        }
245 246 247 248 249 250 251

        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
252
      }
Dirk Wilden's avatar
Dirk Wilden committed
253

254 255 256 257
      // continue processing only if found
      if ( ! found )
        continue;

Dirk Wilden's avatar
Dirk Wilden committed
258 259
      if ( OpenFlipper::Options::gui() ) {
        coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
260
        if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
Dirk Wilden's avatar
Dirk Wilden committed
261 262 263 264
          coreWidget_->setStatus(ApplicationStatus::PROCESSING );
      }

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

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

          // 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) );
          }
284 285
          
        } else
Dirk Wilden's avatar
Dirk Wilden committed
286 287
          coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(_filename), 4000 );

288
        if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
Dirk Wilden's avatar
Dirk Wilden committed
289 290 291 292 293 294 295 296
          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
297 298 299 300 301 302

  return -1;
}

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

Dirk Wilden's avatar
Dirk Wilden committed
310 311
  QFileInfo fi(_filename);
  
312 313
  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
314

315
      QString filters = supportedTypes()[i].plugin->getLoadFilters();
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 341 342 343 344

      // 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
345 346
        continue;
      
Jan Möbius's avatar
 
Jan Möbius committed
347
      if ( OpenFlipper::Options::gui() ) {
Jan Möbius's avatar
Jan Möbius committed
348
        coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
349
        if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
Jan Möbius's avatar
 
Jan Möbius committed
350 351 352
          coreWidget_->setStatus(ApplicationStatus::PROCESSING );
      }

Dirk Wilden's avatar
Dirk Wilden committed
353 354
      int id = -1;

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

      if ( OpenFlipper::Options::gui() ) {
362
        if ( id != -1 ) {
Jan Möbius's avatar
Jan Möbius committed
363
          coreWidget_->statusMessage( tr("Loading %1 ... done").arg(_filename), 4000 );
364 365 366 367 368 369 370 371 372 373
          
          // 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
374
          coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(_filename), 4000 );
Jan Möbius's avatar
 
Jan Möbius committed
375

376
        if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
Jan Möbius's avatar
 
Jan Möbius committed
377 378 379 380 381
          coreWidget_->setStatus(ApplicationStatus::READY );
      }

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

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

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

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

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

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

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

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

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

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

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

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

455
  // return the new id
Jan Möbius's avatar
Jan Möbius committed
456
  _newId = copy->id();
457

458 459 460 461 462 463
  // tell plugins that a new object has been created
  slotEmptyObjectAdded(_newId);

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

464 465
}

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

  if ( OpenFlipper::Options::gui() ) {
    coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
471
    if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
Dirk Wilden's avatar
Dirk Wilden committed
472 473 474 475
      coreWidget_->setStatus(ApplicationStatus::PROCESSING );
  }

  //load file
476
  int id = supportedTypes()[_pluginID].plugin->loadObject(_filename);
Dirk Wilden's avatar
Dirk Wilden committed
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 );

484
    if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
Dirk Wilden's avatar
Dirk Wilden committed
485 486 487
      coreWidget_->setStatus(ApplicationStatus::READY );
  }
  
488 489 490 491 492
  // Initialize as unknown type
  DataType type = DATA_UNKNOWN;

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

494 495
    BaseObjectData* object;
    PluginFunctions::getObject(id,object);
Dirk Wilden's avatar
Dirk Wilden committed
496
    
497
    if ( !object ) {
Dirk Wilden's avatar
Dirk Wilden committed
498 499 500 501 502 503 504 505 506 507 508

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

        group = dynamic_cast< GroupObject* > (baseObj);

        if (group)
509
          type = DATA_GROUP;
Dirk Wilden's avatar
Dirk Wilden committed
510 511 512 513 514 515
      }
      
      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;
      }
516 517 518
    }
    
    // Get the objects type
Dirk Wilden's avatar
Dirk Wilden committed
519 520
    if (object)
      type = object->dataType();
Dirk Wilden's avatar
Dirk Wilden committed
521
  }
522 523
  
  // If the id was greater than zero, add the file to the recent files.
Dirk Wilden's avatar
Dirk Wilden committed
524 525 526 527 528
  if ( id >= 0 )
    if ( OpenFlipper::Options::gui() )
      coreWidget_->addRecent(_filename, type);
}

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

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

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

  // get the opened object
554 555
  BaseObjectData* object;
  PluginFunctions::getObject(_id,object);
556

Jan Möbius's avatar
Jan Möbius committed
557 558
  // ================================================================================
  // Recompute bounding box and scenegraph info
559
  // Reset scene center here to include new object
Jan Möbius's avatar
Jan Möbius committed
560
  // ================================================================================
561
  resetScenegraph(true);
Jan Möbius's avatar
 
Jan Möbius committed
562

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

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

Jan Möbius's avatar
Jan Möbius committed
579 580 581
  // ================================================================================
  // Create initial backup
  // ================================================================================
582
  emit createBackup(_id,"Original Object");
Jan Möbius's avatar
 
Jan Möbius committed
583

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

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

Jan Möbius's avatar
 
Jan Möbius committed
599
  // objectRoot_->dumpTree();
600
}
Jan Möbius's avatar
 
Jan Möbius committed
601 602

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

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

616 617 618 619
  // get the opened object
  BaseObjectData* object;
  PluginFunctions::getObject(_id,object);

620
  
621
  emit emptyObjectAdded( _id );
622

Jan Möbius's avatar
 
Jan Möbius committed
623
  // Tell the Plugins that the Object List and the active object have changed
624
  emit signalObjectUpdated(_id);
Jan Möbius's avatar
Jan Möbius committed
625
  emit signalObjectUpdated(_id,UPDATE_ALL);
Jan Möbius's avatar
 
Jan Möbius committed
626

627 628
  resetScenegraph(false);

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

//    addRecent(filename);
633
}
Jan Möbius's avatar
 
Jan Möbius committed
634 635 636 637 638 639 640

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

/// Opens AddEmpty-Object widget
void Core::slotAddEmptyObjectMenu() {
641 642 643 644 645 646 647 648 649 650 651 652 653
  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) {
    
654
    // Iterate over all supported types (created from plugins on load)
655 656
    // Check if a plugin supports addEmpty for the current type.
    // Only if the type is supported, add it to the addEmpty Dialog
657 658 659
    
    // typePlugin
    for ( uint j = 0 ; j < supportedDataTypes_.size(); j++) {
660
      
661 662
      // Check if a plugin supports the current type
      if ( supportedDataTypes_[j].type & currentType ) {
663 664 665 666 667
        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
668
      }
669 670
    }
    
671
    // filePlugin
672
    for ( uint j = 0 ; j < supportedTypes().size(); j++) {
673 674
      
      // Check if a plugin supports the current Type
675
      if ( supportedTypes()[j].type & currentType ) {
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
	
	// 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;
	}
      }
    }
    
696 697
    // Advance to next type ( Indices are bits so multiply by two to get next bit)
    ++currentType;
698 699 700
  }
  
  
Jan Möbius's avatar
Jan Möbius committed
701

702
  if (supportedTypes().size() != 0) {
703
    
Jan Möbius's avatar
Jan Möbius committed
704 705
    static addEmptyWidget* widget = 0;

706
    if ( !widget ){
Jan Möbius's avatar
 
Jan Möbius committed
707
      widget = new addEmptyWidget(types,typeNames);
708
      widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
Jan Möbius's avatar
 
Jan Möbius committed
709 710
      connect(widget,SIGNAL(chosen(DataType, int&)),this,SLOT(slotAddEmptyObject(DataType, int&)));
    }
711
    
Jan Möbius's avatar
 
Jan Möbius committed
712
    widget->show();
713 714 715 716
    
  } else
    emit log(LOGERR,tr("Could not show 'add Empty' dialog. Missing file-plugins ?"));
  
Jan Möbius's avatar
 
Jan Möbius committed
717 718
}

719 720 721 722
//========================================================================================
// ===             Public Slots                                 ============================
//========================================================================================

Jan Möbius's avatar
 
Jan Möbius committed
723
/// Open Load-Object Widget
724 725 726 727
void Core::loadObject() {

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

728 729
    if (supportedTypes().size() != 0){
      LoadWidget* widget = new LoadWidget(supportedTypes());
Dirk Wilden's avatar
Dirk Wilden committed
730 731
      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
732

733 734
      widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );

735
      widget->showLoad();
736 737 738 739

      widget->disconnect();
      delete widget;

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

743
  }
Jan Möbius's avatar
 
Jan Möbius committed
744 745
}

746 747 748 749 750 751
/// Load settings from file
void Core::loadSettings(){

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

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

753 754 755

    QFileDialog fileDialog( coreWidget_,
                            tr("Load Settings"),
756
                            OpenFlipperSettings().value("Core/CurrentDir").toString(),
757
                            tr("INI files (*.ini)") );
758

759
    fileDialog.setOption (QFileDialog::DontUseNativeDialog, true);
760 761 762 763 764 765 766
    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 ) );
767
    optionsBox->setTitle(tr("Options"));
768 769 770
    layout->addWidget( optionsBox, layout->rowCount() , 0 , 1,layout->columnCount() );

    QCheckBox *loadProgramSettings = new QCheckBox(optionsBox);
771 772
    loadProgramSettings->setText(tr("Load program settings"));
    loadProgramSettings->setToolTip(tr("Load all current program settings from the file ( This will include view settings, colors,...) "));
773 774 775
    loadProgramSettings->setCheckState( Qt::Unchecked );

    QCheckBox *loadPluginSettings = new QCheckBox(optionsBox);
776 777
    loadPluginSettings->setText(tr("Load per Plugin Settings"));
    loadPluginSettings->setToolTip(tr("Plugins should load their current global settings from the file"));
778 779 780
    loadPluginSettings->setCheckState( Qt::Checked );

    QCheckBox *loadObjectInfo = new QCheckBox(optionsBox);
781 782
    loadObjectInfo->setText(tr("Load all objects defined in the file"));
    loadObjectInfo->setToolTip(tr("Load all objects which are defined in the file"));
783 784 785 786 787 788 789 790
    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
791 792
    fileDialog.resize(550 ,500);

793 794 795 796 797 798 799 800 801 802 803 804
    // ========================================================================================
    // 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;
805
      return;
806 807 808 809
    }

    complete_name = fileNames[0];

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

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

814
    if ( complete_name.endsWith("ini",Qt::CaseInsensitive) ) {
815 816 817 818
      openIniFile( complete_name,
                   loadProgramSettings->isChecked(),
                   loadPluginSettings->isChecked(),
                   loadObjectInfo->isChecked());
819 820
      if ( loadProgramSettings->isChecked() )
        applyOptions();
821 822
    } 
    
823
    coreWidget_->addRecent(complete_name, DATA_UNKNOWN);
824 825
  }
}
Jan Möbius's avatar
 
Jan Möbius committed
826

827 828
/// Load settings from file
void Core::loadSettings(QString _filename){
Jan Möbius's avatar
Jan Möbius committed
829

830
  if ( !QFile(_filename).exists() )
Jan Möbius's avatar
 
Jan Möbius committed
831 832
    return;

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

836
  if ( _filename.endsWith("ini",Qt::CaseInsensitive) ) {
837
    // Loaded function for recent files. Load everything.
838
    openIniFile(_filename,true,true,true);
Jan Möbius's avatar
 
Jan Möbius committed
839
    applyOptions();
840
  } else if ( _filename.endsWith("obj",Qt::CaseInsensitive) ) {
Dirk Wilden's avatar
Dirk Wilden committed
841
    loadObject(_filename);
Jan Möbius's avatar
 
Jan Möbius committed
842 843 844 845
    applyOptions();
  }

}