mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-01-10 07:59:58 +01:00
Rapatriement de la branche 0.2 dans le trunk
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@558 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -74,6 +74,7 @@ class CustomElementGraphicPart : public CustomElementPart {
|
||||
|
||||
/// Destructeur
|
||||
virtual ~CustomElementGraphicPart() {
|
||||
if (style_editor -> parentWidget()) return; // l'editeur de style sera supprime par son parent
|
||||
delete style_editor;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -29,7 +29,7 @@ DeletePartsCommand::DeletePartsCommand(
|
||||
const QList<QGraphicsItem *> parts,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("suppression"), parent),
|
||||
QUndoCommand(QObject::tr("suppression", "undo caption"), parent),
|
||||
deleted_parts(parts),
|
||||
editor_scene(scene)
|
||||
{
|
||||
@@ -59,6 +59,94 @@ void DeletePartsCommand::redo() {
|
||||
}
|
||||
}
|
||||
|
||||
/*** CutPartsCommand ***/
|
||||
/**
|
||||
Constructeur
|
||||
@param scene ElementScene concernee
|
||||
@param parts Liste des parties collees
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
PastePartsCommand::PastePartsCommand(
|
||||
ElementView *view,
|
||||
const ElementContent &c,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(parent),
|
||||
content_(c),
|
||||
editor_view_(view),
|
||||
editor_scene_(view -> scene()),
|
||||
uses_offset(false),
|
||||
first_redo(true)
|
||||
{
|
||||
setText(QObject::tr("coller"));
|
||||
editor_scene_ -> qgiManager().manage(content_);
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
PastePartsCommand::~PastePartsCommand() {
|
||||
editor_scene_ -> qgiManager().release(content_);
|
||||
}
|
||||
|
||||
/// annule le coller
|
||||
void PastePartsCommand::undo() {
|
||||
// enleve les parties
|
||||
foreach(QGraphicsItem *part, content_) editor_scene_ -> removeItem(part);
|
||||
if (uses_offset) {
|
||||
editor_view_ -> offset_paste_count_ = old_offset_paste_count_;
|
||||
editor_view_ -> start_top_left_corner_ = old_start_top_left_corner_;
|
||||
}
|
||||
editor_view_ -> adjustSceneRect();
|
||||
}
|
||||
|
||||
/// refait le coller
|
||||
void PastePartsCommand::redo() {
|
||||
if (first_redo) first_redo = false;
|
||||
else {
|
||||
// pose les parties
|
||||
foreach(QGraphicsItem *part, content_) editor_scene_ -> addItem(part);
|
||||
if (uses_offset) {
|
||||
editor_view_ -> offset_paste_count_ = new_offset_paste_count_;
|
||||
editor_view_ -> start_top_left_corner_ = new_start_top_left_corner_;
|
||||
}
|
||||
}
|
||||
foreach(QGraphicsItem *part, content_) part -> setSelected(true);
|
||||
editor_view_ -> adjustSceneRect();
|
||||
}
|
||||
|
||||
/**
|
||||
Indique a cet objet d'annulation que le c/c a annuler ou refaire etait un
|
||||
c/c avec decalage ; il faut plus d'informations pour annuler ce type de
|
||||
collage.
|
||||
*/
|
||||
void PastePartsCommand::setOffset(int old_offset_pc, const QPointF &old_start_tlc, int new_offset_pc, const QPointF &new_start_tlc) {
|
||||
old_offset_paste_count_ = old_offset_pc;
|
||||
old_start_top_left_corner_ = old_start_tlc;
|
||||
new_offset_paste_count_ = new_offset_pc;
|
||||
new_start_top_left_corner_ = new_start_tlc;
|
||||
uses_offset = true;
|
||||
}
|
||||
|
||||
/*** CutPartsCommand ***/
|
||||
/**
|
||||
Constructeur
|
||||
@param scene ElementScene concernee
|
||||
@param parts Liste des parties coupees
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
CutPartsCommand::CutPartsCommand(
|
||||
ElementScene *scene,
|
||||
const QList<QGraphicsItem *> parts,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
DeletePartsCommand(scene, parts, parent)
|
||||
{
|
||||
setText(QString(QObject::tr("couper des parties", "undo caption")));
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
CutPartsCommand::~CutPartsCommand() {
|
||||
}
|
||||
|
||||
/*** MovePartsCommand ***/
|
||||
/**
|
||||
Constructeur
|
||||
@@ -73,7 +161,7 @@ MovePartsCommand::MovePartsCommand(
|
||||
const QList<QGraphicsItem *> parts,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("d\351placement"), parent),
|
||||
QUndoCommand(QObject::tr("d\351placement", "undo caption"), parent),
|
||||
movement(m),
|
||||
first_redo(true)
|
||||
{
|
||||
@@ -114,7 +202,7 @@ AddPartCommand::AddPartCommand(
|
||||
QGraphicsItem *p,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("ajout ") + name, parent),
|
||||
QUndoCommand(QString(QObject::tr("ajout %1", "undo caption")).arg(name), parent),
|
||||
part(p),
|
||||
editor_scene(scene),
|
||||
first_redo(true)
|
||||
@@ -161,7 +249,7 @@ ChangePartCommand::ChangePartCommand(
|
||||
const QVariant &new_v,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("modification ") + name, parent),
|
||||
QUndoCommand(QString(QObject::tr("modification %1", "undo caption")).arg(name), parent),
|
||||
cep(part),
|
||||
property(prop),
|
||||
old_value(old_v),
|
||||
@@ -196,7 +284,7 @@ ChangePolygonPointsCommand::ChangePolygonPointsCommand(
|
||||
const QVector<QPointF> &n_points,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("modification points polygone"), parent),
|
||||
QUndoCommand(QObject::tr("modification points polygone", "undo caption"), parent),
|
||||
polygon(p),
|
||||
old_points(o_points),
|
||||
new_points(n_points)
|
||||
@@ -236,7 +324,7 @@ ChangeHotspotCommand::ChangeHotspotCommand(
|
||||
const QPoint &o,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("modification dimensions/hotspot"), parent),
|
||||
QUndoCommand(QObject::tr("modification dimensions/hotspot", "undo caption"), parent),
|
||||
element(element_scene),
|
||||
size_before(size_1),
|
||||
size_after(size_2),
|
||||
@@ -297,7 +385,7 @@ ChangeNamesCommand::ChangeNamesCommand(
|
||||
const NamesList &after,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("modification noms"), parent),
|
||||
QUndoCommand(QObject::tr("modification noms", "undo caption"), parent),
|
||||
names_before(before),
|
||||
names_after(after),
|
||||
element(element_scene)
|
||||
@@ -331,7 +419,7 @@ ChangeOrientationsCommand::ChangeOrientationsCommand(
|
||||
const OrientationSet &after,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("modification orientations"), parent),
|
||||
QUndoCommand(QObject::tr("modification orientations", "undo caption"), parent),
|
||||
ori_before(before),
|
||||
ori_after(after),
|
||||
element(element_scene)
|
||||
@@ -375,16 +463,16 @@ ChangeZValueCommand::ChangeZValueCommand(
|
||||
|
||||
// choisit le nom en fonction du traitement
|
||||
if (option == BringForward) {
|
||||
setText(QObject::tr("amener au premier plan"));
|
||||
setText(QObject::tr("amener au premier plan", "undo caption"));
|
||||
applyBringForward(items_list);
|
||||
} else if (option == Raise) {
|
||||
setText(QObject::tr("rapprocher"));
|
||||
setText(QObject::tr("rapprocher", "undo caption"));
|
||||
applyRaise(items_list);
|
||||
} else if (option == Lower) {
|
||||
setText(QObject::tr("\351loigner"));
|
||||
setText(QObject::tr("\351loigner", "undo caption"));
|
||||
applyLower(items_list);
|
||||
} else if (option == SendBackward) {
|
||||
setText(QObject::tr("envoyer au fond"));
|
||||
setText(QObject::tr("envoyer au fond", "undo caption"));
|
||||
applySendBackward(items_list);
|
||||
}
|
||||
}
|
||||
@@ -483,7 +571,7 @@ void ChangeZValueCommand::applySendBackward(const QList<QGraphicsItem *> &items_
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
AllowInternalConnectionsCommand::AllowInternalConnectionsCommand(ElementScene *elmt, bool allow, QUndoCommand *parent) :
|
||||
QUndoCommand(QObject::tr("modification connexions internes"), parent),
|
||||
QUndoCommand(QObject::tr("modification connexions internes", "undo caption"), parent),
|
||||
element(elmt),
|
||||
ic(allow)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -19,7 +19,9 @@
|
||||
#define EDITOR_COMMANDS_H
|
||||
#include "customelementpart.h"
|
||||
#include "partpolygon.h"
|
||||
#include "elementview.h"
|
||||
#include "elementscene.h"
|
||||
#include "elementcontent.h"
|
||||
#include "qgimanager.h"
|
||||
#include <QtGui>
|
||||
/**
|
||||
@@ -47,6 +49,52 @@ class DeletePartsCommand : public QUndoCommand {
|
||||
ElementScene *editor_scene;
|
||||
};
|
||||
|
||||
/**
|
||||
Cette classe represente l'action de coller quelque chose dans un element
|
||||
*/
|
||||
class PastePartsCommand : public QUndoCommand {
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
PastePartsCommand(ElementView *, const ElementContent &, QUndoCommand * = 0);
|
||||
virtual ~PastePartsCommand();
|
||||
private:
|
||||
PastePartsCommand(const PastePartsCommand &);
|
||||
|
||||
// methodes
|
||||
public:
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
virtual void setOffset(int, const QPointF &, int, const QPointF &);
|
||||
|
||||
// attributs
|
||||
private:
|
||||
/// contenu ajoute
|
||||
ElementContent content_;
|
||||
/// schema sur lequel on colle les elements et conducteurs
|
||||
ElementView *editor_view_;
|
||||
ElementScene *editor_scene_;
|
||||
/// Informations pour annuler un c/c avec decalage
|
||||
int old_offset_paste_count_;
|
||||
QPointF old_start_top_left_corner_;
|
||||
int new_offset_paste_count_;
|
||||
QPointF new_start_top_left_corner_;
|
||||
bool uses_offset;
|
||||
/// booleen pour empecher le premier appel a redo
|
||||
bool first_redo;
|
||||
};
|
||||
|
||||
/**
|
||||
Cette classe represente l'action de supprimer des parties d'un element
|
||||
*/
|
||||
class CutPartsCommand : public DeletePartsCommand {
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
CutPartsCommand(ElementScene *, const QList<QGraphicsItem *>, QUndoCommand * = 0);
|
||||
virtual ~CutPartsCommand();
|
||||
private:
|
||||
CutPartsCommand(const CutPartsCommand &);
|
||||
};
|
||||
|
||||
/**
|
||||
Cette classe represente l'action de deplacer une ou plusieurs
|
||||
parties lors de l'edition d'un element
|
||||
|
||||
30
sources/editor/elementcontent.h
Normal file
30
sources/editor/elementcontent.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
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 ELEMENT_CONTENT_H
|
||||
#define ELEMENT_CONTENT_H
|
||||
#include <QList>
|
||||
class QGraphicsItem;
|
||||
/**
|
||||
Lors de son edition dans l'editeur d'element, un element est decompose en
|
||||
parties graphiques. La classe ElementContent represente un ensemble de parties
|
||||
graphiques constituant tout ou partie d'un element.
|
||||
Note : pour le moment, ElementContent est un typedef pour QList\<QGraphicsItem *\>
|
||||
@see la documentation Qt de la classe QList
|
||||
*/
|
||||
typedef QList<QGraphicsItem *> ElementContent;
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -22,7 +22,7 @@ class QETElementEditor;
|
||||
class ElementScene;
|
||||
class CustomElementPart;
|
||||
/**
|
||||
Cette classe est la classe de base pour les editeurs de aprties dans
|
||||
Cette classe est la classe de base pour les editeurs de parties dans
|
||||
l'editeur d'element. Elle fournit des methodes pour acceder facilement
|
||||
a l'editeur, a la pile d'annulation, a la scene d'edition ou encore pour
|
||||
ajouter facilement une annulation de type ChangePartCommand.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "qetelementeditor.h"
|
||||
#include <cmath>
|
||||
#include "partline.h"
|
||||
#include "partrectangle.h"
|
||||
#include "partellipse.h"
|
||||
#include "partcircle.h"
|
||||
#include "partpolygon.h"
|
||||
@@ -28,9 +29,7 @@
|
||||
#include "partarc.h"
|
||||
#include "hotspoteditor.h"
|
||||
#include "editorcommands.h"
|
||||
|
||||
const int ElementScene::xGrid = 10;
|
||||
const int ElementScene::yGrid = 10;
|
||||
#include "elementcontent.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@@ -47,6 +46,8 @@ ElementScene::ElementScene(QETElementEditor *editor, QObject *parent) :
|
||||
element_editor(editor)
|
||||
{
|
||||
current_polygon = NULL;
|
||||
setGrid(1, 1);
|
||||
initPasteArea();
|
||||
undo_stack.setClean();
|
||||
}
|
||||
|
||||
@@ -68,6 +69,13 @@ void ElementScene::slot_addLine() {
|
||||
behavior = Line;
|
||||
}
|
||||
|
||||
/**
|
||||
Passe la scene en mode "ajout de rectangle"
|
||||
*/
|
||||
void ElementScene::slot_addRectangle() {
|
||||
behavior = Rectangle;
|
||||
}
|
||||
|
||||
/**
|
||||
Passe la scene en mode "ajout de cercle"
|
||||
*/
|
||||
@@ -104,7 +112,6 @@ void ElementScene::slot_addTerminal() {
|
||||
behavior = Terminal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Passe la scene en mode "ajout d'arc de cercle"
|
||||
*/
|
||||
@@ -124,7 +131,17 @@ void ElementScene::slot_addTextField() {
|
||||
@param e objet decrivant l'evenement
|
||||
*/
|
||||
void ElementScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
||||
QPointF event_pos = e -> scenePos();
|
||||
if (mustSnapToGrid(e)) snapToGrid(event_pos);
|
||||
|
||||
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
||||
if (behavior == PasteArea) {
|
||||
QRectF current_rect(paste_area_ -> rect());
|
||||
current_rect.moveCenter(event_pos);
|
||||
paste_area_ -> setRect(current_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
QRectF temp_rect;
|
||||
qreal radius;
|
||||
QPointF temp_point;
|
||||
@@ -132,21 +149,26 @@ void ElementScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
||||
if (e -> buttons() & Qt::LeftButton) {
|
||||
switch(behavior) {
|
||||
case Line:
|
||||
current_line -> setLine(QLineF(current_line -> line().p1(), e -> scenePos()));
|
||||
current_line -> setLine(QLineF(current_line -> line().p1(), event_pos));
|
||||
break;
|
||||
case Rectangle:
|
||||
temp_rect = current_rectangle -> rect();
|
||||
temp_rect.setBottomRight(event_pos);
|
||||
current_rectangle -> setRect(temp_rect);
|
||||
break;
|
||||
case Ellipse:
|
||||
temp_rect = current_ellipse -> rect();
|
||||
temp_rect.setBottomRight(e -> scenePos());
|
||||
temp_rect.setBottomRight(event_pos);
|
||||
current_ellipse -> setRect(temp_rect);
|
||||
break;
|
||||
case Arc:
|
||||
temp_rect = current_arc -> rect();
|
||||
temp_rect.setBottomRight(e -> scenePos());
|
||||
temp_rect.setBottomRight(event_pos);
|
||||
current_arc -> setRect(temp_rect);
|
||||
break;
|
||||
case Circle:
|
||||
temp_rect = current_circle -> rect();
|
||||
temp_point = e -> scenePos() - current_circle -> mapToScene(temp_rect.center());
|
||||
temp_point = event_pos - current_circle -> mapToScene(temp_rect.center());
|
||||
radius = sqrt(pow(temp_point.x(), 2) + pow(temp_point.y(), 2));
|
||||
temp_rect = QRectF(
|
||||
temp_rect.center() - QPointF(radius, radius),
|
||||
@@ -158,17 +180,35 @@ void ElementScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
||||
if (current_polygon == NULL) break;
|
||||
temp_polygon = current_polygon -> polygon();
|
||||
temp_polygon.pop_back();
|
||||
temp_polygon << e -> scenePos();
|
||||
temp_polygon << event_pos;
|
||||
current_polygon -> setPolygon(temp_polygon);
|
||||
break;
|
||||
case Normal:
|
||||
default:
|
||||
QGraphicsScene::mouseMoveEvent(e);
|
||||
QList<QGraphicsItem *> selected_items = selectedItems();
|
||||
if (!selected_items.isEmpty()) {
|
||||
// mouvement de souris realise depuis le dernier press event
|
||||
QPointF mouse_movement = e -> scenePos() - moving_press_pos;
|
||||
|
||||
// application de ce mouvement a la fsi_pos enregistre dans le dernier press event
|
||||
QPointF new_fsi_pos = fsi_pos + mouse_movement;
|
||||
|
||||
// snap eventuel de la nouvelle fsi_pos
|
||||
if (mustSnapToGrid(e)) snapToGrid(new_fsi_pos);
|
||||
|
||||
// difference entre la fsi_pos finale et la fsi_pos courante = mouvement a appliquer
|
||||
|
||||
QPointF current_fsi_pos = selected_items.first() -> scenePos();
|
||||
QPointF final_movement = new_fsi_pos - current_fsi_pos;
|
||||
foreach(QGraphicsItem *qgi, selected_items) {
|
||||
qgi -> moveBy(final_movement.x(), final_movement.y());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (behavior == Polygon && current_polygon != NULL) {
|
||||
temp_polygon = current_polygon -> polygon();
|
||||
temp_polygon.pop_back();
|
||||
temp_polygon << e -> scenePos();
|
||||
temp_polygon << event_pos;
|
||||
current_polygon -> setPolygon(temp_polygon);
|
||||
} else QGraphicsScene::mouseMoveEvent(e);
|
||||
}
|
||||
@@ -178,27 +218,34 @@ void ElementScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
||||
@param e objet decrivant l'evenement
|
||||
*/
|
||||
void ElementScene::mousePressEvent(QGraphicsSceneMouseEvent *e) {
|
||||
QPointF event_pos = e -> scenePos();
|
||||
if (mustSnapToGrid(e)) snapToGrid(event_pos);
|
||||
|
||||
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
||||
QPolygonF temp_polygon;
|
||||
if (e -> button() & Qt::LeftButton) {
|
||||
switch(behavior) {
|
||||
case Line:
|
||||
current_line = new PartLine(element_editor, 0, this);
|
||||
current_line -> setLine(QLineF(e -> scenePos(), e -> scenePos()));
|
||||
current_line -> setLine(QLineF(event_pos, event_pos));
|
||||
break;
|
||||
case Rectangle:
|
||||
current_rectangle = new PartRectangle(element_editor, 0, this);
|
||||
current_rectangle -> setRect(QRectF(event_pos, QSizeF(0.0, 0.0)));
|
||||
break;
|
||||
case Ellipse:
|
||||
current_ellipse = new PartEllipse(element_editor, 0, this);
|
||||
current_ellipse -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
|
||||
current_ellipse -> setRect(QRectF(event_pos, QSizeF(0.0, 0.0)));
|
||||
current_ellipse -> setProperty("antialias", true);
|
||||
break;
|
||||
case Arc:
|
||||
current_arc = new PartArc(element_editor, 0, this);
|
||||
current_arc -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
|
||||
current_arc -> setRect(QRectF(event_pos, QSizeF(0.0, 0.0)));
|
||||
current_arc -> setProperty("antialias", true);
|
||||
break;
|
||||
case Circle:
|
||||
current_circle = new PartCircle(element_editor, 0, this);
|
||||
current_circle -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
|
||||
current_circle -> setRect(QRectF(event_pos, QSizeF(0.0, 0.0)));
|
||||
current_circle -> setProperty("antialias", true);
|
||||
break;
|
||||
case Polygon:
|
||||
@@ -207,14 +254,23 @@ void ElementScene::mousePressEvent(QGraphicsSceneMouseEvent *e) {
|
||||
temp_polygon = QPolygonF(0);
|
||||
} else temp_polygon = current_polygon -> polygon();
|
||||
// au debut, on insere deux points
|
||||
if (!temp_polygon.count()) temp_polygon << e -> scenePos();
|
||||
temp_polygon << e -> scenePos();
|
||||
if (!temp_polygon.count()) temp_polygon << event_pos;
|
||||
temp_polygon << event_pos;
|
||||
current_polygon -> setPolygon(temp_polygon);
|
||||
break;
|
||||
case Normal:
|
||||
default:
|
||||
QGraphicsScene::mousePressEvent(e);
|
||||
if (!selectedItems().isEmpty()) fsi_pos = selectedItems().first() -> scenePos();
|
||||
// gestion des deplacements de parties
|
||||
if (!selectedItems().isEmpty()) {
|
||||
fsi_pos = selectedItems().first() -> scenePos();
|
||||
moving_press_pos = e -> scenePos();
|
||||
moving_parts_ = true;
|
||||
} else {
|
||||
fsi_pos = QPoint();
|
||||
moving_press_pos = QPoint();
|
||||
moving_parts_ = false;
|
||||
}
|
||||
}
|
||||
} else QGraphicsScene::mousePressEvent(e);
|
||||
}
|
||||
@@ -224,71 +280,97 @@ void ElementScene::mousePressEvent(QGraphicsSceneMouseEvent *e) {
|
||||
@param e objet decrivant l'evenement
|
||||
*/
|
||||
void ElementScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
|
||||
QPointF event_pos = e -> scenePos();
|
||||
if (mustSnapToGrid(e)) snapToGrid(event_pos);
|
||||
|
||||
PartTerminal *terminal;
|
||||
PartText *text;
|
||||
PartTextField *textfield;
|
||||
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
||||
|
||||
if (behavior == PasteArea) {
|
||||
defined_paste_area_ = paste_area_ -> rect();
|
||||
removeItem(paste_area_);
|
||||
emit(pasteAreaDefined(defined_paste_area_));
|
||||
behavior = Normal;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e -> button() & Qt::LeftButton) {
|
||||
switch(behavior) {
|
||||
case Line:
|
||||
if (qgiManager().manages(current_line)) break;
|
||||
undo_stack.push(new AddPartCommand(tr("ligne"), this, current_line));
|
||||
emit(partsAdded());
|
||||
endCurrentBehavior(e);
|
||||
break;
|
||||
case Rectangle:
|
||||
if (qgiManager().manages(current_rectangle)) break;
|
||||
current_rectangle -> setRect(current_rectangle -> rect().normalized());
|
||||
undo_stack.push(new AddPartCommand(tr("rectangle"), this, current_rectangle));
|
||||
emit(partsAdded());
|
||||
endCurrentBehavior(e);
|
||||
break;
|
||||
case Ellipse:
|
||||
if (qgiManager().manages(current_ellipse)) break;
|
||||
current_ellipse -> setRect(current_ellipse -> rect().normalized());
|
||||
undo_stack.push(new AddPartCommand(tr("ellipse"), this, current_ellipse));
|
||||
emit(partsAdded());
|
||||
endCurrentBehavior(e);
|
||||
break;
|
||||
case Arc:
|
||||
if (qgiManager().manages(current_arc)) break;
|
||||
current_arc-> setRect(current_arc -> rect().normalized());
|
||||
undo_stack.push(new AddPartCommand(tr("arc"), this, current_arc));
|
||||
emit(partsAdded());
|
||||
endCurrentBehavior(e);
|
||||
break;
|
||||
case Circle:
|
||||
if (qgiManager().manages(current_circle)) break;
|
||||
current_circle -> setRect(current_circle -> rect().normalized());
|
||||
undo_stack.push(new AddPartCommand(tr("cercle"), this, current_circle));
|
||||
emit(partsAdded());
|
||||
endCurrentBehavior(e);
|
||||
break;
|
||||
case Terminal:
|
||||
terminal = new PartTerminal(element_editor, 0, this);
|
||||
terminal -> setPos(e -> scenePos());
|
||||
terminal -> setPos(event_pos);
|
||||
undo_stack.push(new AddPartCommand(tr("borne"), this, terminal));
|
||||
emit(partsAdded());
|
||||
endCurrentBehavior(e);
|
||||
break;
|
||||
case Text:
|
||||
text = new PartText(element_editor, 0, this);
|
||||
text -> setPos(e -> scenePos());
|
||||
text -> setPos(event_pos);
|
||||
undo_stack.push(new AddPartCommand(tr("texte"), this, text));
|
||||
emit(partsAdded());
|
||||
endCurrentBehavior(e);
|
||||
break;
|
||||
case TextField:
|
||||
textfield = new PartTextField(element_editor, 0, this);
|
||||
textfield -> setPos(e -> scenePos());
|
||||
textfield -> setPos(event_pos);
|
||||
undo_stack.push(new AddPartCommand(tr("champ de texte"), this, textfield));
|
||||
emit(partsAdded());
|
||||
endCurrentBehavior(e);
|
||||
break;
|
||||
case Normal:
|
||||
default:
|
||||
QGraphicsScene::mouseReleaseEvent(e);
|
||||
// detecte les deplacements de parties
|
||||
if (!selectedItems().isEmpty()) {
|
||||
if (!selectedItems().isEmpty() && moving_parts_) {
|
||||
QPointF movement = selectedItems().first() -> scenePos() - fsi_pos;
|
||||
if (!movement.isNull()) {
|
||||
undo_stack.push(new MovePartsCommand(movement, this, selectedItems()));
|
||||
}
|
||||
}
|
||||
QGraphicsScene::mouseReleaseEvent(e);
|
||||
moving_parts_ = false;
|
||||
}
|
||||
} else if (e -> button() & Qt::RightButton) {
|
||||
if (behavior == Polygon && current_polygon != NULL) {
|
||||
behavior = Normal;
|
||||
undo_stack.push(new AddPartCommand(tr("polygone"), this, current_polygon));
|
||||
current_polygon = NULL;
|
||||
emit(partsAdded());
|
||||
emit(needNormalMode());
|
||||
endCurrentBehavior(e);
|
||||
} else QGraphicsScene::mouseReleaseEvent(e);
|
||||
} else QGraphicsScene::mouseReleaseEvent(e);
|
||||
}
|
||||
@@ -317,6 +399,10 @@ void ElementScene::drawBackground(QPainter *p, const QRectF &r) {
|
||||
p -> setBrush(Qt::NoBrush);
|
||||
p -> drawRect(drawable_area);
|
||||
|
||||
// on dessine un point de la grille sur 10
|
||||
int drawn_x_grid = x_grid * 10;
|
||||
int drawn_y_grid = y_grid * 10;
|
||||
|
||||
if (r.width() < 2500 && r.height() < 2500) {
|
||||
// dessine les points de la grille
|
||||
p -> setPen(Qt::black);
|
||||
@@ -325,12 +411,12 @@ void ElementScene::drawBackground(QPainter *p, const QRectF &r) {
|
||||
qreal limite_y = r.y() + r.height();
|
||||
|
||||
int g_x = (int)ceil(r.x());
|
||||
while (g_x % xGrid) ++ g_x;
|
||||
while (g_x % drawn_x_grid) ++ g_x;
|
||||
int g_y = (int)ceil(r.y());
|
||||
while (g_y % yGrid) ++ g_y;
|
||||
while (g_y % drawn_y_grid) ++ g_y;
|
||||
|
||||
for (int gx = g_x ; gx < limite_x ; gx += xGrid) {
|
||||
for (int gy = g_y ; gy < limite_y ; gy += yGrid) {
|
||||
for (int gx = g_x ; gx < limite_x ; gx += drawn_x_grid) {
|
||||
for (int gy = g_y ; gy < limite_y ; gy += drawn_y_grid) {
|
||||
p -> drawPoint(gx, gy);
|
||||
}
|
||||
}
|
||||
@@ -358,11 +444,50 @@ void ElementScene::drawForeground(QPainter *p, const QRectF &) {
|
||||
p -> restore();
|
||||
}
|
||||
|
||||
/**
|
||||
A partir d'un evenement souris, cette methode regarde si la touche shift est
|
||||
enfoncee ou non. Si oui, elle laisse le comportement en cours (cercle,
|
||||
texte, polygone, ...). Si non, elle repasse en mode normal / selection.
|
||||
@param e objet decrivant l'evenement souris
|
||||
*/
|
||||
void ElementScene::endCurrentBehavior(const QGraphicsSceneMouseEvent *event) {
|
||||
if (!(event -> modifiers() & Qt::ShiftModifier)) {
|
||||
// la touche Shift n'est pas enfoncee : on demande le mode normal
|
||||
behavior = Normal;
|
||||
emit(needNormalMode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@return la taille horizontale de la grille
|
||||
*/
|
||||
int ElementScene::xGrid() const {
|
||||
return(x_grid);
|
||||
}
|
||||
|
||||
/**
|
||||
@return la taille verticale de la grille
|
||||
*/
|
||||
int ElementScene::yGrid() const {
|
||||
return(y_grid);
|
||||
}
|
||||
|
||||
/**
|
||||
@param x_grid Taille horizontale de la grille
|
||||
@param y_grid Taille verticale de la grille
|
||||
*/
|
||||
void ElementScene::setGrid(int x_g, int y_g) {
|
||||
x_grid = x_g ? x_g : 1;
|
||||
y_grid = y_g ? y_g : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Exporte l'element en XML
|
||||
@param diagram Booleen (a vrai par defaut) indiquant si le XML genere doit
|
||||
representer tout l'element ou seulement les elements selectionnes
|
||||
@return un document XML decrivant l'element
|
||||
*/
|
||||
const QDomDocument ElementScene::toXml() const {
|
||||
const QDomDocument ElementScene::toXml(bool all_parts) const {
|
||||
// document XML
|
||||
QDomDocument xml_document;
|
||||
|
||||
@@ -383,6 +508,8 @@ const QDomDocument ElementScene::toXml() const {
|
||||
QDomElement description = xml_document.createElement("description");
|
||||
// description de l'element
|
||||
foreach(QGraphicsItem *qgi, zItems(true)) {
|
||||
// si l'export ne concerne que la selection, on ignore les parties non selectionnees
|
||||
if (!all_parts && !qgi -> isSelected()) continue;
|
||||
if (CustomElementPart *ce = dynamic_cast<CustomElementPart *>(qgi)) {
|
||||
if (ce -> isUseless()) continue;
|
||||
description.appendChild(ce -> toXml(xml_document));
|
||||
@@ -395,91 +522,90 @@ const QDomDocument ElementScene::toXml() const {
|
||||
}
|
||||
|
||||
/**
|
||||
Lit un element depuis un document XML
|
||||
@param xml_document un document XML decrivant l'element
|
||||
@param xml_document un document XML decrivant un element
|
||||
@return le boundingRect du contenu de l'element
|
||||
*/
|
||||
void ElementScene::fromXml(const QDomDocument &xml_document) {
|
||||
QRectF ElementScene::boundingRectFromXml(const QDomDocument &xml_document) {
|
||||
// charge les parties depuis le document XML
|
||||
ElementContent loaded_content = loadContent(xml_document);
|
||||
if (loaded_content.isEmpty()) return(QRectF());
|
||||
|
||||
// calcule le boundingRect
|
||||
QRectF bounding_rect = elementContentBoundingRect(loaded_content);
|
||||
|
||||
// detruit les parties chargees
|
||||
qDeleteAll(loaded_content);
|
||||
|
||||
return(bounding_rect);
|
||||
}
|
||||
|
||||
/**
|
||||
Importe l'element decrit dans un document XML. Si une position est
|
||||
precisee, les elements importes sont positionnes de maniere a ce que le
|
||||
coin superieur gauche du plus petit rectangle pouvant les entourant tous
|
||||
(le bounding rect) soit a cette position.
|
||||
@param xml_document un document XML decrivant l'element
|
||||
@param position La position des parties importees
|
||||
@param consider_informations Si vrai, les informations complementaires
|
||||
(dimensions, hotspot, etc.) seront prises en compte
|
||||
@param content_ptr si ce pointeur vers un ElementContent est different de 0,
|
||||
il sera rempli avec le contenu ajoute a l'element par le fromXml
|
||||
@return true si l'import a reussi, false sinon
|
||||
*/
|
||||
void ElementScene::fromXml(
|
||||
const QDomDocument &xml_document,
|
||||
const QPointF &position,
|
||||
bool consider_informations,
|
||||
ElementContent *content_ptr
|
||||
) {
|
||||
QString error_message;
|
||||
bool state = true;
|
||||
|
||||
// la racine est supposee etre une definition d'element
|
||||
QDomElement root = xml_document.documentElement();
|
||||
if (root.tagName() != "definition" || root.attribute("type") != "element") {
|
||||
state = false;
|
||||
error_message = tr("Ce document XML n'est pas une definition d'\351l\351ment.");
|
||||
}
|
||||
|
||||
// dimensions et hotspot
|
||||
if (state) {
|
||||
// ces attributs doivent etre presents et valides
|
||||
int w, h, hot_x, hot_y;
|
||||
if (
|
||||
!QET::attributeIsAnInteger(root, QString("width"), &w) ||\
|
||||
!QET::attributeIsAnInteger(root, QString("height"), &h) ||\
|
||||
!QET::attributeIsAnInteger(root, QString("hotspot_x"), &hot_x) ||\
|
||||
!QET::attributeIsAnInteger(root, QString("hotspot_y"), &hot_y)
|
||||
) {
|
||||
state = false;
|
||||
error_message = tr("Les dimensions ou le point de saisie ne sont pas valides.");
|
||||
} else {
|
||||
setWidth(w);
|
||||
setHeight(h);
|
||||
setHotspot(QPoint(hot_x, hot_y));
|
||||
}
|
||||
}
|
||||
|
||||
// orientations et connexions internes
|
||||
if (state) {
|
||||
internal_connections = (root.attribute("ic") == "true");
|
||||
|
||||
if (!ori.fromString(root.attribute("orientation"))) {
|
||||
state = false;
|
||||
error_message = tr("Les orientations ne sont pas valides.");
|
||||
}
|
||||
}
|
||||
|
||||
// extrait les noms de la definition XML
|
||||
if (state) {
|
||||
_names.fromXml(root);
|
||||
// prend en compte les informations de l'element
|
||||
if (consider_informations) {
|
||||
state = applyInformations(xml_document, &error_message);
|
||||
}
|
||||
|
||||
// parcours des enfants de la definition : parties de l'element
|
||||
if (state) {
|
||||
for (QDomNode node = root.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
|
||||
QDomElement elmts = node.toElement();
|
||||
if (elmts.isNull()) continue;
|
||||
if (elmts.tagName() == "description") {
|
||||
// gestion de la description graphique de l'element
|
||||
// = parcours des differentes parties du dessin
|
||||
int z = 1;
|
||||
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
|
||||
QDomElement qde = n.toElement();
|
||||
if (qde.isNull()) continue;
|
||||
CustomElementPart *cep;
|
||||
if (qde.tagName() == "line") cep = new PartLine (element_editor, 0, this);
|
||||
else if (qde.tagName() == "ellipse") cep = new PartEllipse (element_editor, 0, this);
|
||||
else if (qde.tagName() == "circle") cep = new PartCircle (element_editor, 0, this);
|
||||
else if (qde.tagName() == "polygon") cep = new PartPolygon (element_editor, 0, this);
|
||||
else if (qde.tagName() == "terminal") cep = new PartTerminal (element_editor, 0, this);
|
||||
else if (qde.tagName() == "text") cep = new PartText (element_editor, 0, this);
|
||||
else if (qde.tagName() == "input") cep = new PartTextField(element_editor, 0, this);
|
||||
else if (qde.tagName() == "arc") cep = new PartArc (element_editor, 0, this);
|
||||
else continue;
|
||||
if (QGraphicsItem *qgi = dynamic_cast<QGraphicsItem *>(cep)) qgi -> setZValue(z++);
|
||||
cep -> fromXml(qde);
|
||||
}
|
||||
}
|
||||
ElementContent loaded_content = loadContent(xml_document, &error_message);
|
||||
if (position != QPointF()) {
|
||||
addContentAtPos(loaded_content, position, &error_message);
|
||||
} else {
|
||||
addContent(loaded_content, &error_message);
|
||||
}
|
||||
|
||||
// renvoie le contenu ajoute a l'element
|
||||
if (content_ptr) {
|
||||
*content_ptr = loaded_content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@return le rectangle representant les limites de l'element.
|
||||
Ce rectangle a pour dimensions la taille de l'element et pour coin
|
||||
superieur gauche les coordonnees opposees du hotspot.
|
||||
*/
|
||||
QRectF ElementScene::borderRect() const {
|
||||
return(QRectF(-_hotspot, QSizeF(width(), height())));
|
||||
}
|
||||
|
||||
/**
|
||||
@return un rectangle englobant toutes les parties ainsi que le
|
||||
"bounding rect" de l'element
|
||||
*/
|
||||
QRectF ElementScene::sceneContent() const {
|
||||
return(itemsBoundingRect().unite(QRectF(-_hotspot, QSizeF(width(), height()))));
|
||||
return(itemsBoundingRect().unite(borderRect()));
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si toutes les parties graphiques composant l'element sont
|
||||
integralement contenues dans le rectangle representant les limites de
|
||||
l'element.
|
||||
*/
|
||||
bool ElementScene::borderContainsEveryParts() const {
|
||||
return(borderRect().contains(itemsBoundingRect()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -496,6 +622,64 @@ QGIManager &ElementScene::qgiManager() {
|
||||
return(qgi_manager);
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le presse-papier semble contenir un element
|
||||
*/
|
||||
bool ElementScene::clipboardMayContainElement() {
|
||||
QString clipboard_text = QApplication::clipboard() -> text().trimmed();
|
||||
bool may_be_element = clipboard_text.startsWith("<definition") && clipboard_text.endsWith("</definition>");
|
||||
return(may_be_element);
|
||||
}
|
||||
|
||||
/**
|
||||
@param clipboard_content chaine de caractere, provenant vraisemblablement du
|
||||
presse-papier.
|
||||
@return true si clipboard_content a ete copie depuis cet element.
|
||||
*/
|
||||
bool ElementScene::wasCopiedFromThisElement(const QString &clipboard_content) {
|
||||
return(clipboard_content == last_copied_);
|
||||
}
|
||||
|
||||
/**
|
||||
Gere le fait de couper la selection = l'exporter en XML dans le
|
||||
presse-papier puis la supprimer.
|
||||
*/
|
||||
void ElementScene::cut() {
|
||||
copy();
|
||||
QList<QGraphicsItem *> cut_content = selectedItems();
|
||||
clearSelection();
|
||||
undoStack().push(new CutPartsCommand(this, cut_content));
|
||||
}
|
||||
|
||||
/**
|
||||
Gere le fait de copier la selection = l'exporter en XML dans le
|
||||
presse-papier.
|
||||
*/
|
||||
void ElementScene::copy() {
|
||||
// accede au presse-papier
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
|
||||
// genere la description XML de la selection
|
||||
QString clipboard_content = toXml(false).toString(4);
|
||||
|
||||
// met la description XML dans le presse-papier
|
||||
if (clipboard -> supportsSelection()) {
|
||||
clipboard -> setText(clipboard_content, QClipboard::Selection);
|
||||
}
|
||||
clipboard -> setText(clipboard_content);
|
||||
|
||||
// retient le dernier contenu copie
|
||||
last_copied_ = clipboard_content;
|
||||
}
|
||||
|
||||
/**
|
||||
Gere le fait de coller le contenu du presse-papier = l'importer dans le
|
||||
presse-papier a une position donnee.
|
||||
*/
|
||||
void ElementScene::paste() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Selectionne tout
|
||||
*/
|
||||
@@ -538,7 +722,7 @@ void ElementScene::slot_editSizeHotSpot() {
|
||||
// cree un dialogue
|
||||
QDialog dialog_sh(element_editor);
|
||||
dialog_sh.setModal(true);
|
||||
dialog_sh.setWindowTitle(tr("\311diter la taille et le point de saisie"));
|
||||
dialog_sh.setWindowTitle(tr("\311diter la taille et le point de saisie", "window title"));
|
||||
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_sh);
|
||||
|
||||
// ajoute un HotspotEditor au dialogue
|
||||
@@ -578,7 +762,7 @@ void ElementScene::slot_editOrientations() {
|
||||
QDialog dialog_ori(element_editor);
|
||||
dialog_ori.setModal(true);
|
||||
dialog_ori.setMinimumSize(400, 260);
|
||||
dialog_ori.setWindowTitle(tr("\311diter les orientations"));
|
||||
dialog_ori.setWindowTitle(tr("\311diter les orientations", "window title"));
|
||||
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_ori);
|
||||
|
||||
// ajoute un champ explicatif au dialogue
|
||||
@@ -624,7 +808,7 @@ void ElementScene::slot_editNames() {
|
||||
QDialog dialog(element_editor);
|
||||
dialog.setModal(true);
|
||||
dialog.setMinimumSize(400, 330);
|
||||
dialog.setWindowTitle(tr("\311diter les noms"));
|
||||
dialog.setWindowTitle(tr("\311diter les noms", "window title"));
|
||||
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog);
|
||||
|
||||
// ajoute un champ explicatif au dialogue
|
||||
@@ -716,6 +900,30 @@ QList<QGraphicsItem *> ElementScene::zItems(bool include_terminals) const {
|
||||
return(all_items_list);
|
||||
}
|
||||
|
||||
/**
|
||||
@return les parties graphiques selectionnees
|
||||
*/
|
||||
ElementContent ElementScene::selectedContent() const {
|
||||
ElementContent content;
|
||||
foreach(QGraphicsItem *qgi, zItems(true)) {
|
||||
if (qgi -> isSelected()) content << qgi;
|
||||
}
|
||||
return(content);
|
||||
}
|
||||
|
||||
/**
|
||||
@param to_paste Rectangle englobant les parties a coller
|
||||
@return le rectangle ou il faudra coller ces parties
|
||||
*/
|
||||
void ElementScene::getPasteArea(const QRectF &to_paste) {
|
||||
// on le dessine sur la scene
|
||||
paste_area_ -> setRect(to_paste);
|
||||
addItem(paste_area_);
|
||||
|
||||
// on passe la scene en mode "recherche de zone pour copier/coller"
|
||||
behavior = PasteArea;
|
||||
}
|
||||
|
||||
/**
|
||||
Supprime les parties de l'element et les objets d'annulations.
|
||||
Les autres caracteristiques sont conservees.
|
||||
@@ -729,3 +937,200 @@ void ElementScene::reset() {
|
||||
qgiManager().release(qgi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@param content Contenu ( = parties) d'un element
|
||||
@return le boundingRect de ces parties, exprime dans les coordonnes de la
|
||||
scene
|
||||
*/
|
||||
QRectF ElementScene::elementContentBoundingRect(const ElementContent &content) {
|
||||
QRectF bounding_rect;
|
||||
foreach(QGraphicsItem *qgi, content) {
|
||||
bounding_rect |= qgi -> sceneBoundingRect();
|
||||
}
|
||||
return(bounding_rect);
|
||||
}
|
||||
|
||||
/**
|
||||
Applique les informations (dimensions, hostpot, orientations, connexions
|
||||
internes et noms) contenu dans un document XML.
|
||||
@param xml_document Document XML a analyser
|
||||
@param error_message pointeur vers une QString ; si error_message est
|
||||
different de 0, un message d'erreur sera stocke dedans si necessaire
|
||||
@return true si la lecture et l'application des informations s'est bien
|
||||
passee, false sinon.
|
||||
*/
|
||||
bool ElementScene::applyInformations(const QDomDocument &xml_document, QString *error_message) {
|
||||
// la racine est supposee etre une definition d'element
|
||||
QDomElement root = xml_document.documentElement();
|
||||
if (root.tagName() != "definition" || root.attribute("type") != "element") {
|
||||
if (error_message) {
|
||||
*error_message = tr("Ce document XML n'est pas une d\351finition d'\351l\351ment.", "error message");
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
// dimensions et hotspot : ces attributs doivent etre presents et valides
|
||||
int w, h, hot_x, hot_y;
|
||||
if (
|
||||
!QET::attributeIsAnInteger(root, QString("width"), &w) ||\
|
||||
!QET::attributeIsAnInteger(root, QString("height"), &h) ||\
|
||||
!QET::attributeIsAnInteger(root, QString("hotspot_x"), &hot_x) ||\
|
||||
!QET::attributeIsAnInteger(root, QString("hotspot_y"), &hot_y)
|
||||
) {
|
||||
if (error_message) {
|
||||
*error_message = tr("Les dimensions ou le point de saisie ne sont pas valides.", "error message");
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
//
|
||||
setWidth(w);
|
||||
setHeight(h);
|
||||
setHotspot(QPoint(hot_x, hot_y));
|
||||
|
||||
// orientations
|
||||
internal_connections = (root.attribute("ic") == "true");
|
||||
|
||||
// connexions internes
|
||||
if (!ori.fromString(root.attribute("orientation"))) {
|
||||
if (error_message) {
|
||||
*error_message = tr("Les orientations ne sont pas valides.", "error message");
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
// extrait les noms de la definition XML
|
||||
_names.fromXml(root);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
Par le document XML xml_document et retourne le contenu ( = liste de
|
||||
parties) correspondant.
|
||||
@param xml_document Document XML a analyser
|
||||
@param error_message pointeur vers une QString ; si error_message est
|
||||
different de 0, un message d'erreur sera stocke dedans si necessaire
|
||||
*/
|
||||
ElementContent ElementScene::loadContent(const QDomDocument &xml_document, QString *error_message) {
|
||||
ElementContent loaded_parts;
|
||||
|
||||
// la racine est supposee etre une definition d'element
|
||||
QDomElement root = xml_document.documentElement();
|
||||
if (root.tagName() != "definition" || root.attribute("type") != "element") {
|
||||
if (error_message) {
|
||||
*error_message = tr("Ce document XML n'est pas une d\351finition d'\351l\351ment.", "error message");
|
||||
}
|
||||
return(loaded_parts);
|
||||
}
|
||||
|
||||
// chargement de la description graphique de l'element
|
||||
for (QDomNode node = root.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
|
||||
QDomElement elmts = node.toElement();
|
||||
if (elmts.isNull()) continue;
|
||||
if (elmts.tagName() == "description") {
|
||||
|
||||
// = parcours des differentes parties du dessin
|
||||
int z = 1;
|
||||
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
|
||||
QDomElement qde = n.toElement();
|
||||
if (qde.isNull()) continue;
|
||||
CustomElementPart *cep;
|
||||
if (qde.tagName() == "line") cep = new PartLine (element_editor, 0, 0);
|
||||
else if (qde.tagName() == "rect") cep = new PartRectangle(element_editor, 0, 0);
|
||||
else if (qde.tagName() == "ellipse") cep = new PartEllipse (element_editor, 0, 0);
|
||||
else if (qde.tagName() == "circle") cep = new PartCircle (element_editor, 0, 0);
|
||||
else if (qde.tagName() == "polygon") cep = new PartPolygon (element_editor, 0, 0);
|
||||
else if (qde.tagName() == "terminal") cep = new PartTerminal (element_editor, 0, 0);
|
||||
else if (qde.tagName() == "text") cep = new PartText (element_editor, 0, 0);
|
||||
else if (qde.tagName() == "input") cep = new PartTextField(element_editor, 0, 0);
|
||||
else if (qde.tagName() == "arc") cep = new PartArc (element_editor, 0, 0);
|
||||
else continue;
|
||||
if (QGraphicsItem *qgi = dynamic_cast<QGraphicsItem *>(cep)) {
|
||||
qgi -> setZValue(z++);
|
||||
loaded_parts << qgi;
|
||||
}
|
||||
cep -> fromXml(qde);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(loaded_parts);
|
||||
}
|
||||
|
||||
/**
|
||||
Ajoute le contenu content a cet element
|
||||
@param content contenu ( = liste de parties) a charger
|
||||
@param error_message pointeur vers une QString ; si error_message est
|
||||
different de 0, un message d'erreur sera stocke dedans si necessaire
|
||||
@return Le contenu ajoute
|
||||
*/
|
||||
ElementContent ElementScene::addContent(const ElementContent &content, QString */*error_message*/) {
|
||||
foreach(QGraphicsItem *part, content) {
|
||||
addItem(part);
|
||||
}
|
||||
return(content);
|
||||
}
|
||||
|
||||
/**
|
||||
Ajoute le contenu content a cet element
|
||||
@param content contenu ( = liste de parties) a charger
|
||||
@param pos Position du coin superieur gauche du contenu apres avoir ete ajoute
|
||||
@param error_message pointeur vers une QString ; si error_message est
|
||||
different de 0, un message d'erreur sera stocke dedans si necessaire
|
||||
@return Le contenu ajoute
|
||||
*/
|
||||
ElementContent ElementScene::addContentAtPos(const ElementContent &content, const QPointF &pos, QString */*error_message*/) {
|
||||
// calcule le boundingRect du contenu a ajouter
|
||||
QRectF bounding_rect = elementContentBoundingRect(content);
|
||||
|
||||
// en deduit le decalage a appliquer aux parties pour les poser au point demander
|
||||
QPointF offset = pos - bounding_rect.topLeft();
|
||||
|
||||
// ajoute les parties avec le decalage adequat
|
||||
foreach(QGraphicsItem *part, content) {
|
||||
part -> setPos(part -> pos() + offset);
|
||||
addItem(part);
|
||||
}
|
||||
return(content);
|
||||
}
|
||||
|
||||
/**
|
||||
Initialise la zone de collage
|
||||
*/
|
||||
void ElementScene::initPasteArea() {
|
||||
paste_area_ = new QGraphicsRectItem();
|
||||
paste_area_ -> setZValue(1000000);
|
||||
|
||||
QPen paste_area_pen;
|
||||
paste_area_pen.setStyle(Qt::DashDotLine);
|
||||
paste_area_pen.setColor(QColor(30, 56, 86, 255));
|
||||
|
||||
QBrush paste_area_brush;
|
||||
paste_area_brush.setStyle(Qt::SolidPattern);
|
||||
paste_area_brush.setColor(QColor(90, 167, 255, 64));
|
||||
|
||||
paste_area_ -> setPen(paste_area_pen);
|
||||
paste_area_ -> setBrush(paste_area_brush);
|
||||
}
|
||||
|
||||
/**
|
||||
Arrondit les coordonnees du point passees en parametre de facon a ce que ce
|
||||
point soit aligne sur la grille.
|
||||
@param point une reference vers un QPointF. Cet objet sera modifie.
|
||||
|
||||
*/
|
||||
void ElementScene::snapToGrid(QPointF &point) {
|
||||
point.rx() = qRound(point.x() / x_grid) * x_grid;
|
||||
point.ry() = qRound(point.y() / y_grid) * y_grid;
|
||||
}
|
||||
|
||||
/**
|
||||
@param e Evenement souris
|
||||
@return true s'il faut utiliser le snap-to-grid
|
||||
Typiquement, cette methode retourne true si l'evenement souris se produit
|
||||
sans la touche Ctrl enfoncee.
|
||||
*/
|
||||
bool ElementScene::mustSnapToGrid(QGraphicsSceneMouseEvent *e) {
|
||||
return(!(e -> modifiers() & Qt::ControlModifier));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -22,8 +22,10 @@
|
||||
#include "nameslistwidget.h"
|
||||
#include "orientationsetwidget.h"
|
||||
#include "qgimanager.h"
|
||||
#include "elementcontent.h"
|
||||
class QETElementEditor;
|
||||
class PartLine;
|
||||
class PartRectangle;
|
||||
class PartEllipse;
|
||||
class PartCircle;
|
||||
class PartPolygon;
|
||||
@@ -38,7 +40,7 @@ class ElementScene : public QGraphicsScene {
|
||||
Q_OBJECT
|
||||
|
||||
// enum
|
||||
enum Behavior { Normal, Line, Circle, Ellipse, Polygon, Text, Terminal, Arc, TextField };
|
||||
enum Behavior { Normal, Line, Rectangle, Circle, Ellipse, Polygon, Text, Terminal, Arc, TextField, PasteArea };
|
||||
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
@@ -49,10 +51,6 @@ class ElementScene : public QGraphicsScene {
|
||||
ElementScene(const ElementScene &);
|
||||
|
||||
// attributs
|
||||
public:
|
||||
static const int xGrid; ///< Taille horizontale de la grille
|
||||
static const int yGrid; ///< Taille verticale de la grille
|
||||
|
||||
private:
|
||||
/// longueur de l'element en dizaines de pixels
|
||||
uint _width;
|
||||
@@ -72,16 +70,31 @@ class ElementScene : public QGraphicsScene {
|
||||
QUndoStack undo_stack;
|
||||
/// Position du premier item selectionne (utilise pour annuler les deplacements)
|
||||
QPointF fsi_pos;
|
||||
QPointF moving_press_pos;
|
||||
bool moving_parts_;
|
||||
|
||||
/// Variables relatives a la gestion du dessin des parties sur la scene
|
||||
Behavior behavior;
|
||||
PartLine *current_line;
|
||||
PartRectangle *current_rectangle;
|
||||
PartEllipse *current_ellipse;
|
||||
PartCircle *current_circle;
|
||||
PartPolygon *current_polygon;
|
||||
PartArc *current_arc;
|
||||
QETElementEditor *element_editor;
|
||||
|
||||
/// Variables relatives a la gestion de la zone de collage sur la scene
|
||||
QGraphicsRectItem *paste_area_;
|
||||
QRectF defined_paste_area_;
|
||||
|
||||
/// Variables relatives au copier-coller avec decalage
|
||||
QString last_copied_;
|
||||
|
||||
///< Taille horizontale de la grille
|
||||
int x_grid;
|
||||
///< Taille verticale de la grille
|
||||
int y_grid;
|
||||
|
||||
// methodes
|
||||
public:
|
||||
void setWidth(const uint &);
|
||||
@@ -96,13 +109,26 @@ class ElementScene : public QGraphicsScene {
|
||||
void setOrientations(const OrientationSet &);
|
||||
bool internalConnections();
|
||||
void setInternalConnections(bool);
|
||||
virtual const QDomDocument toXml() const;
|
||||
virtual void fromXml(const QDomDocument &);
|
||||
virtual int xGrid() const;
|
||||
virtual int yGrid() const;
|
||||
virtual void setGrid(int, int);
|
||||
virtual const QDomDocument toXml(bool = true) const;
|
||||
virtual QRectF boundingRectFromXml(const QDomDocument &);
|
||||
virtual void fromXml(const QDomDocument &, const QPointF & = QPointF(), bool = true, ElementContent * = 0);
|
||||
virtual void reset();
|
||||
virtual QList<QGraphicsItem *> zItems(bool = false) const;
|
||||
virtual ElementContent selectedContent() const;
|
||||
virtual void getPasteArea(const QRectF &);
|
||||
QRectF borderRect() const;
|
||||
QRectF sceneContent() const;
|
||||
bool borderContainsEveryParts() const;
|
||||
QUndoStack &undoStack();
|
||||
QGIManager &qgiManager();
|
||||
static bool clipboardMayContainElement();
|
||||
bool wasCopiedFromThisElement(const QString &);
|
||||
void cut();
|
||||
void copy();
|
||||
void paste();
|
||||
|
||||
protected:
|
||||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
|
||||
@@ -110,10 +136,22 @@ class ElementScene : public QGraphicsScene {
|
||||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
|
||||
virtual void drawBackground(QPainter *, const QRectF &);
|
||||
virtual void drawForeground(QPainter *, const QRectF &);
|
||||
virtual void endCurrentBehavior(const QGraphicsSceneMouseEvent *);
|
||||
|
||||
private:
|
||||
QRectF elementContentBoundingRect(const ElementContent &);
|
||||
bool applyInformations(const QDomDocument &, QString * = 0);
|
||||
ElementContent loadContent(const QDomDocument &, QString * = 0);
|
||||
ElementContent addContent(const ElementContent &, QString * = 0);
|
||||
ElementContent addContentAtPos(const ElementContent &, const QPointF &, QString * = 0);
|
||||
void initPasteArea();
|
||||
void snapToGrid(QPointF &);
|
||||
bool mustSnapToGrid(QGraphicsSceneMouseEvent *);
|
||||
|
||||
public slots:
|
||||
void slot_move();
|
||||
void slot_addLine();
|
||||
void slot_addRectangle();
|
||||
void slot_addCircle();
|
||||
void slot_addEllipse();
|
||||
void slot_addPolygon();
|
||||
@@ -145,6 +183,8 @@ class ElementScene : public QGraphicsScene {
|
||||
void partsRemoved();
|
||||
/// Signal emis lorsque la zValue d'une ou plusieurs parties change
|
||||
void partsZValueChanged();
|
||||
/// Signal emis lorsque l'utilisateur a fini de choisir une zone pour un copier/coller
|
||||
void pasteAreaDefined(const QRectF &);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -16,6 +16,8 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "elementview.h"
|
||||
#include "qetelementeditor.h"
|
||||
#include "editorcommands.h"
|
||||
/**
|
||||
Constructeur
|
||||
@param scene ElementScene visualisee par cette ElementView
|
||||
@@ -23,12 +25,14 @@
|
||||
*/
|
||||
ElementView::ElementView(ElementScene *scene, QWidget *parent) :
|
||||
QGraphicsView(scene, parent),
|
||||
scene_(scene)
|
||||
scene_(scene),
|
||||
offset_paste_count_(0)
|
||||
{
|
||||
setInteractive(true);
|
||||
setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
zoomReset();
|
||||
connect(scene_, SIGNAL(pasteAreaDefined(const QRectF &)), this, SLOT(pasteAreaDefined(const QRectF &)));
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
@@ -40,6 +44,24 @@ ElementScene *ElementView::scene() const {
|
||||
return(scene_);
|
||||
}
|
||||
|
||||
/**
|
||||
@return le rectangle de l'element visualise par cet ElementView
|
||||
*/
|
||||
QRectF ElementView::viewedSceneRect() const {
|
||||
// recupere la taille du widget viewport
|
||||
QSize viewport_size = viewport() -> size();
|
||||
|
||||
// recupere la transformation viewport -> scene
|
||||
QTransform view_to_scene = viewportTransform().inverted();
|
||||
|
||||
// mappe le coin superieur gauche et le coin inferieur droit de la viewport sur la scene
|
||||
QPointF scene_left_top = view_to_scene.map(QPointF(0.0, 0.0));
|
||||
QPointF scene_right_bottom = view_to_scene.map(QPointF(viewport_size.width(), viewport_size.height()));
|
||||
|
||||
// en deduit le rectangle visualise par la scene
|
||||
return(QRectF(scene_left_top, scene_right_bottom));
|
||||
}
|
||||
|
||||
/**
|
||||
Definit l'ElementScene visualisee par cette ElementView
|
||||
@param s l'ElementScene visualisee par cette ElementView
|
||||
@@ -110,6 +132,196 @@ void ElementView::adjustSceneRect() {
|
||||
scene_ -> update(old_scene_rect.united(new_scene_rect));
|
||||
}
|
||||
|
||||
/**
|
||||
Gere le fait de couper la selection = l'exporter en XML dans le
|
||||
presse-papier puis la supprimer.
|
||||
*/
|
||||
void ElementView::cut() {
|
||||
// delegue cette action a la scene
|
||||
scene_ -> cut();
|
||||
}
|
||||
|
||||
/**
|
||||
Gere le fait de copier la selection = l'exporter en XML dans le
|
||||
presse-papier.
|
||||
*/
|
||||
void ElementView::copy() {
|
||||
// delegue cette action a la scene
|
||||
scene_ -> copy();
|
||||
offset_paste_count_ = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Gere le fait de coller le contenu du presse-papier = l'importer dans
|
||||
l'element. Cette methode examine le contenu du presse-papier. Si celui-ci
|
||||
semble avoir ete copie depuis cet element, il est colle a cote de sa zone
|
||||
d'origine ; s'il est recolle, il sera colle un cran a cote de la zone deja
|
||||
recollee, etc.
|
||||
Sinon, cette methode demande a l'utilisateur de definir la zone ou le
|
||||
collage devra s'effectuer.
|
||||
@see pasteAreaDefined(const QRectF &)
|
||||
*/
|
||||
void ElementView::paste() {
|
||||
QString clipboard_text = QApplication::clipboard() -> text();
|
||||
if (clipboard_text.isEmpty()) return;
|
||||
|
||||
QDomDocument document_xml;
|
||||
if (!document_xml.setContent(clipboard_text)) return;
|
||||
|
||||
if (scene_ -> wasCopiedFromThisElement(clipboard_text)) {
|
||||
// copier/coller avec decalage
|
||||
pasteWithOffset(document_xml);
|
||||
} else {
|
||||
// copier/coller par choix de la zone de collage
|
||||
QRectF pasted_content_bounding_rect = scene_ -> boundingRectFromXml(document_xml);
|
||||
if (pasted_content_bounding_rect.isEmpty()) return;
|
||||
|
||||
to_paste_in_area_ = clipboard_text;
|
||||
getPasteArea(pasted_content_bounding_rect);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Colle le contenu du presse-papier en demandant systematiquement a
|
||||
l'utilisateur de choisir une zone de collage
|
||||
*/
|
||||
void ElementView::pasteInArea() {
|
||||
QString clipboard_text = QApplication::clipboard() -> text();
|
||||
if (clipboard_text.isEmpty()) return;
|
||||
|
||||
QDomDocument document_xml;
|
||||
if (!document_xml.setContent(clipboard_text)) return;
|
||||
|
||||
QRectF pasted_content_bounding_rect = scene_ -> boundingRectFromXml(document_xml);
|
||||
if (pasted_content_bounding_rect.isEmpty()) return;
|
||||
|
||||
// copier/coller par choix de la zone de collage
|
||||
to_paste_in_area_ = clipboard_text;
|
||||
getPasteArea(pasted_content_bounding_rect);
|
||||
}
|
||||
|
||||
/**
|
||||
Gere le fait de coller le contenu du presse-papier = l'importer dans
|
||||
l'element. Cette methode examine le contenu du presse-papier. Si celui-ci
|
||||
est exploitable, elle le colle a la position passee en parametre.
|
||||
@see pasteAreaDefined(const QRectF &)
|
||||
@param position Point de collage
|
||||
*/
|
||||
ElementContent ElementView::paste(const QPointF &position) {
|
||||
QString clipboard_text = QApplication::clipboard() -> text();
|
||||
if (clipboard_text.isEmpty()) return(ElementContent());
|
||||
|
||||
QDomDocument document_xml;
|
||||
if (!document_xml.setContent(clipboard_text)) return(ElementContent());
|
||||
|
||||
// objet pour recuperer le contenu ajoute au schema par le coller
|
||||
return(paste(document_xml, position));
|
||||
}
|
||||
|
||||
/**
|
||||
@param to_paste Rectangle englobant les parties a coller
|
||||
*/
|
||||
void ElementView::getPasteArea(const QRectF &to_paste) {
|
||||
// on copie le rectangle fourni - on s'interesse a ses dimensions, pas a sa position
|
||||
QRectF used_rect(to_paste);
|
||||
|
||||
// on lui attribue pour centre l'origine du repere
|
||||
if (underMouse()) {
|
||||
used_rect.moveCenter(mapToScene(mapFromGlobal(QCursor::pos())));
|
||||
} else {
|
||||
used_rect.moveCenter(QPointF(0.0, 0.0));
|
||||
}
|
||||
scene_ -> getPasteArea(used_rect);
|
||||
}
|
||||
|
||||
/**
|
||||
Slot appele lorsque la scene annonce avoir defini une zone de collage
|
||||
@param target_rect Rectangle cible pour le collage
|
||||
*/
|
||||
ElementContent ElementView::pasteAreaDefined(const QRectF &target_rect) {
|
||||
if (to_paste_in_area_.isEmpty()) return(ElementContent());
|
||||
|
||||
QDomDocument xml_document;
|
||||
if (!xml_document.setContent(to_paste_in_area_)) {
|
||||
to_paste_in_area_.clear();
|
||||
return(ElementContent());
|
||||
} else {
|
||||
return(paste(xml_document, target_rect.topLeft()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Colle le document XML xml_document a la position pos
|
||||
@param xml_document Document XML a coller
|
||||
@param pos Coin superieur gauche du rectangle cible
|
||||
*/
|
||||
ElementContent ElementView::paste(const QDomDocument &xml_document, const QPointF &pos) {
|
||||
// objet pour recuperer le contenu ajoute au schema par le coller
|
||||
ElementContent content_pasted;
|
||||
scene_ -> fromXml(xml_document, pos, false, &content_pasted);
|
||||
|
||||
// si quelque chose a effectivement ete ajoute au schema, on cree un objet d'annulation
|
||||
if (content_pasted.count()) {
|
||||
scene_ -> clearSelection();
|
||||
PastePartsCommand *undo_object = new PastePartsCommand(this, content_pasted);
|
||||
scene_ -> undoStack().push(undo_object);
|
||||
}
|
||||
return(content_pasted);
|
||||
}
|
||||
|
||||
/**
|
||||
Colle le document XML xml_document a la position pos
|
||||
@param xml_document Document XML a coller
|
||||
*/
|
||||
ElementContent ElementView::pasteWithOffset(const QDomDocument &xml_document) {
|
||||
// objet pour recuperer le contenu ajoute au schema par le coller
|
||||
ElementContent content_pasted;
|
||||
|
||||
// rectangle source
|
||||
QRectF pasted_content_bounding_rect = scene_ -> boundingRectFromXml(xml_document);
|
||||
if (pasted_content_bounding_rect.isEmpty()) return(content_pasted);
|
||||
|
||||
// copier/coller avec decalage
|
||||
++ offset_paste_count_;
|
||||
if (offset_paste_count_ == 1) {
|
||||
start_top_left_corner_ = pasted_content_bounding_rect.topLeft();
|
||||
} else {
|
||||
pasted_content_bounding_rect.moveTopLeft(start_top_left_corner_);
|
||||
}
|
||||
|
||||
// on applique le decalage qui convient
|
||||
QRectF final_pasted_content_bounding_rect = applyMovement(
|
||||
pasted_content_bounding_rect,
|
||||
QETElementEditor::pasteMovement(),
|
||||
QETElementEditor::pasteOffset()
|
||||
);
|
||||
|
||||
QPointF old_start_top_left_corner_ = start_top_left_corner_;
|
||||
start_top_left_corner_ = final_pasted_content_bounding_rect.topLeft();
|
||||
scene_ -> fromXml(xml_document, start_top_left_corner_, false, &content_pasted);
|
||||
|
||||
// si quelque chose a effectivement ete ajoute au schema, on cree un objet d'annulation
|
||||
if (content_pasted.count()) {
|
||||
scene_ -> clearSelection();
|
||||
PastePartsCommand *undo_object = new PastePartsCommand(this, content_pasted);
|
||||
undo_object -> setOffset(offset_paste_count_ - 1, old_start_top_left_corner_, offset_paste_count_, start_top_left_corner_);
|
||||
scene_ -> undoStack().push(undo_object);
|
||||
}
|
||||
return(content_pasted);
|
||||
}
|
||||
|
||||
/**
|
||||
Gere les clics sur la vue - permet de coller lorsaue l'on enfonce le bouton
|
||||
du milieu de la souris.
|
||||
@param e QMouseEvent decrivant l'evenement souris
|
||||
*/
|
||||
void ElementView::mousePressEvent(QMouseEvent *e) {
|
||||
if (e -> buttons() & Qt::MidButton) {
|
||||
paste(mapToScene(e -> pos()));
|
||||
}
|
||||
QGraphicsView::mousePressEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
Gere les actions liees a la rollette de la souris
|
||||
@param e QWheelEvent decrivant l'evenement rollette
|
||||
@@ -126,3 +338,107 @@ void ElementView::wheelEvent(QWheelEvent *e) {
|
||||
QAbstractScrollArea::wheelEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Dessine l'arriere-plan de l'editeur, cad la grille.
|
||||
@param p Le QPainter a utiliser pour dessiner
|
||||
@param r Le rectangle de la zone a dessiner
|
||||
*/
|
||||
void ElementView::drawBackground(QPainter *p, const QRectF &r) {
|
||||
p -> save();
|
||||
|
||||
// desactive tout antialiasing, sauf pour le texte
|
||||
p -> setRenderHint(QPainter::Antialiasing, false);
|
||||
p -> setRenderHint(QPainter::TextAntialiasing, true);
|
||||
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
|
||||
|
||||
// dessine un fond blanc
|
||||
p -> setPen(Qt::NoPen);
|
||||
p -> setBrush(Qt::white);
|
||||
p -> drawRect(r);
|
||||
|
||||
// encadre la zone dessinable de l'element
|
||||
QRectF drawable_area(-scene_ -> hotspot().x(), -scene_ -> hotspot().y(), scene_ -> width(), scene_ -> height());
|
||||
p -> setPen(Qt::black);
|
||||
p -> setBrush(Qt::NoBrush);
|
||||
p -> drawRect(drawable_area);
|
||||
|
||||
// determine le zoom en cours
|
||||
qreal zoom_factor = matrix().m11();
|
||||
|
||||
// choisit la granularite de la grille en fonction du zoom en cours
|
||||
int drawn_x_grid = scene_ -> xGrid();
|
||||
int drawn_y_grid = scene_ -> yGrid();
|
||||
bool draw_grid = true;
|
||||
bool draw_cross = false;
|
||||
if (zoom_factor < (4.0/3.0)) {
|
||||
// pas de grille du tout
|
||||
draw_grid = false;
|
||||
} else if (zoom_factor < 4.0) {
|
||||
// grille a 10 px
|
||||
drawn_x_grid *= 10;
|
||||
drawn_y_grid *= 10;
|
||||
} else if (zoom_factor < 6.0) {
|
||||
// grille a 2 px (avec croix)
|
||||
drawn_x_grid *= 2;
|
||||
drawn_y_grid *= 2;
|
||||
draw_cross = true;
|
||||
} else {
|
||||
// grille a 1 px (avec croix)
|
||||
draw_cross = true;
|
||||
}
|
||||
|
||||
if (draw_grid) {
|
||||
// dessine les points de la grille
|
||||
p -> setPen(Qt::black);
|
||||
p -> setBrush(Qt::NoBrush);
|
||||
qreal limite_x = r.x() + r.width();
|
||||
qreal limite_y = r.y() + r.height();
|
||||
|
||||
int g_x = (int)ceil(r.x());
|
||||
while (g_x % drawn_x_grid) ++ g_x;
|
||||
int g_y = (int)ceil(r.y());
|
||||
while (g_y % drawn_y_grid) ++ g_y;
|
||||
|
||||
for (int gx = g_x ; gx < limite_x ; gx += drawn_x_grid) {
|
||||
for (int gy = g_y ; gy < limite_y ; gy += drawn_y_grid) {
|
||||
if (draw_cross) {
|
||||
if (!(gx % 10) && !(gy % 10)) {
|
||||
p -> drawLine(QLineF(gx - 0.25, gy, gx + 0.25, gy));
|
||||
p -> drawLine(QLineF(gx, gy - 0.25, gx, gy + 0.25));
|
||||
} else {
|
||||
p -> drawPoint(gx, gy);
|
||||
}
|
||||
} else {
|
||||
p -> drawPoint(gx, gy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
p -> restore();
|
||||
}
|
||||
|
||||
/**
|
||||
Applique le decalage offset dans le sens movement au rectangle start
|
||||
@param start rectangle a decaler
|
||||
@param movement Orientation du decalage a appliquer
|
||||
@param offset Decalage a appliquer
|
||||
*/
|
||||
QRectF ElementView::applyMovement(const QRectF &start, const QET::OrientedMovement &movement, const QPointF &offset) {
|
||||
// calcule le decalage a appliquer a partir de l'offset indique et du mouvement
|
||||
QPointF final_offset;
|
||||
if (movement == QET::ToNorthEast || movement == QET::ToEast || movement == QET::ToSouthEast) {
|
||||
final_offset.rx() = start.width() + offset.x();
|
||||
} else if (movement == QET::ToNorthWest || movement == QET::ToWest || movement == QET::ToSouthWest) {
|
||||
final_offset.rx() = -start.width() - offset.x();
|
||||
}
|
||||
|
||||
if (movement == QET::ToNorthWest || movement == QET::ToNorth || movement == QET::ToNorthEast) {
|
||||
final_offset.ry() = -start.height() - offset.y();
|
||||
} else if (movement == QET::ToSouthWest || movement == QET::ToSouth || movement == QET::ToSouthEast) {
|
||||
final_offset.ry() = start.height() + offset.y();
|
||||
}
|
||||
|
||||
// applique le decalage ainsi calcule
|
||||
return(start.translated(final_offset));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -25,6 +25,8 @@
|
||||
*/
|
||||
class ElementView : public QGraphicsView {
|
||||
Q_OBJECT
|
||||
friend class PastePartsCommand;
|
||||
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
ElementView(ElementScene *, QWidget * = 0);
|
||||
@@ -37,9 +39,16 @@ class ElementView : public QGraphicsView {
|
||||
public:
|
||||
ElementScene *scene() const;
|
||||
void setScene(ElementScene *);
|
||||
QRectF viewedSceneRect() const;
|
||||
|
||||
protected:
|
||||
bool event(QEvent *);
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
void wheelEvent(QWheelEvent *);
|
||||
virtual void drawBackground(QPainter *, const QRectF &);
|
||||
|
||||
private:
|
||||
QRectF applyMovement(const QRectF &, const QET::OrientedMovement &, const QPointF &);
|
||||
|
||||
// slots
|
||||
public slots:
|
||||
@@ -48,9 +57,23 @@ class ElementView : public QGraphicsView {
|
||||
void zoomFit();
|
||||
void zoomReset();
|
||||
void adjustSceneRect();
|
||||
void cut();
|
||||
void copy();
|
||||
void paste();
|
||||
void pasteInArea();
|
||||
|
||||
private slots:
|
||||
void getPasteArea(const QRectF &);
|
||||
ElementContent pasteAreaDefined(const QRectF &);
|
||||
ElementContent paste(const QPointF &);
|
||||
ElementContent paste(const QDomDocument &, const QPointF &);
|
||||
ElementContent pasteWithOffset(const QDomDocument &);
|
||||
|
||||
//attributs
|
||||
private:
|
||||
ElementScene *scene_;
|
||||
QString to_paste_in_area_;
|
||||
int offset_paste_count_;
|
||||
QPointF start_top_left_corner_;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -63,9 +63,9 @@ EllipseEditor::~EllipseEditor() {
|
||||
*/
|
||||
void EllipseEditor::updateEllipse() {
|
||||
part -> setProperty("x", x -> text().toDouble());
|
||||
part -> setProperty("y", x -> text().toDouble());
|
||||
part -> setProperty("diameter_h", x -> text().toDouble());
|
||||
part -> setProperty("diameter_v", x -> text().toDouble());
|
||||
part -> setProperty("y", y -> text().toDouble());
|
||||
part -> setProperty("diameter_h", h -> text().toDouble());
|
||||
part -> setProperty("diameter_v", v -> text().toDouble());
|
||||
}
|
||||
|
||||
/// Met a jour l'abscisse du centre de l'ellipse et cree un objet d'annulation
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
#include "lineeditor.h"
|
||||
#include "partline.h"
|
||||
#include "qet.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@@ -38,16 +39,46 @@ LineEditor::LineEditor(QETElementEditor *editor, PartLine *line, QWidget *parent
|
||||
x2 -> setValidator(new QDoubleValidator(x2));
|
||||
y2 -> setValidator(new QDoubleValidator(y2));
|
||||
|
||||
QGridLayout *grid = new QGridLayout(this);
|
||||
grid -> addWidget(new QLabel("x1"), 0, 0);
|
||||
grid -> addWidget(x1, 0, 1);
|
||||
grid -> addWidget(new QLabel("y1"), 0, 2);
|
||||
grid -> addWidget(y1, 0, 3);
|
||||
grid -> addWidget(new QLabel("x2"), 1, 0);
|
||||
grid -> addWidget(x2, 1, 1);
|
||||
grid -> addWidget(new QLabel("y2"), 1, 2);
|
||||
grid -> addWidget(y2, 1, 3);
|
||||
end1_type = new QComboBox();
|
||||
end1_type -> addItem(QIcon(":/ico/endline-none.png"), tr("Normale", "type of the 1st end of a line"), QET::None );
|
||||
end1_type -> addItem(QIcon(":/ico/endline-simple.png"), tr("Fl\350che simple", "type of the 1st end of a line"), QET::Simple );
|
||||
end1_type -> addItem(QIcon(":/ico/endline-triangle.png"), tr("Fl\350che triangulaire", "type of the 1st end of a line"), QET::Triangle);
|
||||
end1_type -> addItem(QIcon(":/ico/endline-circle.png"), tr("Cercle", "type of the 1st end of a line"), QET::Circle );
|
||||
end1_type -> addItem(QIcon(":/ico/endline-diamond.png"), tr("Carr\351", "type of the 1st end of a line"), QET::Diamond );
|
||||
end2_type = new QComboBox();
|
||||
end2_type -> addItem(QIcon(":/ico/endline-none.png"), tr("Normale", "type of the 2nd end of a line"), QET::None );
|
||||
end2_type -> addItem(QIcon(":/ico/endline-simple.png"), tr("Fl\350che simple", "type of the 2nd end of a line"), QET::Simple );
|
||||
end2_type -> addItem(QIcon(":/ico/endline-triangle.png"), tr("Fl\350che triangulaire", "type of the 2nd end of a line"), QET::Triangle);
|
||||
end2_type -> addItem(QIcon(":/ico/endline-circle.png"), tr("Cercle", "type of the 2nd end of a line"), QET::Circle );
|
||||
end2_type -> addItem(QIcon(":/ico/endline-diamond.png"), tr("Carr\351", "type of the 2nd end of a line"), QET::Diamond );
|
||||
|
||||
end1_length = new QLineEdit();
|
||||
end2_length = new QLineEdit();
|
||||
|
||||
end1_length -> setValidator(new QDoubleValidator(end1_length));
|
||||
end2_length -> setValidator(new QDoubleValidator(end2_length));
|
||||
|
||||
QGridLayout *grid = new QGridLayout();
|
||||
grid -> addWidget(new QLabel("x1"), 0, 0);
|
||||
grid -> addWidget(x1, 0, 1);
|
||||
grid -> addWidget(new QLabel("y1"), 0, 2);
|
||||
grid -> addWidget(y1, 0, 3);
|
||||
grid -> addWidget(new QLabel("x2"), 1, 0);
|
||||
grid -> addWidget(x2, 1, 1);
|
||||
grid -> addWidget(new QLabel("y2"), 1, 2);
|
||||
grid -> addWidget(y2, 1, 3);
|
||||
|
||||
QGridLayout *grid2 = new QGridLayout();
|
||||
grid2 -> addWidget(new QLabel(tr("Fin 1")), 0, 0);
|
||||
grid2 -> addWidget(end1_type, 0, 1);
|
||||
grid2 -> addWidget(end1_length, 0, 2);
|
||||
grid2 -> addWidget(new QLabel(tr("Fin 2")), 1, 0);
|
||||
grid2 -> addWidget(end2_type, 1, 1);
|
||||
grid2 -> addWidget(end2_length, 1, 2);
|
||||
|
||||
QVBoxLayout *v_layout = new QVBoxLayout(this);
|
||||
v_layout -> addLayout(grid);
|
||||
v_layout -> addLayout(grid2);
|
||||
updateForm();
|
||||
}
|
||||
|
||||
@@ -59,6 +90,10 @@ LineEditor::~LineEditor() {
|
||||
Met a jour la ligne a partir des donnees du formulaire
|
||||
*/
|
||||
void LineEditor::updateLine() {
|
||||
part -> setFirstEndType(static_cast<QET::EndType>(end1_type -> currentIndex()));
|
||||
part -> setFirstEndLength(end1_length -> text().toDouble());
|
||||
part -> setSecondEndType(static_cast<QET::EndType>(end2_type -> currentIndex()));
|
||||
part -> setSecondEndLength(end2_length -> text().toDouble());
|
||||
part -> setLine(
|
||||
QLineF(
|
||||
part -> mapFromScene(
|
||||
@@ -81,6 +116,14 @@ void LineEditor::updateLineY1() { addChangePartCommand(tr("ordonn\351e point 1")
|
||||
void LineEditor::updateLineX2() { addChangePartCommand(tr("abscisse point 2"), part, "x2", x2 -> text().toDouble()); }
|
||||
/// Met a jour l'ordonnee du second point de la ligne et cree un objet d'annulation
|
||||
void LineEditor::updateLineY2() { addChangePartCommand(tr("ordonn\351e point 2"), part, "y2", y2 -> text().toDouble()); }
|
||||
/// Met a jour le type de la premiere extremite
|
||||
void LineEditor::updateLineEndType1() { addChangePartCommand(tr("type fin 1"), part, "end1", end1_type -> currentIndex()); }
|
||||
/// Met a jour la longueur de la premiere extremite
|
||||
void LineEditor::updateLineEndLength1() { addChangePartCommand(tr("longueur fin 1"), part, "length1", end1_length -> text()); }
|
||||
/// Met a jour le type de la seconde extremite
|
||||
void LineEditor::updateLineEndType2() { addChangePartCommand(tr("type fin 2"), part, "end2", end2_type -> currentIndex()); }
|
||||
/// Met a jour la longueur de la seconde extremite
|
||||
void LineEditor::updateLineEndLength2() { addChangePartCommand(tr("longueur fin 2"), part, "length2", end2_length -> text()); }
|
||||
|
||||
/**
|
||||
Met a jour le formulaire d'edition
|
||||
@@ -93,6 +136,10 @@ void LineEditor::updateForm() {
|
||||
y1 -> setText(QString("%1").arg(p1.y()));
|
||||
x2 -> setText(QString("%1").arg(p2.x()));
|
||||
y2 -> setText(QString("%1").arg(p2.y()));
|
||||
end1_type -> setCurrentIndex(part -> firstEndType());
|
||||
end1_length -> setText(QString("%1").arg(part -> firstEndLength()));
|
||||
end2_type -> setCurrentIndex(part -> secondEndType());
|
||||
end2_length -> setText(QString("%1").arg(part -> secondEndLength()));
|
||||
activeConnections(true);
|
||||
}
|
||||
|
||||
@@ -106,10 +153,18 @@ void LineEditor::activeConnections(bool active) {
|
||||
connect(y1, SIGNAL(editingFinished()), this, SLOT(updateLineY1()));
|
||||
connect(x2, SIGNAL(editingFinished()), this, SLOT(updateLineX2()));
|
||||
connect(y2, SIGNAL(editingFinished()), this, SLOT(updateLineY2()));
|
||||
connect(end1_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateLineEndType1()));
|
||||
connect(end1_length, SIGNAL(editingFinished()), this, SLOT(updateLineEndLength1()));
|
||||
connect(end2_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateLineEndType2()));
|
||||
connect(end2_length, SIGNAL(editingFinished()), this, SLOT(updateLineEndLength2()));
|
||||
} else {
|
||||
connect(x1, SIGNAL(editingFinished()), this, SLOT(updateLineX1()));
|
||||
connect(y1, SIGNAL(editingFinished()), this, SLOT(updateLineY1()));
|
||||
connect(x2, SIGNAL(editingFinished()), this, SLOT(updateLineX2()));
|
||||
connect(y2, SIGNAL(editingFinished()), this, SLOT(updateLineY2()));
|
||||
disconnect(x1, SIGNAL(editingFinished()), this, SLOT(updateLineX1()));
|
||||
disconnect(y1, SIGNAL(editingFinished()), this, SLOT(updateLineY1()));
|
||||
disconnect(x2, SIGNAL(editingFinished()), this, SLOT(updateLineX2()));
|
||||
disconnect(y2, SIGNAL(editingFinished()), this, SLOT(updateLineY2()));
|
||||
disconnect(end1_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateLineEndType1()));
|
||||
disconnect(end1_length, SIGNAL(editingFinished()), this, SLOT(updateLineEndLength1()));
|
||||
disconnect(end2_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateLineEndType2()));
|
||||
disconnect(end2_length, SIGNAL(editingFinished()), this, SLOT(updateLineEndLength2()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -37,6 +37,8 @@ class LineEditor : public ElementItemEditor {
|
||||
private:
|
||||
PartLine *part;
|
||||
QLineEdit *x1, *y1, *x2, *y2;
|
||||
QComboBox *end1_type, *end2_type;
|
||||
QLineEdit *end1_length, *end2_length;
|
||||
|
||||
// methodes
|
||||
public slots:
|
||||
@@ -45,6 +47,10 @@ class LineEditor : public ElementItemEditor {
|
||||
void updateLineY1();
|
||||
void updateLineX2();
|
||||
void updateLineY2();
|
||||
void updateLineEndType1();
|
||||
void updateLineEndLength1();
|
||||
void updateLineEndType2();
|
||||
void updateLineEndLength2();
|
||||
void updateForm();
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -159,6 +159,7 @@ void PartArc::setProperty(const QString &property, const QVariant &value) {
|
||||
} else if (property == "angle") {
|
||||
setAngle(value.toInt());
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -48,7 +48,7 @@ class PartArc : public QGraphicsEllipseItem, public CustomElementGraphicPart {
|
||||
*/
|
||||
virtual int type() const { return Type; }
|
||||
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
|
||||
virtual QString name() const { return(QObject::tr("arc")); }
|
||||
virtual QString name() const { return(QObject::tr("arc", "element part name")); }
|
||||
virtual const QDomElement toXml(QDomDocument &) const;
|
||||
virtual void fromXml(const QDomElement &);
|
||||
virtual QPointF sceneTopLeft() const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -125,6 +125,7 @@ void PartCircle::setProperty(const QString &property, const QVariant &value) {
|
||||
current_rect.setSize(QSizeF(new_diameter, new_diameter));
|
||||
setRect(current_rect);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -46,7 +46,7 @@ class PartCircle : public QGraphicsEllipseItem, public CustomElementGraphicPart
|
||||
*/
|
||||
virtual int type() const { return Type; }
|
||||
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
|
||||
virtual QString name() const { return(QObject::tr("cercle")); }
|
||||
virtual QString name() const { return(QObject::tr("cercle", "element part name")); }
|
||||
virtual const QDomElement toXml(QDomDocument &) const;
|
||||
virtual void fromXml(const QDomElement &);
|
||||
virtual QPointF sceneTopLeft() const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -129,6 +129,7 @@ void PartEllipse::setProperty(const QString &property, const QVariant &value) {
|
||||
current_rect.setHeight(new_height);
|
||||
setRect(current_rect);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -46,7 +46,7 @@ class PartEllipse : public QGraphicsEllipseItem, public CustomElementGraphicPart
|
||||
*/
|
||||
virtual int type() const { return Type; }
|
||||
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
|
||||
virtual QString name() const { return(QObject::tr("ellipse")); }
|
||||
virtual QString name() const { return(QObject::tr("ellipse", "element part name")); }
|
||||
virtual const QDomElement toXml(QDomDocument &) const;
|
||||
virtual void fromXml(const QDomElement &);
|
||||
virtual QPointF sceneTopLeft() const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -25,7 +25,14 @@
|
||||
@param parent Le QGraphicsItem parent de cette ligne
|
||||
@param scene La scene sur laquelle figure cette ligne
|
||||
*/
|
||||
PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsLineItem(parent, scene), CustomElementGraphicPart(editor) {
|
||||
PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
|
||||
QGraphicsLineItem(parent, scene),
|
||||
CustomElementGraphicPart(editor),
|
||||
first_end(QET::None),
|
||||
first_length(1.5),
|
||||
second_end(QET::None),
|
||||
second_length(1.5)
|
||||
{
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||
setAcceptedMouseButtons(Qt::LeftButton);
|
||||
informations = new LineEditor(elementEditor(), this);
|
||||
@@ -38,6 +45,20 @@ PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsSce
|
||||
PartLine::~PartLine() {
|
||||
}
|
||||
|
||||
/**
|
||||
@param end_type Type d'extremite
|
||||
@return Le nombre de "longueurs" requises pour dessiner une extremite de type end_type
|
||||
*/
|
||||
uint PartLine::requiredLengthForEndType(const QET::EndType &end_type) {
|
||||
uint length_count_required = 0;
|
||||
if (end_type == QET::Circle || end_type == QET::Diamond) {
|
||||
length_count_required = 2;
|
||||
} else if (end_type == QET::Simple || end_type == QET::Triangle) {
|
||||
length_count_required = 1;
|
||||
}
|
||||
return(length_count_required);
|
||||
}
|
||||
|
||||
/**
|
||||
Dessine la ligne
|
||||
@param painter QPainter a utiliser pour rendre le dessin
|
||||
@@ -45,14 +66,91 @@ PartLine::~PartLine() {
|
||||
@param widget Widget sur lequel le rendu est effectue
|
||||
*/
|
||||
void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem */*q*/, QWidget */*w*/) {
|
||||
// inutile de dessiner une ligne nulle
|
||||
if (line().p1() == line().p2()) return;
|
||||
applyStylesToQPainter(*painter);
|
||||
QPen t = painter -> pen();
|
||||
t.setJoinStyle(Qt::MiterJoin);
|
||||
if (isSelected()) {
|
||||
t.setColor(Qt::red);
|
||||
painter -> setPen(t);
|
||||
}
|
||||
painter -> setBrush(Qt::NoBrush);
|
||||
painter -> drawLine(line());
|
||||
painter -> setPen(t);
|
||||
|
||||
QPointF point1(line().p1());
|
||||
QPointF point2(line().p2());
|
||||
|
||||
qreal line_length(line().length());
|
||||
qreal pen_width = painter -> pen().widthF();
|
||||
|
||||
qreal length1 = first_length;
|
||||
qreal length2 = second_length;
|
||||
|
||||
//debugPaint(painter);
|
||||
|
||||
// determine s'il faut dessiner les extremites
|
||||
bool draw_1st_end, draw_2nd_end;
|
||||
qreal reduced_line_length = line_length - (length1 * requiredLengthForEndType(first_end));
|
||||
draw_1st_end = first_end && reduced_line_length >= 0;
|
||||
if (draw_1st_end) {
|
||||
reduced_line_length -= (length2 * requiredLengthForEndType(second_end));
|
||||
} else {
|
||||
reduced_line_length = line_length - (length2 * requiredLengthForEndType(second_end));
|
||||
}
|
||||
draw_2nd_end = second_end && reduced_line_length >= 0;
|
||||
|
||||
// dessine la premiere extremite
|
||||
QPointF start_point, stop_point;
|
||||
if (draw_1st_end) {
|
||||
QList<QPointF> four_points1(fourEndPoints(point1, point2, length1));
|
||||
if (first_end == QET::Circle) {
|
||||
painter -> drawEllipse(QRectF(four_points1[0] - QPointF(length1, length1), QSizeF(length1 * 2.0, length1 * 2.0)));
|
||||
start_point = four_points1[1];
|
||||
} else if (first_end == QET::Diamond) {
|
||||
painter -> drawPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3]);
|
||||
start_point = four_points1[1];
|
||||
} else if (first_end == QET::Simple) {
|
||||
painter -> drawPolyline(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
|
||||
start_point = point1;
|
||||
|
||||
} else if (first_end == QET::Triangle) {
|
||||
painter -> drawPolygon(QPolygonF() << four_points1[0] << four_points1[2] << point1 << four_points1[3]);
|
||||
start_point = four_points1[0];
|
||||
}
|
||||
|
||||
// ajuste le depart selon l'epaisseur du trait
|
||||
if (pen_width && (first_end == QET::Simple || first_end == QET::Circle)) {
|
||||
start_point = QLineF(start_point, point2).pointAt(pen_width / 2.0 / line_length);
|
||||
}
|
||||
} else {
|
||||
start_point = point1;
|
||||
}
|
||||
|
||||
// dessine la seconde extremite
|
||||
if (draw_2nd_end) {
|
||||
QList<QPointF> four_points2(fourEndPoints(point2, point1, length2));
|
||||
if (second_end == QET::Circle) {
|
||||
painter -> drawEllipse(QRectF(four_points2[0] - QPointF(length2, length2), QSizeF(length2 * 2.0, length2 * 2.0)));
|
||||
stop_point = four_points2[1];
|
||||
} else if (second_end == QET::Diamond) {
|
||||
painter -> drawPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1]);
|
||||
stop_point = four_points2[1];
|
||||
} else if (second_end == QET::Simple) {
|
||||
painter -> drawPolyline(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
|
||||
stop_point = point2;
|
||||
} else if (second_end == QET::Triangle) {
|
||||
painter -> drawPolygon(QPolygonF() << four_points2[0] << four_points2[2] << point2 << four_points2[3] << four_points2[0]);
|
||||
stop_point = four_points2[0];
|
||||
}
|
||||
|
||||
// ajuste l'arrivee selon l'epaisseur du trait
|
||||
if (pen_width && (second_end == QET::Simple || second_end == QET::Circle)) {
|
||||
stop_point = QLineF(point1, stop_point).pointAt((line_length - (pen_width / 2.0)) / line_length);
|
||||
}
|
||||
} else {
|
||||
stop_point = point2;
|
||||
}
|
||||
|
||||
painter -> drawLine(start_point, stop_point);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +168,11 @@ const QDomElement PartLine::toXml(QDomDocument &xml_document) const {
|
||||
xml_element.setAttribute("y1", QString("%1").arg(p1.y()));
|
||||
xml_element.setAttribute("x2", QString("%1").arg(p2.x()));
|
||||
xml_element.setAttribute("y2", QString("%1").arg(p2.y()));
|
||||
xml_element.setAttribute("end1", QET::endTypeToString(first_end));
|
||||
xml_element.setAttribute("length1", first_length);
|
||||
xml_element.setAttribute("end2", QET::endTypeToString(second_end));
|
||||
xml_element.setAttribute("length2", second_length);
|
||||
|
||||
stylesToXml(xml_element);
|
||||
return(xml_element);
|
||||
}
|
||||
@@ -92,6 +195,10 @@ void PartLine::fromXml(const QDomElement &qde) {
|
||||
)
|
||||
)
|
||||
);
|
||||
first_end = QET::endTypeFromString(qde.attribute("end1"));
|
||||
first_length = qde.attribute("length1", "1.5").toDouble();
|
||||
second_end = QET::endTypeFromString(qde.attribute("end2"));
|
||||
second_length = qde.attribute("length2", "1.5").toDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,6 +208,8 @@ void PartLine::fromXml(const QDomElement &qde) {
|
||||
* y1 : ordonnee du second point
|
||||
* x2 : abscisse du premier point
|
||||
* y2 : ordonnee du second point
|
||||
*end1 : type d'embout du premier point
|
||||
*end2 : type d'embout du second point
|
||||
@param value Valeur a attribuer a la propriete
|
||||
*/
|
||||
void PartLine::setProperty(const QString &property, const QVariant &value) {
|
||||
@@ -116,8 +225,20 @@ void PartLine::setProperty(const QString &property, const QVariant &value) {
|
||||
new_p2.setX(value.toDouble());
|
||||
} else if (property == "y2") {
|
||||
new_p2.setY(value.toDouble());
|
||||
} else setline = false;
|
||||
setLine(QLineF(mapFromScene(new_p1), mapFromScene(new_p2)));
|
||||
} else {
|
||||
setline = false;
|
||||
if (property == "end1") {
|
||||
setFirstEndType(static_cast<QET::EndType>(value.toUInt()));
|
||||
} else if (property == "end2") {
|
||||
setSecondEndType(static_cast<QET::EndType>(value.toUInt()));
|
||||
} else if (property == "length1") {
|
||||
setFirstEndLength(value.toDouble());
|
||||
} else if (property == "length2") {
|
||||
setSecondEndLength(value.toDouble());
|
||||
}
|
||||
}
|
||||
if (setline) setLine(QLineF(mapFromScene(new_p1), mapFromScene(new_p2)));
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,6 +263,14 @@ QVariant PartLine::property(const QString &property) {
|
||||
return(sceneP2().x());
|
||||
} else if (property == "y2") {
|
||||
return(sceneP2().y());
|
||||
} else if (property == "end1") {
|
||||
return(firstEndType());
|
||||
} else if (property == "end2") {
|
||||
return(secondEndType());
|
||||
} else if (property == "length1") {
|
||||
return(firstEndLength());
|
||||
} else if (property == "length2") {
|
||||
return(secondEndLength());
|
||||
}
|
||||
return(QVariant());
|
||||
}
|
||||
@@ -186,6 +315,24 @@ QPainterPath PartLine::shape() const {
|
||||
t.lineTo(points.at(2));
|
||||
t.lineTo(points.at(3));
|
||||
t.lineTo(points.at(0));
|
||||
|
||||
// n'en fait pas plus si la ligne se ramene a un point
|
||||
if (line().p1() == line().p2()) return(t);
|
||||
|
||||
// ajoute un cercle pour l'extremite 1 si besoin
|
||||
if (first_end) {
|
||||
QPainterPath t2;
|
||||
t2.addEllipse(firstEndCircleRect());
|
||||
t.addPath(t2.subtracted(t));
|
||||
}
|
||||
|
||||
// ajoute un cercle pour l'extremite 2 si besoin
|
||||
if (second_end) {
|
||||
QPainterPath t2;
|
||||
t2.addEllipse(secondEndCircleRect());
|
||||
t.addPath(t2.subtracted(t));
|
||||
}
|
||||
|
||||
return(t);
|
||||
}
|
||||
|
||||
@@ -233,12 +380,86 @@ QList<QPointF> PartLine::fourShapePoints() const {
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
@return le rectangle encadrant l'integralite de la premiere extremite
|
||||
*/
|
||||
QRectF PartLine::firstEndCircleRect() const {
|
||||
QList<QPointF> interesting_points = fourEndPoints(
|
||||
line().p1(),
|
||||
line().p2(),
|
||||
first_length
|
||||
);
|
||||
|
||||
QRectF end_rect(
|
||||
interesting_points[0] - QPointF(first_length, first_length),
|
||||
QSizeF(2.0 * first_length, 2.0 * first_length)
|
||||
);
|
||||
|
||||
return(end_rect);
|
||||
}
|
||||
|
||||
/**
|
||||
@return le rectangle encadrant l'integralite de la seconde extremite
|
||||
*/
|
||||
QRectF PartLine::secondEndCircleRect() const {
|
||||
QList<QPointF> interesting_points = fourEndPoints(
|
||||
line().p2(),
|
||||
line().p1(),
|
||||
second_length
|
||||
);
|
||||
|
||||
QRectF end_rect(
|
||||
interesting_points[0] - QPointF(second_length, second_length),
|
||||
QSizeF(2.0 * second_length, 2.0 * second_length)
|
||||
);
|
||||
|
||||
return(end_rect);
|
||||
}
|
||||
|
||||
/**
|
||||
Affiche differentes composantes du dessin :
|
||||
- le boundingRect
|
||||
- les point speciaux a chaque extremite
|
||||
- la quadrature du cercle a chaque extremite, meme si celle-ci est d'un
|
||||
autre type
|
||||
*/
|
||||
void PartLine::debugPaint(QPainter *painter) {
|
||||
painter -> save();
|
||||
painter -> setPen(Qt::gray);
|
||||
painter -> drawRect(boundingRect());
|
||||
|
||||
painter -> setPen(Qt::green);
|
||||
painter -> drawRect(firstEndCircleRect());
|
||||
painter -> drawRect(secondEndCircleRect());
|
||||
|
||||
painter -> setPen(Qt::red);
|
||||
foreach(QPointF pointy, fourEndPoints(line().p1(), line().p2(), first_length)) {
|
||||
painter -> drawEllipse(pointy, 0.1, 0.1);
|
||||
}
|
||||
foreach(QPointF pointy, fourEndPoints(line().p2(), line().p1(), second_length)) {
|
||||
painter -> drawEllipse(pointy, 0.1, 0.1);
|
||||
}
|
||||
|
||||
painter -> restore();
|
||||
}
|
||||
|
||||
/**
|
||||
@return le rectangle delimitant cette partie.
|
||||
*/
|
||||
QRectF PartLine::boundingRect() const {
|
||||
qreal adjust = 1.5;
|
||||
QRectF r(QGraphicsLineItem::boundingRect());
|
||||
|
||||
// cas special : le cercle sort largement du bounding rect originel
|
||||
if (first_end == QET::Circle) {
|
||||
r = r.united(firstEndCircleRect());
|
||||
}
|
||||
|
||||
if (second_end == QET::Circle) {
|
||||
r = r.united(secondEndCircleRect());
|
||||
}
|
||||
|
||||
// la taille du bounding rect est ajustee de 0.2px
|
||||
qreal adjust = 0.6;
|
||||
r.adjust(-adjust, -adjust, adjust, adjust);
|
||||
return(r);
|
||||
}
|
||||
@@ -251,3 +472,91 @@ QRectF PartLine::boundingRect() const {
|
||||
bool PartLine::isUseless() const {
|
||||
return(sceneP1() == sceneP2());
|
||||
}
|
||||
|
||||
/**
|
||||
@param end_type nouveau type d'embout pour l'extremite 1
|
||||
*/
|
||||
void PartLine::setFirstEndType(const QET::EndType &end_type) {
|
||||
first_end = end_type;
|
||||
}
|
||||
|
||||
/**
|
||||
@return le type d'embout pour l'extremite 1
|
||||
*/
|
||||
QET::EndType PartLine::firstEndType() const {
|
||||
return(first_end);
|
||||
}
|
||||
|
||||
/**
|
||||
@param end_type Nouveau type d'embout pour l'extremite 2
|
||||
*/
|
||||
void PartLine::setSecondEndType(const QET::EndType &end_type) {
|
||||
second_end = end_type;
|
||||
}
|
||||
|
||||
/**
|
||||
@return le type d'embout pour l'extremite 2
|
||||
*/
|
||||
QET::EndType PartLine::secondEndType() const {
|
||||
return(second_end);
|
||||
}
|
||||
|
||||
/**
|
||||
@return Les quatre points interessants a l'extremite d'une droite
|
||||
Ces points sont, dans l'ordre :
|
||||
* O : point sur la ligne, a une distance length de l'extremite
|
||||
* A : point sur la ligne a une distance 2 x length de l'extremite
|
||||
* B : point a une distance length de O - O est le projete de B sur la droite
|
||||
* C : point a une distance length de O - O est le projete de C sur la droite
|
||||
B et C sont situes de part et d'autre de la ligne
|
||||
@param end_point Extremite concernee
|
||||
@param other_point Autre point permettant de definir une ligne
|
||||
@param length Longueur a utiliser entre l'extremite et le point O
|
||||
*/
|
||||
QList<QPointF> PartLine::fourEndPoints(const QPointF &end_point, const QPointF &other_point, const qreal &length) {
|
||||
// vecteur et longueur de la ligne
|
||||
QPointF line_vector = end_point - other_point;
|
||||
qreal line_length = sqrt(pow(line_vector.x(), 2) + pow(line_vector.y(), 2));
|
||||
|
||||
// vecteur unitaire et vecteur perpendiculaire
|
||||
QPointF u(line_vector / line_length * length);
|
||||
QPointF v(-u.y(), u.x());
|
||||
|
||||
// points O, A, B et C
|
||||
QPointF o(end_point - u);
|
||||
QPointF a(o - u);
|
||||
QPointF b(o + v);
|
||||
QPointF c(o - v);
|
||||
|
||||
return(QList<QPointF>() << o << a << b << c);
|
||||
}
|
||||
|
||||
/**
|
||||
@param length nouvelle longueur de la premiere extremite
|
||||
la longueur de l'extemite ne peut exceder celle de la ligne
|
||||
*/
|
||||
void PartLine::setFirstEndLength(const qreal &length) {
|
||||
first_length = qMin(qAbs(length), line().length());
|
||||
}
|
||||
|
||||
/**
|
||||
@return longueur de la premiere extremite
|
||||
*/
|
||||
qreal PartLine::firstEndLength() const {
|
||||
return(first_length);
|
||||
}
|
||||
|
||||
/**
|
||||
@param length nouvelle longueur de la seconde extremite
|
||||
la longueur de l'extemite ne peut exceder celle de la ligne
|
||||
*/
|
||||
void PartLine::setSecondEndLength(const qreal &length) {
|
||||
second_length = qMin(qAbs(length), line().length());
|
||||
}
|
||||
|
||||
/**
|
||||
@return longueur de la seconde extremite
|
||||
*/
|
||||
qreal PartLine::secondEndLength() const {
|
||||
return(second_length);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -19,10 +19,18 @@
|
||||
#define PART_LINE_H
|
||||
#include <QtGui>
|
||||
#include "customelementgraphicpart.h"
|
||||
#include "qet.h"
|
||||
class LineEditor;
|
||||
/**
|
||||
Cette classe represente une ligne pouvant etre utilisee pour composer le
|
||||
dessin d'un element dans l'editeur d'element.
|
||||
Une ligne est composee de deux points. Elle peut comporter des extremites
|
||||
speciales definissables grace aux methodes setFirstEndType et
|
||||
setSecondEndType. La taille des extremites est definissable via les
|
||||
methodes setFirstEndLength et setSecondEndLength.
|
||||
A noter que les extremites ne sont pas dessinees si la longueur requise
|
||||
pour leur dessin n'est pas contenue dans la ligne. S'il n'y a de la place
|
||||
que pour une seule extremite, c'est la premiere qui est privilegiee.
|
||||
*/
|
||||
class PartLine : public QGraphicsLineItem, public CustomElementGraphicPart {
|
||||
// constructeurs, destructeur
|
||||
@@ -36,17 +44,22 @@ class PartLine : public QGraphicsLineItem, public CustomElementGraphicPart {
|
||||
// attributs
|
||||
private:
|
||||
LineEditor *informations;
|
||||
QET::EndType first_end;
|
||||
qreal first_length;
|
||||
QET::EndType second_end;
|
||||
qreal second_length;
|
||||
|
||||
// methodes
|
||||
public:
|
||||
enum { Type = UserType + 1104 };
|
||||
|
||||
/**
|
||||
permet de caster un QGraphicsItem en PartLine avec qgraphicsitem_cast
|
||||
@return le type de QGraphicsItem
|
||||
*/
|
||||
virtual int type() const { return Type; }
|
||||
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
|
||||
virtual QString name() const { return(QObject::tr("ligne")); }
|
||||
virtual QString name() const { return(QObject::tr("ligne", "element part name")); }
|
||||
virtual const QDomElement toXml(QDomDocument &) const;
|
||||
virtual void fromXml(const QDomElement &);
|
||||
virtual QPointF sceneP1() const;
|
||||
@@ -56,11 +69,23 @@ class PartLine : public QGraphicsLineItem, public CustomElementGraphicPart {
|
||||
virtual void setProperty(const QString &, const QVariant &);
|
||||
virtual QVariant property(const QString &);
|
||||
virtual bool isUseless() const;
|
||||
|
||||
virtual void setFirstEndType(const QET::EndType &);
|
||||
virtual QET::EndType firstEndType() const;
|
||||
virtual void setSecondEndType(const QET::EndType &);
|
||||
virtual QET::EndType secondEndType() const;
|
||||
virtual void setFirstEndLength(const qreal &);
|
||||
virtual qreal firstEndLength() const;
|
||||
virtual void setSecondEndLength(const qreal &);
|
||||
virtual qreal secondEndLength() const;
|
||||
static uint requiredLengthForEndType(const QET::EndType &);
|
||||
static QList<QPointF> fourEndPoints(const QPointF &, const QPointF &, const qreal &);
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||
|
||||
private:
|
||||
QList<QPointF> fourShapePoints() const;
|
||||
QRectF firstEndCircleRect() const;
|
||||
QRectF secondEndCircleRect() const;
|
||||
void debugPaint(QPainter *);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -114,6 +114,7 @@ void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWi
|
||||
void PartPolygon::setProperty(const QString &property, const QVariant &value) {
|
||||
CustomElementGraphicPart::setProperty(property, value);
|
||||
if (property == "closed") closed = value.toBool();
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -58,7 +58,7 @@ class PartPolygon : public QGraphicsPolygonItem, public CustomElementGraphicPart
|
||||
@return le type de QGraphicsItem
|
||||
*/
|
||||
virtual int type() const { return Type; }
|
||||
virtual QString name() const { return(QObject::tr("polygone")); }
|
||||
virtual QString name() const { return(QObject::tr("polygone", "element part name")); }
|
||||
void fromXml(const QDomElement &);
|
||||
const QDomElement toXml(QDomDocument &) const;
|
||||
virtual QRectF boundingRect() const;
|
||||
|
||||
207
sources/editor/partrectangle.cpp
Normal file
207
sources/editor/partrectangle.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
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 "partrectangle.h"
|
||||
#include "rectangleeditor.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param editor L'editeur d'element concerne
|
||||
@param parent Le QGraphicsItem parent de ce rectangle
|
||||
@param scene La scene sur laquelle figure ce rectangle
|
||||
*/
|
||||
PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsRectItem(parent, scene), CustomElementGraphicPart(editor) {
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||
setAcceptedMouseButtons(Qt::LeftButton);
|
||||
informations = new RectangleEditor(elementEditor(), this);
|
||||
informations -> setElementTypeName(name());
|
||||
style_editor -> appendWidget(informations);
|
||||
style_editor -> setElementTypeName(name());
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
PartRectangle::~PartRectangle() {
|
||||
}
|
||||
|
||||
/**
|
||||
Dessine le rectangle
|
||||
@param painter QPainter a utiliser pour rendre le dessin
|
||||
@param options Options pour affiner le rendu
|
||||
@param widget Widget sur lequel le rendu est effectue
|
||||
*/
|
||||
void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
|
||||
applyStylesToQPainter(*painter);
|
||||
QPen t = painter -> pen();
|
||||
if (isSelected()) {
|
||||
t.setColor(Qt::red);
|
||||
}
|
||||
|
||||
// force le type de jointures pour les rectangles
|
||||
t.setJoinStyle(Qt::MiterJoin);
|
||||
|
||||
// force le dessin avec un trait fin si l'une des dimensions du rectangle est nulle
|
||||
if (!rect().width() || !rect().height()) {
|
||||
t.setWidth(0);
|
||||
}
|
||||
|
||||
painter -> setPen(t);
|
||||
painter -> drawRect(rect());
|
||||
if (isSelected()) {
|
||||
painter -> setRenderHint(QPainter::Antialiasing, false);
|
||||
painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
|
||||
QPointF center = rect().center();
|
||||
painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
|
||||
painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Exporte le rectangle en XML
|
||||
@param xml_document Document XML a utiliser pour creer l'element XML
|
||||
@return un element XML decrivant le rectangle
|
||||
*/
|
||||
const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const {
|
||||
QDomElement xml_element = xml_document.createElement("rect");
|
||||
QPointF top_left(sceneTopLeft());
|
||||
xml_element.setAttribute("x", QString("%1").arg(top_left.x()));
|
||||
xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
|
||||
xml_element.setAttribute("width", QString("%1").arg(rect().width()));
|
||||
xml_element.setAttribute("height", QString("%1").arg(rect().height()));
|
||||
stylesToXml(xml_element);
|
||||
return(xml_element);
|
||||
}
|
||||
|
||||
/**
|
||||
Importe les proprietes d'une rectangle depuis un element XML
|
||||
@param qde Element XML a lire
|
||||
*/
|
||||
void PartRectangle::fromXml(const QDomElement &qde) {
|
||||
stylesFromXml(qde);
|
||||
setRect(
|
||||
QRectF(
|
||||
mapFromScene(
|
||||
qde.attribute("x", "0").toDouble(),
|
||||
qde.attribute("y", "0").toDouble()
|
||||
),
|
||||
QSizeF(
|
||||
qde.attribute("width", "0").toDouble(),
|
||||
qde.attribute("height", "0").toDouble()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Specifie la valeur d'une propriete donnee du rectangle
|
||||
@param property propriete a modifier. Valeurs acceptees :
|
||||
* x : abscisse du coin superieur gauche du rectangle
|
||||
* y : ordonnee du coin superieur gauche du rectangle
|
||||
* width : largeur du rectangle
|
||||
* height : hauteur du rectangle
|
||||
@param value Valeur a attribuer a la propriete
|
||||
*/
|
||||
void PartRectangle::setProperty(const QString &property, const QVariant &value) {
|
||||
CustomElementGraphicPart::setProperty(property, value);
|
||||
if (!value.canConvert(QVariant::Double)) return;
|
||||
if (property == "x") {
|
||||
QRectF current_rect = rect();
|
||||
QPointF current_pos = mapToScene(current_rect.topLeft());
|
||||
setRect(current_rect.translated(value.toDouble() - current_pos.x(), 0.0));
|
||||
} else if (property == "y") {
|
||||
QRectF current_rect = rect();
|
||||
QPointF current_pos = mapToScene(current_rect.topLeft());
|
||||
setRect(current_rect.translated(0.0, value.toDouble() - current_pos.y()));
|
||||
} else if (property == "width") {
|
||||
qreal new_width = qAbs(value.toDouble());
|
||||
QRectF current_rect = rect();
|
||||
current_rect.setWidth(new_width);
|
||||
setRect(current_rect);
|
||||
} else if (property == "height") {
|
||||
qreal new_height = qAbs(value.toDouble());
|
||||
QRectF current_rect = rect();
|
||||
current_rect.setHeight(new_height);
|
||||
setRect(current_rect);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
Permet d'acceder a la valeur d'une propriete donnee du rectangle
|
||||
@param property propriete lue. Valeurs acceptees :
|
||||
* x : abscisse du coin superieur gauche du rectangle
|
||||
* y : ordonnee du coin superieur gauche du rectangle
|
||||
* width : largeur du rectangle
|
||||
* height : hauteur du rectangle
|
||||
@return La valeur de la propriete property
|
||||
*/
|
||||
QVariant PartRectangle::property(const QString &property) {
|
||||
// appelle la methode property de CustomElementGraphicpart pour les styles
|
||||
QVariant style_property = CustomElementGraphicPart::property(property);
|
||||
if (style_property != QVariant()) return(style_property);
|
||||
|
||||
if (property == "x") {
|
||||
return(mapToScene(rect().topLeft()).x());
|
||||
} else if (property == "y") {
|
||||
return(mapToScene(rect().topLeft()).y());
|
||||
} else if (property == "width") {
|
||||
return(rect().width());
|
||||
} else if (property == "height") {
|
||||
return(rect().height());
|
||||
}
|
||||
return(QVariant());
|
||||
}
|
||||
|
||||
/**
|
||||
Gere les changements intervenant sur cette partie
|
||||
@param change Type de changement
|
||||
@param value Valeur numerique relative au changement
|
||||
*/
|
||||
QVariant PartRectangle::itemChange(GraphicsItemChange change, const QVariant &value) {
|
||||
if (scene()) {
|
||||
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
|
||||
informations -> updateForm();
|
||||
}
|
||||
}
|
||||
return(QGraphicsRectItem::itemChange(change, value));
|
||||
}
|
||||
|
||||
/**
|
||||
@return le coin superieur gauche du rectangle, dans les coordonnees de la
|
||||
scene.
|
||||
*/
|
||||
QPointF PartRectangle::sceneTopLeft() const {
|
||||
return(mapToScene(rect().topLeft()));
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
|
||||
conservee / enregistree.
|
||||
Un rectangle est pertinent des lors que ses dimensions ne sont pas nulles.
|
||||
*/
|
||||
bool PartRectangle::isUseless() const {
|
||||
return(rect().isNull());
|
||||
}
|
||||
|
||||
/**
|
||||
@return le rectangle delimitant cette partie.
|
||||
*/
|
||||
QRectF PartRectangle::boundingRect() const {
|
||||
qreal adjust = 1.5;
|
||||
QRectF r(QGraphicsRectItem::boundingRect().normalized());
|
||||
r.adjust(-adjust, -adjust, adjust, adjust);
|
||||
return(r);
|
||||
}
|
||||
61
sources/editor/partrectangle.h
Normal file
61
sources/editor/partrectangle.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
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 PART_RECTANGLE_H
|
||||
#define PART_RECTANGLE_H
|
||||
#include <QtGui>
|
||||
#include "customelementgraphicpart.h"
|
||||
class RectangleEditor;
|
||||
/**
|
||||
Cette classe represente un rectangle pouvant etre utilise pour composer le
|
||||
dessin d'un element dans l'editeur d'element.
|
||||
*/
|
||||
class PartRectangle : public QGraphicsRectItem, public CustomElementGraphicPart {
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
PartRectangle(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
|
||||
virtual ~PartRectangle();
|
||||
|
||||
private:
|
||||
PartRectangle(const PartRectangle &);
|
||||
|
||||
// attributs
|
||||
private:
|
||||
RectangleEditor *informations;
|
||||
|
||||
// methodes
|
||||
public:
|
||||
enum { Type = UserType + 1109 };
|
||||
/**
|
||||
permet de caster un QGraphicsItem en PartRectangle avec qgraphicsitem_cast
|
||||
@return le type de QGraphicsItem
|
||||
*/
|
||||
virtual int type() const { return Type; }
|
||||
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
|
||||
virtual QString name() const { return(QObject::tr("rectangle", "element part name")); }
|
||||
virtual const QDomElement toXml(QDomDocument &) const;
|
||||
virtual void fromXml(const QDomElement &);
|
||||
virtual QPointF sceneTopLeft() const;
|
||||
virtual QRectF boundingRect() const;
|
||||
virtual void setProperty(const QString &, const QVariant &);
|
||||
virtual QVariant property(const QString &);
|
||||
virtual bool isUseless() const;
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||
};
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -39,6 +39,7 @@ PartTerminal::PartTerminal(QETElementEditor *editor, QGraphicsItem *parent, QGra
|
||||
|
||||
/// Destructeur
|
||||
PartTerminal::~PartTerminal() {
|
||||
if (informations -> parentWidget()) return; // le widget sera supprime par son parent
|
||||
delete informations;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -48,7 +48,7 @@ class PartTerminal : public CustomElementPart, public QGraphicsItem {
|
||||
@return le type de QGraphicsItem
|
||||
*/
|
||||
virtual int type() const { return Type; }
|
||||
virtual QString name() const { return(QObject::tr("borne")); }
|
||||
virtual QString name() const { return(QObject::tr("borne", "element part name")); }
|
||||
virtual void fromXml(const QDomElement &);
|
||||
virtual const QDomElement toXml(QDomDocument &) const;
|
||||
virtual QWidget *elementInformations();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -33,14 +33,14 @@ PartText::PartText(QETElementEditor *editor, QGraphicsItem *parent, ElementScene
|
||||
{
|
||||
setDefaultTextColor(Qt::black);
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||
setPlainText(QObject::tr("T"));
|
||||
setPlainText(QObject::tr("T", "default text when adding a text in the element editor"));
|
||||
infos = new TextEditor(elementEditor(), this);
|
||||
infos -> setElementTypeName(name());
|
||||
}
|
||||
|
||||
|
||||
/// Destructeur
|
||||
PartText::~PartText() {
|
||||
if (infos -> parentWidget()) return; // le widget sera supprime par son parent
|
||||
delete infos;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ void PartText::focusOutEvent(QFocusEvent *e) {
|
||||
if (previous_text != toPlainText()) {
|
||||
undoStack().push(
|
||||
new ChangePartCommand(
|
||||
TextEditor::tr("texte") + " " + name(),
|
||||
TextEditor::tr("contenu") + " " + name(),
|
||||
this,
|
||||
"text",
|
||||
previous_text,
|
||||
@@ -139,6 +139,13 @@ void PartText::focusOutEvent(QFocusEvent *e) {
|
||||
);
|
||||
previous_text = toPlainText();
|
||||
}
|
||||
|
||||
// deselectionne le texte
|
||||
QTextCursor qtc = textCursor();
|
||||
qtc.clearSelection();
|
||||
setTextCursor(qtc);
|
||||
|
||||
setTextInteractionFlags(Qt::NoTextInteraction);
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||
}
|
||||
|
||||
@@ -176,6 +183,7 @@ void PartText::setProperty(const QString &property, const QVariant &value) {
|
||||
} else if (property == "text") {
|
||||
setPlainText(value.toString());
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -44,7 +44,7 @@ class PartText : public QGraphicsTextItem, public CustomElementPart {
|
||||
@return le type de QGraphicsItem
|
||||
*/
|
||||
virtual int type() const { return Type; }
|
||||
virtual QString name() const { return(QObject::tr("texte")); }
|
||||
virtual QString name() const { return(QObject::tr("texte", "element part name")); }
|
||||
void fromXml(const QDomElement &);
|
||||
const QDomElement toXml(QDomDocument &) const;
|
||||
QWidget *elementInformations();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -33,13 +33,14 @@ PartTextField::PartTextField(QETElementEditor *editor, QGraphicsItem *parent, QG
|
||||
{
|
||||
setDefaultTextColor(Qt::black);
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||
setPlainText(QObject::tr("_"));
|
||||
setPlainText(QObject::tr("_", "default text when adding a textfield in the element editor"));
|
||||
infos = new TextFieldEditor(elementEditor(), this);
|
||||
infos -> setElementTypeName(name());
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
PartTextField::~PartTextField() {
|
||||
if (infos -> parentWidget()) return; // le widget sera supprime par son parent
|
||||
delete infos;
|
||||
}
|
||||
|
||||
@@ -148,7 +149,7 @@ void PartTextField::focusOutEvent(QFocusEvent *e) {
|
||||
if (previous_text != toPlainText()) {
|
||||
undoStack().push(
|
||||
new ChangePartCommand(
|
||||
TextFieldEditor::tr("texte") + " " + name(),
|
||||
TextFieldEditor::tr("contenu") + " " + name(),
|
||||
this,
|
||||
"text",
|
||||
previous_text,
|
||||
@@ -157,6 +158,13 @@ void PartTextField::focusOutEvent(QFocusEvent *e) {
|
||||
);
|
||||
previous_text = toPlainText();
|
||||
}
|
||||
|
||||
// deselectionne le texte
|
||||
QTextCursor qtc = textCursor();
|
||||
qtc.clearSelection();
|
||||
setTextCursor(qtc);
|
||||
|
||||
setTextInteractionFlags(Qt::NoTextInteraction);
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||
}
|
||||
|
||||
@@ -197,6 +205,7 @@ void PartTextField::setProperty(const QString &property, const QVariant &value)
|
||||
} else if (property == "rotate") {
|
||||
follow_parent_rotations = value.toBool();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -48,7 +48,7 @@ class PartTextField : public QGraphicsTextItem, public CustomElementPart {
|
||||
@return le type de QGraphicsItem
|
||||
*/
|
||||
virtual int type() const { return Type; }
|
||||
virtual QString name() const { return(QObject::tr("champ de texte")); }
|
||||
virtual QString name() const { return(QObject::tr("champ de texte", "element part name")); }
|
||||
void fromXml(const QDomElement &);
|
||||
const QDomElement toXml(QDomDocument &) const;
|
||||
QWidget *elementInformations();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -69,8 +69,8 @@ void PolygonEditor::updatePolygonPoints() {
|
||||
if (points.count() < 2) {
|
||||
QMessageBox::warning(
|
||||
this,
|
||||
tr("Erreur"),
|
||||
tr("Le polygone doit comporter au moins deux points.")
|
||||
tr("Erreur", "message box title"),
|
||||
tr("Le polygone doit comporter au moins deux points.", "message box content")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "customelementpart.h"
|
||||
#include "newelementwizard.h"
|
||||
#include "elementitemeditor.h"
|
||||
#include "elementdefinition.h"
|
||||
#include "elementdialog.h"
|
||||
#include "recentfiles.h"
|
||||
|
||||
/**
|
||||
@@ -31,8 +33,8 @@
|
||||
QETElementEditor::QETElementEditor(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
read_only(false),
|
||||
min_title(tr("QElectroTech - \311diteur d'\351l\351ment")),
|
||||
_filename(QString())
|
||||
min_title(tr("QElectroTech - \311diteur d'\351l\351ment", "window title")),
|
||||
opened_from_file(false)
|
||||
{
|
||||
setWindowTitle(min_title);
|
||||
setWindowIcon(QIcon(":/ico/qet.png"));
|
||||
@@ -47,6 +49,7 @@ QETElementEditor::QETElementEditor(QWidget *parent) :
|
||||
|
||||
// lecture des parametres
|
||||
readSettings();
|
||||
slot_updateMenus();
|
||||
|
||||
// affichage
|
||||
show();
|
||||
@@ -62,12 +65,18 @@ QETElementEditor::~QETElementEditor() {
|
||||
void QETElementEditor::setupActions() {
|
||||
new_element = new QAction(QIcon(":/ico/new.png"), tr("&Nouveau"), this);
|
||||
open = new QAction(QIcon(":/ico/open.png"), tr("&Ouvrir"), this);
|
||||
open_file = new QAction(QIcon(":/ico/open.png"), tr("&Ouvrir depuis un fichier"), this);
|
||||
save = new QAction(QIcon(":/ico/save.png"), tr("&Enregistrer"), this);
|
||||
save_as = new QAction(QIcon(":/ico/saveas.png"), tr("Enregistrer sous"), this);
|
||||
save_as_file = new QAction(QIcon(":/ico/saveas.png"), tr("Enregistrer dans un fichier"), this);
|
||||
reload = new QAction(QIcon(":/ico/reload.png"), tr("Recharger"), this);
|
||||
quit = new QAction(QIcon(":/ico/exit.png"), tr("&Quitter"), this);
|
||||
selectall = new QAction( tr("Tout s\351lectionner"), this);
|
||||
deselectall = new QAction( tr("D\351s\351lectionner tout"), this);
|
||||
cut = new QAction(QIcon(":/ico/cut.png"), tr("Co&uper"), this);
|
||||
copy = new QAction(QIcon(":/ico/copy.png"), tr("Cop&ier"), this);
|
||||
paste = new QAction(QIcon(":/ico/paste.png"), tr("C&oller"), this);
|
||||
paste_in_area = new QAction(QIcon(":/ico/paste.png"), tr("C&oller dans la zone..."), this);
|
||||
inv_select = new QAction( tr("Inverser la s\351lection"), this);
|
||||
edit_delete = new QAction(QIcon(":/ico/delete.png"), tr("&Supprimer"), this);
|
||||
zoom_in = new QAction(QIcon(":/ico/viewmag+.png"), tr("Zoom avant"), this);
|
||||
@@ -83,6 +92,7 @@ void QETElementEditor::setupActions() {
|
||||
edit_forward = new QAction(QIcon(":/ico/bring_forward.png"),tr("Amener au premier plan"), this);
|
||||
move = new QAction(QIcon(":/ico/select.png"), tr("D\351placer un objet"), this);
|
||||
add_line = new QAction(QIcon(":/ico/line.png"), tr("Ajouter une ligne"), this);
|
||||
add_rectangle = new QAction(QIcon(":/ico/rectangle.png"), tr("Ajouter un rectangle"), this);
|
||||
add_ellipse = new QAction(QIcon(":/ico/ellipse.png"), tr("Ajouter une ellipse"), this);
|
||||
add_circle = new QAction(QIcon(":/ico/circle.png"), tr("Ajouter un cercle"), this);
|
||||
add_polygon = new QAction(QIcon(":/ico/polygon.png"), tr("Ajouter un polygone"), this);
|
||||
@@ -91,6 +101,17 @@ void QETElementEditor::setupActions() {
|
||||
add_terminal = new QAction(QIcon(":/ico/terminal.png"), tr("Ajouter une borne"), this);
|
||||
add_textfield = new QAction(QIcon(":/ico/textfield.png"), tr("Ajouter un champ de texte"), this);
|
||||
|
||||
QString add_status_tip = tr("Maintenez la touche Shift enfonc\351e pour effectuer plusieurs ajouts d'affil\351e");
|
||||
add_line -> setStatusTip(add_status_tip);
|
||||
add_rectangle -> setStatusTip(add_status_tip);
|
||||
add_ellipse -> setStatusTip(add_status_tip);
|
||||
add_circle -> setStatusTip(add_status_tip);
|
||||
add_text -> setStatusTip(add_status_tip);
|
||||
add_arc -> setStatusTip(add_status_tip);
|
||||
add_terminal -> setStatusTip(add_status_tip);
|
||||
add_textfield -> setStatusTip(add_status_tip);
|
||||
add_polygon -> setStatusTip(tr("Utilisez le bouton droit de la souris pour poser le dernier point du polygone"));
|
||||
|
||||
undo = ce_scene -> undoStack().createUndoAction(this, tr("Annuler"));
|
||||
redo = ce_scene -> undoStack().createRedoAction(this, tr("Refaire"));
|
||||
undo -> setIcon(QIcon(":/ico/undo.png"));
|
||||
@@ -100,12 +121,18 @@ void QETElementEditor::setupActions() {
|
||||
|
||||
new_element -> setShortcut(QKeySequence::New);
|
||||
open -> setShortcut(QKeySequence::Open);
|
||||
open_file -> setShortcut(tr("Ctrl+Shift+O"));
|
||||
save -> setShortcut(QKeySequence::Save);
|
||||
save_as_file -> setShortcut(tr("Ctrl+Shift+S"));
|
||||
reload -> setShortcut(Qt::Key_F5);
|
||||
quit -> setShortcut(QKeySequence(tr("Ctrl+Q")));
|
||||
selectall -> setShortcut(QKeySequence::SelectAll);
|
||||
deselectall -> setShortcut(QKeySequence(tr("Ctrl+Shift+A")));
|
||||
inv_select -> setShortcut(QKeySequence(tr("Ctrl+I")));
|
||||
cut -> setShortcut(QKeySequence::Cut);
|
||||
copy -> setShortcut(QKeySequence::Copy);
|
||||
paste -> setShortcut(QKeySequence::Paste);
|
||||
paste_in_area -> setShortcut(tr("Ctrl+Shift+V"));
|
||||
edit_delete -> setShortcut(QKeySequence(tr("Suppr")));
|
||||
|
||||
zoom_in -> setShortcut(QKeySequence::ZoomIn);
|
||||
@@ -124,13 +151,19 @@ void QETElementEditor::setupActions() {
|
||||
|
||||
connect(new_element, SIGNAL(triggered()), this, SLOT(slot_new()));
|
||||
connect(open, SIGNAL(triggered()), this, SLOT(slot_open()));
|
||||
connect(open_file, SIGNAL(triggered()), this, SLOT(slot_openFile()));
|
||||
connect(save, SIGNAL(triggered()), this, SLOT(slot_save()));
|
||||
connect(save_as, SIGNAL(triggered()), this, SLOT(slot_saveAs()));
|
||||
connect(save_as_file, SIGNAL(triggered()), this, SLOT(slot_saveAsFile()));
|
||||
connect(reload, SIGNAL(triggered()), this, SLOT(slot_reload()));
|
||||
connect(quit, SIGNAL(triggered()), this, SLOT(close()));
|
||||
connect(selectall, SIGNAL(triggered()), ce_scene, SLOT(slot_selectAll()));
|
||||
connect(deselectall, SIGNAL(triggered()), ce_scene, SLOT(slot_deselectAll()));
|
||||
connect(inv_select, SIGNAL(triggered()), ce_scene, SLOT(slot_invertSelection()));
|
||||
connect(cut, SIGNAL(triggered()), ce_view, SLOT(cut()));
|
||||
connect(copy, SIGNAL(triggered()), ce_view, SLOT(copy()));
|
||||
connect(paste, SIGNAL(triggered()), ce_view, SLOT(paste()));
|
||||
connect(paste_in_area, SIGNAL(triggered()), ce_view, SLOT(pasteInArea()));
|
||||
connect(zoom_in, SIGNAL(triggered()), ce_view, SLOT(zoomIn()));
|
||||
connect(zoom_out, SIGNAL(triggered()), ce_view, SLOT(zoomOut()));
|
||||
connect(zoom_fit, SIGNAL(triggered()), ce_view, SLOT(zoomFit()));
|
||||
@@ -145,6 +178,7 @@ void QETElementEditor::setupActions() {
|
||||
connect(edit_backward, SIGNAL(triggered()), ce_scene, SLOT(slot_sendBackward()));
|
||||
connect(move, SIGNAL(triggered()), ce_scene, SLOT(slot_move()));
|
||||
connect(add_line, SIGNAL(triggered()), ce_scene, SLOT(slot_addLine()));
|
||||
connect(add_rectangle, SIGNAL(triggered()), ce_scene, SLOT(slot_addRectangle()));
|
||||
connect(add_ellipse, SIGNAL(triggered()), ce_scene, SLOT(slot_addEllipse()));
|
||||
connect(add_circle, SIGNAL(triggered()), ce_scene, SLOT(slot_addCircle()));
|
||||
connect(add_polygon, SIGNAL(triggered()), ce_scene, SLOT(slot_addPolygon()));
|
||||
@@ -155,6 +189,7 @@ void QETElementEditor::setupActions() {
|
||||
|
||||
connect(move, SIGNAL(triggered()), this, SLOT(slot_setRubberBandToView()));
|
||||
connect(add_line, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||
connect(add_rectangle, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||
connect(add_ellipse, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||
connect(add_circle, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||
connect(add_polygon, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||
@@ -167,6 +202,7 @@ void QETElementEditor::setupActions() {
|
||||
|
||||
move -> setCheckable(true);
|
||||
add_line -> setCheckable(true);
|
||||
add_rectangle -> setCheckable(true);
|
||||
add_ellipse -> setCheckable(true);
|
||||
add_circle -> setCheckable(true);
|
||||
add_polygon -> setCheckable(true);
|
||||
@@ -178,16 +214,17 @@ void QETElementEditor::setupActions() {
|
||||
parts = new QActionGroup(this);
|
||||
parts -> addAction(move);
|
||||
parts -> addAction(add_line);
|
||||
parts -> addAction(add_rectangle);
|
||||
parts -> addAction(add_ellipse);
|
||||
parts -> addAction(add_circle);
|
||||
parts -> addAction(add_polygon);
|
||||
parts -> addAction(add_text);
|
||||
parts -> addAction(add_arc);
|
||||
parts -> addAction(add_text);
|
||||
parts -> addAction(add_textfield);
|
||||
parts -> addAction(add_terminal);
|
||||
parts -> setExclusive(true);
|
||||
|
||||
parts_toolbar = new QToolBar(tr("Parties"), this);
|
||||
parts_toolbar = new QToolBar(tr("Parties", "toolbar title"), this);
|
||||
parts_toolbar -> setObjectName("parts");
|
||||
foreach (QAction *action, parts -> actions()) parts_toolbar -> addAction(action);
|
||||
move -> setChecked(true);
|
||||
@@ -199,13 +236,13 @@ void QETElementEditor::setupActions() {
|
||||
parts_toolbar -> addAction(xml_preview);
|
||||
*/
|
||||
|
||||
main_toolbar = new QToolBar(tr("Outils"), this);
|
||||
main_toolbar = new QToolBar(tr("Outils", "toolbar title"), this);
|
||||
main_toolbar -> setObjectName("main_toolbar");
|
||||
view_toolbar = new QToolBar(tr("Affichage"), this);
|
||||
view_toolbar = new QToolBar(tr("Affichage", "toolbar title"), this);
|
||||
view_toolbar -> setObjectName("display");
|
||||
element_toolbar = new QToolBar(tr("\311l\351ment"), this);
|
||||
element_toolbar = new QToolBar(tr("\311l\351ment", "toolbar title"), this);
|
||||
element_toolbar -> setObjectName("element_toolbar");
|
||||
depth_toolbar = new QToolBar(tr("Profondeur"), this);
|
||||
depth_toolbar = new QToolBar(tr("Profondeur", "toolbar title"), this);
|
||||
depth_toolbar -> setObjectName("depth_toolbar");
|
||||
|
||||
main_toolbar -> addAction(new_element);
|
||||
@@ -238,6 +275,7 @@ void QETElementEditor::setupActions() {
|
||||
|
||||
connect(ce_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updateInformations()));
|
||||
connect(ce_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updateMenus()));
|
||||
connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slot_updateMenus()));
|
||||
connect(&(ce_scene -> undoStack()), SIGNAL(cleanChanged(bool)), this, SLOT(slot_updateMenus()));
|
||||
connect(&(ce_scene -> undoStack()), SIGNAL(cleanChanged(bool)), this, SLOT(slot_updateTitle()));
|
||||
connect(&(ce_scene -> undoStack()), SIGNAL(indexChanged(int)), this, SLOT(slot_updatePartsList()));
|
||||
@@ -261,10 +299,12 @@ void QETElementEditor::setupMenus() {
|
||||
|
||||
file_menu -> addAction(new_element);
|
||||
file_menu -> addAction(open);
|
||||
file_menu -> addAction(open_file);
|
||||
file_menu -> addMenu(QETApp::elementsRecentFiles() -> menu());
|
||||
connect(QETApp::elementsRecentFiles(), SIGNAL(fileOpeningRequested(const QString &)), this, SLOT(openRecentFile(const QString &)));
|
||||
file_menu -> addAction(save);
|
||||
file_menu -> addAction(save_as);
|
||||
file_menu -> addAction(save_as_file);
|
||||
file_menu -> addSeparator();
|
||||
file_menu -> addAction(reload);
|
||||
file_menu -> addSeparator();
|
||||
@@ -277,6 +317,11 @@ void QETElementEditor::setupMenus() {
|
||||
edit_menu -> addAction(deselectall);
|
||||
edit_menu -> addAction(inv_select);
|
||||
edit_menu -> addSeparator();
|
||||
edit_menu -> addAction(cut);
|
||||
edit_menu -> addAction(copy);
|
||||
edit_menu -> addAction(paste);
|
||||
edit_menu -> addAction(paste_in_area);
|
||||
edit_menu -> addSeparator();
|
||||
edit_menu -> addAction(edit_delete);
|
||||
edit_menu -> addSeparator();
|
||||
edit_menu -> addAction(edit_names);
|
||||
@@ -309,6 +354,13 @@ void QETElementEditor::setupMenus() {
|
||||
*/
|
||||
void QETElementEditor::slot_updateMenus() {
|
||||
bool selected_items = !ce_scene -> selectedItems().isEmpty();
|
||||
bool clipboard_elmt = ElementScene::clipboardMayContainElement();
|
||||
|
||||
deselectall -> setEnabled(selected_items);
|
||||
cut -> setEnabled(selected_items);
|
||||
copy -> setEnabled(selected_items);
|
||||
paste -> setEnabled(clipboard_elmt);
|
||||
paste_in_area -> setEnabled(clipboard_elmt);
|
||||
edit_delete -> setEnabled(selected_items);
|
||||
edit_forward -> setEnabled(selected_items);
|
||||
edit_raise -> setEnabled(selected_items);
|
||||
@@ -323,10 +375,10 @@ void QETElementEditor::slot_updateMenus() {
|
||||
void QETElementEditor::slot_updateTitle() {
|
||||
QString title = min_title;
|
||||
title += " - " + ce_scene -> names().name() + " ";
|
||||
if (_filename != QString()) {
|
||||
if (!ce_scene -> undoStack().isClean()) title += tr("[Modifi\351]");
|
||||
if (isReadOnly()) title += tr(" [lecture seule]");
|
||||
if (!filename_.isEmpty() || !location_.isNull()) {
|
||||
if (!ce_scene -> undoStack().isClean()) title += tr("[Modifi\351]", "window title tag");
|
||||
}
|
||||
if (isReadOnly()) title += tr(" [lecture seule]", "window title tag");
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
@@ -344,19 +396,25 @@ void QETElementEditor::setupInterface() {
|
||||
// widget par defaut dans le QDockWidget
|
||||
default_informations = new QLabel();
|
||||
|
||||
// ScrollArea pour accueillir un widget d'edition (change a la volee)
|
||||
tools_dock_scroll_area_ = new QScrollArea();
|
||||
|
||||
// Pile de widgets pour accueillir les deux widgets precedents
|
||||
tools_dock_stack_ = new QStackedWidget();
|
||||
tools_dock_stack_ -> insertWidget(0, default_informations);
|
||||
tools_dock_stack_ -> insertWidget(1, tools_dock_scroll_area_);
|
||||
|
||||
// panel sur le cote pour editer les parties
|
||||
tools_dock = new QDockWidget(tr("Informations"), this);
|
||||
tools_dock = new QDockWidget(tr("Informations", "dock title"), this);
|
||||
tools_dock -> setObjectName("informations");
|
||||
tools_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
tools_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||
tools_dock -> setMinimumWidth(290);
|
||||
tools_dock -> setMinimumWidth(380);
|
||||
addDockWidget(Qt::RightDockWidgetArea, tools_dock);
|
||||
QWidget *info_widget = new QWidget();
|
||||
info_widget -> setLayout(new QVBoxLayout(info_widget));
|
||||
tools_dock -> setWidget(info_widget);
|
||||
tools_dock -> setWidget(tools_dock_stack_);
|
||||
|
||||
// panel sur le cote pour les annulations
|
||||
undo_dock = new QDockWidget(tr("Annulations"), this);
|
||||
undo_dock = new QDockWidget(tr("Annulations", "dock title"), this);
|
||||
undo_dock -> setObjectName("undo");
|
||||
undo_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
undo_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||
@@ -374,7 +432,7 @@ void QETElementEditor::setupInterface() {
|
||||
connect(ce_scene, SIGNAL(partsZValueChanged()), this, SLOT(slot_createPartsList()));
|
||||
connect(ce_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updatePartsList()));
|
||||
connect(parts_list, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateSelectionFromPartsList()));
|
||||
parts_dock = new QDockWidget(tr("Parties"), this);
|
||||
parts_dock = new QDockWidget(tr("Parties", "dock title"), this);
|
||||
parts_dock -> setObjectName("parts_list");
|
||||
parts_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
parts_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||
@@ -386,7 +444,7 @@ void QETElementEditor::setupInterface() {
|
||||
slot_createPartsList();
|
||||
|
||||
// barre d'etat
|
||||
statusBar() -> showMessage(tr("\311diteur d'\351l\351ments"));
|
||||
statusBar() -> showMessage(tr("\311diteur d'\351l\351ments", "status bar message"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,31 +486,26 @@ void QETElementEditor::slot_updateInformations() {
|
||||
}
|
||||
}
|
||||
|
||||
// recupere le layout
|
||||
QLayout *layout = tools_dock -> widget() -> layout();
|
||||
|
||||
// enleve les widgets deja presents
|
||||
QLayoutItem *qli;
|
||||
while ((qli = layout -> takeAt(0)) != 0) {
|
||||
if (QWidget *w = qli -> widget()) {
|
||||
layout -> removeWidget(w);
|
||||
w -> setParent(0);
|
||||
w -> hide();
|
||||
}
|
||||
if (QWidget *previous_widget = tools_dock_scroll_area_ -> takeWidget()) {
|
||||
previous_widget -> setParent(0);
|
||||
previous_widget -> hide();
|
||||
}
|
||||
|
||||
if (selected_parts.size() == 1) {
|
||||
// recupere le premier CustomElementPart et en ajoute le widget d'edition
|
||||
QWidget *edit_widget = selected_parts.first() -> elementInformations();
|
||||
layout -> addWidget(edit_widget);
|
||||
edit_widget -> show();
|
||||
tools_dock_scroll_area_ -> setWidget(edit_widget);
|
||||
tools_dock_stack_ -> setCurrentIndex(1);
|
||||
} else {
|
||||
default_informations -> setText(
|
||||
selected_parts.size() ?
|
||||
QString("%1").arg(selected_parts.size()) + tr(" parties s\351lectionn\351es.") :
|
||||
tr("Aucune partie s\351lectionn\351e.")
|
||||
tr(
|
||||
"%n partie(s) s\351lectionn\351e(s).",
|
||||
"",
|
||||
selected_parts.size()
|
||||
)
|
||||
);
|
||||
layout -> addWidget(default_informations);
|
||||
default_informations -> show();
|
||||
default_informations -> setAlignment(Qt::AlignHCenter | Qt::AlignTop);
|
||||
tools_dock_stack_ -> setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,6 +521,33 @@ void QETElementEditor::xmlPreview() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Verifie si l'ensemble des parties graphiques consituant l'element en cours
|
||||
d'edition est bien contenu dans le rectangle representant les limites de
|
||||
l'element. Si ce n'est pas le cas, l'utilisateur en est informe.
|
||||
@return true si la situation est ok, false sinon
|
||||
*/
|
||||
bool QETElementEditor::checkElementSize() {
|
||||
if (ce_scene -> borderContainsEveryParts()) {
|
||||
return(true);
|
||||
} else {
|
||||
QMessageBox::warning(
|
||||
this,
|
||||
tr("Dimensions de l'\351l\351ment", "messagebox title"),
|
||||
tr(
|
||||
"Attention : certaines parties graphiques (textes, cercles, "
|
||||
"lignes...) semblent d\351border du cadre de l'\351l\351ment. Cela"
|
||||
" risque de g\351n\351rer des bugs graphiques lors de leur "
|
||||
"manipulation sur un sch\351ma. Vous pouvez corriger cela soit "
|
||||
"en d\351pla\347ant ces parties, soit en vous rendant dans "
|
||||
"\311dition > \311diter la taille et le point de saisie."
|
||||
, "messagebox content"
|
||||
)
|
||||
);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Charge un fichier
|
||||
@param filepath Chemin du fichier a charger
|
||||
@@ -480,7 +560,7 @@ void QETElementEditor::fromFile(const QString &filepath) {
|
||||
QFileInfo infos_file(filepath);
|
||||
if (!infos_file.exists() || !infos_file.isFile()) {
|
||||
state = false;
|
||||
error_message = tr("Le fichier ") + filepath + tr(" n'existe pas.");
|
||||
error_message = QString(tr("Le fichier %1 n'existe pas.", "message box content")).arg(filepath);
|
||||
}
|
||||
|
||||
// le fichier doit etre lisible
|
||||
@@ -488,7 +568,7 @@ void QETElementEditor::fromFile(const QString &filepath) {
|
||||
if (state) {
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
state = false;
|
||||
error_message = tr("Impossible d'ouvrir le fichier ") + filepath + ".";
|
||||
error_message = QString(tr("Impossible d'ouvrir le fichier %1.", "message box content")).arg(filepath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,13 +577,13 @@ void QETElementEditor::fromFile(const QString &filepath) {
|
||||
if (state) {
|
||||
if (!document_xml.setContent(&file)) {
|
||||
state = false;
|
||||
error_message = tr("Ce fichier n'est pas un document XML valide");
|
||||
error_message = tr("Ce fichier n'est pas un document XML valide", "message box content");
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
QMessageBox::critical(this, tr("Erreur"), error_message);
|
||||
QMessageBox::critical(this, tr("Erreur", "toolbar title"), error_message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -515,8 +595,8 @@ void QETElementEditor::fromFile(const QString &filepath) {
|
||||
if (!infos_file.isWritable()) {
|
||||
QMessageBox::warning(
|
||||
this,
|
||||
tr("\311dition en lecture seule"),
|
||||
tr("Vous n'avez pas les privil\350ges n\351cessaires pour modifier cet \351lement. Il sera donc ouvert en lecture seule.")
|
||||
tr("\311dition en lecture seule", "message box title"),
|
||||
tr("Vous n'avez pas les privil\350ges n\351cessaires pour modifier cet \351lement. Il sera donc ouvert en lecture seule.", "message box content")
|
||||
);
|
||||
setReadOnly(true);
|
||||
}
|
||||
@@ -527,7 +607,6 @@ void QETElementEditor::fromFile(const QString &filepath) {
|
||||
slot_updateMenus();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Enregistre l'element vers un fichier
|
||||
@param fn Chemin du fichier a enregistrer
|
||||
@@ -536,7 +615,7 @@ void QETElementEditor::fromFile(const QString &filepath) {
|
||||
bool QETElementEditor::toFile(const QString &fn) {
|
||||
QFile file(fn);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QMessageBox::warning(this, tr("Erreur"), tr("Impossible d'ecrire dans ce fichier"));
|
||||
QMessageBox::warning(this, tr("Erreur", "message box title"), tr("Impossible d'\351crire dans ce fichier", "message box content"));
|
||||
return(false);
|
||||
}
|
||||
QTextStream out(&file);
|
||||
@@ -546,6 +625,45 @@ bool QETElementEditor::toFile(const QString &fn) {
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
Enregistre l'element vers un emplacement
|
||||
@param location Emplacement de l'element a enregistrer
|
||||
@return true en cas de reussite, false sinon
|
||||
*/
|
||||
bool QETElementEditor::toLocation(const ElementsLocation &location) {
|
||||
ElementsCollectionItem *item = QETApp::collectionItem(location);
|
||||
ElementDefinition *element;
|
||||
if (item) {
|
||||
// l'element existe deja
|
||||
element = qobject_cast<ElementDefinition *>(item);
|
||||
} else {
|
||||
// l'element n'existe pas encore, on demande sa creation
|
||||
element = QETApp::createElement(location);
|
||||
}
|
||||
|
||||
if (!element) {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Erreur", "message box title"),
|
||||
tr("Impossible d'atteindre l'\351l\351ment", "message box content")
|
||||
);
|
||||
return(false);
|
||||
}
|
||||
|
||||
// enregistre l'element
|
||||
element -> setXml(ce_scene -> toXml().documentElement());
|
||||
if (!element -> write()) {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Erreur", "message box title"),
|
||||
tr("Impossible d'enregistrer l'\351l\351ment", "message box content")
|
||||
);
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
specifie si l'editeur d'element doit etre en mode lecture seule
|
||||
@param ro true pour activer le mode lecture seule, false pour le desactiver
|
||||
@@ -559,6 +677,9 @@ void QETElementEditor::setReadOnly(bool ro) {
|
||||
ce_view -> setInteractive(!ro);
|
||||
|
||||
// active / desactive l'edition de la taille, du hotspot, des noms et des orientations
|
||||
cut -> setEnabled(!ro);
|
||||
copy -> setEnabled(!ro);
|
||||
paste -> setEnabled(!ro);
|
||||
selectall -> setEnabled(!ro);
|
||||
deselectall -> setEnabled(!ro);
|
||||
inv_select -> setEnabled(!ro);
|
||||
@@ -587,15 +708,33 @@ void QETElementEditor::slot_new() {
|
||||
}
|
||||
|
||||
/**
|
||||
Demande un fichier a l'utilisateur et ouvre ce fichier
|
||||
Ouvre un element
|
||||
*/
|
||||
void QETElementEditor::slot_open() {
|
||||
// demande le chemin virtuel de l'element a ouvrir a l'utilisateur
|
||||
ElementsLocation location = ElementDialog::getOpenElementLocation();
|
||||
if (location.isNull()) return;
|
||||
QETElementEditor *cee = new QETElementEditor();
|
||||
cee -> fromLocation(location);
|
||||
cee -> show();
|
||||
}
|
||||
|
||||
/**
|
||||
Ouvre un fichier
|
||||
Demande un fichier a l'utilisateur et ouvre ce fichier
|
||||
*/
|
||||
void QETElementEditor::slot_openFile() {
|
||||
// demande un nom de fichier a ouvrir a l'utilisateur
|
||||
QString user_filename = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
tr("Ouvrir un fichier"),
|
||||
_filename.isEmpty() ? QETApp::customElementsDir() : QDir(_filename).absolutePath(),
|
||||
tr("\311l\351ments QElectroTech (*.elmt);;Fichiers XML (*.xml);;Tous les fichiers (*)")
|
||||
tr("Ouvrir un fichier", "dialog title"),
|
||||
filename_.isEmpty() ? QETApp::customElementsDir() : QDir(filename_).absolutePath(),
|
||||
tr(
|
||||
"\311l\351ments QElectroTech (*.elmt);;"
|
||||
"Fichiers XML (*.xml);;"
|
||||
"Tous les fichiers (*)",
|
||||
"filetypes allowed when opening an element file"
|
||||
)
|
||||
);
|
||||
openElement(user_filename);
|
||||
}
|
||||
@@ -628,16 +767,13 @@ void QETElementEditor::openElement(const QString &filepath) {
|
||||
Recharge l'element edite
|
||||
*/
|
||||
void QETElementEditor::slot_reload() {
|
||||
// impossible de recharger un element non enregistre
|
||||
if (_filename.isEmpty()) return;
|
||||
|
||||
// s'il ya des modifications, on demande a l'utilisateur s'il est certain
|
||||
// de vouloir recharger
|
||||
if (!ce_scene -> undoStack().isClean()) {
|
||||
QMessageBox::StandardButton answer = QMessageBox::question(
|
||||
this,
|
||||
tr("Recharger l'\351l\351ment"),
|
||||
tr("Vous avez efffectu\351 des modifications sur cet \351l\351ment. Si vous le rechargez, ces modifications seront perdues. Voulez-vous vraiment recharger l'\351l\351ment ?"),
|
||||
tr("Recharger l'\351l\351ment", "dialog title"),
|
||||
tr("Vous avez efffectu\351 des modifications sur cet \351l\351ment. Si vous le rechargez, ces modifications seront perdues. Voulez-vous vraiment recharger l'\351l\351ment ?", "dialog content"),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel
|
||||
);
|
||||
@@ -645,8 +781,19 @@ void QETElementEditor::slot_reload() {
|
||||
}
|
||||
|
||||
// recharge l'element
|
||||
ce_scene -> reset();
|
||||
fromFile(_filename);
|
||||
if (opened_from_file) {
|
||||
// l'element a ete ouvert a partir d'un chemin de fichier
|
||||
ce_scene -> reset();
|
||||
fromFile(filename_);
|
||||
} else {
|
||||
// l'element a ete ouvert a partir d'un emplacement (ElementsLocation)
|
||||
// il peut s'agir aussi bien d'un fichier que d'un element XML
|
||||
if (ElementsCollectionItem *item = QETApp::collectionItem(location_)) {
|
||||
item -> reload();
|
||||
ce_scene -> reset();
|
||||
fromLocation(location_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -656,24 +803,57 @@ void QETElementEditor::slot_reload() {
|
||||
@see slot_saveAs()
|
||||
*/
|
||||
bool QETElementEditor::slot_save() {
|
||||
// verification avant d'enregistrer le fichier
|
||||
checkElementSize();
|
||||
|
||||
// si on ne connait pas le nom du fichier en cours, enregistrer revient a enregistrer sous
|
||||
if (_filename.isEmpty()) return(slot_saveAs());
|
||||
// sinon on enregistre dans le nom de fichier connu
|
||||
bool result_save = toFile(_filename);
|
||||
if (result_save) ce_scene -> undoStack().setClean();
|
||||
if (opened_from_file) {
|
||||
if (filename_.isEmpty()) return(slot_saveAsFile());
|
||||
// sinon on enregistre dans le nom de fichier connu
|
||||
bool result_save = toFile(filename_);
|
||||
if (result_save) ce_scene -> undoStack().setClean();
|
||||
return(result_save);
|
||||
} else {
|
||||
if (location_.isNull()) return(slot_saveAs());
|
||||
// sinon on enregistre a l'emplacement connu
|
||||
bool result_save = toLocation(location_);
|
||||
if (result_save) ce_scene -> undoStack().setClean();
|
||||
return(result_save);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Demande une localisation a l'utilisateur et enregistre l'element
|
||||
*/
|
||||
bool QETElementEditor::slot_saveAs() {
|
||||
// demande une localisation a l'utilisateur
|
||||
ElementsLocation location = ElementDialog::getSaveElementLocation();
|
||||
if (location.isNull()) return(false);
|
||||
|
||||
// tente l'enregistrement
|
||||
bool result_save = toLocation(location);
|
||||
if (result_save) {
|
||||
setLocation(location);
|
||||
ce_scene -> undoStack().setClean();
|
||||
}
|
||||
|
||||
// retourne un booleen representatif de la reussite de l'enregistrement
|
||||
return(result_save);
|
||||
}
|
||||
|
||||
/**
|
||||
Demande un nom de fichier a l'utilisateur et enregistre l'element
|
||||
*/
|
||||
bool QETElementEditor::slot_saveAs() {
|
||||
bool QETElementEditor::slot_saveAsFile() {
|
||||
// demande un nom de fichier a l'utilisateur pour enregistrer l'element
|
||||
QString fn = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
tr("Enregistrer sous"),
|
||||
_filename.isEmpty() ? QETApp::customElementsDir() : QDir(_filename).absolutePath(),
|
||||
tr("\311l\351ments QElectroTech (*.elmt)")
|
||||
tr("Enregistrer sous", "dialog title"),
|
||||
filename_.isEmpty() ? QETApp::customElementsDir() : QDir(filename_).absolutePath(),
|
||||
tr(
|
||||
"\311l\351ments QElectroTech (*.elmt)",
|
||||
"filetypes allowed when saving an element file"
|
||||
)
|
||||
);
|
||||
// si aucun nom n'est entre, renvoie faux.
|
||||
if (fn.isEmpty()) return(false);
|
||||
@@ -702,9 +882,14 @@ bool QETElementEditor::canClose() {
|
||||
// demande d'abord a l'utilisateur s'il veut enregistrer l'element en cours
|
||||
QMessageBox::StandardButton answer = QMessageBox::question(
|
||||
this,
|
||||
tr("Enregistrer l'\351l\351ment en cours ?"),
|
||||
tr("Voulez-vous enregistrer l'\351l\351ment ") + ce_scene -> names().name() + tr(" ?"),
|
||||
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
|
||||
tr("Enregistrer l'\351l\351ment en cours ?", "dialog title"),
|
||||
QString(
|
||||
tr(
|
||||
"Voulez-vous enregistrer l'\351l\351ment %1 ?",
|
||||
"dialog content - %1 is an element name"
|
||||
)
|
||||
).arg(ce_scene -> names().name()),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel
|
||||
);
|
||||
bool result;
|
||||
@@ -787,6 +972,7 @@ void QETElementEditor::slot_updateSelectionFromPartsList() {
|
||||
parts_list -> blockSignals(false);
|
||||
ce_scene -> blockSignals(false);
|
||||
slot_updateInformations();
|
||||
slot_updateMenus();
|
||||
}
|
||||
|
||||
/// Lit les parametres de l'editeur d'element
|
||||
@@ -808,3 +994,70 @@ void QETElementEditor::writeSettings() {
|
||||
settings.setValue("elementeditor/geometry", saveGeometry());
|
||||
settings.setValue("elementeditor/state", saveState());
|
||||
}
|
||||
|
||||
/**
|
||||
@return les decalages horizontaux et verticaux (sous la forme d'un point) a
|
||||
utiliser lors d'un copier/coller avec decalage.
|
||||
*/
|
||||
QPointF QETElementEditor::pasteOffset() {
|
||||
QPointF paste_offset(5.0, 0.0);
|
||||
return(paste_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le type de mouvement a effectuer lors d'un copier/coller avec
|
||||
decalage.
|
||||
*/
|
||||
QET::OrientedMovement QETElementEditor::pasteMovement() {
|
||||
return(QET::ToEast);
|
||||
}
|
||||
|
||||
/**
|
||||
@param location Emplacement de l'element a editer
|
||||
*/
|
||||
void QETElementEditor::fromLocation(const ElementsLocation &location) {
|
||||
|
||||
// l'element doit exister
|
||||
ElementsCollectionItem *item = QETApp::collectionItem(location);
|
||||
ElementDefinition *element = 0;
|
||||
if (!item) {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("\311l\351ment inexistant.", "message box title"),
|
||||
tr("L'\351l\351ment n'existe pas.", "message box content")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!item -> isElement() || !(element = qobject_cast<ElementDefinition *>(item)) || element -> isNull()) {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("\311l\351ment inexistant.", "message box title"),
|
||||
tr("Le chemin virtuel choisi ne correspond pas \340 un \351l\351ment.", "message box content")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// le fichier doit etre un document XML
|
||||
QDomDocument document_xml;
|
||||
QDomNode node = document_xml.importNode(element -> xml(), true);
|
||||
document_xml.appendChild(node);
|
||||
|
||||
// chargement de l'element
|
||||
ce_scene -> fromXml(document_xml);
|
||||
slot_createPartsList();
|
||||
|
||||
// gestion de la lecture seule
|
||||
if (!element -> isWritable()) {
|
||||
QMessageBox::warning(
|
||||
this,
|
||||
tr("\311dition en lecture seule", "message box title"),
|
||||
tr("Vous n'avez pas les privil\350ges n\351cessaires pour modifier cet \351lement. Il sera donc ouvert en lecture seule.", "message box content")
|
||||
);
|
||||
setReadOnly(true);
|
||||
}
|
||||
|
||||
// memorise le fichier
|
||||
setLocation(location);
|
||||
slot_updateMenus();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -18,8 +18,10 @@
|
||||
#ifndef CUSTOM_ELEMENT_EDITOR_H
|
||||
#define CUSTOM_ELEMENT_EDITOR_H
|
||||
#include <QtGui>
|
||||
#include "qet.h"
|
||||
#include "elementscene.h"
|
||||
#include "orientationset.h"
|
||||
#include "elementslocation.h"
|
||||
class ElementView;
|
||||
/**
|
||||
Cette classe represente un editeur d'element. Elle permet a l'utilisateur
|
||||
@@ -48,6 +50,12 @@ class QETElementEditor : public QMainWindow {
|
||||
ElementScene *ce_scene;
|
||||
/// container pour les widgets d'edition des parties
|
||||
QDockWidget *tools_dock;
|
||||
/// Pile de widgets pour tools_dock
|
||||
QStackedWidget *tools_dock_stack_;
|
||||
/// label affiche lors de la selection de plusieurs elements
|
||||
QLabel *default_informations;
|
||||
/// ScrollArea pour le DockWidget affichant des infos sur la partie selectionnee
|
||||
QScrollArea *tools_dock_scroll_area_;
|
||||
/// container pour la liste des annulations
|
||||
QDockWidget *undo_dock;
|
||||
/// Container pour la liste des parties
|
||||
@@ -55,9 +63,10 @@ class QETElementEditor : public QMainWindow {
|
||||
/// Liste des parties
|
||||
QListWidget *parts_list;
|
||||
/// actions du menu fichier
|
||||
QAction *new_element, *open, *save, *save_as, *reload, *quit;
|
||||
QAction *new_element, *open, *open_file, *save, *save_as, *save_as_file, *reload, *quit;
|
||||
/// actions du menu edition
|
||||
QAction *selectall, *deselectall, *inv_select;
|
||||
QAction *cut, *copy, *paste, *paste_in_area;
|
||||
QAction *undo, *redo;
|
||||
QAction *zoom_in, *zoom_out, *zoom_fit, *zoom_reset;
|
||||
QAction *edit_delete, *edit_size_hs, *edit_names, *edit_ori;
|
||||
@@ -66,14 +75,16 @@ class QETElementEditor : public QMainWindow {
|
||||
QToolBar *parts_toolbar, *main_toolbar, *view_toolbar, *depth_toolbar, *element_toolbar;
|
||||
/// actions de la barre d'outils
|
||||
QActionGroup *parts;
|
||||
QAction *move, *add_line, *add_circle, *add_ellipse, *add_polygon, *add_text;
|
||||
QAction *move, *add_line, *add_circle, *add_rectangle, *add_ellipse, *add_polygon, *add_text;
|
||||
QAction *add_arc, *add_terminal, *add_textfield;
|
||||
/// label affiche lors de la selection de plusieurs elements
|
||||
QLabel *default_informations;
|
||||
/// titre minimal
|
||||
QString min_title;
|
||||
/// Nom de fichier
|
||||
QString _filename;
|
||||
/// Nom de fichier de l'element edite
|
||||
QString filename_;
|
||||
/// Emplacement de l'element edite
|
||||
ElementsLocation location_;
|
||||
/// booleen indiquant si l'element en cours d'edition provient d'un fichier ou d'un emplacement
|
||||
bool opened_from_file;
|
||||
|
||||
// methodes
|
||||
public:
|
||||
@@ -84,15 +95,21 @@ class QETElementEditor : public QMainWindow {
|
||||
void setNames(const NamesList &);
|
||||
void setOrientations(const OrientationSet &orientation_set);
|
||||
OrientationSet orientations() const;
|
||||
void setLocation(const ElementsLocation &);
|
||||
ElementsLocation location() const;
|
||||
void setFileName(const QString &);
|
||||
QString fileName() const;
|
||||
void setReadOnly(bool);
|
||||
bool isReadOnly() const;
|
||||
void fromFile(const QString &);
|
||||
void fromLocation(const ElementsLocation &);
|
||||
bool toFile(const QString &);
|
||||
bool toLocation(const ElementsLocation &);
|
||||
ElementScene *elementScene() const;
|
||||
void readSettings();
|
||||
void writeSettings();
|
||||
static QPointF pasteOffset();
|
||||
static QET::OrientedMovement pasteMovement();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
@@ -106,11 +123,13 @@ class QETElementEditor : public QMainWindow {
|
||||
public slots:
|
||||
void slot_new();
|
||||
void slot_open();
|
||||
void slot_openFile();
|
||||
void openRecentFile(const QString &);
|
||||
void openElement(const QString &);
|
||||
void slot_reload();
|
||||
bool slot_save();
|
||||
bool slot_saveAs();
|
||||
bool slot_saveAsFile();
|
||||
void slot_setRubberBandToView();
|
||||
void slot_setNoDragToView();
|
||||
void slot_setNormalMode();
|
||||
@@ -121,6 +140,7 @@ class QETElementEditor : public QMainWindow {
|
||||
void slot_updatePartsList();
|
||||
void slot_updateSelectionFromPartsList();
|
||||
void xmlPreview();
|
||||
bool checkElementSize();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -179,18 +199,35 @@ inline OrientationSet QETElementEditor::orientations() const {
|
||||
}
|
||||
|
||||
/**
|
||||
@param fn Le nouveau nom de fichier de l'element edite
|
||||
@param el Le nouvel emplacement de l'element edite
|
||||
*/
|
||||
inline void QETElementEditor::setFileName(const QString &fn) {
|
||||
_filename = fn;
|
||||
inline void QETElementEditor::setLocation(const ElementsLocation &el) {
|
||||
location_ = el;
|
||||
opened_from_file = false;
|
||||
slot_updateTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
@return le nomde fichier de l'element edite
|
||||
@return l'emplacement de l'element edite
|
||||
*/
|
||||
inline ElementsLocation QETElementEditor::location() const {
|
||||
return(location_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param fn Le nouveau nom de fichier de l'element edite
|
||||
*/
|
||||
inline void QETElementEditor::setFileName(const QString &fn) {
|
||||
filename_ = fn;
|
||||
opened_from_file = true;
|
||||
slot_updateTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
@return le nom de fichier de l'element edite
|
||||
*/
|
||||
inline QString QETElementEditor::fileName() const {
|
||||
return(_filename);
|
||||
return(filename_);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
108
sources/editor/rectangleeditor.cpp
Normal file
108
sources/editor/rectangleeditor.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
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 "rectangleeditor.h"
|
||||
#include "partrectangle.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param editor L'editeur d'element concerne
|
||||
@param rect Le rectangle a editer
|
||||
@param parent le Widget parent
|
||||
*/
|
||||
RectangleEditor::RectangleEditor(QETElementEditor *editor, PartRectangle *rect, QWidget *parent) : ElementItemEditor(editor, parent) {
|
||||
|
||||
part = rect;
|
||||
|
||||
x = new QLineEdit();
|
||||
y = new QLineEdit();
|
||||
w = new QLineEdit();
|
||||
h = new QLineEdit();
|
||||
|
||||
x -> setValidator(new QDoubleValidator(x));
|
||||
y -> setValidator(new QDoubleValidator(y));
|
||||
w -> setValidator(new QDoubleValidator(w));
|
||||
h -> setValidator(new QDoubleValidator(h));
|
||||
|
||||
QGridLayout *grid = new QGridLayout(this);
|
||||
grid -> addWidget(new QLabel(tr("Coin sup\351rieur gauche\240: ")), 0, 0);
|
||||
grid -> addWidget(new QLabel("x"), 1, 0);
|
||||
grid -> addWidget(x, 1, 1);
|
||||
grid -> addWidget(new QLabel("y"), 1, 2);
|
||||
grid -> addWidget(y, 1, 3);
|
||||
grid -> addWidget(new QLabel(tr("Dimensions\240: ")), 2, 0);
|
||||
grid -> addWidget(new QLabel(tr("Largeur\240:")), 3, 0);
|
||||
grid -> addWidget(w, 3, 1);
|
||||
grid -> addWidget(new QLabel(tr("Hauteur\240:")), 4, 0);
|
||||
grid -> addWidget(h, 4, 1);
|
||||
|
||||
activeConnections(true);
|
||||
updateForm();
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
RectangleEditor::~RectangleEditor() {
|
||||
}
|
||||
|
||||
/**
|
||||
Met a jour le rectangle a partir des donnees du formulaire
|
||||
*/
|
||||
void RectangleEditor::updateRectangle() {
|
||||
part -> setProperty("x", x -> text().toDouble());
|
||||
part -> setProperty("y", y -> text().toDouble());
|
||||
part -> setProperty("width", w -> text().toDouble());
|
||||
part -> setProperty("height", h -> text().toDouble());
|
||||
}
|
||||
|
||||
/// Met a jour l'abscisse du coin superieur gauche du rectangle et cree un objet d'annulation
|
||||
void RectangleEditor::updateRectangleX() { addChangePartCommand(tr("abscisse"), part, "x", x -> text().toDouble()); }
|
||||
/// Met a jour l'ordonnee du coin superieur gauche du rectangle et cree un objet d'annulation
|
||||
void RectangleEditor::updateRectangleY() { addChangePartCommand(tr("ordonn\351e"), part, "y", y -> text().toDouble()); }
|
||||
/// Met a jour la largeur du rectangle et cree un objet d'annulation
|
||||
void RectangleEditor::updateRectangleW() { addChangePartCommand(tr("largeur"), part, "width", w -> text().toDouble()); }
|
||||
/// Met a jour la hauteur du rectangle et cree un objet d'annulation
|
||||
void RectangleEditor::updateRectangleH() { addChangePartCommand(tr("hauteur"), part, "height", h -> text().toDouble()); }
|
||||
|
||||
/**
|
||||
Met a jour le formulaire d'edition
|
||||
*/
|
||||
void RectangleEditor::updateForm() {
|
||||
activeConnections(false);
|
||||
x -> setText(part -> property("x").toString());
|
||||
y -> setText(part -> property("y").toString());
|
||||
w -> setText(part -> property("width").toString());
|
||||
h -> setText(part -> property("height").toString());
|
||||
activeConnections(true);
|
||||
}
|
||||
|
||||
/**
|
||||
Active ou desactive les connexionx signaux/slots entre les widgets internes.
|
||||
@param active true pour activer les connexions, false pour les desactiver
|
||||
*/
|
||||
void RectangleEditor::activeConnections(bool active) {
|
||||
if (active) {
|
||||
connect(x, SIGNAL(editingFinished()), this, SLOT(updateRectangleX()));
|
||||
connect(y, SIGNAL(editingFinished()), this, SLOT(updateRectangleY()));
|
||||
connect(w, SIGNAL(editingFinished()), this, SLOT(updateRectangleW()));
|
||||
connect(h, SIGNAL(editingFinished()), this, SLOT(updateRectangleH()));
|
||||
} else {
|
||||
disconnect(x, SIGNAL(editingFinished()), this, SLOT(updateRectangleX()));
|
||||
disconnect(y, SIGNAL(editingFinished()), this, SLOT(updateRectangleY()));
|
||||
disconnect(w, SIGNAL(editingFinished()), this, SLOT(updateRectangleW()));
|
||||
disconnect(h, SIGNAL(editingFinished()), this, SLOT(updateRectangleH()));
|
||||
}
|
||||
}
|
||||
53
sources/editor/rectangleeditor.h
Normal file
53
sources/editor/rectangleeditor.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
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 RECTANGLE_EDITOR_H
|
||||
#define RECTANGLE_EDITOR_H
|
||||
#include <QtGui>
|
||||
#include "elementitemeditor.h"
|
||||
class PartRectangle;
|
||||
/**
|
||||
Cette classe represente le widget d'edition d'un rectangle dans l'editeur
|
||||
d'element.
|
||||
*/
|
||||
class RectangleEditor : public ElementItemEditor {
|
||||
Q_OBJECT
|
||||
//constructeurs, destructeur
|
||||
public:
|
||||
RectangleEditor(QETElementEditor *, PartRectangle *, QWidget * = 0);
|
||||
~RectangleEditor();
|
||||
private:
|
||||
RectangleEditor(const RectangleEditor &);
|
||||
|
||||
// attributs
|
||||
private:
|
||||
PartRectangle *part;
|
||||
QLineEdit *x, *y, *w, *h;
|
||||
|
||||
// methodes
|
||||
public slots:
|
||||
void updateRectangle();
|
||||
void updateRectangleX();
|
||||
void updateRectangleY();
|
||||
void updateRectangleW();
|
||||
void updateRectangleH();
|
||||
void updateForm();
|
||||
|
||||
private:
|
||||
void activeConnections(bool);
|
||||
};
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -27,26 +27,26 @@
|
||||
StyleEditor::StyleEditor(QETElementEditor *editor, CustomElementGraphicPart *p, QWidget *parent) : ElementItemEditor(editor, parent), part(p) {
|
||||
// couleur
|
||||
color = new QButtonGroup(this);
|
||||
color -> addButton(black_color = new QRadioButton(tr("Noir")), CustomElementGraphicPart::BlackColor);
|
||||
color -> addButton(white_color = new QRadioButton(tr("Blanc")), CustomElementGraphicPart::WhiteColor);
|
||||
color -> addButton(black_color = new QRadioButton(tr("Noir", "element part color")), CustomElementGraphicPart::BlackColor);
|
||||
color -> addButton(white_color = new QRadioButton(tr("Blanc", "element part color")), CustomElementGraphicPart::WhiteColor);
|
||||
|
||||
// style
|
||||
style = new QButtonGroup(this);
|
||||
style -> addButton(normal_style = new QRadioButton(tr("Normal")), CustomElementGraphicPart::NormalStyle);
|
||||
style -> addButton(dashed_style = new QRadioButton(tr("Pointill\351")), CustomElementGraphicPart::DashedStyle);
|
||||
style -> addButton(normal_style = new QRadioButton(tr("Normal", "element part line style")), CustomElementGraphicPart::NormalStyle);
|
||||
style -> addButton(dashed_style = new QRadioButton(tr("Pointill\351", "element part line style")), CustomElementGraphicPart::DashedStyle);
|
||||
style -> button(part -> lineStyle()) -> setChecked(true);
|
||||
|
||||
// epaisseur
|
||||
weight = new QButtonGroup(this);
|
||||
weight -> addButton(none_weight = new QRadioButton(tr("Nulle")), CustomElementGraphicPart::NoneWeight);
|
||||
weight -> addButton(thin_weight = new QRadioButton(tr("Fine")), CustomElementGraphicPart::ThinWeight);
|
||||
weight -> addButton(normal_weight = new QRadioButton(tr("Normale")), CustomElementGraphicPart::NormalWeight);
|
||||
weight -> addButton(none_weight = new QRadioButton(tr("Nulle", "element part weight")), CustomElementGraphicPart::NoneWeight);
|
||||
weight -> addButton(thin_weight = new QRadioButton(tr("Fine", "element part weight")), CustomElementGraphicPart::ThinWeight);
|
||||
weight -> addButton(normal_weight = new QRadioButton(tr("Normale", "element part weight")), CustomElementGraphicPart::NormalWeight);
|
||||
|
||||
// remplissage
|
||||
filling = new QButtonGroup(this);
|
||||
filling -> addButton(no_filling = new QRadioButton(tr("Aucun")), CustomElementGraphicPart::NoneFilling );
|
||||
filling -> addButton(black_filling = new QRadioButton(tr("Noir")), CustomElementGraphicPart::BlackFilling);
|
||||
filling -> addButton(white_filling = new QRadioButton(tr("Blanc")), CustomElementGraphicPart::WhiteFilling);
|
||||
filling -> addButton(no_filling = new QRadioButton(tr("Aucun", "element part filling")), CustomElementGraphicPart::NoneFilling );
|
||||
filling -> addButton(black_filling = new QRadioButton(tr("Noir", "element part filling")), CustomElementGraphicPart::BlackFilling);
|
||||
filling -> addButton(white_filling = new QRadioButton(tr("Blanc", "element part filling")), CustomElementGraphicPart::WhiteFilling);
|
||||
|
||||
// antialiasing
|
||||
antialiasing = new QCheckBox(tr("Antialiasing"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -81,7 +81,7 @@ void TextEditor::updateTextX() { addChangePartCommand(tr("abscisse"), part, "
|
||||
/// Met a jour l'ordonnee de la position du texte et cree un objet d'annulation
|
||||
void TextEditor::updateTextY() { addChangePartCommand(tr("ordonn\351e"), part, "y", qle_y -> text().toDouble()); updateForm(); }
|
||||
/// Met a jour le texte et cree un objet d'annulation
|
||||
void TextEditor::updateTextT() { addChangePartCommand(tr("texte"), part, "text", qle_text -> text()); }
|
||||
void TextEditor::updateTextT() { addChangePartCommand(tr("contenu"), part, "text", qle_text -> text()); }
|
||||
/// Met a jour la taille du texte et cree un objet d'annulation
|
||||
void TextEditor::updateTextS() { addChangePartCommand(tr("taille"), part, "size", font_size -> value()); }
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -86,7 +86,7 @@ void TextFieldEditor::updateTextFieldX() { addChangePartCommand(tr("abscisse"),
|
||||
/// Met a jour l'ordonnee de la position du champ de texte et cree un objet d'annulation
|
||||
void TextFieldEditor::updateTextFieldY() { addChangePartCommand(tr("ordonn\351e"), part, "y", qle_y -> text().toDouble()); updateForm(); }
|
||||
/// Met a jour le texte du champ de texte et cree un objet d'annulation
|
||||
void TextFieldEditor::updateTextFieldT() { addChangePartCommand(tr("texte"), part, "text", qle_text -> text()); }
|
||||
void TextFieldEditor::updateTextFieldT() { addChangePartCommand(tr("contenu"), part, "text", qle_text -> text()); }
|
||||
/// Met a jour la taille du champ de texte et cree un objet d'annulation
|
||||
void TextFieldEditor::updateTextFieldS() { addChangePartCommand(tr("taille"), part, "size", font_size -> value()); }
|
||||
/// Met a jour la taille du champ de texte et cree un objet d'annulation
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
Copyright 2006-2009 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
|
||||
Reference in New Issue
Block a user