All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TextItem.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 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 TextItem.cpp
22 
23  \brief
24 
25  \ingroup layout
26 */
27 
28 // TerraLib
29 #include "TextItem.h"
30 #include "../../core/pattern/mvc/ItemController.h"
31 #include "../core/Scene.h"
32 #include "../../core/pattern/mvc/Observable.h"
33 #include "../../../color/RGBAColor.h"
34 #include "../../../qt/widgets/Utils.h"
35 #include "../../../geometry/Envelope.h"
36 #include "../../../common/STLUtils.h"
37 #include "../../core/pattern/singleton/Context.h"
38 #include "../../item/TextModel.h"
39 #include "../../core/property/Properties.h"
40 #include "../core/pattern/command/ChangePropertyCommand.h"
41 
42 // STL
43 #include <string>
44 
45 // Qt
46 #include <QTextDocument>
47 #include <QStyleOptionGraphicsItem>
48 #include <QTextCursor>
49 #include <QAbstractTextDocumentLayout>
50 #include <QGraphicsSceneMouseEvent>
51 #include <QPainter>
52 #include <QStyleOptionGraphicsItem>
53 #include <QWidget>
54 #include <QKeyEvent>
55 #include <QGraphicsView>
56 #include <QList>
57 
59  ParentItem<QGraphicsTextItem>(controller, o, true),
60  m_editable(false),
61  m_move(false)
62 {
63  m_nameClass = std::string(this->metaObject()->className());
64 
65  //If enabled is true, this item will accept hover events
66  setAcceptHoverEvents(false);
67 
68  m_backgroundColor.setAlpha(0);
69 
70  init();
71 }
72 
74 {
75  if(m_editable)
76  {
77  resetEdit();
78  }
79 }
80 
82 {
83  QFont ft("Arial", 12);
84  document()->setDefaultFont(ft);
85 
86  std::string name = m_model->getName();
87  TextModel* model = dynamic_cast<TextModel*>(m_model);
88  if(model)
89  {
90  if(model->getText().compare("") == 0)
91  {
92  model->setText(name);
93  }
94 
95  QTextCursor cursor(document());
96  cursor.movePosition(QTextCursor::Start);
97  cursor.insertText(name.c_str());
98 
99  std::string txt = model->getText();
100  document()->setPlainText(txt.c_str());
101  }
102 
103  resetEdit();
104 }
105 
107 {
108  if(!m_model)
109  return;
110 
111  if(!document())
112  return;
113 
114  TextModel* model = dynamic_cast<TextModel*>(m_model);
115 
116  if(!model)
117  return;
118 
119  updateTextConfig();
120 
121  std::string txt = model->getText();
122  document()->setPlainText(txt.c_str());
123 
124  update();
125 }
126 
127 void te::layout::TextItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget /*= 0 */ )
128 {
129  Q_UNUSED( option );
130  Q_UNUSED( widget );
131  if ( !painter )
132  {
133  return;
134  }
135 
136  updateTextConfig();
137 
138  drawBackground( painter );
139 
140  QGraphicsTextItem::paint(painter, option, widget);
141 
142  drawBorder(painter);
143 
144  //Draw Selection
145  if (option->state & QStyle::State_Selected)
146  {
147  drawSelection(painter);
148  }
149 }
150 
152 {
153  TextModel* model = dynamic_cast<TextModel*>(m_model);
154 
155  if(!model)
156  {
157  QImage ig;
158  return ig;
159  }
160 
161  //The text size automatically resized by QGraphicsTextItem
162  //depending on the zoom level
163  // So it is not necessary to calculate a new value for the font size
164  QFont ft = document()->defaultFont();
165  Font fot = model->getFont();
166  int pts = (int)fot.getPointSize();
167  ft.setPointSize(pts);
168  document()->setDefaultFont(ft);
169 
170  double w = document()->size().width();
171  double h = document()->size().height();
172 
173  QImage img(w, h, QImage::Format_ARGB32_Premultiplied);
174  img.fill(m_backgroundColor);
175 
176  QPainter ptr(&img);
177  ptr.setFont(ft);
178  ptr.setRenderHint(QPainter::Antialiasing, true);
179 
180  document()->drawContents(&ptr);
181 
182  return img;
183 }
184 
186 {
187  if(!m_model)
188  return;
189 
190  TextModel* model = dynamic_cast<TextModel*>(m_model);
191 
192  if(!model)
193  return;
194 
195  double w = 0;
196  double h = 0;
197 
198  getDocumentSizeMM(w, h);
199 
200  QPointF pp = scenePos();
201 
202  double x1 = pp.x();
203  double y1 = pp.y() - h;
204  double x2 = x1 + w;
205  double y2 = y1 + h;
206 
207  te::gm::Envelope box(x1, y1, x2, y2);
208 
209  model->setBox(box);
210  model->setText(document()->toPlainText().toStdString());
211 }
212 
214 {
215  QPointF posF = scenePos();
216 
217  double w = 0;
218  double h = 0;
219 
220  getDocumentSizeMM(w, h);
221  qreal valuex = posF.x();
222  qreal valuey = posF.y() - h;
223 
224  te::gm::Coord2D coordinate;
225  coordinate.x = valuex;
226  coordinate.y = valuey;
227 
228  return coordinate;
229 }
230 
232 {
233  refreshDocument();
234 
235  QImage img = createImage();
236 
237  w = img.width();
238  h = img.height();
239 
241  return teImg;
242 }
243 
244 QVariant te::layout::TextItem::itemChange( GraphicsItemChange change, const QVariant & value )
245 {
246  if(change == QGraphicsItem::ItemPositionChange && !m_move)
247  {
248  // value is the new position.
249  QPointF newPos = value.toPointF();
250  double w = 0;
251  double h = 0;
252  getDocumentSizeMM(w, h);
253 
254  newPos.setX(newPos.x() - transform().dx());
255  newPos.setY(newPos.y() - transform().dy() + h);
256  return newPos;
257  }
258  else if(change == QGraphicsItem::ItemPositionHasChanged)
259  {
260  refresh();
261  m_move = false;
262  }
263  else if(change == QGraphicsItem::ItemSelectedHasChanged)
264  {
265  if(m_editable && isSelected() == false)
266  {
267  resetEdit();
268  }
269  }
270 
271  return QGraphicsTextItem::itemChange(change, value);
272 }
273 
274 void te::layout::TextItem::keyPressEvent( QKeyEvent * event )
275 {
276  if(m_editable == true)
277  QGraphicsTextItem::keyPressEvent(event);
278 }
279 
280 void te::layout::TextItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * event )
281 {
282  if(event->button() == Qt::LeftButton)
283  {
284  m_editable = !m_editable;
285  if(m_editable)
286  {
287  //If enabled is true, this item will accept hover events
288  setTextInteractionFlags(Qt::TextEditable);
289  setCursor(Qt::IBeamCursor);
290  QTextCursor cursor(textCursor());
291  cursor.clearSelection();
292  setTextCursor(cursor);
293  setFocus();
294  }
295  else
296  {
297  setCursor(Qt::ArrowCursor);
298  }
299  }
300 }
301 
302 void te::layout::TextItem::mouseMoveEvent( QGraphicsSceneMouseEvent * event )
303 {
304  m_move = true;
305  if(m_editable == false)
306  {
307  QGraphicsItem::mouseMoveEvent(event);
308  return;
309  }
310  QGraphicsTextItem::mouseMoveEvent(event);
311 }
312 
313 void te::layout::TextItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
314 {
315  if(m_editable == false)
316  {
317  QGraphicsItem::mousePressEvent(event);
318  return;
319  }
320  QGraphicsTextItem::mousePressEvent(event);
321 }
322 
323 void te::layout::TextItem::mouseReleaseEvent( QGraphicsSceneMouseEvent * event )
324 {
325  if(m_editable == false)
326  {
327  QGraphicsItem::mouseReleaseEvent(event);
328  return;
329  }
330  QGraphicsTextItem::mouseReleaseEvent(event);
331 }
332 
334 {
335  return m_editable;
336 }
337 
338 void te::layout::TextItem::getDocumentSizeMM( double &w, double &h )
339 {
340  QImage img = createImage();
341  w = img.widthMM();
342  h = img.heightMM();
343 }
344 
346 {
347  m_editable = editable;
348 }
349 
351 {
352  m_editable = false;
353 
354  TextModel* model = dynamic_cast<TextModel*>(m_model);
355  if(model)
356  {
357  if(model->getText().compare(document()->toPlainText().toStdString()) != 0)
358  {
359  Properties* beforeProps = model->getProperties();
360  Properties* oldCommand = new Properties(*beforeProps);
361 
362  refreshDocument();
363 
364  beforeProps = model->getProperties();
365  Properties* newCommand = new Properties(*beforeProps);
366 
367  QUndoCommand* command = new ChangePropertyCommand(this, oldCommand, newCommand);
368 
369  Scene* sc = dynamic_cast<Scene*>(scene());
370  if(sc)
371  {
372  sc->addUndoStack(command);
373  }
374  }
375  }
376 
377  /*Necessary clear the selection and focus of the edit
378  after being completely closed and like this not cause bad behavior.*/
379  QTextCursor cursor(textCursor());
380  cursor.clearSelection();
381  setTextInteractionFlags(Qt::NoTextInteraction);
382  unsetCursor();
383  clearFocus();
384 }
385 
387 {
388  if(!m_model)
389  return;
390 
391  if(!document())
392  return;
393 
394  TextModel* model = dynamic_cast<TextModel*>(m_model);
395 
396  if(!model)
397  return;
398 
399  te::color::RGBAColor clrBack = model->getBackgroundColor();
400  m_backgroundColor.setRed(clrBack.getRed());
401  m_backgroundColor.setGreen(clrBack.getGreen());
402  m_backgroundColor.setBlue(clrBack.getBlue());
403  m_backgroundColor.setAlpha(clrBack.getAlpha());
404 
405  Font ft = model->getFont();
406 
407  QFont qft;
408  qft.setFamily(ft.getFamily().c_str());
409  qft.setBold(ft.isBold());
410  qft.setItalic(ft.isItalic());
411  qft.setPointSizeF(ft.getPointSize());
412  qft.setKerning(ft.isKerning());
413  qft.setStrikeOut(ft.isStrikeout());
414  qft.setUnderline(ft.isUnderline());
415 
416  document()->setDefaultFont(qft);
417 }
418 
420 {
421  return QGraphicsTextItem::boundingRect();
422 }
423 
424 
Abstract class to represent an observable. "Model" part of MVC component.
Definition: Observable.h:56
virtual void updateObserver(ContextItem context)
Reimplemented from ItemObserver.
Definition: TextItem.cpp:106
Class responsible for maintaining the drawing context of a MVC component. It is always used by the "M...
Definition: ContextItem.h:49
virtual void setText(std::string txt)
Definition: TextModel.cpp:99
virtual void setEditable(bool editable)
Definition: TextItem.cpp:345
Class specifies a font.
Definition: Font.h:46
virtual te::gm::Coord2D getPosition()
Reimplemented from ItemObserver.
Definition: TextItem.cpp:213
bool isBold()
Returns true if font use bold, false otherwise.
Definition: Font.cpp:81
double y
y-coordinate.
Definition: Coord2D.h:114
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event)
Reimplemented from QGraphicsTextItem.
Definition: TextItem.cpp:313
bool isStrikeout()
Returns true if font use strikeout, false otherwise.
Definition: Font.cpp:111
int getRed() const
It returns the red component color value (a value from 0 to 255).
Definition: RGBAColor.h:295
double x
x-coordinate.
Definition: Coord2D.h:113
virtual void resetEdit()
Definition: TextItem.cpp:350
virtual QRectF boundingRect() const
Reimplemented from QGraphicsItem.
Definition: TextItem.cpp:419
int getPointSize()
Returns point size of the font.
Definition: Font.cpp:71
int getBlue() const
It returns the blue component color value (a value from 0 to 255).
Definition: RGBAColor.h:305
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
Reimplemented from QGraphicsTextItem.
Definition: TextItem.cpp:302
int getGreen() const
It returns the green component color value (a value from 0 to 255).
Definition: RGBAColor.h:300
virtual std::string getText()
Definition: TextModel.cpp:104
The Properties class represents a persistent set of properties. The Properties can be saved to a file...
Definition: Properties.h:52
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
Abstract class to represent a controller. "Controller" part of MVC component. All classes representin...
Class that represents a "Model" part of Text MVC component. Its coordinate system is the same of scen...
Definition: TextModel.h:58
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
Reimplemented from QGraphicsTextItem.
Definition: TextItem.cpp:127
TextItem(ItemController *controller, Observable *o)
Constructor.
Definition: TextItem.cpp:58
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
virtual QImage createImage()
Definition: TextItem.cpp:151
virtual void refreshDocument()
Definition: TextItem.cpp:185
void setFamily(std::string family)
Returns font family name.
Definition: Font.cpp:56
int getAlpha() const
It returns the alpha component color value (a value from 0 to 255).
Definition: RGBAColor.h:310
virtual void keyPressEvent(QKeyEvent *event)
Reimplemented from QGraphicsTextItem.
Definition: TextItem.cpp:274
bool isItalic()
Returns true if font use italic, false otherwise.
Definition: Font.cpp:91
std::string m_nameClass
Class name.
Definition: ItemObserver.h:201
virtual ~TextItem()
Destructor.
Definition: TextItem.cpp:73
bool isUnderline()
Returns true if font use underline, false otherwise.
Definition: Font.cpp:101
virtual te::color::RGBAColor ** getRGBAColorImage(int &w, int &h)
Reimplemented from ItemObserver.
Definition: TextItem.cpp:231
Class representing the scene. This scene is child of QGraphicsScene, part of Graphics View Framework...
Definition: Scene.h:80
virtual te::color::RGBAColor getBackgroundColor()
Returns the background color of the MVC component.
virtual void updateTextConfig()
Definition: TextItem.cpp:386
virtual bool isEditable()
Definition: TextItem.cpp:333
QColor m_backgroundColor
Definition: TextItem.h:172
virtual void getDocumentSizeMM(double &w, double &h)
Definition: TextItem.cpp:338
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
Reimplemented from QGraphicsTextItem.
Definition: TextItem.cpp:323
TEQTWIDGETSEXPORT QImage * GetImage(te::color::RGBAColor **img, int width, int height)
It creates a QImage from an RGBA color array.
Definition: Utils.cpp:69
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
virtual void addUndoStack(QUndoCommand *command)
Method that insert command Undo/Redo of type AddCommand in the Undo/Redo stack.
Definition: Scene.cpp:313
std::string getFamily()
Sets font family name.
Definition: Font.cpp:61
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
Reimplemented from QGraphicsTextItem.
Definition: TextItem.cpp:280
Class that represents text. This object is of type QGraphicsTextItem. He is directly editable via use...
virtual Font getFont()
Definition: TextModel.cpp:109
virtual te::layout::Properties * getProperties() const
Reimplemented from Observable.
Definition: TextModel.cpp:57
Undo/Redo for changes in component properties.
virtual void setBox(te::gm::Envelope box)
Change the bounding rectangle.
Abstract class that represents a graphic item. Its coordinate system is the same of scene (millimeter...
Definition: ParentItem.h:86
virtual void init()
Definition: TextItem.cpp:81
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value)
Reimplemented from QGraphicsTextItem.
Definition: TextItem.cpp:244
bool isKerning()
Returns true if font use kerning, false otherwise.
Definition: Font.cpp:121