All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Scene.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2013-2014 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file Scene.cpp
22 
23  \brief
24 
25  \ingroup layout
26 */
27 
28 // TerraLib
29 #include "Scene.h"
30 #include "ItemObserver.h"
31 #include <QWidget>
32 #include "Context.h"
33 #include "ItemGroup.h"
34 #include "ItemGroupModel.h"
35 #include "ItemGroupController.h"
36 #include "AbstractType.h"
37 #include "Observer.h"
38 #include "TemplateEditor.h"
39 #include "AbstractTemplate.h"
40 #include "RectangleModel.h"
41 #include "RectangleController.h"
42 #include "RectangleItem.h"
43 #include "PaperConfig.h"
44 #include "VisualizationArea.h"
45 #include "BuildGraphicsItem.h"
46 #include "MapItem.h"
47 #include "ItemUtils.h"
48 
49 // STL
50 #include <iostream>
51 #include <fstream>
52 
53 // Qt
54 #include <QGraphicsScene.h>
55 #include <QGraphicsPixmapItem>
56 #include <QGraphicsItem>
57 #include <QtGui>
58 #include <QPixmap>
59 #include <QPainter>
60 #include <QMessageBox>
61 
62 te::layout::Scene::Scene( QWidget* widget):
63  QGraphicsScene(widget),
64  m_boxW(0),
65  m_boxPaperW(0),
66  m_masterParent(0),
67  m_lineIntersectHrz(0),
68  m_lineIntersectVrt(0)
69 {
70 
71 }
72 
74 {
75  if(m_boxW)
76  {
77  delete m_boxW;
78  m_boxW = 0;
79  }
80 
81  if(m_boxPaperW)
82  {
83  delete m_boxPaperW;
84  m_boxPaperW = 0;
85  }
86 }
87 
88 void te::layout::Scene::init( double widthMM, double heightMM )
89 {
90  m_screenWidthMM = widthMM;
91  m_screenHeightMM = heightMM;
92 
93  m_boxW = calculateWindow();
94  m_boxPaperW = calculateBoxPaper();
95 
96  calculateMatrixViewScene();
97 
98  createMasterParentItem();
99 }
100 
102 {
103  QGraphicsItem* qitem = ((QGraphicsItem*)item);
104 
105  int total = 0;
106 
107  if(qitem)
108  {
109  if(qitem->scene() != this)
110  {
111  if(m_masterParent)
112  {
113  total = m_masterParent->childItems().count();
114  qitem->setParentItem(m_masterParent); // have a addItem call inside
115  }
116  else
117  this->addItem(qitem);
118 
119  qitem->setZValue(total);
120  }
121 
122  ItemObserver* obs = dynamic_cast<ItemObserver*>(qitem);
123  if(obs)
124  {
125  obs->refresh();
126  }
127  }
128 
129  emit addItemFinalized();
130 }
131 
133 {
134  QWidget* qWidget = ((QWidget*)widget);
135  this->addWidget(qWidget);
136 }
137 
139 {
140  QWidget* qWidget = ((QWidget*)widget);
141  return this->addWidget(qWidget);
142 }
143 
144 void te::layout::Scene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent )
145 {
146  QGraphicsScene::mousePressEvent(mouseEvent);
147 }
148 
150 {
151  QRectF srect = sceneRect();
152 
153  QPointF ll = srect.bottomLeft();
154  QPointF ur = srect.topRight();
155 
156  te::gm::Envelope box(ll.x(), ll.y(), ur.x(), ur.y());
157  return box;
158 }
159 
161 {
162  double factor = Context::getInstance()->getZoomFactor();
163 
164  QList<QGraphicsItem*> graphicsItems = items();
165  foreach( QGraphicsItem *item, graphicsItems)
166  {
167  if (item)
168  {
169  ItemObserver* lItem = dynamic_cast<ItemObserver*>(item);
170  if(lItem)
171  {
172  lItem->redraw(factor);
173  }
174  }
175  }
176 }
177 
178 QGraphicsItemGroup* te::layout::Scene::createItemGroup( const QList<QGraphicsItem *> & items )
179 {
180  //The scene create a new group with important restriction
181  QGraphicsItemGroup* p = QGraphicsScene::createItemGroup(items);
182 
183  //Create a new group
185  te::gm::Coord2D coord(0,0);
186  QGraphicsItem* item = build->createItem(TypeCreateItemGroup, coord, false);
187 
188  ItemGroup* group = dynamic_cast<ItemGroup*>(item);
189 
190  if(p)
191  {
192  if(group)
193  {
194  QGraphicsItem* parent = group->parentItem();
195  group->setParentItem(p->parentItem());
196  foreach (QGraphicsItem *item, p->childItems())
197  {
198  group->addToGroup(item);
199  }
200 
201  delete p;
202 
203  group->setParentItem(parent);
204  }
205  }
206 
207  return group;
208 }
209 
210 void te::layout::Scene::destroyItemGroup( QGraphicsItemGroup *group )
211 {
212  group->setHandlesChildEvents(false);
213  QGraphicsScene::destroyItemGroup(group);
214 }
215 
217 {
219 
220  double ppSizeWMM = 0;
221  double ppSizeHMM = 0;
222 
223  config->getPaperSize(ppSizeWMM, ppSizeHMM);
224 
225  double x1 = 0.;
226  double y1 = 0.;
227  double x2 = 0.;
228  double y2 = 0.;
229 
230  te::gm::Envelope* boxW = calculateWindow();
231 
232  int widthW = boxW->getWidth();
233  int heightW = boxW->getHeight();
234 
235  double middleWW = widthW/2.;
236  double middleHW = heightW/2.;
237 
238  double ppW = ppSizeWMM/2.;
239  double ppH = ppSizeHMM/2.;
240 
241  if(widthW > ppSizeWMM)
242  {
243  x1 = 0;
244  x2 = ppSizeWMM;
245  }
246  else
247  {
248  x1 = middleWW - ppW;
249  x2 = x1 + ppSizeWMM;
250  }
251 
252  if(heightW > ppSizeHMM)
253  {
254  y1 = 0;
255  y2 = ppSizeHMM;
256  }
257  else
258  {
259  y1 = middleHW - ppH;
260  y2 = y1 + ppSizeHMM;
261  }
262 
263  te::gm::Envelope* box = new te::gm::Envelope(x1, y1, x2, y2);
264  return box;
265 }
266 
268 {
270 
271  double ppSizeWMM = 0;
272  double ppSizeHMM = 0;
273 
274  config->getPaperSize(ppSizeWMM, ppSizeHMM);
275 
276  double x1 = 0;
277  double y1 = 0;
278  double x2 = 0;
279  double y2 = 0;
280 
281  int w = m_screenWidthMM;
282  int h = m_screenHeightMM;
283 
284  double paddingW = w - ppSizeWMM;
285  double margin1 = paddingW / 2.;
286 
287  if(w > ppSizeWMM)
288  {
289  x1 = - margin1;
290  x2 = (paddingW + ppSizeWMM) - margin1;
291  }
292  else
293  {
294  x1 = 0;
295  x2 = w;
296  }
297 
298  double paddingH = h - ppSizeHMM;
299  double margin2 = paddingH / 2.;
300 
301  if(h > ppSizeHMM)
302  {
303  y1 = - margin2;
304  y2 = (paddingW + ppSizeHMM) - margin2;
305 
306  }
307  else
308  {
309  y1 = 0;
310  y2 = h;
311  }
312 
313  te::gm::Envelope* box = new te::gm::Envelope(x1, y1, x2, y2);
314  return box;
315 }
316 
318 {
319  double llx = m_boxW->getLowerLeftX();
320  double lly = m_boxW->getLowerLeftY();
321  double urx = m_boxW->getUpperRightX();
322  double ury = m_boxW->getUpperRightY();
323 
324  double dpiX = Context::getInstance()->getDpiX();
325  double dpiY = Context::getInstance()->getDpiY();
326 
327  //mm (inversão do y)
328  m_matrix = QTransform().scale(dpiX / 25.4, -dpiY / 25.4).translate(-llx, -ury);
329 
330  //Coordenadas de mundo - mm
331  setSceneRect(QRectF(QPointF(llx, lly), QPointF(urx, ury)));
332 }
333 
335 {
336  return m_boxW;
337 }
338 
340 {
341  return m_boxPaperW;
342 }
343 
345 {
346  return m_matrix;
347 }
348 
350 {
351  double llx = m_boxW->getLowerLeftX();
352  double lly = m_boxW->getLowerLeftY();
353 
354  //Background
355  QRectF sceneRectBack = sceneRect();
356  m_masterParent = addRect(sceneRectBack);
357  ((QGraphicsRectItem*)m_masterParent)->setBrush((QBrush(QColor(109,109,109))));
358  m_masterParent->setPos(0, 0);
359 }
360 
362 {
363  return m_masterParent;
364 }
365 
367 {
368  QPrinter* printer = createPrinter();
369 
370  QPrintPreviewDialog preview(printer);
371  connect(&preview, SIGNAL(paintRequested(QPrinter*)), SLOT(printPaper(QPrinter*)));
372  preview.exec();
373 
375 }
376 
377 void te::layout::Scene::printPaper(QPrinter* printer)
378 {
379  //Impressão de parte da Cena
380  //Não é necessário mudar a escala do View
381 
382  QPainter newPainter(printer);
383  newPainter.setRenderHint(QPainter::Antialiasing);
384 
385  double dpiX = Context::getInstance()->getDpiX();
386  double dpiY = Context::getInstance()->getDpiY();
387 
388  Context::getInstance()->setDpiX(printer->logicalDpiX());
389  Context::getInstance()->setDpiY(printer->logicalDpiY());
390 
391  renderScene(&newPainter);
392 
393  Context::getInstance()->setDpiX(dpiX);
394  Context::getInstance()->setDpiY(dpiY);
395 }
396 
398 {
399  QString fileName = QFileDialog::getSaveFileName(QApplication::desktop(), tr("Save Image File"), QDir::currentPath(), tr("Image Files (*.png *.jpg *.bmp)"));
400  if(!fileName.isEmpty())
401  {
402  QImage image(fileName);
403  QPainter newPainter(&image);
404  newPainter.setRenderHint(QPainter::Antialiasing);
405 
406  renderScene(&newPainter);
407 
408  image.save(fileName);
409  }
410 }
411 
413 {
414  QPrinter* printer= createPrinter();
415  QString fileName = QFileDialog::getSaveFileName(QApplication::desktop(), tr("Save Image File"), QDir::currentPath(), tr("PDF Files (*.pdf)"));
416  if(!fileName.isEmpty())
417  {
418  printer->setOutputFormat(QPrinter::PdfFormat);
419  printer->setOutputFileName(fileName);
420  printPaper(printer);
421  }
422 }
423 
425 {
426  QPrinter* printer=new QPrinter(QPrinter::HighResolution);
427  printer->setPageSize(QPrinter::A4);
428  printer->setOrientation( QPrinter::Portrait );
429  printer->pageRect(QPrinter::Millimeter);
430 
431  return printer;
432 }
433 
434 void te::layout::Scene::renderScene( QPainter* newPainter )
435 {
436  changePrintVisibility(false);
437 
438  te::gm::Envelope* paperBox = getPaperBox();
439 
440  //Box Paper in the Scene (Source)
441  QRectF mmSourceRect(paperBox->getLowerLeftX(), paperBox->getLowerLeftY(),
442  paperBox->getWidth(), paperBox->getHeight());
443 
444  //Paper size using the printer dpi (Target)
445  QRect pxTargetRect(0, 0, newPainter->device()->width(), newPainter->device()->height());
446 
447  /* Print Paper (Scene to Printer)
448  draw items with printer painter */
449 
450  Utils* utils = Context::getInstance()->getUtils();
451  //Convert world to screen coordinate. Uses dpi printer.
452  te::gm::Envelope paperNewBox = utils->viewportBox(*paperBox);
453 
454  this->render(newPainter, pxTargetRect, mmSourceRect);
455 
456  changePrintVisibility(true);
457 }
458 
460 {
461  QList<QGraphicsItem*> graphicsItems = items();
462  foreach( QGraphicsItem *item, graphicsItems)
463  {
464  if (item)
465  {
466  ItemObserver* lItem = dynamic_cast<ItemObserver*>(item);
467  if(lItem)
468  {
469  if(!lItem->isPrintable())
470  {
471  item->setVisible(change);
472  }
473  }
474  }
475  }
476 }
477 
479 {
480  bool is_export = false;
481 
482  QString fileName = QFileDialog::getSaveFileName(QApplication::desktop(), tr("Save File"),
483  QDir::currentPath(), tr("JSON Files (*.json)"));
484 
485  if(fileName.isEmpty())
486  {
487  return is_export;
488  }
489 
490  std::string j_name = fileName.toStdString();
491 
492  std::vector<te::layout::Properties*> props = getItemsProperties();
493 
494  if(props.empty())
495  return is_export;
496 
497  TemplateEditor editor(TPJSONTemplate, j_name);
498 
499  AbstractTemplate* jtemplate = editor.getTemplate();
500 
501  if(!jtemplate)
502  return is_export;
503 
504  is_export = jtemplate->exportTemplate(props);
505 
506  QMessageBox msgBox;
507 
508  if(is_export)
509  {
510  msgBox.setIcon(QMessageBox::Information);
511  msgBox.setText("Template exported successfully!");
512  }
513  else
514  {
515  msgBox.setIcon(QMessageBox::Warning);
516  msgBox.setText("Error exporting template!");
517  }
518 
519  msgBox.exec();
520 
521  return is_export;
522 }
523 
524 std::vector<te::layout::Properties*> te::layout::Scene::importJsonAsProps()
525 {
526  std::vector<te::layout::Properties*> props;
527 
528  QString fileName = QFileDialog::getOpenFileName(QApplication::desktop(), tr("Import File"),
529  QDir::currentPath(), tr("JSON Files (*.json)"));
530 
531  if(fileName.isEmpty())
532  {
533  return props;
534  }
535 
536  std::string j_name = fileName.toStdString();
537 
538  TemplateEditor editor(TPJSONTemplate, j_name);
539 
540  AbstractTemplate* jtemplate = editor.getTemplate();
541 
542  if(!jtemplate)
543  return props;
544 
545  props = jtemplate->importTemplate();
546 
547  return props;
548 }
549 
550 std::vector<te::layout::Properties*> te::layout::Scene::getItemsProperties()
551 {
552  std::vector<te::layout::Properties*> props;
553 
554  QList<QGraphicsItem*> graphicsItems = items();
555  foreach( QGraphicsItem *item, graphicsItems)
556  {
557  if (item)
558  {
559  ItemObserver* lItem = dynamic_cast<ItemObserver*>(item);
560  if(lItem)
561  {
562  if(!lItem->isPrintable())
563  continue;
564 
565  props.push_back(lItem->getProperties());
566  }
567  }
568  }
569 
570  return props;
571 }
572 
574 {
575  clear();
576  createMasterParentItem();
577 }
578 
579 void te::layout::Scene::drawForeground( QPainter *painter, const QRectF &rect )
580 {
581  QGraphicsScene::drawForeground(painter, rect);
582 
583  if(Context::getInstance()->getLineIntersectionMouseMode() != TypeActiveLinesIntersectionMouse)
584  return;
585 
586  QBrush brush = painter->brush();
587 
588  QBrush brushCopy = brush;
589  brush.setColor(QColor(0,0,0,255));
590 
591  QPen pen = painter->pen();
592 
593  QPen penCopy = pen;
594  penCopy.setStyle(Qt::DashDotLine);
595 
596  painter->save();
597  painter->setPen(penCopy);
598  painter->setBrush(brushCopy);
599  painter->drawLines(m_lineIntersectHrz, 1);
600  painter->drawLines(m_lineIntersectVrt, 1);
601  painter->restore();
602 
603  painter->setBrush(brush);
604 
605  update();
606 }
607 
609 {
611 
612  if(!build)
613  return;
614 
615  std::vector<te::layout::Properties*> props = importJsonAsProps();
616 
617  if(props.empty())
618  return;
619 
620  refresh();
621 
622  std::vector<te::layout::Properties*>::iterator it;
623 
624  te::gm::Envelope* boxW = getWorldBox();
625  vzArea->changeBoxArea(boxW);
626  vzArea->rebuildWithoutPaper();
627 
628  for(it = props.begin() ; it != props.end() ; ++it)
629  {
630  te::layout::Properties* proper = (*it);
631 
632  if(!proper)
633  continue;
634 
635  build->rebuildItem(proper);
636  }
637 }
638 
640 {
641  QList<QGraphicsItem*> graphicsItems = selectedItems();
642 
643  foreach( QGraphicsItem *item, graphicsItems)
644  {
645  if (item)
646  {
647  removeItem(item);
648  if(item)
649  {
650  delete item;
651  item = 0;
652  }
653  }
654  }
655 }
656 
658 {
660 
661  if(!build)
662  return;
663 
664  QGraphicsItem* item = 0;
665 
667 
668  item = build->createItem(mode, coord);
669 
670  //If Create item
671  if(item)
672  {
674  }
675 }
676 
678 {
679  if(mode == TypeNone)
680  return;
681 
683  return;
684 
685  QList<QGraphicsItem*> graphicsItems = selectedItems();
686 
687  foreach(QGraphicsItem *item, graphicsItems)
688  {
689  if(!item)
690  continue;
691 
692  te::layout::ItemObserver* lItem = dynamic_cast<te::layout::ItemObserver*>(item);
693  if(!lItem)
694  continue;
695 
696  te::layout::MapItem* mit = dynamic_cast<te::layout::MapItem*>(lItem);
697  if(!mit)
698  continue;
699 
700  mit->changeCurrentTool(mode);
701  }
702 }
703 
705 {
706  m_lineIntersectHrz = line;
707 }
708 
710 {
711  m_lineIntersectVrt = line;
712 }
void setDpiY(double dpiY)
Definition: Context.cpp:161
virtual void printPreview(bool isPdf=false)
Definition: Scene.cpp:366
virtual void drawForeground(QPainter *painter, const QRectF &rect)
Definition: Scene.cpp:579
virtual void savePaperAsImage()
Definition: Scene.cpp:397
virtual void buildTemplate(VisualizationArea *vzArea)
Definition: Scene.cpp:608
virtual void printPaper(QPrinter *printer)
Definition: Scene.cpp:377
virtual std::vector< te::layout::Properties * > importJsonAsProps()
Definition: Scene.cpp:524
virtual void changeCurrentTool(LayoutMode mode)
Definition: MapItem.cpp:459
virtual te::gm::Envelope * calculateWindow()
Definition: Scene.cpp:267
virtual te::gm::Envelope * getWorldBox() const
Definition: Scene.cpp:334
void setMode(LayoutMode mode)
Definition: Context.cpp:66
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
Definition: Envelope.h:400
double getWidth() const
It returns the envelope width.
Definition: Envelope.h:443
virtual void refresh()
Definition: Scene.cpp:573
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
virtual te::gm::Envelope * getPaperBox() const
Definition: Scene.cpp:339
virtual void deleteItems()
Definition: Scene.cpp:639
virtual te::layout::AbstractTemplate * getTemplate()
virtual void createItem(const te::gm::Coord2D &coord)
Definition: Scene.cpp:657
LayoutMode
Enum LayoutMode. This is the enumeration of the components types.
Definition: EnumMode.h:38
virtual bool isPrintable()
virtual QGraphicsProxyWidget * insertOutsideProxy(OutsideObserver *widget)
Definition: Scene.cpp:138
void setDpiX(double dpiX)
Definition: Context.cpp:151
virtual void insertOutside(OutsideObserver *widget)
Definition: Scene.cpp:132
virtual void changePrintVisibility(bool change)
Definition: Scene.cpp:459
virtual void setCurrentToolInSelectedMapItems(LayoutMode mode)
Definition: Scene.cpp:677
QGraphicsItemGroup * createItemGroup(const QList< QGraphicsItem * > &items)
Definition: Scene.cpp:178
virtual bool exportTemplate(std::vector< te::layout::Properties * > properties)=0
virtual QGraphicsItem * getMasterParentItem()
Definition: Scene.cpp:361
virtual void calculateMatrixViewScene()
Definition: Scene.cpp:317
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
virtual te::gm::Envelope getSceneBox()
Definition: Scene.cpp:149
portrait orientation
Definition: AbstractType.h:85
Utils * getUtils()
Definition: Context.cpp:126
virtual void redrawItems()
Definition: Scene.cpp:160
QGraphicsItem * rebuildItem(te::layout::Properties *props, bool draw=true)
virtual te::gm::Envelope * calculateBoxPaper()
Definition: Scene.cpp:216
Scene(QWidget *widget=(QWidget *) 0)
Definition: Scene.cpp:62
virtual void init(double widthMM, double heightMM)
Definition: Scene.cpp:88
virtual void addToGroup(QGraphicsItem *item)
Definition: ItemGroup.cpp:124
QGraphicsItem * createItem(te::layout::LayoutMode mode, const te::gm::Coord2D &coordinate, bool draw=true)
void setLineIntersectionHzr(QLineF *line)
Definition: Scene.cpp:704
virtual void createMasterParentItem()
Definition: Scene.cpp:349
void setLineIntersectionVrt(QLineF *line)
Definition: Scene.cpp:709
virtual bool exportPropsAsJSON()
Definition: Scene.cpp:478
virtual void getPaperSize(double &w, double &h)
Definition: PaperConfig.cpp:56
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
Definition: Envelope.h:390
BuildGraphicsItem * getBuildGraphicsItem()
Definition: Context.cpp:181
virtual std::vector< te::layout::Properties * > importTemplate()=0
virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
Definition: Scene.cpp:144
TELAYOUTEXPORT bool isCurrentMapTools()
Definition: ItemUtils.cpp:169
virtual void savePaperAsPDF()
Definition: Scene.cpp:412
virtual void changeBoxArea(te::gm::Envelope *boxArea)
PaperConfig * getPaperConfig() const
Definition: Context.cpp:171
virtual void redraw(const double &scaleFactor=1.)
virtual te::layout::Properties * getProperties() const
static Context * getInstance()
This function is called to create an instance of the class.
Definition: Context.cpp:46
double getZoomFactor()
Definition: Context.cpp:76
void renderScene(QPainter *newPainter)
Definition: Scene.cpp:434
virtual void insertItem(ItemObserver *item)
Definition: Scene.cpp:101
LayoutMode getMode()
Definition: Context.cpp:56
double getHeight() const
It returns the envelope height.
Definition: Envelope.h:448
virtual QTransform getMatrixViewScene()
Definition: Scene.cpp:344
virtual QPrinter * createPrinter()
Definition: Scene.cpp:424
void destroyItemGroup(QGraphicsItemGroup *group)
Definition: Scene.cpp:210
virtual std::vector< te::layout::Properties * > getItemsProperties()
Definition: Scene.cpp:550