DrawingView.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2007 Jürgen Riegel <juergen.riegel@web.de>              *
00003  *                                                                         *
00004  *   This file is Drawing of the FreeCAD CAx development system.           *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A DrawingICULAR PURPOSE.  See the      *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <QAction>
00027 # include <QApplication>
00028 # include <QBuffer>
00029 # include <QContextMenuEvent>
00030 # include <QFileInfo>
00031 # include <QFileDialog>
00032 # include <QGLWidget>
00033 # include <QGraphicsRectItem>
00034 # include <QGraphicsSvgItem>
00035 # include <QGridLayout>
00036 # include <QGroupBox>
00037 # include <QListWidget>
00038 # include <QMenu>
00039 # include <QMessageBox>
00040 # include <QMouseEvent>
00041 # include <QPainter>
00042 # include <QPaintEvent>
00043 # include <QPrinter>
00044 # include <QPrintDialog>
00045 # include <QPrintPreviewDialog>
00046 # include <QPrintPreviewWidget>
00047 # include <QScrollArea>
00048 # include <QSlider>
00049 # include <QStatusBar>
00050 # include <QSvgRenderer>
00051 # include <QSvgWidget>
00052 # include <QWheelEvent>
00053 # include <strstream>
00054 # include <cmath>
00055 #endif
00056 
00057 #include "DrawingView.h"
00058 #include <Base/Stream.h>
00059 #include <Base/gzstream.h>
00060 #include <Gui/FileDialog.h>
00061 #include <Gui/WaitCursor.h>
00062 
00063 using namespace DrawingGui;
00064 
00065 SvgView::SvgView(QWidget *parent)
00066     : QGraphicsView(parent)
00067     , m_renderer(Native)
00068     , m_svgItem(0)
00069     , m_backgroundItem(0)
00070     , m_outlineItem(0)
00071 {
00072     setScene(new QGraphicsScene(this));
00073     setTransformationAnchor(AnchorUnderMouse);
00074     setDragMode(ScrollHandDrag);
00075 
00076     // Prepare background check-board pattern
00077     QPixmap tilePixmap(64, 64);
00078     tilePixmap.fill(Qt::white);
00079     QPainter tilePainter(&tilePixmap);
00080     QColor color(220, 220, 220);
00081     tilePainter.fillRect(0, 0, 32, 32, color);
00082     tilePainter.fillRect(32, 32, 32, 32, color);
00083     tilePainter.end();
00084 
00085     setBackgroundBrush(tilePixmap);
00086 }
00087 
00088 void SvgView::drawBackground(QPainter *p, const QRectF &)
00089 {
00090     p->save();
00091     p->resetTransform();
00092     p->drawTiledPixmap(viewport()->rect(), backgroundBrush().texture());
00093     p->restore();
00094 }
00095 
00096 void SvgView::openFile(const QFile &file)
00097 {
00098     if (!file.exists())
00099         return;
00100 
00101     QGraphicsScene *s = scene();
00102 
00103     bool drawBackground = (m_backgroundItem ? m_backgroundItem->isVisible() : true);
00104     bool drawOutline = (m_outlineItem ? m_outlineItem->isVisible() : false);
00105 
00106     s->clear();
00107     resetTransform();
00108 
00109     m_svgItem = new QGraphicsSvgItem(file.fileName());
00110     m_svgItem->setFlags(QGraphicsItem::ItemClipsToShape);
00111     m_svgItem->setCacheMode(QGraphicsItem::NoCache);
00112     m_svgItem->setZValue(0);
00113 
00114     m_backgroundItem = new QGraphicsRectItem(m_svgItem->boundingRect());
00115     m_backgroundItem->setBrush(Qt::white);
00116     m_backgroundItem->setPen(Qt::NoPen);
00117     m_backgroundItem->setVisible(drawBackground);
00118     m_backgroundItem->setZValue(-1);
00119 
00120     m_outlineItem = new QGraphicsRectItem(m_svgItem->boundingRect());
00121     QPen outline(Qt::black, 2, Qt::DashLine);
00122     outline.setCosmetic(true);
00123     m_outlineItem->setPen(outline);
00124     m_outlineItem->setBrush(Qt::NoBrush);
00125     m_outlineItem->setVisible(drawOutline);
00126     m_outlineItem->setZValue(1);
00127 
00128     s->addItem(m_backgroundItem);
00129     s->addItem(m_svgItem);
00130     s->addItem(m_outlineItem);
00131 
00132     s->setSceneRect(m_outlineItem->boundingRect().adjusted(-10, -10, 10, 10));
00133 }
00134 
00135 void SvgView::setRenderer(RendererType type)
00136 {
00137     m_renderer = type;
00138 
00139     if (m_renderer == OpenGL) {
00140 #ifndef QT_NO_OPENGL
00141         setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
00142 #endif
00143     } else {
00144         setViewport(new QWidget);
00145     }
00146 }
00147 
00148 void SvgView::setHighQualityAntialiasing(bool highQualityAntialiasing)
00149 {
00150 #ifndef QT_NO_OPENGL
00151     setRenderHint(QPainter::HighQualityAntialiasing, highQualityAntialiasing);
00152 #else
00153     Q_UNUSED(highQualityAntialiasing);
00154 #endif
00155 }
00156 
00157 void SvgView::setViewBackground(bool enable)
00158 {
00159     if (!m_backgroundItem)
00160         return;
00161 
00162     m_backgroundItem->setVisible(enable);
00163 }
00164 
00165 void SvgView::setViewOutline(bool enable)
00166 {
00167     if (!m_outlineItem)
00168         return;
00169 
00170     m_outlineItem->setVisible(enable);
00171 }
00172 
00173 void SvgView::paintEvent(QPaintEvent *event)
00174 {
00175     if (m_renderer == Image) {
00176         if (m_image.size() != viewport()->size()) {
00177             m_image = QImage(viewport()->size(), QImage::Format_ARGB32_Premultiplied);
00178         }
00179 
00180         QPainter imagePainter(&m_image);
00181         QGraphicsView::render(&imagePainter);
00182         imagePainter.end();
00183 
00184         QPainter p(viewport());
00185         p.drawImage(0, 0, m_image);
00186 
00187     } else {
00188         QGraphicsView::paintEvent(event);
00189     }
00190 }
00191 
00192 void SvgView::wheelEvent(QWheelEvent *event)
00193 {
00194     qreal factor = std::pow(1.2, -event->delta() / 240.0);
00195     scale(factor, factor);
00196     event->accept();
00197 }
00198 
00199 // ----------------------------------------------------------------------------
00200 
00201 /* TRANSLATOR DrawingGui::DrawingView */
00202 
00203 DrawingView::DrawingView(QWidget* parent)
00204   : Gui::MDIView(0, parent), m_view(new SvgView)
00205 {
00206     m_backgroundAction = new QAction(tr("&Background"), this);
00207     m_backgroundAction->setEnabled(false);
00208     m_backgroundAction->setCheckable(true);
00209     m_backgroundAction->setChecked(true);
00210     connect(m_backgroundAction, SIGNAL(toggled(bool)), m_view, SLOT(setViewBackground(bool)));
00211 
00212     m_outlineAction = new QAction(tr("&Outline"), this);
00213     m_outlineAction->setEnabled(false);
00214     m_outlineAction->setCheckable(true);
00215     m_outlineAction->setChecked(false);
00216     connect(m_outlineAction, SIGNAL(toggled(bool)), m_view, SLOT(setViewOutline(bool)));
00217 
00218     m_nativeAction = new QAction(tr("&Native"), this);
00219     m_nativeAction->setCheckable(true);
00220     m_nativeAction->setChecked(false);
00221 #ifndef QT_NO_OPENGL
00222     m_glAction = new QAction(tr("&OpenGL"), this);
00223     m_glAction->setCheckable(true);
00224 #endif
00225     m_imageAction = new QAction(tr("&Image"), this);
00226     m_imageAction->setCheckable(true);
00227 
00228 #ifndef QT_NO_OPENGL
00229     m_highQualityAntialiasingAction = new QAction(tr("&High Quality Antialiasing"), this);
00230     m_highQualityAntialiasingAction->setEnabled(false);
00231     m_highQualityAntialiasingAction->setCheckable(true);
00232     m_highQualityAntialiasingAction->setChecked(false);
00233     connect(m_highQualityAntialiasingAction, SIGNAL(toggled(bool)),
00234             m_view, SLOT(setHighQualityAntialiasing(bool)));
00235 #endif
00236 
00237     QActionGroup *rendererGroup = new QActionGroup(this);
00238     rendererGroup->addAction(m_nativeAction);
00239 #ifndef QT_NO_OPENGL
00240     rendererGroup->addAction(m_glAction);
00241 #endif
00242     rendererGroup->addAction(m_imageAction);
00243     connect(rendererGroup, SIGNAL(triggered(QAction *)),
00244             this, SLOT(setRenderer(QAction *)));
00245 
00246     setCentralWidget(m_view);
00247     //setWindowTitle(tr("SVG Viewer"));
00248 }
00249 
00250 void DrawingView::load (const QString & fileName)
00251 {
00252     if (!fileName.isEmpty()) {
00253         QFile file(fileName);
00254         if (!file.exists()) {
00255             QMessageBox::critical(this, tr("Open SVG File"),
00256                            tr("Could not open file '%1'.").arg(fileName));
00257 
00258             m_outlineAction->setEnabled(false);
00259             m_backgroundAction->setEnabled(false);
00260             return;
00261         }
00262 
00263         m_view->openFile(file);
00264 
00265         if (!fileName.startsWith(QLatin1String(":/"))) {
00266             m_currentPath = fileName;
00267             //setWindowTitle(tr("%1 - SVG Viewer").arg(m_currentPath));
00268         }
00269 
00270         m_outlineAction->setEnabled(true);
00271         m_backgroundAction->setEnabled(true);
00272     }
00273 }
00274 
00275 void DrawingView::contextMenuEvent(QContextMenuEvent *event)
00276 {
00277     QMenu menu;
00278     menu.addAction(this->m_backgroundAction);
00279     menu.addAction(this->m_outlineAction);
00280     QMenu* submenu = menu.addMenu(tr("&Renderer"));
00281     submenu->addAction(this->m_nativeAction);
00282     submenu->addAction(this->m_glAction);
00283     submenu->addAction(this->m_imageAction);
00284     submenu->addSeparator();
00285     submenu->addAction(this->m_highQualityAntialiasingAction);
00286     menu.exec(event->globalPos());
00287 }
00288 
00289 void DrawingView::setRenderer(QAction *action)
00290 {
00291 #ifndef QT_NO_OPENGL
00292     m_highQualityAntialiasingAction->setEnabled(false);
00293 #endif
00294 
00295     if (action == m_nativeAction)
00296         m_view->setRenderer(SvgView::Native);
00297 #ifndef QT_NO_OPENGL
00298     else if (action == m_glAction) {
00299         m_highQualityAntialiasingAction->setEnabled(true);
00300         m_view->setRenderer(SvgView::OpenGL);
00301     }
00302 #endif
00303     else if (action == m_imageAction) {
00304         m_view->setRenderer(SvgView::Image);
00305     }
00306 }
00307 
00308 bool DrawingView::onMsg(const char* pMsg, const char** ppReturn)
00309 {
00310     if (strcmp("ViewFit",pMsg) == 0) {
00311         viewAll();
00312         return true;
00313     }
00314     return false;
00315 }
00316 
00317 bool DrawingView::onHasMsg(const char* pMsg) const
00318 {
00319     if (strcmp("ViewFit",pMsg) == 0)
00320         return true;
00321     else if (strcmp("Print",pMsg) == 0)
00322         return true; 
00323     else if (strcmp("PrintPreview",pMsg) == 0)
00324         return true; 
00325     else if (strcmp("PrintPdf",pMsg) == 0)
00326         return true; 
00327     return false;
00328 }
00329 
00330 void DrawingView::printPdf()
00331 {
00332     Gui::FileOptionsDialog dlg(this, 0);
00333     dlg.setFileMode(QFileDialog::AnyFile);
00334     dlg.setAcceptMode(QFileDialog::AcceptSave);
00335     dlg.setWindowTitle(tr("Export PDF"));
00336     dlg.setFilters(QStringList() << tr("PDF file (*.pdf)"));
00337 
00338     QGridLayout *gridLayout;
00339     QGridLayout *formLayout;
00340     QGroupBox *groupBox;
00341     QListWidget *listWidget;
00342     QListWidgetItem* item;
00343     QWidget *form = new QWidget(&dlg);
00344     form->resize(40, 300);
00345     formLayout = new QGridLayout(form);
00346     groupBox = new QGroupBox(form);
00347     gridLayout = new QGridLayout(groupBox);
00348     listWidget = new QListWidget(groupBox);
00349     gridLayout->addWidget(listWidget, 0, 0, 1, 1);
00350     formLayout->addWidget(groupBox, 0, 0, 1, 1);
00351 
00352     groupBox->setTitle(tr("Page sizes"));
00353     item = new QListWidgetItem(tr("A0"), listWidget);
00354     item->setData(Qt::UserRole, QVariant(QPrinter::A0));
00355     item = new QListWidgetItem(tr("A1"), listWidget);
00356     item->setData(Qt::UserRole, QVariant(QPrinter::A1));
00357     item = new QListWidgetItem(tr("A2"), listWidget);
00358     item->setData(Qt::UserRole, QVariant(QPrinter::A2));
00359     item = new QListWidgetItem(tr("A3"), listWidget);
00360     item->setData(Qt::UserRole, QVariant(QPrinter::A3));
00361     item = new QListWidgetItem(tr("A4"), listWidget);
00362     item->setData(Qt::UserRole, QVariant(QPrinter::A4));
00363     item = new QListWidgetItem(tr("A5"), listWidget);
00364     item->setData(Qt::UserRole, QVariant(QPrinter::A5));
00365     listWidget->item(4)->setSelected(true); // by default A4
00366     dlg.setOptionsWidget(Gui::FileOptionsDialog::ExtensionRight, form, false);
00367 
00368     if (dlg.exec() == QDialog::Accepted) {
00369         Gui::WaitCursor wc;
00370         QString filename = dlg.selectedFiles().front();
00371         QPrinter printer(QPrinter::HighResolution);
00372         printer.setOutputFormat(QPrinter::PdfFormat);
00373         printer.setOutputFileName(filename);
00374         printer.setOrientation(QPrinter::Landscape);
00375         QList<QListWidgetItem*> items = listWidget->selectedItems();
00376         if (items.size() == 1) {
00377             int AX = items.front()->data(Qt::UserRole).toInt();
00378             printer.setPaperSize(QPrinter::PageSize(AX));
00379         }
00380         print(&printer);
00381     }
00382 }
00383 
00384 void DrawingView::print()
00385 {
00386     QPrinter printer(QPrinter::HighResolution);
00387     printer.setFullPage(true);
00388     printer.setOrientation(QPrinter::Landscape);
00389     QPrintDialog dlg(&printer, this);
00390     if (dlg.exec() == QDialog::Accepted) {
00391         print(&printer);
00392     }
00393 }
00394 
00395 void DrawingView::printPreview()
00396 {
00397     QPrinter printer(QPrinter::HighResolution);
00398     printer.setFullPage(true);
00399     printer.setOrientation(QPrinter::Landscape);
00400 
00401     QPrintPreviewDialog dlg(&printer, this);
00402     connect(&dlg, SIGNAL(paintRequested (QPrinter *)),
00403             this, SLOT(print(QPrinter *)));
00404     dlg.exec();
00405 }
00406 
00407 void DrawingView::print(QPrinter* printer)
00408 {
00409 #if 1
00410     QPainter p(printer);
00411     QRect rect = printer->pageRect();
00412     this->m_view->scene()->render(&p, rect);
00413     p.end();
00414 #else
00415     printer->setResolution(QPrinter::HighResolution);
00416     printer->setPageSize(QPrinter::A4);
00417     QPainter painter(printer);
00418 
00419     // print, fitting the viewport contents into a full page
00420     m_view->render(&painter);
00421 
00422     // print the upper half of the viewport into the lower.
00423     // half of the page.
00424     QRect viewport = m_view->viewport()->rect();
00425     m_view->render(&painter,
00426                    QRectF(0, printer->height() / 2,
00427                              printer->width(), printer->height() / 2),
00428                    viewport.adjusted(0, 0, 0, -viewport.height() / 2));
00429 #endif
00430 }
00431 
00432 void DrawingView::viewAll()
00433 {
00434     m_view->fitInView(m_view->scene()->sceneRect(), Qt::KeepAspectRatio);
00435 }
00436 
00437 #include "moc_DrawingView.cpp"

Generated on Wed Nov 23 19:00:09 2011 for FreeCAD by  doxygen 1.6.1