Core.cc 33.2 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
 * 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),
  set_random_base_color_(true),
  coreWidget_(0)
{
Dirk Wilden's avatar
Dirk Wilden committed
108
109
110
111
112
  //init logFile
  logStream_ = 0;
  logFile_ = 0;
  OpenFlipper::Options::logFileEnabled(true);

Dirk Wilden's avatar
Dirk Wilden committed
113
114
115
116
  //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
117
118
119
120
121
   // Add ViewMode All
  ViewMode* vm = new ViewMode();
  vm->name = "All";
  vm->custom = false;
  vm->visibleWidgets = QStringList();
122

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

  // Get all relevant Paths and Options from option files
  setupOptions();
127
128
  // set discriptions for scriptable slots
  setDescriptions();
Jan Möbius's avatar
 
Jan Möbius committed
129
130
}

131
132
133
/** \brief Second initialization stage
 *
 * This Stage does the following :\n
Jan Möbius's avatar
 
Jan Möbius committed
134
135
136
137
138
139
 * - 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
 */
140
141
142
void
Core::init() {

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

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

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

152

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

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


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

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
173
174
175
176
177
178
179
    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()));
180
    connect(coreWidget_, SIGNAL(applyOptions())       , this, SLOT(applyOptions()));
Dirk Wilden's avatar
Dirk Wilden committed
181
    connect(coreWidget_, SIGNAL(saveOptions())        , this, SLOT(saveOptions()));
Jan Möbius's avatar
 
Jan Möbius committed
182
183
    connect(coreWidget_, SIGNAL(recentOpen(QAction*)) , this, SLOT(slotRecentOpen(QAction*)));
    connect(coreWidget_, SIGNAL(exit())               , this, SLOT(slotExit()));
184

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

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

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

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


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

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

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

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

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

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

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
227
228
229
    // 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
230
231
    // connection to file logger
    connect(widgetlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
232
  }
233

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

    connect( coreWidget_->examiner_widget_, SIGNAL(signalMouseEvent(QMouseEvent*)),
Jan Möbius's avatar
 
Jan Möbius committed
391
392
393
394
395
            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 &)));
396

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

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

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

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

411

Jan Möbius's avatar
 
Jan Möbius committed
412
413
414
415
416
417
  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.");
418
  }
Jan Möbius's avatar
 
Jan Möbius committed
419
420

  applyOptions();
421

Jan Möbius's avatar
 
Jan Möbius committed
422
  if ( OpenFlipper::Options::gui() ) {
Dirk Wilden's avatar
Dirk Wilden committed
423
424
425
426
427
428

    //try to restore the windowState
    QFile file(QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() + ".OpenFlipper" +
                                                  OpenFlipper::Options::dirSeparator() +  "windowState.dat");
    if (file.open(QIODevice::ReadOnly)){
      QByteArray bytes = file.readAll();
429

Dirk Wilden's avatar
Dirk Wilden committed
430
      coreWidget_->restoreState( bytes );
431

Dirk Wilden's avatar
Dirk Wilden committed
432
433
434
435
436
437
438
439
      file.close();
    }

    //try to restore the geometry
    QFile file2(QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() + ".OpenFlipper" +
                                                  OpenFlipper::Options::dirSeparator() +  "geometry.dat");
    if (file2.open(QIODevice::ReadOnly)){
      QByteArray bytes = file2.readAll();
440

Dirk Wilden's avatar
Dirk Wilden committed
441
      coreWidget_->restoreGeometry( bytes );
442

Dirk Wilden's avatar
Dirk Wilden committed
443
444
445
446
      file2.close();
    }


Jan Möbius's avatar
 
Jan Möbius committed
447
    coreWidget_->show();
448

Jan Möbius's avatar
 
Jan Möbius committed
449
450
451
    if ( OpenFlipper::Options::splash() ) {
      splash_->finish(coreWidget_);
    }
452

Jan Möbius's avatar
 
Jan Möbius committed
453
  }
454

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
464
465
466
467
468
     // 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);
  }
469

Jan Möbius's avatar
 
Jan Möbius committed
470
471
  objectRoot_->deleteSubtree();
  delete objectRoot_;
472

Jan Möbius's avatar
 
Jan Möbius committed
473
  // Clean up loggers
474
475
476
  for ( uint i = 0 ; i < loggers_.size(); ++i )
    delete loggers_[i];

Jan Möbius's avatar
 
Jan Möbius committed
477
478
479
480
481
482
483
484
485
486
}

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

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

Jan Möbius's avatar
 
Jan Möbius committed
488
489
490
491
492
493
494
495
496
497
498
499
  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;
500

Jan Möbius's avatar
 
Jan Möbius committed
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
  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() )
517
    coreWidget_->examiner_widget_->addPickMode(_mode);
Jan Möbius's avatar
 
Jan Möbius committed
518
519
520
521
522
523
524
}

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

void
Core::slotAddHiddenPickMode( const std::string _mode ) {
  if ( OpenFlipper::Options::gui() )
525
    coreWidget_->examiner_widget_->addPickMode(_mode,false,1000,false);
Jan Möbius's avatar
 
Jan Möbius committed
526
527
528
529
530
531
532
}

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

void
Core::slotAddPickMode( const std::string _mode , QCursor _cursor) {
  if ( OpenFlipper::Options::gui() )
533
    coreWidget_->examiner_widget_->addPickMode(_mode,false,1000,true,_cursor);
Jan Möbius's avatar
 
Jan Möbius committed
534
535
536
537
538
539
540
}

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

void
Core::slotAddHiddenPickMode( const std::string _mode , QCursor _cursor) {
  if ( OpenFlipper::Options::gui() )
541
    coreWidget_->examiner_widget_->addPickMode(_mode,false,1000,false, _cursor);
Jan Möbius's avatar
 
Jan Möbius committed
542
543
544
545
546
547
548
549
550
}



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

 /** Update the view in the examiner widget
  */
void Core::updateView() {
Jan Möbius's avatar
Jan Möbius committed
551
552
553
554
555
556
557
558
559

  if ( OpenFlipper::Options::doSlotDebugging() ) {
    if ( sender() != 0 ) {
      if ( sender()->metaObject() != 0 ) {
        emit log(LOGINFO,"updateView() called by " + QString( sender()->metaObject()->className() ) );
      }
    }
  }

560
  if ( OpenFlipper::Options::restrictFrameRate() ) {
561
562
563

    // redraw time not reached ... waiting for timer event for next redraw
    if ( redrawTimer_->isActive() ) {
Jan Möbius's avatar
Jan Möbius committed
564
565
      if ( OpenFlipper::Options::doSlotDebugging() )
        emit log(LOGINFO,"Too early for redraw! Delaying request from " + QString( sender()->metaObject()->className() ) );
566
567
568
      return;
    }

569
//     std::cerr << "Redraw" << std::endl;
570
571

    // Start the timer if we are not called by the timer
Jan Möbius's avatar
Jan Möbius committed
572
    if ( sender() != redrawTimer_ ) {
573
      redrawTimer_->start( 1000 / OpenFlipper::Options::maxFrameRate() );
Jan Möbius's avatar
Jan Möbius committed
574
    }
575
576
577
578

  }


Dirk Wilden's avatar
Dirk Wilden committed
579
  if ( OpenFlipper::Options::gui() && !OpenFlipper::Options::openingIni() && !OpenFlipper::Options::redrawDisabled() ) {
Dirk Wilden's avatar
Dirk Wilden committed
580
    coreWidget_->examiner_widget_->sceneGraph(root_node_scenegraph_);
Jan Möbius's avatar
 
Jan Möbius committed
581
582
583
584
585
586
    coreWidget_->examiner_widget_->updateGL();
  }
}

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

587
588
589
590
591
592
593
594
595
596
597
598
599
void Core::restrictFrameRate( bool _enable ) {
  OpenFlipper::Options::restrictFrameRate( _enable );
}

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

void Core::setMaxFrameRate( int _rate ) {
  OpenFlipper::Options::maxFrameRate( _rate );
  OpenFlipper::Options::restrictFrameRate( true );
}

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

600
601
void
Core::clearAll()
Jan Möbius's avatar
 
Jan Möbius committed
602
603
{
  objectRoot_->deleteSubtree();
Jan Möbius's avatar
Jan Möbius committed
604
  emit allCleared();
Jan Möbius's avatar
 
Jan Möbius committed
605
  emit ObjectListUpdated(-1);
606

Jan Möbius's avatar
 
Jan Möbius committed
607
608
609
610
611
  slotScriptInfo( "core" , "clearAll()"  );
}

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

612
613
void
Core::exitApplication()
Jan Möbius's avatar
 
Jan Möbius committed
614
615
616
617
{
  QTimer* timer = new QTimer();
  connect(timer, SIGNAL(timeout()), this, SLOT(slotExit()));
  timer->start(100);
618

Jan Möbius's avatar
 
Jan Möbius committed
619
620
621
622
623
  QApplication::quit();
}

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

624
625
void
Core::setDrawMode(QString _mode)
Jan Möbius's avatar
 
Jan Möbius committed
626
{
627

Jan Möbius's avatar
 
Jan Möbius committed
628
629
630
  QStringList list = _mode.split(';');

  std::vector< QString > drawModeList;
631

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

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

Jan Möbius's avatar
 
Jan Möbius committed
637
638
639
640
641
642
643
644
  PluginFunctions::setDrawMode( mode );
  emit updateView();
}


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

void Core::translate( Vector _vec ) {
645
  PluginFunctions::translate( _vec );
Jan Möbius's avatar
 
Jan Möbius committed
646
647
648
649
650
}

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

void Core::rotate( Vector _axis, double _angle, Vector _center ) {
651
  PluginFunctions::rotate( _axis, _angle, _center );
Jan Möbius's avatar
 
Jan Möbius committed
652
653
654
655
656
657
658
659
660
661
662
}

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

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

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

void Core::fullscreen() {
663
  if ( OpenFlipper::Options::gui() )
Jan Möbius's avatar
 
Jan Möbius committed
664
665
666
667
668
669
    coreWidget_->toggleFullscreen();
}

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

void Core::logger() {
670
  if ( OpenFlipper::Options::gui() )
Jan Möbius's avatar
 
Jan Möbius committed
671
672
673
674
675
676
    coreWidget_->toggleLogger();
}

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

void Core::toolbox() {
677
  if ( OpenFlipper::Options::gui() )
Jan Möbius's avatar
 
Jan Möbius committed
678
679
    coreWidget_->toggleToolbox();
}
680

Jan Möbius's avatar
 
Jan Möbius committed
681
682
683

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

684
685
void
Core::slotRecentOpen(QAction* _action)
Jan Möbius's avatar
 
Jan Möbius committed
686
687
688
689
690
691
692
693
694
695
{
  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;
    }
}


696
void
Jan Möbius's avatar
 
Jan Möbius committed
697
Core::writeOnExit() {
698
  QString inifile = QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() + ".OpenFlipper" +
Jan Möbius's avatar
 
Jan Möbius committed
699
700
701
702
703
                                                  OpenFlipper::Options::dirSeparator() +  "OpenFlipper.ini";

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

Jan Möbius's avatar
 
Jan Möbius committed
705
706
707
    if ( ! ini.connect( inifile,true) ) {
      emit log(LOGERR,"Can not create user ini file");
    } else {
Dirk Wilden's avatar
Dirk Wilden committed
708
      writeApplicationOptions(ini);
Jan Möbius's avatar
 
Jan Möbius committed
709
710
711
      ini.disconnect();
    }
  } else {
Dirk Wilden's avatar
Dirk Wilden committed
712
    writeApplicationOptions(ini);
Jan Möbius's avatar
 
Jan Möbius committed
713
    ini.disconnect();
714
715
  }

Dirk Wilden's avatar
Dirk Wilden committed
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
  //store the windowState
  if ( OpenFlipper::Options::gui() ) {
    QFile file(QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() + ".OpenFlipper" +
                                                  OpenFlipper::Options::dirSeparator() +  "windowState.dat");
    if (file.open(QIODevice::WriteOnly))
    {
      file.write( coreWidget_->saveState() );
      file.close();
    }
    QFile file2(QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() + ".OpenFlipper" +
                                                  OpenFlipper::Options::dirSeparator() +  "geometry.dat");
    if (file2.open(QIODevice::WriteOnly))
    {
      file2.write( coreWidget_->saveGeometry() );
      file2.close();
    }
  }

Jan Möbius's avatar
 
Jan Möbius committed
734
735
736
737
738
739
740
741
742
743
744
  // 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
745
746
747
748

  if (logFile_)
    logFile_->close();

Jan Möbius's avatar
 
Jan Möbius committed
749
  qApp->quit();
750
}
Jan Möbius's avatar
 
Jan Möbius committed
751
752
753
754
755
756
757

/// 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);
758
    if (ok)
Jan Möbius's avatar
 
Jan Möbius committed
759
760
761
762
763
764
765
766
      coreWidget_->examiner_widget_->setSynchronization(true);
    else
      emit log(LOGERR,"Sync failed! ");
    return ok;
  }
  return false;
}

Dirk Wilden's avatar
Dirk Wilden committed
767
768
769
770
771
772
773
774
775
/// 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() == "")
776
        OpenFlipper::Options::logFile(QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() + ".OpenFlipper" +
Dirk Wilden's avatar
Dirk Wilden committed
777
778
779
780
781
782
783
784
785
786
                                                  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
787

Dirk Wilden's avatar
Dirk Wilden committed
788
789
790
791
792
793
794
795
796
797
798
799
  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;
800

Dirk Wilden's avatar
Dirk Wilden committed
801
}
Jan Möbius's avatar
 
Jan Möbius committed
802

803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
/// set descriptions for a scriptable slot
void Core::slotSetSlotDescription(QString      _slotName,   QString _slotDescription,
                              QStringList _parameters, QStringList _descriptions)
{
  //handle core slots
  if (sender() == this){
    SlotInfo info;
    info.slotName = _slotName;
    info.slotDescription = _slotDescription;
    info.parameters = _parameters;
    info.descriptions = _descriptions;

    coreSlots_.push_back( info );
    return;
  }

  //handle plugin slots

  //find plugin
 PluginInfo* pluginInfo = 0;

  for (uint i=0; i < plugins.size(); i++)
    if (plugins[i].plugin == sender())
      pluginInfo = &plugins[i];

Jan Möbius's avatar
Jan Möbius committed
828
829
    if (pluginInfo == 0){
      emit log(LOGERR, "Unable to set slot-description. Plugin not found!");
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
    return;
  }

  SlotInfo info;
  info.slotName = _slotName;
  info.slotDescription = _slotDescription;
  info.parameters = _parameters;
  info.descriptions = _descriptions;

  pluginInfo->slotInfos.append( info );
}

/// get available Descriptions for a scriptable slot
void Core::slotGetDescription(QString      _function,   QString&     _fnDescription,
                              QStringList& _parameters, QStringList& _descriptions )
{
  QString pluginName = _function.section(".", 0, 0);
  QString slotName   = _function.section(".", 1, 1);

  //handle core slots
  if (pluginName == "core"){

    _fnDescription = "";
    _parameters.clear();
    _descriptions.clear();

    for (int i=0; i < coreSlots_.count(); i++)
      if (coreSlots_[i].slotName == slotName){
      _fnDescription = coreSlots_[i].slotDescription;
      _parameters    = coreSlots_[i].parameters;
      _descriptions  = coreSlots_[i].descriptions;
      return;
      }
    return;
  }

  //handle plugin slots

  //find plugin
  PluginInfo* pluginInfo = 0;

  for (uint i=0; i < plugins.size(); i++)
    if (plugins[i].rpcName == pluginName)
      pluginInfo = &plugins[i];

  if (pluginInfo == 0){
    emit log(LOGERR, "Unable to get slot-description. Plugin not found!");
    return;
  }

  _fnDescription = "";
  _parameters.clear();
  _descriptions.clear();

  //find slot
  for (int i=0; i < pluginInfo->slotInfos.count(); i++)
    if (pluginInfo->slotInfos[i].slotName == slotName){
      _fnDescription = pluginInfo->slotInfos[i].slotDescription;
      _parameters    = pluginInfo->slotInfos[i].parameters;
      _descriptions  = pluginInfo->slotInfos[i].descriptions;
      return;
    }
}

894
895
896
897
898
899
900
901
902
903
904
void Core::snapshotBaseFileName(const QString& _fname){
  if ( OpenFlipper::Options::gui() )
    coreWidget_->examiner_widget_->snapshotBaseFileName(_fname);
}

void Core::snapshot(){
  if ( OpenFlipper::Options::gui() )
    coreWidget_->examiner_widget_->snapshot();

}

Dirk Wilden's avatar
   
Dirk Wilden committed
905
void Core::resizeViewer(int _width, int _height ){
Dirk Wilden's avatar
   
Dirk Wilden committed
906
907
908
909
  if ( OpenFlipper::Options::gui() ){
    //+40 / +20 corresponds to the bottom and right scrollbar
    coreWidget_->examiner_widget_->resize(_width+40, _height+20);
  }
Dirk Wilden's avatar
   
Dirk Wilden committed
910
911
}

912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
/// set the descriptions for scriptable slots of the core
void Core::setDescriptions(){

  connect(this, SIGNAL(setSlotDescription(QString,QString,QStringList,QStringList)),
          this,   SLOT(slotSetSlotDescription(QString,QString,QStringList,QStringList)) );

  emit setSlotDescription("updateView()", "Redraw the contents of the viewer.", QStringList(), QStringList());
  emit setSlotDescription("clearAll()", "Clear all data objects.", QStringList(), QStringList());
  emit setSlotDescription("exitApplication()", "Quit OpenFlipper", QStringList(), QStringList());
  emit setSlotDescription("translate(Vector)", "translate Scene",
                          QStringList("TranslationVector"), QStringList("vector for the translation."));
  emit setSlotDescription("rotate(Vector,double,Vector)", "Rotate Scene",
                          QString("Axis,Angle,Center").split(","),
                          QString("Rotation axis., Rotation Angle., Rotation Center.").split(","));
  emit setSlotDescription("setViewingDirection(Vector,Vector)", "Set the viewing direction",
                          QString("direction,upVector").split(","),
Jan Möbius's avatar
Jan Möbius committed
928
                          QString("Viewing direction., Up-Vector.").split(","));
929
930
931
932
933
934
935
936
937
  emit setSlotDescription("fullscreen()", "Toggle fullscreen mode", QStringList(), QStringList());
  emit setSlotDescription("logger()", "Toggle logging window visibility", QStringList(), QStringList());
  emit setSlotDescription("toolbox()", "Toggle toolbox visibility", QStringList(), QStringList());
  emit setSlotDescription("setDrawMode(QString)", "Set the drawMode",
                        QStringList("DrawMode"), QStringList("the drawMode ( ; separated list )"));
  emit setSlotDescription("restrictFrameRate(bool)", "Restrict FrameRate to MaxFrameRate",
                        QStringList("enabled"), QStringList("restriction switch"));
  emit setSlotDescription("setMaxFrameRate(int)", "set the maximal framerate (automatically enables framerate restriction)",
                        QStringList("frameRate"), QStringList("Maximum frameRate"));
Dirk Wilden's avatar
   
Dirk Wilden committed
938
939
940
941
942
943
  emit setSlotDescription("snapshotBaseFileName(QString&)", "Set a filename for storing snapshots."
                          , QStringList(), QStringList());
  emit setSlotDescription("snapshot()", "Make a snapshot of the viewer. If no filename"
                          " was set using snapshotBaseFileName() the snapshot is stored"
                          " in snap.png in the current directory. For every snapshot"
                          " a counter is added to the filename.", QStringList(), QStringList());
Dirk Wilden's avatar
   
Dirk Wilden committed
944
945
946
947
  emit setSlotDescription("resizeViewer(int,int)", "Resize the viewer",
                           QString("width,height").split(","),
                           QString("new width for the viewer,new height for the viewer").split(","));

948
}
Dirk Wilden's avatar
Dirk Wilden committed
949
// //-----------------------------------------------------------------------------
950
//
Dirk Wilden's avatar
Dirk Wilden committed
951
952
953
954
955
956
// void Core::slotGetPlugin(QString _name, QObject* & _plugin ){
//   for (uint i=0; i < plugins.size(); i++)
//     if (plugins[i].name == _name){
//       _plugin = plugins[i].plugin;
//       return;
//     }
957
//
Dirk Wilden's avatar
Dirk Wilden committed
958
959
960
//   _plugin = 0;
//   return;
// }
Jan Möbius's avatar
 
Jan Möbius committed
961
962

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