File indexing completed on 2024-04-28 05:38:12
0001 /*************************************************************************** 0002 * Copyright (C) 2010 by Renaud Guezennec * 0003 * * 0004 * * 0005 * rolisteam is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "textitem.h" 0021 #include <QDebug> 0022 #include <QFont> 0023 #include <QLineEdit> 0024 #include <QMenu> 0025 #include <QObject> 0026 #include <QPainter> 0027 #include <QStyle> 0028 0029 #include <QGraphicsSceneWheelEvent> 0030 #include <QStyleOptionGraphicsItem> 0031 0032 #include "controller/item_controllers/textcontroller.h" 0033 #include "controller/item_controllers/visualitemcontroller.h" 0034 #include "controller/view_controller/vectorialmapcontroller.h" 0035 #include "editors/mrichtextedit.h" 0036 #include "network/networkmessagereader.h" 0037 #include "network/networkmessagewriter.h" 0038 0039 #include "customs/vmap.h" 0040 0041 /////////////////////////////////////// 0042 /// Code of TextLabel 0043 /////////////////////////////////////// 0044 TextLabel::TextLabel(QGraphicsItem* parent) : QGraphicsTextItem(parent) 0045 { 0046 setFlag(QGraphicsItem::ItemIsFocusable, true); 0047 } 0048 0049 QRectF TextLabel::textRect() const 0050 { 0051 return m_rect; 0052 } 0053 0054 QRectF TextLabel::boundingRect() const 0055 { 0056 auto rect= QGraphicsTextItem::boundingRect(); 0057 0058 QRectF maxRect(0, 0, std::max(m_rect.width(), rect.width()), std::max(rect.height(), m_rect.height())); 0059 return maxRect; 0060 } 0061 0062 void TextLabel::setTextRect(const QRectF& rect) 0063 { 0064 if(rect == m_rect) 0065 return; 0066 0067 m_rect= rect; 0068 emit textRectChanged(); 0069 setTextWidth(rect.width()); 0070 } 0071 void TextLabel::mousePressEvent(QGraphicsSceneMouseEvent* event) 0072 { 0073 VMap* map= dynamic_cast<VMap*>(scene()); 0074 if(nullptr != map) 0075 { 0076 // if(map->getSelectedtool() == Core::HANDLER) 0077 { 0078 // event->accept(); 0079 setFocus(Qt::OtherFocusReason); 0080 QGraphicsTextItem::mousePressEvent(event); 0081 } 0082 // else if((map->getSelectedtool() == Core::TEXT) || (map->getSelectedtool() == Core::TEXTBORDER)) 0083 { 0084 QGraphicsTextItem::mousePressEvent(event); 0085 } 0086 } 0087 } 0088 0089 void TextLabel::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) 0090 { 0091 QGraphicsTextItem::mouseDoubleClickEvent(event); 0092 } 0093 0094 /////////////////////////////////////// 0095 /// Code of RichTextEditDialog 0096 /////////////////////////////////////// 0097 0098 RichTextEditDialog::RichTextEditDialog() 0099 { 0100 m_richText= new MRichTextEdit(this); 0101 QVBoxLayout* lay= new QVBoxLayout(this); 0102 lay->addWidget(m_richText); 0103 0104 QDialogButtonBox* dialogButton= new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 0105 lay->addWidget(dialogButton); 0106 0107 connect(dialogButton, &QDialogButtonBox::accepted, this, &RichTextEditDialog::accept); 0108 connect(dialogButton, &QDialogButtonBox::rejected, this, &RichTextEditDialog::reject); 0109 0110 setLayout(lay); 0111 } 0112 0113 void RichTextEditDialog::setText(QString str) 0114 { 0115 m_richText->setText(str); 0116 } 0117 0118 QString RichTextEditDialog::getText() 0119 { 0120 return m_richText->toHtml(); 0121 } 0122 0123 /////////////////////// 0124 /// Code of TextItem 0125 // 0126 // 0127 // 0128 /////////////////////// 0129 0130 RichTextEditDialog* TextItem::m_dialog= nullptr; 0131 0132 TextItem::TextItem(vmap::TextController* ctrl) 0133 : VisualItem(ctrl) 0134 , m_textCtrl(ctrl) 0135 , m_doc(new QTextDocument) 0136 , m_textItem(new TextLabel(this)) 0137 , m_increaseFontSize(new QAction(tr("Increase Text Size"))) 0138 , m_decreaseFontSize(new QAction(tr("Decrease Text Size"))) 0139 , m_edit(new QAction(tr("Edit Text…"))) 0140 , m_adapt(new QAction(tr("Adapt to content"))) 0141 { 0142 if(nullptr == m_dialog) 0143 m_dialog= new RichTextEditDialog(); 0144 0145 connect(m_edit.get(), &QAction::triggered, this, &TextItem::editText); 0146 connect(m_adapt.get(), &QAction::triggered, this, &TextItem::sizeToTheContent); 0147 0148 connect(m_increaseFontSize.get(), &QAction::triggered, m_textCtrl, &vmap::TextController::increaseFontSize); 0149 connect(m_decreaseFontSize.get(), &QAction::triggered, m_textCtrl, &vmap::TextController::decreaseFontSize); 0150 0151 m_textItem->setDocument(m_doc.get()); 0152 connect(m_textCtrl, &vmap::TextController::borderRectChanged, this, 0153 [this]() 0154 { 0155 m_textItem->setTextWidth(m_textCtrl->borderRect().width()); 0156 m_textCtrl->setTextRect(m_textItem->boundingRect()); 0157 updateChildPosition(); 0158 }); 0159 connect(m_textCtrl, &vmap::TextController::textRectChanged, this, 0160 [this]() { m_textItem->setTextWidth(m_textCtrl->textRect().width()); }); 0161 connect(m_textCtrl, &vmap::TextController::textPosChanged, this, 0162 [this](const QPointF& pos) { m_textItem->setPos(pos); }); 0163 0164 connect(m_textCtrl, &vmap::TextController::textChanged, m_doc.get(), &QTextDocument::setPlainText); 0165 connect(m_doc.get(), &QTextDocument::contentsChanged, this, 0166 [this]() 0167 { 0168 if(!m_textCtrl) 0169 return; 0170 m_textCtrl->setText(m_doc->toPlainText()); 0171 auto rect= m_textItem->boundingRect(); 0172 m_textCtrl->setTextRect(rect); 0173 }); 0174 0175 for(int i= 0; i <= vmap::TextController::BottomLeft; ++i) 0176 { 0177 ChildPointItem* tmp= new ChildPointItem(m_textCtrl, i, this); 0178 tmp->setMotion(ChildPointItem::MOUSE); 0179 m_children.append(tmp); 0180 } 0181 updateChildPosition(); 0182 0183 setAcceptHoverEvents(true); 0184 m_textItem->setFocus(); 0185 m_textItem->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); 0186 m_textItem->setPos(QPointF(0, 0)); 0187 m_textItem->setTextWidth(100); 0188 m_textItem->setTextInteractionFlags(Qt::TextEditorInteraction); 0189 if(m_textCtrl) 0190 m_textItem->setDefaultTextColor(m_textCtrl->color()); 0191 m_doc->setPlainText(tr("Text")); 0192 } 0193 0194 QRectF TextItem::boundingRect() const 0195 { 0196 return m_textCtrl->borderRect(); 0197 } 0198 void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) 0199 { 0200 Q_UNUSED(option) 0201 Q_UNUSED(widget) 0202 setChildrenVisible(hasFocusOrChild()); 0203 if(m_textCtrl->border()) 0204 { 0205 QPen pen= painter->pen(); 0206 pen.setColor(m_textCtrl->color()); 0207 pen.setWidth(m_textCtrl->border() ? m_textCtrl->penWidth() : 2); 0208 painter->setPen(pen); 0209 painter->drawRect(boundingRect()); 0210 } 0211 if(canBeMoved() && (option->state & QStyle::State_MouseOver || isSelected())) 0212 { 0213 painter->save(); 0214 QPen pen= painter->pen(); 0215 pen.setColor(isSelected() ? m_selectedColor : m_highlightColor); 0216 pen.setWidth(m_highlightWidth); 0217 painter->setPen(pen); 0218 painter->drawRect(m_textCtrl->borderRect()); 0219 painter->restore(); 0220 } 0221 } 0222 0223 void TextItem::setNewEnd(const QPointF& p) 0224 { 0225 Q_UNUSED(p) 0226 } 0227 0228 void TextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) 0229 { 0230 if(event->button() == Qt::LeftButton) 0231 { 0232 setChildrenVisible(false); 0233 m_menuPos= event->screenPos(); 0234 editText(); 0235 event->accept(); 0236 } 0237 else 0238 { 0239 VisualItem::mouseDoubleClickEvent(event); 0240 } 0241 } 0242 void TextItem::wheelEvent(QGraphicsSceneWheelEvent* event) 0243 { 0244 if(!event->modifiers() & Qt::ControlModifier) 0245 VisualItem::wheelEvent(event); 0246 0247 event->delta() > 0 ? m_textCtrl->increaseFontSize() : m_textCtrl->decreaseFontSize(); 0248 event->accept(); 0249 } 0250 0251 void TextItem::updateChildPosition() 0252 { 0253 if(!m_textCtrl) 0254 return; 0255 auto rect= m_textCtrl->borderRect(); 0256 m_children.value(0)->setPos(rect.topLeft()); 0257 m_children.value(0)->setPlacement(ChildPointItem::TopLeft); 0258 m_children.value(1)->setPos(rect.topRight()); 0259 m_children.value(1)->setPlacement(ChildPointItem::TopRight); 0260 m_children.value(2)->setPos(rect.bottomRight()); 0261 m_children.value(2)->setPlacement(ChildPointItem::ButtomRight); 0262 m_children.value(3)->setPos(rect.bottomLeft()); 0263 m_children.value(3)->setPlacement(ChildPointItem::ButtomLeft); 0264 update(); 0265 } 0266 0267 void TextItem::editText() 0268 { 0269 m_dialog->setText(m_textItem->toHtml()); 0270 m_dialog->move(m_menuPos); 0271 if(QDialog::Accepted == m_dialog->exec()) 0272 { 0273 m_textItem->setHtml(m_dialog->getText()); 0274 // updateTextPosition(); 0275 emit itemGeometryChanged(this); 0276 } 0277 } 0278 0279 /*void TextItem::endOfGeometryChange(ChildPointItem::Change change) 0280 { 0281 if(change == ChildPointItem::Resizing) 0282 { 0283 auto oldScenePos= scenePos(); 0284 setTransformOriginPoint(m_textCtrl->borderRect().center()); 0285 auto newScenePos= scenePos(); 0286 auto oldPos= pos(); 0287 m_textCtrl->setPos(QPointF(oldPos.x() + (oldScenePos.x() - newScenePos.x()), 0288 oldPos.y() + (oldScenePos.y() - newScenePos.y()))); 0289 } 0290 VisualItem::endOfGeometryChange(change); 0291 }*/ 0292 0293 void TextItem::addActionContextMenu(QMenu& menu) 0294 { 0295 menu.addAction(m_edit.get()); 0296 menu.addAction(m_adapt.get()); 0297 0298 QMenu* state= menu.addMenu(tr("Font Size")); 0299 state->addAction(m_increaseFontSize.get()); 0300 state->addAction(m_decreaseFontSize.get()); 0301 VisualItem::addActionContextMenu(menu); 0302 } 0303 0304 void TextItem::sizeToTheContent() 0305 { 0306 QRectF rectItem= m_textItem->boundingRect(); 0307 /* setTransformOriginPoint(m_rect.center()); 0308 if(rectItem.height() < m_rect.height() + 10) 0309 { 0310 m_rect.setHeight(rectItem.height() + 10); 0311 m_resizing= true; 0312 } 0313 if(rectItem.width() < m_rect.width() + 10) 0314 { 0315 m_rect.setWidth(rectItem.width() + 10); 0316 m_resizing= true; 0317 }*/ 0318 /*if(m_resizing) 0319 { 0320 endOfGeometryChange(ChildPointItem::Resizing); 0321 }*/ 0322 } 0323 0324 void TextItem::updateItemFlags() 0325 { 0326 VisualItem::updateItemFlags(); 0327 if(!canBeMoved()) 0328 { 0329 m_textItem->setTextInteractionFlags(Qt::NoTextInteraction); 0330 } 0331 else 0332 { 0333 m_textItem->setTextInteractionFlags(Qt::TextEditorInteraction); 0334 } 0335 } 0336 void TextItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) 0337 { 0338 Q_UNUSED(event) 0339 if(canBeMoved()) 0340 { 0341 VMap* vmap= dynamic_cast<VMap*>(scene()); 0342 if(nullptr != vmap) 0343 { 0344 /*Core::SelectableTool tool= vmap->getSelectedtool(); 0345 if((Core::TEXT == tool) || (Core::TEXTBORDER == tool)) 0346 { 0347 QApplication::setOverrideCursor(QCursor(Qt::IBeamCursor)); 0348 }*/ 0349 } 0350 } 0351 VisualItem::hoverEnterEvent(event); 0352 } 0353 void TextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) 0354 { 0355 Q_UNUSED(event) 0356 if(canBeMoved()) 0357 QApplication::restoreOverrideCursor(); 0358 0359 VisualItem::hoverLeaveEvent(event); 0360 } 0361 void TextItem::keyPressEvent(QKeyEvent* event) 0362 { 0363 if(m_textItem->hasCursor()) 0364 { 0365 QGraphicsItem::keyPressEvent(event); 0366 } 0367 else 0368 { 0369 VisualItem::keyPressEvent(event); 0370 } 0371 }