Gui: enable dock/undock/fullscreen for all MDI widgets
This commit is contained in:
@@ -1682,7 +1682,7 @@ void StdViewDock::activated(int iMsg)
|
||||
bool StdViewDock::isActive()
|
||||
{
|
||||
MDIView* view = getMainWindow()->activeWindow();
|
||||
return (qobject_cast<View3DInventor*>(view) ? true : false);
|
||||
return view != nullptr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -1711,7 +1711,7 @@ void StdViewUndock::activated(int iMsg)
|
||||
bool StdViewUndock::isActive()
|
||||
{
|
||||
MDIView* view = getMainWindow()->activeWindow();
|
||||
return (qobject_cast<View3DInventor*>(view) ? true : false);
|
||||
return view != nullptr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -1773,7 +1773,7 @@ void StdViewFullscreen::activated(int iMsg)
|
||||
bool StdViewFullscreen::isActive()
|
||||
{
|
||||
MDIView* view = getMainWindow()->activeWindow();
|
||||
return (qobject_cast<View3DInventor*>(view) ? true : false);
|
||||
return view != nullptr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -1825,67 +1825,61 @@ void StdViewDockUndockFullscreen::activated(int iMsg)
|
||||
if (!view) // no active view
|
||||
return;
|
||||
|
||||
// nothing to do when the view is docked and 'Docked' is pressed
|
||||
if (iMsg == 0 && view->currentViewMode() == MDIView::Child)
|
||||
const auto oldmode = view->currentViewMode();
|
||||
auto mode = (MDIView::ViewMode)iMsg;
|
||||
|
||||
// Pressing the same button again toggles the view back to docked.
|
||||
if (mode == oldmode) {
|
||||
mode = MDIView::Child;
|
||||
}
|
||||
|
||||
if (mode == oldmode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Change the view mode after an mdi view was already visible doesn't
|
||||
// work well with Qt5 any more because of some strange OpenGL behaviour.
|
||||
// A workaround is to clone the mdi view, set its view mode and delete
|
||||
// the original view.
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
if (doc) {
|
||||
Gui::MDIView* clone = doc->cloneView(view);
|
||||
if (!clone)
|
||||
return;
|
||||
|
||||
const char* ppReturn = nullptr;
|
||||
if (view->onMsg("GetCamera", &ppReturn)) {
|
||||
std::string sMsg = "SetCamera ";
|
||||
sMsg += ppReturn;
|
||||
bool needsClone = mode == MDIView::Child || oldmode == MDIView::Child;
|
||||
Gui::MDIView* clone = needsClone ? view->clone() : nullptr;
|
||||
|
||||
const char** pReturnIgnore=nullptr;
|
||||
clone->onMsg(sMsg.c_str(), pReturnIgnore);
|
||||
}
|
||||
|
||||
if (iMsg==0) {
|
||||
if (clone) {
|
||||
if (mode == MDIView::Child) {
|
||||
getMainWindow()->addWindow(clone);
|
||||
}
|
||||
else if (iMsg==1) {
|
||||
if (view->currentViewMode() == MDIView::TopLevel)
|
||||
getMainWindow()->addWindow(clone);
|
||||
else
|
||||
clone->setCurrentViewMode(MDIView::TopLevel);
|
||||
}
|
||||
else if (iMsg==2) {
|
||||
if (view->currentViewMode() == MDIView::FullScreen)
|
||||
getMainWindow()->addWindow(clone);
|
||||
else
|
||||
clone->setCurrentViewMode(MDIView::FullScreen);
|
||||
else {
|
||||
clone->setCurrentViewMode(mode);
|
||||
}
|
||||
|
||||
// destroy the old view
|
||||
view->deleteSelf();
|
||||
}
|
||||
else {
|
||||
// no clone needed, simply change the view mode
|
||||
view->setCurrentViewMode(mode);
|
||||
}
|
||||
}
|
||||
|
||||
bool StdViewDockUndockFullscreen::isActive()
|
||||
{
|
||||
MDIView* view = getMainWindow()->activeWindow();
|
||||
if (qobject_cast<View3DInventor*>(view)) {
|
||||
// update the action group if needed
|
||||
auto pActGrp = qobject_cast<ActionGroup*>(_pcAction);
|
||||
if (pActGrp) {
|
||||
int index = pActGrp->checkedAction();
|
||||
int mode = (int)(view->currentViewMode());
|
||||
if (index != mode) {
|
||||
// active window has changed with another view mode
|
||||
pActGrp->setCheckedAction(mode);
|
||||
}
|
||||
}
|
||||
if (!view)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
// update the action group if needed
|
||||
auto pActGrp = qobject_cast<ActionGroup*>(_pcAction);
|
||||
if (pActGrp) {
|
||||
int index = pActGrp->checkedAction();
|
||||
int mode = (int)(view->currentViewMode());
|
||||
if (index != mode) {
|
||||
// active window has changed with another view mode
|
||||
pActGrp->setCheckedAction(mode);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2016,7 +2016,7 @@ void Document::addRootObjectsToGroup(const std::vector<App::DocumentObject*>& ob
|
||||
}
|
||||
}
|
||||
|
||||
MDIView *Document::createView(const Base::Type& typeId)
|
||||
MDIView* Document::createView(const Base::Type& typeId, CreateViewMode mode)
|
||||
{
|
||||
if (!typeId.isDerivedFrom(MDIView::getClassTypeId()))
|
||||
return nullptr;
|
||||
@@ -2062,11 +2062,16 @@ MDIView *Document::createView(const Base::Type& typeId)
|
||||
for (App::DocumentObject* obj : child_vps)
|
||||
view3D->getViewer()->removeViewProvider(getViewProvider(obj));
|
||||
|
||||
const char* name = getDocument()->Label.getValue();
|
||||
QString title = QStringLiteral("%1 : %2[*]")
|
||||
.arg(QString::fromUtf8(name)).arg(d->_iWinCount++);
|
||||
// When cloning the view, don't increment the window counter as the old view will be deleted
|
||||
// shortly after.
|
||||
if (mode != CreateViewMode::Clone) {
|
||||
const char* name = getDocument()->Label.getValue();
|
||||
QString title =
|
||||
QStringLiteral("%1 : %2[*]").arg(QString::fromUtf8(name)).arg(d->_iWinCount++);
|
||||
|
||||
view3D->setWindowTitle(title);
|
||||
}
|
||||
|
||||
view3D->setWindowTitle(title);
|
||||
view3D->setWindowModified(this->isModified());
|
||||
view3D->resize(400, 300);
|
||||
|
||||
@@ -2075,65 +2080,19 @@ MDIView *Document::createView(const Base::Type& typeId)
|
||||
view3D->onMsg(cameraSettings.c_str(),&ppReturn);
|
||||
}
|
||||
|
||||
getMainWindow()->addWindow(view3D);
|
||||
// When cloning the view, don't add the view to the main window. The whole purpose of the
|
||||
// workaround using cloned views is that the view can be shown in undocked/fullscreen mode
|
||||
// without having been docked before.
|
||||
if (mode != CreateViewMode::Clone) {
|
||||
getMainWindow()->addWindow(view3D);
|
||||
}
|
||||
|
||||
view3D->getViewer()->redraw();
|
||||
return view3D;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Gui::MDIView* Document::cloneView(Gui::MDIView* oldview)
|
||||
{
|
||||
if (!oldview)
|
||||
return nullptr;
|
||||
|
||||
if (oldview->is<View3DInventor>()) {
|
||||
auto view3D = new View3DInventor(this, getMainWindow());
|
||||
|
||||
auto firstView = static_cast<View3DInventor*>(oldview);
|
||||
std::string overrideMode = firstView->getViewer()->getOverrideMode();
|
||||
view3D->getViewer()->setOverrideMode(overrideMode);
|
||||
|
||||
view3D->getViewer()->setAxisCross(firstView->getViewer()->hasAxisCross());
|
||||
|
||||
// attach the viewproviders. we need to make sure that we only attach the toplevel ones
|
||||
// and not viewproviders which are claimed by other providers. To ensure this we first
|
||||
// add all providers and then remove the ones already claimed
|
||||
std::map<const App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator It1;
|
||||
std::vector<App::DocumentObject*> child_vps;
|
||||
for (It1=d->_ViewProviderMap.begin();It1!=d->_ViewProviderMap.end();++It1) {
|
||||
view3D->getViewer()->addViewProvider(It1->second);
|
||||
std::vector<App::DocumentObject*> children = It1->second->claimChildren3D();
|
||||
child_vps.insert(child_vps.end(), children.begin(), children.end());
|
||||
}
|
||||
std::map<std::string,ViewProvider*>::const_iterator It2;
|
||||
for (It2=d->_ViewProviderMapAnnotation.begin();It2!=d->_ViewProviderMapAnnotation.end();++It2) {
|
||||
view3D->getViewer()->addViewProvider(It2->second);
|
||||
std::vector<App::DocumentObject*> children = It2->second->claimChildren3D();
|
||||
child_vps.insert(child_vps.end(), children.begin(), children.end());
|
||||
}
|
||||
|
||||
for (App::DocumentObject* obj : child_vps)
|
||||
view3D->getViewer()->removeViewProvider(getViewProvider(obj));
|
||||
|
||||
view3D->setWindowTitle(oldview->windowTitle());
|
||||
view3D->setWindowModified(oldview->isWindowModified());
|
||||
view3D->setWindowIcon(oldview->windowIcon());
|
||||
view3D->resize(oldview->size());
|
||||
|
||||
// FIXME: Add parameter to define behaviour by the calling instance
|
||||
// View provider editing
|
||||
if (d->_editViewProvider) {
|
||||
firstView->getViewer()->resetEditingViewProvider();
|
||||
view3D->getViewer()->setEditingViewProvider(d->_editViewProvider, d->_editMode);
|
||||
}
|
||||
|
||||
return view3D;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *Document::getCameraSettings() const {
|
||||
return cameraSettings.size()>10?cameraSettings.c_str()+10:cameraSettings.c_str();
|
||||
}
|
||||
|
||||
@@ -58,6 +58,12 @@ class Application;
|
||||
class DocumentPy;
|
||||
class TransactionViewProvider;
|
||||
|
||||
enum class CreateViewMode
|
||||
{
|
||||
Normal,
|
||||
Clone
|
||||
};
|
||||
|
||||
/** The Gui Document
|
||||
* This is the document on GUI level. Its main responsibility is keeping
|
||||
* track off open windows for a document and warning on unsaved closes.
|
||||
@@ -186,9 +192,7 @@ public:
|
||||
Gui::MDIView* getViewOfViewProvider(const Gui::ViewProvider*) const;
|
||||
Gui::MDIView* getViewOfNode(SoNode*) const;
|
||||
/// Create a new view
|
||||
MDIView *createView(const Base::Type& typeId);
|
||||
/// Create a clone of the given view
|
||||
Gui::MDIView* cloneView(Gui::MDIView*);
|
||||
MDIView* createView(const Base::Type& typeId, CreateViewMode mode = CreateViewMode::Normal);
|
||||
/** send messages to the active view
|
||||
* Send a specific massage to the active view and is able to receive a
|
||||
* return message
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef _PreComp_
|
||||
# include <boost/signals2.hpp>
|
||||
# include <boost/core/ignore_unused.hpp>
|
||||
# include <QAction>
|
||||
# include <QApplication>
|
||||
# include <QEvent>
|
||||
# include <QCloseEvent>
|
||||
@@ -129,6 +130,11 @@ void MDIView::deleteSelf()
|
||||
_pcDocument = nullptr;
|
||||
}
|
||||
|
||||
MDIView* MDIView::clone()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* MDIView::getPyObject()
|
||||
{
|
||||
if (!pythonObject)
|
||||
@@ -207,7 +213,7 @@ bool MDIView::canClose()
|
||||
return true;
|
||||
}
|
||||
|
||||
void MDIView::closeEvent(QCloseEvent *e)
|
||||
void MDIView::closeEvent(QCloseEvent* e)
|
||||
{
|
||||
if (canClose()) {
|
||||
e->accept();
|
||||
@@ -353,7 +359,8 @@ QSize MDIView::minimumSizeHint () const
|
||||
return {400, 300};
|
||||
}
|
||||
|
||||
void MDIView::changeEvent(QEvent *e)
|
||||
|
||||
void MDIView::changeEvent(QEvent* e)
|
||||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::ActivationChange:
|
||||
@@ -377,6 +384,29 @@ void MDIView::changeEvent(QEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
bool MDIView::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
// As long as this widget is a top-level window (either in 'TopLevel' or 'FullScreen' mode) we
|
||||
// need to be notified when an action is added to a widget. This action must also be added to
|
||||
// this window to allow one to make use of its shortcut (if defined).
|
||||
// Note: We don't need to care about removing an action if its parent widget gets destroyed.
|
||||
// This does the action itself for us.
|
||||
|
||||
if (watched != this && event->type() == QEvent::ActionAdded) {
|
||||
auto actionEvent = static_cast<QActionEvent*>(event);
|
||||
QAction* action = actionEvent->action();
|
||||
|
||||
if (!action->isSeparator()) {
|
||||
QList<QAction*> acts = actions();
|
||||
if (!acts.contains(action)) {
|
||||
addAction(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(Q_WS_X11)
|
||||
// To fix bug #0000345 move function declaration to here
|
||||
extern void qt_x11_wait_for_window_manager( QWidget* w ); // defined in qwidget_x11.cpp
|
||||
@@ -384,36 +414,43 @@ extern void qt_x11_wait_for_window_manager( QWidget* w ); // defined in qwidget_
|
||||
|
||||
void MDIView::setCurrentViewMode(ViewMode mode)
|
||||
{
|
||||
ViewMode oldmode = MDIView::currentViewMode();
|
||||
if (oldmode == mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
// go to normal mode
|
||||
case Child:
|
||||
{
|
||||
if (this->currentMode == FullScreen) {
|
||||
if (currentMode == FullScreen) {
|
||||
showNormal();
|
||||
setWindowFlags(windowFlags() & ~Qt::Window);
|
||||
}
|
||||
else if (this->currentMode == TopLevel) {
|
||||
this->wstate = windowState();
|
||||
else if (currentMode == TopLevel) {
|
||||
wstate = windowState();
|
||||
setWindowFlags( windowFlags() & ~Qt::Window );
|
||||
}
|
||||
|
||||
if (this->currentMode != Child) {
|
||||
this->currentMode = Child;
|
||||
if (currentMode != Child) {
|
||||
currentMode = Child;
|
||||
getMainWindow()->addWindow(this);
|
||||
getMainWindow()->activateWindow();
|
||||
update();
|
||||
}
|
||||
} break;
|
||||
|
||||
// go to top-level mode
|
||||
case TopLevel:
|
||||
{
|
||||
if (this->currentMode == Child) {
|
||||
if (qobject_cast<QMdiSubWindow*>(this->parentWidget()))
|
||||
getMainWindow()->removeWindow(this,false);
|
||||
if (currentMode == Child) {
|
||||
if (qobject_cast<QMdiSubWindow*>(parentWidget()))
|
||||
getMainWindow()->removeWindow(this, false);
|
||||
setWindowFlags(windowFlags() | Qt::Window);
|
||||
setParent(nullptr, Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinMaxButtonsHint);
|
||||
if (this->wstate & Qt::WindowMaximized)
|
||||
setParent(nullptr,
|
||||
Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
|
||||
| Qt::WindowMinMaxButtonsHint);
|
||||
if (wstate & Qt::WindowMaximized)
|
||||
showMaximized();
|
||||
else
|
||||
showNormal();
|
||||
@@ -424,35 +461,64 @@ void MDIView::setCurrentViewMode(ViewMode mode)
|
||||
#endif
|
||||
activateWindow();
|
||||
}
|
||||
else if (this->currentMode == FullScreen) {
|
||||
if (this->wstate & Qt::WindowMaximized)
|
||||
else if (currentMode == FullScreen) {
|
||||
if (wstate & Qt::WindowMaximized)
|
||||
showMaximized();
|
||||
else
|
||||
showNormal();
|
||||
}
|
||||
|
||||
this->currentMode = TopLevel;
|
||||
currentMode = TopLevel;
|
||||
update();
|
||||
} break;
|
||||
|
||||
// go to fullscreen mode
|
||||
case FullScreen:
|
||||
{
|
||||
if (this->currentMode == Child) {
|
||||
if (qobject_cast<QMdiSubWindow*>(this->parentWidget()))
|
||||
getMainWindow()->removeWindow(this,false);
|
||||
if (currentMode == Child) {
|
||||
if (qobject_cast<QMdiSubWindow*>(parentWidget()))
|
||||
getMainWindow()->removeWindow(this, false);
|
||||
setWindowFlags(windowFlags() | Qt::Window);
|
||||
setParent(nullptr, Qt::Window);
|
||||
showFullScreen();
|
||||
}
|
||||
else if (this->currentMode == TopLevel) {
|
||||
this->wstate = windowState();
|
||||
else if (currentMode == TopLevel) {
|
||||
wstate = windowState();
|
||||
showFullScreen();
|
||||
}
|
||||
|
||||
this->currentMode = FullScreen;
|
||||
currentMode = FullScreen;
|
||||
update();
|
||||
} break;
|
||||
}
|
||||
|
||||
|
||||
if (oldmode == Child) {
|
||||
// To make a global shortcut working from this window we need to add
|
||||
// all existing actions from the mainwindow and its sub-widgets
|
||||
|
||||
QList<QAction*> acts = getMainWindow()->findChildren<QAction*>();
|
||||
addActions(acts);
|
||||
|
||||
// To be notfified for new actions
|
||||
qApp->installEventFilter(this);
|
||||
}
|
||||
else if (mode == Child) {
|
||||
qApp->removeEventFilter(this);
|
||||
QList<QAction*> acts = actions();
|
||||
for (QAction* it : acts) {
|
||||
removeAction(it);
|
||||
}
|
||||
|
||||
// When switching from undocked to docked mode, the widget position is somehow not updated
|
||||
// correctly. In this case mapToGlobal(Point()) returns {0, 0} even though the widget is
|
||||
// clearly not at the top-left corner of the screen. We fix this by briefly changing the
|
||||
// maximum size of the widget.
|
||||
|
||||
const auto oldsize = maximumSize();
|
||||
setMaximumSize({1, 1});
|
||||
setMaximumSize(oldsize);
|
||||
}
|
||||
}
|
||||
|
||||
QString MDIView::buildWindowTitle() const
|
||||
|
||||
@@ -70,6 +70,8 @@ public:
|
||||
*/
|
||||
~MDIView() override;
|
||||
|
||||
virtual MDIView* clone();
|
||||
|
||||
/// get called when the document is updated
|
||||
void onRelabel(Gui::Document *pDoc) override;
|
||||
virtual void viewAll();
|
||||
@@ -177,9 +179,11 @@ protected Q_SLOTS:
|
||||
virtual void windowStateChanged(QWidget*);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e) override;
|
||||
void closeEvent(QCloseEvent* e) override;
|
||||
/** \internal */
|
||||
void changeEvent(QEvent *e) override;
|
||||
void changeEvent(QEvent* e) override;
|
||||
|
||||
bool eventFilter(QObject* watched, QEvent* e) override;
|
||||
|
||||
protected:
|
||||
PyObject* pythonObject;
|
||||
|
||||
@@ -1234,6 +1234,7 @@ void MainWindow::removeWindow(Gui::MDIView* view, bool close)
|
||||
auto subwindow = qobject_cast<QMdiSubWindow*>(parent);
|
||||
if(subwindow && d->mdiArea->subWindowList().contains(subwindow)) {
|
||||
subwindow->setParent(nullptr);
|
||||
subwindow->deleteLater();
|
||||
|
||||
assert(!d->mdiArea->subWindowList().contains(subwindow));
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <string>
|
||||
# include <QAction>
|
||||
# include <QApplication>
|
||||
# include <QKeyEvent>
|
||||
# include <QEvent>
|
||||
@@ -39,6 +38,7 @@
|
||||
# include <QPrintDialog>
|
||||
# include <QPrintPreviewDialog>
|
||||
# include <QStackedWidget>
|
||||
# include <QSurfaceFormat>
|
||||
# include <QTimer>
|
||||
# include <QUrl>
|
||||
# include <QWindow>
|
||||
@@ -94,9 +94,12 @@ void GLOverlayWidget::paintEvent(QPaintEvent*)
|
||||
|
||||
TYPESYSTEM_SOURCE_ABSTRACT(Gui::View3DInventor,Gui::MDIView)
|
||||
|
||||
View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent,
|
||||
const QOpenGLWidget* sharewidget, Qt::WindowFlags wflags)
|
||||
: MDIView(pcDocument, parent, wflags), _viewerPy(nullptr)
|
||||
View3DInventor::View3DInventor(Gui::Document* pcDocument,
|
||||
QWidget* parent,
|
||||
const QOpenGLWidget* sharewidget,
|
||||
Qt::WindowFlags wflags)
|
||||
: MDIView(pcDocument, parent, wflags)
|
||||
, _viewerPy(nullptr)
|
||||
{
|
||||
stack = new QStackedWidget(this);
|
||||
// important for highlighting
|
||||
@@ -189,6 +192,30 @@ void View3DInventor::deleteSelf()
|
||||
MDIView::deleteSelf();
|
||||
}
|
||||
|
||||
View3DInventor* View3DInventor::clone()
|
||||
{
|
||||
auto mdiView = _pcDocument->createView(getClassTypeId(), CreateViewMode::Clone);
|
||||
auto view3D = static_cast<View3DInventor*>(mdiView);
|
||||
|
||||
view3D->getViewer()->setAxisCross(getViewer()->hasAxisCross());
|
||||
|
||||
view3D->setWindowTitle(windowTitle());
|
||||
view3D->setWindowIcon(windowIcon());
|
||||
view3D->resize(size());
|
||||
|
||||
// FIXME: Add parameter to define behaviour by the calling instance
|
||||
// View provider editing
|
||||
|
||||
int editMode;
|
||||
ViewProvider* editViewProvider = _pcDocument->getInEdit(nullptr, nullptr, &editMode);
|
||||
if (editViewProvider) {
|
||||
getViewer()->resetEditingViewProvider();
|
||||
view3D->getViewer()->setEditingViewProvider(editViewProvider, editMode);
|
||||
}
|
||||
|
||||
return view3D;
|
||||
}
|
||||
|
||||
PyObject *View3DInventor::getPyObject()
|
||||
{
|
||||
if (!_viewerPy)
|
||||
@@ -722,33 +749,27 @@ void View3DInventor::dragEnterEvent (QDragEnterEvent * e)
|
||||
e->ignore();
|
||||
}
|
||||
|
||||
void View3DInventor::setCurrentViewMode(ViewMode newmode)
|
||||
void View3DInventor::setCurrentViewMode(ViewMode mode)
|
||||
{
|
||||
ViewMode oldmode = MDIView::currentViewMode();
|
||||
if (oldmode == newmode)
|
||||
ViewMode oldmode = currentViewMode();
|
||||
if (mode == oldmode) {
|
||||
return;
|
||||
|
||||
if (newmode == Child) {
|
||||
// Fix in two steps:
|
||||
// The mdi view got a QWindow when it became a top-level widget and when resetting it to a child widget
|
||||
// the QWindow must be deleted because it has an impact on resize events and may break the layout of
|
||||
// mdi view inside the QMdiSubWindow.
|
||||
// In the second step below the layout must be invalidated after it's again a child widget to make sure
|
||||
// the mdi view fits into the QMdiSubWindow.
|
||||
QWindow* winHandle = this->windowHandle();
|
||||
if (winHandle)
|
||||
winHandle->destroy();
|
||||
}
|
||||
|
||||
MDIView::setCurrentViewMode(newmode);
|
||||
if (mode == Child) {
|
||||
// Fix in two steps:
|
||||
// The mdi view got a QWindow when it became a top-level widget and when resetting it to a
|
||||
// child widget the QWindow must be deleted because it has an impact on resize events and
|
||||
// may break the layout of mdi view inside the QMdiSubWindow. In the second step below the
|
||||
// layout must be invalidated after it's again a child widget to make sure the mdi view fits
|
||||
// into the QMdiSubWindow.
|
||||
QWindow* winHandle = this->windowHandle();
|
||||
if (winHandle) {
|
||||
winHandle->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// Internally the QOpenGLWidget switches of the multi-sampling and there is no
|
||||
// way to switch it on again. So as a workaround we just re-create a new viewport
|
||||
// The method is private but defined as slot to avoid to call it by accident.
|
||||
//int index = _viewer->metaObject()->indexOfMethod("replaceViewport()");
|
||||
//if (index >= 0) {
|
||||
// _viewer->qt_metacall(QMetaObject::InvokeMetaMethod, index, 0);
|
||||
//}
|
||||
MDIView::setCurrentViewMode(mode);
|
||||
|
||||
// This widget becomes the focus proxy of the embedded GL widget if we leave
|
||||
// the 'Child' mode. If we reenter 'Child' mode the focus proxy is reset to 0.
|
||||
@@ -760,26 +781,18 @@ void View3DInventor::setCurrentViewMode(ViewMode newmode)
|
||||
//
|
||||
// It is important to set the focus proxy to get all key events otherwise we would lose
|
||||
// control after redirecting the first key event to the GL widget.
|
||||
|
||||
if (oldmode == Child) {
|
||||
// To make a global shortcut working from this window we need to add
|
||||
// all existing actions from the mainwindow and its sub-widgets
|
||||
QList<QAction*> acts = getMainWindow()->findChildren<QAction*>();
|
||||
this->addActions(acts);
|
||||
_viewer->getGLWidget()->setFocusProxy(this);
|
||||
// To be notfified for new actions
|
||||
qApp->installEventFilter(this);
|
||||
}
|
||||
else if (newmode == Child) {
|
||||
else if (mode == Child) {
|
||||
_viewer->getGLWidget()->setFocusProxy(nullptr);
|
||||
qApp->removeEventFilter(this);
|
||||
QList<QAction*> acts = this->actions();
|
||||
for (QAction* it : acts)
|
||||
this->removeAction(it);
|
||||
|
||||
// Step two
|
||||
auto mdi = qobject_cast<QMdiSubWindow*>(parentWidget());
|
||||
if (mdi && mdi->layout())
|
||||
if (mdi && mdi->layout()) {
|
||||
mdi->layout()->invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -874,27 +887,6 @@ RayPickInfo View3DInventor::getObjInfoRay(Base::Vector3d* startvec, Base::Vector
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool View3DInventor::eventFilter(QObject* watched, QEvent* e)
|
||||
{
|
||||
// As long as this widget is a top-level window (either in 'TopLevel' or 'FullScreen' mode) we
|
||||
// need to be notified when an action is added to a widget. This action must also be added to
|
||||
// this window to allow one to make use of its shortcut (if defined).
|
||||
// Note: We don't need to care about removing an action if its parent widget gets destroyed.
|
||||
// This does the action itself for us.
|
||||
if (watched != this && e->type() == QEvent::ActionAdded) {
|
||||
auto a = static_cast<QActionEvent*>(e);
|
||||
QAction* action = a->action();
|
||||
|
||||
if (!action->isSeparator()) {
|
||||
QList<QAction*> actions = this->actions();
|
||||
if (!actions.contains(action))
|
||||
this->addAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void View3DInventor::keyPressEvent (QKeyEvent* e)
|
||||
{
|
||||
// See StdViewDockUndockFullscreen::activated()
|
||||
|
||||
@@ -85,6 +85,8 @@ public:
|
||||
View3DInventor(Gui::Document* pcDocument, QWidget* parent, const QOpenGLWidget* sharewidget = nullptr, Qt::WindowFlags wflags=Qt::WindowFlags());
|
||||
~View3DInventor() override;
|
||||
|
||||
View3DInventor* clone() override;
|
||||
|
||||
/// Message handler
|
||||
bool onMsg(const char* pMsg, const char** ppReturn) override;
|
||||
bool onHasMsg(const char* pMsg) const override;
|
||||
@@ -132,9 +134,6 @@ public Q_SLOTS:
|
||||
protected Q_SLOTS:
|
||||
void stopAnimating();
|
||||
|
||||
public:
|
||||
bool eventFilter(QObject*, QEvent* ) override;
|
||||
|
||||
private:
|
||||
void applySettings();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user