/*************************************************************************** * Copyright (c) 2013 Luke Parry * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ # include # include # include # include # include # include # include # include # include # include # include #include # include #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Rez.h" #include "QGIDrawingTemplate.h" #include "QGITemplate.h" #include "QGISVGTemplate.h" #include "TemplateTextField.h" #include "QGIViewCollection.h" #include "QGIViewDimension.h" #include "QGIViewBalloon.h" #include "QGIProjGroup.h" #include "QGIViewPart.h" #include "QGIViewSection.h" #include "QGIViewAnnotation.h" #include "QGIViewSymbol.h" #include "QGIViewClip.h" #include "QGIViewSpreadsheet.h" #include "QGIViewImage.h" #include "QGIFace.h" #include "QGILeaderLine.h" #include "QGIRichAnno.h" #include "ZVALUE.h" #include "ViewProviderPage.h" #include "QGVPage.h" using namespace TechDrawGui; QGVPage::QGVPage(ViewProviderPage *vp, QGraphicsScene* s, QWidget *parent) : QGraphicsView(parent), pageTemplate(0), m_renderer(Native), drawBkg(true), m_vpPage(0) // , // m_borderState(true) { assert(vp); m_vpPage = vp; const char* name = vp->getDrawPage()->getNameInDocument(); setObjectName(QString::fromLocal8Bit(name)); m_vpPage->setGraphicsView(this); setScene(s); setMouseTracking(true); viewport()->setMouseTracking(true); setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); setCacheMode(QGraphicsView::CacheBackground); Base::Reference hGrp = App::GetApplication().GetUserParameter() .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("View"); m_atCursor = hGrp->GetBool("ZoomAtCursor", 1l); m_invertZoom = hGrp->GetBool("InvertZoom", 0l); m_zoomIncrement = hGrp->GetFloat("ZoomStep",0.02); hGrp = App::GetApplication().GetUserParameter() .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General"); m_reversePan = hGrp->GetInt("KbPan",1); m_reverseScroll = hGrp->GetInt("KbScroll",1); if (m_atCursor) { setResizeAnchor(AnchorUnderMouse); setTransformationAnchor(AnchorUnderMouse); } else { setResizeAnchor(AnchorViewCenter); setTransformationAnchor(AnchorViewCenter); } setAlignment(Qt::AlignCenter); setDragMode(ScrollHandDrag); setCursor(QCursor(Qt::ArrowCursor)); setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); bkgBrush = new QBrush(getBackgroundColor()); balloonIndex = 1; balloonPlacing(false); resetCachedContent(); } QGVPage::~QGVPage() { delete bkgBrush; } void QGVPage::drawBackground(QPainter *p, const QRectF &) { //Note: Background is not part of scene() if(!drawBkg) return; if(!m_vpPage) { return; } if (!m_vpPage->getDrawPage()) { //Base::Console().Log("TROUBLE - QGVP::drawBackground - no Page Object!\n"); return; } p->save(); p->resetTransform(); p->setBrush(*bkgBrush); p->drawRect(viewport()->rect().adjusted(-2,-2,2,2)); //just bigger than viewport to prevent artifacts // Default to A3 landscape, though this is currently relevant // only for opening corrupt docs, etc. float pageWidth = 420, pageHeight = 297; if ( m_vpPage->getDrawPage()->hasValidTemplate() ) { pageWidth = Rez::guiX(m_vpPage->getDrawPage()->getPageWidth()); pageHeight = Rez::guiX(m_vpPage->getDrawPage()->getPageHeight()); } // Draw the white page QRectF paperRect(0, -pageHeight, pageWidth, pageHeight); QPolygon poly = mapFromScene(paperRect); QBrush pageBrush(Qt::white); p->setBrush(pageBrush); p->drawRect(poly.boundingRect()); p->restore(); } //! retrieve the QGIView objects currently in the scene std::vector QGVPage::getViews() const { std::vector result; QList items = scene()->items(); for (auto& v:items) { QGIView* qv = dynamic_cast(v); if (qv != nullptr) { result.push_back(qv); } } return result; } int QGVPage::addQView(QGIView *view) { //don't add twice! QGIView* existing = getQGIVByName(view->getViewName()); if (existing == nullptr) { auto ourScene( scene() ); assert(ourScene); ourScene->addItem(view); // Find if it belongs to a parent QGIView *parent = 0; parent = findParent(view); QPointF viewPos(Rez::guiX(view->getViewObject()->X.getValue()), Rez::guiX(view->getViewObject()->Y.getValue() * -1)); if(parent) { // move child view to center of parent QPointF posRef(0.,0.); QPointF mapPos = view->mapToItem(parent, posRef); view->moveBy(-mapPos.x(), -mapPos.y()); parent->addToGroup(view); } view->setPos(viewPos); view->updateView(true); } return 0; } int QGVPage::removeQView(QGIView *view) { if (view != nullptr) { removeQViewFromScene(view); delete view; } return 0; } int QGVPage::removeQViewByName(const char* name) { std::vector items = getViews(); QString qsName = QString::fromUtf8(name); bool found = false; QGIView* ourItem = nullptr; for (auto& i:items) { if (qsName == i->data(1).toString()) { //is there a QGIV with this name in scene? found = true; ourItem = i; break; } } if (found) { int balloonItemType = QGraphicsItem::UserType + 140; if (ourItem->type() == balloonItemType) { QGIViewBalloon* balloon = dynamic_cast(ourItem); balloon->disconnect(); } removeQViewFromScene(ourItem); delete ourItem; } return 0; } void QGVPage::removeQViewFromScene(QGIView *view) { QGraphicsItemGroup* grp = view->group(); if (grp) { grp->removeFromGroup(view); } if (view->parentItem()) { //not top level view->setParentItem(0); } if (view->scene()) { view->scene()->removeItem(view); } } QGIView * QGVPage::addViewPart(TechDraw::DrawViewPart *part) { QGIView* existing = findQViewForDocObj(part); if (existing != nullptr) { return existing; } auto viewPart( new QGIViewPart ); viewPart->setViewPartFeature(part); addQView(viewPart); return viewPart; } QGIView * QGVPage::addViewSection(TechDraw::DrawViewPart *part) { auto viewSection( new QGIViewSection ); viewSection->setViewPartFeature(part); addQView(viewSection); return viewSection; } QGIView * QGVPage::addProjectionGroup(TechDraw::DrawProjGroup *view) { auto qview( new QGIProjGroup ); qview->setViewFeature(view); addQView(qview); return qview; } QGIView * QGVPage::addDrawView(TechDraw::DrawView *view) { auto qview( new QGIView ); qview->setViewFeature(view); addQView(qview); return qview; } QGIView * QGVPage::addDrawViewCollection(TechDraw::DrawViewCollection *view) { auto qview( new QGIViewCollection ); qview->setViewFeature(view); addQView(qview); return qview; } // TODO change to (App?) annotation object ?? QGIView * QGVPage::addDrawViewAnnotation(TechDraw::DrawViewAnnotation *view) { auto qview( new QGIViewAnnotation ); qview->setViewAnnoFeature(view); addQView(qview); return qview; } QGIView * QGVPage::addDrawViewSymbol(TechDraw::DrawViewSymbol *view) { auto qview( new QGIViewSymbol ); qview->setViewFeature(view); addQView(qview); return qview; } QGIView * QGVPage::addDrawViewClip(TechDraw::DrawViewClip *view) { auto qview( new QGIViewClip ); qview->setPosition(Rez::guiX(view->X.getValue()), Rez::guiX(view->Y.getValue())); qview->setViewFeature(view); addQView(qview); return qview; } QGIView * QGVPage::addDrawViewSpreadsheet(TechDraw::DrawViewSpreadsheet *view) { auto qview( new QGIViewSpreadsheet ); qview->setViewFeature(view); addQView(qview); return qview; } QGIView * QGVPage::addDrawViewImage(TechDraw::DrawViewImage *view) { auto qview( new QGIViewImage ); qview->setViewFeature(view); addQView(qview); return qview; } QGIView * QGVPage::addViewBalloon(TechDraw::DrawViewBalloon *balloon) { auto balloonGroup( new QGIViewBalloon ); auto ourScene( scene() ); assert(ourScene); ourScene->addItem(balloonGroup); balloonGroup->setViewPartFeature(balloon); // Find if it belongs to a parent QGIView *parent = 0; parent = findParent(balloonGroup); if(balloon->OriginIsSet.getValue() == false) { if(parent) { balloonPlacing(true); QApplication::setOverrideCursor(QCursor(QPixmap(QString::fromUtf8(":/icons/cursor-balloon.png")),0,32)); balloonGroup->connect(parent); addBalloonToParent(balloonGroup,parent); } } return balloonGroup; } void QGVPage::addBalloonToParent(QGIViewBalloon* balloon, QGIView* parent) { assert(balloon); assert(parent); //blow up if we don't have Dimension or Parent QPointF posRef(0.,0.); QPointF mapPos = balloon->mapToItem(parent, posRef); balloon->moveBy(-mapPos.x(), -mapPos.y()); parent->addToGroup(balloon); balloon->setZValue(ZVALUE::DIMENSION); } QGIView * QGVPage::addViewDimension(TechDraw::DrawViewDimension *dim) { auto dimGroup( new QGIViewDimension ); auto ourScene( scene() ); assert(ourScene); ourScene->addItem(dimGroup); dimGroup->setViewPartFeature(dim); // Find if it belongs to a parent QGIView *parent = 0; parent = findParent(dimGroup); if(parent) { addDimToParent(dimGroup,parent); } return dimGroup; } void QGVPage::addDimToParent(QGIViewDimension* dim, QGIView* parent) { assert(dim); assert(parent); //blow up if we don't have Dimension or Parent QPointF posRef(0.,0.); QPointF mapPos = dim->mapToItem(parent, posRef); dim->moveBy(-mapPos.x(), -mapPos.y()); parent->addToGroup(dim); dim->setZValue(ZVALUE::DIMENSION); } QGIView * QGVPage::addViewLeader(TechDraw::DrawLeaderLine *leader) { // Base::Console().Message("QGVP::addViewLeader(%s)\n",leader->getNameInDocument()); QGILeaderLine* leaderGroup = nullptr; App::DocumentObject* parentObj = leader->LeaderParent.getValue(); TechDraw::DrawView* parentDV = dynamic_cast(parentObj); //NOTE: if Leaders are ever allowed to not be attached to a View, this next bit will have to change if (parentDV != nullptr) { QGIView* parentQV = findQViewForDocObj(parentObj); if (parentQV != nullptr) { leaderGroup = new QGILeaderLine(parentQV, leader); leaderGroup->updateView(true); //this is different from everybody else, //but it works. return leaderGroup; } } else { throw Base::TypeError("QGVP::addViewLeader - parent DV has no QGIV"); } return nullptr; } void QGVPage::addLeaderToParent(QGILeaderLine* lead, QGIView* parent) { assert(lead); assert(parent); //blow up if we don't have Leader or Parent QPointF posRef(0.,0.); QPointF mapPos = lead->mapToItem(parent, posRef); lead->moveBy(-mapPos.x(), -mapPos.y()); parent->addToGroup(lead); //vs lead->setParentItem(parent)?? lead->setZValue(ZVALUE::DIMENSION); } QGIView * QGVPage::addRichAnno(TechDraw::DrawRichAnno* anno) { QGIRichAnno* annoGroup = nullptr; TechDraw::DrawView* parentDV = nullptr; App::DocumentObject* parentObj = anno->AnnoParent.getValue(); if (parentObj != nullptr) { parentDV = dynamic_cast(parentObj); } if (parentDV != nullptr) { QGIView* parentQV = findQViewForDocObj(parentObj); annoGroup = new QGIRichAnno(parentQV, anno); annoGroup->updateView(true); } else { annoGroup = new QGIRichAnno(nullptr, anno); if (annoGroup->scene() == nullptr) { scene()->addItem(annoGroup); } annoGroup->updateView(true); } return annoGroup; } //! find the graphic for a DocumentObject QGIView * QGVPage::findQViewForDocObj(App::DocumentObject *obj) const { if(obj) { const std::vector qviews = getViews(); for(std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { if(strcmp(obj->getNameInDocument(), (*it)->getViewName()) == 0) return *it; } } return 0; } //! find the graphic for DocumentObject with name QGIView* QGVPage::getQGIVByName(std::string name) { QList qgItems = scene()->items(); QList::iterator it = qgItems.begin(); for (; it != qgItems.end(); it++) { QGIView* qv = dynamic_cast((*it)); if (qv) { const char* qvName = qv->getViewName(); if(name.compare(qvName) == 0) { return (qv); } } } return nullptr; } QGIView * QGVPage::findParent(QGIView *view) const { const std::vector qviews = getViews(); TechDraw::DrawView *myFeat = view->getViewObject(); //If type is dimension we check references first TechDraw::DrawViewDimension *dim = 0; dim = dynamic_cast(myFeat); if(dim) { std::vector objs = dim->References2D.getValues(); if(objs.size() > 0) { std::vector objs = dim->References2D.getValues(); // Attach the dimension to the first object's group for(std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { if(strcmp((*it)->getViewName(), objs.at(0)->getNameInDocument()) == 0) { return *it; } } } } //If type is balloon we check references first TechDraw::DrawViewBalloon *balloon = 0; balloon = dynamic_cast(myFeat); if(balloon) { App::DocumentObject* obj = balloon->sourceView.getValue(); if(obj) { // Attach the dimension to the first object's group for(std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { if(strcmp((*it)->getViewName(), obj->getNameInDocument()) == 0) { return *it; } } } } // Check if part of view collection for(std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { QGIViewCollection *grp = 0; grp = dynamic_cast(*it); if(grp) { TechDraw::DrawViewCollection *collection = 0; collection = dynamic_cast(grp->getViewObject()); if(collection) { std::vector objs = collection->Views.getValues(); for( std::vector::iterator it = objs.begin(); it != objs.end(); ++it) { if(strcmp(myFeat->getNameInDocument(), (*it)->getNameInDocument()) == 0) return grp; } } } } //If type is LeaderLine we check LeaderParent TechDraw::DrawLeaderLine *lead = 0; lead = dynamic_cast(myFeat); if(lead) { App::DocumentObject* obj = lead->LeaderParent.getValue(); if(obj != nullptr) { std::string parentName = obj->getNameInDocument(); for(std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { if(strcmp((*it)->getViewName(), parentName.c_str()) == 0) { return *it; } } } } // Not found a parent return nullptr; } void QGVPage::setPageTemplate(TechDraw::DrawTemplate *obj) { removeTemplate(); if(obj->isDerivedFrom(TechDraw::DrawParametricTemplate::getClassTypeId())) { pageTemplate = new QGIDrawingTemplate(scene()); } else if(obj->isDerivedFrom(TechDraw::DrawSVGTemplate::getClassTypeId())) { pageTemplate = new QGISVGTemplate(scene()); } pageTemplate->setTemplate(obj); pageTemplate->updateView(); } QGITemplate* QGVPage::getTemplate() const { return pageTemplate; } void QGVPage::removeTemplate() { if(pageTemplate) { scene()->removeItem(pageTemplate); pageTemplate->deleteLater(); pageTemplate = 0; } } void QGVPage::setRenderer(RendererType type) { m_renderer = type; if (m_renderer == OpenGL) { #ifndef QT_NO_OPENGL setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); #endif } else { setViewport(new QWidget); } } void QGVPage::setHighQualityAntialiasing(bool highQualityAntialiasing) { #ifndef QT_NO_OPENGL setRenderHint(QPainter::HighQualityAntialiasing, highQualityAntialiasing); #else Q_UNUSED(highQualityAntialiasing); #endif } void QGVPage::refreshViews(void) { // Base::Console().Message("QGVP::refreshViews()\n"); QList list = scene()->items(); for (QList::iterator it = list.begin(); it != list.end(); ++it) { QGIView *itemView = dynamic_cast(*it); if(itemView) { itemView->updateView(true); } } } void QGVPage::toggleHatch(bool enable) { QList sceneItems = scene()->items(); for (auto& qgi:sceneItems) { QGIViewPart* qgiPart = dynamic_cast(qgi); if(qgiPart) { QList partChildren = qgiPart->childItems(); int faceItemType = QGraphicsItem::UserType + 104; for (auto& c:partChildren) { if (c->type() == faceItemType) { static_cast(c)->toggleSvg(enable); } } } } } void QGVPage::saveSvg(QString filename) { // TODO: We only have m_vpPage because constructor gets passed a view provider... //NOTE: this makes wrong size pages in low-Rez TechDraw::DrawPage *page( m_vpPage->getDrawPage() ); const QString docName( QString::fromUtf8(page->getDocument()->getName()) ); const QString pageName( QString::fromUtf8(page->getNameInDocument()) ); QString svgDescription = tr("Drawing page:") + QString::fromUtf8(" ") + pageName + tr(" exported from FreeCAD document:") + QString::fromUtf8(" ") + docName; QSvgGenerator svgGen; QTemporaryFile* tempFile = new QTemporaryFile();; svgGen.setOutputDevice(tempFile); svgGen.setSize(QSize((int) Rez::guiX(page->getPageWidth()), (int) Rez::guiX(page->getPageHeight()))); //expects pixels, gets mm //"By default this property is set to QSize(-1, -1), which indicates that the generator should not output // the width and height attributes of the element." >> but Inkscape won't read it without size info?? svgGen.setViewBox(QRect(0, 0, Rez::guiX(page->getPageWidth()), Rez::guiX(page->getPageHeight()))); svgGen.setResolution(Rez::guiX(25.4)); // docs say this is DPI. Rez::guiX(1dot/mm) so 254 dpi? svgGen.setTitle(QObject::tr("FreeCAD SVG Export")); svgGen.setDescription(svgDescription); Gui::Selection().clearSelection(); bool saveState = m_vpPage->getFrameState(); m_vpPage->setFrameState(false); m_vpPage->setTemplateMarkers(false); toggleHatch(false); refreshViews(); viewport()->repaint(); double width = Rez::guiX(page->getPageWidth()); double height = Rez::guiX(page->getPageHeight()); QRectF sourceRect(0.0,-height,width,height); QRectF targetRect; Gui::Selection().clearSelection(); QPainter p; p.begin(&svgGen); scene()->render(&p, targetRect,sourceRect); p.end(); m_vpPage->setFrameState(saveState); m_vpPage->setTemplateMarkers(saveState); toggleHatch(true); refreshViews(); viewport()->repaint(); tempFile->close(); postProcessXml(tempFile, filename, pageName); } void QGVPage::postProcessXml(QTemporaryFile* tempFile, QString fileName, QString pageName) { QDomDocument doc(QString::fromUtf8("SvgDoc")); QFile file(tempFile->fileName()); if (!file.open(QIODevice::ReadOnly)) { Base::Console().Message("QGVPage::ppsvg - tempfile open error\n"); return; } if (!doc.setContent(&file)) { Base::Console().Message("QGVPage::ppsvg - xml error\n"); file.close(); return; } file.close(); QDomElement docElem = doc.documentElement(); //root QDomNode n = docElem.firstChild(); bool firstGroupFound = false; QString groupTag = QString::fromUtf8("g"); QDomElement e; while(!n.isNull()) { e = n.toElement(); // try to convert the node to an element. if(!e.isNull()) { if (!firstGroupFound) { if (e.tagName() == groupTag) { firstGroupFound = true; break; } } } n = n.nextSibling(); } e.setAttribute(QString::fromUtf8("id"),pageName); QFile outFile( fileName ); if( !outFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) { Base::Console().Message("QGVP::ppxml - failed to open file for writing: %s\n",qPrintable(fileName) ); } QTextStream stream( &outFile ); stream << doc.toString(); outFile.close(); delete tempFile; } void QGVPage::paintEvent(QPaintEvent *event) { if (m_renderer == Image) { if (m_image.size() != viewport()->size()) { m_image = QImage(viewport()->size(), QImage::Format_ARGB32_Premultiplied); } QPainter imagePainter(&m_image); QGraphicsView::render(&imagePainter); imagePainter.end(); QPainter p(viewport()); p.drawImage(0, 0, m_image); } else { QGraphicsView::paintEvent(event); } } void QGVPage::wheelEvent(QWheelEvent *event) { //Delta is the distance that the wheel is rotated, in eighths of a degree. //positive indicates rotation forwards away from the user; negative backwards toward the user. //Most mouse types work in steps of 15 degrees, in which case the delta value is a multiple of 120; i.e., 120 units * 1/8 = 15 degrees. //1 click = 15 degrees. 15 degrees = 120 deltas. delta/240 -> 1 click = 0.5 ==> factor = 1.2^0.5 = 1.095 // 1 click = -0.5 ==> factor = 1.2^-0.5 = 0.91 //so to change wheel direction, multiply (event->delta() / 240.0) by +/-1 double mouseBase = 1.2; //magic numbers. change for different mice? double mouseAdjust = -240.0; if (m_invertZoom) { mouseAdjust = -mouseAdjust; } QPointF center = mapToScene(viewport()->rect().center()); qreal factor = std::pow(mouseBase, event->delta() / mouseAdjust); scale(factor, factor); QPointF newCenter = mapToScene(viewport()->rect().center()); QPointF change = newCenter - center; translate(change.x(), change.y()); event->accept(); } void QGVPage::keyPressEvent(QKeyEvent *event) { if(event->modifiers().testFlag(Qt::ControlModifier)) { switch(event->key()) { case Qt::Key_Plus: { scale(1.0 + m_zoomIncrement, 1.0 + m_zoomIncrement); break; } case Qt::Key_Minus: { scale(1.0 - m_zoomIncrement, 1.0 - m_zoomIncrement); break; } default: { break; } } } if(event->modifiers().testFlag( Qt::NoModifier)) { switch(event->key()) { case Qt::Key_Left: { kbPanScroll(1, 0); break; } case Qt::Key_Up: { kbPanScroll(0, 1); break; } case Qt::Key_Right: { kbPanScroll(-1, 0); break; } case Qt::Key_Down: { kbPanScroll(0, -1); break; } default: { break; } } } QGraphicsView::keyPressEvent(event); } void QGVPage::kbPanScroll(int xMove, int yMove) { if (xMove != 0) { QScrollBar* hsb = horizontalScrollBar(); // int hRange = hsb->maximum() - hsb->minimum(); //default here is 100? // int hDelta = xMove/hRange int hStep = hsb->singleStep() * xMove * m_reversePan; int hNow = hsb->value(); hsb->setValue(hNow + hStep); } if (yMove != 0) { QScrollBar* vsb = verticalScrollBar(); int vStep = vsb->singleStep() * yMove * m_reverseScroll; int vNow = vsb->value(); vsb->setValue(vNow + vStep); } } void QGVPage::enterEvent(QEvent *event) { QGraphicsView::enterEvent(event); setCursor(Qt::ArrowCursor); viewport()->setCursor(Qt::ArrowCursor); } void QGVPage::leaveEvent(QEvent * event) { if(m_balloonPlacing) { // Get the window geometry & cursor position const QRect &rect = geometry(); QPoint position = this->mapFromGlobal(QCursor::pos()); // Check the bounds qint32 x = qBound(rect.left(), position.x(), rect.right()); qint32 y = qBound(rect.top(), position.y(), rect.bottom()); QPoint newPoint(x, y); // Adjust the cursor if (x != position.x() || y != position.y()) QCursor::setPos(this->mapToGlobal(newPoint)); event->accept(); } QGraphicsView::leaveEvent(event); } void QGVPage::mousePressEvent(QMouseEvent *event) { QGraphicsView::mousePressEvent(event); // setCursor(Qt::ArrowCursor); } void QGVPage::mouseMoveEvent(QMouseEvent *event) { QGraphicsView::mouseMoveEvent(event); } void QGVPage::mouseReleaseEvent(QMouseEvent *event) { QGraphicsView::mouseReleaseEvent(event); // setCursor(Qt::ArrowCursor); // viewport()->setCursor(Qt::ArrowCursor); } TechDraw::DrawPage* QGVPage::getDrawPage() { return m_vpPage->getDrawPage(); } QColor QGVPage::getBackgroundColor() { Base::Reference hGrp = App::GetApplication().GetUserParameter() .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors"); App::Color fcColor; fcColor.setPackedValue(hGrp->GetUnsigned("Background", 0x70707000)); return fcColor.asValue(); } #include