Core.cc 24.9 KB
Newer Older
Jan Möbius's avatar
 
Jan Möbius committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//=============================================================================
//
//                               OpenFlipper
//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
//                           www.openflipper.org
//
//-----------------------------------------------------------------------------
//
//                                License
//
//  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.
15
//
Jan Möbius's avatar
 
Jan Möbius committed
16 17 18 19
//  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.
20
//
Jan Möbius's avatar
 
Jan Möbius committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
//  You should have received a copy of the GNU Lesser General Public License
//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
//   $Revision$
//   $Author$
//   $Date$
//
//=============================================================================





//=============================================================================
//
//  CLASS Core - IMPLEMENTATION
//
//=============================================================================


//== INCLUDES =================================================================

// -------------------- mview
#include "Core.hh"
// -------------------- ACG
#include <ACG/Scenegraph/DrawModes.hh>

#include <ACG/QtWidgets/QtFileDialog.hh>
// -------------------- Qt

#include <QKeyEvent>
#include <QSplitter>
#include <QMenuBar>
#include <QToolBox>
#include <QApplication>
#include <QStatusBar>
#include <QMessageBox>
#include <QFile>

#include <QPluginLoader>
#include "OpenFlipper/BasePlugin/BaseInterface.hh"
#include "OpenFlipper/BasePlugin/KeyInterface.hh"
#include "OpenFlipper/BasePlugin/MouseInterface.hh"
#include "OpenFlipper/BasePlugin/PickingInterface.hh"
#include "OpenFlipper/BasePlugin/ToolboxInterface.hh"
#include "OpenFlipper/BasePlugin/TextureInterface.hh"
#include "OpenFlipper/BasePlugin/MenuInterface.hh"
#include "OpenFlipper/BasePlugin/INIInterface.hh"
#include "OpenFlipper/BasePlugin/GlobalAccessInterface.hh"

#include "OpenFlipper/INIFile/INIFile.hh"

#include "OpenFlipper/common/GlobalOptions.hh"
#include <OpenFlipper/common/RecentFiles.hh>
#include <OpenFlipper/ACGHelper/DrawModeConverter.hh>

#include <QStringList>
#include <QtScript/QScriptValueIterator>

#include <ACG/Scenegraph/SeparatorNode.hh>

#include "OpenFlipper/BasePlugin/PluginFunctions.hh"

#include <OpenMesh/Core/System/omstream.hh>

#define WIDGET_HEIGHT 800
#define WIDGET_WIDTH  800

91
//== IMPLEMENTATION ==========================================================
Jan Möbius's avatar
 
Jan Möbius committed
92 93

/** \brief Constuctor for the Core Widget ( This is stage 1 , call init for stage 2)
94
 *
Jan Möbius's avatar
 
Jan Möbius committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108
 * Initialization is working the following way:\n
 * - Setup basic paths \n
 * - Get Options from Option files ( While skipping the OpenFiles Sections as Core is not running )\n
 * - Jump back ( Stage two is done by calling init from main ) so CALL init!!
 * - This Two stage system allows using commandline options which override Option Files
*/
Core::
Core() :
  QObject(),
  nextBackupId_(0),
  standard_draw_mode_(ACG::SceneGraph::DrawModes::SOLID_SMOOTH_SHADED),
  set_random_base_color_(true),
  coreWidget_(0)
{
Dirk Wilden's avatar
Dirk Wilden committed
109 110 111 112 113
  //init logFile
  logStream_ = 0;
  logFile_ = 0;
  OpenFlipper::Options::logFileEnabled(true);

Dirk Wilden's avatar
Dirk Wilden committed
114 115 116 117
  //init nodes
  root_node_scenegraph_ = new ACG::SceneGraph::SeparatorNode(0, "SceneGraph Root Node");
  root_node_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_, "Data Root Node");

Jan Möbius's avatar
 
Jan Möbius committed
118 119 120 121 122
   // Add ViewMode All
  ViewMode* vm = new ViewMode();
  vm->name = "All";
  vm->custom = false;
  vm->visibleWidgets = QStringList();
123

Jan Möbius's avatar
 
Jan Möbius committed
124 125 126 127 128 129
  viewModes_.push_front(vm);

  // Get all relevant Paths and Options from option files
  setupOptions();
}

130 131 132
/** \brief Second initialization stage
 *
 * This Stage does the following :\n
Jan Möbius's avatar
 
Jan Möbius committed
133 134 135 136 137 138
 * - Create the Core GUI Elements (Examiner, Toolbox,...)\n
 * - Create the MenuBar \n
 * - load the Plugins \n
 * - connect the Mouse slots \n
 * - Load all ini files (This includes the Global Option files) \n
 */
139 140 141
void
Core::init() {

Jan Möbius's avatar
 
Jan Möbius committed
142
  // Make root_node available to the plugins ( defined in PluginFunctions.hh)
143 144 145
  PluginFunctions::set_rootNode( root_node_ );

  PluginFunctions::set_sceneGraphRootNode( root_node_scenegraph_ );
Dirk Wilden's avatar
Dirk Wilden committed
146

Jan Möbius's avatar
 
Jan Möbius committed
147
  // Initialize the first object as the root Object for the object tree
148
  objectRoot_ =  dynamic_cast< BaseObject* > ( new GroupObject("ObjectRoot") );
Jan Möbius's avatar
 
Jan Möbius committed
149 150
  PluginFunctions::setDataRoot( objectRoot_ );

151

Jan Möbius's avatar
 
Jan Möbius committed
152
  if ( OpenFlipper::Options::gui() ) {
153 154 155 156 157 158

    redrawTimer_ = new QTimer();
    redrawTimer_->setSingleShot(true);
    connect(redrawTimer_, SIGNAL(timeout()), this, SLOT(updateView()),Qt::DirectConnection);


Jan Möbius's avatar
 
Jan Möbius committed
159 160
    if ( OpenFlipper::Options::splash() ) {
      QPixmap splashPixmap(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "splash.png");
161

Jan Möbius's avatar
 
Jan Möbius committed
162 163
      splash_ = new QSplashScreen(splashPixmap);
      splash_->show();
164 165

      splash_->showMessage("Initializing mainwindow" ,
Jan Möbius's avatar
 
Jan Möbius committed
166 167 168
                          Qt::AlignBottom | Qt::AlignLeft , Qt::white);
      QApplication::processEvents();
    }
169

Dirk Wilden's avatar
Dirk Wilden committed
170
    coreWidget_ = new CoreWidget(viewModes_ , plugins);
171

Jan Möbius's avatar
 
Jan Möbius committed
172 173 174 175 176 177 178
    connect(coreWidget_, SIGNAL(clearAll())           , this, SLOT(clearAll()));
    connect(coreWidget_, SIGNAL(loadMenu())           , this, SLOT(slotLoadMenu()));
    connect(coreWidget_, SIGNAL(addEmptyObjectMenu()) , this, SLOT(slotAddEmptyObjectMenu()));
    connect(coreWidget_, SIGNAL(saveMenu())           , this, SLOT(slotSaveMenu()));
    connect(coreWidget_, SIGNAL(saveToMenu())         , this, SLOT(slotSaveToMenu()));
    connect(coreWidget_, SIGNAL(loadIniMenu())        , this, SLOT(slotLoadIniMenu()));
    connect(coreWidget_, SIGNAL(saveIniMenu())        , this, SLOT(slotSaveIniMenu()));
179
    connect(coreWidget_, SIGNAL(applyOptions())       , this, SLOT(applyOptions()));
Dirk Wilden's avatar
Dirk Wilden committed
180
    connect(coreWidget_, SIGNAL(saveOptions())        , this, SLOT(saveOptions()));
Jan Möbius's avatar
 
Jan Möbius committed
181 182
    connect(coreWidget_, SIGNAL(recentOpen(QAction*)) , this, SLOT(slotRecentOpen(QAction*)));
    connect(coreWidget_, SIGNAL(exit())               , this, SLOT(slotExit()));
183

Jan Möbius's avatar
 
Jan Möbius committed
184 185
    connect(coreWidget_, SIGNAL(loadPlugin())         , this, SLOT(slotLoadPlugin()));
    connect(coreWidget_, SIGNAL(unloadPlugin())       , this, SLOT(slotUnloadPlugin()));
186

Jan Möbius's avatar
 
Jan Möbius committed
187
    coreWidget_->resize(1000,1000);
188 189 190

    coreWidget_->setWindowTitle( OpenFlipper::Options::windowTitle() );

Jan Möbius's avatar
 
Jan Möbius committed
191 192
    // Make examiner available to the plugins ( defined in PluginFunctions.hh)
    PluginFunctions::set_examiner( coreWidget_->examiner_widget_ );
193 194


Jan Möbius's avatar
 
Jan Möbius committed
195
  }
196

Jan Möbius's avatar
 
Jan Möbius committed
197 198 199 200
  // ======================================================================
  // Create intermediate logger class for Core which will mangle the output
  // ======================================================================
  PluginLogger* newlog = new PluginLogger("Core");
201

Jan Möbius's avatar
 
Jan Möbius committed
202 203
  loggers_.push_back(newlog);
  connect(this,SIGNAL(log(Logtype, QString )),newlog,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
204 205
  connect(this,SIGNAL(log(QString )),newlog,SLOT(slotLog(QString )),Qt::DirectConnection);

Jan Möbius's avatar
 
Jan Möbius committed
206 207 208
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
209

Jan Möbius's avatar
 
Jan Möbius committed
210
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
211

Dirk Wilden's avatar
Dirk Wilden committed
212 213
  // connection to file logger
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
214 215 216 217 218 219 220

  // ======================================================================
  // Create a logger class for CoreWidget
  // ======================================================================

  if ( OpenFlipper::Options::gui() ){
    PluginLogger* widgetlog = new PluginLogger("CoreWidget");
221

Dirk Wilden's avatar
Dirk Wilden committed
222 223
    loggers_.push_back(widgetlog);
    connect(coreWidget_,SIGNAL(log(Logtype, QString )),widgetlog,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
224 225
    connect(coreWidget_,SIGNAL(log(QString )),widgetlog,SLOT(slotLog(QString )),Qt::DirectConnection);

Dirk Wilden's avatar
Dirk Wilden committed
226 227 228
    // Connect it to the Master logger
    connect(widgetlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
    connect(widgetlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
229 230
    // connection to file logger
    connect(widgetlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
231
  }
232

Jan Möbius's avatar
 
Jan Möbius committed
233 234 235 236 237 238
  // ======================================================================
  // Catch OpenMesh Error logs with an own Logger
  // ======================================================================
  newlog = new PluginLogger("Core ( OpenMesh )",LOGERR);
  omerr().connect(*newlog);
  omerr().disconnect(std::cerr);
239

Jan Möbius's avatar
 
Jan Möbius committed
240
  loggers_.push_back(newlog);
241

Jan Möbius's avatar
 
Jan Möbius committed
242 243 244
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
245

Jan Möbius's avatar
 
Jan Möbius committed
246
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
247 248
  // connection to file logger
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
249

Jan Möbius's avatar
 
Jan Möbius committed
250 251 252 253 254 255
  // ======================================================================
  // Catch OpenMesh omout logs with an own Logger
  // ======================================================================
  newlog = new PluginLogger("Core ( OpenMesh )",LOGINFO);
  omout().connect(*newlog);
  omout().disconnect(std::cout);
256

Jan Möbius's avatar
 
Jan Möbius committed
257
  loggers_.push_back(newlog);
258

Jan Möbius's avatar
 
Jan Möbius committed
259 260 261
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
262

Jan Möbius's avatar
 
Jan Möbius committed
263
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
264 265
  // connection to file logger
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
266

Jan Möbius's avatar
 
Jan Möbius committed
267 268 269 270 271
  // ======================================================================
  // Catch OpenMesh omlog logs with an own Logger
  // ======================================================================
  newlog = new PluginLogger("Core ( OpenMesh )",LOGOUT);
  omlog().connect(*newlog);
272

Jan Möbius's avatar
 
Jan Möbius committed
273
  loggers_.push_back(newlog);
274

Jan Möbius's avatar
 
Jan Möbius committed
275 276 277
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
278

Jan Möbius's avatar
 
Jan Möbius committed
279
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
280 281
  // connection to file logger
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
282

Jan Möbius's avatar
 
Jan Möbius committed
283 284 285 286
  // ======================================================================
  // Log Scripting stuff through a separate logger
  // ======================================================================
  newlog = new PluginLogger("Scripting",LOGOUT);
287

Jan Möbius's avatar
 
Jan Möbius committed
288
  loggers_.push_back(newlog);
289

Jan Möbius's avatar
 
Jan Möbius committed
290 291 292
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
293

Jan Möbius's avatar
 
Jan Möbius committed
294
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
295
  // connection to file logger
296
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
297

Jan Möbius's avatar
 
Jan Möbius committed
298
  // connect signal to logger
299 300
  connect(this,SIGNAL(scriptLog(QString )),newlog,SLOT(slotLog(QString )),Qt::DirectConnection);

Jan Möbius's avatar
 
Jan Möbius committed
301 302 303 304 305
  // ======================================================================
  // This connection will tell the plugins, when their Toolbox is active
  // ======================================================================
  ///@todo reimplement
//   connect(module_list,SIGNAL(currentChanged(int)),this,SLOT(slotToolboxSwitched(int)));
306

Jan Möbius's avatar
 
Jan Möbius committed
307 308
  // process Events every 500 msecs during script execution
  scriptEngine_.setProcessEventsInterval( 500 );
309

Jan Möbius's avatar
 
Jan Möbius committed
310 311 312 313
  // Register own print function :
  QScriptValue printFunction = scriptEngine_.newFunction(myPrintFunction);
  printFunction.setProperty("textedit",scriptEngine_.newQObject(this));
  scriptEngine_.globalObject().setProperty("print", printFunction);
314

Jan Möbius's avatar
 
Jan Möbius committed
315
  // Register Vector Type to ScriptEngine ( is Vec3d )
316 317
  qScriptRegisterMetaType(&scriptEngine_,
                          toScriptValueVector,
Jan Möbius's avatar
 
Jan Möbius committed
318 319
                          fromScriptValueVector,
                          scriptEngine_.newQObject(&vec3dPrototype_));
320

Jan Möbius's avatar
 
Jan Möbius committed
321 322 323
  // set a constructor to allow creation via Vector(x,y,z)
  QScriptValue ctor = scriptEngine_.newFunction(createVector);
  scriptEngine_.globalObject().setProperty("Vector", ctor);
324 325


Jan Möbius's avatar
 
Jan Möbius committed
326
//    // Register ObjectId Type to ScriptEngine ( is int )
327 328
//   qScriptRegisterMetaType(&scriptEngine_,
//                           toScriptValueObjectId,
Jan Möbius's avatar
 
Jan Möbius committed
329
//                           fromScriptValueObjectId);
330
//
Jan Möbius's avatar
 
Jan Möbius committed
331 332 333
//   // set a constructor to allow creation via Vector(x,y,z)
//   ctor = scriptEngine_.newFunction(createObjectId);
//   scriptEngine_.globalObject().setProperty("ObjectId", ctor);
334 335


Jan Möbius's avatar
 
Jan Möbius committed
336 337 338 339
  // Register idList Type to scripting Engine
  qScriptRegisterSequenceMetaType< idList >(&scriptEngine_);

  qScriptRegisterSequenceMetaType< QVector< int > >(&scriptEngine_);
340 341


Jan Möbius's avatar
 
Jan Möbius committed
342
  // Register Matrix Type to scripting Engine ( is ACG::Matrix4x4d )
343 344
  qScriptRegisterMetaType(&scriptEngine_,
                          toScriptValueMatrix4x4 ,
Jan Möbius's avatar
 
Jan Möbius committed
345 346
                          fromScriptValueMatrix4x4,
                          scriptEngine_.newQObject(&matrix4x4Prototype_));
347

Jan Möbius's avatar
 
Jan Möbius committed
348 349 350
  // set a constructor to allow creation via Matrix(x,y,z)
  QScriptValue matrix4x4ctor = scriptEngine_.newFunction(createMatrix4x4);
  scriptEngine_.globalObject().setProperty("Matrix4x4", matrix4x4ctor);
351

Jan Möbius's avatar
 
Jan Möbius committed
352 353 354 355 356 357 358
  // Collect Core scripting information
  QScriptValue scriptInstance = scriptEngine_.newQObject(this,
                                                         QScriptEngine::QtOwnership,
                                                         QScriptEngine::ExcludeChildObjects |
                                                         QScriptEngine::ExcludeSuperClassMethods |
                                                         QScriptEngine::ExcludeSuperClassProperties
                                                         );
359

Jan Möbius's avatar
 
Jan Möbius committed
360 361
  scriptEngine_.globalObject().setProperty("core", scriptInstance);
  emit log(LOGOUT,"Core Scripting initialized with Name : core  ");
362

Jan Möbius's avatar
 
Jan Möbius committed
363
  emit log(LOGOUT,"Available scripting functions :");
364

Jan Möbius's avatar
 
Jan Möbius committed
365 366 367
  QScriptValueIterator it(scriptInstance);
  while (it.hasNext()) {
    it.next();
368

Jan Möbius's avatar
 
Jan Möbius committed
369 370 371
    /// Skip all signals for function calls
    if ( checkSignal( this, it.name().toAscii() ) )
      continue;
372

Jan Möbius's avatar
 
Jan Möbius committed
373
    scriptingFunctions_.push_back( "core." + it.name() );
374

Jan Möbius's avatar
 
Jan Möbius committed
375 376
    emit log(LOGOUT,"\t" + it.name());
  }
377

Jan Möbius's avatar
 
Jan Möbius committed
378
  emit log(LOGOUT,"=============================================================================================");
379

Jan Möbius's avatar
 
Jan Möbius committed
380
  loadPlugins();
381

Jan Möbius's avatar
 
Jan Möbius committed
382
  if ( OpenFlipper::Options::gui() ) {
383 384

    if ( OpenFlipper::Options::defaultToolboxMode( ) != "" )
Jan Möbius's avatar
 
Jan Möbius committed
385 386 387
      coreWidget_->setViewMode( OpenFlipper::Options::defaultToolboxMode() );
    else
      coreWidget_->setViewMode("All");
388 389

    connect( coreWidget_->examiner_widget_, SIGNAL(signalMouseEvent(QMouseEvent*)),
Jan Möbius's avatar
 
Jan Möbius committed
390 391 392 393 394
            this,SLOT(slotMouseEvent(QMouseEvent*)));
    connect( coreWidget_->examiner_widget_, SIGNAL(signalMouseEventIdentify(QMouseEvent*)),
            this,SLOT(slotMouseEventIdentify(QMouseEvent*)));
    connect( coreWidget_->examiner_widget_, SIGNAL(signalWheelEvent(QWheelEvent *, const std::string &)),
            this,                           SLOT(slotWheelEvent(QWheelEvent *, const std::string &)));
395

Jan Möbius's avatar
 
Jan Möbius committed
396
  }
397

Jan Möbius's avatar
 
Jan Möbius committed
398 399
  QStringList optionFiles = OpenFlipper::Options::optionFiles();
  for ( int i = 0 ; i < (int)optionFiles.size(); ++i) {
400

Jan Möbius's avatar
 
Jan Möbius committed
401
    if ( OpenFlipper::Options::gui() && OpenFlipper::Options::splash() ) {
402
      splash_->showMessage("Loading Configuration File " + QString::number(i) + "/"  + QString::number(optionFiles.size()) ,
Jan Möbius's avatar
 
Jan Möbius committed
403 404 405
                           Qt::AlignBottom | Qt::AlignLeft , Qt::white);
      QApplication::processEvents();
    }
406

Jan Möbius's avatar
 
Jan Möbius committed
407 408 409
    openIniFile( optionFiles[i] );
  }

410

Jan Möbius's avatar
 
Jan Möbius committed
411 412 413 414 415 416
  if ( OpenFlipper::Options::lang().contains("UTF") || OpenFlipper::Options::lang().contains("utf") ) {
    emit log(LOGWARN,"Warning, OpenFlipper detected that you are using an utf-8 locale!");
    emit log(LOGWARN,"Only OFF files are fully supported with UTF8. Others might fail.");
    emit log(LOGWARN,"You can change your locale by :");
    emit log(LOGWARN,"export LANG=C");
    emit log(LOGWARN,"Work is in progress to resolve this issue.");
417
  }
Jan Möbius's avatar
 
Jan Möbius committed
418 419

  applyOptions();
420

Jan Möbius's avatar
 
Jan Möbius committed
421 422
  if ( OpenFlipper::Options::gui() ) {
    coreWidget_->show();
423

Jan Möbius's avatar
 
Jan Möbius committed
424 425 426
    if ( OpenFlipper::Options::splash() ) {
      splash_->finish(coreWidget_);
    }
427

Jan Möbius's avatar
 
Jan Möbius committed
428
  }
429

Jan Möbius's avatar
 
Jan Möbius committed
430 431 432 433 434 435 436 437
}

//-----------------------------------------------------------------------------

Core::~Core()
{
   for ( uint i = 0 ; i < plugins.size() ; ++i ){
     BaseInterface* basePlugin = qobject_cast< BaseInterface * >(plugins[i].plugin);
438

Jan Möbius's avatar
 
Jan Möbius committed
439 440 441 442 443
     // Dont call exit if we cannot get the Plugin
     if ( basePlugin )
       if ( checkSlot( plugins[i].plugin , "exit()" ) )
          QMetaObject::invokeMethod(plugins[i].plugin, "exit",  Qt::DirectConnection);
  }
444

Jan Möbius's avatar
 
Jan Möbius committed
445 446
  objectRoot_->deleteSubtree();
  delete objectRoot_;
447

Jan Möbius's avatar
 
Jan Möbius committed
448
  // Clean up loggers
449 450 451
  for ( uint i = 0 ; i < loggers_.size(); ++i )
    delete loggers_[i];

Jan Möbius's avatar
 
Jan Möbius committed
452 453 454 455 456 457 458 459 460 461
}

//-----------------------------------------------------------------------------

void
Core::slotMouseEventIdentify( QMouseEvent* _event )
{
  // Dont do anything as a context Menu will popup on right button click
  if ( _event->button() == Qt::RightButton )
    return;
462

Jan Möbius's avatar
 
Jan Möbius committed
463 464 465 466 467 468 469 470 471 472 473 474
  emit PluginMouseEventIdentify( _event );
}

//-----------------------------------------------------------------------------


void
Core::slotMouseEvent( QMouseEvent* _event )
{
  // Dont do anything as a context Menu will popup on right button click
  if ( _event->button() == Qt::RightButton )
    return;
475

Jan Möbius's avatar
 
Jan Möbius committed
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
  emit PluginMouseEvent(_event );
}

//-----------------------------------------------------------------------------

void
Core::slotWheelEvent( QWheelEvent * _event, const std::string & _mode)
{
  emit PluginWheelEvent(_event , _mode );
}

//-----------------------------------------------------------------------------

void
Core::slotAddPickMode( const std::string _mode ) {
  if ( OpenFlipper::Options::gui() )
492
    coreWidget_->examiner_widget_->addPickMode(_mode);
Jan Möbius's avatar
 
Jan Möbius committed
493 494 495 496 497 498 499
}

//-----------------------------------------------------------------------------

void
Core::slotAddHiddenPickMode( const std::string _mode ) {
  if ( OpenFlipper::Options::gui() )
500
    coreWidget_->examiner_widget_->addPickMode(_mode,false,1000,false);
Jan Möbius's avatar
 
Jan Möbius committed
501 502 503 504 505 506 507
}

//-----------------------------------------------------------------------------

void
Core::slotAddPickMode( const std::string _mode , QCursor _cursor) {
  if ( OpenFlipper::Options::gui() )
508
    coreWidget_->examiner_widget_->addPickMode(_mode,false,1000,true,_cursor);
Jan Möbius's avatar
 
Jan Möbius committed
509 510 511 512 513 514 515
}

//-----------------------------------------------------------------------------

void
Core::slotAddHiddenPickMode( const std::string _mode , QCursor _cursor) {
  if ( OpenFlipper::Options::gui() )
516
    coreWidget_->examiner_widget_->addPickMode(_mode,false,1000,false, _cursor);
Jan Möbius's avatar
 
Jan Möbius committed
517 518 519 520 521 522 523 524 525
}



//-----------------------------------------------------------------------------

 /** Update the view in the examiner widget
  */
void Core::updateView() {
526 527 528 529
  if ( true ) {

    // redraw time not reached ... waiting for timer event for next redraw
    if ( redrawTimer_->isActive() ) {
530
//       std::cerr << "Too early for redraw!" << std::endl;
531 532 533
      return;
    }

534
//     std::cerr << "Redraw" << std::endl;
535 536 537 538 539 540 541 542

    // Start the timer if we are not called by the timer
    if ( sender() != redrawTimer_ )
      redrawTimer_->start(35);

  }


Jan Möbius's avatar
 
Jan Möbius committed
543
  if ( OpenFlipper::Options::gui() && !OpenFlipper::Options::openingIni() ) {
Dirk Wilden's avatar
Dirk Wilden committed
544
    coreWidget_->examiner_widget_->sceneGraph(root_node_scenegraph_);
Jan Möbius's avatar
 
Jan Möbius committed
545 546 547 548 549 550
    coreWidget_->examiner_widget_->updateGL();
  }
}

//-----------------------------------------------------------------------------

551 552
void
Core::clearAll()
Jan Möbius's avatar
 
Jan Möbius committed
553 554
{
  objectRoot_->deleteSubtree();
Jan Möbius's avatar
Jan Möbius committed
555
  emit allCleared();
Jan Möbius's avatar
 
Jan Möbius committed
556
  emit ObjectListUpdated(-1);
557

Jan Möbius's avatar
 
Jan Möbius committed
558 559 560 561 562
  slotScriptInfo( "core" , "clearAll()"  );
}

//-----------------------------------------------------------------------------

563 564
void
Core::exitApplication()
Jan Möbius's avatar
 
Jan Möbius committed
565 566 567 568
{
  QTimer* timer = new QTimer();
  connect(timer, SIGNAL(timeout()), this, SLOT(slotExit()));
  timer->start(100);
569

Jan Möbius's avatar
 
Jan Möbius committed
570 571 572 573 574
  QApplication::quit();
}

//-----------------------------------------------------------------------------

575 576
void
Core::setDrawMode(QString _mode)
Jan Möbius's avatar
 
Jan Möbius committed
577
{
578

Jan Möbius's avatar
 
Jan Möbius committed
579 580 581
  QStringList list = _mode.split(';');

  std::vector< QString > drawModeList;
582

Jan Möbius's avatar
 
Jan Möbius committed
583 584
  for ( int i = 0 ; i < list.size() ; ++i )
    drawModeList.push_back(list[i]);
585

Jan Möbius's avatar
 
Jan Möbius committed
586
  unsigned int mode = ListToDrawMode(drawModeList);
587

Jan Möbius's avatar
 
Jan Möbius committed
588 589 590 591 592 593 594 595
  PluginFunctions::setDrawMode( mode );
  emit updateView();
}


//-----------------------------------------------------------------------------

void Core::translate( Vector _vec ) {
596
  PluginFunctions::translate( _vec );
Jan Möbius's avatar
 
Jan Möbius committed
597 598 599 600 601
}

//-----------------------------------------------------------------------------

void Core::rotate( Vector _axis, double _angle, Vector _center ) {
602
  PluginFunctions::rotate( _axis, _angle, _center );
Jan Möbius's avatar
 
Jan Möbius committed
603 604 605 606 607 608 609 610 611 612 613
}

//-----------------------------------------------------------------------------

void Core::setViewingDirection( Vector _direction, Vector _upvector ) {
  PluginFunctions::viewingDirection(_direction, _upvector);
}

//-----------------------------------------------------------------------------

void Core::fullscreen() {
614
  if ( OpenFlipper::Options::gui() )
Jan Möbius's avatar
 
Jan Möbius committed
615 616 617 618 619 620
    coreWidget_->toggleFullscreen();
}

//-----------------------------------------------------------------------------

void Core::logger() {
621
  if ( OpenFlipper::Options::gui() )
Jan Möbius's avatar
 
Jan Möbius committed
622 623 624 625 626 627
    coreWidget_->toggleLogger();
}

//-----------------------------------------------------------------------------

void Core::toolbox() {
628
  if ( OpenFlipper::Options::gui() )
Jan Möbius's avatar
 
Jan Möbius committed
629 630
    coreWidget_->toggleToolbox();
}
631

Jan Möbius's avatar
 
Jan Möbius committed
632 633 634

//-----------------------------------------------------------------------------

635 636
void
Core::slotRecentOpen(QAction* _action)
Jan Möbius's avatar
 
Jan Möbius committed
637 638 639 640 641 642 643 644 645 646
{
  QVector< OpenFlipper::Options::RecentFile > recentFiles = OpenFlipper::Options::recentFiles();
  for (int i = 0 ; i < recentFiles.size() ; ++i )
    if ( recentFiles[i].filename == _action->text() ){
      loadObject(recentFiles[i].type, recentFiles[i].filename);
      break;
    }
}


647
void
Jan Möbius's avatar
 
Jan Möbius committed
648
Core::writeOnExit() {
649
  QString inifile = QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() + ".OpenFlipper" +
Jan Möbius's avatar
 
Jan Möbius committed
650 651 652 653 654
                                                  OpenFlipper::Options::dirSeparator() +  "OpenFlipper.ini";

  INIFile ini;
  if ( ! ini.connect( inifile ,false) ) {
    emit log(LOGERR,"Failed to connect to users ini file");
655

Jan Möbius's avatar
 
Jan Möbius committed
656 657 658
    if ( ! ini.connect( inifile,true) ) {
      emit log(LOGERR,"Can not create user ini file");
    } else {
Dirk Wilden's avatar
Dirk Wilden committed
659
      writeApplicationOptions(ini);
Jan Möbius's avatar
 
Jan Möbius committed
660 661 662
      ini.disconnect();
    }
  } else {
Dirk Wilden's avatar
Dirk Wilden committed
663
    writeApplicationOptions(ini);
Jan Möbius's avatar
 
Jan Möbius committed
664
    ini.disconnect();
665 666
  }

Jan Möbius's avatar
 
Jan Möbius committed
667 668 669 670 671 672 673 674 675 676 677
  // Call exit for all plugins
   for (uint i = 0 ; i < plugins.size() ; ++i) {
      BaseInterface* basePlugin = qobject_cast< BaseInterface * >(plugins[i].plugin);
      if ( basePlugin )
          if ( checkSlot( plugins[i].plugin , "exit()" ) )
            QMetaObject::invokeMethod(plugins[i].plugin, "exit",  Qt::DirectConnection);
   }
}

void Core::slotExit() {
  writeOnExit();
Dirk Wilden's avatar
Dirk Wilden committed
678 679 680 681

  if (logFile_)
    logFile_->close();

Jan Möbius's avatar
 
Jan Möbius committed
682
  qApp->quit();
683
}
Jan Möbius's avatar
 
Jan Möbius committed
684 685 686 687 688 689 690

/// Synchronise two viewers
bool Core::add_sync_host(const QString& _name)
{
  if ( OpenFlipper::Options::gui() ) {
    emit log(LOGINFO,"Adding SyncHost");
    bool ok = coreWidget_->examiner_widget_->add_sync_host(_name);
691
    if (ok)
Jan Möbius's avatar
 
Jan Möbius committed
692 693 694 695 696 697 698 699
      coreWidget_->examiner_widget_->setSynchronization(true);
    else
      emit log(LOGERR,"Sync failed! ");
    return ok;
  }
  return false;
}

Dirk Wilden's avatar
Dirk Wilden committed
700 701 702 703 704 705 706 707 708
/// log to file
void Core::slotLogToFile(Logtype _type, QString _message){

  if (!OpenFlipper::Options::logFileEnabled())
    return;

  if (logStream_ == 0){
    //check if a logfile has been specified
    if (OpenFlipper::Options::logFile() == "")
709
        OpenFlipper::Options::logFile(QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() + ".OpenFlipper" +
Dirk Wilden's avatar
Dirk Wilden committed
710 711 712 713 714 715 716 717 718 719
                                                  OpenFlipper::Options::dirSeparator() +  "OpenFlipper.log");

    logFile_ = new QFile( OpenFlipper::Options::logFile() );
    if ( logFile_->open(QFile::WriteOnly) ) {
        logStream_ = new QTextStream (logFile_);
    }else{
      emit log(LOGERR, "Unable to open logfile!");
      return;
    }
  }
Jan Möbius's avatar
 
Jan Möbius committed
720

Dirk Wilden's avatar
Dirk Wilden committed
721 722 723 724 725 726 727 728 729 730 731 732
  switch (_type) {
    case LOGINFO:
      (*logStream_) << "INFO:"; break;
    case LOGOUT:
      (*logStream_) << "OUT :"; break;
    case LOGWARN:
      (*logStream_) << "WARN:"; break;
    case LOGERR:
      (*logStream_) << "ERR :"; break;
  }

  (*logStream_) << _message << "\n" << flush;
733

Dirk Wilden's avatar
Dirk Wilden committed
734
}
Jan Möbius's avatar
 
Jan Möbius committed
735 736 737


//=============================================================================