1
/***************************************************************************
2
* Copyright (c) 2004 Jļæ½rgen Riegel <juergen.riegel@web.de> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
24
#include "PreCompiled.h"
27
# include <QApplication>
31
# include <QDropEvent>
32
# include <QDragEnterEvent>
33
# include <Inventor/actions/SoWriteAction.h>
34
# include <Inventor/actions/SoGetPrimitiveCountAction.h>
35
# include <Inventor/nodes/SoDirectionalLight.h>
36
# include <Inventor/nodes/SoMaterial.h>
37
# include <Inventor/nodes/SoOrthographicCamera.h>
38
# include <Inventor/nodes/SoPerspectiveCamera.h>
39
# include <Inventor/nodes/SoSeparator.h>
40
# include <Inventor/nodes/SoShapeHints.h>
41
# include <Inventor/events/SoEvent.h>
42
# include <Inventor/fields/SoSFString.h>
43
# include <Inventor/fields/SoSFColor.h>
46
#include <Base/Exception.h>
48
#include "View3DInventor.h"
49
#include "View3DInventorViewer.h"
51
#include "FileDialog.h"
52
#include "Application.h"
53
#include "MainWindow.h"
54
#include "MenuManager.h"
55
#include <App/Feature.h>
56
#include <Base/Console.h>
59
#include "Inventor/Qt/viewers/SoQtExaminerViewer.h"
60
#include <Inventor/nodes/SoPerspectiveCamera.h>
61
#include <Inventor/nodes/SoOrthographicCamera.h>
63
#include "View3DInventorExamples.h"
64
#include "SoFCSelectionAction.h"
67
#include "NavigationStyle.h"
73
TYPESYSTEM_SOURCE_ABSTRACT(Gui::View3DInventor,Gui::BaseView);
75
View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent, Qt::WFlags wflags)
76
: MDIView(pcDocument, parent, wflags), _viewerPy(0)
78
// important for highlighting
79
setMouseTracking(true);
80
// accept drops on the window, get handled in dropEvent, dragEnterEvent
83
// attach parameter Observer
84
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
87
// create the inventor widget and set the defaults
88
_viewer = new View3DInventorViewer(this);
90
// apply the user settings
91
hGrp->Notify("HeadlightColor");
92
hGrp->Notify("HeadlightDirection");
93
hGrp->Notify("HeadlightIntensity");
94
hGrp->Notify("EnableBacklight");
95
hGrp->Notify("BacklightColor");
96
hGrp->Notify("BacklightDirection");
97
hGrp->Notify("BacklightIntensity");
98
hGrp->Notify("NavigationStyle");
100
stopSpinTimer = new QTimer(this);
101
connect(stopSpinTimer, SIGNAL(timeout()), this, SLOT(stopAnimating()));
104
View3DInventor::~View3DInventor()
108
//If we destroy this viewer by calling 'delete' directly the focus proxy widget which is defined
109
//by a widget in SoQtViewer isn't resetted. This widget becomes to a dangling pointer and makes
110
//the application crash. (Probably it's better to destroy this viewer by calling close().)
111
//See also Gui::Document::~Document().
112
QWidget* foc = qApp->focusWidget();
114
QWidget* par = foc->parentWidget();
117
foc->setFocusProxy(0);
121
par = par->parentWidget();
126
static_cast<View3DInventorPy*>(_viewerPy)->_view = 0;
127
Py_DECREF(_viewerPy);
133
PyObject *View3DInventor::getPyObject(void)
136
_viewerPy = new View3DInventorPy(this);
138
Py_INCREF(_viewerPy);
142
void View3DInventor::setViewerDefaults(void)
144
_viewer->setStereoOffset(hGrp->GetFloat("EyeDistance",65.0));
145
_viewer->setFeedbackVisibility(hGrp->GetBool("CornerCoordSystem",true));
146
_viewer->setAnimationEnabled(hGrp->GetBool("UseAutoRotation",true));
147
_viewer->setGradientBackgroud((hGrp->GetBool("Gradient",true)));
148
unsigned long col1 = hGrp->GetUnsigned("BackgroundColor",0);
149
unsigned long col2 = hGrp->GetUnsigned("BackgroundColor2",2139082239); // default color (purple)
150
unsigned long col3 = hGrp->GetUnsigned("BackgroundColor3",ULONG_MAX); // default color (white)
151
unsigned long col4 = hGrp->GetUnsigned("BackgroundColor4",ULONG_MAX); // default color (white)
152
float r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4;
153
r1 = ((col1 >> 24) & 0xff) / 255.0; g1 = ((col1 >> 16) & 0xff) / 255.0; b1 = ((col1 >> 8) & 0xff) / 255.0;
154
r2 = ((col2 >> 24) & 0xff) / 255.0; g2 = ((col2 >> 16) & 0xff) / 255.0; b2 = ((col2 >> 8) & 0xff) / 255.0;
155
r3 = ((col3 >> 24) & 0xff) / 255.0; g3 = ((col3 >> 16) & 0xff) / 255.0; b3 = ((col3 >> 8) & 0xff) / 255.0;
156
r4 = ((col4 >> 24) & 0xff) / 255.0; g4 = ((col4 >> 16) & 0xff) / 255.0; b4 = ((col4 >> 8) & 0xff) / 255.0;
157
_viewer->setBackgroundColor(SbColor(r1, g1, b1));
158
if (hGrp->GetBool("UseBackgroundColorMid",false) == false)
159
_viewer->setGradientBackgroudColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3));
161
_viewer->setGradientBackgroudColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3), SbColor(r4, g4, b4));
163
if (hGrp->GetBool("UseAntialiasing" ,false))
164
_viewer->getGLRenderAction()->setSmoothing(true);
166
_viewer->getGLRenderAction()->setSmoothing(false);
167
_viewer->setEnabledFPSCounter(hGrp->GetBool("ShowFPS",false));
169
// check whether a perspective or orthogrphic camera should be set
170
if (hGrp->GetBool("Orthographic", false))
171
_viewer->setCameraType(SoOrthographicCamera::getClassTypeId());
173
_viewer->setCameraType(SoPerspectiveCamera::getClassTypeId());
176
void View3DInventor::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason)
178
const ParameterGrp& rGrp = static_cast<ParameterGrp&>(rCaller);
179
if (strcmp(Reason,"HeadlightColor") == 0) {
180
unsigned long headlight = rGrp.GetUnsigned("HeadlightColor",ULONG_MAX); // default color (white)
182
SbColor headlightColor;
183
headlightColor.setPackedValue((uint32_t)headlight, transparency);
184
_viewer->getHeadlight()->color.setValue(headlightColor);
186
else if (strcmp(Reason,"HeadlightDirection") == 0) {
187
std::string pos = rGrp.GetASCII("HeadlightDirection");
188
QString flt = QString::fromAscii("([-+]?[0-9]+\\.?[0-9]+)");
189
QRegExp rx(QString::fromAscii("^\\(%1,%1,%1\\)$").arg(flt));
190
if (rx.indexIn(QLatin1String(pos.c_str())) > -1) {
191
float x = rx.cap(1).toFloat();
192
float y = rx.cap(2).toFloat();
193
float z = rx.cap(3).toFloat();
194
_viewer->getHeadlight()->direction.setValue(x,y,z);
197
else if (strcmp(Reason,"HeadlightIntensity") == 0) {
198
long value = rGrp.GetInt("HeadlightIntensity", 100);
199
_viewer->getHeadlight()->intensity.setValue((float)value/100.0f);
201
else if (strcmp(Reason,"EnableBacklight") == 0) {
202
_viewer->setBacklight(rGrp.GetBool("EnableBacklight", false));
204
else if (strcmp(Reason,"BacklightColor") == 0) {
205
unsigned long backlight = rGrp.GetUnsigned("BacklightColor",ULONG_MAX); // default color (white)
207
SbColor backlightColor;
208
backlightColor.setPackedValue((uint32_t)backlight, transparency);
209
_viewer->getBacklight()->color.setValue(backlightColor);
211
else if (strcmp(Reason,"BacklightDirection") == 0) {
212
std::string pos = rGrp.GetASCII("BacklightDirection");
213
QString flt = QString::fromAscii("([-+]?[0-9]+\\.?[0-9]+)");
214
QRegExp rx(QString::fromAscii("^\\(%1,%1,%1\\)$").arg(flt));
215
if (rx.indexIn(QLatin1String(pos.c_str())) > -1) {
216
float x = rx.cap(1).toFloat();
217
float y = rx.cap(2).toFloat();
218
float z = rx.cap(3).toFloat();
219
_viewer->getBacklight()->direction.setValue(x,y,z);
222
else if (strcmp(Reason,"BacklightIntensity") == 0) {
223
long value = rGrp.GetInt("BacklightIntensity", 100);
224
_viewer->getBacklight()->intensity.setValue((float)value/100.0f);
226
else if (strcmp(Reason,"EnablePreselection") == 0) {
227
const ParameterGrp& rclGrp = ((ParameterGrp&)rCaller);
228
SoFCEnableHighlightAction cAct(rclGrp.GetBool("EnablePreselection", false));
229
cAct.apply(_viewer->getSceneGraph());
231
else if (strcmp(Reason,"EnableSelection") == 0) {
232
const ParameterGrp& rclGrp = ((ParameterGrp&)rCaller);
233
SoFCEnableSelectionAction cAct(rclGrp.GetBool("EnableSelection", false));
234
cAct.apply(_viewer->getSceneGraph());
236
else if (strcmp(Reason,"HighlightColor") == 0) {
238
SbColor highlightColor(0.1f, 0.1f, 0.8f);
239
unsigned long highlight = (unsigned long)(highlightColor.getPackedValue());
240
highlight = rGrp.GetUnsigned("HighlightColor", highlight);
241
highlightColor.setPackedValue((uint32_t)highlight, transparency);
242
SoSFColor col; col.setValue(highlightColor);
243
SoFCHighlightColorAction cAct(col);
244
cAct.apply(_viewer->getSceneGraph());
246
else if (strcmp(Reason,"SelectionColor") == 0) {
248
SbColor selectionColor(0.1f, 0.5f, 0.1f);
249
unsigned long selection = (unsigned long)(selectionColor.getPackedValue());
250
selection = rGrp.GetUnsigned("SelectionColor", selection);
251
selectionColor.setPackedValue((uint32_t)selection, transparency);
252
SoSFColor col; col.setValue(selectionColor);
253
SoFCSelectionColorAction cAct(col);
254
cAct.apply(_viewer->getSceneGraph());
256
else if (strcmp(Reason,"NavigationStyle") == 0) {
257
// check whether the simple or the full mouse model is used
258
std::string model = rGrp.GetASCII("NavigationStyle",CADNavigationStyle::getClassTypeId().getName());
259
Base::Type type = Base::Type::fromName(model.c_str());
260
_viewer->setNavigationType(type);
267
void View3DInventor::onRename(Gui::Document *pDoc)
270
name.setValue(pDoc->getDocument()->getName());
271
SoFCDocumentAction cAct(name);
272
cAct.apply(_viewer->getSceneGraph());
275
void View3DInventor::onUpdate(void)
277
#ifdef FC_LOGUPDATECHAIN
278
Base::Console().Log("Acti: Gui::View3DInventor::onUpdate()");
284
void View3DInventor::viewAll()
289
const char *View3DInventor::getName(void) const
291
return "View3DInventor";
294
// **********************************************************************************
296
bool View3DInventor::onMsg(const char* pMsg, const char** ppReturn)
298
if (strcmp("ViewFit",pMsg) == 0 ) {
302
else if(strcmp("ViewSelection",pMsg) == 0) {
303
_viewer->viewSelection();
305
// comment out on older Inventor
306
#if (SOQT_MAJOR_VERSION >= 1 && SOQT_MINOR_VERSION >= 2)
308
else if(strcmp("SetStereoRedGreen",pMsg) == 0 ) {
309
_viewer->setStereoType(SoQtViewer::STEREO_ANAGLYPH);
312
else if(strcmp("SetStereoQuadBuff",pMsg) == 0 ) {
313
_viewer->setStereoType(SoQtViewer::STEREO_QUADBUFFER );
316
else if(strcmp("SetStereoInterleavedRows",pMsg) == 0 ) {
317
_viewer->setStereoType(SoQtViewer::STEREO_INTERLEAVED_ROWS );
320
else if(strcmp("SetStereoInterleavedColumns",pMsg) == 0 ) {
321
_viewer->setStereoType(SoQtViewer::STEREO_INTERLEAVED_COLUMNS );
324
else if(strcmp("SetStereoOff",pMsg) == 0 ) {
325
_viewer->setStereoType(SoQtViewer::STEREO_NONE );
329
else if(strcmp("SetStereoRedGreen",pMsg) == 0 ) {
330
Base::Console().Warning("Use SoQt 1.2.x or later!\n");
333
else if(strcmp("SetStereoQuadBuff",pMsg) == 0 ) {
334
Base::Console().Warning("Use SoQt 1.2.x or later!\n");
337
else if(strcmp("SetStereoInterleavedRows",pMsg) == 0 ) {
338
Base::Console().Warning("Use SoQt 1.2.x or later!\n");
341
else if(strcmp("SetStereoInterleavedColumns",pMsg) == 0 ) {
342
Base::Console().Warning("Use SoQt 1.2.x or later!\n");
345
else if(strcmp("SetStereoOff",pMsg) == 0 ) {
346
Base::Console().Warning("Use SoQt 1.2.x or later!\n");
350
else if(strcmp("Example1",pMsg) == 0 ) {
351
SoSeparator * root = new SoSeparator;
353
_viewer->setSceneGraph(root);
356
else if(strcmp("Example2",pMsg) == 0 ) {
357
SoSeparator * root = new SoSeparator;
359
_viewer->setSceneGraph(root);
362
else if(strcmp("Example3",pMsg) == 0 ) {
363
SoSeparator * root = new SoSeparator;
364
AnimationTexture(root);
365
_viewer->setSceneGraph(root);
368
else if(strcmp("GetCamera",pMsg) == 0 ) {
369
SoCamera * Cam = _viewer->getCamera();
370
*ppReturn = SoFCDB::writeNodesToString(Cam).c_str();
373
else if(strncmp("SetCamera",pMsg,9) == 0 ) {
374
return setCamera(pMsg+10);
376
else if(strncmp("Dump",pMsg,4) == 0 ) {
380
else if(strcmp("ViewBottom",pMsg) == 0 ) {
381
_viewer->setCameraOrientation(SbRotation(-1, 0, 0, 0));
385
else if(strcmp("ViewFront",pMsg) == 0 ) {
386
float root = (float)(sqrt(2.0)/2.0);
387
_viewer->setCameraOrientation(SbRotation(-root, 0, 0, -root));
391
else if(strcmp("ViewLeft",pMsg) == 0 ) {
392
_viewer->setCameraOrientation(SbRotation(0.5, 0.5, 0.5, 0.5));
396
else if(strcmp("ViewRear",pMsg) == 0 ) {
397
float root = (float)(sqrt(2.0)/2.0);
398
_viewer->setCameraOrientation(SbRotation(0, root, root, 0));
402
else if(strcmp("ViewRight",pMsg) == 0 ) {
403
_viewer->setCameraOrientation(SbRotation(-0.5, 0.5, 0.5, -0.5));
407
else if(strcmp("ViewTop",pMsg) == 0 ) {
408
_viewer->setCameraOrientation(SbRotation(0, 0, 0, 1));
412
else if(strcmp("ViewAxo",pMsg) == 0 ) {
413
_viewer->setCameraOrientation(SbRotation
414
(-0.353553f, -0.146447f, -0.353553f, 0.853553f));
418
else if(strcmp("OrthographicCamera",pMsg) == 0 ) {
419
_viewer->setCameraType(SoOrthographicCamera::getClassTypeId());
422
else if(strcmp("PerspectiveCamera",pMsg) == 0 ) {
423
_viewer->setCameraType(SoPerspectiveCamera::getClassTypeId());
426
else if(strcmp("Undo",pMsg) == 0 ) {
427
getGuiDocument()->undo(1);
430
else if(strcmp("Redo",pMsg) == 0 ) {
431
getGuiDocument()->redo(1);
434
else if (strcmp("Save",pMsg) == 0) {
435
getGuiDocument()->save();
438
else if (strcmp("SaveAs",pMsg) == 0) {
439
getGuiDocument()->saveAs();
447
bool View3DInventor::onHasMsg(const char* pMsg) const
449
if(strcmp("Save",pMsg) == 0 ){
451
}else if(strcmp("SaveAs",pMsg) == 0 ){
453
}else if(strcmp("Undo",pMsg) == 0 ){
454
return getAppDocument()->getAvailableUndos() > 0;
455
}else if(strcmp("Redo",pMsg) == 0 ){
456
return getAppDocument()->getAvailableRedos() > 0;
457
}else if(strcmp("SetStereoRedGreen",pMsg) == 0 ){
459
}else if(strcmp("SetStereoQuadBuff",pMsg) == 0 ){
461
}else if(strcmp("SetStereoInterleavedRows",pMsg) == 0 ){
463
}else if(strcmp("SetStereoInterleavedColumns",pMsg) == 0 ){
465
}else if(strcmp("SetStereoOff",pMsg) == 0 ){
467
}else if(strcmp("Example1",pMsg) == 0 ){
469
}else if(strcmp("Example2",pMsg) == 0 ){
471
}else if(strcmp("Example3",pMsg) == 0 ){
473
}else if(strcmp("ViewFit",pMsg) == 0 ){
475
}else if(strcmp("ViewSelection",pMsg) == 0 ){
477
}else if(strcmp("ViewBottom",pMsg) == 0 ){
479
}else if(strcmp("ViewFront",pMsg) == 0 ){
481
}else if(strcmp("ViewLeft",pMsg) == 0 ){
483
}else if(strcmp("ViewRear",pMsg) == 0 ){
485
}else if(strcmp("ViewRight",pMsg) == 0 ){
487
}else if(strcmp("ViewTop",pMsg) == 0 ){
489
}else if(strcmp("ViewAxo",pMsg) == 0 ){
491
}else if(strcmp("GetCamera",pMsg) == 0 ){
493
}else if(strncmp("SetCamera",pMsg,9) == 0 ){
495
}else if(strncmp("Dump",pMsg,4) == 0 ){
501
bool View3DInventor::setCamera(const char* pCamera)
503
SoCamera * CamViewer = _viewer->getCamera();
505
throw Base::Exception("No camera set so far...");
509
in.setBuffer((void*)pCamera,std::strlen(pCamera));
515
throw Base::Exception("Camera settings failed to read");
518
// toogle between persepective and orthographic camera
519
if (Cam->getTypeId() != CamViewer->getTypeId())
521
_viewer->setCameraType(Cam->getTypeId());
522
CamViewer = _viewer->getCamera();
525
SoPerspectiveCamera * CamViewerP = 0;
526
SoOrthographicCamera * CamViewerO = 0;
528
if (CamViewer->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
529
CamViewerP = (SoPerspectiveCamera *)CamViewer; // safe downward cast, knows the type
530
} else if (CamViewer->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
531
CamViewerO = (SoOrthographicCamera *)CamViewer; // safe downward cast, knows the type
534
if (Cam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
536
CamViewerP->position = ((SoPerspectiveCamera *)Cam)->position;
537
CamViewerP->orientation = ((SoPerspectiveCamera *)Cam)->orientation;
538
CamViewerP->nearDistance = ((SoPerspectiveCamera *)Cam)->nearDistance;
539
CamViewerP->farDistance = ((SoPerspectiveCamera *)Cam)->farDistance;
540
CamViewerP->focalDistance = ((SoPerspectiveCamera *)Cam)->focalDistance;
542
throw Base::Exception("Camera type mismatch");
544
} else if (Cam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
546
CamViewerO->viewportMapping = ((SoOrthographicCamera *)Cam)->viewportMapping;
547
CamViewerO->position = ((SoOrthographicCamera *)Cam)->position;
548
CamViewerO->orientation = ((SoOrthographicCamera *)Cam)->orientation;
549
CamViewerO->nearDistance = ((SoOrthographicCamera *)Cam)->nearDistance;
550
CamViewerO->farDistance = ((SoOrthographicCamera *)Cam)->farDistance;
551
CamViewerO->focalDistance = ((SoOrthographicCamera *)Cam)->focalDistance;
552
CamViewerO->aspectRatio = ((SoOrthographicCamera *)Cam)->aspectRatio ;
553
CamViewerO->height = ((SoOrthographicCamera *)Cam)->height;
555
throw Base::Exception("Camera type mismatch");
562
void View3DInventor::toggleClippingPlane()
564
_viewer->toggleClippingPlane();
567
bool View3DInventor::hasClippingPlane() const
569
return _viewer->hasClippingPlane();
572
void View3DInventor::setCursor(const QCursor& aCursor)
574
_viewer->getWidget()->setCursor(aCursor);
577
void View3DInventor::dump(const char* filename)
579
SoGetPrimitiveCountAction action;
580
action.setCanApproximate(true);
581
action.apply(_viewer->getSceneGraph());
583
if ( action.getTriangleCount() > 100000 || action.getPointCount() > 30000 || action.getLineCount() > 10000 )
584
_viewer->dumpToFile(filename,true);
586
_viewer->dumpToFile(filename,false);
589
void View3DInventor::windowStateChanged(MDIView* view)
591
bool canStartTimer = false;
593
// If both views are child widgets of the workspace and view is maximized this view
594
// must be hidden, hence we can start the timer.
595
// Note: If view is top-level or fullscreen it doesn't necessarily hide the other view
596
// e.g. if it is on a second monitor.
597
canStartTimer = (!this->isTopLevel() && !view->isTopLevel() && view->isMaximized());
598
} else if (isMinimized()) {
599
// I am the active view but minimized
600
canStartTimer = true;
604
// do a single shot event (maybe insert a checkbox in viewer settings)
605
int msecs = hGrp->GetInt("stopAnimatingIfDeactivated", 3000);
606
if (!stopSpinTimer->isActive() && msecs >= 0) { // if < 0 do not stop rotation
607
stopSpinTimer->setSingleShot(true);
608
stopSpinTimer->start(msecs);
610
} else if (stopSpinTimer->isActive()) {
611
// If this view may be visible again we can stop the timer
612
stopSpinTimer->stop();
616
void View3DInventor::stopAnimating()
618
_viewer->stopAnimating();
622
* Drops the event \a e and writes the right Python command.
624
void View3DInventor::dropEvent (QDropEvent * e)
626
const QMimeData* data = e->mimeData();
627
if (data->hasUrls()) {
628
QList<QUrl> uri = data->urls();
630
App::Document* pDoc = getAppDocument();
632
for (QList<QUrl>::ConstIterator it = uri.begin(); it != uri.end(); ++it) {
633
QFileInfo info((*it).toLocalFile());
634
if ( info.exists() && info.isFile() ) {
635
if (info.isSymLink())
636
info.setFile(info.readLink());
637
files << info.absoluteFilePath();
641
const char *docName = pDoc->getName();
642
SelectModule::Dict dict = SelectModule::importHandler(files);
643
// load the files with the associated modules
644
for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
645
Application::Instance->importFrom(it.key().toUtf8(), docName, it.value().toAscii());
650
MDIView::dropEvent(e);
654
void View3DInventor::dragEnterEvent (QDragEnterEvent * e)
656
// Here we must allow uri drafs and check them in dropEvent
657
const QMimeData* data = e->mimeData();
658
if ( data->hasUrls() )
664
void View3DInventor::setCurrentViewMode(ViewMode newmode)
666
ViewMode oldmode = MDIView::currentViewMode();
667
MDIView::setCurrentViewMode(newmode);
669
// This widget becomes the focus proxy of the embedded GL widget if we leave
670
// the 'Child' mode. If we reenter 'Child' mode the focus proxy is reset to 0.
671
// If we change from 'TopLevel' mode to 'Fullscreen' mode or vice versa nothing
673
// Grabbing keyboard when leaving 'Child' mode (as done in a recent version) should
674
// be avoided because when two or more windows are either in 'TopLevel' or 'Fullscreen'
675
// mode only the last window gets all key event even if it is not the active one.
677
// It is important to set the focus proxy to get all key events otherwise we would loose
678
// control after redirecting the first key event to the GL widget.
679
// We redirect these events in keyPressEvent() and keyReleaseEvent().
680
if (oldmode == Child) {
681
// To make a global shortcut working from this window we need to add
682
// all existing actions from the mainwindow and its sub-widgets
683
QList<QAction*> acts = getMainWindow()->findChildren<QAction*>();
684
this->addActions(acts);
685
_viewer->getGLWidget()->setFocusProxy(this);
686
// To be notfified for new actions
687
qApp->installEventFilter(this);
688
} else if (newmode == Child) {
689
_viewer->getGLWidget()->setFocusProxy(0);
690
qApp->removeEventFilter(this);
691
QList<QAction*> acts = this->actions();
692
for (QList<QAction*>::Iterator it = acts.begin(); it != acts.end(); ++it)
693
this->removeAction(*it);
697
bool View3DInventor::eventFilter(QObject* watched, QEvent* e)
699
// As long as this widget is a top-level window (either in 'TopLevel' or 'FullScreen' mode) we
700
// need to be notified when an action is added to a widget. This action must also be added to
701
// this window to allow to make use of its shortcut (if defined).
702
// Note: We don't need to care about removing an action if its parent widget gets destroyed.
703
// This does the action itself for us.
704
if (watched != this && e->type() == QEvent::ActionAdded) {
705
QActionEvent* a = static_cast<QActionEvent*>(e);
706
QAction* action = a->action();
708
if (!action->isSeparator()) {
709
QList<QAction*> actions = this->actions();
710
if (!actions.contains(action))
711
this->addAction(action);
718
void View3DInventor::keyPressEvent (QKeyEvent* e)
720
ViewMode mode = MDIView::currentViewMode();
722
// If the widget is in fullscreen mode then we can return to normal mode either
723
// by pressing the matching accelerator or ESC.
724
if (e->key() == Qt::Key_Escape) {
725
setCurrentViewMode(Child);
727
// Note: The key events should be redirected directly to the GL widget and not to the main window
728
// otherwise the first redirected key event always disappears in hyperspace.
730
// send the event to the GL widget that converts to and handles an SoEvent
731
QWidget* w = _viewer->getGLWidget();
732
QApplication::sendEvent(w,e);
735
QMainWindow::keyPressEvent(e);
739
void View3DInventor::keyReleaseEvent (QKeyEvent* e)
741
ViewMode mode = MDIView::currentViewMode();
743
// send the event to the GL widget that converts to and handles an SoEvent
744
QWidget* w = _viewer->getGLWidget();
745
QApplication::sendEvent(w,e);
747
QMainWindow::keyReleaseEvent(e);
751
void View3DInventor::focusInEvent (QFocusEvent * e)
753
_viewer->getGLWidget()->setFocus();
756
#include "moc_View3DInventor.cpp"