mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-09-13 20:23:04 +02:00
First step for the dynamic element text : Now user can add directly from the diagram editor an editable text of an element.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5005 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
parent
0df5391491
commit
3ef55906a4
@ -10,6 +10,7 @@ ConductorTextItem + 1006
|
||||
DiagramImageItem + 1007
|
||||
QetShapItem + 1008
|
||||
crossRefItem + 1009
|
||||
DynamiqueElementTextItem + 1010
|
||||
ElementPrimitiveDecorator + 2200
|
||||
|
||||
###ELEMENT EDITOR###
|
||||
@ -21,3 +22,6 @@ part terminal + 1106
|
||||
part text + 1107
|
||||
part text field + 1108
|
||||
part rectangle + 1109
|
||||
|
||||
###QetGraphicsHandlerItem###
|
||||
QetGraphicsHandlerItem = 1200
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "elementcollectionhandler.h"
|
||||
#include "element.h"
|
||||
#include "diagramview.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
|
||||
const int Diagram::xGrid = 10;
|
||||
const int Diagram::yGrid = 10;
|
||||
@ -75,7 +76,7 @@ Diagram::Diagram(QETProject *project) :
|
||||
|
||||
//Init object for manage movement
|
||||
elements_mover_ = new ElementsMover();
|
||||
element_texts_mover_ = new ElementTextsMover();
|
||||
m_element_texts_mover = new ElementTextsMover();
|
||||
|
||||
connect(&border_and_titleblock, SIGNAL(needTitleBlockTemplate(const QString &)), this, SLOT(setTitleBlockTemplate(const QString &)));
|
||||
connect(&border_and_titleblock, SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(titleChanged(const QString &)));
|
||||
@ -91,7 +92,10 @@ Diagram::Diagram(QETProject *project) :
|
||||
* @brief Diagram::~Diagram
|
||||
* Destructor
|
||||
*/
|
||||
Diagram::~Diagram() {
|
||||
Diagram::~Diagram()
|
||||
{
|
||||
//First clear every selection to close an hypothetical editor
|
||||
clearSelection();
|
||||
// clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
|
||||
undoStack().clear();
|
||||
//delete of QGIManager, every elements he knows are removed
|
||||
@ -101,21 +105,17 @@ Diagram::~Diagram() {
|
||||
|
||||
// delete of object for manage movement
|
||||
delete elements_mover_;
|
||||
delete element_texts_mover_;
|
||||
delete m_element_texts_mover;
|
||||
|
||||
if (m_event_interface) delete m_event_interface;
|
||||
if (m_event_interface)
|
||||
delete m_event_interface;
|
||||
|
||||
// list removable items
|
||||
QList<QGraphicsItem *> deletable_items;
|
||||
for(QGraphicsItem *qgi : items())
|
||||
{
|
||||
if (qgi->parentItem())
|
||||
continue;
|
||||
if (qgi->type() == Conductor::Type)
|
||||
continue;
|
||||
if (qgi->type() == QetGraphicsHandlerItem::Type)
|
||||
continue;
|
||||
|
||||
if (qgi -> parentItem()) continue;
|
||||
if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
|
||||
deletable_items << qgi;
|
||||
}
|
||||
|
||||
@ -302,10 +302,10 @@ void Diagram::keyPressEvent(QKeyEvent *e)
|
||||
qreal top_position = 0;
|
||||
qreal left_position = 0;
|
||||
QList<QGraphicsItem*> selected_elmts = this->selectedContent().items();
|
||||
if (!this->selectedContent().items(255).isEmpty()) {
|
||||
if (!this->selectedContent().items(DiagramContent::All).isEmpty()) {
|
||||
switch(e -> key()) {
|
||||
case Qt::Key_Left:
|
||||
foreach (Element *item, selectedContent().elements) {
|
||||
foreach (Element *item, selectedContent().m_elements) {
|
||||
left_position = item->mapRectFromScene(item->boundingRect()).x();
|
||||
if (left_position >= this->sceneRect().left() - item->boundingRect().width())
|
||||
return;
|
||||
@ -314,7 +314,7 @@ void Diagram::keyPressEvent(QKeyEvent *e)
|
||||
break;
|
||||
case Qt::Key_Right: movement = QPointF(+xGrid, 0.0); break;
|
||||
case Qt::Key_Up:
|
||||
foreach (Element *item, selectedContent().elements) {
|
||||
foreach (Element *item, selectedContent().m_elements) {
|
||||
top_position = item->mapRectFromScene(item->boundingRect()).y();
|
||||
if (top_position >= this->sceneRect().top() - item->boundingRect().height())
|
||||
return;
|
||||
@ -378,8 +378,6 @@ void Diagram::keyReleaseEvent(QKeyEvent *e)
|
||||
* Diagram become the ownership of event_interface
|
||||
* If there is a previous interface, they will be delete before
|
||||
* and call init() to the new interface.
|
||||
* The derivated class of DiagramEventInterface need to emit the signal "finish" when the job is done,
|
||||
* diagram use this signal to delete the interface. If the signal isn't send, the interface will never be deleted.
|
||||
* @param event_interface
|
||||
*/
|
||||
void Diagram::setEventInterface(DiagramEventInterface *event_interface)
|
||||
@ -968,20 +966,14 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
|
||||
qgi -> setPos( qgi -> pos() += pos_);
|
||||
}
|
||||
|
||||
//Filling of optional lists
|
||||
// remplissage des listes facultatives
|
||||
if (content_ptr) {
|
||||
content_ptr -> elements = added_elements.toSet();
|
||||
content_ptr -> conductorsToMove = added_conductors.toSet();
|
||||
content_ptr -> textFields = added_texts.toSet();
|
||||
content_ptr -> images = added_images.toSet();
|
||||
content_ptr -> shapes = added_shapes.toSet();
|
||||
content_ptr -> m_elements = added_elements.toSet();
|
||||
content_ptr -> m_conductors_to_move = added_conductors.toSet();
|
||||
content_ptr -> m_text_fields = added_texts.toSet();
|
||||
content_ptr -> m_images = added_images.toSet();
|
||||
content_ptr -> m_shapes = added_shapes.toSet();
|
||||
}
|
||||
|
||||
//Ensure the texts of conductor are inside the border of the folio
|
||||
//and so don't cause the annoying margin on the left border of the folio.
|
||||
for(Conductor *cond : added_conductors)
|
||||
cond->textItem()->setPos(cond->textItem()->pos());
|
||||
|
||||
adjustSceneRect();
|
||||
return(true);
|
||||
}
|
||||
@ -1438,7 +1430,7 @@ void Diagram::endMoveElements() {
|
||||
@see ElementTextsMover
|
||||
*/
|
||||
int Diagram::beginMoveElementTexts(QGraphicsItem *driver_item) {
|
||||
return(element_texts_mover_ -> beginMovement(this, driver_item));
|
||||
return(m_element_texts_mover -> beginMovement(this, driver_item));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1447,7 +1439,7 @@ int Diagram::beginMoveElementTexts(QGraphicsItem *driver_item) {
|
||||
@see ElementTextsMover
|
||||
*/
|
||||
void Diagram::continueMoveElementTexts(const QPointF &movement) {
|
||||
element_texts_mover_ -> continueMovement(movement);
|
||||
m_element_texts_mover -> continueMovement(movement);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1455,7 +1447,7 @@ void Diagram::continueMoveElementTexts(const QPointF &movement) {
|
||||
@see ElementTextsMover
|
||||
*/
|
||||
void Diagram::endMoveElementTexts() {
|
||||
element_texts_mover_ -> endMovement();
|
||||
m_element_texts_mover -> endMovement();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1656,53 +1648,24 @@ QSet<Conductor *> Diagram::selectedConductors() const {
|
||||
}
|
||||
|
||||
/**
|
||||
@return la liste de tous les textes selectionnes : les textes independants,
|
||||
mais aussi ceux rattaches a des conducteurs ou des elements
|
||||
*/
|
||||
QSet<DiagramTextItem *> Diagram::selectedTexts() const {
|
||||
* @brief Diagram::selectedTexts
|
||||
* @return A list of every selected texts (every kind of texts)
|
||||
*/
|
||||
QSet<DiagramTextItem *> Diagram::selectedTexts() const
|
||||
{
|
||||
QSet<DiagramTextItem *> selected_texts;
|
||||
foreach(QGraphicsItem *item, selectedItems()) {
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
|
||||
selected_texts << cti;
|
||||
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
|
||||
selected_texts << eti;
|
||||
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
|
||||
selected_texts << iti;
|
||||
}
|
||||
for(QGraphicsItem *qgi : selectedItems())
|
||||
{
|
||||
if (qgi->type() == ConductorTextItem::Type ||
|
||||
qgi->type() == ElementTextItem::Type ||
|
||||
qgi->type() == IndependentTextItem::Type ||
|
||||
qgi->type() == DynamicElementTextItem::Type)
|
||||
selected_texts << static_cast<DiagramTextItem *>(qgi);
|
||||
}
|
||||
|
||||
return(selected_texts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Diagram::selectedConductorTexts
|
||||
* @return the list of conductor texts selected
|
||||
*/
|
||||
QSet<ConductorTextItem *> Diagram::selectedConductorTexts() const {
|
||||
QSet<ConductorTextItem *> selected_texts;
|
||||
foreach(QGraphicsItem *item, selectedItems()) {
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
|
||||
selected_texts << cti;
|
||||
}
|
||||
}
|
||||
return(selected_texts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Diagram::selectedElementTexts
|
||||
* @return the list of element texts selected
|
||||
*/
|
||||
QSet<ElementTextItem*> Diagram::selectedElementTexts() const {
|
||||
QSet<ElementTextItem *> selected_texts;
|
||||
foreach(QGraphicsItem *item, selectedItems()) {
|
||||
if (ElementTextItem *cti = qgraphicsitem_cast< ElementTextItem*>(item)) {
|
||||
selected_texts << cti;
|
||||
}
|
||||
}
|
||||
return(selected_texts);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @return true si le presse-papier semble contenir un schema
|
||||
bool Diagram::clipboardMayContainDiagram() {
|
||||
QString clipboard_text = QApplication::clipboard() -> text().trimmed();
|
||||
@ -1775,47 +1738,53 @@ DiagramContent Diagram::content() const {
|
||||
DiagramContent dc;
|
||||
foreach(QGraphicsItem *qgi, items()) {
|
||||
if (Element *e = qgraphicsitem_cast<Element *>(qgi)) {
|
||||
dc.elements << e;
|
||||
dc.m_elements << e;
|
||||
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(qgi)) {
|
||||
dc.textFields << iti;
|
||||
dc.m_text_fields << iti;
|
||||
} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) {
|
||||
dc.conductorsToMove << c;
|
||||
dc.m_conductors_to_move << c;
|
||||
}
|
||||
}
|
||||
return(dc);
|
||||
}
|
||||
|
||||
/**
|
||||
@return le contenu selectionne du schema.
|
||||
*/
|
||||
DiagramContent Diagram::selectedContent() {
|
||||
* @brief Diagram::selectedContent
|
||||
* @return the selected items, stored in a DiagramContent
|
||||
*/
|
||||
DiagramContent Diagram::selectedContent()
|
||||
{
|
||||
DiagramContent dc;
|
||||
|
||||
// recupere les elements deplaces
|
||||
foreach (QGraphicsItem *item, selectedItems()) {
|
||||
if (Element *elmt = qgraphicsitem_cast<Element *>(item)) {
|
||||
dc.elements << elmt;
|
||||
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
|
||||
dc.textFields << iti;
|
||||
} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item)) {
|
||||
//Get the selected items
|
||||
for (QGraphicsItem *item : selectedItems())
|
||||
{
|
||||
if (Element *elmt = qgraphicsitem_cast<Element *>(item))
|
||||
dc.m_elements << elmt;
|
||||
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
|
||||
dc.m_text_fields << iti;
|
||||
else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item))
|
||||
{
|
||||
// recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables)
|
||||
if (
|
||||
!c -> terminal1 -> parentItem() -> isSelected() &&\
|
||||
!c -> terminal2 -> parentItem() -> isSelected()
|
||||
) {
|
||||
dc.otherConductors << c;
|
||||
dc.m_other_conductors << c;
|
||||
}
|
||||
} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item)) {
|
||||
dc.images << dii;
|
||||
} else if (QetShapeItem *dsi = qgraphicsitem_cast<QetShapeItem *>(item)) {
|
||||
dc.shapes << dsi;
|
||||
}
|
||||
else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item))
|
||||
dc.m_images << dii;
|
||||
else if (QetShapeItem *dsi = qgraphicsitem_cast<QetShapeItem *>(item))
|
||||
dc.m_shapes << dsi;
|
||||
else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
|
||||
dc.m_element_texts << deti;
|
||||
}
|
||||
|
||||
// pour chaque element deplace, determine les conducteurs qui seront modifies
|
||||
foreach(Element *elmt, dc.elements) {
|
||||
foreach(Terminal *terminal, elmt -> terminals()) {
|
||||
foreach(Conductor *conductor, terminal -> conductors()) {
|
||||
//For each selected element, we determine if conductors must be moved or updated.
|
||||
for(Element *elmt : dc.m_elements) {
|
||||
for(Terminal *terminal : elmt -> terminals()) {
|
||||
for(Conductor *conductor : terminal -> conductors()) {
|
||||
Terminal *other_terminal;
|
||||
if (conductor -> terminal1 == terminal) {
|
||||
other_terminal = conductor -> terminal2;
|
||||
@ -1823,10 +1792,10 @@ DiagramContent Diagram::selectedContent() {
|
||||
other_terminal = conductor -> terminal1;
|
||||
}
|
||||
// si les deux elements du conducteur sont deplaces
|
||||
if (dc.elements.contains(other_terminal -> parentElement())) {
|
||||
dc.conductorsToMove << conductor;
|
||||
if (dc.m_elements.contains(other_terminal -> parentElement())) {
|
||||
dc.m_conductors_to_move << conductor;
|
||||
} else {
|
||||
dc.conductorsToUpdate << conductor;
|
||||
dc.m_conductors_to_update << conductor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1836,17 +1805,20 @@ DiagramContent Diagram::selectedContent() {
|
||||
}
|
||||
|
||||
/**
|
||||
@return true s'il est possible de tourner les elements selectionnes.
|
||||
Concretement, cette methode retourne true s'il y a des elements selectionnes
|
||||
et qu'au moins l'un d'entre eux peut etre pivote.
|
||||
*/
|
||||
bool Diagram::canRotateSelection() const {
|
||||
foreach(QGraphicsItem * qgi, selectedItems()) {
|
||||
if (qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
|
||||
qgraphicsitem_cast<ConductorTextItem *>(qgi) ||
|
||||
qgraphicsitem_cast<DiagramImageItem *>(qgi) ||
|
||||
qgraphicsitem_cast<ElementTextItem *>(qgi) ||
|
||||
qgraphicsitem_cast<Element *>(qgi)) return (true);
|
||||
* @brief Diagram::canRotateSelection
|
||||
* @return True if a least one of selected items can be rotated
|
||||
*/
|
||||
bool Diagram::canRotateSelection() const
|
||||
{
|
||||
for (QGraphicsItem *qgi : selectedItems())
|
||||
{
|
||||
if (qgi->type() == IndependentTextItem::Type ||
|
||||
qgi->type() == ConductorTextItem::Type ||
|
||||
qgi->type() == DiagramImageItem::Type ||
|
||||
qgi->type() == ElementTextItem::Type ||
|
||||
qgi->type() == Element::Type ||
|
||||
qgi->type() == DynamicElementTextItem::Type) return true;
|
||||
}
|
||||
return(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -36,11 +36,8 @@ class DiagramTextItem;
|
||||
class Element;
|
||||
class ElementsLocation;
|
||||
class ElementsMover;
|
||||
class ElementTextItem;
|
||||
class IndependentTextItem;
|
||||
class QETProject;
|
||||
class Terminal;
|
||||
class ConductorTextItem;
|
||||
class DiagramImageItem;
|
||||
class ElementTextsMover;
|
||||
class DiagramEventInterface;
|
||||
@ -96,7 +93,7 @@ class Diagram : public QGraphicsScene
|
||||
private:
|
||||
QGraphicsLineItem *conductor_setter_;
|
||||
ElementsMover *elements_mover_;
|
||||
ElementTextsMover *element_texts_mover_;
|
||||
ElementTextsMover *m_element_texts_mover;
|
||||
QGIManager *qgi_manager_;
|
||||
QETProject *m_project;
|
||||
|
||||
@ -191,8 +188,6 @@ class Diagram : public QGraphicsScene
|
||||
QList<Element *> elements() const;
|
||||
QList<Conductor *> conductors() const;
|
||||
QSet<DiagramTextItem *> selectedTexts() const;
|
||||
QSet<ConductorTextItem *> selectedConductorTexts() const;
|
||||
QSet<ElementTextItem*> selectedElementTexts() const;
|
||||
QSet<Conductor *> selectedConductors() const;
|
||||
DiagramContent content() const;
|
||||
DiagramContent selectedContent();
|
||||
|
@ -42,88 +42,6 @@ QString itemText(const Conductor *item) {
|
||||
return QObject::tr("un conducteur");
|
||||
}
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param dia Schema dont on supprime des elements et conducteurs
|
||||
@param content Contenu supprime
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
DeleteElementsCommand::DeleteElementsCommand(
|
||||
Diagram *dia,
|
||||
const DiagramContent &content,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(parent),
|
||||
removed_content(content),
|
||||
diagram(dia)
|
||||
{
|
||||
setText(
|
||||
QString(
|
||||
QObject::tr(
|
||||
"supprimer %1",
|
||||
"undo caption - %1 is a sentence listing the removed content"
|
||||
)
|
||||
).arg(removed_content.sentence(DiagramContent::All))
|
||||
);
|
||||
diagram -> qgiManager().manage(removed_content.items(DiagramContent::All));
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
DeleteElementsCommand::~DeleteElementsCommand() {
|
||||
diagram -> qgiManager().release(removed_content.items(DiagramContent::All));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeleteElementsCommand::undo
|
||||
* Undo this command
|
||||
*/
|
||||
void DeleteElementsCommand::undo()
|
||||
{
|
||||
diagram -> showMe();
|
||||
|
||||
foreach(QGraphicsItem *item, removed_content.items())
|
||||
diagram->addItem(item);
|
||||
|
||||
//We relink element after every element was added to diagram
|
||||
foreach(Element *e, removed_content.elements)
|
||||
foreach (Element *elmt, m_link_hash[e])
|
||||
e -> linkToElement(elmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeleteElementsCommand::redo
|
||||
* Redo the delete command
|
||||
*/
|
||||
void DeleteElementsCommand::redo()
|
||||
{
|
||||
diagram -> showMe();
|
||||
|
||||
foreach(Conductor *c, removed_content.conductors(DiagramContent::AnyConductor))
|
||||
{
|
||||
//If option one text per folio is enable, and the text item of
|
||||
//current conductor is visible (that mean the conductor have the single displayed text)
|
||||
//We call adjustTextItemPosition to other conductor at the same potential to keep
|
||||
//a visible text on this potential.
|
||||
if (diagram -> defaultConductorProperties.m_one_text_per_folio && c -> textItem() -> isVisible())
|
||||
{
|
||||
QList <Conductor *> conductor_list;
|
||||
conductor_list << c -> relatedPotentialConductors(false).toList();
|
||||
if (conductor_list.count())
|
||||
conductor_list.first() -> calculateTextItemPosition();
|
||||
}
|
||||
}
|
||||
|
||||
foreach(Element *e, removed_content.elements)
|
||||
{
|
||||
//Get linked element, for relink it at undo
|
||||
if (!e->linkedElements().isEmpty())
|
||||
m_link_hash.insert(e, e->linkedElements());
|
||||
}
|
||||
|
||||
foreach(QGraphicsItem *item, removed_content.items())
|
||||
diagram->removeItem(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PasteDiagramCommand::PasteDiagramCommand
|
||||
* Constructor
|
||||
@ -176,7 +94,7 @@ void PasteDiagramCommand::redo()
|
||||
first_redo = false;
|
||||
|
||||
//this is the first paste, we do some actions for the new element
|
||||
const QList <Element *> elmts_list = content.elements.toList();
|
||||
const QList <Element *> elmts_list = content.m_elements.toList();
|
||||
for (Element *e : elmts_list)
|
||||
{
|
||||
//make new uuid, because old uuid are the uuid of the copied element
|
||||
@ -211,7 +129,7 @@ void PasteDiagramCommand::redo()
|
||||
eti -> setPlainText("_");
|
||||
|
||||
//Reset the text of conductors
|
||||
const QList <Conductor *> conductors_list = content.conductorsToMove.toList();
|
||||
const QList <Conductor *> conductors_list = content.m_conductors_to_move.toList();
|
||||
for (Conductor *c : conductors_list)
|
||||
{
|
||||
ConductorProperties cp = c -> properties();
|
||||
@ -253,7 +171,7 @@ CutDiagramCommand::CutDiagramCommand(
|
||||
const DiagramContent &content,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
DeleteElementsCommand(dia, content, parent)
|
||||
DeleteQGraphicsItemCommand(dia, content, parent)
|
||||
{
|
||||
setText(
|
||||
QString(
|
||||
@ -366,12 +284,12 @@ void MoveElementsCommand::move(const QPointF &actual_movement) {
|
||||
}
|
||||
|
||||
// Move some conductors
|
||||
foreach(Conductor *conductor, content_to_move.conductorsToMove) {
|
||||
foreach(Conductor *conductor, content_to_move.m_conductors_to_move) {
|
||||
setupAnimation(conductor, "pos", conductor->pos(), conductor->pos() + actual_movement);
|
||||
}
|
||||
|
||||
// Recalcul the path of other conductor
|
||||
foreach(Conductor *conductor, content_to_move.conductorsToUpdate) {
|
||||
foreach(Conductor *conductor, content_to_move.m_conductors_to_update) {
|
||||
setupAnimation(conductor, "animPath", 1, 1);
|
||||
}
|
||||
}
|
||||
@ -588,21 +506,6 @@ void RotateElementsCommand::redo() {
|
||||
foreach(DiagramImageItem *dii, images_to_rotate) dii -> rotateBy(applied_rotation_angle_);
|
||||
}
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param previous_state Hash associant les textes impactes par l'action et leur angle de rotation avant l'action
|
||||
@param applied_rotation Nouvel angle de rotation, a appliquer au textes concernes
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
RotateTextsCommand::RotateTextsCommand(const QHash<DiagramTextItem *, double> &previous_state, double applied_rotation, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
texts_to_rotate(previous_state),
|
||||
applied_rotation_angle_(applied_rotation),
|
||||
diagram(previous_state.key(0)->diagram())
|
||||
{
|
||||
defineCommandName();
|
||||
}
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param texts Liste des textes impactes par l'action. L'objet retiendra leur angle de rotation au moment de sa construction.
|
||||
@ -611,11 +514,11 @@ RotateTextsCommand::RotateTextsCommand(const QHash<DiagramTextItem *, double> &p
|
||||
*/
|
||||
RotateTextsCommand::RotateTextsCommand(const QList<DiagramTextItem *> &texts, double applied_rotation, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
applied_rotation_angle_(applied_rotation),
|
||||
diagram(texts.first()->diagram())
|
||||
m_applied_rotation_angle(applied_rotation),
|
||||
m_diagram(texts.first()->diagram())
|
||||
{
|
||||
foreach(DiagramTextItem *text, texts) {
|
||||
texts_to_rotate.insert(text, text -> rotationAngle());
|
||||
m_texts_to_rotate.insert(text, text -> rotationAngle());
|
||||
}
|
||||
defineCommandName();
|
||||
}
|
||||
@ -630,11 +533,11 @@ RotateTextsCommand::~RotateTextsCommand() {
|
||||
Annule la rotation des textes
|
||||
*/
|
||||
void RotateTextsCommand::undo() {
|
||||
diagram -> showMe();
|
||||
foreach(DiagramTextItem *text, texts_to_rotate.keys()) {
|
||||
m_diagram -> showMe();
|
||||
foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text))
|
||||
cti -> forceRotateByUser(previous_rotate_by_user_[cti]);
|
||||
text -> setRotationAngle(texts_to_rotate[text]);
|
||||
cti -> forceRotateByUser(m_previous_rotate_by_user[cti]);
|
||||
text -> setRotationAngle(m_texts_to_rotate[text]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -642,14 +545,14 @@ void RotateTextsCommand::undo() {
|
||||
Applique l'angle de rotation aux textes
|
||||
*/
|
||||
void RotateTextsCommand::redo() {
|
||||
diagram -> showMe();
|
||||
foreach(DiagramTextItem *text, texts_to_rotate.keys()) {
|
||||
m_diagram -> showMe();
|
||||
foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text)) {
|
||||
//we grab the previous rotation by user of each ConductorTextItem
|
||||
previous_rotate_by_user_.insert(cti, cti -> wasRotateByUser());
|
||||
m_previous_rotate_by_user.insert(cti, cti -> wasRotateByUser());
|
||||
cti -> forceRotateByUser(true);
|
||||
}
|
||||
text -> setRotationAngle(applied_rotation_angle_);
|
||||
text -> setRotationAngle(m_applied_rotation_angle);
|
||||
}
|
||||
}
|
||||
|
||||
@ -663,8 +566,8 @@ void RotateTextsCommand::defineCommandName() {
|
||||
"orienter %1 à %2°",
|
||||
"undo caption - %1 looks like '42 texts', %2 is a rotation angle"
|
||||
)
|
||||
).arg(QET::ElementsAndConductorsSentence(0, 0, texts_to_rotate.count()))
|
||||
.arg(applied_rotation_angle_)
|
||||
).arg(QET::ElementsAndConductorsSentence(0, 0, m_texts_to_rotate.count()))
|
||||
.arg(m_applied_rotation_angle)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "qetgraphicsitem/qetshapeitem.h"
|
||||
#include "conductorprofile.h"
|
||||
#include "diagram.h"
|
||||
#include "undocommand/deleteqgraphicsitemcommand.h"
|
||||
|
||||
class DiagramTextItem;
|
||||
class Element;
|
||||
@ -80,32 +81,6 @@ QString itemText(const QetGraphicsItem *item);
|
||||
QString itemText(const IndependentTextItem *item);
|
||||
QString itemText(const Conductor *item);
|
||||
|
||||
/**
|
||||
This command removes content from a particular diagram.
|
||||
*/
|
||||
class DeleteElementsCommand : public QUndoCommand {
|
||||
// constructors, destructor
|
||||
public:
|
||||
DeleteElementsCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
|
||||
virtual ~DeleteElementsCommand();
|
||||
private:
|
||||
DeleteElementsCommand(const DeleteElementsCommand &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
// attributes
|
||||
private:
|
||||
/// removed content
|
||||
DiagramContent removed_content;
|
||||
/// diagram which the content is removed from
|
||||
Diagram *diagram;
|
||||
/// keep linked element for each removed element linked to other element.
|
||||
QHash <Element *, QList<Element *> > m_link_hash;
|
||||
};
|
||||
|
||||
/**
|
||||
This command pastes some content onto a particular diagram.
|
||||
*/
|
||||
@ -137,7 +112,7 @@ class PasteDiagramCommand : public QUndoCommand {
|
||||
/**
|
||||
This command cuts content from a particular diagram.
|
||||
*/
|
||||
class CutDiagramCommand : public DeleteElementsCommand {
|
||||
class CutDiagramCommand : public DeleteQGraphicsItemCommand {
|
||||
// constructors, destructor
|
||||
public:
|
||||
CutDiagramCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
|
||||
@ -275,19 +250,19 @@ class RotateElementsCommand : public QUndoCommand {
|
||||
This command directs several text items to a same particular angle of
|
||||
rotation.
|
||||
*/
|
||||
class RotateTextsCommand : public QUndoCommand {
|
||||
class RotateTextsCommand : public QUndoCommand
|
||||
{
|
||||
// constructors, destructor
|
||||
public:
|
||||
RotateTextsCommand(const QHash<DiagramTextItem *, double> &, double, QUndoCommand * = 0);
|
||||
RotateTextsCommand(const QList<DiagramTextItem *> &, double, QUndoCommand * = 0);
|
||||
virtual ~RotateTextsCommand();
|
||||
RotateTextsCommand(const QList<DiagramTextItem *> &, double, QUndoCommand * = nullptr);
|
||||
virtual ~RotateTextsCommand() override;
|
||||
private:
|
||||
RotateTextsCommand(const RotateTextsCommand &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
private:
|
||||
void defineCommandName();
|
||||
@ -295,12 +270,12 @@ class RotateTextsCommand : public QUndoCommand {
|
||||
// attributes
|
||||
private:
|
||||
/// hold rotated text items along with their former angle of rotation
|
||||
QHash<DiagramTextItem *, double> texts_to_rotate;
|
||||
QHash<DiagramTextItem *, double> m_texts_to_rotate;
|
||||
/// angle of rotation of all text items after the command
|
||||
double applied_rotation_angle_;
|
||||
double m_applied_rotation_angle;
|
||||
/// previous state of each conductor text item
|
||||
QHash<ConductorTextItem *, bool> previous_rotate_by_user_;
|
||||
Diagram *diagram;
|
||||
QHash<ConductorTextItem *, bool> m_previous_rotate_by_user;
|
||||
Diagram *m_diagram;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -23,61 +23,67 @@
|
||||
#include "diagramimageitem.h"
|
||||
#include "elementtextitem.h"
|
||||
#include "qetshapeitem.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
|
||||
/**
|
||||
Constructeur par defaut. Ne contient rien.
|
||||
*/
|
||||
DiagramContent::DiagramContent() {
|
||||
}
|
||||
* @brief DiagramContent::DiagramContent
|
||||
*/
|
||||
DiagramContent::DiagramContent() {}
|
||||
|
||||
/**
|
||||
Constructeur de copie.
|
||||
*/
|
||||
* @brief DiagramContent::DiagramContent
|
||||
* Copy constructor
|
||||
* @param other
|
||||
*/
|
||||
DiagramContent::DiagramContent(const DiagramContent &other) :
|
||||
elements(other.elements),
|
||||
textFields(other.textFields),
|
||||
images(other.images),
|
||||
shapes(other.shapes),
|
||||
conductorsToUpdate(other.conductorsToUpdate),
|
||||
conductorsToMove(other.conductorsToMove),
|
||||
otherConductors(other.otherConductors)
|
||||
m_elements(other.m_elements),
|
||||
m_text_fields(other.m_text_fields),
|
||||
m_images(other.m_images),
|
||||
m_shapes(other.m_shapes),
|
||||
m_conductors_to_update(other.m_conductors_to_update),
|
||||
m_conductors_to_move(other.m_conductors_to_move),
|
||||
m_other_conductors(other.m_other_conductors),
|
||||
m_element_texts(other.m_element_texts)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief DiagramContent::~DiagramContent
|
||||
*/
|
||||
DiagramContent::~DiagramContent() {}
|
||||
|
||||
/**
|
||||
* @brief DiagramContent::conductors
|
||||
* @param filter
|
||||
* @return Every conductors according to the filter
|
||||
*/
|
||||
QList<Conductor *> DiagramContent::conductors(int filter) const
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
*/
|
||||
DiagramContent::~DiagramContent() {
|
||||
}
|
||||
|
||||
/**
|
||||
@param filter Types de conducteurs desires
|
||||
@return tous les conducteurs
|
||||
*/
|
||||
QList<Conductor *> DiagramContent::conductors(int filter) const {
|
||||
QSet<Conductor *> result;
|
||||
if (filter & ConductorsToMove) result += conductorsToMove;
|
||||
if (filter & ConductorsToUpdate) result += conductorsToUpdate;
|
||||
if (filter & OtherConductors) result += otherConductors;
|
||||
if (filter & ConductorsToMove) result += m_conductors_to_move;
|
||||
if (filter & ConductorsToUpdate) result += m_conductors_to_update;
|
||||
if (filter & OtherConductors) result += m_other_conductors;
|
||||
if (filter & SelectedOnly) {
|
||||
foreach(Conductor *conductor, result) {
|
||||
if (!conductor -> isSelected()) result.remove(conductor);
|
||||
for(Conductor *conductor : result) {
|
||||
if (!conductor->isSelected()) result.remove(conductor);
|
||||
}
|
||||
}
|
||||
return(result.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
Vide le conteneur
|
||||
*/
|
||||
void DiagramContent::clear() {
|
||||
elements.clear();
|
||||
textFields.clear();
|
||||
images.clear();
|
||||
shapes.clear();
|
||||
conductorsToUpdate.clear();
|
||||
conductorsToMove.clear();
|
||||
otherConductors.clear();
|
||||
* @brief DiagramContent::clear
|
||||
* Remove all items from the diagram content
|
||||
*/
|
||||
void DiagramContent::clear()
|
||||
{
|
||||
m_elements.clear();
|
||||
m_text_fields.clear();
|
||||
m_images.clear();
|
||||
m_shapes.clear();
|
||||
m_conductors_to_update.clear();
|
||||
m_conductors_to_move.clear();
|
||||
m_other_conductors.clear();
|
||||
m_element_texts.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,42 +95,47 @@ int DiagramContent::removeNonMovableItems()
|
||||
{
|
||||
int count_ = 0;
|
||||
|
||||
foreach(Element *elmt, elements) {
|
||||
for(Element *elmt : m_elements) {
|
||||
if (!elmt->isMovable()) {
|
||||
elements.remove(elmt);
|
||||
m_elements.remove(elmt);
|
||||
++count_;
|
||||
}
|
||||
}
|
||||
foreach(DiagramImageItem *img, images) {
|
||||
for(DiagramImageItem *img : m_images) {
|
||||
if (!img->isMovable()) {
|
||||
images.remove(img);
|
||||
m_images.remove(img);
|
||||
++count_;
|
||||
}
|
||||
}
|
||||
foreach (QetShapeItem *shape, shapes) {
|
||||
for(QetShapeItem *shape : m_shapes) {
|
||||
if (!shape->isMovable()) {
|
||||
shapes.remove(shape);
|
||||
m_shapes.remove(shape);
|
||||
++count_;
|
||||
}
|
||||
}
|
||||
|
||||
return count_;
|
||||
}
|
||||
/**
|
||||
@param filter Types desires
|
||||
@return la liste des items formant le contenu du schema
|
||||
*/
|
||||
QList<QGraphicsItem *> DiagramContent::items(int filter) const {
|
||||
QList<QGraphicsItem *> items_list;
|
||||
foreach(QGraphicsItem *qgi, conductors(filter)) items_list << qgi;
|
||||
|
||||
if (filter & Elements) foreach(QGraphicsItem *qgi, elements) items_list << qgi;
|
||||
if (filter & TextFields) foreach(QGraphicsItem *qgi, textFields) items_list << qgi;
|
||||
if (filter & Images) foreach(QGraphicsItem *qgi, images) items_list << qgi;
|
||||
if (filter & Shapes) foreach(QGraphicsItem *qgi, shapes) items_list << qgi;
|
||||
/**
|
||||
* @brief DiagramContent::items
|
||||
* @param filter
|
||||
* @return The items of this diagram content according to @filter
|
||||
*/
|
||||
QList<QGraphicsItem *> DiagramContent::items(int filter) const
|
||||
{
|
||||
QList<QGraphicsItem *> items_list;
|
||||
|
||||
for(QGraphicsItem *qgi : conductors(filter)) items_list << qgi;
|
||||
|
||||
if (filter & Elements) for(QGraphicsItem *qgi : m_elements) items_list << qgi;
|
||||
if (filter & TextFields) for(QGraphicsItem *qgi : m_text_fields) items_list << qgi;
|
||||
if (filter & Images) for(QGraphicsItem *qgi : m_images) items_list << qgi;
|
||||
if (filter & Shapes) for(QGraphicsItem *qgi : m_shapes) items_list << qgi;
|
||||
if (filter & ElementTextFields) for(QGraphicsItem *qgi : m_element_texts) items_list << qgi;
|
||||
|
||||
if (filter & SelectedOnly) {
|
||||
foreach(QGraphicsItem *qgi, items_list) {
|
||||
for(QGraphicsItem *qgi : items_list) {
|
||||
if (!qgi -> isSelected()) items_list.removeOne(qgi);
|
||||
}
|
||||
}
|
||||
@ -132,44 +143,50 @@ QList<QGraphicsItem *> DiagramContent::items(int filter) const {
|
||||
}
|
||||
|
||||
/**
|
||||
@param filter Types desires
|
||||
@return le nombre d'items formant le contenu du schema
|
||||
*/
|
||||
int DiagramContent::count(int filter) const {
|
||||
* @brief DiagramContent::count
|
||||
* @param filter
|
||||
* @return The number of items, according to @filter
|
||||
*/
|
||||
int DiagramContent::count(int filter) const
|
||||
{
|
||||
int count = 0;
|
||||
if (filter & SelectedOnly) {
|
||||
if (filter & Elements) foreach(Element *element, elements) { if (element -> isSelected()) ++ count; }
|
||||
if (filter & TextFields) foreach(DiagramTextItem *dti, textFields) { if (dti -> isSelected()) ++ count; }
|
||||
if (filter & Images) foreach(DiagramImageItem *dii, images) { if (dii -> isSelected()) ++ count; }
|
||||
if (filter & Shapes) foreach(QetShapeItem *dsi, shapes) { if (dsi -> isSelected()) ++ count; }
|
||||
if (filter & ConductorsToMove) foreach(Conductor *conductor, conductorsToMove) { if (conductor -> isSelected()) ++ count; }
|
||||
if (filter & ConductorsToUpdate) foreach(Conductor *conductor, conductorsToUpdate) { if (conductor -> isSelected()) ++ count; }
|
||||
if (filter & OtherConductors) foreach(Conductor *conductor, otherConductors) { if (conductor -> isSelected()) ++ count; }
|
||||
if (filter & Elements) for(Element *element : m_elements) { if (element -> isSelected()) ++ count; }
|
||||
if (filter & TextFields) for(DiagramTextItem *dti : m_text_fields) { if (dti -> isSelected()) ++ count; }
|
||||
if (filter & Images) for(DiagramImageItem *dii : m_images) { if (dii -> isSelected()) ++ count; }
|
||||
if (filter & Shapes) for(QetShapeItem *dsi : m_shapes) { if (dsi -> isSelected()) ++ count; }
|
||||
if (filter & ConductorsToMove) for(Conductor *conductor : m_conductors_to_move) { if (conductor -> isSelected()) ++ count; }
|
||||
if (filter & ConductorsToUpdate) for(Conductor *conductor : m_conductors_to_update) { if (conductor -> isSelected()) ++ count; }
|
||||
if (filter & OtherConductors) for(Conductor *conductor : m_other_conductors) { if (conductor -> isSelected()) ++ count; }
|
||||
if (filter & ElementTextFields) for(DynamicElementTextItem *deti : m_element_texts) { if (deti -> isSelected()) ++ count; }
|
||||
}
|
||||
else {
|
||||
if (filter & Elements) count += elements.count();
|
||||
if (filter & TextFields) count += textFields.count();
|
||||
if (filter & Images) count += images.count();
|
||||
if (filter & Shapes) count += shapes.count();
|
||||
if (filter & ConductorsToMove) count += conductorsToMove.count();
|
||||
if (filter & ConductorsToUpdate) count += conductorsToUpdate.count();
|
||||
if (filter & OtherConductors) count += otherConductors.count();
|
||||
if (filter & Elements) count += m_elements.count();
|
||||
if (filter & TextFields) count += m_text_fields.count();
|
||||
if (filter & Images) count += m_images.count();
|
||||
if (filter & Shapes) count += m_shapes.count();
|
||||
if (filter & ConductorsToMove) count += m_conductors_to_move.count();
|
||||
if (filter & ConductorsToUpdate) count += m_conductors_to_update.count();
|
||||
if (filter & OtherConductors) count += m_other_conductors.count();
|
||||
if (filter & ElementTextFields) count += m_element_texts.count();
|
||||
}
|
||||
return(count);
|
||||
}
|
||||
|
||||
/**
|
||||
Permet de composer rapidement la proposition "x elements, y conducteurs et
|
||||
z champs de texte".
|
||||
@param filter Types desires
|
||||
@return la proposition decrivant le contenu.
|
||||
*/
|
||||
QString DiagramContent::sentence(int filter) const {
|
||||
int elements_count = (filter & Elements) ? elements.count() : 0;
|
||||
* @brief DiagramContent::sentence
|
||||
* @param filter
|
||||
* @return A string that describe the items of the diagram content according to @filter.
|
||||
* Exemple : X elements, Y conductors etc....
|
||||
*/
|
||||
QString DiagramContent::sentence(int filter) const
|
||||
{
|
||||
int elements_count = (filter & Elements) ? m_elements.count() : 0;
|
||||
int conductors_count = conductors(filter).count();
|
||||
int textfields_count = (filter & TextFields) ? (textFields.count()) : 0;
|
||||
int images_count = (filter & Images) ? images.count() : 0;
|
||||
int shapes_count = (filter & Shapes) ? shapes.count() : 0;
|
||||
int textfields_count = (filter & TextFields) ? (m_text_fields.count()) : 0;
|
||||
int images_count = (filter & Images) ? m_images.count() : 0;
|
||||
int shapes_count = (filter & Shapes) ? m_shapes.count() : 0;
|
||||
int elmt_text_count = (filter & ElementTextFields) ? m_element_texts.count() : 0;
|
||||
|
||||
return(
|
||||
QET::ElementsAndConductorsSentence(
|
||||
@ -177,16 +194,18 @@ QString DiagramContent::sentence(int filter) const {
|
||||
conductors_count,
|
||||
textfields_count,
|
||||
images_count,
|
||||
shapes_count
|
||||
shapes_count,
|
||||
elmt_text_count
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Permet de debugger un contenu de schema
|
||||
@param d Object QDebug a utiliser pour l'affichage des informations de debug
|
||||
@param content Contenu de schema a debugger
|
||||
*/
|
||||
* @brief operator << Use to debug a diagram content
|
||||
* @param d : QDebug to use for display the debug info
|
||||
* @param content : content to debug
|
||||
* @return
|
||||
*/
|
||||
QDebug &operator<<(QDebug d, DiagramContent &content) {
|
||||
Q_UNUSED(content);
|
||||
d << "DiagramContent {" << "\n";
|
||||
|
@ -27,6 +27,7 @@ class IndependentTextItem;
|
||||
class DiagramImageItem;
|
||||
class ElementTextItem;
|
||||
class QetShapeItem;
|
||||
class DynamicElementTextItem;
|
||||
|
||||
/**
|
||||
This class provides a container that makes the transmission of diagram content
|
||||
@ -37,7 +38,8 @@ class QetShapeItem;
|
||||
Please note this container does not systematically contains a whole
|
||||
diagram: it may describe only a part of it, e.g. selected items.
|
||||
*/
|
||||
class DiagramContent {
|
||||
class DiagramContent
|
||||
{
|
||||
public:
|
||||
DiagramContent();
|
||||
DiagramContent(const DiagramContent &);
|
||||
@ -58,20 +60,14 @@ class DiagramContent {
|
||||
SelectedOnly = 256
|
||||
};
|
||||
|
||||
/// Hold electrical elements
|
||||
QSet<Element *> elements;
|
||||
/// Hold independent text items
|
||||
QSet<IndependentTextItem *> textFields;
|
||||
/// Hold image
|
||||
QSet<DiagramImageItem *> images;
|
||||
/// Hold shape
|
||||
QSet<QetShapeItem *> shapes;
|
||||
/// Hold conductors that would get updated considering electrical elements are moved
|
||||
QSet<Conductor *> conductorsToUpdate;
|
||||
/// Hold conductors that would be moved as is considering electrical elements are moved
|
||||
QSet<Conductor *> conductorsToMove;
|
||||
/// Hold conductors that would be left untouched considering electrical elements are moved
|
||||
QSet<Conductor *> otherConductors;
|
||||
QSet<Element *> m_elements;
|
||||
QSet<IndependentTextItem *> m_text_fields;
|
||||
QSet<DiagramImageItem *> m_images;
|
||||
QSet<QetShapeItem *> m_shapes;
|
||||
QSet<Conductor *> m_conductors_to_update;
|
||||
QSet<Conductor *> m_conductors_to_move;
|
||||
QSet<Conductor *> m_other_conductors;
|
||||
QSet<DynamicElementTextItem *> m_element_texts;
|
||||
|
||||
QList<Conductor *> conductors(int = AnyConductor) const;
|
||||
QList<QGraphicsItem *> items(int = All) const;
|
||||
|
@ -45,6 +45,8 @@
|
||||
#include "diagrameventaddelement.h"
|
||||
#include "QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
#include "qetshapeitem.h"
|
||||
#include "undocommand/deleteqgraphicsitemcommand.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@ -53,9 +55,7 @@
|
||||
*/
|
||||
DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
|
||||
QGraphicsView (parent),
|
||||
m_scene (diagram),
|
||||
m_event_interface (nullptr),
|
||||
m_first_activation (true)
|
||||
m_diagram (diagram)
|
||||
{
|
||||
grabGesture(Qt::PinchGesture);
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
@ -74,8 +74,8 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
|
||||
setRenderHint(QPainter::TextAntialiasing, true);
|
||||
setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||
|
||||
setScene(m_scene);
|
||||
m_scene -> undoStack().setClean();
|
||||
setScene(m_diagram);
|
||||
m_diagram -> undoStack().setClean();
|
||||
setWindowIcon(QET::Icons::QETLogo);
|
||||
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
@ -83,17 +83,17 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
|
||||
setSelectionMode();
|
||||
adjustSceneRect();
|
||||
updateWindowTitle();
|
||||
m_scene->loadElmtFolioSeq();
|
||||
m_scene->loadCndFolioSeq();
|
||||
m_diagram->loadElmtFolioSeq();
|
||||
m_diagram->loadCndFolioSeq();
|
||||
|
||||
context_menu = new QMenu(this);
|
||||
paste_here = new QAction(QET::Icons::EditPaste, tr("Coller ici", "context menu action"), this);
|
||||
connect(paste_here, SIGNAL(triggered()), this, SLOT(pasteHere()));
|
||||
m_context_menu = new QMenu(this);
|
||||
m_paste_here = new QAction(QET::Icons::EditPaste, tr("Coller ici", "context menu action"), this);
|
||||
connect(m_paste_here, SIGNAL(triggered()), this, SLOT(pasteHere()));
|
||||
|
||||
connect(m_scene, SIGNAL(showDiagram(Diagram*)), this, SIGNAL(showDiagram(Diagram*)));
|
||||
connect(m_scene, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
|
||||
connect(m_scene, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustSceneRect()));
|
||||
connect(&(m_scene -> border_and_titleblock), SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(updateWindowTitle()));
|
||||
connect(m_diagram, SIGNAL(showDiagram(Diagram*)), this, SIGNAL(showDiagram(Diagram*)));
|
||||
connect(m_diagram, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
|
||||
connect(m_diagram, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustSceneRect()));
|
||||
connect(&(m_diagram -> border_and_titleblock), SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(updateWindowTitle()));
|
||||
connect(diagram, SIGNAL(editElementRequired(ElementsLocation)), this, SIGNAL(editElementRequired(ElementsLocation)));
|
||||
connect(diagram, SIGNAL(findElementRequired(ElementsLocation)), this, SIGNAL(findElementRequired(ElementsLocation)));
|
||||
|
||||
@ -111,93 +111,113 @@ DiagramView::~DiagramView() {
|
||||
Selectionne tous les objets du schema
|
||||
*/
|
||||
void DiagramView::selectAll() {
|
||||
m_scene -> selectAll();
|
||||
m_diagram -> selectAll();
|
||||
}
|
||||
|
||||
/**
|
||||
Deslectionne tous les objets selectionnes
|
||||
*/
|
||||
void DiagramView::selectNothing() {
|
||||
m_scene -> deselectAll();
|
||||
m_diagram -> deselectAll();
|
||||
}
|
||||
|
||||
/**
|
||||
Inverse l'etat de selection de tous les objets du schema
|
||||
*/
|
||||
void DiagramView::selectInvert() {
|
||||
m_scene -> invertSelection();
|
||||
m_diagram -> invertSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
Supprime les composants selectionnes
|
||||
*/
|
||||
void DiagramView::deleteSelection() {
|
||||
if (m_scene -> isReadOnly()) return;
|
||||
DiagramContent removed_content = m_scene -> selectedContent();
|
||||
m_scene -> clearSelection();
|
||||
m_scene -> undoStack().push(new DeleteElementsCommand(m_scene, removed_content));
|
||||
* @brief DiagramView::deleteSelection
|
||||
* Delete the selected items
|
||||
*/
|
||||
void DiagramView::deleteSelection()
|
||||
{
|
||||
if (m_diagram -> isReadOnly())
|
||||
return;
|
||||
DiagramContent removed_content = m_diagram->selectedContent();
|
||||
m_diagram->clearSelection();
|
||||
m_diagram->undoStack().push(new DeleteQGraphicsItemCommand(m_diagram, removed_content));
|
||||
adjustSceneRect();
|
||||
}
|
||||
|
||||
/**
|
||||
Pivote les composants selectionnes
|
||||
*/
|
||||
void DiagramView::rotateSelection() {
|
||||
if (m_scene -> isReadOnly()) return;
|
||||
* @brief DiagramView::rotateSelection
|
||||
* Rotate the selected items
|
||||
*/
|
||||
void DiagramView::rotateSelection()
|
||||
{
|
||||
if (m_diagram->isReadOnly())
|
||||
return;
|
||||
|
||||
// recupere les elements et les champs de texte a pivoter
|
||||
QList<Element *> elements_to_rotate;
|
||||
QList<DiagramTextItem *> texts_to_rotate;
|
||||
QList<DiagramImageItem *> images_to_rotate;
|
||||
foreach (QGraphicsItem *item, m_scene -> selectedItems()) {
|
||||
if (Element *e = qgraphicsitem_cast<Element *>(item)) {
|
||||
|
||||
for (QGraphicsItem *item : m_diagram->selectedItems())
|
||||
{
|
||||
if (Element *e = qgraphicsitem_cast<Element *>(item))
|
||||
elements_to_rotate << e;
|
||||
} else if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
|
||||
else if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
|
||||
texts_to_rotate << cti;
|
||||
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
|
||||
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
|
||||
texts_to_rotate << iti;
|
||||
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
|
||||
// on ne pivote un texte d'element que si son parent n'est pas selectionne
|
||||
if (eti -> parentItem() && !eti -> parentItem() -> isSelected()) {
|
||||
else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
|
||||
{
|
||||
//We rotate element text item only if is parent element is not selected
|
||||
if (eti->parentItem() && !eti->parentItem()->isSelected())
|
||||
texts_to_rotate << eti;
|
||||
}
|
||||
} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item)) {
|
||||
else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
|
||||
{
|
||||
//We rotate dynamic element text item only if is parent element is not selected
|
||||
if (deti->parentItem() && !deti->parentItem()->isSelected())
|
||||
texts_to_rotate << deti;
|
||||
}
|
||||
else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item))
|
||||
images_to_rotate << dii;
|
||||
}
|
||||
}
|
||||
|
||||
// effectue les rotations s'il y a quelque chose a pivoter
|
||||
if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty()) return;
|
||||
m_scene -> undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate));
|
||||
//Do the rotation
|
||||
if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty())
|
||||
return;
|
||||
m_diagram->undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate));
|
||||
}
|
||||
|
||||
void DiagramView::rotateTexts() {
|
||||
if (m_scene -> isReadOnly()) return;
|
||||
/**
|
||||
* @brief DiagramView::rotateTexts
|
||||
* Open a dialog to set the rotation angle, and apply it to the selected texts.
|
||||
*/
|
||||
void DiagramView::rotateTexts()
|
||||
{
|
||||
if (m_diagram->isReadOnly())
|
||||
return;
|
||||
|
||||
// recupere les champs de texte a orienter
|
||||
//Get the texts fields
|
||||
QList<DiagramTextItem *> texts_to_rotate;
|
||||
foreach (QGraphicsItem *item, m_scene -> selectedItems()) {
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
|
||||
for (QGraphicsItem *item : m_diagram->selectedItems())
|
||||
{
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
|
||||
texts_to_rotate << cti;
|
||||
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
|
||||
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
|
||||
texts_to_rotate << iti;
|
||||
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
|
||||
// ici, on pivote un texte d'element meme si son parent est selectionne
|
||||
else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
|
||||
texts_to_rotate << eti;
|
||||
}
|
||||
else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
|
||||
texts_to_rotate << deti;
|
||||
}
|
||||
|
||||
// effectue les rotations s'il y a quelque chose a pivoter
|
||||
if (texts_to_rotate.isEmpty()) return;
|
||||
if (texts_to_rotate.isEmpty())
|
||||
return;
|
||||
|
||||
// demande un angle a l'utilisateur
|
||||
//Open the dialog
|
||||
QDialog ori_text_dialog(diagramEditor());
|
||||
ori_text_dialog.setSizeGripEnabled(false);
|
||||
#ifdef Q_OS_MAC
|
||||
ori_text_dialog.setWindowFlags(Qt::Sheet);
|
||||
#endif
|
||||
ori_text_dialog.setWindowTitle(tr("Orienter les textes sélectionnés", "window title"));
|
||||
// ori_text_dialog.setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
||||
|
||||
QTextOrientationSpinBoxWidget *ori_widget = QETApp::createTextOrientationSpinBoxWidget();
|
||||
@ -207,22 +227,18 @@ void DiagramView::rotateTexts() {
|
||||
}
|
||||
ori_widget -> spinBox() -> selectAll();
|
||||
|
||||
// boutons
|
||||
QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(&buttons, SIGNAL(accepted()), &ori_text_dialog, SLOT(accept()));
|
||||
connect(&buttons, SIGNAL(rejected()), &ori_text_dialog, SLOT(reject()));
|
||||
|
||||
// ajout dans une disposition verticale
|
||||
QVBoxLayout layout_v(&ori_text_dialog);
|
||||
layout_v.setSizeConstraint(QLayout::SetFixedSize);
|
||||
layout_v.addWidget(ori_widget);
|
||||
layout_v.addStretch();
|
||||
layout_v.addWidget(&buttons);
|
||||
|
||||
// si le dialogue est accepte
|
||||
if (ori_text_dialog.exec() == QDialog::Accepted) {
|
||||
m_scene -> undoStack().push(new RotateTextsCommand(texts_to_rotate, ori_widget -> orientation()));
|
||||
}
|
||||
if (ori_text_dialog.exec() == QDialog::Accepted)
|
||||
m_diagram -> undoStack().push(new RotateTextsCommand(texts_to_rotate, ori_widget -> orientation()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -307,11 +323,11 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
|
||||
if (tbt_loc.isValid())
|
||||
{
|
||||
// fetch the current title block properties
|
||||
TitleBlockProperties titleblock_properties_before = m_scene->border_and_titleblock.exportTitleBlock();
|
||||
TitleBlockProperties titleblock_properties_before = m_diagram->border_and_titleblock.exportTitleBlock();
|
||||
|
||||
// check the provided template is not already applied
|
||||
QETProject *tbt_parent_project = tbt_loc.parentProject();
|
||||
if (tbt_parent_project && tbt_parent_project == m_scene -> project())
|
||||
if (tbt_parent_project && tbt_parent_project == m_diagram -> project())
|
||||
{
|
||||
// same parent project and same name = same title block template
|
||||
if (tbt_loc.name() == titleblock_properties_before.template_name)
|
||||
@ -324,7 +340,7 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
|
||||
{
|
||||
IntegrationMoveTitleBlockTemplatesHandler *handler = new IntegrationMoveTitleBlockTemplatesHandler(this);
|
||||
//QString error_message;
|
||||
integrated_template_name = m_scene->project()->integrateTitleBlockTemplate(tbt_loc, handler);
|
||||
integrated_template_name = m_diagram->project()->integrateTitleBlockTemplate(tbt_loc, handler);
|
||||
|
||||
if (integrated_template_name.isEmpty())
|
||||
return;
|
||||
@ -336,7 +352,7 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
|
||||
|
||||
TitleBlockProperties titleblock_properties_after = titleblock_properties_before;
|
||||
titleblock_properties_after.template_name = integrated_template_name;
|
||||
m_scene->undoStack().push(new ChangeTitleBlockCommand(m_scene, titleblock_properties_before, titleblock_properties_after));
|
||||
m_diagram->undoStack().push(new ChangeTitleBlockCommand(m_diagram, titleblock_properties_before, titleblock_properties_after));
|
||||
|
||||
adjustSceneRect();
|
||||
}
|
||||
@ -348,7 +364,7 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
|
||||
* @param e the QDropEvent describing the current drag'n drop
|
||||
*/
|
||||
void DiagramView::handleTextDrop(QDropEvent *e) {
|
||||
if (m_scene -> isReadOnly() || (e -> mimeData() -> hasText() == false) ) return;
|
||||
if (m_diagram -> isReadOnly() || (e -> mimeData() -> hasText() == false) ) return;
|
||||
|
||||
IndependentTextItem *iti = new IndependentTextItem (e -> mimeData() -> text());
|
||||
|
||||
@ -356,7 +372,7 @@ void DiagramView::handleTextDrop(QDropEvent *e) {
|
||||
iti -> setHtml (e -> mimeData() -> text());
|
||||
}
|
||||
|
||||
m_scene -> undoStack().push(new AddItemCommand<IndependentTextItem *>(iti, m_scene, mapToScene(e->pos())));
|
||||
m_diagram -> undoStack().push(new AddItemCommand<IndependentTextItem *>(iti, m_diagram, mapToScene(e->pos())));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -398,9 +414,8 @@ void DiagramView::zoom(const qreal zoom_factor)
|
||||
(horizontalScrollBar()->maximum() || verticalScrollBar()->maximum()) )
|
||||
scale(zoom_factor, zoom_factor);
|
||||
}
|
||||
m_scene->adjustSceneRect();
|
||||
m_diagram->adjustSceneRect();
|
||||
adjustGridToZoom();
|
||||
adjustSceneRect();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -410,7 +425,7 @@ void DiagramView::zoom(const qreal zoom_factor)
|
||||
*/
|
||||
void DiagramView::zoomFit() {
|
||||
adjustSceneRect();
|
||||
fitInView(m_scene->sceneRect(), Qt::KeepAspectRatio);
|
||||
fitInView(m_diagram->sceneRect(), Qt::KeepAspectRatio);
|
||||
adjustGridToZoom();
|
||||
}
|
||||
|
||||
@ -418,7 +433,7 @@ void DiagramView::zoomFit() {
|
||||
Adjust zoom to fit all elements in the view, regardless of diagram borders.
|
||||
*/
|
||||
void DiagramView::zoomContent() {
|
||||
fitInView(m_scene -> itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
fitInView(m_diagram -> itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
adjustGridToZoom();
|
||||
}
|
||||
|
||||
@ -435,9 +450,9 @@ void DiagramView::zoomReset() {
|
||||
*/
|
||||
void DiagramView::cut() {
|
||||
copy();
|
||||
DiagramContent cut_content = m_scene -> selectedContent();
|
||||
m_scene -> clearSelection();
|
||||
m_scene -> undoStack().push(new CutDiagramCommand(m_scene, cut_content));
|
||||
DiagramContent cut_content = m_diagram -> selectedContent();
|
||||
m_diagram -> clearSelection();
|
||||
m_diagram -> undoStack().push(new CutDiagramCommand(m_diagram, cut_content));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -445,7 +460,7 @@ void DiagramView::cut() {
|
||||
*/
|
||||
void DiagramView::copy() {
|
||||
QClipboard *presse_papier = QApplication::clipboard();
|
||||
QString contenu_presse_papier = m_scene -> toXml(false).toString(4);
|
||||
QString contenu_presse_papier = m_diagram -> toXml(false).toString(4);
|
||||
if (presse_papier -> supportsSelection()) presse_papier -> setText(contenu_presse_papier, QClipboard::Selection);
|
||||
presse_papier -> setText(contenu_presse_papier);
|
||||
}
|
||||
@ -457,7 +472,7 @@ void DiagramView::copy() {
|
||||
@param clipboard_mode Type de presse-papier a prendre en compte
|
||||
*/
|
||||
void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) {
|
||||
if (!isInteractive() || m_scene -> isReadOnly()) return;
|
||||
if (!isInteractive() || m_diagram -> isReadOnly()) return;
|
||||
|
||||
QString texte_presse_papier = QApplication::clipboard() -> text(clipboard_mode);
|
||||
if ((texte_presse_papier).isEmpty()) return;
|
||||
@ -468,12 +483,12 @@ void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) {
|
||||
// objet pour recuperer le contenu ajoute au schema par le coller
|
||||
DiagramContent content_pasted;
|
||||
this->diagram()->item_paste = true;
|
||||
m_scene -> fromXml(document_xml, pos, false, &content_pasted);
|
||||
m_diagram -> fromXml(document_xml, pos, false, &content_pasted);
|
||||
|
||||
// si quelque chose a effectivement ete ajoute au schema, on cree un objet d'annulation
|
||||
if (content_pasted.count()) {
|
||||
m_scene -> clearSelection();
|
||||
m_scene -> undoStack().push(new PasteDiagramCommand(m_scene, content_pasted));
|
||||
m_diagram -> clearSelection();
|
||||
m_diagram -> undoStack().push(new PasteDiagramCommand(m_diagram, content_pasted));
|
||||
adjustSceneRect();
|
||||
}
|
||||
this->diagram()->item_paste = false;
|
||||
@ -483,7 +498,7 @@ void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) {
|
||||
Colle le contenu du presse-papier sur le schema a la position de la souris
|
||||
*/
|
||||
void DiagramView::pasteHere() {
|
||||
paste(mapToScene(paste_here_pos));
|
||||
paste(mapToScene(m_paste_here_pos));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -492,10 +507,10 @@ void DiagramView::pasteHere() {
|
||||
*/
|
||||
void DiagramView::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
if (fresh_focus_in_)
|
||||
if (m_fresh_focus_in)
|
||||
{
|
||||
switchToVisualisationModeIfNeeded(e);
|
||||
fresh_focus_in_ = false;
|
||||
m_fresh_focus_in = false;
|
||||
}
|
||||
|
||||
if (m_event_interface && m_event_interface->mousePressEvent(e)) return;
|
||||
@ -503,7 +518,7 @@ void DiagramView::mousePressEvent(QMouseEvent *e)
|
||||
//Start drag view when hold the middle button
|
||||
if (e->button() == Qt::MidButton)
|
||||
{
|
||||
rubber_band_origin = e->pos();
|
||||
m_rubber_band_origin = e->pos();
|
||||
viewport()->setCursor(Qt::ClosedHandCursor);
|
||||
}
|
||||
|
||||
@ -523,11 +538,10 @@ void DiagramView::mouseMoveEvent(QMouseEvent *e)
|
||||
{
|
||||
QScrollBar *h = horizontalScrollBar();
|
||||
QScrollBar *v = verticalScrollBar();
|
||||
QPointF pos = rubber_band_origin - e -> pos();
|
||||
rubber_band_origin = e -> pos();
|
||||
QPointF pos = m_rubber_band_origin - e -> pos();
|
||||
m_rubber_band_origin = e -> pos();
|
||||
h -> setValue(h -> value() + pos.x());
|
||||
v -> setValue(v -> value() + pos.y());
|
||||
adjustSceneRect();
|
||||
}
|
||||
|
||||
else QGraphicsView::mouseMoveEvent(e);
|
||||
@ -619,7 +633,7 @@ bool DiagramView::gestureEvent(QGestureEvent *event)
|
||||
*/
|
||||
void DiagramView::focusInEvent(QFocusEvent *e) {
|
||||
if (e -> reason() == Qt::MouseFocusReason) {
|
||||
fresh_focus_in_ = true;
|
||||
m_fresh_focus_in = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -641,10 +655,10 @@ switch(e -> key())
|
||||
case Qt::Key_Home:
|
||||
if (!hasTextItems()) {
|
||||
if (
|
||||
qgraphicsitem_cast<IndependentTextItem *>(m_scene->focusItem()) ||
|
||||
qgraphicsitem_cast<ElementTextItem *>(m_scene->focusItem()) ||
|
||||
qgraphicsitem_cast<ConductorTextItem *>(m_scene->focusItem()) ||
|
||||
qgraphicsitem_cast<DiagramTextItem *>(m_scene->focusItem())
|
||||
qgraphicsitem_cast<IndependentTextItem *>(m_diagram->focusItem()) ||
|
||||
qgraphicsitem_cast<ElementTextItem *>(m_diagram->focusItem()) ||
|
||||
qgraphicsitem_cast<ConductorTextItem *>(m_diagram->focusItem()) ||
|
||||
qgraphicsitem_cast<DiagramTextItem *>(m_diagram->focusItem())
|
||||
)
|
||||
break;
|
||||
current_project->changeFirstTab();
|
||||
@ -654,10 +668,10 @@ switch(e -> key())
|
||||
case Qt::Key_End:
|
||||
if (!hasTextItems()) {
|
||||
if (
|
||||
qgraphicsitem_cast<IndependentTextItem *>(m_scene->focusItem()) ||
|
||||
qgraphicsitem_cast<ElementTextItem *>(m_scene->focusItem()) ||
|
||||
qgraphicsitem_cast<ConductorTextItem *>(m_scene->focusItem()) ||
|
||||
qgraphicsitem_cast<DiagramTextItem *>(m_scene->focusItem())
|
||||
qgraphicsitem_cast<IndependentTextItem *>(m_diagram->focusItem()) ||
|
||||
qgraphicsitem_cast<ElementTextItem *>(m_diagram->focusItem()) ||
|
||||
qgraphicsitem_cast<ConductorTextItem *>(m_diagram->focusItem()) ||
|
||||
qgraphicsitem_cast<DiagramTextItem *>(m_diagram->focusItem())
|
||||
)
|
||||
break;
|
||||
current_project->changeLastTab();
|
||||
@ -677,19 +691,19 @@ switch(e -> key())
|
||||
if (e->modifiers() & Qt::ControlModifier)
|
||||
zoom(1.15);
|
||||
case Qt::Key_Up:
|
||||
if(!(m_scene->selectedContent().items(255).isEmpty())){
|
||||
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
|
||||
scrollOnMovement(e);
|
||||
}
|
||||
case Qt::Key_Down:
|
||||
if(!(m_scene->selectedContent().items(255).isEmpty())){
|
||||
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
|
||||
scrollOnMovement(e);
|
||||
}
|
||||
case Qt::Key_Left:
|
||||
if(!(m_scene->selectedContent().items(255).isEmpty())){
|
||||
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
|
||||
scrollOnMovement(e);
|
||||
}
|
||||
case Qt::Key_Right:
|
||||
if(!(m_scene->selectedContent().items(255).isEmpty())){
|
||||
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
|
||||
scrollOnMovement(e);
|
||||
}
|
||||
}
|
||||
@ -714,7 +728,7 @@ void DiagramView::keyReleaseEvent(QKeyEvent *e) {
|
||||
or below the editor SceneRect is expanded
|
||||
*/
|
||||
void DiagramView::scrollOnMovement(QKeyEvent *e){
|
||||
QList<QGraphicsItem *> selected_elmts = m_scene->selectedContent().items(255);
|
||||
QList<QGraphicsItem *> selected_elmts = m_diagram->selectedContent().items(DiagramContent::All);
|
||||
QRectF viewed_scene = viewedSceneRect();
|
||||
foreach (QGraphicsItem *qgi, selected_elmts){
|
||||
if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
|
||||
@ -755,10 +769,10 @@ void DiagramView::scrollOnMovement(QKeyEvent *e){
|
||||
h_increment = 2*qgi->boundingRect().right();
|
||||
if (h_increment == 0) h_increment = -2*qgi->boundingRect().width();
|
||||
}
|
||||
if (((elmt_right >= m_scene->sceneRect().right() - qgi->boundingRect().right()) ||
|
||||
(elmt_bottom >= m_scene->sceneRect().bottom() - qgi->boundingRect().bottom())) &&
|
||||
if (((elmt_right >= m_diagram->sceneRect().right() - qgi->boundingRect().right()) ||
|
||||
(elmt_bottom >= m_diagram->sceneRect().bottom() - qgi->boundingRect().bottom())) &&
|
||||
(e->key()==Qt::Key_Right || e->key()==Qt::Key_Down)){
|
||||
m_scene->adjustSceneRect();
|
||||
m_diagram->adjustSceneRect();
|
||||
}
|
||||
h -> setValue(h -> value() + h_increment);
|
||||
v -> setValue(v -> value() + v_increment);
|
||||
@ -775,7 +789,7 @@ void DiagramView::scrollOnMovement(QKeyEvent *e){
|
||||
*/
|
||||
QString DiagramView::title() const {
|
||||
QString view_title;
|
||||
QString diagram_title(m_scene -> title());
|
||||
QString diagram_title(m_diagram -> title());
|
||||
if (diagram_title.isEmpty()) {
|
||||
view_title = tr("Sans titre", "what to display for untitled diagrams");
|
||||
} else {
|
||||
@ -789,14 +803,14 @@ QString DiagramView::title() const {
|
||||
* Edit the properties of the viewed digram
|
||||
*/
|
||||
void DiagramView::editDiagramProperties() {
|
||||
DiagramPropertiesDialog::diagramPropertiesDialog(m_scene, diagramEditor());
|
||||
DiagramPropertiesDialog::diagramPropertiesDialog(m_diagram, diagramEditor());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true s'il y a des items selectionnes sur le schema, false sinon
|
||||
*/
|
||||
bool DiagramView::hasSelectedItems() {
|
||||
return(m_scene -> selectedItems().size() > 0);
|
||||
return(m_diagram -> selectedItems().size() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -804,7 +818,7 @@ bool DiagramView::hasSelectedItems() {
|
||||
peuvent etre copies dans le presse-papier, false sinon
|
||||
*/
|
||||
bool DiagramView::hasCopiableItems() {
|
||||
foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) {
|
||||
foreach(QGraphicsItem *qgi, m_diagram -> selectedItems()) {
|
||||
if (
|
||||
qgraphicsitem_cast<Element *>(qgi) ||
|
||||
qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
|
||||
@ -821,7 +835,7 @@ bool DiagramView::hasCopiableItems() {
|
||||
@return true if there is any Text Item selected
|
||||
*/
|
||||
bool DiagramView::hasTextItems() {
|
||||
foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) {
|
||||
foreach(QGraphicsItem *qgi, m_diagram -> selectedItems()) {
|
||||
if (
|
||||
qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
|
||||
qgraphicsitem_cast<ElementTextItem *>(qgi) ||
|
||||
@ -835,20 +849,20 @@ bool DiagramView::hasTextItems() {
|
||||
}
|
||||
|
||||
/**
|
||||
@return true s'il y a des items selectionnes sur le schema et que ceux-ci
|
||||
peuvent etre supprimes, false sinon
|
||||
*/
|
||||
bool DiagramView::hasDeletableItems() {
|
||||
foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) {
|
||||
if (
|
||||
qgraphicsitem_cast<Element *>(qgi) ||
|
||||
qgraphicsitem_cast<Conductor *>(qgi) ||
|
||||
qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
|
||||
qgraphicsitem_cast<QetShapeItem *>(qgi) ||
|
||||
qgraphicsitem_cast<DiagramImageItem *>(qgi)
|
||||
) {
|
||||
return(true);
|
||||
}
|
||||
* @brief DiagramView::hasDeletableItems
|
||||
* @return True if a least on of selected item can be deleted
|
||||
*/
|
||||
bool DiagramView::hasDeletableItems()
|
||||
{
|
||||
for(QGraphicsItem *qgi : m_diagram->selectedItems())
|
||||
{
|
||||
if (qgi->type() == Element::Type ||
|
||||
qgi->type() == Conductor::Type ||
|
||||
qgi->type() == IndependentTextItem::Type ||
|
||||
qgi->type() == QetShapeItem::Type ||
|
||||
qgi->type() == DiagramImageItem::Type ||
|
||||
qgi->type() == DynamicElementTextItem::Type)
|
||||
return true;
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
@ -857,64 +871,55 @@ bool DiagramView::hasDeletableItems() {
|
||||
Ajoute une colonne au schema.
|
||||
*/
|
||||
void DiagramView::addColumn() {
|
||||
if (m_scene -> isReadOnly()) return;
|
||||
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
|
||||
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
|
||||
if (m_diagram -> isReadOnly()) return;
|
||||
BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
|
||||
BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
|
||||
new_bp.columns_count += 1;
|
||||
m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp));
|
||||
m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
|
||||
}
|
||||
|
||||
/**
|
||||
Enleve une colonne au schema.
|
||||
*/
|
||||
void DiagramView::removeColumn() {
|
||||
if (m_scene -> isReadOnly()) return;
|
||||
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
|
||||
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
|
||||
if (m_diagram -> isReadOnly()) return;
|
||||
BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
|
||||
BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
|
||||
new_bp.columns_count -= 1;
|
||||
m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp));
|
||||
m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
|
||||
}
|
||||
|
||||
/**
|
||||
Agrandit le schema en hauteur
|
||||
*/
|
||||
void DiagramView::addRow() {
|
||||
if (m_scene -> isReadOnly()) return;
|
||||
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
|
||||
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
|
||||
if (m_diagram -> isReadOnly()) return;
|
||||
BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
|
||||
BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
|
||||
new_bp.rows_count += 1;
|
||||
m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp));
|
||||
m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
|
||||
}
|
||||
|
||||
/**
|
||||
Retrecit le schema en hauteur
|
||||
*/
|
||||
void DiagramView::removeRow() {
|
||||
if (m_scene -> isReadOnly()) return;
|
||||
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
|
||||
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
|
||||
if (m_diagram -> isReadOnly()) return;
|
||||
BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
|
||||
BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
|
||||
new_bp.rows_count -= 1;
|
||||
m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp));
|
||||
m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DiagramView::adjustSceneRect
|
||||
* Calcul and set the area of the scene visualized by this view
|
||||
* The area are diagram sceneRect * 2.
|
||||
*/
|
||||
void DiagramView::adjustSceneRect()
|
||||
{
|
||||
QRectF scene_rect = m_scene->sceneRect();
|
||||
QRectF scene_rect = m_diagram->sceneRect();
|
||||
scene_rect.adjust(-Diagram::margin, -Diagram::margin, Diagram::margin, Diagram::margin);
|
||||
|
||||
QSettings settings;
|
||||
if (settings.value("diagrameditor/zoom-out-beyond-of-folio", false).toBool())
|
||||
{
|
||||
//When zoom out beyong of folio is active,
|
||||
//we always adjust the scene rect to be 1/3 bigger than the wiewport
|
||||
QRectF vpbr = mapToScene(viewport()->rect()).boundingRect();
|
||||
vpbr.adjust(0, 0, vpbr.width()/3, vpbr.height()/3);
|
||||
scene_rect = scene_rect.united(vpbr);
|
||||
}
|
||||
setSceneRect(scene_rect);
|
||||
}
|
||||
|
||||
@ -931,9 +936,9 @@ void DiagramView::updateWindowTitle() {
|
||||
void DiagramView::adjustGridToZoom() {
|
||||
QRectF viewed_scene = viewedSceneRect();
|
||||
if (diagramEditor()->drawGrid())
|
||||
m_scene->setDisplayGrid(viewed_scene.width() < 2000 || viewed_scene.height() < 2000);
|
||||
m_diagram->setDisplayGrid(viewed_scene.width() < 2000 || viewed_scene.height() < 2000);
|
||||
else
|
||||
m_scene->setDisplayGrid(false);
|
||||
m_diagram->setDisplayGrid(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -965,7 +970,7 @@ bool DiagramView::mustIntegrateTitleBlockTemplate(const TitleBlockTemplateLocati
|
||||
QETProject *tbt_parent_project = tbt_loc.parentProject();
|
||||
if (!tbt_parent_project) return(true);
|
||||
|
||||
return(tbt_parent_project != m_scene -> project());
|
||||
return(tbt_parent_project != m_diagram -> project());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -973,9 +978,9 @@ bool DiagramView::mustIntegrateTitleBlockTemplate(const TitleBlockTemplateLocati
|
||||
seule
|
||||
*/
|
||||
void DiagramView::applyReadOnly() {
|
||||
if (!m_scene) return;
|
||||
if (!m_diagram) return;
|
||||
|
||||
bool is_writable = !m_scene -> isReadOnly();
|
||||
bool is_writable = !m_diagram -> isReadOnly();
|
||||
setInteractive(is_writable);
|
||||
setAcceptDrops(is_writable);
|
||||
}
|
||||
@ -985,7 +990,7 @@ void DiagramView::applyReadOnly() {
|
||||
*/
|
||||
void DiagramView::editSelectionProperties() {
|
||||
// get selection
|
||||
DiagramContent selection = m_scene -> selectedContent();
|
||||
DiagramContent selection = m_diagram -> selectedContent();
|
||||
|
||||
// if selection contains nothing return
|
||||
int selected_items_count = selection.count(DiagramContent::All | DiagramContent::SelectedOnly);
|
||||
@ -999,8 +1004,8 @@ void DiagramView::editSelectionProperties() {
|
||||
if (selection.conductors(DiagramContent::AnyConductor | DiagramContent::SelectedOnly).size())
|
||||
selection.conductors().first()->editProperty();
|
||||
// edit element
|
||||
else if (selection.elements.size())
|
||||
selection.elements.toList().first() -> editProperty();
|
||||
else if (selection.m_elements.size())
|
||||
selection.m_elements.toList().first() -> editProperty();
|
||||
}
|
||||
|
||||
else {
|
||||
@ -1022,7 +1027,7 @@ void DiagramView::editSelectionProperties() {
|
||||
*/
|
||||
void DiagramView::editSelectedConductorColor() {
|
||||
// retrieve selected content
|
||||
DiagramContent selection = m_scene -> selectedContent();
|
||||
DiagramContent selection = m_diagram -> selectedContent();
|
||||
|
||||
// we'll focus on the selected conductor (we do not handle multiple conductors edition)
|
||||
QList<Conductor *> selected_conductors = selection.conductors(DiagramContent::AnyConductor | DiagramContent::SelectedOnly);
|
||||
@ -1037,7 +1042,7 @@ void DiagramView::editSelectedConductorColor() {
|
||||
*/
|
||||
void DiagramView::editConductorColor(Conductor *edited_conductor)
|
||||
{
|
||||
if (m_scene -> isReadOnly() || !edited_conductor) return;
|
||||
if (m_diagram -> isReadOnly() || !edited_conductor) return;
|
||||
|
||||
// store the initial properties of the provided conductor
|
||||
ConductorProperties initial_properties = edited_conductor -> properties();
|
||||
@ -1073,9 +1078,9 @@ void DiagramView::editConductorColor(Conductor *edited_conductor)
|
||||
Reinitialise le profil des conducteurs selectionnes
|
||||
*/
|
||||
void DiagramView::resetConductors() {
|
||||
if (m_scene -> isReadOnly()) return;
|
||||
if (m_diagram -> isReadOnly()) return;
|
||||
// recupere les conducteurs selectionnes
|
||||
QSet<Conductor *> selected_conductors = m_scene -> selectedConductors();
|
||||
QSet<Conductor *> selected_conductors = m_diagram -> selectedConductors();
|
||||
|
||||
// repere les conducteurs modifies (= profil non nul)
|
||||
QHash<Conductor *, ConductorProfilesGroup> conductors_and_profiles;
|
||||
@ -1092,7 +1097,7 @@ void DiagramView::resetConductors() {
|
||||
}
|
||||
|
||||
if (conductors_and_profiles.isEmpty()) return;
|
||||
m_scene -> undoStack().push(new ResetConductorCommand(conductors_and_profiles));
|
||||
m_diagram -> undoStack().push(new ResetConductorCommand(conductors_and_profiles));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1186,9 +1191,9 @@ bool DiagramView::isCtrlShifting(QInputEvent *e) {
|
||||
*/
|
||||
bool DiagramView::selectedItemHasFocus() {
|
||||
return(
|
||||
m_scene -> hasFocus() &&
|
||||
m_scene -> focusItem() &&
|
||||
m_scene -> focusItem() -> isSelected()
|
||||
m_diagram -> hasFocus() &&
|
||||
m_diagram -> focusItem() &&
|
||||
m_diagram -> focusItem() -> isSelected()
|
||||
);
|
||||
}
|
||||
|
||||
@ -1197,9 +1202,9 @@ bool DiagramView::selectedItemHasFocus() {
|
||||
* Edit the selected item if he can be edited and if only one item is selected
|
||||
*/
|
||||
void DiagramView::editSelection() {
|
||||
if (m_scene -> isReadOnly() || m_scene -> selectedItems().size() != 1 ) return;
|
||||
if (m_diagram -> isReadOnly() || m_diagram -> selectedItems().size() != 1 ) return;
|
||||
|
||||
QGraphicsItem *item = m_scene->selectedItems().first();
|
||||
QGraphicsItem *item = m_diagram->selectedItems().first();
|
||||
|
||||
//We use dynamic_cast instead of qgraphicsitem_cast for QetGraphicsItem
|
||||
//because they haven't got they own type().
|
||||
@ -1230,31 +1235,31 @@ void DiagramView::setEventInterface(DVEventInterface *event_interface)
|
||||
@param e Evenement decrivant la demande de menu contextuel
|
||||
*/
|
||||
void DiagramView::contextMenuEvent(QContextMenuEvent *e) {
|
||||
if (QGraphicsItem *qgi = m_scene -> itemAt(mapToScene(e -> pos()), transform())) {
|
||||
if (!qgi -> isSelected()) m_scene -> clearSelection();
|
||||
if (QGraphicsItem *qgi = m_diagram -> itemAt(mapToScene(e -> pos()), transform())) {
|
||||
if (!qgi -> isSelected()) m_diagram -> clearSelection();
|
||||
qgi -> setSelected(true);
|
||||
}
|
||||
|
||||
if (QETDiagramEditor *qde = diagramEditor()) {
|
||||
context_menu -> clear();
|
||||
if (m_scene -> selectedItems().isEmpty()) {
|
||||
paste_here_pos = e -> pos();
|
||||
paste_here -> setEnabled(Diagram::clipboardMayContainDiagram());
|
||||
context_menu -> addAction(paste_here);
|
||||
context_menu -> addSeparator();
|
||||
context_menu -> addAction(qde -> infos_diagram);
|
||||
context_menu -> addActions(qde -> m_row_column_actions_group.actions());
|
||||
m_context_menu -> clear();
|
||||
if (m_diagram -> selectedItems().isEmpty()) {
|
||||
m_paste_here_pos = e -> pos();
|
||||
m_paste_here -> setEnabled(Diagram::clipboardMayContainDiagram());
|
||||
m_context_menu -> addAction(m_paste_here);
|
||||
m_context_menu -> addSeparator();
|
||||
m_context_menu -> addAction(qde -> infos_diagram);
|
||||
m_context_menu -> addActions(qde -> m_row_column_actions_group.actions());
|
||||
} else {
|
||||
context_menu -> addAction(qde -> cut);
|
||||
context_menu -> addAction(qde -> copy);
|
||||
context_menu -> addSeparator();
|
||||
context_menu -> addAction(qde -> conductor_reset);
|
||||
context_menu -> addSeparator();
|
||||
context_menu -> addActions(qde -> m_selection_actions_group.actions());
|
||||
m_context_menu -> addAction(qde -> m_cut);
|
||||
m_context_menu -> addAction(qde -> m_copy);
|
||||
m_context_menu -> addSeparator();
|
||||
m_context_menu -> addAction(qde -> m_conductor_reset);
|
||||
m_context_menu -> addSeparator();
|
||||
m_context_menu -> addActions(qde -> m_selection_actions_group.actions());
|
||||
}
|
||||
|
||||
// affiche le menu contextuel
|
||||
context_menu -> popup(e -> globalPos());
|
||||
m_context_menu -> popup(e -> globalPos());
|
||||
}
|
||||
e -> accept();
|
||||
}
|
||||
@ -1280,7 +1285,7 @@ void DiagramView::mouseDoubleClickEvent(QMouseEvent *e)
|
||||
{
|
||||
if (m_event_interface && m_event_interface -> mouseDoubleClickEvent(e)) return;
|
||||
|
||||
BorderTitleBlock &bi = m_scene -> border_and_titleblock;
|
||||
BorderTitleBlock &bi = m_diagram -> border_and_titleblock;
|
||||
|
||||
//Get the click pos on the diagram
|
||||
QPointF click_pos = viewportTransform().inverted().map(e -> pos());
|
||||
|
@ -49,15 +49,14 @@ class DiagramView : public QGraphicsView
|
||||
|
||||
// attributes
|
||||
|
||||
Diagram *m_scene;
|
||||
DVEventInterface *m_event_interface;
|
||||
QMenu *context_menu;
|
||||
QAction *paste_here;
|
||||
QPoint paste_here_pos;
|
||||
QPointF rubber_band_origin;
|
||||
bool fresh_focus_in_; ///< Indicate the focus was freshly gained
|
||||
bool m_first_activation;
|
||||
|
||||
Diagram *m_diagram;
|
||||
DVEventInterface *m_event_interface = nullptr;
|
||||
QMenu *m_context_menu;
|
||||
QAction *m_paste_here;
|
||||
QPoint m_paste_here_pos;
|
||||
QPointF m_rubber_band_origin;
|
||||
bool m_fresh_focus_in,
|
||||
m_first_activation = true;
|
||||
public:
|
||||
QString title() const;
|
||||
void editDiagramProperties();
|
||||
@ -66,7 +65,7 @@ class DiagramView : public QGraphicsView
|
||||
void addRow();
|
||||
void removeRow();
|
||||
/// @return the diagram rendered by this view
|
||||
Diagram *diagram() { return(m_scene); }
|
||||
Diagram *diagram() { return(m_diagram); }
|
||||
QETDiagramEditor *diagramEditor() const;
|
||||
bool hasSelectedItems();
|
||||
bool hasCopiableItems();
|
||||
|
@ -105,12 +105,12 @@ void ElementsMover::continueMovement(const QPointF &movement) {
|
||||
}
|
||||
|
||||
// Move some conductors
|
||||
foreach(Conductor *conductor, moved_content_.conductorsToMove) {
|
||||
foreach(Conductor *conductor, moved_content_.m_conductors_to_move) {
|
||||
conductor -> setPos(conductor -> pos() + movement);
|
||||
}
|
||||
|
||||
// Recalcul the path of other conductors
|
||||
foreach(Conductor *conductor, moved_content_.conductorsToUpdate) {
|
||||
foreach(Conductor *conductor, moved_content_.m_conductors_to_update) {
|
||||
conductor -> updatePath();
|
||||
}
|
||||
}
|
||||
@ -142,7 +142,7 @@ void ElementsMover::endMovement()
|
||||
moved_content_.items(dc::Elements).size() == 1 &&
|
||||
diagram_ -> project() -> autoConductor())
|
||||
{
|
||||
Element *elmt = moved_content_.elements.toList().first();
|
||||
Element *elmt = moved_content_.m_elements.toList().first();
|
||||
|
||||
int acc = elmt->AlignedFreeTerminals().size();
|
||||
|
||||
|
@ -19,15 +19,12 @@
|
||||
#include "elementtextitem.h"
|
||||
#include "diagram.h"
|
||||
#include "QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
|
||||
/**
|
||||
* @brief ElementTextsMover::ElementTextsMover
|
||||
*/
|
||||
ElementTextsMover::ElementTextsMover() :
|
||||
movement_running_(false),
|
||||
diagram_(nullptr),
|
||||
movement_driver_(nullptr)
|
||||
{}
|
||||
ElementTextsMover::ElementTextsMover() {}
|
||||
|
||||
/**
|
||||
* @brief ElementTextsMover::isReady
|
||||
@ -35,7 +32,7 @@ ElementTextsMover::ElementTextsMover() :
|
||||
* False if this ElementTextsMover is actually process a movement
|
||||
*/
|
||||
bool ElementTextsMover::isReady() const {
|
||||
return(!movement_running_);
|
||||
return(!m_movement_running);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,24 +44,24 @@ bool ElementTextsMover::isReady() const {
|
||||
*/
|
||||
int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item)
|
||||
{
|
||||
if (movement_running_ || !diagram) return(-1);
|
||||
if (m_movement_running || !diagram) return(-1);
|
||||
|
||||
diagram_ = diagram;
|
||||
movement_driver_ = driver_item;
|
||||
m_diagram = diagram;
|
||||
m_movement_driver = driver_item;
|
||||
m_texts_item_H.clear();
|
||||
|
||||
foreach(QGraphicsItem *item, diagram -> selectedItems())
|
||||
for(QGraphicsItem *item : diagram->selectedItems())
|
||||
{
|
||||
if (item->type() == ElementTextItem::Type)
|
||||
if (item->type() == ElementTextItem::Type || item->type() == DynamicElementTextItem::Type)
|
||||
{
|
||||
ElementTextItem *eti = static_cast<ElementTextItem *> (item);
|
||||
m_texts_item_H.insert(eti, eti->pos());
|
||||
DiagramTextItem *dti = static_cast<DiagramTextItem *> (item);
|
||||
m_texts_item_H.insert(dti, dti->pos());
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_texts_item_H.size()) return(-1);
|
||||
|
||||
movement_running_ = true;
|
||||
m_movement_running = true;
|
||||
|
||||
return(m_texts_item_H.size());
|
||||
}
|
||||
@ -77,13 +74,14 @@ int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_ite
|
||||
*/
|
||||
void ElementTextsMover::continueMovement(const QPointF &movement)
|
||||
{
|
||||
if (!movement_running_ || movement.isNull()) return;
|
||||
if (!m_movement_running || movement.isNull()) return;
|
||||
|
||||
foreach(ElementTextItem *text_item, m_texts_item_H.keys())
|
||||
for(DiagramTextItem *text_item : m_texts_item_H.keys())
|
||||
{
|
||||
if (text_item == movement_driver_) continue;
|
||||
QPointF applied_movement = text_item -> mapMovementToParent(text_item-> mapMovementFromScene(movement));
|
||||
text_item -> setPos(text_item -> pos() + applied_movement);
|
||||
if (text_item == m_movement_driver)
|
||||
continue;
|
||||
QPointF applied_movement = text_item->mapMovementToParent(text_item->mapMovementFromScene(movement));
|
||||
text_item->setPos(text_item->pos() + applied_movement);
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,31 +92,25 @@ void ElementTextsMover::continueMovement(const QPointF &movement)
|
||||
void ElementTextsMover::endMovement()
|
||||
{
|
||||
//No movement running, or no text to move
|
||||
if (!movement_running_ || m_texts_item_H.isEmpty()) return;
|
||||
if (!m_movement_running || m_texts_item_H.isEmpty())
|
||||
return;
|
||||
|
||||
//Movement is null
|
||||
ElementTextItem *eti = m_texts_item_H.keys().first();
|
||||
if (eti->pos() == m_texts_item_H.value(eti)) return;
|
||||
DiagramTextItem *dti = m_texts_item_H.keys().first();
|
||||
if (dti->pos() == m_texts_item_H.value(dti))
|
||||
return;
|
||||
|
||||
QPropertyUndoCommand *undo = nullptr;
|
||||
QUndoCommand *undo = new QUndoCommand(m_texts_item_H.size() == 1 ? QString(QObject::tr("Déplacer un texte d'élément")) :
|
||||
QString(QObject::tr("Déplacer %1 textes d'élément").arg(m_texts_item_H.size())));
|
||||
|
||||
foreach (ElementTextItem *eti, m_texts_item_H.keys())
|
||||
for (DiagramTextItem *dti : m_texts_item_H.keys())
|
||||
{
|
||||
if (undo)
|
||||
{
|
||||
QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(eti, "pos", m_texts_item_H.value(eti), eti->pos(), undo);
|
||||
QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(dti, "pos", m_texts_item_H.value(dti), dti->pos(), undo);
|
||||
child_undo->enableAnimation();
|
||||
}
|
||||
else
|
||||
{
|
||||
undo = new QPropertyUndoCommand(eti, "pos", m_texts_item_H.value(eti), eti->pos());
|
||||
undo->enableAnimation();
|
||||
QString txt = m_texts_item_H.size() == 1? QString(QObject::tr("Déplacer un texte d'élément")) :
|
||||
QString(QObject::tr("Déplacer %1 textes d'élément").arg(m_texts_item_H.size()));
|
||||
undo->setText(txt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
diagram_->undoStack().push(undo);
|
||||
m_diagram->undoStack().push(undo);
|
||||
|
||||
movement_running_ = false;
|
||||
m_movement_running = false;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <QPointF>
|
||||
|
||||
class QGraphicsItem;
|
||||
class ElementTextItem;
|
||||
class DiagramTextItem;
|
||||
class Diagram;
|
||||
|
||||
/**
|
||||
@ -38,14 +38,14 @@ class ElementTextsMover
|
||||
|
||||
public:
|
||||
bool isReady() const;
|
||||
int beginMovement(Diagram *, QGraphicsItem * = 0);
|
||||
int beginMovement(Diagram *diagram, QGraphicsItem *driver_item = nullptr);
|
||||
void continueMovement(const QPointF &);
|
||||
void endMovement();
|
||||
|
||||
private:
|
||||
bool movement_running_;
|
||||
Diagram *diagram_;
|
||||
QGraphicsItem *movement_driver_;
|
||||
QHash <ElementTextItem *, QPointF> m_texts_item_H;
|
||||
bool m_movement_running = false;
|
||||
Diagram *m_diagram = nullptr;
|
||||
QGraphicsItem *m_movement_driver = nullptr;
|
||||
QHash <DiagramTextItem *, QPointF> m_texts_item_H;
|
||||
};
|
||||
#endif
|
||||
|
@ -232,7 +232,7 @@ bool QET::attributeIsAReal(const QDomElement &e, QString nom_attribut, qreal *re
|
||||
@return la proposition decrivant le nombre d'elements, de conducteurs et de
|
||||
textes
|
||||
*/
|
||||
QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count, int texts_count, int images_count, int shapes_count) {
|
||||
QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count, int texts_count, int images_count, int shapes_count, int element_text_count) {
|
||||
QString text;
|
||||
if (elements_count) {
|
||||
text += QObject::tr(
|
||||
@ -240,61 +240,28 @@ QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_co
|
||||
"part of a sentence listing the content of a diagram",
|
||||
elements_count
|
||||
);
|
||||
if ((conductors_count && texts_count) ||
|
||||
(conductors_count && images_count) ||
|
||||
(texts_count && images_count)) {
|
||||
text += QObject::tr(
|
||||
", ",
|
||||
"separator between elements and conductors in a sentence "
|
||||
"listing the content of a diagram"
|
||||
);
|
||||
} else if (conductors_count || texts_count || images_count) {
|
||||
text += QObject::tr(
|
||||
" et ",
|
||||
"separator between elements and conductors (or texts) in a "
|
||||
"sentence listing the content of a diagram"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (conductors_count) {
|
||||
if (!text.isEmpty()) text += ", ";
|
||||
text += QObject::tr(
|
||||
"%n conducteur(s)",
|
||||
"part of a sentence listing the content of a diagram",
|
||||
conductors_count
|
||||
);
|
||||
if (texts_count && images_count) {
|
||||
text += QObject::tr(
|
||||
", ",
|
||||
"separator between elements and conductors in a sentence "
|
||||
"listing the content of a diagram"
|
||||
);
|
||||
}
|
||||
else if (texts_count || images_count) {
|
||||
text += QObject::tr(
|
||||
" et ",
|
||||
"separator between conductors and texts in a sentence listing "
|
||||
"the content of a diagram"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (texts_count) {
|
||||
if (!text.isEmpty()) text += ", ";
|
||||
text += QObject::tr(
|
||||
"%n champ(s) de texte",
|
||||
"part of a sentence listing the content of a diagram",
|
||||
texts_count
|
||||
);
|
||||
if (images_count) {
|
||||
text += QObject::tr(
|
||||
" et ",
|
||||
"separator between conductors and texts in a sentence listing "
|
||||
"the content of a diagram"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (images_count) {
|
||||
if (!text.isEmpty()) text += ", ";
|
||||
text += QObject::tr(
|
||||
"%n image(s)",
|
||||
"part of a sentence listing the content of a diagram",
|
||||
@ -303,12 +270,22 @@ QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_co
|
||||
}
|
||||
|
||||
if (shapes_count) {
|
||||
if (!text.isEmpty()) text += ", ";
|
||||
text += QObject::tr(
|
||||
"%n forme(s)",
|
||||
"part of a sentence listing the content of a diagram",
|
||||
shapes_count
|
||||
);
|
||||
}
|
||||
|
||||
if (element_text_count) {
|
||||
if (!text.isEmpty()) text += ", ";
|
||||
text += QObject::tr(
|
||||
"%n texte(s) d'élément",
|
||||
"part of a sentence listing the content of a diagram",
|
||||
element_text_count);
|
||||
}
|
||||
|
||||
return(text);
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ namespace QET {
|
||||
bool orthogonalProjection(const QPointF &, const QLineF &, QPointF * = 0);
|
||||
bool attributeIsAnInteger(const QDomElement &, QString , int * = NULL);
|
||||
bool attributeIsAReal(const QDomElement &, QString , qreal * = NULL);
|
||||
QString ElementsAndConductorsSentence(int, int, int = 0, int = 0, int = 0);
|
||||
QString ElementsAndConductorsSentence(int, int, int = 0, int = 0, int = 0, int = 0);
|
||||
QList<QDomElement> findInDomElement(const QDomElement &, const QString &);
|
||||
QList<QDomElement> findInDomElement(const QDomElement &, const QString &, const QString &);
|
||||
QList<QChar> forbiddenCharacters();
|
||||
|
@ -42,6 +42,9 @@
|
||||
#include "diagrameventaddtext.h"
|
||||
#include "elementscollectionwidget.h"
|
||||
#include "autonumberingdockwidget.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include "conductortextitem.h"
|
||||
#include "elementtextitem.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QStandardPaths>
|
||||
@ -242,24 +245,24 @@ void QETDiagramEditor::setUpActions()
|
||||
redo -> setStatusTip(tr("Restaure l'action annulée", "status bar tip"));
|
||||
|
||||
//cut copy past action
|
||||
cut = new QAction(QET::Icons::EditCut, tr("Co&uper"), this);
|
||||
copy = new QAction(QET::Icons::EditCopy, tr("Cop&ier"), this);
|
||||
m_cut = new QAction(QET::Icons::EditCut, tr("Co&uper"), this);
|
||||
m_copy = new QAction(QET::Icons::EditCopy, tr("Cop&ier"), this);
|
||||
paste = new QAction(QET::Icons::EditPaste, tr("C&oller"), this);
|
||||
|
||||
cut -> setShortcut(QKeySequence::Cut);
|
||||
copy -> setShortcut(QKeySequence::Copy);
|
||||
m_cut -> setShortcut(QKeySequence::Cut);
|
||||
m_copy -> setShortcut(QKeySequence::Copy);
|
||||
paste -> setShortcut(QKeySequence::Paste);
|
||||
|
||||
cut -> setStatusTip(tr("Transfère les éléments sélectionnés dans le presse-papier", "status bar tip"));
|
||||
copy -> setStatusTip(tr("Copie les éléments sélectionnés dans le presse-papier", "status bar tip"));
|
||||
m_cut -> setStatusTip(tr("Transfère les éléments sélectionnés dans le presse-papier", "status bar tip"));
|
||||
m_copy -> setStatusTip(tr("Copie les éléments sélectionnés dans le presse-papier", "status bar tip"));
|
||||
paste -> setStatusTip(tr("Place les éléments du presse-papier sur le folio", "status bar tip"));
|
||||
|
||||
connect(cut, SIGNAL(triggered()), this, SLOT(slot_cut()));
|
||||
connect(copy, SIGNAL(triggered()), this, SLOT(slot_copy()));
|
||||
connect(m_cut, SIGNAL(triggered()), this, SLOT(slot_cut()));
|
||||
connect(m_copy, SIGNAL(triggered()), this, SLOT(slot_copy()));
|
||||
connect(paste, SIGNAL(triggered()), this, SLOT(slot_paste()));
|
||||
|
||||
conductor_reset = new QAction(QET::Icons::ConductorSettings, tr("Réinitialiser les conducteurs"), this);
|
||||
conductor_reset -> setShortcut( QKeySequence( tr("Ctrl+K") ) );
|
||||
m_conductor_reset = new QAction(QET::Icons::ConductorSettings, tr("Réinitialiser les conducteurs"), this);
|
||||
m_conductor_reset -> setShortcut( QKeySequence( tr("Ctrl+K") ) );
|
||||
|
||||
m_auto_conductor = new QAction (QET::Icons::Autoconnect, tr("Création automatique de conducteur(s)","Tool tip of auto conductor"), this);
|
||||
m_auto_conductor -> setStatusTip (tr("Utiliser la création automatique de conducteur(s) quand cela est possible", "Status tip of auto conductor"));
|
||||
@ -348,27 +351,27 @@ void QETDiagramEditor::setUpActions()
|
||||
connect(&m_row_column_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::rowColumnGroupTriggered);
|
||||
|
||||
//Selections Actions (related to a selected item)
|
||||
delete_selection = m_selection_actions_group.addAction( QET::Icons::EditDelete, tr("Supprimer") );
|
||||
rotate_selection = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Pivoter") );
|
||||
rotate_texts = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Orienter les textes") );
|
||||
find_element = m_selection_actions_group.addAction( tr("Retrouver dans le panel") );
|
||||
edit_selection = m_selection_actions_group.addAction( QET::Icons::ElementEdit, tr("Éditer l'item sélectionné") );
|
||||
m_delete_selection = m_selection_actions_group.addAction( QET::Icons::EditDelete, tr("Supprimer") );
|
||||
m_rotate_selection = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Pivoter") );
|
||||
m_rotate_texts = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Orienter les textes") );
|
||||
m_find_element = m_selection_actions_group.addAction( tr("Retrouver dans le panel") );
|
||||
m_edit_selection = m_selection_actions_group.addAction( QET::Icons::ElementEdit, tr("Éditer l'item sélectionné") );
|
||||
|
||||
delete_selection -> setShortcut( QKeySequence::Delete);
|
||||
rotate_selection -> setShortcut( QKeySequence( tr("Space") ) );
|
||||
rotate_texts -> setShortcut( QKeySequence( tr("Ctrl+Space") ) );
|
||||
edit_selection -> setShortcut( QKeySequence( tr("Ctrl+E") ) );
|
||||
m_delete_selection -> setShortcut( QKeySequence::Delete);
|
||||
m_rotate_selection -> setShortcut( QKeySequence( tr("Space") ) );
|
||||
m_rotate_texts -> setShortcut( QKeySequence( tr("Ctrl+Space") ) );
|
||||
m_edit_selection -> setShortcut( QKeySequence( tr("Ctrl+E") ) );
|
||||
|
||||
delete_selection -> setStatusTip( tr("Enlève les éléments sélectionnés du folio", "status bar tip"));
|
||||
rotate_selection -> setStatusTip( tr("Pivote les éléments et textes sélectionnés", "status bar tip"));
|
||||
rotate_texts -> setStatusTip( tr("Pivote les textes sélectionnés à un angle précis", "status bar tip"));
|
||||
find_element -> setStatusTip( tr("Retrouve l'élément sélectionné dans le panel", "status bar tip"));
|
||||
m_delete_selection -> setStatusTip( tr("Enlève les éléments sélectionnés du folio", "status bar tip"));
|
||||
m_rotate_selection -> setStatusTip( tr("Pivote les éléments et textes sélectionnés", "status bar tip"));
|
||||
m_rotate_texts -> setStatusTip( tr("Pivote les textes sélectionnés à un angle précis", "status bar tip"));
|
||||
m_find_element -> setStatusTip( tr("Retrouve l'élément sélectionné dans le panel", "status bar tip"));
|
||||
|
||||
delete_selection ->setData("delete_selection");
|
||||
rotate_selection ->setData("rotate_selection");
|
||||
rotate_texts ->setData("rotate_selected_text");
|
||||
find_element ->setData("find_selected_element");
|
||||
edit_selection ->setData("edit_selected_element");
|
||||
m_delete_selection ->setData("delete_selection");
|
||||
m_rotate_selection ->setData("rotate_selection");
|
||||
m_rotate_texts ->setData("rotate_selected_text");
|
||||
m_find_element ->setData("find_selected_element");
|
||||
m_edit_selection ->setData("edit_selected_element");
|
||||
|
||||
connect(&m_selection_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::selectionGroupTriggered);
|
||||
|
||||
@ -452,7 +455,7 @@ void QETDiagramEditor::setUpActions()
|
||||
export_diagram -> setStatusTip(tr("Exporte le folio courant dans un autre format", "status bar tip"));
|
||||
print -> setStatusTip(tr("Imprime un ou plusieurs folios du projet courant", "status bar tip"));
|
||||
quit_editor -> setStatusTip(tr("Ferme l'application QElectroTech", "status bar tip"));
|
||||
conductor_reset -> setStatusTip(tr("Recalcule les chemins des conducteurs sans tenir compte des modifications", "status bar tip"));
|
||||
m_conductor_reset -> setStatusTip(tr("Recalcule les chemins des conducteurs sans tenir compte des modifications", "status bar tip"));
|
||||
infos_diagram -> setStatusTip(tr("Édite les propriétés du folio (dimensions, informations du cartouche, propriétés des conducteurs...)", "status bar tip"));
|
||||
|
||||
windowed_view_mode -> setStatusTip(tr("Présente les différents projets ouverts dans des sous-fenêtres", "status bar tip"));
|
||||
@ -503,7 +506,7 @@ void QETDiagramEditor::setUpActions()
|
||||
connect(cascade_window, SIGNAL(triggered()), &workspace, SLOT(cascadeSubWindows()) );
|
||||
connect(next_window, SIGNAL(triggered()), &workspace, SLOT(activateNextSubWindow()) );
|
||||
connect(prev_window, SIGNAL(triggered()), &workspace, SLOT(activatePreviousSubWindow()) );
|
||||
connect(conductor_reset, SIGNAL(triggered()), this, SLOT(slot_resetConductors()) );
|
||||
connect(m_conductor_reset, SIGNAL(triggered()), this, SLOT(slot_resetConductors()) );
|
||||
connect(infos_diagram, SIGNAL(triggered()), this, SLOT(editCurrentDiagramProperties()));
|
||||
}
|
||||
|
||||
@ -526,12 +529,12 @@ void QETDiagramEditor::setUpToolBar() {
|
||||
main_bar -> addAction(undo);
|
||||
main_bar -> addAction(redo);
|
||||
main_bar -> addSeparator();
|
||||
main_bar -> addAction(cut);
|
||||
main_bar -> addAction(copy);
|
||||
main_bar -> addAction(m_cut);
|
||||
main_bar -> addAction(m_copy);
|
||||
main_bar -> addAction(paste);
|
||||
main_bar -> addSeparator();
|
||||
main_bar -> addAction(delete_selection);
|
||||
main_bar -> addAction(rotate_selection);
|
||||
main_bar -> addAction(m_delete_selection);
|
||||
main_bar -> addAction(m_rotate_selection);
|
||||
|
||||
// Modes selection / visualisation et zoom
|
||||
view_bar -> addAction(mode_selection);
|
||||
@ -543,7 +546,7 @@ void QETDiagramEditor::setUpToolBar() {
|
||||
view_bar -> addActions(m_zoom_action_toolBar);
|
||||
|
||||
diagram_bar -> addAction (infos_diagram);
|
||||
diagram_bar -> addAction (conductor_reset);
|
||||
diagram_bar -> addAction (m_conductor_reset);
|
||||
diagram_bar -> addAction (m_auto_conductor);
|
||||
|
||||
m_add_item_toolBar = new QToolBar(tr("Ajouter"), this);
|
||||
@ -592,15 +595,15 @@ void QETDiagramEditor::setUpMenu() {
|
||||
menu_edition -> addAction(undo);
|
||||
menu_edition -> addAction(redo);
|
||||
menu_edition -> addSeparator();
|
||||
menu_edition -> addAction(cut);
|
||||
menu_edition -> addAction(copy);
|
||||
menu_edition -> addAction(m_cut);
|
||||
menu_edition -> addAction(m_copy);
|
||||
menu_edition -> addAction(paste);
|
||||
menu_edition -> addSeparator();
|
||||
menu_edition -> addActions(m_select_actions_group.actions());
|
||||
menu_edition -> addSeparator();
|
||||
menu_edition -> addActions(m_selection_actions_group.actions());
|
||||
menu_edition -> addSeparator();
|
||||
menu_edition -> addAction(conductor_reset);
|
||||
menu_edition -> addAction(m_conductor_reset);
|
||||
menu_edition -> addSeparator();
|
||||
menu_edition -> addAction(infos_diagram);
|
||||
menu_edition -> addActions(m_row_column_actions_group.actions());
|
||||
@ -1039,7 +1042,7 @@ Element *QETDiagramEditor::currentElement() const {
|
||||
DiagramView *dv = currentDiagram();
|
||||
if (!dv) return(0);
|
||||
|
||||
QList<Element *> selected_elements = dv -> diagram() -> selectedContent().elements.toList();
|
||||
QList<Element *> selected_elements = dv -> diagram() -> selectedContent().m_elements.toList();
|
||||
if (selected_elements.count() != 1) return(0);
|
||||
|
||||
return(selected_elements.first());
|
||||
@ -1383,76 +1386,90 @@ void QETDiagramEditor::slot_updateUndoStack()
|
||||
* Manage the actions who need some conditions to be enable or not.
|
||||
* This method does nothing if there is no project opened
|
||||
*/
|
||||
void QETDiagramEditor::slot_updateComplexActions() {
|
||||
void QETDiagramEditor::slot_updateComplexActions()
|
||||
{
|
||||
DiagramView *dv = currentDiagram();
|
||||
bool editable_diagram = (dv && !dv -> diagram() -> isReadOnly());
|
||||
if(!dv)
|
||||
{
|
||||
QList <QAction *> action_list;
|
||||
action_list << m_conductor_reset << m_find_element << m_cut << m_copy << m_delete_selection << m_rotate_selection << m_edit_selection;
|
||||
for(QAction *action : action_list)
|
||||
action->setEnabled(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Diagram *diagram_ = dv->diagram();
|
||||
bool ro = diagram_->isReadOnly();
|
||||
|
||||
|
||||
//Number of selected conductors
|
||||
int selected_conductors_count = dv ? dv -> diagram() -> selectedConductors().count() : 0;
|
||||
conductor_reset -> setEnabled(editable_diagram && selected_conductors_count);
|
||||
int selected_conductors_count = diagram_->selectedConductors().count();
|
||||
m_conductor_reset->setEnabled(!ro && selected_conductors_count);
|
||||
|
||||
// number of selected elements
|
||||
int selected_elements_count = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Elements) : 0;
|
||||
find_element -> setEnabled(selected_elements_count == 1);
|
||||
int selected_elements_count = diagram_->selectedContent().count(DiagramContent::Elements);
|
||||
m_find_element->setEnabled(selected_elements_count == 1);
|
||||
|
||||
//Action that need items (elements, conductors, texts...) selected, to be enabled
|
||||
bool copiable_items = dv ? (dv -> hasCopiableItems()) : false;
|
||||
bool deletable_items = dv ? (dv -> hasDeletableItems()) : false;
|
||||
cut -> setEnabled(editable_diagram && copiable_items);
|
||||
copy -> setEnabled(copiable_items);
|
||||
delete_selection -> setEnabled(editable_diagram && deletable_items);
|
||||
rotate_selection -> setEnabled(editable_diagram && dv -> diagram() -> canRotateSelection());
|
||||
bool copiable_items = dv->hasCopiableItems();
|
||||
bool deletable_items = dv->hasDeletableItems();
|
||||
m_cut -> setEnabled(!ro && copiable_items);
|
||||
m_copy -> setEnabled(copiable_items);
|
||||
m_delete_selection -> setEnabled(!ro && deletable_items);
|
||||
m_rotate_selection -> setEnabled(!ro && diagram_->canRotateSelection());
|
||||
|
||||
//Action that need selected texts
|
||||
int selected_texts = dv ? (dv -> diagram() -> selectedTexts().count()) : 0;
|
||||
int selected_conductor_texts = dv ? (dv -> diagram() -> selectedConductorTexts().count()) : 0;
|
||||
int selected_element_texts = dv ? (dv -> diagram() -> selectedElementTexts().count()) : 0;
|
||||
rotate_texts -> setEnabled(editable_diagram && selected_texts);
|
||||
int selected_texts = diagram_->selectedTexts().count();
|
||||
int selected_conductor_texts = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ConductorTextItem::Type) selected_conductor_texts++;}
|
||||
int selected_element_texts = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ElementTextItem::Type) selected_element_texts++;}
|
||||
int selected_dynamic_elmt_text = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == DynamicElementTextItem::Type) selected_dynamic_elmt_text++;}
|
||||
m_rotate_texts -> setEnabled(!ro && selected_texts);
|
||||
|
||||
// actions need only one editable item
|
||||
int selected_image = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Images) : 0;
|
||||
int selected_image = diagram_-> selectedContent().count(DiagramContent::Images);
|
||||
|
||||
int selected_shape = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Shapes) : 0;
|
||||
int selected_shape = diagram_-> selectedContent().count(DiagramContent::Shapes);
|
||||
int selected_editable = selected_elements_count +
|
||||
(selected_texts - selected_conductor_texts - selected_element_texts) +
|
||||
(selected_texts - selected_conductor_texts - selected_element_texts - selected_dynamic_elmt_text) +
|
||||
selected_image +
|
||||
selected_shape +
|
||||
selected_conductors_count;
|
||||
|
||||
if (selected_editable == 1)
|
||||
{
|
||||
edit_selection -> setEnabled(true);
|
||||
m_edit_selection -> setEnabled(true);
|
||||
//edit element
|
||||
if (selected_elements_count)
|
||||
{
|
||||
edit_selection -> setText(tr("Éditer l'élement", "edit element"));
|
||||
edit_selection -> setIcon(QET::Icons::ElementEdit);
|
||||
m_edit_selection -> setText(tr("Éditer l'élement", "edit element"));
|
||||
m_edit_selection -> setIcon(QET::Icons::ElementEdit);
|
||||
}
|
||||
//edit text field
|
||||
else if (selected_texts)
|
||||
{
|
||||
edit_selection -> setText(tr("Éditer le champ de texte", "edit text field"));
|
||||
edit_selection -> setIcon(QET::Icons::EditText);
|
||||
m_edit_selection -> setText(tr("Éditer le champ de texte", "edit text field"));
|
||||
m_edit_selection -> setIcon(QET::Icons::EditText);
|
||||
}
|
||||
//edit image
|
||||
else if (selected_image)
|
||||
{
|
||||
edit_selection -> setText(tr("Éditer l'image", "edit image"));
|
||||
edit_selection -> setIcon(QET::Icons::resize_image);
|
||||
m_edit_selection -> setText(tr("Éditer l'image", "edit image"));
|
||||
m_edit_selection -> setIcon(QET::Icons::resize_image);
|
||||
}
|
||||
//edit conductor
|
||||
else if (selected_conductors_count)
|
||||
{
|
||||
edit_selection -> setText(tr("Éditer le conducteur", "edit conductor"));
|
||||
edit_selection -> setIcon(QET::Icons::ElementEdit);
|
||||
m_edit_selection -> setText(tr("Éditer le conducteur", "edit conductor"));
|
||||
m_edit_selection -> setIcon(QET::Icons::ElementEdit);
|
||||
}
|
||||
}
|
||||
//not an editable item
|
||||
else
|
||||
{
|
||||
edit_selection -> setText(tr("Éditer l'objet sélectionné", "edit selected item"));
|
||||
edit_selection -> setIcon(QET::Icons::ElementEdit);
|
||||
edit_selection -> setEnabled(false);
|
||||
m_edit_selection -> setText(tr("Éditer l'objet sélectionné", "edit selected item"));
|
||||
m_edit_selection -> setIcon(QET::Icons::ElementEdit);
|
||||
m_edit_selection -> setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,9 +174,9 @@ class QETDiagramEditor : public QETMainWindow {
|
||||
QAction *redo; ///< Redo the latest cancelled operation
|
||||
public:
|
||||
QAction *infos_diagram; ///< Show a dialog to edit diagram properties
|
||||
QAction *conductor_reset; ///< Reset paths of selected conductors
|
||||
QAction *cut; ///< Cut selection to clipboard
|
||||
QAction *copy; ///< Copy selection to clipboard
|
||||
QAction *m_conductor_reset; ///< Reset paths of selected conductors
|
||||
QAction *m_cut; ///< Cut selection to clipboard
|
||||
QAction *m_copy; ///< Copy selection to clipboard
|
||||
private:
|
||||
QAction *paste; ///< Paste clipboard content on the current diagram
|
||||
QAction *m_auto_conductor; ///< Enable/Disable the use of auto conductor
|
||||
@ -194,7 +194,7 @@ class QETDiagramEditor : public QETMainWindow {
|
||||
QAction *cascade_window; ///< Show MDI subwindows as cascade
|
||||
QAction *prev_window; ///< Switch to the previous document
|
||||
QAction *next_window; ///< Switch to the next document
|
||||
QAction *edit_selection; ///< To edit selected item
|
||||
QAction *m_edit_selection; ///< To edit selected item
|
||||
|
||||
QActionGroup m_add_item_actions_group; ///Action related to adding (add text image shape...)
|
||||
|
||||
@ -207,10 +207,10 @@ class QETDiagramEditor : public QETMainWindow {
|
||||
QActionGroup m_row_column_actions_group; /// Action related to add/remove rows/column in diagram
|
||||
QActionGroup m_selection_actions_group; ///Action related to edit a selected item
|
||||
private:
|
||||
QAction *delete_selection; ///< Delete selection
|
||||
QAction *rotate_selection; ///< Rotate selected elements and text items by 90 degrees
|
||||
QAction *rotate_texts; ///< Direct selected text items to a specific angle
|
||||
QAction *find_element; ///< Find the selected element in the panel
|
||||
QAction *m_delete_selection; ///< Delete selection
|
||||
QAction *m_rotate_selection; ///< Rotate selected elements and text items by 90 degrees
|
||||
QAction *m_rotate_texts; ///< Direct selected text items to a specific angle
|
||||
QAction *m_find_element; ///< Find the selected element in the panel
|
||||
|
||||
QActionGroup m_file_actions_group; ///Actions related to file (open, close, save...)
|
||||
QAction *close_file; ///< Close current project file
|
||||
|
@ -27,10 +27,7 @@
|
||||
*/
|
||||
DiagramTextItem::DiagramTextItem(QGraphicsItem *parent) :
|
||||
QGraphicsTextItem(parent),
|
||||
m_mouse_hover(false),
|
||||
previous_text_(),
|
||||
rotation_angle_(0.0),
|
||||
m_first_move (true)
|
||||
m_rotation_angle(0.0)
|
||||
{ build(); }
|
||||
|
||||
/**
|
||||
@ -41,8 +38,8 @@ DiagramTextItem::DiagramTextItem(QGraphicsItem *parent) :
|
||||
DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent) :
|
||||
QGraphicsTextItem(text, parent),
|
||||
m_mouse_hover(false),
|
||||
previous_text_(text),
|
||||
rotation_angle_(0.0)
|
||||
m_previous_html_text(text),
|
||||
m_rotation_angle(0.0)
|
||||
{ build(); }
|
||||
|
||||
/**
|
||||
@ -83,7 +80,7 @@ QDomElement DiagramTextItem::toXml(QDomDocument &) const {
|
||||
@return l'angle de rotation actuel de ce texte
|
||||
*/
|
||||
qreal DiagramTextItem::rotationAngle() const {
|
||||
return(rotation_angle_);
|
||||
return(m_rotation_angle);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,8 +91,8 @@ qreal DiagramTextItem::rotationAngle() const {
|
||||
*/
|
||||
void DiagramTextItem::setRotationAngle(const qreal &rotation) {
|
||||
qreal applied_rotation = QET::correctAngle(rotation);
|
||||
applyRotation(applied_rotation - rotation_angle_);
|
||||
rotation_angle_ = applied_rotation;
|
||||
applyRotation(applied_rotation - m_rotation_angle);
|
||||
m_rotation_angle = applied_rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,7 +103,7 @@ void DiagramTextItem::setRotationAngle(const qreal &rotation) {
|
||||
*/
|
||||
void DiagramTextItem::rotateBy(const qreal &added_rotation) {
|
||||
qreal applied_added_rotation = QET::correctAngle(added_rotation);
|
||||
rotation_angle_ = QET::correctAngle(rotation_angle_ + applied_added_rotation);
|
||||
m_rotation_angle = QET::correctAngle(m_rotation_angle + applied_added_rotation);
|
||||
applyRotation(applied_added_rotation);
|
||||
}
|
||||
|
||||
@ -186,8 +183,25 @@ QPointF DiagramTextItem::mapMovementFromParent(const QPointF &movement) const {
|
||||
return(local_movement_point - local_origin);
|
||||
}
|
||||
|
||||
void DiagramTextItem::setFontSize(int &s) {
|
||||
void DiagramTextItem::setFontSize(int s)
|
||||
{
|
||||
setFont(QETApp::diagramTextsFont(s));
|
||||
emit fontSizeChanged(s);
|
||||
}
|
||||
|
||||
int DiagramTextItem::fontSize() const
|
||||
{
|
||||
return font().pointSize();
|
||||
}
|
||||
|
||||
void DiagramTextItem::setColor(QColor color)
|
||||
{
|
||||
setDefaultTextColor(color);
|
||||
emit colorChanged(color);
|
||||
}
|
||||
|
||||
QColor DiagramTextItem::color() const {
|
||||
return defaultTextColor();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,42 +240,39 @@ void DiagramTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
|
||||
}
|
||||
|
||||
/**
|
||||
Gere la prise de focus du champ de texte
|
||||
@param e Objet decrivant la prise de focus
|
||||
*/
|
||||
void DiagramTextItem::focusInEvent(QFocusEvent *e) {
|
||||
QGraphicsTextItem::focusInEvent(e);
|
||||
* @brief DiagramTextItem::focusInEvent
|
||||
* @param e
|
||||
*/
|
||||
void DiagramTextItem::focusInEvent(QFocusEvent *event)
|
||||
{
|
||||
QGraphicsTextItem::focusInEvent(event);
|
||||
|
||||
// empeche le deplacement du texte pendant son edition
|
||||
setFlag(QGraphicsItem::ItemIsMovable, false);
|
||||
|
||||
// memorise le texte avant que l'utilisateur n'y touche
|
||||
previous_text_ = toHtml();
|
||||
// cela permettra de determiner si l'utilisateur a modifie le texte a la fin de l'edition
|
||||
m_previous_html_text = toHtml();
|
||||
m_previous_text = toPlainText();
|
||||
}
|
||||
|
||||
/**
|
||||
Gere la perte de focus du champ de texte
|
||||
@param e Objet decrivant la perte de focus
|
||||
*/
|
||||
void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
|
||||
QGraphicsTextItem::focusOutEvent(e);
|
||||
* @brief DiagramTextItem::focusOutEvent
|
||||
* @param event
|
||||
*/
|
||||
void DiagramTextItem::focusOutEvent(QFocusEvent *event)
|
||||
{
|
||||
QGraphicsTextItem::focusOutEvent(event);
|
||||
|
||||
// signale la modification du texte si besoin
|
||||
if (toPlainText() != previous_text_) {
|
||||
emit(diagramTextChanged(this, previous_text_, toHtml()));
|
||||
previous_text_ = toHtml();
|
||||
}
|
||||
if (toHtml() != m_previous_html_text)
|
||||
emit(diagramTextChanged(this, m_previous_html_text, toHtml()));
|
||||
if(toPlainText() != m_previous_text)
|
||||
emit textEdited(m_previous_text, toPlainText());
|
||||
|
||||
// deselectionne le texte
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.clearSelection();
|
||||
setTextCursor(cursor);
|
||||
|
||||
// hack a la con pour etre re-entrant
|
||||
//Bad hack to be re-entrant
|
||||
setTextInteractionFlags(Qt::NoTextInteraction);
|
||||
|
||||
// autorise de nouveau le deplacement du texte
|
||||
setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
setFlag(QGraphicsTextItem::ItemIsFocusable, false);
|
||||
}
|
||||
@ -271,7 +282,7 @@ void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
|
||||
@param event un QGraphicsSceneMouseEvent decrivant le double-clic
|
||||
*/
|
||||
void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
|
||||
if (!(textInteractionFlags() & Qt::TextEditable) && !no_editable) {
|
||||
if (!(textInteractionFlags() & Qt::TextEditable) && !m_no_editable) {
|
||||
// rend le champ de texte editable
|
||||
setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||
|
||||
|
@ -33,6 +33,13 @@ class DiagramTextItem : public QGraphicsTextItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged)
|
||||
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
|
||||
|
||||
signals:
|
||||
void fontSizeChanged(int size);
|
||||
void colorChanged(QColor color);
|
||||
|
||||
public:
|
||||
DiagramTextItem(QGraphicsItem * = 0);
|
||||
DiagramTextItem(const QString &, QGraphicsItem * = 0);
|
||||
@ -42,7 +49,7 @@ class DiagramTextItem : public QGraphicsTextItem
|
||||
|
||||
public:
|
||||
enum { Type = UserType + 1004 };
|
||||
virtual int type() const { return Type; }
|
||||
virtual int type() const override { return Type; }
|
||||
|
||||
Diagram *diagram() const;
|
||||
virtual void fromXml(const QDomElement &) = 0;
|
||||
@ -57,35 +64,43 @@ class DiagramTextItem : public QGraphicsTextItem
|
||||
QPointF mapMovementToParent (const QPointF &) const;
|
||||
QPointF mapMovementFromParent (const QPointF &) const;
|
||||
|
||||
void setFontSize(int &s);
|
||||
void setNoEditable(bool e = true) {no_editable = e;}
|
||||
void setFontSize(int s);
|
||||
int fontSize()const;
|
||||
|
||||
void setColor(QColor color);
|
||||
QColor color() const;
|
||||
|
||||
void setNoEditable(bool e = true) {m_no_editable = e;}
|
||||
|
||||
protected:
|
||||
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
|
||||
virtual void focusInEvent(QFocusEvent *);
|
||||
virtual void focusOutEvent(QFocusEvent *);
|
||||
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
|
||||
virtual void focusInEvent(QFocusEvent *) override;
|
||||
virtual void focusOutEvent(QFocusEvent *) override;
|
||||
|
||||
virtual void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event);
|
||||
virtual void mousePressEvent (QGraphicsSceneMouseEvent *event);
|
||||
virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event);
|
||||
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event);
|
||||
virtual void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event) override;
|
||||
virtual void mousePressEvent (QGraphicsSceneMouseEvent *event) override;
|
||||
virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
|
||||
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
|
||||
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *);
|
||||
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *) override;
|
||||
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *) override;
|
||||
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *) override;
|
||||
|
||||
virtual void applyRotation(const qreal &);
|
||||
|
||||
signals:
|
||||
/// signal emitted after text was changed
|
||||
void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
|
||||
void textEdited(const QString &old_str, const QString &new_str);
|
||||
|
||||
protected:
|
||||
bool m_mouse_hover;
|
||||
QString previous_text_;
|
||||
qreal rotation_angle_;
|
||||
bool no_editable;
|
||||
bool m_first_move;
|
||||
bool m_mouse_hover = false,
|
||||
m_first_move = true,
|
||||
m_no_editable;
|
||||
|
||||
QString m_previous_html_text,
|
||||
m_previous_text;
|
||||
|
||||
qreal m_rotation_angle;
|
||||
QPointF m_mouse_to_origin_movement;
|
||||
};
|
||||
#endif
|
||||
|
255
sources/qetgraphicsitem/dynamicelementtextitem.cpp
Normal file
255
sources/qetgraphicsitem/dynamicelementtextitem.cpp
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include "qet.h"
|
||||
#include "element.h"
|
||||
#include "qetapp.h"
|
||||
#include "diagram.h"
|
||||
#include "QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::DynamicElementTextItem
|
||||
* Constructor
|
||||
* @param parent_element
|
||||
*/
|
||||
DynamicElementTextItem::DynamicElementTextItem(Element *parent_element) :
|
||||
m_parent_element(parent_element),
|
||||
m_uuid(QUuid::createUuid())
|
||||
{
|
||||
setFont(QETApp::diagramTextsFont(9));
|
||||
setText(tr("Texte"));
|
||||
setParentItem(parent_element);
|
||||
|
||||
connect(this, &DynamicElementTextItem::textEdited, [this](const QString &old_str, const QString &new_str)
|
||||
{
|
||||
if(this->m_parent_element && this->m_parent_element->diagram())
|
||||
{
|
||||
QUndoCommand *undo = new QPropertyUndoCommand(this, "text", old_str, new_str);
|
||||
undo->setText(tr("Éditer un texte d'élément"));
|
||||
this->m_parent_element->diagram()->undoStack().push(undo);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
DynamicElementTextItem::~DynamicElementTextItem()
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::toXml
|
||||
* Export this text to xml
|
||||
* @param dom_doc
|
||||
* @return
|
||||
*/
|
||||
QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const
|
||||
{
|
||||
QDomElement root_element = dom_doc.createElement(xmlTaggName());
|
||||
|
||||
root_element.setAttribute("x", QString::number(pos().x()));
|
||||
root_element.setAttribute("y", QString::number(pos().y()));
|
||||
root_element.setAttribute("rotation", QString::number(QET::correctAngle(rotation())));
|
||||
root_element.setAttribute("font_size", font().pointSize());
|
||||
root_element.setAttribute("uuid", m_uuid.toString());
|
||||
|
||||
QMetaEnum me = metaObject()->enumerator(metaObject()->indexOfEnumerator("TextFrom"));
|
||||
root_element.setAttribute("text_from", me.valueToKey(m_text_from));
|
||||
|
||||
QDomElement dom_text = dom_doc.createElement("text");
|
||||
dom_text.appendChild(dom_doc.createTextNode(toPlainText()));
|
||||
root_element.appendChild(dom_text);
|
||||
|
||||
//tagg
|
||||
if (!m_tagg.isEmpty())
|
||||
{
|
||||
QDomElement dom_tagg = dom_doc.createElement("tagg");
|
||||
dom_tagg.appendChild(dom_doc.createTextNode(m_tagg));
|
||||
root_element.appendChild(dom_tagg);
|
||||
}
|
||||
|
||||
//Color
|
||||
if(color() != QColor(Qt::black))
|
||||
{
|
||||
QDomElement dom_color = dom_doc.createElement("color");
|
||||
dom_color.appendChild(dom_doc.createTextNode(color().name()));
|
||||
root_element.appendChild(dom_color);
|
||||
}
|
||||
|
||||
return root_element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::fromXml
|
||||
* Import this text from xml
|
||||
* @param dom_elmt
|
||||
*/
|
||||
void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt)
|
||||
{
|
||||
if (dom_elmt.tagName() != xmlTaggName()) {
|
||||
qDebug() << "DynamicElementTextItem::fromXml : Wrong tagg name";
|
||||
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()));
|
||||
|
||||
QMetaEnum me = metaObject()->enumerator(metaObject()->indexOfEnumerator("TextFrom"));
|
||||
m_text_from = DynamicElementTextItem::TextFrom(me.keyToValue(dom_elmt.attribute("text_from").toStdString().data()));
|
||||
setNoEditable(m_text_from == ElementInfo? true : false);
|
||||
|
||||
//Text
|
||||
QDomElement dom_text = dom_elmt.firstChildElement("text");
|
||||
if (!dom_text.isNull())
|
||||
setPlainText(dom_text.text());
|
||||
|
||||
//tagg
|
||||
QDomElement dom_tagg = dom_elmt.firstChildElement("tagg");
|
||||
if (!dom_tagg.isNull())
|
||||
m_tagg = dom_tagg.text();
|
||||
|
||||
//Color
|
||||
QDomElement dom_color = dom_elmt.firstChildElement("color");
|
||||
if(!dom_color.isNull())
|
||||
setColor(QColor(dom_color.text()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::ParentElement
|
||||
* @return a pointer to the parent element. Note the pointer can be null.
|
||||
*/
|
||||
Element *DynamicElementTextItem::ParentElement() const {
|
||||
return m_parent_element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::textFrom
|
||||
* @return what the final text is created from.
|
||||
*/
|
||||
DynamicElementTextItem::TextFrom DynamicElementTextItem::textFrom() const {
|
||||
return m_text_from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::setTextFrom
|
||||
* Set the final text is created from.
|
||||
* @param text_from
|
||||
*/
|
||||
void DynamicElementTextItem::setTextFrom(DynamicElementTextItem::TextFrom text_from)
|
||||
{
|
||||
m_text_from = text_from;
|
||||
setNoEditable(m_text_from == ElementInfo? true : false);
|
||||
emit TextFromChanged(m_text_from);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::tagg
|
||||
* @return the tagg of this text
|
||||
*/
|
||||
QString DynamicElementTextItem::tagg() const {
|
||||
return m_tagg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::setTagg
|
||||
* set the taggof this text
|
||||
* @param tagg
|
||||
*/
|
||||
void DynamicElementTextItem::setTagg(const QString &tagg)
|
||||
{
|
||||
m_tagg = tagg;
|
||||
emit taggChanged(m_tagg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::text
|
||||
* @return the text of this text
|
||||
*/
|
||||
QString DynamicElementTextItem::text() const {
|
||||
return m_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::setText
|
||||
* Set the text of this text
|
||||
* @param formula
|
||||
*/
|
||||
void DynamicElementTextItem::setText(const QString &text)
|
||||
{
|
||||
m_text = text;
|
||||
setPlainText(m_text);
|
||||
emit textChanged(m_text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::mouseMoveEvent
|
||||
* @param event
|
||||
*/
|
||||
void DynamicElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if(event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
QPointF old_pos = pos(); //The old pos
|
||||
QPointF movement = event->pos() - event->buttonDownPos(Qt::LeftButton); //The movement since the button down pos
|
||||
QPointF new_pos = pos() + mapMovementToParent(movement); //The new pos with this event
|
||||
event->modifiers() == Qt::ControlModifier ? setPos(new_pos) : setPos(Diagram::snapToGrid(new_pos));
|
||||
|
||||
if(m_parent_element && m_parent_element->diagram())
|
||||
{
|
||||
Diagram *diagram = m_parent_element->diagram();
|
||||
|
||||
if(m_first_move)
|
||||
{
|
||||
if(diagram->beginMoveElementTexts(this) == 1)
|
||||
m_parent_element->setHighlighted(true);
|
||||
}
|
||||
|
||||
//Because setPos() can be snaped to grid or not, we calcule the real movement
|
||||
QPointF effective_movement = pos() - old_pos;
|
||||
QPointF scene_effective_movement = mapMovementToScene(mapMovementFromParent(effective_movement));
|
||||
diagram->continueMoveElementTexts(scene_effective_movement);
|
||||
}
|
||||
}
|
||||
else
|
||||
event->ignore();
|
||||
|
||||
if(m_first_move)
|
||||
m_first_move = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItem::mouseReleaseEvent
|
||||
* @param event
|
||||
*/
|
||||
void DynamicElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_parent_element)
|
||||
m_parent_element->setHighlighted(false);
|
||||
|
||||
if(m_parent_element && m_parent_element->diagram())
|
||||
m_parent_element->diagram()->endMoveElementTexts();
|
||||
|
||||
if(!(event->modifiers() & Qt::ControlModifier))
|
||||
QGraphicsTextItem::mouseReleaseEvent(event);
|
||||
}
|
||||
|
87
sources/qetgraphicsitem/dynamicelementtextitem.h
Normal file
87
sources/qetgraphicsitem/dynamicelementtextitem.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DYNAMICELEMENTTEXTITEM_H
|
||||
#define DYNAMICELEMENTTEXTITEM_H
|
||||
|
||||
#include "diagramtextitem.h"
|
||||
#include <QUuid>
|
||||
|
||||
class Element;
|
||||
|
||||
/**
|
||||
* @brief The DynamicElementTextItem class
|
||||
* This class provide a simple text field of element who can be added or removed directly from the diagram editor.
|
||||
* This text is created to compensate a big lack of the ElementTextItem : ElementTextItem can't be added or removed directly in the diagram editor
|
||||
*
|
||||
*/
|
||||
class DynamicElementTextItem : public DiagramTextItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString tagg READ tagg WRITE setTagg NOTIFY taggChanged)
|
||||
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
||||
Q_PROPERTY(TextFrom textFrom READ textFrom WRITE setTextFrom NOTIFY TextFromChanged)
|
||||
|
||||
public:
|
||||
Q_ENUMS(TextFrom)
|
||||
enum TextFrom {
|
||||
UserText,
|
||||
ElementInfo
|
||||
};
|
||||
enum {Type = UserType + 1010};
|
||||
virtual int type() const override {return Type;}
|
||||
|
||||
signals:
|
||||
void taggChanged(QString tagg);
|
||||
void textChanged(QString text);
|
||||
void TextFromChanged(DynamicElementTextItem::TextFrom text_from);
|
||||
|
||||
public:
|
||||
DynamicElementTextItem(Element *parent_element);
|
||||
virtual ~DynamicElementTextItem() override;
|
||||
private:
|
||||
DynamicElementTextItem(const DynamicElementTextItem &);
|
||||
|
||||
public:
|
||||
virtual QDomElement toXml(QDomDocument &dom_doc) const override;
|
||||
virtual void fromXml(const QDomElement &dom_elmt) override;
|
||||
|
||||
Element *ParentElement() const;
|
||||
|
||||
DynamicElementTextItem::TextFrom textFrom() const;
|
||||
void setTextFrom (DynamicElementTextItem::TextFrom text_from);
|
||||
QString tagg() const;
|
||||
void setTagg(const QString &tagg);
|
||||
QString text() const;
|
||||
void setText(const QString &text);
|
||||
static QString xmlTaggName() {return QString("dynamic_elmt_text");}
|
||||
|
||||
protected:
|
||||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
Element *m_parent_element = nullptr;
|
||||
QString m_tagg,
|
||||
m_text,
|
||||
m_elmt_info_name;
|
||||
DynamicElementTextItem::TextFrom m_text_from = UserText;
|
||||
QUuid m_uuid;
|
||||
};
|
||||
|
||||
#endif // DYNAMICELEMENTTEXTITEM_H
|
@ -29,6 +29,7 @@
|
||||
#include "numerotationcontextcommands.h"
|
||||
#include "diagramcontext.h"
|
||||
#include "changeelementinformationcommand.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
|
||||
class ElementXmlRetroCompatibility
|
||||
{
|
||||
@ -77,7 +78,9 @@ Element::Element(QGraphicsItem *parent) :
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
Element::~Element() {
|
||||
Element::~Element()
|
||||
{
|
||||
qDeleteAll(m_dynamic_text_list);
|
||||
}
|
||||
|
||||
void Element::editProperty()
|
||||
@ -529,6 +532,15 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool
|
||||
} else {
|
||||
applyRotation(90*read_ori);
|
||||
}
|
||||
|
||||
//Dynamic texts
|
||||
for (QDomElement qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTaggName()))
|
||||
{
|
||||
DynamicElementTextItem *deti = new DynamicElementTextItem(this);
|
||||
addDynamicTextItem(deti);
|
||||
deti->fromXml(qde);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
@ -615,9 +627,54 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
|
||||
element.appendChild(infos);
|
||||
}
|
||||
|
||||
//Dynamic texts
|
||||
QDomElement dyn_text = document.createElement("dynamic_texts");
|
||||
for (DynamicElementTextItem *deti : m_dynamic_text_list)
|
||||
dyn_text.appendChild(deti->toXml(document));
|
||||
element.appendChild(dyn_text);
|
||||
|
||||
return(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Element::addDynamiqueTextItem
|
||||
* Add @deti as a dynamic text item of this element
|
||||
* If @deti is null, a new DynamicElementTextItem is created and added to this element.
|
||||
* @param deti
|
||||
*/
|
||||
void Element::addDynamicTextItem(DynamicElementTextItem *deti)
|
||||
{
|
||||
if (deti && !m_dynamic_text_list.contains(deti))
|
||||
{
|
||||
m_dynamic_text_list.append(deti);
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicElementTextItem *text = new DynamicElementTextItem(this);
|
||||
m_dynamic_text_list.append(text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Element::removeDynamicTextItem
|
||||
* Remove @deti as dynamic text item of this element.
|
||||
* The parent item of deti stay this item.
|
||||
* @param deti
|
||||
*/
|
||||
void Element::removeDynamicTextItem(DynamicElementTextItem *deti)
|
||||
{
|
||||
if (m_dynamic_text_list.contains(deti))
|
||||
m_dynamic_text_list.removeOne(deti);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Element::dynamicTextItems
|
||||
* @return all dynamic text items of this element
|
||||
*/
|
||||
QList<DynamicElementTextItem *> Element::dynamicTextItems() const {
|
||||
return m_dynamic_text_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Element::AlignedFreeTerminals
|
||||
* @return a list of terminal (owned by this element) aligned to other terminal (from other element)
|
||||
|
@ -30,6 +30,7 @@ class Terminal;
|
||||
class Conductor;
|
||||
class NumerotationContext;
|
||||
class DiagramTextItem;
|
||||
class DynamicElementTextItem;
|
||||
|
||||
/**
|
||||
This is the base class for electrical elements.
|
||||
@ -158,9 +159,6 @@ class Element : public QetGraphicsItem
|
||||
bool m_freeze_label = false;
|
||||
QString m_F_str;
|
||||
|
||||
/**
|
||||
Draw this element
|
||||
*/
|
||||
public:
|
||||
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
|
||||
/// @return This element type ID
|
||||
@ -197,6 +195,10 @@ class Element : public QetGraphicsItem
|
||||
// orientation-related methods
|
||||
int orientation() const;
|
||||
|
||||
void addDynamicTextItem(DynamicElementTextItem *deti = nullptr);
|
||||
void removeDynamicTextItem(DynamicElementTextItem *deti);
|
||||
QList<DynamicElementTextItem *> dynamicTextItems() const;
|
||||
|
||||
protected:
|
||||
void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
|
||||
|
||||
@ -216,6 +218,7 @@ class Element : public QetGraphicsItem
|
||||
private:
|
||||
bool m_mouse_over;
|
||||
QString m_prefix;
|
||||
QList <DynamicElementTextItem *> m_dynamic_text_list;
|
||||
|
||||
};
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "imagepropertieswidget.h"
|
||||
#include "qetshapeitem.h"
|
||||
#include "shapegraphicsitempropertieswidget.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
|
||||
/**
|
||||
* @brief DiagramPropertiesEditorDockWidget::DiagramPropertiesEditorDockWidget
|
||||
@ -56,7 +57,7 @@ void DiagramPropertiesEditorDockWidget::setDiagram(Diagram *diagram)
|
||||
if (diagram)
|
||||
{
|
||||
m_diagram = diagram;
|
||||
connect(m_diagram, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
|
||||
connect(m_diagram, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()), Qt::QueuedConnection);
|
||||
connect(m_diagram, SIGNAL(destroyed()), this, SLOT(diagramWasDeleted()));
|
||||
selectionChanged();
|
||||
}
|
||||
@ -120,6 +121,22 @@ void DiagramPropertiesEditorDockWidget::selectionChanged()
|
||||
addEditor(new ShapeGraphicsItemPropertiesWidget(static_cast<QetShapeItem*>(item), this));
|
||||
break; }
|
||||
|
||||
case DynamicElementTextItem::Type: {
|
||||
DynamicElementTextItem *deti = static_cast<DynamicElementTextItem *>(item);
|
||||
|
||||
//For dynamic element text, we open the element editor
|
||||
//We already edit an element, just update the editor with a new element
|
||||
if (m_edited_qgi_type == Element::Type)
|
||||
{
|
||||
static_cast<ElementPropertiesWidget*>(editors().first())->setElement(deti->ParentElement());
|
||||
return;
|
||||
}
|
||||
|
||||
clear();
|
||||
m_edited_qgi_type = Element::Type;
|
||||
addEditor(new ElementPropertiesWidget(deti->ParentElement(), this));
|
||||
break; }
|
||||
|
||||
default:
|
||||
m_edited_qgi_type = -1;
|
||||
clear();
|
||||
|
152
sources/ui/dynamicelementtextitemeditor.cpp
Normal file
152
sources/ui/dynamicelementtextitemeditor.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "dynamicelementtextitemeditor.h"
|
||||
#include "ui_dynamicelementtextitemeditor.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include "element.h"
|
||||
#include "dynamicelementtextmodel.h"
|
||||
#include "diagram.h"
|
||||
#include "undocommand/deleteqgraphicsitemcommand.h"
|
||||
#include "undocommand/addelementtextcommand.h"
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QUndoCommand>
|
||||
|
||||
DynamicElementTextItemEditor::DynamicElementTextItemEditor(Element *element, QWidget *parent) :
|
||||
AbstractElementPropertiesEditorWidget(parent),
|
||||
ui(new Ui::DynamicElementTextItemEditor)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
m_tree_view = new QTreeView(this);
|
||||
m_tree_view->header()->setDefaultSectionSize(150);
|
||||
m_tree_view->setItemDelegate(new DynamicTextItemDelegate(m_tree_view));
|
||||
m_tree_view->setAlternatingRowColors(true);
|
||||
ui->verticalLayout->addWidget(m_tree_view);
|
||||
setElement(element);
|
||||
}
|
||||
|
||||
DynamicElementTextItemEditor::~DynamicElementTextItemEditor()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DynamicElementTextItemEditor::setElement(Element *element)
|
||||
{
|
||||
if (m_element == element)
|
||||
return;
|
||||
|
||||
m_element = element;
|
||||
|
||||
DynamicElementTextModel *old_model = m_model;
|
||||
m_model = new DynamicElementTextModel(m_tree_view);
|
||||
connect(m_model, &DynamicElementTextModel::itemChanged, this, &DynamicElementTextItemEditor::dataEdited);
|
||||
|
||||
for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
|
||||
m_model->addText(deti);
|
||||
|
||||
m_tree_view->setModel(m_model);
|
||||
|
||||
if(old_model)
|
||||
delete old_model;
|
||||
}
|
||||
|
||||
bool DynamicElementTextItemEditor::setLiveEdit(bool live_edit)
|
||||
{
|
||||
m_live_edit = live_edit;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DynamicElementTextItemEditor::apply()
|
||||
{
|
||||
QList <QUndoCommand *> undo_list;
|
||||
for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
|
||||
{
|
||||
QUndoCommand *undo = m_model->undoForEditedText(deti);
|
||||
if(undo->childCount())
|
||||
undo_list << undo;
|
||||
else
|
||||
delete undo;
|
||||
}
|
||||
|
||||
for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
|
||||
deti->blockSignals(true);
|
||||
|
||||
if(!undo_list.isEmpty() && m_element->diagram())
|
||||
{
|
||||
if (undo_list.size() == 1)
|
||||
m_element->diagram()->undoStack().push(undo_list.first());
|
||||
else
|
||||
{
|
||||
QUndoStack &us = m_element->diagram()->undoStack();
|
||||
us.beginMacro(tr("Modifier des texte d'élément"));
|
||||
for (QUndoCommand *quc : undo_list)
|
||||
us.push(quc);
|
||||
us.endMacro();
|
||||
}
|
||||
}
|
||||
|
||||
for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
|
||||
deti->blockSignals(false);
|
||||
}
|
||||
|
||||
void DynamicElementTextItemEditor::dataEdited(QStandardItem *qsi)
|
||||
{
|
||||
Q_UNUSED(qsi)
|
||||
if (m_live_edit)
|
||||
apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItemEditor::on_m_add_text_clicked
|
||||
* Add a new dynamic text
|
||||
*/
|
||||
void DynamicElementTextItemEditor::on_m_add_text_clicked()
|
||||
{
|
||||
if (!m_element)
|
||||
return;
|
||||
|
||||
DynamicElementTextItem *deti = new DynamicElementTextItem(m_element);
|
||||
if (m_element->diagram())
|
||||
{
|
||||
m_element->diagram()->undoStack().push(new AddElementTextCommand(m_element, deti));
|
||||
m_model->addText(deti);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete deti;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextItemEditor::on_m_remove_text_clicked
|
||||
* Remove the selected text field
|
||||
*/
|
||||
void DynamicElementTextItemEditor::on_m_remove_text_clicked()
|
||||
{
|
||||
DynamicElementTextItem *deti = m_model->textFromIndex(m_tree_view->currentIndex());
|
||||
if(deti)
|
||||
{
|
||||
if(m_element->diagram())
|
||||
{
|
||||
DiagramContent dc;
|
||||
dc.m_element_texts << deti;
|
||||
m_element->diagram()->undoStack().push(new DeleteQGraphicsItemCommand(m_element->diagram(), dc));
|
||||
m_model->removeText(deti);
|
||||
}
|
||||
}
|
||||
}
|
59
sources/ui/dynamicelementtextitemeditor.h
Normal file
59
sources/ui/dynamicelementtextitemeditor.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DYNAMICELEMENTTEXTITEMEDITOR_H
|
||||
#define DYNAMICELEMENTTEXTITEMEDITOR_H
|
||||
|
||||
#include "abstractelementpropertieseditorwidget.h"
|
||||
|
||||
class DynamicElementTextItem;
|
||||
class DynamicElementTextModel;
|
||||
class QTreeView;
|
||||
class QStandardItem;
|
||||
|
||||
namespace Ui {
|
||||
class DynamicElementTextItemEditor;
|
||||
}
|
||||
|
||||
class DynamicElementTextItemEditor : public AbstractElementPropertiesEditorWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DynamicElementTextItemEditor(Element *element, QWidget *parent = 0);
|
||||
~DynamicElementTextItemEditor();
|
||||
|
||||
virtual void setElement(Element *element);
|
||||
virtual QString title() const {return tr("Textes");}
|
||||
virtual bool setLiveEdit(bool live_edit);
|
||||
virtual void apply();
|
||||
|
||||
private:
|
||||
void dataEdited(QStandardItem *qsi);
|
||||
|
||||
private slots:
|
||||
void on_m_add_text_clicked();
|
||||
void on_m_remove_text_clicked();
|
||||
|
||||
private:
|
||||
Ui::DynamicElementTextItemEditor *ui;
|
||||
QTreeView *m_tree_view = nullptr;
|
||||
DynamicElementTextModel *m_model = nullptr;
|
||||
|
||||
};
|
||||
|
||||
#endif // DYNAMICELEMENTTEXTITEMEDITOR_H
|
62
sources/ui/dynamicelementtextitemeditor.ui
Normal file
62
sources/ui/dynamicelementtextitemeditor.ui
Normal file
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DynamicElementTextItemEditor</class>
|
||||
<widget class="QWidget" name="DynamicElementTextItemEditor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_add_text">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_remove_text">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/16x16/list-remove.png</normaloff>:/ico/16x16/list-remove.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../qelectrotech.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
407
sources/ui/dynamicelementtextmodel.cpp
Normal file
407
sources/ui/dynamicelementtextmodel.cpp
Normal file
@ -0,0 +1,407 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "dynamicelementtextmodel.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include <QStandardItem>
|
||||
#include <QHash>
|
||||
#include <QColorDialog>
|
||||
#include <QModelIndex>
|
||||
#include <QComboBox>
|
||||
#include <QUndoCommand>
|
||||
#include "QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
|
||||
DynamicElementTextModel::DynamicElementTextModel(QObject *parent) :
|
||||
QStandardItemModel(parent)
|
||||
{
|
||||
setColumnCount(2);
|
||||
setHeaderData(0, Qt::Horizontal, tr("Propriété"), Qt::DisplayRole);
|
||||
setHeaderData(1, Qt::Horizontal, tr("Valeur"), Qt::DisplayRole);
|
||||
|
||||
connect(this, &DynamicElementTextModel::itemChanged, this, &DynamicElementTextModel::dataEdited);
|
||||
}
|
||||
|
||||
DynamicElementTextModel::~DynamicElementTextModel()
|
||||
{
|
||||
//Connection is not destroy automaticaly,
|
||||
//because was not connected to a slot, but a lambda
|
||||
for(DynamicElementTextItem *deti : m_hash_text_connect.keys())
|
||||
setConnection(deti, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextModel::addText
|
||||
* @param deti
|
||||
*/
|
||||
void DynamicElementTextModel::addText(DynamicElementTextItem *deti)
|
||||
{
|
||||
if(m_texts_list.keys().contains(deti))
|
||||
return;
|
||||
|
||||
QList <QStandardItem *> qsi_list;
|
||||
|
||||
QStandardItem *qsi = new QStandardItem(deti->toPlainText());
|
||||
qsi->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
|
||||
//Source of text
|
||||
QStandardItem *src = new QStandardItem(tr("Source du texte"));
|
||||
src->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
QStandardItem *srca = new QStandardItem(deti->textFrom() == DynamicElementTextItem::UserText ? tr("Texte utilisateur") : tr("Information de l'élément"));
|
||||
srca->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
||||
srca->setData(textFrom, Qt::UserRole+1);
|
||||
|
||||
qsi_list << src << srca;
|
||||
qsi->appendRow(qsi_list);
|
||||
|
||||
//User text
|
||||
QStandardItem *usr = new QStandardItem(tr("Texte"));
|
||||
usr->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
QStandardItem *usra = new QStandardItem(deti->toPlainText());
|
||||
usra->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
||||
usra->setData(DynamicElementTextModel::userText, Qt::UserRole+1);
|
||||
|
||||
qsi_list.clear();
|
||||
qsi_list << usr << usra;
|
||||
src->appendRow(qsi_list);
|
||||
|
||||
//Info text
|
||||
QStandardItem *info = new QStandardItem(tr("Information"));
|
||||
info->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
QStandardItem *infoa = new QStandardItem(deti->toPlainText());
|
||||
infoa->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
||||
infoa->setData(DynamicElementTextModel::infoText, Qt::UserRole+1);
|
||||
|
||||
qsi_list.clear();
|
||||
qsi_list << info << infoa;
|
||||
src->appendRow(qsi_list);
|
||||
|
||||
|
||||
//Size
|
||||
QStandardItem *size = new QStandardItem(tr("Taille"));
|
||||
size->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
QStandardItem *siza = new QStandardItem();
|
||||
siza->setData(deti->fontSize(), Qt::EditRole);
|
||||
siza->setData(DynamicElementTextModel::size, Qt::UserRole+1);
|
||||
siza->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
||||
|
||||
qsi_list.clear();
|
||||
qsi_list << size << siza;
|
||||
qsi->appendRow(qsi_list);
|
||||
|
||||
//Tagg
|
||||
QStandardItem *tagg = new QStandardItem(tr("Tagg"));
|
||||
tagg->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
QStandardItem *tagga = new QStandardItem(deti->tagg());
|
||||
tagga->setData(DynamicElementTextModel::tagg, Qt::UserRole+1);
|
||||
tagga->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
||||
|
||||
qsi_list.clear();
|
||||
qsi_list << tagg << tagga;
|
||||
qsi->appendRow(qsi_list);
|
||||
|
||||
//Color
|
||||
QStandardItem *color = new QStandardItem(tr("Couleur"));
|
||||
color->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
QStandardItem *colora = new QStandardItem;
|
||||
colora->setData(deti->color(), Qt::ForegroundRole);
|
||||
colora->setData(deti->color(), Qt::EditRole);
|
||||
colora->setData(DynamicElementTextModel::color, Qt::UserRole+1);
|
||||
colora->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
||||
|
||||
qsi_list.clear();
|
||||
qsi_list << color << colora;
|
||||
qsi->appendRow(qsi_list);
|
||||
|
||||
qsi_list.clear();
|
||||
QStandardItem *empty_qsi = new QStandardItem(0);
|
||||
empty_qsi->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
qsi_list << qsi << empty_qsi;
|
||||
this->appendRow(qsi_list);
|
||||
|
||||
m_texts_list.insert(deti, qsi);
|
||||
blockSignals(true);
|
||||
enableSourceText(deti, deti->textFrom());
|
||||
blockSignals(false);
|
||||
setConnection(deti, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextModel::removeText
|
||||
* @param deti
|
||||
*/
|
||||
void DynamicElementTextModel::removeText(DynamicElementTextItem *deti)
|
||||
{
|
||||
if (!m_texts_list.contains(deti))
|
||||
return;
|
||||
|
||||
QModelIndex text_index = m_texts_list.value(deti)->index();
|
||||
this->removeRow(text_index.row(), text_index.parent());
|
||||
m_texts_list.remove(deti);
|
||||
setConnection(deti, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextModel::textFromIndex
|
||||
* @param index
|
||||
* @return the text associated with @index. Return value can be nullptr
|
||||
* @Index can be a child of an index associated with a text
|
||||
*/
|
||||
DynamicElementTextItem *DynamicElementTextModel::textFromIndex(const QModelIndex &index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return nullptr;
|
||||
|
||||
if (QStandardItem *item = itemFromIndex(index))
|
||||
return textFromItem(item);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextModel::textFromItem
|
||||
* @param item
|
||||
* @return the text associated with @item. Return value can be nullptr
|
||||
* @item can be a child of an item associated with a text
|
||||
*/
|
||||
DynamicElementTextItem *DynamicElementTextModel::textFromItem(QStandardItem *item) const
|
||||
{
|
||||
QStandardItem *text_item = item;
|
||||
while (text_item->parent())
|
||||
text_item = text_item->parent();
|
||||
|
||||
if (m_texts_list.values().contains(text_item))
|
||||
return m_texts_list.key(text_item);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextModel::undoForEditedText
|
||||
* @param deti
|
||||
* @return A QUndoCommand that describe all changes made for @deti.
|
||||
* Each change made for @deti is append as a child of the returned QUndoCommand.
|
||||
* In other word, if the returned QUndoCommand have no child, that mean there is no change.
|
||||
*/
|
||||
QUndoCommand *DynamicElementTextModel::undoForEditedText(DynamicElementTextItem *deti) const
|
||||
{
|
||||
QUndoCommand *undo = new QUndoCommand(tr("Éditer un texte d'élément"));
|
||||
|
||||
if (!m_texts_list.contains(deti))
|
||||
return undo;
|
||||
|
||||
QStandardItem *text_qsi = m_texts_list.value(deti);
|
||||
|
||||
QString from = text_qsi->child(0,1)->data(Qt::DisplayRole).toString();
|
||||
if ((from == tr("Texte utilisateur")) && (deti->textFrom() != DynamicElementTextItem::UserText))
|
||||
new QPropertyUndoCommand(deti, "textFrom", QVariant(deti->textFrom()), QVariant(DynamicElementTextItem::UserText), undo);
|
||||
else if ((from == tr("Information de l'élément")) && (deti->textFrom() != DynamicElementTextItem::ElementInfo))
|
||||
new QPropertyUndoCommand(deti, "textFrom", QVariant(deti->textFrom()), QVariant(DynamicElementTextItem::ElementInfo), undo);
|
||||
|
||||
QString text = text_qsi->child(0,0)->child(0,1)->data(Qt::DisplayRole).toString();
|
||||
if (text != deti->text())
|
||||
new QPropertyUndoCommand(deti, "text", QVariant(deti->text()), QVariant(text), undo);
|
||||
|
||||
int fs = text_qsi->child(1,1)->data(Qt::EditRole).toInt();
|
||||
if (fs != deti->fontSize())
|
||||
new QPropertyUndoCommand(deti, "fontSize", QVariant(deti->fontSize()), QVariant(fs), undo);
|
||||
|
||||
QString tagg = text_qsi->child(2,1)->data(Qt::DisplayRole).toString();
|
||||
if(tagg != deti->tagg())
|
||||
new QPropertyUndoCommand(deti, "tagg", QVariant(deti->tagg()), QVariant(tagg), undo);
|
||||
|
||||
QColor color = text_qsi->child(3,1)->data(Qt::EditRole).value<QColor>();
|
||||
if(color != deti->color())
|
||||
new QPropertyUndoCommand(deti, "color", QVariant(deti->color()), QVariant(color), undo);
|
||||
|
||||
return undo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextModel::enableSourceText
|
||||
* Enable the good field, according to the current source of text, for the edited text @deti
|
||||
* @param deti
|
||||
* @param tf
|
||||
*/
|
||||
void DynamicElementTextModel::enableSourceText(DynamicElementTextItem *deti, DynamicElementTextItem::TextFrom tf)
|
||||
{
|
||||
if (!m_texts_list.contains(deti))
|
||||
return;
|
||||
|
||||
QStandardItem *qsi = m_texts_list.value(deti)->child(0,0);
|
||||
|
||||
bool usr = true, info = false;
|
||||
if(tf == DynamicElementTextItem::ElementInfo) {
|
||||
usr = false; info = true;}
|
||||
|
||||
//User text
|
||||
qsi->child(0,0)->setEnabled(usr);
|
||||
qsi->child(0,1)->setEnabled(usr);
|
||||
//Info text
|
||||
qsi->child(1,0)->setEnabled(info);
|
||||
qsi->child(1,1)->setEnabled(info);
|
||||
}
|
||||
|
||||
void DynamicElementTextModel::dataEdited(QStandardItem *qsi)
|
||||
{
|
||||
DynamicElementTextItem *deti = textFromItem(qsi);
|
||||
if (!deti)
|
||||
return;
|
||||
|
||||
if (qsi->data().toInt() == textFrom)
|
||||
{
|
||||
QString from = qsi->data(Qt::DisplayRole).toString();
|
||||
if (from == tr("Texte utilisateur"))
|
||||
enableSourceText(deti, DynamicElementTextItem::UserText);
|
||||
else
|
||||
enableSourceText(deti, DynamicElementTextItem::ElementInfo);
|
||||
}
|
||||
else if (qsi->data().toInt() == userText)
|
||||
{
|
||||
QString text = qsi->data(Qt::DisplayRole).toString();
|
||||
m_texts_list.value(deti)->setData(text, Qt::DisplayRole);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DynamicElementTextModel::setConnection
|
||||
* Set up the connection for @deti to keep up to date the data of this model and the text.
|
||||
* Is notably use with the use of QUndoCommand.
|
||||
* @param deti - text to setup connection
|
||||
* @param set - true = set connection - false unset connection
|
||||
*/
|
||||
void DynamicElementTextModel::setConnection(DynamicElementTextItem *deti, bool set)
|
||||
{
|
||||
if(set)
|
||||
{
|
||||
if(m_hash_text_connect.keys().contains(deti))
|
||||
return;
|
||||
|
||||
QList<QMetaObject::Connection> connection_list;
|
||||
connection_list << connect(deti, &DynamicElementTextItem::colorChanged, [deti,this](){this->updateDataFromText(deti, color);});
|
||||
connection_list << connect(deti, &DynamicElementTextItem::fontSizeChanged, [deti,this](){this->updateDataFromText(deti, size);});
|
||||
connection_list << connect(deti, &DynamicElementTextItem::taggChanged, [deti,this](){this->updateDataFromText(deti, tagg);});
|
||||
connection_list << connect(deti, &DynamicElementTextItem::textChanged, [deti,this](){this->updateDataFromText(deti, userText);});
|
||||
connection_list << connect(deti, &DynamicElementTextItem::TextFromChanged, [deti,this](){this->updateDataFromText(deti, textFrom);});
|
||||
|
||||
m_hash_text_connect.insert(deti, connection_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!m_hash_text_connect.keys().contains(deti))
|
||||
return;
|
||||
|
||||
for (QMetaObject::Connection con : m_hash_text_connect.value(deti))
|
||||
disconnect(con);
|
||||
|
||||
m_hash_text_connect.remove(deti);
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicElementTextModel::updateDataFromText(DynamicElementTextItem *deti, ValueType type)
|
||||
{
|
||||
QStandardItem *qsi = m_texts_list.value(deti);
|
||||
if (!qsi)
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case textFrom:
|
||||
qsi->child(0,1)->setData(deti->textFrom() == DynamicElementTextItem::UserText ? tr("Texte utilisateur") : tr("Information de l'élément"), Qt::DisplayRole);
|
||||
break;
|
||||
case userText:
|
||||
{
|
||||
QStandardItem *qsia = qsi->child(0,0);
|
||||
qsia->child(0,1)->setData(deti->toPlainText(), Qt::DisplayRole);
|
||||
qsi->setData(deti->toPlainText(), Qt::DisplayRole);
|
||||
break;
|
||||
}
|
||||
case infoText:
|
||||
break;
|
||||
case size:
|
||||
qsi->child(1,1)->setData(deti->fontSize(), Qt::EditRole);
|
||||
break;
|
||||
case tagg:
|
||||
qsi->child(2,1)->setData(deti->tagg(), Qt::DisplayRole);
|
||||
break;
|
||||
case color:
|
||||
{
|
||||
qsi->child(3,1)->setData(deti->color(), Qt::EditRole);
|
||||
qsi->child(3,1)->setData(deti->color(), Qt::ForegroundRole);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* A little delegate only for add a combobox and a color dialog,
|
||||
* for use with the model
|
||||
***************************************************/
|
||||
|
||||
DynamicTextItemDelegate::DynamicTextItemDelegate(QObject *parent) :
|
||||
QStyledItemDelegate(parent)
|
||||
{}
|
||||
|
||||
QWidget *DynamicTextItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
switch (index.data(Qt::UserRole+1).toInt())
|
||||
{
|
||||
case DynamicElementTextModel::textFrom:
|
||||
{
|
||||
QComboBox *qcb = new QComboBox(parent);
|
||||
qcb->addItem(tr("Texte utilisateur"));
|
||||
qcb->addItem(tr("Information de l'élément"));
|
||||
return qcb;
|
||||
}
|
||||
case DynamicElementTextModel::color:
|
||||
{
|
||||
QColorDialog *cd = new QColorDialog(index.data(Qt::EditRole).value<QColor>());
|
||||
return cd;
|
||||
}
|
||||
}
|
||||
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||
}
|
||||
|
||||
void DynamicTextItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
if (QStandardItemModel *qsim = dynamic_cast<QStandardItemModel *>(model))
|
||||
{
|
||||
QStandardItem *qsi = qsim->itemFromIndex(index);
|
||||
if(qsi)
|
||||
{
|
||||
if(QColorDialog *cd = dynamic_cast<QColorDialog *> (editor))
|
||||
{
|
||||
qsi->setData(cd->selectedColor(), Qt::EditRole);
|
||||
qsi->setData(cd->selectedColor(), Qt::ForegroundRole);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
76
sources/ui/dynamicelementtextmodel.h
Normal file
76
sources/ui/dynamicelementtextmodel.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DYNAMICELEMENTTEXTMODEL_H
|
||||
#define DYNAMICELEMENTTEXTMODEL_H
|
||||
|
||||
#include <QStandardItemModel>
|
||||
#include <qstyleditemdelegate.h>
|
||||
#include "dynamicelementtextitem.h"
|
||||
|
||||
class QUndoCommand;
|
||||
|
||||
/**
|
||||
* @brief The DynamicElementTextModel class
|
||||
* A model to use with QtView.
|
||||
* This model display and can edit the value of dynamic text of an element.
|
||||
* Set the delegate DynamicTextItemDelegate as delegate of this model.
|
||||
*/
|
||||
class DynamicElementTextModel : public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum ValueType {
|
||||
textFrom =1,
|
||||
userText,
|
||||
infoText,
|
||||
size,
|
||||
tagg,
|
||||
color
|
||||
};
|
||||
|
||||
DynamicElementTextModel(QObject *parent = nullptr);
|
||||
~DynamicElementTextModel();
|
||||
|
||||
void addText(DynamicElementTextItem *deti);
|
||||
void removeText(DynamicElementTextItem *deti);
|
||||
DynamicElementTextItem *textFromIndex(const QModelIndex &index) const;
|
||||
DynamicElementTextItem *textFromItem(QStandardItem *item) const;
|
||||
QUndoCommand *undoForEditedText(DynamicElementTextItem *deti) const;
|
||||
|
||||
private:
|
||||
void enableSourceText(DynamicElementTextItem *deti, DynamicElementTextItem::TextFrom tf );
|
||||
void dataEdited(QStandardItem *qsi);
|
||||
void setConnection(DynamicElementTextItem *deti, bool set);
|
||||
void updateDataFromText(DynamicElementTextItem *deti, DynamicElementTextModel::ValueType type);
|
||||
|
||||
private:
|
||||
QHash <DynamicElementTextItem *, QStandardItem *> m_texts_list;
|
||||
QHash <DynamicElementTextItem *, QList<QMetaObject::Connection>> m_hash_text_connect;
|
||||
};
|
||||
|
||||
class DynamicTextItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
DynamicTextItemDelegate(QObject *parent = Q_NULLPTR);
|
||||
|
||||
virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
|
||||
};
|
||||
|
||||
#endif // DYNAMICELEMENTTEXTMODEL_H
|
@ -24,6 +24,7 @@
|
||||
#include "diagram.h"
|
||||
#include "diagramposition.h"
|
||||
#include "qeticons.h"
|
||||
#include "dynamicelementtextitemeditor.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
@ -203,9 +204,10 @@ void ElementPropertiesWidget::updateUi()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_list_editor << new DynamicElementTextItemEditor(m_element, this);
|
||||
|
||||
//Add each editors in tab widget
|
||||
foreach (AbstractElementPropertiesEditorWidget *aepew, m_list_editor)
|
||||
for (AbstractElementPropertiesEditorWidget *aepew : m_list_editor)
|
||||
{
|
||||
aepew->setLiveEdit(m_live_edit);
|
||||
m_tab->addTab(aepew, aepew->title());
|
||||
|
83
sources/undocommand/addelementtextcommand.cpp
Normal file
83
sources/undocommand/addelementtextcommand.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "addelementtextcommand.h"
|
||||
#include "element.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include <QGraphicsScene>
|
||||
|
||||
AddElementTextCommand::AddElementTextCommand(Element *element, DynamicElementTextItem *deti, QUndoCommand *parent):
|
||||
QUndoCommand(parent),
|
||||
m_element(element),
|
||||
m_text(deti)
|
||||
{
|
||||
setText(QObject::tr("Ajouter un texte d'élément"));
|
||||
}
|
||||
|
||||
AddElementTextCommand::~AddElementTextCommand()
|
||||
{
|
||||
if(!m_element->dynamicTextItems().contains(m_text))
|
||||
delete m_text;
|
||||
}
|
||||
|
||||
void AddElementTextCommand::undo()
|
||||
{
|
||||
m_element->removeDynamicTextItem(m_text);
|
||||
m_text->setParentItem(nullptr);
|
||||
if(m_text->scene())
|
||||
m_text->scene()->removeItem(m_text);
|
||||
}
|
||||
|
||||
void AddElementTextCommand::redo()
|
||||
{
|
||||
m_text->setParentItem(m_element);
|
||||
m_element->addDynamicTextItem(m_text);
|
||||
}
|
||||
|
||||
//RemoveElementTextCommand::RemoveElementTextCommand(DynamicElementTextItem *deti, QUndoCommand *parent) :
|
||||
// QUndoCommand(parent),
|
||||
// m_text(deti)
|
||||
//{
|
||||
// setText(QObject::tr("Supprimer un texte d'élément"));
|
||||
// m_element = deti->ParentElement();
|
||||
//}
|
||||
|
||||
//RemoveElementTextCommand::~RemoveElementTextCommand()
|
||||
//{
|
||||
// if(m_element && !m_element->dynamicTextItems().contains(m_text))
|
||||
// delete m_text;
|
||||
//}
|
||||
|
||||
//void RemoveElementTextCommand::undo()
|
||||
//{
|
||||
// if(m_element)
|
||||
// {
|
||||
// m_text->setParentItem(m_element);
|
||||
// m_element->addDynamicTextItem(m_text);
|
||||
// }
|
||||
//}
|
||||
|
||||
//void RemoveElementTextCommand::redo()
|
||||
//{
|
||||
// if(m_element && m_text->scene())
|
||||
// {
|
||||
|
||||
// m_element->removeDynamicTextItem(m_text);
|
||||
// m_text->setParentItem(nullptr);
|
||||
// m_text->scene()->removeItem(m_text);
|
||||
// }
|
||||
//}
|
54
sources/undocommand/addelementtextcommand.h
Normal file
54
sources/undocommand/addelementtextcommand.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ADDELEMENTTEXTCOMMAND_H
|
||||
#define ADDELEMENTTEXTCOMMAND_H
|
||||
|
||||
#include <QUndoCommand>
|
||||
|
||||
class Element;
|
||||
class DynamicElementTextItem;
|
||||
|
||||
class AddElementTextCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
AddElementTextCommand(Element *element, DynamicElementTextItem *deti, QUndoCommand *parent = nullptr);
|
||||
virtual ~AddElementTextCommand();
|
||||
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
private:
|
||||
Element *m_element = nullptr;
|
||||
DynamicElementTextItem *m_text = nullptr;
|
||||
};
|
||||
|
||||
//class RemoveElementTextCommand : public QUndoCommand
|
||||
//{
|
||||
// public:
|
||||
// RemoveElementTextCommand(DynamicElementTextItem *deti, QUndoCommand *parent = nullptr);
|
||||
// virtual ~RemoveElementTextCommand();
|
||||
|
||||
// virtual void undo();
|
||||
// virtual void redo();
|
||||
|
||||
// private:
|
||||
// Element *m_element = nullptr;
|
||||
// DynamicElementTextItem *m_text = nullptr;
|
||||
//};
|
||||
|
||||
#endif // ADDELEMENTTEXTCOMMAND_H
|
119
sources/undocommand/deleteqgraphicsitemcommand.cpp
Normal file
119
sources/undocommand/deleteqgraphicsitemcommand.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "deleteqgraphicsitemcommand.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include "diagram.h"
|
||||
#include "element.h"
|
||||
#include "conductor.h"
|
||||
#include "conductortextitem.h"
|
||||
|
||||
/**
|
||||
* @brief DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand
|
||||
* @param diagram : deigram where this undo work
|
||||
* @param content : content to remove
|
||||
* @param parent : parent undo
|
||||
*/
|
||||
DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
m_removed_contents(content),
|
||||
m_diagram(diagram)
|
||||
{
|
||||
//If parent element of a dynamic element text item is also in @m_removed_content,
|
||||
//we remove it, because when the element will be removed from the scene every child's will also be removed.
|
||||
const QSet<DynamicElementTextItem *> elmt_set = m_removed_contents.m_element_texts;
|
||||
for(DynamicElementTextItem *deti : elmt_set)
|
||||
{
|
||||
if (m_removed_contents.m_elements.contains(deti->ParentElement()))
|
||||
m_removed_contents.m_element_texts.remove(deti);
|
||||
|
||||
}
|
||||
|
||||
for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
|
||||
m_elmt_text_hash.insert(deti, deti->ParentElement());
|
||||
|
||||
setText(QString(QObject::tr("supprimer %1", "undo caption - %1 is a sentence listing the removed content")).arg(m_removed_contents.sentence(DiagramContent::All)));
|
||||
m_diagram->qgiManager().manage(m_removed_contents.items(DiagramContent::All));
|
||||
}
|
||||
|
||||
DeleteQGraphicsItemCommand::~DeleteQGraphicsItemCommand() {
|
||||
m_diagram->qgiManager().release(m_removed_contents.items(DiagramContent::All));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeleteQGraphicsItemCommand::undo
|
||||
* Undo this command
|
||||
*/
|
||||
void DeleteQGraphicsItemCommand::undo()
|
||||
{
|
||||
m_diagram->showMe();
|
||||
|
||||
for(QGraphicsItem *item : m_removed_contents.items())
|
||||
m_diagram->addItem(item);
|
||||
|
||||
//We relink element after every element was added to diagram
|
||||
for(Element *e : m_removed_contents.m_elements)
|
||||
for(Element *elmt : m_link_hash[e])
|
||||
e->linkToElement(elmt);
|
||||
|
||||
for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
|
||||
{
|
||||
deti->setParentItem(m_elmt_text_hash.value(deti));
|
||||
m_elmt_text_hash.value(deti)->addDynamicTextItem(deti);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeleteQGraphicsItemCommand::redo
|
||||
* Redo the delete command
|
||||
*/
|
||||
void DeleteQGraphicsItemCommand::redo()
|
||||
{
|
||||
m_diagram -> showMe();
|
||||
|
||||
for(Conductor *c : m_removed_contents.conductors(DiagramContent::AnyConductor))
|
||||
{
|
||||
//If option one text per folio is enable, and the text item of
|
||||
//current conductor is visible (that mean the conductor have the single displayed text)
|
||||
//We call adjustTextItemPosition to other conductor at the same potential to keep
|
||||
//a visible text on this potential.
|
||||
if (m_diagram -> defaultConductorProperties.m_one_text_per_folio && c -> textItem() -> isVisible())
|
||||
{
|
||||
QList <Conductor *> conductor_list;
|
||||
conductor_list << c -> relatedPotentialConductors(false).toList();
|
||||
if (conductor_list.count())
|
||||
conductor_list.first() -> calculateTextItemPosition();
|
||||
}
|
||||
}
|
||||
|
||||
for(Element *e : m_removed_contents.m_elements)
|
||||
{
|
||||
//Get linked element, for relink it at undo
|
||||
if (!e->linkedElements().isEmpty())
|
||||
m_link_hash.insert(e, e->linkedElements());
|
||||
}
|
||||
|
||||
for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
|
||||
{
|
||||
deti->ParentElement()->removeDynamicTextItem(deti);
|
||||
deti->setParentItem(nullptr);
|
||||
}
|
||||
|
||||
|
||||
for(QGraphicsItem *item : m_removed_contents.items())
|
||||
m_diagram->removeItem(item);
|
||||
}
|
46
sources/undocommand/deleteqgraphicsitemcommand.h
Normal file
46
sources/undocommand/deleteqgraphicsitemcommand.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DELETEQGRAPHICSITEMCOMMAND_H
|
||||
#define DELETEQGRAPHICSITEMCOMMAND_H
|
||||
|
||||
#include <QUndoCommand>
|
||||
#include "diagramcontent.h"
|
||||
|
||||
class Diagram;
|
||||
|
||||
class DeleteQGraphicsItemCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand * parent = nullptr);
|
||||
virtual ~DeleteQGraphicsItemCommand() override;
|
||||
private:
|
||||
DeleteQGraphicsItemCommand(const DeleteQGraphicsItemCommand &);
|
||||
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
// attributes
|
||||
private:
|
||||
DiagramContent m_removed_contents;
|
||||
Diagram *m_diagram;
|
||||
QHash <Element *, QList<Element *> > m_link_hash; /// keep linked element for each removed element linked to other element.
|
||||
QHash <DynamicElementTextItem *, Element *> m_elmt_text_hash; /// Keep the parent element of each deleted dynamic element text item
|
||||
};
|
||||
|
||||
#endif // DELETEQGRAPHICSITEMCOMMAND_H
|
Loading…
x
Reference in New Issue
Block a user