viewerControl.cc 41.8 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
40
41
\*===========================================================================*/

42

43
44
45
46
47
48
49
50
51
52
53
54
55
56



//=============================================================================
//
//  CLASS CoreWidget - IMPLEMENTATION
//
//=============================================================================


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

#include "CoreWidget.hh"

57

Matthias Möller's avatar
Matthias Möller committed
58
59
#include <QtConcurrent>

60

61
#include <OpenFlipper/widgets/snapshotDialog/SnapshotDialog.hh>
62
#include <cmath>
63

64
#ifdef _MSC_VER
Jan Möbius's avatar
Jan Möbius committed
65
  #include <ACG/Utils/VSToolsT.hh>
66
67
#endif

68
#include <ACG/Scenegraph/MaterialNode.hh>
69
70
71
72
73
74
75
76
77
78

//== IMPLEMENTATION ==========================================================

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

void CoreWidget::slotToggleStereoMode()
{
  stereoActive_ = !stereoActive_;

  if ( stereoActive_ ) {
79
    statusBar_->showMessage(tr("Stereo enabled"));
Dirk Wilden's avatar
Dirk Wilden committed
80
    stereoButton_->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"stereo.png") );
81
  } else {
82
    statusBar_->showMessage(tr("Stereo disabled"));
Dirk Wilden's avatar
Dirk Wilden committed
83
    stereoButton_->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"mono.png") );
84
85
  }

86
  cursorPainter_->setEnabled (stereoActive_);
87

88
  for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
89
    examiner_widgets_[i]->properties()->stereo(stereoActive_);
90
91
}

Jan Möbius's avatar
Jan Möbius committed
92
93
94
95
96
97
98
void CoreWidget::slotSetGlobalBackgroundColor() {
  ACG::Vec4f bc = PluginFunctions::viewerProperties().backgroundColor() * 255.0;

  QColor backCol((int)bc[0], (int)bc[1], (int)bc[2], (int)bc[3]);
  QColor c = QColorDialog::getColor(backCol,this);

  if (c != backCol && c.isValid())
99
    for ( uint i = 0 ; i < OpenFlipper::Options::examinerWidgets(); ++i )
Jan Möbius's avatar
Jan Möbius committed
100
101
102
103
104
      PluginFunctions::viewerProperties(i).backgroundColor(ACG::Vec4f(((double) c.redF())   ,
                                                                      ((double) c.greenF()) ,
                                                                      ((double) c.blueF())  ,
                                                                        1.0));

105
  OpenFlipperSettings().setValue("Core/Gui/glViewer/defaultBackgroundColor",c);
Jan Möbius's avatar
Jan Möbius committed
106
107
108

}

109
void CoreWidget::slotSetContextBackgroundColor() {
Jan Möbius's avatar
Jan Möbius committed
110
111
112
113
114
115
116
117
118
119
120
121
122
  ACG::Vec4f bc = PluginFunctions::viewerProperties().backgroundColor() * 255.0;

  QColor backCol((int)bc[0], (int)bc[1], (int)bc[2], (int)bc[3]);
  QColor c = QColorDialog::getColor(backCol,this);

  if (c != backCol && c.isValid())
    PluginFunctions::viewerProperties().backgroundColor(ACG::Vec4f(((double) c.redF())   ,
                                                                    ((double) c.greenF()) ,
                                                                    ((double) c.blueF())  ,
                                                                     1.0));
}


123
124
125
126
127
/// Set the viewer to home position
void CoreWidget::slotContextHomeView() {
  examiner_widgets_[PluginFunctions::activeExaminer()]->home();
}

128
129
/// Show / hide wheels in examiner windows
void CoreWidget::slotSwitchWheels(bool _state) {
130
  std::vector< glViewer* >::iterator it = examiner_widgets_.begin();
131

Jan Möbius's avatar
Jan Möbius committed
132
  for(; it != examiner_widgets_.end(); ++it)
133
    _state ? (*it)->slotShowWheels() : (*it)->slotHideWheels();
134
}
135

136
137
138
139
/// Switch navigation mode
void CoreWidget::slotSwitchNavigation(bool _egomode) {
  std::vector< glViewer* >::iterator it = examiner_widgets_.begin();

Jan Möbius's avatar
Jan Möbius committed
140
  for(; it != examiner_widgets_.end(); ++it) {
Mike Kremer's avatar
Mike Kremer committed
141
    _egomode ? (*it)->navigationMode(glViewer::FIRSTPERSON_NAVIGATION) :
142
143
144
145
    	(*it)->navigationMode(glViewer::NORMAL_NAVIGATION);
  }
}

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/// Set the viewer to home position
void CoreWidget::slotGlobalHomeView() {
  for ( int i = 0 ; i < PluginFunctions::viewers() ; ++i )
    examiner_widgets_[i]->home();
}

/// Set the viewers home position
void CoreWidget::slotContextSetHomeView() {
  examiner_widgets_[PluginFunctions::activeExaminer()]->setHome();
}


/// Set the home position for all viewers
void CoreWidget::slotGlobalSetHomeView() {
  for ( int i = 0 ; i < PluginFunctions::viewers() ; ++i )
    examiner_widgets_[i]->setHome();
}

/// Change view on active viewer to view complete scene
void CoreWidget::slotContextViewAll() {
  examiner_widgets_[PluginFunctions::activeExaminer()]->viewAll();
}


/// Change view on all viewers to view complete scene
void CoreWidget::slotGlobalViewAll() {
  for ( int i = 0 ; i < PluginFunctions::viewers() ; ++i )
    examiner_widgets_[i]->viewAll();
}

176
/// Toggle projection mode of the active viewer
177
178
179
180
void CoreWidget::slotContextSwitchProjection() {
  examiner_widgets_[PluginFunctions::activeExaminer()]->toggleProjectionMode();
}

181
182
183
184
185
186
187
188
189
190
191
192
193
194
/// Toggle coordsys projection mode of the active viewer
ACG::SceneGraph::CoordsysNode::ProjectionMode CoreWidget::getCoordsysProjection() {  
    // Find coordsys node
    ACG::SceneGraph::BaseNode* node = 0;
    node = PluginFunctions::getSceneGraphRootNode()->find("Core Coordsys Node");
    if (node != 0) {
	return dynamic_cast<ACG::SceneGraph::CoordsysNode*> (node)->getProjectionMode();
    } else {
        emit statusMessage(QString(tr("getCoordsysProjection(): Could not find coordsys node. Assuming default orthographic projection.")));
	return ACG::SceneGraph::CoordsysNode::ORTHOGRAPHIC_PROJECTION;
    }
}

/// Toggle coordsys projection mode of the active viewer
195
void CoreWidget::slotContextSwitchCoordsysProjection() {
196
197
198
199
    // Find coordsys node
    ACG::SceneGraph::BaseNode* node = 0;
    node = PluginFunctions::getSceneGraphRootNode()->find("Core Coordsys Node");
    if (node != 0) {
200
201
202
203
204
205
206
        ACG::SceneGraph::CoordsysNode* cnode = dynamic_cast<ACG::SceneGraph::CoordsysNode*> (node);
        if (cnode->getProjectionMode() == ACG::SceneGraph::CoordsysNode::PERSPECTIVE_PROJECTION) {
            cnode->setProjectionMode(ACG::SceneGraph::CoordsysNode::ORTHOGRAPHIC_PROJECTION);
        }
        else {
            cnode->setProjectionMode(ACG::SceneGraph::CoordsysNode::PERSPECTIVE_PROJECTION);
        }
207
208
209
    } else {
        emit statusMessage(QString(tr("slotContextSwitchCoordsysProjection(): Could not find coordsys node, thus its projection mode will not be toggled.")));
    }
210
211
212

    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
        examiner_widgets_[i]->updateGL();
213
214
}

215
/// Toggle projection mode of all viewers to perspective projection
216
217
218
219
220
void CoreWidget::slotGlobalPerspectiveProjection() {
  for ( int i = 0 ; i < PluginFunctions::viewers() ; ++i )
    examiner_widgets_[i]->perspectiveProjection();
}

221
/// Toggle projection mode of all viewers to orthogonal projection
222
223
224
225
226
void CoreWidget::slotGlobalOrthographicProjection() {
  for ( int i = 0 ; i < PluginFunctions::viewers() ; ++i )
    examiner_widgets_[i]->orthographicProjection();
}

227
228
229
230
231
232
233
234
235
236
237
238
239
240

/// If animation is disabled in all viewers, enable it in all viewers. Otherwise disable it.
void CoreWidget::slotGlobalToggleAnimation() {
  int enabledCount  = 0;

  for ( int i = 0 ; i< PluginFunctions::viewers(); ++i ) {
    if ( PluginFunctions::viewerProperties(i).animation() )
      enabledCount++;
  }
  
  slotGlobalChangeAnimation (enabledCount == 0);
}

/// Set the animation mode for all viewers
241
242
243
244
245
void CoreWidget::slotGlobalChangeAnimation(bool _animation){
  for ( uint i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
    PluginFunctions::viewerProperties(i).animation(_animation);
}

246
/// Set the animation mode for active viewer
247
248
249
250
void CoreWidget::slotLocalChangeAnimation(bool _animation){
  PluginFunctions::viewerProperties().animation(_animation);
}

251
252
253
254
255
256
257
258
259
260
261
262
263
264

/// If backface culling is disabled in all viewers, enable it in all viewers. Otherwise disable it.
void CoreWidget::slotGlobalToggleBackFaceCulling() {
  int enabledCount  = 0;

  for ( int i = 0 ; i< PluginFunctions::viewers(); ++i ) {
    if ( PluginFunctions::viewerProperties(i).backFaceCulling() )
      enabledCount++;
  }
  
  slotGlobalChangeBackFaceCulling (enabledCount == 0);
}

/// Set backface culling for all viewers
265
266
267
void CoreWidget::slotGlobalChangeBackFaceCulling(bool _backFaceCulling){
  for ( uint i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
    PluginFunctions::viewerProperties(i).backFaceCulling(_backFaceCulling);
268

269
270
}

271
/// Set backface culling for active viewer
272
273
274
275
276
void CoreWidget::slotLocalChangeBackFaceCulling(bool _backFaceCulling){
  PluginFunctions::viewerProperties().backFaceCulling(_backFaceCulling);
}


277
278
279
280
281
282
283
284
285
286
287
288
289
/// If two-sided lighting is disabled in all viewers, enable it in all viewers. Otherwise disable it.
void CoreWidget::slotGlobalToggleTwoSidedLighting() {
  int enabledCount  = 0;

  for ( int i = 0 ; i< PluginFunctions::viewers(); ++i ) {
    if ( PluginFunctions::viewerProperties(i).twoSidedLighting() )
      enabledCount++;
  }
  
  slotGlobalChangeTwoSidedLighting (enabledCount == 0);
}

/// Set two-sided lighting for all viewers
290
291
292
293
294
void CoreWidget::slotGlobalChangeTwoSidedLighting(bool _lighting) {
  for ( uint i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
    PluginFunctions::viewerProperties(i).twoSidedLighting(_lighting);
}

295
/// Set two-sided lighting for active viewer
296
297
298
299
void CoreWidget::slotLocalChangeTwoSidedLighting(bool _lighting) {
  PluginFunctions::viewerProperties().twoSidedLighting(_lighting);
}

300
301
302
303
304
305
306
307
308
309
310
311
312
313

/// If multisampling is disabled in all viewers, enable it in all viewers. Otherwise disable it.
void CoreWidget::slotGlobalToggleMultisampling() {
  int enabledCount  = 0;

  for ( int i = 0 ; i< PluginFunctions::viewers(); ++i ) {
    if ( PluginFunctions::viewerProperties(i).multisampling() )
      enabledCount++;
  }
  
  slotGlobalChangeMultisampling (enabledCount == 0);
}

/// Set multisampling for all viewers
314
315
316
317
318
void CoreWidget::slotGlobalChangeMultisampling(bool _multisampling) {
  for ( uint i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
    PluginFunctions::viewerProperties(i).multisampling( _multisampling );
}

319
/// Set multisampling for active viewer
320
321
322
323
void CoreWidget::slotLocalChangeMultisampling(bool _multisampling) {
  PluginFunctions::viewerProperties().multisampling( _multisampling );
}

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

/// If mipmapping is disabled in all viewers, enable it in all viewers. Otherwise disable it.
void CoreWidget::slotGlobalToggleMipmapping() {
  int enabledCount  = 0;

  for ( int i = 0 ; i< PluginFunctions::viewers(); ++i ) {
    if ( PluginFunctions::viewerProperties(i).mipmapping() )
      enabledCount++;
  }
  
  slotGlobalChangeMipmapping (enabledCount == 0);
}

/// Set mipmapping for all viewers
void CoreWidget::slotGlobalChangeMipmapping(bool _mipmapping) {
  for ( uint i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
    PluginFunctions::viewerProperties(i).mipmapping( _mipmapping );
}

/// Set mipmapping for active viewer
Mike Kremer's avatar
Mike Kremer committed
344
345
346
347
void CoreWidget::slotLocalChangeMipmapping(bool _mipmapping) {
  PluginFunctions::viewerProperties().mipmapping( _mipmapping );
}

Dirk Wilden's avatar
Dirk Wilden committed
348
/// Take a snapshot of the current Viewer
349
void CoreWidget::slotExaminerSnapshot() {
Dirk Wilden's avatar
Dirk Wilden committed
350
351
352
353

  QFileInfo fi(PluginFunctions::viewerProperties().snapshotName());
  int counter = PluginFunctions::viewerProperties().snapshotCounter();

Jan Möbius's avatar
Jan Möbius committed
354
355
356
357
358
359
    // Add leading zeros
  QString number = QString::number(counter);
  while ( number.size() < 7 )
    number = "0" + number;

  QString suggest = fi.baseName() + "." + number + ".";
Dirk Wilden's avatar
Dirk Wilden committed
360
361
362
363
364
365

  QString format="png";

  if (fi.completeSuffix() == "ppm")
    format="ppmraw";

Jan Möbius's avatar
Jan Möbius committed
366
367
368
  if (fi.completeSuffix() == "jpg")
    format="jpg";

Dirk Wilden's avatar
Dirk Wilden committed
369
370
  suggest += format;

Dirk Wilden's avatar
Dirk Wilden committed
371
372
373
  QFileDialog dialog(this);
  dialog.setFileMode(QFileDialog::AnyFile);
  dialog.setDefaultSuffix("png");
374
  dialog.setNameFilter(tr("Images (*.png *.ppm *.jpg)"));
Dirk Wilden's avatar
Dirk Wilden committed
375
  dialog.setFileMode(QFileDialog::AnyFile);
376
  dialog.setOption(QFileDialog::DontConfirmOverwrite, false);
Dirk Wilden's avatar
Dirk Wilden committed
377
378
379
  dialog.setDirectory( fi.path() );
  dialog.selectFile( suggest );
  dialog.setAcceptMode(QFileDialog::AcceptSave);
380
  dialog.setWindowTitle(tr("Save Snapshot"));
Dirk Wilden's avatar
Dirk Wilden committed
381

Dirk Wilden's avatar
Dirk Wilden committed
382
383
384
385
386
 if (dialog.exec()){
     QString newName = dialog.selectedFiles()[0];

      if (newName != fi.path() + OpenFlipper::Options::dirSeparator() + suggest)
        PluginFunctions::viewerProperties().snapshotBaseFileName(newName);
Dirk Wilden's avatar
Dirk Wilden committed
387

Dirk Wilden's avatar
Dirk Wilden committed
388
389
      QImage image;
      examiner_widgets_[PluginFunctions::activeExaminer()]->snapshot(image);
Dirk Wilden's avatar
Dirk Wilden committed
390

Dirk Wilden's avatar
Dirk Wilden committed
391
      image.save(newName);
Dirk Wilden's avatar
Dirk Wilden committed
392
393
394
  }
}

395
396
static QString suggestSnapshotFilename(QString mostRecentPath) {
    if (mostRecentPath.isEmpty()) {
397
        mostRecentPath = QString("%1%2snap.0000000.png")
398
399
400
            .arg(OpenFlipperSettings().value("Core/CurrentDir").toString())
            .arg(QDir::separator());
    }
Dirk Wilden's avatar
Dirk Wilden committed
401

402
403
    QFileInfo fi(mostRecentPath);
    QString path = fi.path();
Dirk Wilden's avatar
Dirk Wilden committed
404

405
406
407
408
409
410
411
    if (!fi.exists() && QFileInfo(path).isWritable()) {
#ifndef NDEBUG
        std::cout << "suggestSnapshotFilename(): mostRecentPath feasible as "
                "file name. Using it." << std::endl;
#endif
        return mostRecentPath;
    }
Jan Möbius's avatar
Jan Möbius committed
412

413
414
415
416
417
    if (!QFileInfo(path).isWritable()) {
#ifndef NDEBUG
        std::cout << "suggestSnapshotFilename(): Most recent path invalid. "
                "Doesn't exist. Returning empty string." << std::endl;
#endif
418
        return QString();
419
    }
Dirk Wilden's avatar
Dirk Wilden committed
420

421
422
    QString base_name = fi.completeBaseName();
    QString suffix = fi.suffix();
Dirk Wilden's avatar
Dirk Wilden committed
423

424
425
    if (suffix.isEmpty())
        suffix = "png";
Dirk Wilden's avatar
Dirk Wilden committed
426

427
428
429
430
431
432
433
    QRegExp base_name_re("(\\D*)(\\d+)?(.*)");
    base_name_re.setPatternSyntax(QRegExp::RegExp2);
    if (!base_name_re.exactMatch(base_name)) {
#ifndef NDEBUG
        std::cout << "suggestSnapshotFilename(): Regexp didn't match. This "
            "should be impossible." << std::endl;
#endif
434
        return QString();
435
    }
Jan Möbius's avatar
Jan Möbius committed
436

437
438
439
440
441
    QString pre = base_name_re.cap(1),
            num = base_name_re.cap(2),
            post = base_name_re.cap(3);

#ifndef NDEBUG
442
    std::cout << (QString("suggestSnapshotFilename(): Decomposition of "
443
444
445
446
447
448
        "\"%1\": \"%2\", \"%3\", \"%4\"")
            .arg(base_name)
            .arg(pre)
            .arg(num)
            .arg(post)).toStdString() << std::endl;
#endif
Dirk Wilden's avatar
Dirk Wilden committed
449

450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
    if (pre.isEmpty() && num.isEmpty() && post.isEmpty()) {
        pre = "snap.";
    }

    size_t num_len = num.length();
    bool num_is_int;
    int file_no = num.toInt(&num_is_int);
    if (!num_is_int) {
        file_no = 0;
        num_len = 6;
    }

    size_t sanity_counter = 0;
    for (; sanity_counter < 100000; ++file_no, ++sanity_counter) {
        QString suggested_file_name =
465
                QString("%1%2%3%4%5.%6")
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
                .arg(path)
                .arg(QDir::separator())
                .arg(pre)
                .arg(file_no, num_len, 10, QLatin1Char('0'))
                .arg(post)
                .arg(suffix)
                ;
        QFileInfo suggested_fi(suggested_file_name);
        if (!suggested_fi.exists()){
#ifndef NDEBUG
            std::cout << "suggestSnapshotFilename(): Found a feasible file "
                    "name. Returning it." << std::endl;
#endif
            return suggested_file_name;
        }
    }

#ifndef NDEBUG
    std::cout << "suggestSnapshotFilename(): No luck incrementing file_no. "
            "Aborting, returning empty string." << std::endl;
#endif
487
    return QString();
488
489
490
491
}

///Take a snapshot of the whole application
void CoreWidget::applicationSnapshotDialog() {
492
493
494
  int w = width();
  int h = height();

495
  SnapshotDialog dialog(suggestSnapshotFilename(snapshotName_), false, w, h, 0);
496
  
497
498
499
  connect(&dialog, SIGNAL(resizeApplication(int,int)), this, SIGNAL(resizeApplication(int,int)) );

  bool ok = dialog.exec();
500
501

  if ( ok ){
502
    QString newName = dialog.filename->text();
Dirk Wilden's avatar
Dirk Wilden committed
503

504
    OpenFlipperSettings().setValue("Core/CurrentDir", QFileInfo(newName).absolutePath() );
505
      
506
    snapshotName_ = newName;
Jan's avatar
Jan committed
507
508
    dialog.hide();

509
510
511
512
513
514
    #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
      QScreen* screen = window()->screen();
      QPixmap pic = screen->grabWindow( winId() );
    #else
      QPixmap pic = QPixmap::grabWindow( winId() );
    #endif
Dirk Wilden's avatar
Dirk Wilden committed
515

516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
    QPainter painter (&pic);

    //so we have to add the content from the GLContext manually
    for (std::vector< glViewer* >::iterator iter = examiner_widgets_.begin(); iter != examiner_widgets_.end(); ++iter)
    {
      if (*iter)
      {
        QImage fillImage;

        (*iter)->snapshot(fillImage, (*iter)->glWidth() , (*iter)->glHeight());

        QPoint localPos = QPoint((*iter)->pos().x(),(*iter)->pos().y());
        QPointF pos = glView_->mapTo(this,localPos);
        painter.drawImage(pos,fillImage);
      }
    }

Dirk Wilden's avatar
Dirk Wilden committed
533
534
    pic.save(newName);
  }
535
536

  emit resizeApplication(w,h);
Dirk Wilden's avatar
Dirk Wilden committed
537
538
539
540
}

///Take a snapshot of the whole application
void CoreWidget::applicationSnapshot() {
541
542
543
544
545

  #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
    QScreen* screen = window()->screen();
    QPixmap pix = screen->grabWindow( winId() );
  #else
Jan's avatar
Jan committed
546
    QPixmap pix = QPixmap::grabWindow( winId() );
547
  #endif
Jan's avatar
Jan committed
548

549
  // Write image asynchronously
Jan's avatar
Jan committed
550
  QImage* pic = new QImage( pix.toImage() );
551
  writeImageAsynchronously(pic, suggestSnapshotFilename(snapshotName_));
552
553
}

554
void CoreWidget::viewerSnapshot(QString file_name, bool store_comments,
555
        bool comments_visible_only, bool comments_targeted_only,
556
        bool store_material_info, int snapshot_width, int snapshot_height,
557
558
559
560
561
562
        bool snapshot_transparent, bool hide_coord_sys,
        int snapshot_multisampling, bool store_view) {

    if (snapshot_height < 0) {
        int w = glView_->width();
        int h = glView_->height();
563
        snapshot_height = static_cast<int>(round(
564
                static_cast<double>(snapshot_width) / w * h));
565
    }
Dirk Wilden's avatar
Dirk Wilden committed
566

567
    QString comments;
568
    if (store_comments) {
569
        comments = PluginFunctions::collectObjectComments(
570
571
                comments_visible_only,
                comments_targeted_only).join("\n");
572
573
    }

574
    QString materials;
575
576
    if (ACG::SceneGraph::Material::support_json_serialization() &&
    //if (ACG::SceneGraph::Material::CP_JSON_SERIALIZABLE &&
577
            store_material_info) {
578
        materials = PluginFunctions::collectObjectMaterials(
579
580
                comments_visible_only,
                comments_targeted_only).join("\n");
581
582
    }

Dirk Wilden's avatar
Dirk Wilden committed
583
584
585
586
587
588
589
    //now take the snapshot
    switch ( baseLayout_->mode() ){

      case QtMultiViewLayout::SingleView:
      {
        QImage finalImage;

590
        examiner_widgets_[PluginFunctions::activeExaminer()]->snapshot(finalImage,
591
592
593
            snapshot_width, snapshot_height,
            snapshot_transparent, hide_coord_sys,
            snapshot_multisampling);
Dirk Wilden's avatar
Dirk Wilden committed
594

595
596
        if (!comments.isEmpty())
            finalImage.setText("Mesh Comments", comments);
597
598
        if (!materials.isEmpty())
            finalImage.setText("Mesh Materials", materials);
599
        if (store_view) {
600
601
            QSize window_size;
            if (isMaximized())
602
              window_size = QSize(-width(), -height());
603
            else
604
              window_size = QSize (width(), height());
605
606
607
608
609
610
611
612
613
614
615

            int splitter_size = 0;
            if (OpenFlipperSettings().value("Core/Gui/ToolBoxes/ToolBoxOnTheRight",true).toBool())
              splitter_size = toolSplitter_->sizes()[1];
            else
              splitter_size = toolSplitter_->sizes()[0];

            QString view;
            examiner_widgets_[PluginFunctions::activeExaminer()]->encodeView(view, window_size, splitter_size);
            finalImage.setText("View", view);
        }
616
        finalImage.save(file_name);
Dirk Wilden's avatar
Dirk Wilden committed
617
618
619

        break;
      }
Jan Möbius's avatar
Jan Möbius committed
620
621
      case QtMultiViewLayout::DoubleView:
      {
622
        int w = snapshot_height;
Jan Möbius's avatar
Jan Möbius committed
623

624
        double relSizeW = static_cast<double>( examiner_widgets_[0]->glWidth() / static_cast<double>( glScene_->width() ) );
Jan Möbius's avatar
Jan Möbius committed
625

626
627
628
629
630
631
632
633
634
635
        //Get the images
        QImage img[2];
        examiner_widgets_[0]->snapshot(
                img[0], static_cast<int>(relSizeW * w),
                snapshot_width, snapshot_transparent,
                hide_coord_sys);
        examiner_widgets_[1]->snapshot(
                img[1], static_cast<int>(relSizeW * w),
                snapshot_width, snapshot_transparent,
                hide_coord_sys);
Jan Möbius's avatar
Jan Möbius committed
636

637
638
        QImage finalImage(img[0].width() + img[1].width() +2, img[0].height(),
                QImage::Format_ARGB32_Premultiplied);
Jan Möbius's avatar
Jan Möbius committed
639

640
        QPainter painter(&finalImage);
Jan Möbius's avatar
Jan Möbius committed
641

642
643
        painter.fillRect(0,0,finalImage.width(),
                finalImage.height(), QBrush(Qt::gray));
Jan Möbius's avatar
Jan Möbius committed
644

645
646
647
648
        painter.drawImage(QRectF(           0,     0, img[0].width(), img[0].height()),img[0],
                          QRectF(           0,     0, img[0].width(), img[0].height()) );
        painter.drawImage(QRectF(img[0].width()+2, 0, img[1].width(), img[1].height()),img[1],
                          QRectF(           0,     0, img[1].width(), img[1].height()) );
Jan Möbius's avatar
Jan Möbius committed
649

650
651
        if (!comments.isEmpty())
            finalImage.setText("Mesh Comments", comments);
652
        finalImage.save(file_name);
Jan Möbius's avatar
Jan Möbius committed
653

654
        break;
Jan Möbius's avatar
Jan Möbius committed
655
656
      }

Dirk Wilden's avatar
Dirk Wilden committed
657
658
      case QtMultiViewLayout::Grid:
      {
659
660
661
662
        // Relative size of first viewer (in relation to the other viewers
        double relSizeW = (double)examiner_widgets_[0]->glWidth() / (double)glScene_->width();
        double relSizeH = (double)examiner_widgets_[0]->glHeight() / (double)glScene_->height();
          
Dirk Wilden's avatar
Dirk Wilden committed
663
664
        QImage img0,img1,img2,img3;

665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
        examiner_widgets_[0]->snapshot(img0,
                (int)((double)snapshot_width * relSizeW),
                (int)((double)snapshot_height * relSizeH),
                snapshot_transparent, hide_coord_sys);
        examiner_widgets_[1]->snapshot(img1,
                (int)((double)snapshot_width * (1.0 - relSizeW)),
                (int)((double)snapshot_height * relSizeH),
                snapshot_transparent, hide_coord_sys);
        examiner_widgets_[2]->snapshot(img2,
                (int)((double)snapshot_width * relSizeW),
                (int)((double)snapshot_height * (1.0 - relSizeH)),
                snapshot_transparent, hide_coord_sys);
        examiner_widgets_[3]->snapshot(img3,
                (int)((double)snapshot_width * (1.0 - relSizeW)),
                (int)((double)snapshot_height * (1.0 - relSizeH)),
                snapshot_transparent, hide_coord_sys);

        QImage finalImage(img0.width() + img1.width()+2,
                img0.height() + img2.height()+2,
                QImage::Format_ARGB32_Premultiplied);
Dirk Wilden's avatar
Dirk Wilden committed
685
686

        QPainter painter(&finalImage);
687
688
689

        painter.fillRect(0,0,finalImage.width(), finalImage.height(), QBrush(Qt::gray));

Dirk Wilden's avatar
Dirk Wilden committed
690
691
        painter.drawImage(QRectF(           0,             0, img0.width(), img0.height()),img0,
                          QRectF(           0,             0, img0.width(), img0.height()) );
692
        painter.drawImage(QRectF(img0.width()+2,           0, img1.width(), img1.height()),img1,
Dirk Wilden's avatar
Dirk Wilden committed
693
                          QRectF(           0,             0, img1.width(), img1.height()) );
694
        painter.drawImage(QRectF(          0,img0.height()+2, img2.width(), img2.height()),img2,
Dirk Wilden's avatar
Dirk Wilden committed
695
                          QRectF(           0,             0, img2.width(), img2.height()) );
696
        painter.drawImage(QRectF(img0.width()+2, img0.height()+2, img3.width(), img3.height()),img3,
Dirk Wilden's avatar
Dirk Wilden committed
697
698
                          QRectF(           0,             0, img3.width(), img3.height()) );

699
700
        if (!comments.isEmpty())
            finalImage.setText("Mesh Comments", comments);
701
        finalImage.save(file_name);
Dirk Wilden's avatar
Dirk Wilden committed
702
703
704
705
706

        break;
      }
      case QtMultiViewLayout::HSplit:
      {
707
708
709
710
711
712
        // Relative size of first viewer (in relation to the other viewers
        double relSizeW = (double)examiner_widgets_[0]->glWidth() / (double)glScene_->width();
        double relSizeH1 = (double)examiner_widgets_[1]->glHeight() / (double)glScene_->height();
        double relSizeH2 = (double)examiner_widgets_[2]->glHeight() / (double)glScene_->height();
        double relSizeH3 = (double)examiner_widgets_[3]->glHeight() / (double)glScene_->height();
          
Dirk Wilden's avatar
Dirk Wilden committed
713
714
        QImage img0,img1,img2,img3;

715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
        examiner_widgets_[0]->snapshot(img0,
                (int)((double)snapshot_width * relSizeW), snapshot_height,
                snapshot_transparent, hide_coord_sys);
        examiner_widgets_[1]->snapshot(img1,
                (int)((double)snapshot_width * (1.0 - relSizeW)),
                relSizeH1 * (double)snapshot_height,
                snapshot_transparent, hide_coord_sys);
        examiner_widgets_[2]->snapshot(img2,
                (int)((double)snapshot_width * (1.0 - relSizeW)),
                relSizeH2 * (double)snapshot_height,
                snapshot_transparent, hide_coord_sys);
        examiner_widgets_[3]->snapshot(img3,
                (int)((double)snapshot_width * (1.0 - relSizeW)),
                relSizeH3 * (double)snapshot_height,
                snapshot_transparent, hide_coord_sys);
Dirk Wilden's avatar
Dirk Wilden committed
730

731
        QImage finalImage(img0.width() + img1.width() +2, img0.height(), QImage::Format_ARGB32_Premultiplied);
Dirk Wilden's avatar
Dirk Wilden committed
732
733

        QPainter painter(&finalImage);
734
735
736

        painter.fillRect(0,0,finalImage.width(), finalImage.height(), QBrush(Qt::gray));

Dirk Wilden's avatar
Dirk Wilden committed
737
738
        painter.drawImage(QRectF(           0,             0, img0.width(), img0.height()),img0,
                          QRectF(           0,             0, img0.width(), img0.height()) );
739
        painter.drawImage(QRectF(img0.width()+2,             0, img1.width(), img1.height()),img1,
Dirk Wilden's avatar
Dirk Wilden committed
740
                          QRectF(           0,             0, img1.width(), img1.height()) );
741
        painter.drawImage(QRectF(img0.width()+2, img1.height()+2, img2.width(), img2.height()),img2,
Dirk Wilden's avatar
Dirk Wilden committed
742
                          QRectF(           0,             0, img2.width(), img2.height()) );
743
        painter.drawImage(QRectF(img0.width()+2, img1.height()+img2.height()+4, img3.width(),img3.height()),img3,
Dirk Wilden's avatar
Dirk Wilden committed
744
745
                          QRectF(           0,             0, img3.width(), img3.height()) );

746
747
        if (!comments.isEmpty())
            finalImage.setText("Mesh Comments", comments);
748
        finalImage.save(file_name);
Dirk Wilden's avatar
Dirk Wilden committed
749
750
751
752
753
754

        break;
      }
      default: break;

    }
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
}

///Take a snapshot of all viewers
void CoreWidget::viewerSnapshotDialog() {
  int w = glView_->width();
  int h = glView_->height();

  SnapshotDialog dialog(suggestSnapshotFilename(snapshotName_), true, w, h, 0);

  if (!ACG::SceneGraph::Material::support_json_serialization())
      dialog.metaData_storeMatInfo_cb->setVisible(false);

  bool ok = dialog.exec();

  if (ok){
    QString newName = dialog.filename->text();

    OpenFlipperSettings().setValue("Core/CurrentDir", QFileInfo(newName).absolutePath() );

    snapshotName_ = newName;

    const bool storeComments = dialog.metaData_storeComments_cb->isChecked();
    const bool comments_visible_only =
            dialog.metaData_comments_visibleOnly_cb->isChecked();
    const bool comments_targeted_only =
            dialog.metaData_comments_targetedOnly_cb->isChecked();
    const bool store_material_info =
            dialog.metaData_storeMatInfo_cb->isChecked();
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
783
784
    const int snapshot_width = dialog.snapWidth->value();
    const int snapshot_height = dialog.snapHeight->value();
785
786
787
788
789
790
791
792
793
794
795
    const bool snapshot_transparent = dialog.transparent->isChecked();
    const bool hide_coord_sys = dialog.hideCoordsys->isChecked();
    const int snapshot_multisampling =
            dialog.multisampling->isChecked() ?
                    dialog.num_samples->value() : 1;
    const bool store_view = dialog.metaData_storeView_cb->isChecked();

    viewerSnapshot(newName, storeComments, comments_visible_only,
            comments_targeted_only, store_material_info, snapshot_width,
            snapshot_height, snapshot_transparent, hide_coord_sys,
            snapshot_multisampling, store_view);
Dirk Wilden's avatar
Dirk Wilden committed
796
  }
797
  //glView_->resize(w, h);
Dirk Wilden's avatar
Dirk Wilden committed
798
799
}

Dirk Wilden's avatar
Dirk Wilden committed
800
///Take a snapshot of all viewers
Dirk Wilden's avatar
Dirk Wilden committed
801
802
void CoreWidget::viewerSnapshot() {

803
    switch ( baseLayout_->mode() ){
Dirk Wilden's avatar
Dirk Wilden committed
804
805
806

    case QtMultiViewLayout::SingleView:
    {
807
      QImage* finalImage = new QImage();
Dirk Wilden's avatar
Dirk Wilden committed
808

809
      examiner_widgets_[PluginFunctions::activeExaminer()]->snapshot(*finalImage);
Dirk Wilden's avatar
Dirk Wilden committed
810

811
      writeImageAsynchronously(finalImage, suggestSnapshotFilename(snapshotName_));
Dirk Wilden's avatar
Dirk Wilden committed
812
813
814

      break;
    }
Jan Möbius's avatar
Jan Möbius committed
815
816
817
818
819
820
821
    case QtMultiViewLayout::DoubleView:
    {
    	//Get the images
    	QImage img[2];
    	examiner_widgets_[0]->snapshot(img[0]);
    	examiner_widgets_[1]->snapshot(img[1]);

Jan Möbius's avatar
Jan Möbius committed
822
    	QImage* finalImage = new QImage(img[0].width() + img[1].width() +2, img[0].height(), QImage::Format_ARGB32_Premultiplied);
Jan Möbius's avatar
Jan Möbius committed
823

Jan Möbius's avatar
Jan Möbius committed
824
    	QPainter painter(finalImage);
Jan Möbius's avatar
Jan Möbius committed
825

Jan Möbius's avatar
Jan Möbius committed
826
    	painter.fillRect(0,0,finalImage->width(), finalImage->height(), QBrush(Qt::gray));
Jan Möbius's avatar
Jan Möbius committed
827
828

    	painter.drawImage(QRectF(           0,             0, img[0].width(), img[0].height()),img[0],
Jan Möbius's avatar
Jan Möbius committed
829
    			              QRectF(           0,             0, img[0].width(), img[0].height()) );
Jan Möbius's avatar
Jan Möbius committed
830
    	painter.drawImage(QRectF(img[0].width()+2,         0, img[1].width(), img[1].height()),img[1],
Jan Möbius's avatar
Jan Möbius committed
831
    	              		QRectF(           0,             0, img[1].width(), img[1].height()) );
Jan Möbius's avatar
Jan Möbius committed
832

833
    	writeImageAsynchronously(finalImage, suggestSnapshotFilename(snapshotName_));
Jan Möbius's avatar
Jan Möbius committed
834
835
836
837

    	break;
    }

Dirk Wilden's avatar
Dirk Wilden committed
838
839
    case QtMultiViewLayout::Grid:
    {
Dirk Wilden's avatar
Dirk Wilden committed
840
      QImage img0,img1,img2,img3;
841
      
Dirk Wilden's avatar
Dirk Wilden committed
842
843
844
845
846
      examiner_widgets_[0]->snapshot(img0);
      examiner_widgets_[1]->snapshot(img1);
      examiner_widgets_[2]->snapshot(img2);
      examiner_widgets_[3]->snapshot(img3);

847
      QImage* finalImage = new QImage(img0.width() + img1.width() + 2, img0.height() + img2.height() + 2, QImage::Format_ARGB32_Premultiplied);
Dirk Wilden's avatar
Dirk Wilden committed
848

849
      QPainter painter(finalImage);
850

851
      painter.fillRect(0,0,finalImage->width(), finalImage->height(), QBrush(Qt::gray));
852

Dirk Wilden's avatar
Dirk Wilden committed
853
854
      painter.drawImage(QRectF(           0,             0, img0.width(), img0.height()),img0,
                        QRectF(           0,             0, img0.width(), img0.height()) );
855
      painter.drawImage(QRectF(img0.width()+2,           0, img1.width(), img1.height()),img1,
Dirk Wilden's avatar
Dirk Wilden committed
856
                        QRectF(           0,             0, img1.width(), img1.height()) );
857
      painter.drawImage(QRectF(           0, img0.height()+2, img2.width(), img2.height()),img2,
Dirk Wilden's avatar
Dirk Wilden committed
858
                        QRectF(           0,             0, img2.width(), img2.height()) );
859
      painter.drawImage(QRectF(img0.width()+2, img0.height()+2, img3.width(), img3.height()),img3,
Dirk Wilden's avatar
Dirk Wilden committed
860
861
                        QRectF(           0,             0, img3.width(), img3.height()) );

862
      writeImageAsynchronously(finalImage, suggestSnapshotFilename(snapshotName_));
Dirk Wilden's avatar
Dirk Wilden committed
863
864
865
866
867
868
869
870
871
872
873
874

      break;
    }
    case QtMultiViewLayout::HSplit:
    {
      QImage img0,img1,img2,img3;

      examiner_widgets_[0]->snapshot(img0);
      examiner_widgets_[1]->snapshot(img1);
      examiner_widgets_[2]->snapshot(img2);
      examiner_widgets_[3]->snapshot(img3);

875
      QImage* finalImage = new QImage(img0.width() + img1.width() + 2, img0.height(), QImage::Format_ARGB32_Premultiplied);
Dirk Wilden's avatar
Dirk Wilden committed
876

877
      QPainter painter(finalImage);
878

879
      painter.fillRect(0,0,finalImage->width(), finalImage->height(), QBrush(Qt::gray));
880

Dirk Wilden's avatar
Dirk Wilden committed
881
882
      painter.drawImage(QRectF(           0,             0, img0.width(), img0.height()),img0,
                        QRectF(           0,             0, img0.width(), img0.height()) );
883
      painter.drawImage(QRectF(img0.width()+2,             0, img1.width(), img1.height()),img1,
Dirk Wilden's avatar
Dirk Wilden committed
884
                        QRectF(           0,             0, img1.width(), img1.height()) );
885
      painter.drawImage(QRectF(img0.width()+2, img1.height()+2, img2.width(), img2.height()),img2,
Dirk Wilden's avatar
Dirk Wilden committed
886
                        QRectF(           0,             0, img2.width(), img2.height()) );
887
      painter.drawImage(QRectF(img0.width()+2, img1.height()+img2.height()+4, img3.width(),img3.height()),img3,
Dirk Wilden's avatar
Dirk Wilden committed
888
                        QRectF(           0,             0, img3.width(), img3.height()) );
Dirk Wilden's avatar
Dirk Wilden committed
889

890
      writeImageAsynchronously(finalImage, suggestSnapshotFilename(snapshotName_));
Dirk Wilden's avatar
Dirk Wilden committed
891
892
893
894
895
896
897

      break;
    }
    default: break;

  }
}
Dirk Wilden's avatar
Dirk Wilden committed
898
899
900
901
902

void CoreWidget::applicationSnapshotName(QString _name) {
  snapshotName_ = _name;
}

903
904
905
906
907

void writeImageQImage(QImage* _image, const QString _name) {

    _image->save(_name);
    delete _image;
908
909
}

910
911
912
void CoreWidget::writeImageAsynchronously(QImage* _image, const QString _name) {

    QFuture<void>* future = new QFuture<void>();
913
    *future = QtConcurrent::run(writeImageQImage, _image, _name);
914
915
916
917
918
919
920
921
922
923
    QFutureWatcher<void>* watcher = new QFutureWatcher<void>();
    watcher->setFuture(*future);

    watcher_garbage_.insert(std::pair<QFutureWatcher<void>*,QFuture<void>*>(watcher, future));

    connect(watcher, SIGNAL(finished()), this, SLOT(delete_garbage()));
}



924
925
926
927
928
929
930
void CoreWidget::delete_garbage() {

    QObject* obj = QObject::sender();
    QFutureWatcher<void>* watcher = dynamic_cast<QFutureWatcher<void>*>(obj);
    if(!watcher) {
        return;
    }
931
932
933

    map_mutex_.lock();

934
935
936
937
938
939
940
    std::map<QFutureWatcher<void>*,QFuture<void>*>::iterator f;
    f = watcher_garbage_.find(watcher);
    if(f != watcher_garbage_.end()) {
        delete f->second;
        delete f->first;
        watcher_garbage_.erase(f);
    }
941
942

    map_mutex_.unlock();
943
}
Dirk Wilden's avatar
Dirk Wilden committed
944

945
void CoreWidget::slotPasteView( ) {
946
947
948
  examiner_widgets_[PluginFunctions::activeExaminer()]->actionPasteView();
}

949
950
951
952
void CoreWidget::slotSetView( QString view ) {
  examiner_widgets_[PluginFunctions::activeExaminer()]->actionSetView(view);
}

953
954
955
956
957
void CoreWidget::slotSetViewAndWindowGeometry(QString view) {
    const unsigned int viewerId = PluginFunctions::activeExaminer();

    QSize windowSize(0, 0);
    int splitterWidth = 0;
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
958
959
960
    QSize viewportSize(0, 0);
    examiner_widgets_[viewerId]->decodeView (
            view, &windowSize, &splitterWidth, &viewportSize);
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989

    if (windowSize.height() != 0 && windowSize.width() != 0) {
        if (windowSize.width() < 0) {
            windowSize *= -1;
            showNormal();
            resize(windowSize);
            showMaximized();
        } else {
            showNormal();
            resize(windowSize);
        }
    }

    if (splitterWidth > 0) {
        QList<int> splitter_sizes = toolSplitter_->sizes();
        if (splitter_sizes.size() < 2) {
            std::cerr << "The tool splitter has less than two children. This "
                    "shouldn't happen." << std::endl;
        } else {
            const size_t primary_idx = OpenFlipperSettings().value(
                    "Core/Gui/ToolBoxes/ToolBoxOnTheRight",true).toBool()
                    ? 1 : 0;

            const int diff = splitterWidth - splitter_sizes[primary_idx];
            splitter_sizes[primary_idx] += diff;
            splitter_sizes[1-primary_idx] -= diff;
        }
        toolSplitter_->setSizes(splitter_sizes);
    }
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
990
991
992
993
994
995

    /*
     * Viewport size has precedence. Manipulate window size so that the
     * viewport size is matched exactly.
     */
    if (viewportSize.width() > 0 && viewportSize.height() > 0) {
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
        /*
         * Try twice: Sometimes sizes of elements get readjusted after resizing
         * and the viewport will not have the desired size.
         */
        for (int i = 0; i < 2; ++i) {
            const QSize cur_viewport_size = examiner_widgets_[viewerId]->size().toSize();
            if (cur_viewport_size != viewportSize) {
                std::cout << "Stored viewport size is " << viewportSize.width()
                        << " x " << viewportSize.height() << ". Actual size is "
                        << cur_viewport_size.width() << " x "
                        << cur_viewport_size.height() << ". Resizing window."
                        <<  std::endl;

                showNormal();
                QSize diff = viewportSize - cur_viewport_size;
                resize(size() + diff);
                const QSize new_viewport_size =
                        examiner_widgets_[viewerId]->size().toSize();
                diff = viewportSize - new_viewport_size;
                if (diff.width() != 0) {
                    std::cout << "New viewport size is "
                            << new_viewport_size.width()
                            << " x " << new_viewport_size.height() << "."
                            << " Moving splitter by " << diff.width() << "."
                            << std::endl;
                    // Move splitter.
                    QList<int> splitter_sizes = toolSplitter_->sizes();
                    if (splitter_sizes.size() < 2) {
                        std::cerr << "The tool splitter has less than two children. This "
                                "shouldn't happen." << std::endl;
                    } else {
                        const size_t primary_idx = OpenFlipperSettings().value(
                                "Core/Gui/ToolBoxes/ToolBoxOnTheRight",true).toBool()
                                ? 0 : 1;

                        splitter_sizes[primary_idx] += diff.width();
                        splitter_sizes[1-primary_idx] -= diff.width();
                    }
                    toolSplitter_->setSizes(splitter_sizes);

                }
            } else {
                break;
            }
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
1040
1041
        }
    }
1042
1043
}

1044
1045
void CoreWidget::slotPasteViewAndWindow()
{
1046
  QSize size;
1047
1048
  int splitterWidth;
  examiner_widgets_[PluginFunctions::activeExaminer()]->actionPasteView(&size,&splitterWidth);
1049

1050
  //resize the toolbox and splitter
1051
  if (splitterWidth != -1)
1052
  {
1053
    QList<int> sizes;
1054

1055
1056
1057
    //std::cerr << "Sizes : " << size[0] << " " << size[1] << " " << sum_size << std::endl;

    bool onRight = OpenFlipperSettings().value("Core/Gui/ToolBoxes/ToolBoxOnTheRight",true).toBool();
1058
1059
    if (onRight)
    {
1060
1061
      sizes.push_back(size.width() - splitterWidth);
      sizes.push_back(splitterWidth);
1062
1063
1064
    }
    else
    {
1065
1066
      sizes.push_back(splitterWidth);
      sizes.push_back(size.width() - splitterWidth);
1067
    }
1068

1069
1070
    toolSplitter_->setSizes(sizes);
  }
1071

1072
  //resize window
1073
  if (size.isValid())
1074
  {
1075
    if (size == QSize(0,0))
1076
    {
1077
1078
1079
1080
1081
1082
      showMaximized();
    }
    else
    {
      showNormal();
      resizeApplication(size.width(),size.height());
1083
    }
1084
  }
1085
1086
1087
}

void CoreWidget::slotCopyView( ) {
1088
1089
1090
1091
1092
  QSize size;
  if (isMaximized())
    size = QSize(0,0);
  else
    size = QSize (width(),height());
1093
1094

  int splitter_size = 0;
1095
  if (OpenFlipperSettings().value("Core/Gui/ToolBoxes/ToolBoxOnTheRight",true).toBool())
1096
1097
1098
1099
    splitter_size = toolSplitter_->sizes()[1];
  else
    splitter_size = toolSplitter_->sizes()[0];

1100
1101
1102
  const bool make_c_string = (QApplication::keyboardModifiers() & Qt::ControlModifier);
  examiner_widgets_[PluginFunctions::activeExaminer()]->actionCopyView(
          size, splitter_size, make_c_string);
1103
1104
}

Dirk Wilden's avatar
Dirk Wilden committed
1105
void CoreWidget::slotCoordSysVisibility(bool _visible){
1106

Dirk Wilden's avatar
Dirk Wilden committed
1107
1108
1109
1110
  ACG::SceneGraph::BaseNode* root = PluginFunctions::getSceneGraphRootNode();
  ACG::SceneGraph::BaseNode* coordSys = root->find("Core Coordsys Node");

  if (coordSys == 0){
1111
    emit log( LOGERR, tr("CoordSys Node not found"));
Dirk Wilden's avatar
Dirk Wilden committed
1112
1113
1114
    return;
  }

1115
if (_visible)
Dirk Wilden's avatar
Dirk Wilden committed
1116
    coordSys->show();
1117
  else
Dirk Wilden's avatar
Dirk Wilden committed
1118
    coordSys->hide();
1119

1120
1121
  for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
    examiner_widgets_[i]->updateGL();
1122

Dirk Wilden's avatar
Dirk Wilden committed
1123
}
Jan Möbius's avatar
Jan Möbius committed
1124

1125
1126
1127
void CoreWidget::slotSetViewingDirection(QAction* _action) {

  PluginFunctions::setFixedView( _action->data().toInt() );
1128
1129
1130
  if (_action->data().toInt() != PluginFunctions::VIEW_FREE)
    PluginFunctions::allowRotation( false, PluginFunctions::activeExaminer() );
  
1131
1132
  // Update view
  examiner_widgets_[PluginFunctions::activeExaminer()]->updateGL();
1133
}
1134

1135
1136
1137
void CoreWidget::slotLockRotation(bool _lock) {

  PluginFunctions::allowRotation( !_lock, PluginFunctions::activeExaminer() );
1138
1139
  if (!_lock)
    PluginFunctions::setFixedView( PluginFunctions::VIEW_FREE );
1140
1141
}

Jan Möbius's avatar