diff --git a/sources/qetgraphicsitem/diagramtextitem.cpp b/sources/qetgraphicsitem/diagramtextitem.cpp index be38eab7c..5edc38f9a 100644 --- a/sources/qetgraphicsitem/diagramtextitem.cpp +++ b/sources/qetgraphicsitem/diagramtextitem.cpp @@ -171,6 +171,17 @@ QColor DiagramTextItem::color() const { return defaultTextColor(); } +void DiagramTextItem::setAlignment(const Qt::Alignment &alignment) +{ + m_alignment = alignment; + emit alignmentChanged(alignment); +} + +Qt::Alignment DiagramTextItem::alignment() const +{ + return m_alignment; +} + /** * @brief DiagramTextItem::paint * Draw this text field. This method draw the text by calling QGraphicsTextItem::paint. @@ -328,6 +339,46 @@ void DiagramTextItem::applyRotation(const qreal &angle) { setRotation(QET::correctAngle(rotation()+angle)); } +/** + * @brief DiagramTextItem::prepareAlignment + * Call this function before changing the bounding rect of this text. + */ +void DiagramTextItem::prepareAlignment() +{ + m_alignment_rect = mapToParent(boundingRect()).boundingRect(); +} + +/** + * @brief DiagramTextItem::finishAlignment + * Call this function after changing the bouding rect of this text + * to set the position of this text according the alignment property. + */ +void DiagramTextItem::finishAlignment() +{ + if(m_block_alignment) + return; + + QPointF pos = this->pos(); + + if(m_alignment &Qt::AlignRight) + pos.setX(m_alignment_rect.right() - boundingRect().width()); + else if(m_alignment &Qt::AlignHCenter) + { + qreal x = m_alignment_rect.x() + (m_alignment_rect.width()/2); + pos.setX(x - boundingRect().width()/2); + } + + if(m_alignment &Qt::AlignBottom) + pos.setY(m_alignment_rect.bottom() - boundingRect().height()); + else if(m_alignment &Qt::AlignVCenter) + { + qreal y = m_alignment_rect.y() + (m_alignment_rect.height()/2); + pos.setY(y - boundingRect().height()/2); + } + + setPos(pos); +} + /** * @brief Edit the text with HtmlEditor */ diff --git a/sources/qetgraphicsitem/diagramtextitem.h b/sources/qetgraphicsitem/diagramtextitem.h index 8e7a6918f..53c471b8c 100644 --- a/sources/qetgraphicsitem/diagramtextitem.h +++ b/sources/qetgraphicsitem/diagramtextitem.h @@ -35,10 +35,14 @@ class DiagramTextItem : public QGraphicsTextItem Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) signals: void fontSizeChanged(int size); void colorChanged(QColor color); + void alignmentChanged(Qt::Alignment alignment); + void diagramTextChanged(DiagramTextItem *, const QString &, const QString &); + void textEdited(const QString &old_str, const QString &new_str); public: DiagramTextItem(QGraphicsItem * = nullptr); @@ -68,6 +72,10 @@ class DiagramTextItem : public QGraphicsTextItem QColor color() const; void setNoEditable(bool e = true) {m_no_editable = e;} + + void setAlignment(const Qt::Alignment &alignment); + Qt::Alignment alignment() const; + bool m_block_alignment = false; protected: void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override; @@ -84,10 +92,9 @@ class DiagramTextItem : public QGraphicsTextItem void hoverMoveEvent(QGraphicsSceneHoverEvent *) override; virtual void applyRotation(const qreal &); + void prepareAlignment(); + void finishAlignment(); - signals: - void diagramTextChanged(DiagramTextItem *, const QString &, const QString &); - void textEdited(const QString &old_str, const QString &new_str); protected: bool m_mouse_hover = false, @@ -98,5 +105,9 @@ class DiagramTextItem : public QGraphicsTextItem m_previous_text; QPointF m_mouse_to_origin_movement; + + private: + QRectF m_alignment_rect; + Qt::Alignment m_alignment = (Qt::AlignTop | Qt::AlignLeft); }; #endif diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.cpp b/sources/qetgraphicsitem/dynamicelementtextitem.cpp index a4189a8d2..def9dedf8 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.cpp +++ b/sources/qetgraphicsitem/dynamicelementtextitem.cpp @@ -97,6 +97,22 @@ QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const QMetaEnum me = textFromMetaEnum(); root_element.setAttribute("text_from", me.valueToKey(m_text_from)); + me = QMetaEnum::fromType(); + if(this->alignment() &Qt::AlignRight) + root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignRight)); + else if(this->alignment() &Qt::AlignLeft) + root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignLeft)); + else if(this->alignment() &Qt::AlignHCenter) + root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignHCenter)); + + if(this->alignment() &Qt::AlignBottom) + root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignBottom)); + else if(this->alignment() & Qt::AlignTop) + root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignTop)); + else if(this->alignment() &Qt::AlignVCenter) + root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignVCenter)); + + QDomElement dom_text = dom_doc.createElement("text"); dom_text.appendChild(dom_doc.createTextNode(toPlainText())); root_element.appendChild(dom_text); @@ -140,8 +156,6 @@ void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt) return; } - QGraphicsTextItem::setPos(dom_elmt.attribute("x", QString::number(0)).toDouble(), - dom_elmt.attribute("y", QString::number(0)).toDouble()); QGraphicsTextItem::setRotation(dom_elmt.attribute("rotation", QString::number(0)).toDouble()); setFont(QETApp::diagramTextsFont(dom_elmt.attribute("font_size", QString::number(9)).toInt())); m_uuid = QUuid(dom_elmt.attribute("uuid", QUuid::createUuid().toString())); @@ -151,6 +165,12 @@ void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt) //Text from QMetaEnum me = textFromMetaEnum(); setTextFrom(DynamicElementTextItem::TextFrom(me.keyToValue(dom_elmt.attribute("text_from").toStdString().data()))); + + me = QMetaEnum::fromType(); + if(dom_elmt.hasAttribute("Halignment")) + setAlignment(Qt::Alignment(me.keyToValue(dom_elmt.attribute("Halignment").toStdString().data()))); + if(dom_elmt.hasAttribute(("Valignment"))) + setAlignment(Qt::Alignment(me.keyToValue(dom_elmt.attribute("Valignment").toStdString().data())) | this->alignment()); //Text QDomElement dom_text = dom_elmt.firstChildElement("text"); @@ -174,6 +194,9 @@ void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt) //Force the update of the displayed text setTextFrom(m_text_from); + + QGraphicsTextItem::setPos(dom_elmt.attribute("x", QString::number(0)).toDouble(), + dom_elmt.attribute("y", QString::number(0)).toDouble()); } /** @@ -1291,6 +1314,8 @@ void DynamicElementTextItem::updateXref() void DynamicElementTextItem::setPlainText(const QString &text) { + prepareAlignment(); + DiagramTextItem::setPlainText(text); //User define a text width @@ -1306,6 +1331,8 @@ void DynamicElementTextItem::setPlainText(const QString &text) } } + finishAlignment(); + if(m_Xref_item) m_Xref_item->autoPos(); else if(m_slave_Xref_item) @@ -1323,4 +1350,3 @@ void DynamicElementTextItem::setTextWidth(qreal width) m_text_width = width; emit textWidthChanged(width); } - diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.h b/sources/qetgraphicsitem/dynamicelementtextitem.h index 1f9a7dbff..e995130a0 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.h +++ b/sources/qetgraphicsitem/dynamicelementtextitem.h @@ -130,6 +130,7 @@ class DynamicElementTextItem : public DiagramTextItem void conductorPropertiesChanged(); QString reportReplacedCompositeText() const; void zoomToLinkedElement(); + private: QPointer m_parent_element, diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp index baa7f483f..3c06a3eb9 100644 --- a/sources/qetgraphicsitem/element.cpp +++ b/sources/qetgraphicsitem/element.cpp @@ -551,7 +551,14 @@ bool Element::fromXml(QDomElement &e, QHash &table_id_adr, bool !m_element_informations.value("label").toString().isEmpty()) dc.addValue("label", m_element_informations.value("label")); + //We must to block the update of the alignment when load the information + //otherwise the pos of the text will not be the same as it was at save time. + for(DynamicElementTextItem *deti : m_dynamic_text_list) + deti->m_block_alignment = true; setElementInformations(dc); + for(DynamicElementTextItem *deti : m_dynamic_text_list) + deti->m_block_alignment = false; + /** During the devel of the version 0.7, the "old text" was replaced by the dynamic element text item. diff --git a/sources/ui/alignmenttextdialog.cpp b/sources/ui/alignmenttextdialog.cpp new file mode 100644 index 000000000..fddeb644e --- /dev/null +++ b/sources/ui/alignmenttextdialog.cpp @@ -0,0 +1,94 @@ +/* + Copyright 2006-2017 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "alignmenttextdialog.h" +#include "ui_alignmenttextdialog.h" +#include "dynamicelementtextitem.h" + +AlignmentTextDialog::AlignmentTextDialog(DynamicElementTextItem *text, QWidget *parent) : + QDialog(parent), + ui(new Ui::AlignmentTextDialog) +{ + ui->setupUi(this); + + Qt::Alignment align = text->alignment(); + if(align == (Qt::AlignTop|Qt::AlignLeft)) + ui->top_left->setChecked(true); + else if(align == (Qt::AlignTop|Qt::AlignHCenter)) + ui->top->setChecked(true); + else if(align == (Qt::AlignTop|Qt::AlignRight)) + ui->top_right->setChecked(true); + else if(align == (Qt::AlignVCenter|Qt::AlignLeft)) + ui->left->setChecked(true); + else if(align == Qt::AlignCenter) + ui->center->setChecked(true); + else if(align == (Qt::AlignVCenter|Qt::AlignRight)) + ui->right->setChecked(true); + else if(align == (Qt::AlignBottom|Qt::AlignLeft)) + ui->bottom_left->setChecked(true); + else if(align == (Qt::AlignBottom|Qt::AlignHCenter)) + ui->bottom->setChecked(true); + else if(align == (Qt::AlignBottom|Qt::AlignRight)) + ui->bottom_right->setChecked(true); +} + +AlignmentTextDialog::~AlignmentTextDialog() +{ + delete ui; +} + +/** + * @brief AlignmentTextDialog::alignment + * @return the selected alignment + */ +Qt::Alignment AlignmentTextDialog::alignment() const +{ + if(ui->top_left->isChecked()) + return (Qt::AlignTop|Qt::AlignLeft); + else if(ui->top->isChecked()) + return (Qt::AlignTop|Qt::AlignHCenter); + else if(ui->top_right->isChecked()) + return (Qt::AlignTop|Qt::AlignRight); + else if(ui->left->isChecked()) + return (Qt::AlignVCenter|Qt::AlignLeft); + else if (ui->center->isChecked()) + return Qt::AlignCenter; + else if(ui->right->isChecked()) + return (Qt::AlignVCenter|Qt::AlignRight); + else if(ui->bottom_left->isChecked()) + return (Qt::AlignBottom|Qt::AlignLeft); + else if(ui->bottom->isChecked()) + return (Qt::AlignBottom|Qt::AlignHCenter); + else if(ui->bottom_right->isChecked()) + return (Qt::AlignBottom|Qt::AlignRight); + else + return (Qt::AlignTop|Qt::AlignLeft); +} + +bool AlignmentTextDialog::event(QEvent *event) +{ + //Little hack to set focus to a radio button + //if we not do that, when the user click on the title bar (for move the dialog) or try to resize the dialog, + //the dialog lose focus and close. + if(event->type() == QEvent::Show && m_first_show) + { + QTimer::singleShot(50, [this](){ui->top_left->setFocus();}); + m_first_show = false; + } + + return QDialog::event(event); +} diff --git a/sources/ui/alignmenttextdialog.h b/sources/ui/alignmenttextdialog.h new file mode 100644 index 000000000..5e9b7b625 --- /dev/null +++ b/sources/ui/alignmenttextdialog.h @@ -0,0 +1,47 @@ +/* + Copyright 2006-2017 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef ALIGNMENTTEXTDIALOG_H +#define ALIGNMENTTEXTDIALOG_H + +#include + +class DynamicElementTextItem; + +namespace Ui { + class AlignmentTextDialog; +} + +class AlignmentTextDialog : public QDialog +{ + Q_OBJECT + + public: + explicit AlignmentTextDialog(DynamicElementTextItem *text, QWidget *parent = nullptr); + ~AlignmentTextDialog(); + + Qt::Alignment alignment() const; + + protected: + bool event(QEvent *event); + + private: + bool m_first_show = true; + Ui::AlignmentTextDialog *ui; +}; + +#endif // ALIGNMENTTEXTDIALOG_H diff --git a/sources/ui/alignmenttextdialog.ui b/sources/ui/alignmenttextdialog.ui new file mode 100644 index 000000000..96581bc12 --- /dev/null +++ b/sources/ui/alignmenttextdialog.ui @@ -0,0 +1,185 @@ + + + AlignmentTextDialog + + + + 0 + 0 + 160 + 158 + + + + + 200 + 150 + + + + + 160 + 158 + + + + Alignement du texte + + + true + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AlignmentTextDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AlignmentTextDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/sources/ui/dynamicelementtextmodel.cpp b/sources/ui/dynamicelementtextmodel.cpp index bdf8ffedb..f319b6efe 100644 --- a/sources/ui/dynamicelementtextmodel.cpp +++ b/sources/ui/dynamicelementtextmodel.cpp @@ -33,6 +33,7 @@ #include "qeticons.h" #include "diagram.h" #include "addelementtextcommand.h" +#include "alignmenttextdialog.h" int src_txt_row = 0; int usr_txt_row = 1; @@ -45,6 +46,7 @@ int width_txt_row = 7; int x_txt_row = 8; int y_txt_row = 9; int rot_txt_row = 10; +int align_txt_row = 11; int align_grp_row = 0; int rot_grp_row = 1; @@ -276,6 +278,19 @@ QList DynamicElementTextModel::itemsForText(DynamicElementTextI qsi_list.clear();; qsi_list << rot << rot_a; + qsi->appendRow(qsi_list); + + //Alignment + QStandardItem *alignment = new QStandardItem(tr("Alignement")); + alignment->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + + QStandardItem *alignmenta = new QStandardItem(tr("Éditer")); + alignmenta->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); + alignmenta->setData(DynamicElementTextModel::txtAlignment, Qt::UserRole+1); + alignmenta->setData(QVariant::fromValue(deti->alignment()), Qt::UserRole+2); + + qsi_list.clear(); + qsi_list << alignment << alignmenta; qsi->appendRow(qsi_list); } @@ -451,6 +466,13 @@ QUndoCommand *DynamicElementTextModel::undoForEditedText(DynamicElementTextItem new QPropertyUndoCommand(deti, "compositeText", QVariant(deti->compositeText()), QVariant(composite_text), undo); } + Qt::Alignment alignment = text_qsi->child(align_txt_row, 1)->data(Qt::UserRole+2).value(); + if (alignment != deti->alignment()) + { + QPropertyUndoCommand *quc = new QPropertyUndoCommand(deti, "alignment", QVariant(deti->alignment()), QVariant(alignment), undo); + quc->setText(tr("Modifier l'alignement d'un texte d'élément")); + } + int fs = text_qsi->child(size_txt_row,1)->data(Qt::EditRole).toInt(); if (fs != deti->fontSize()) { @@ -1368,6 +1390,22 @@ QWidget *DynamicTextItemDelegate::createEditor(QWidget *parent, const QStyleOpti cted->setObjectName("composite_text"); return cted; } + case DynamicElementTextModel::txtAlignment: + { + const DynamicElementTextModel *detm = static_cast(index.model()); + QStandardItem *qsi = detm->itemFromIndex(index); + + if(!qsi) + break; + + DynamicElementTextItem *deti = detm->textFromIndex(index); + if(!deti) + break; + + AlignmentTextDialog *atd = new AlignmentTextDialog(deti, parent); + atd->setObjectName("alignment_text"); + return atd; + } case DynamicElementTextModel::size: { QSpinBox *sb = new QSpinBox(parent); @@ -1502,6 +1540,19 @@ void DynamicTextItemDelegate::setModelData(QWidget *editor, QAbstractItemModel * } } } + else if (editor->objectName() == "alignment_text") + { + if(QStandardItemModel *qsim = dynamic_cast(model)) + { + if(QStandardItem *qsi = qsim->itemFromIndex(index)) + { + AlignmentTextDialog *atd = static_cast(editor); + Qt::Alignment align = atd->alignment(); + qsi->setData(QVariant::fromValue(align), Qt::UserRole+2); + return; + } + } + } else if (editor->objectName() == "group_alignment") { if(QStandardItemModel *qsim = dynamic_cast(model)) diff --git a/sources/ui/dynamicelementtextmodel.h b/sources/ui/dynamicelementtextmodel.h index 0e19d08dd..2227e3e19 100644 --- a/sources/ui/dynamicelementtextmodel.h +++ b/sources/ui/dynamicelementtextmodel.h @@ -42,6 +42,7 @@ class DynamicElementTextModel : public QStandardItemModel userText, infoText, compositeText, + txtAlignment, size, color, pos,