Compare commits

..

1 Commits
0.21 ... 0.1rc1

Author SHA1 Message Date
xavierqet
13817f9133 Tag de la version 0.1 Release Candidate 1
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/tags/0.1rc1@307 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-03-02 15:50:13 +00:00
767 changed files with 11123 additions and 100430 deletions

90
CREDIT
View File

@@ -1,83 +1,17 @@
[en]
Thanks to Qt Software for their Qt library ( http://www.qtsoftware.com/ ), licensed under GNU/GPL.
Thanks to Everaldo Coelho for the Crystal SVG icons theme ( http://www.everaldo.com/crystal/ ) licensed under LGPL.
Thanks to Nuno Pinheiro for the Oxygen icons theme ( http://www.oxygen-icons.org/ ) licensed under LGPL but also for the QElectroTech-dedicated icons.
Thanks to the KDE project ( http://www.kde.org/ ).
Thanks to Trolltech for their Qt library ( http://trolltech.com/ ), licensed
under GNU/GPL.
Thanks to Everaldo Coelho for the Crystal SVG icons theme (
http://www.everaldo.com/crystal/ ) licensed under LGPL, and to the KDE
project (http://www.kde.org/ ).
Thanks to Loic for his mathematics-related explanations.
Thanks to Remi Collet for the Fedora packaging.
Thanks to Laurent Trinques for the Debian packaging.
Thanks to `trem' for the Mandriva packaging.
Thanks to TuxFamily ( http://tuxfamily.org/ ) for hosting the project.
Thanks to `Nishiki' for his elements and his support.
Thanks to qtcentre.org for their SingleApplication class.
Thanks to Alfredo Carreto for his Spanish translations and fixing Spanish translations ( http://electronicosmx.comxa.com )
Thanks to Nicolas for the Mac OS X Packaging.
[fr]
Merci à Qt Software pour la bibliothèque Qt ( http://www.qtsoftware.com/ ), sous licence GNU/GPL.
Merci à Everaldo Coelho pour le thème d'icônes Crystal SVG ( http://www.everaldo.com/crystal/ ) sous licence LGPL.
Merci à Nuno Pinheiro pour le thème d'icônes Oxygen ( http://www.oxygen-icons.org/ ) sous licence LGPL mais aussi pour les icônes dédiées à QElectroTech
Merci au projet KDE ( http://www.kde.org/ ).
Merci à Trolltech pour la bibliothèque Qt ( http://trolltech.com/ ), sous
licence GNU/GPL.
Merci à Everaldo Coelho pour le thème d'icônes Crystal SVG (
http://www.everaldo.com/crystal/ ) sous licence LGPL, ainsi qu'au projet KDE (
http://www.kde.org/ ).
Merci à Loic pour ses explications d'ordre mathématique.
Merci à Remi Collet pour les paquets Fedora.
Merci à Laurent Trinques pour les paquets Debian.
Merci à `trem' pour les paquets Mandriva.
Merci à TuxFamily ( http://tuxfamily.org/ ) pour l'hébergement du projet.
Merci à `Nishiki' pour ses éléments et son soutien.
Merci à qtcentre.org pour leur classe SingleApplication.
Merci à Alfredo Carreto pour ses traductions et corrections en espagnol ( http://electronicosmx.comxa.com )
[ru]
Спасибо Qt Software за их библиотеку Qt ( http://www.qtsoftware.com/ ), лицензированную на условиях GNU/GPL.
Спасибо Everaldo Coelho за тему значков Crystal SVG ( http://www.everaldo.com/crystal/ ) лицензированную на условиях LGPL.
Спасибо Nuno Pinheiro за тему значков Oxygen ( http://www.oxygen-icons.org/ ) лицензированную на условиях LGPL, а также за значки связанные с QElectroTech.
Спасибо проекту KDE ( http://www.kde.org/ ).
Спасибо Loic за объяснения связанные с математикой.
Спасибо Remi Collet за пакет для Fedora.
Спасибо Laurent Trinques за пакет для Debian.
Спасибо `trem' за пакет для Mandriva.
Спасибо TuxFamily ( http://tuxfamily.org/ ) за хостинг для проекта.
Спасибо `Nishiki' за элементы и поддержку.
Спасибо qtcentre.org за их класс SingleApplication.
Спасибо Alfredo Carreto за исправления и перевод на испанский ( http://electronicosmx.comxa.com )
[pt]
Agradecimentos a Qt Software pela sua biblioteca Qt ( http://www.qtsoftware.com/ ), licenciada de acordo com a GNU/GPL.
Agradecimentos a Everaldo Coelho pelo tema de ícones Crystal SVG ( http://www.everaldo.com/crystal/ ), licenciado de acordo com a LGPL.
Agradecimentos a Nuno Pinheiro pelo tema de ícones Oxygen e em especial pelos ícones dedicados ao programa QElectroTech ( http://www.oxygen-icons.org/ ), lincenciado de acordo com a LGPL.
Agradecimentos ao projecto KDE ( http://www.kde.org/ ).
Agradecimentos a Loic pelas suas explicações relacionadas com problemas matemáticos.
Agradecimentos a Remi Collet pela criação dos pacotes para Fedora.
Agradecimentos a Laurent Trinques pela criação dos pacotes para Debian.
Agradecimentos a "trem" pela criação dos pacotes para Mandriva.
Agradecimentos a TuxFamily ( http://tuxfamily.org/ ) por albergarem este projecto.
Agradecimentos a "Nishiki" pela criação de elementos e o seu suporte.
Agradecimentos a qtcentre.org pela classe SingleApplication.
Agradecimentos a Alfredo Carreto pela tradução para Espanhol e pela correcção de traduções em Espanhol ( http://electronicosmx.comxa.com ).
[es]
Agradecimientos a Qt Software por su biblioteca Qt ( http://www.qtsoftware.com/ ), licenciada bajo GNU/GPL.
Agradecimientos a Everaldo Coelho por el tema de icónos Crystal SVG ( http://www.everaldo.com/crystal/ ), licenciado bajo LGPL.
Agradecimientos a Nuno Pinheiro por el tema de icónos Oxygen y especialmente por los icónos dedicados al programa QElectroTech ( http://www.oxygen-icons.org/ ), licenciado bajo LGPL.
Agradecimientos al proyecto KDE ( http://www.kde.org/ ).
Agradecimientos a Loic por sus explicaciones relacionadas con problemas matemáticos.
Agradecimientos a Remi Collet por criación de paquetes para Fedora.
Agradecimientos a Laurent Trinques por la creación de paquetes para Debian.
Agradecimientos a "trem" por creación de paquetes para Mandriva.
Agradecimientos a TuxFamily ( http://tuxfamily.org/ ) por el alojamiento de este proyecto.
Agradecimientos a "Nishiki" por creación de elementos e de su suporte.
Agradecimientos a qtcentre.org por classe SingleApplication.
Agradecimientos a Alfredo Carreto por sus traducciones en español y correcciones de traducción en español ( http://electronicosmx.comxa.com)
[cs]
Díky Qt Software za jejich knihovnu Qt ( http://www.qtsoftware.com/ ), pod licencí GNU/GPL.
Díky Everaldovi Coelho za téma Crystal SVG icons theme ( http://www.everaldo.com/crystal/ ) pod licencí LGPL.
Díky Nunovi Pinheirovi za téma ikon Oxygen ( http://www.oxygen-icons.org/ ) pod licencí LGPL ale také za ikony věnované QElectroTech.
Díky projektu KDE ( http://www.kde.org/ ).
Díky Loicovi za jeho vysvětlení vztahující se k matematice.
Díky Remi Colletovi za balíček pro Fedoru.
Díky Laurentu Trinquesovi za balíček pro Debian.
Díky `trem' za balíček pro Mandrivu.
Díky TuxFamily ( http://tuxfamily.org/ ) za poskytování hostingu pro projekt.
Díky `Nishiki' za jeho prvky a jeho podporu.
Díky qtcentre.org za jejich třídu SingleApplication.
Poděkování Alfredovi Carretovi za jeho španělský překlad a opravy španělského překladu ( http://electronicosmx.comxa.com )
Merci à Nicolas pour le packaging pour Mac OS X.

View File

@@ -1,86 +0,0 @@
====== Changelog 0.11 -> 0.2 ======
À partir de la version 0.2, QElectroTech est disponible en français, anglais, mais aussi :
* en espagnol, grâce aux traductions de Youssef ;
* en russe, grâce aux traductions de Yuriy ;
* en portugais, grâce aux traductions de José.
L'application utilise désormais le thème d'icônes Oxygen, réalisé par Nuno Pinheiro pour le projet KDE.
===== Notion de fichier projet =====
Un fichier .qet peut désormais contenir zéro, un ou plusieurs schémas électriques. Les éléments composant ces schémas sont embarqués dans le fichier projet au moment où ils sont posés sur un schéma. Le panel d'éléments affiche donc désormais :
* les projets ouverts, avec, sous chaque projet :
* les schémas de ce projet,
* la collection embarquée du projet (catégories et éléments utilisés dans les schémas)
* la collection commune fournie par QET,
* et la collection personnelle de l'utilisateur.
===== Éditeur de schémas =====
* Il est désormais possible de déplacer et copier les catégories et éléments par simple glisser-déposer (drag'n drop) dans le panel d'éléments.
* La collection embarquée est manipulable au même titre que la collection utilisateur. Les éléments inutilisés dans le projet apparaissent sur fond rouge et un dialogue permet de les purger rapidement.
* Chaque projet embarque également (au niveau de ses propriétés) les paramétrages par défaut pour les nouveaux schémas, cartouches et conducteurs.
* Il est possible de changer l'ordre des schémas dans le projet en déplaçant les onglets qui les représente. Dans le champ "Folio" des cartouches, on peut se référer à la position du schéma courant ou au nombre total de schémas dans le projet en écrivant respectivement %id et %total.
* Lors du chargement d'un fichier .qet, si des éléments ne sont pas trouvés, ils sont remplacés par un élément "fantôme", ce qui évite de perdre certaines informations lors de l'enregistrement du fichier.
* Le rendu avec un zoom réduit a été amélioré.
* Enfin, le logiciel gère l'ouverture en lecture seule d'un fichier projet.
==== Impression et export ====
À partir de la version 0.2, QElectroTech :
* propose d'utiliser une imprimante réelle ou bien de générer un document PDF ou PostScript, et ce sous Windows comme sous X11.
* génère un aperçu avant l'impression d'un projet. Cet aperçu permet de choisir les options d'impression mais également les schémas à imprimer ou non.
À noter toutefois une limitation pour les impressions PDF/PS sous Windows : le dialogue de mise en page, permettant de spécifier le format du papier ainsi que ses marges, n'est pas disponible.
Le dialogue "Exporter" (pour générer un fichier image d'un schéma) a également été refait dans l'optique d'un export simultané de tous les schémas du projet.
===== Éditeur d'éléments =====
* Lorsque l'on dessine une ligne dans l'éditeur d'éléments, il est possible de choisir un embout différent pour chaque extrémité, comme par exemple une flèche, un cercle, un carré ou, tout simplement, un bout de ligne normal.
* La forme "Rectangle" a été ajoutée.
* On peut enregistrer un élément en désignant un fichier (= comportement en 0.11) ou bien en choisissant un élément cible dans une liste reprenant l'arborescence du panel d'éléments.
* Si l'on maintient la touche Shift lorsque l'on ajoute une partie (droite, cercle, texte, ...), l'outil en cours est conservé après le dessin. Sinon l'éditeur repasse sur l'outil de sélection.
* La grille a été améliorée : sa densité varie en fonction du zoom ; les points correspondant à ceux de la grille de l'éditeur de schémas sont mis en valeur.
* L'accrochage à la grille (aka "snap to grid", également connu sous le nom de grille magnétique ou encore grille aimantée) a été ajouté. Le dessin s'y accroche désormais avec une précision de 1px. On peut travailler en coordonnées libres en maintenant la touche Ctrl enfoncée durant le dessin.
* Le copier-coller a été implémenté : il est possible de coller :
* avec le bouton du milieu de la souris
* en choisissant une "zone de collage" sur l'élément (Ctrl+Shift+V)
* directement (Ctrl+V) : les parties collées sont placées à côté des parties copiées ; si on recolle les parties, elles sont collées encore un cran à côté, et ce de manière incrémentale.
* Des contrôles sont désormais effectués à l'enregistrement : présence de bornes, respect du cadre, etc.
* Uniformisation des menus par rapport à l'éditeur de schémas
====== Changelog 0.1 -> 0.11 ======
===== Fonctionnalités et interface =====
* L'application est désormais capable d'ouvrir un fichier élément passe en paramètre
* L'application se lance désormais une seule fois par utilisateur
* Lors de l'ouverture d'un fichier en dehors de l'application alors que QET est déjà démarré celui-ci essaye de s'afficher ou d'attirer l'attention de l'utilisateur.
* L'application vérifie que ce fichier n'est pas déjà ouvert dans tous les éditeurs de schémas / éléments.
* Ajout de fichiers permettant d'automatiser les associations de fichiers sous Windows (.bat et .reg) et X11 (.desktop et .xml)
* Ajout de menus "Récemment ouverts" pour accéder aux fichiers récents dans les éditeurs de schémas et éléments.
* Ajout d'un splash screen
* La hauteur du schéma est désormais gérée via un système de lignes, dont le nombre et la hauteur sont ajustables.
* Il est également possible d'afficher ou non les en-têtes des lignes et/ou des colonnes.
* Ajout d'une option --lang-dir
* Ajout d'une description dans le dialogue des options d'impression
* Ajout de pages de manuel Unix (`man') en anglais et en français
===== Corrections de bugs =====
* Bug #12 : QET provoquait une erreur de segmentation dès son démarrage dans un environnement sans systray
* Bug #14 : il manquait un / dans le chemin proposé lors de l'impression vers un PDF
* Bug #15 : Mauvais positionnement des champs de texte sur le schéma
* Bug #16 : Mauvaise gestion des modifications du texte d'un conducteur
* La classe DiagramView écrivait sur la sortie d'erreur sans fin de ligne
* L'option --config-dir était mal prise en compte
* Après fermeture d'un schema, le menu Fenêtres n'était pas correctement mis à jour
* Les textes des éléments, des conducteurs, du cartouche ainsi que les textes indépendants utilisent désormais tous la même police.
* Remise à niveau de l'impression suite au passage à Qt 4.4
===== Code et détails techniques =====
* Corrections pour que QET compile avec gcc-4.3
* Les classes Conductor et Element héritent désormais de QObject (dépendance sur Qt 4.4)
* Affinage du constructeur de la classe QETApp
* Moins d'avertissements à la compilation (testé avec gcc 4.3)
* Moins d'inclusions non pertinentes
* Nettoyage du trunk : déplacement des sources dans un sous-répertoire

1320
Doxyfile

File diff suppressed because it is too large Load Diff

View File

@@ -1,83 +0,0 @@
[en]
The elements collection provided along with QElectroTech is provided as is and
without any warranty of fitness for your purpose or working.
The usage, the modification and the integration of the elements into electric
diagrams is allowed without any condition, whatever the final license of the
diagrams is.
If you redistribute all or a part of the QElectroTech collection, with or
without any modification, out of an electric diagram, you must respect the
conditions of the CC-BY license:
This work is licensed under the Creative Commons Attribution 3.0 License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
[fr]
La collection d'éléments fournie avec QElectroTech est fournie telle quelle et
sans la moindre garantie qu'elle convienne à votre utilisation ou qu'elle
fonctionne.
L'utilisation, la modification et l'intégration des éléments dans des schémas
électriques est autorisée sans condition, quelle que soit la licence finale des
schémas.
Si vous redistribuez tout ou partie de la collection QElectroTech, avec ou sans
modification, en dehors d'un schéma électrique, vous devrez respecter les
conditions de la licence CC-BY :
Cette création est mise à disposition selon le Contrat Paternité 3.0
disponible en ligne http://creativecommons.org/licenses/by/3.0/ ou par
courrier postal à Creative Commons, 171 Second Street, Suite 300, San Francisco,
California 94105, USA.
[ru]
Коллекция элементов, поставляемая вместе с QElectroTech, поставляется "как есть"
и без каких-либо гарантий пригодности для той или иной цели или работы.
Использование, изменение и интеграция элементов в электрическую
схему разрешается без каких-либо условий, безотносительно конечной лицензии на
схему.
Если Вы распространяете всю или часть коллекции QElectroTech, с или без
изменений, отдельно от электрической схемы, Вы должны соблюдать условия лицензии
CC-BY:
Эта работа лицензирована на условиях Creative Commons Attribution 3.0 License.
Чтобы увидеть копию этой лицензии, посетите
http://creativecommons.org/licenses/by/3.0/ или отправте письмо в Creative
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
(данный перевод, на русский язык, является вольным и выполнен не юристом!)
[pt]
A colecção de elementos fornecida com o programa QElectroTech é fornecida como é
e sem nenhuma garantia da aptidão para o seu uso e sem garantia de que funciona.
É permitido, sem condição alguma, qualquer que seja a licença final, usar,
editar e incluir estes elementos em esquemas eléctricos.
Se você redistribuir uma parte ou toda a colecção de elementos do programa
QElectroTech, tendo editado ou não os elementos, sem ser num esquema eléctrico,
tem de respeitar as condições da licença CC-BY:
Este trabalho está licenciado de acordo com os termos da licença Creative
Commons Attribution 3.0 License.
Para ver uma cópia da licença visite http://creativecommons.org/licenses/by/3.0/
ou envie uma carta para o endereço Creative Commons, 171 Second Street, Suite
300, San Francisco, California, 94105, USA.
[es]
La colección de elementos QElectrotech es distruibida tal cual y sin ninguna
garantía a la conveniencia de su uso y sin garantía de que funciona.
Se permite sin condicione alguna, cualquiera que sea la licencia final, usar,
editar, e incluir estos elementos en esquemas eléctricos.
Si usted redistribuye una parte de la colección o toda la collección de
QElectrotech, con o sin ediciones, fuera de un esquema eléctrico, tiene que
respetar las condiciones de la licencia CC-BY:
Esta obra está bajo una licencia Reconocimiento 3.0 de Creative Commons.
Para ver una copia de esta licencia, visite
http://creativecommons.org/licenses/by/3.0/ o envie una carta a Creative
Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.
[cs]
Sbírka prvků poskytovaná společně s QElectroTechem je poskytována tak, jak je,
bez záruky nebo vhodnosti pro váš účal nebo práci.
Používání, úpravy a začlenění prvků do nákresů elektrických
obvodů se povoluje bez jakýchkoli podmínek, cokoli je konečná licence nákresu.
Pokud rozdáte celou nebo část ze sbírky QElectroTechu, s nebo bez
jakýchkoli úprav, mimo elektrický nákres, musíte brát ohledy na podmínky
licence CC-BY:
tato práce je licencována pod licencí Creative Commons Attribution 3.0 License.
Kopii této licence si můžete prohlédnout, navštivte
http://creativecommons.org/licenses/by/3.0/ nebo pošlete dopis Creative
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

46
INSTALL
View File

@@ -6,7 +6,6 @@ cupsys-bsd for printing
Howto compile :
$ qmake (qmake-qt4 for Debian-based systems)
$ make
# umask 0022
# make install
[fr]
@@ -17,49 +16,4 @@ cupsys-bsd pour l'impression
Comment compiler :
$ qmake (qmake-qt4 pour les systèmes basés sur Debian)
$ make
# umask 0022
# make install
[ru]
Зависимости:
libQt4 (пакет libqt4*)
cupsys-bsd для печати
Как компилировать?:
$ qmake (qmake-qt4 для систем основанных на Debian)
$ make
# umask 0022
# make install
[pt]
Dependências:
libqt4 (ver pacotes libqt4*)
cupsys-bsd para impressão
Como compilar:
$ qmake (qmake-qt4 para sistemas baseados em Debian)
$ make
# umask 0022
# make install
[es]
Dependencias:
libqt4 (paquetes libqt4*)
cupsys-bsd para imprimir
Cómo compilar:
$ qmake (qmake-qt4 para los sistemas basados en Debian)
$ make
# umask 0022
# make install
[cs]
Požadavky :
libQt4 (viz balíček libqt4*)
cupsys-bsd kvůli tisku
Jak program sestavit :
$ qmake (qmake-qt4 u systémů založených na Debianu)
$ make
# umask 0022
# make install

24
README
View File

@@ -1,23 +1,9 @@
[en]
QElectroTech is a Qt4 application to design electric diagrams.
It uses XML files for elements and diagrams, and includes both a diagram editor and an element editor.
QElectroTech is a Qt4 application to design electric diagrams. It uses XML
files for elements and diagrams, and includes both a diagram editor and an
element editor.
[fr]
QElectroTech est une application Qt4 pour réaliser des schémas électriques.
QET utilise le format XML pour ses éléments et ses schémas et inclut un éditeur de schémas ainsi qu'un éditeur d'élément.
[ru]
QElectroTech - приложение написанное на Qt4 и предназначенное для разработки электрических схем.
Оно использует XML-файлы для элементов и схем, и включает, как редактор схем, так и редактор элементов.
[pt]
QElectroTech é uma aplicação baseada em Qt4 para desenhar esquemas eléctricos.
QET utiliza ficheiros XML para os elementos e para os esquemas e inclui um editor de esquemas e um editor de elementos.
[es]
QElectroTech es una aplicación Qt4 para diseñar esquemas eléctricos.
Utiliza archivos XML para los elementos y esquemas, e incluye un editor de esquemas y un editor de elemento.
[cs]
QElectroTech je aplikací Qt4 určenou pro návrh nákresů elektrických obvodů.
Pro prvky a nákresy používá soubory XML, a zahrnuje v sobě jak editor nákresů, tak editor prvků.
QET utilise le format XML pour ses éléments et ses schémas et inclut un
éditeur de schémas ainsi qu'un éditeur d'élément.

138
aboutqet.cpp Normal file
View File

@@ -0,0 +1,138 @@
/*
Copyright 2006-2008 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 "aboutqet.h"
#include "qet.h"
/**
Constructeur
@param parent Le QWidget parent de la boite de dialogue
*/
AboutQET::AboutQET(QWidget *parent) : QDialog(parent) {
// Titre, taille, comportement...
setWindowTitle(tr("\300 propos de QElectrotech"));
setMinimumWidth(680);
setMinimumHeight(350);
setModal(true);
// Trois onglets
QTabWidget *onglets = new QTabWidget(this);
onglets -> addTab(ongletAPropos(), tr("\300 &propos"));
onglets -> addTab(ongletAuteurs(), tr("A&uteurs"));
onglets -> addTab(ongletLicence(), tr("&Accord de licence"));
// Un bouton pour fermer la boite de dialogue
QDialogButtonBox *boutons = new QDialogButtonBox(QDialogButtonBox::Close);
connect(boutons, SIGNAL(accepted()), this, SLOT(accept()));
connect(boutons, SIGNAL(rejected()), this, SLOT(accept()));
// Le tout dans une disposition verticale
QVBoxLayout *disposition = new QVBoxLayout();
disposition -> addWidget(titre());
disposition -> addWidget(onglets);
disposition -> addWidget(boutons);
setLayout(disposition);
}
/**
Destructeur
*/
AboutQET::~AboutQET() {
}
/**
@return Le titre QElectroTech avec son icone
*/
QWidget *AboutQET::titre() const {
QWidget *icone_et_titre = new QWidget();
// icone
QLabel *icone = new QLabel();
icone -> setPixmap(QIcon(":/ico/qelectrotech.png").pixmap(48, 48));
// label "QElectroTech"
QLabel *titre = new QLabel("<span style=\"font-weight:0;font-size:16pt;\">QElectroTech v" + QET::version + "</span>");
titre -> setTextFormat(Qt::RichText);
// le tout dans une grille
QGridLayout *dispo_horiz = new QGridLayout();
dispo_horiz -> addWidget(icone, 0, 0);
dispo_horiz -> addWidget(titre, 0, 1);
dispo_horiz -> setColumnStretch(0, 1);
dispo_horiz -> setColumnStretch(1, 100);
icone_et_titre -> setLayout(dispo_horiz);
return(icone_et_titre);
}
/**
@return Le widget contenu par l'onglet <20> A propos <20>
*/
QWidget *AboutQET::ongletAPropos() const {
QLabel *apropos = new QLabel(
tr("QElectroTech, une application de r\351alisation de sch\351mas \351lectriques.") +
"<br><br>" +
tr("\251 2006-2008 Les d\351veloppeurs de QElectroTech") +
"<br><br>"
"<a href=\"http://qelectrotech.tuxfamily.org/\">"
"http://qelectrotech.tuxfamily.org/</a>"
);
apropos -> setAlignment(Qt::AlignCenter);
apropos -> setOpenExternalLinks(true);
apropos -> setTextFormat(Qt::RichText);
return(apropos);
}
/**
@return Le widget contenu par l'onglet <20> Auteurs <20>
*/
QWidget *AboutQET::ongletAuteurs() const {
QLabel *auteurs = new QLabel(
"<span style=\"text-decoration: underline;\">" +
tr("Id\351e originale") +
"</span> : Beno\356t Ansieau "
"&lt;<a href=\"mailto:benoit.ansieau@gmail.com\">"
"benoit.ansieau@gmail.com</a>&gt;"
"<br><br>"
"<span style=\"text-decoration: underline;\">" +
tr("Programmation") +
"</span> : Xavier Guerrin "
"&lt;<a href=\"mailto:xavier.guerrin@gmail.com\">"
"xavier.guerrin@gmail.com</a>&gt;"
);
auteurs -> setAlignment(Qt::AlignCenter);
auteurs -> setOpenExternalLinks(true);
auteurs -> setTextFormat(Qt::RichText);
return(auteurs);
}
/**
@return Le widget contenu par l'onglet <20> Accord de Licence <20>
*/
QWidget *AboutQET::ongletLicence() const {
QWidget *licence = new QWidget();
// label
QLabel *titre_licence = new QLabel(tr("Ce programme est sous licence GNU/GPL."));
// texte de la GNU/GPL dans une zone de texte scrollable non editable
QTextEdit *texte_licence = new QTextEdit();
texte_licence -> setPlainText(QET::license());
texte_licence -> setReadOnly(true);
// le tout dans une disposition verticale
QVBoxLayout *dispo_licence = new QVBoxLayout();
dispo_licence -> addWidget(titre_licence);
dispo_licence -> addWidget(texte_licence);
licence -> setLayout(dispo_licence);
return(licence);
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -17,11 +17,10 @@
*/
#ifndef ABOUTQET_H
#define ABOUTQET_H
#include <QDialog>
class QLabel;
#include <QtGui>
/**
Cette classe represente la boite de dialogue
"A propos de QElectroTech".
« A propos de QElectroTech »
*/
class AboutQET : public QDialog {
Q_OBJECT
@@ -36,12 +35,9 @@ class AboutQET : public QDialog {
// methodes
private:
QWidget *title() const;
QWidget *aboutTab() const;
QWidget *authorsTab() const;
QWidget *translatorsTab() const;
QWidget *contributorsTab() const;
QWidget *licenseTab() const;
void addAuthor(QLabel *, const QString &, const QString &, const QString &) const;
QWidget *titre() const;
QWidget *ongletAPropos() const;
QWidget *ongletAuteurs() const;
QWidget *ongletLicence() const;
};
#endif

231
borderinset.cpp Normal file
View File

@@ -0,0 +1,231 @@
/*
Copyright 2006-2008 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 "borderinset.h"
#include "qetapp.h"
/**
Constructeur simple : construit une bordure de 15 colonnes de 50x500 avec
un cartouche de 400x50.
@param parent QObject parent de ce BorderInset
*/
BorderInset::BorderInset(QObject *parent) : QObject(parent) {
nb_columns = qMax(3, QETApp::settings().value("diagrameditor/defaultcols", 15).toInt());
min_nb_columns = 3;
columns_width = QETApp::settings().value("diagrameditor/defaultcolsize", 50.0).toDouble();
columns_height = QETApp::settings().value("diagrameditor/defaultheight", 500.0).toDouble();
min_columns_height = 80.0;
inset_width = nb_columns * columns_width;
inset_height = 50.0;
columns_header_height = 20.0;
display_inset = true;
display_columns = true;
display_border = true;
updateRectangles();
bi_author = QETApp::settings().value("diagrameditor/defaultauthor").toString();
bi_title = QETApp::settings().value("diagrameditor/defaulttitle").toString();
bi_folio = QETApp::settings().value("diagrameditor/defaultfolio").toString();
bi_filename = QETApp::settings().value("diagrameditor/defaultfilename").toString();
QString settings_date = QETApp::settings().value("diagrameditor/defaultdate").toString();
if (settings_date == "now") bi_date = QDate::currentDate();
else if (settings_date.isEmpty() || settings_date == "null") bi_date = QDate();
else bi_date = QDate::fromString(settings_date, "yyyyMMdd");
}
/**
Destructeur - ne fait rien
*/
BorderInset::~BorderInset() {
}
/**
Methode recalculant les rectangles composant le cadre et le cartouche en
fonction des attributs de taille
*/
void BorderInset::updateRectangles() {
// rectangle delimitant le schema
QRectF previous_border = border;
border = QRectF(0, 0, nb_columns * columns_width, columns_height);
if (border != previous_border) emit(borderChanged(previous_border, border));
// rectangles relatifs au cartouche
inset = QRectF(border.bottomLeft().x(), border.bottomLeft().y(), inset_width, inset_height);
inset_author = QRectF(inset.topLeft(), QSizeF(2.0 * inset_width / 9.0, 0.5 * inset_height));
inset_date = QRectF(inset_author.bottomLeft(), inset_author.size());
inset_title = QRectF(inset_author.topRight(), QSizeF(5.0 * inset_width / 9.0, inset_height));
inset_file = QRectF(inset_title.topRight(), inset_author.size());
inset_folio = QRectF(inset_file.bottomLeft(), inset_author.size());
}
/**
Dessine le cadre et le cartouche
@param qp QPainter a utiliser pour dessiner le cadre et le cartouche
@param x Abscisse du cadre
@param y Ordonnee du cadre
*/
void BorderInset::draw(QPainter *qp, qreal x, qreal y) {
// translate tous les rectangles
border .translate(x, y);
inset .translate(x, y);
inset_author.translate(x, y);
inset_date .translate(x, y);
inset_title .translate(x, y);
inset_file .translate(x, y);
inset_folio .translate(x, y);
// prepare le QPainter
qp -> save();
qp -> setPen(Qt::black);
qp -> setBrush(Qt::NoBrush);
// dessine le cadre
if (display_border) qp -> drawRect(border);
// dessine la numerotation des colonnes
if (display_columns) {
qp -> setBrush(Qt::white);
for (int i = 1 ; i <= nb_columns ; ++ i) {
QRectF numbered_rectangle = QRectF(
border.topLeft().x() + ((i - 1) * columns_width),
border.topLeft().y(),
columns_width,
columns_header_height
);
qp -> drawRect(numbered_rectangle);
qp -> drawText(numbered_rectangle, Qt::AlignVCenter | Qt::AlignCenter, QString("%1").arg(i));
}
}
// dessine le cartouche
if (display_inset) {
qp -> setBrush(Qt::white);
qp -> drawRect(inset);
qp -> drawRect(inset_author);
qp -> drawText(inset_author, Qt::AlignVCenter | Qt::AlignLeft, tr(" Auteur : ") + bi_author);
qp -> drawRect(inset_date);
qp -> drawText(inset_date, Qt::AlignVCenter | Qt::AlignLeft, tr(" Date : ") + bi_date.toString("dd/MM/yyyy"));
qp -> drawRect(inset_title);
qp -> drawText(inset_title, Qt::AlignVCenter | Qt::AlignCenter, tr("Titre du document : ") + bi_title);
qp -> drawRect(inset_file);
qp -> drawText(inset_file, Qt::AlignVCenter | Qt::AlignLeft, tr(" Fichier : ") + bi_filename);
qp -> drawRect(inset_folio);
qp -> drawText(inset_folio, Qt::AlignVCenter | Qt::AlignLeft, tr(" Folio : ") + bi_folio);
}
qp -> restore();
// annule la translation des rectangles
border .translate(-x, -y);
inset .translate(-x, -y);
inset_author.translate(-x, -y);
inset_date .translate(-x, -y);
inset_title .translate(-x, -y);
inset_file .translate(-x, -y);
inset_folio .translate(-x, -y);
}
/**
Ajoute une colonne.
*/
void BorderInset::addColumn() {
++ nb_columns;
setInsetWidth(nb_columns * columns_width);
updateRectangles();
}
/**
Enleve une colonne. Il doit rester au moins 3 colonnes.
*/
void BorderInset::removeColumn() {
if (nb_columns == min_nb_columns) return;
-- nb_columns;
setInsetWidth(nb_columns * columns_width);
updateRectangles();
}
/**
Permet de changer le nombre de colonnes.
Si ce nombre de colonnes est inferieur au minimum requis, cette fonction ne
fait rien
@param nb_c nouveau nombre de colonnes
@see minNbColumns()
*/
void BorderInset::setNbColumns(int nb_c) {
if (nb_c < min_nb_columns) return;
nb_columns = nb_c;
setInsetWidth(nb_columns * columns_width);
updateRectangles();
}
/**
Change la largeur des colonnes ; celle-ci doit rester comprise entre 10 et
200px.
*/
void BorderInset::setColumnsWidth(const qreal &new_cw) {
columns_width = qBound(10.0, new_cw, 200.0);
updateRectangles();
}
/**
Change la hauteur des en-tetes contenant les numeros de colonnes. Celle-ci
doit rester comprise entre 5 et 50 px.
*/
void BorderInset::setColumnsHeaderHeight(const qreal &new_chh) {
columns_header_height = qBound(5.0, new_chh, 50.0);
updateRectangles();
}
/**
Change la hauteur des colonnes (et donc du cadre). Cette hauteur doit
rester superieure a la hauteur des en-tetes de colonnes + 20px.
*/
void BorderInset::setColumnsHeight(const qreal &new_ch) {
columns_height = qMax(columns_header_height + min_columns_height, new_ch);
updateRectangles();
}
/**
Change la largeur du cartouche. Cette largeur doit rester comprise entre
100px et la largeur du cartouche
*/
void BorderInset::setInsetWidth(const qreal &new_iw) {
inset_width = qMax(100.0, qMin(nb_columns * columns_width, new_iw));
updateRectangles();
}
/**
Change la hauteur du cartouche. Cette largeur doit rester comprise entre
20px et la hauteur du cartouche.
*/
void BorderInset::setInsetHeight(const qreal &new_ih) {
inset_height = qMax(20.0, qMin(columns_height, new_ih));
updateRectangles();
}
/**
Ajuste la largeur du cartouche de facon a ce que celui-ci soit aussi large
que le schema
*/
void BorderInset::adjustInsetToColumns() {
setInsetWidth(nbColumn() * columnsWidth());
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -18,12 +18,10 @@
#ifndef BORDERINSET_H
#define BORDERINSET_H
#include "insetproperties.h"
#include "borderproperties.h"
#include <QObject>
#include <QRectF>
#include <QPainter>
#include <QDate>
class QPainter;
class DiagramPosition;
/**
Cette classe represente l'ensemble bordure + cartouche qui encadre le
schema electrique.
@@ -41,51 +39,29 @@ class BorderInset : public QObject {
// methodes
public:
static int minNbColumns();
static qreal minColumnsWidth();
static int minNbRows();
static qreal minRowsHeight();
void draw(QPainter *, qreal = 0.0, qreal = 0.0);
// methodes d'acces en lecture aux dimensions
// colonnes
/// @return le nombre de colonnes du schema
int nbColumns() const { return(nb_columns); }
/// @return la largeur des colonnes en pixels
int nbColumn() const { return(nb_columns); }
/// @return la taille des colonnes en pixels
qreal columnsWidth() const { return(columns_width); }
/// @return la taille de l'ensemble des colonnes, en-tete des lignes non inclus
qreal columnsTotalWidth() const { return(nb_columns * columns_width); }
/// @return la hauteur, en pixels, des en-tetes des colonnes
qreal columnsHeaderHeight() const { return(columns_header_height); }
// lignes
/// @return le nombre de lignes du schema
int nbRows() const { return(nb_rows); }
/// @return la hauteur des lignes en pixels
qreal rowsHeight() const { return(rows_height); }
/// @return la taille de l'ensemble des lignes, en-tete des colonnes non inclus
qreal rowsTotalHeight() const { return(nb_rows * rows_height); }
/// @return la largeur, en pixels, des en-tetes des lignes
qreal rowsHeaderWidth() const { return(rows_header_width); }
// cadre sans le cartouche = schema
/// @return la largeur du schema, c'est-a-dire du cadre sans le cartouche
qreal diagramWidth() const { return(columnsTotalWidth() + rowsHeaderWidth()); }
/// @return la hauteurdu schema, c'est-a-dire du cadre sans le cartouche
qreal diagramHeight() const { return(rowsTotalHeight() + columnsHeaderHeight()); }
// cartouche
/// @return la hauteur des colonnes, en-tetes inclus
qreal columnsHeight() const { return(columns_height); }
/// @return la largeur de la bordure
qreal borderWidth() const { return(nb_columns * columns_width); }
/// @return la hauteur de la bordure
qreal borderHeight() const { return(columns_height + inset_height); }
/// @return la largeur du cartouche
qreal insetWidth() const { return(inset_width); }
/// @return la hauteur du cartouche
qreal insetHeight() const { return(inset_height); }
// cadre avec le cartouche
/// @return la hauteur de la bordure
qreal borderWidth() const { return(diagramWidth()); }
/// @return la hauteur de la bordure
qreal borderHeight() const { return(diagramHeight() + insetHeight()); }
/// @return la hauteur minimale acceptee des colonnes
qreal minColumnsHeight() const { return(min_columns_height); }
/// @return le nombre minimum accepte de colonnes
int minNbColumns() const { return(min_nb_columns); }
// methodes d'acces en lecture aux informations du cartouche
/// @return le champ "Auteur" du cartouche
@@ -104,61 +80,62 @@ class BorderInset : public QObject {
bool insetIsDisplayed() const { return(display_inset); }
/// @return true si les entetes des colonnes sont affiches, false sinon
bool columnsAreDisplayed() const { return(display_columns); }
/// @return true si les entetes des lignes sont affiches, false sinon
bool rowsAreDisplayed() const { return(display_rows); }
/// @return true si la bordure est affichee, false sinon
bool borderIsDisplayed() const { return(display_border); }
// methodes d'acces en ecriture aux dimensions
void addColumn ();
void addRow ();
void removeColumn ();
void removeRow ();
void setNbColumns (int);
void setNbRows (int);
void setColumnsWidth (const qreal &);
void setRowsHeight (const qreal &);
void setColumnsHeaderHeight(const qreal &);
void setRowsHeaderWidth (const qreal &);
void setDiagramHeight (const qreal &);
void setColumnsHeight (const qreal &);
void setInsetWidth (const qreal &);
void setInsetHeight (const qreal &);
void adjustInsetToColumns ();
DiagramPosition convertPosition(const QPointF &);
// methodes d'acces en ecriture aux informations du cartouche
/// @param author le nouveau contenu du champ "Auteur"
void setAuthor (const QString &author) { bi_author = author; }
/// @param date le nouveau contenu du champ "Date"
void setDate (const QDate &date) { bi_date = date; }
/// @param title le nouveau contenu du champ "Titre"
void setTitle (const QString &title) {
if (bi_title != title) {
bi_title = title;
emit(diagramTitleChanged(title));
}
}
void setTitle (const QString &title) { bi_title = title; }
/// @param folio le nouveau contenu du champ "Folio"
void setFolio (const QString &folio) { bi_folio = folio; }
void setFolioData(int, int);
/// @param filename le nouveau contenu du champ "Fichier"
void setFileName (const QString &filename) { bi_filename = filename; }
InsetProperties exportInset();
void importInset(const InsetProperties &);
BorderProperties exportBorder();
void importBorder(const BorderProperties &);
/// @return les proprietes du cartouches
InsetProperties exportInset() {
InsetProperties ip;
ip.author = bi_author;
ip.date = bi_date;
ip.title = bi_title;
ip.folio = bi_folio;
ip.filename = bi_filename;
return(ip);
}
/// @param ip les nouvelles proprietes du cartouche
void importInset(const InsetProperties &ip) {
bi_author = ip.author;
bi_date = ip.date;
bi_title = ip.title;
bi_folio = ip.folio;
bi_filename = ip.filename;
}
// methodes d'acces en ecriture aux options
void displayInset(bool);
void displayColumns(bool);
void displayRows(bool);
void displayBorder(bool);
/// @param di true pour afficher le cartouche, false sinon
void displayInset (bool di) { display_inset = di; }
/// @param dc true pour afficher les entetes des colonnes, false sinon
void displayColumns (bool dc) { display_columns = dc; }
/// @param db true pour afficher la bordure du schema, false sinon
void displayBorder (bool db) { display_border = db; }
private:
void updateRectangles();
QString incrementLetters(const QString &);
// signaux
signals:
@@ -168,21 +145,6 @@ class BorderInset : public QObject {
@param new_border Nouvelle bordure
*/
void borderChanged(QRectF old_border, QRectF new_border);
/**
Signal emise lorsque des options d'affichage change
*/
void displayChanged();
/**
Signal emis lorsque le titre du schema change
*/
void diagramTitleChanged(const QString &);
/**
Signal emis lorsque le cartouche requiert une mise a jour des donnees
utilisees pour generer le folio.
*/
void needFolioData();
// attributs
private:
@@ -191,28 +153,20 @@ class BorderInset : public QObject {
QDate bi_date;
QString bi_title;
QString bi_folio;
QString bi_final_folio;
int folio_index_;
int folio_total_;
QString bi_filename;
// dimensions du cadre (lignes et colonnes)
// colonnes : nombres et dimensions
// dimensions du cadre et du cartouche
int nb_columns;
int min_nb_columns;
qreal columns_width;
qreal columns_header_height;
// lignes : nombres et dimensions
int nb_rows;
qreal rows_height;
qreal rows_header_width;
// dimensions du cartouche
qreal columns_height;
qreal min_columns_height;
qreal inset_width;
qreal inset_height;
// rectangles utilises pour le dessin
QRectF diagram;
QRectF border;
QRectF inset;
QRectF inset_author;
QRectF inset_date;
@@ -223,7 +177,6 @@ class BorderInset : public QObject {
// booleens pour les options de dessin
bool display_inset;
bool display_columns;
bool display_rows;
bool display_border;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,7 +19,6 @@
#include "conductor.h"
#include "conductorsegment.h"
#include "conductorsegmentprofile.h"
#include "diagramtextitem.h"
#include "element.h"
#include "diagram.h"
#include "diagramcommands.h"
@@ -37,7 +36,6 @@ QBrush Conductor::square_brush = QBrush(Qt::darkGreen);
@param scene QGraphicsScene a laquelle appartient le conducteur
*/
Conductor::Conductor(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene *scene) :
QObject(),
QGraphicsPathItem(parent, scene),
terminal1(p1),
terminal2(p2),
@@ -47,8 +45,7 @@ Conductor::Conductor(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene
moving_segment(false),
previous_z_value(zValue()),
modified_path(false),
has_to_save_profile(false),
segments_squares_scale_(1.0)
has_to_save_profile(false)
{
// ajout du conducteur a la liste de conducteurs de chacune des deux bornes
bool ajout_p1 = terminal1 -> addConductor(this);
@@ -88,12 +85,6 @@ Conductor::Conductor(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene
text_item -> previous_text = properties_.text;
calculateTextItemPosition();
text_item -> setParentItem(this);
connect(
text_item,
SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
this,
SLOT(displayedTextChanged())
);
}
/**
@@ -193,9 +184,7 @@ void Conductor::segmentsToPath() {
@param p2 Coordonnees du point d'amarrage de la borne 2
@param o2 Orientation de la borne 2
*/
void Conductor::priv_modifieConductor(const QPointF &p1, QET::Orientation o1, const QPointF &p2, QET::Orientation o2) {
Q_UNUSED(o1);
Q_UNUSED(o2);
void Conductor::priv_modifieConductor(const QPointF &p1, QET::Orientation, const QPointF &p2, QET::Orientation) {
ConductorProfile &conductor_profile = conductor_profiles[currentPathType()];
@@ -363,40 +352,40 @@ void Conductor::priv_calculeConductor(const QPointF &p1, QET::Orientation o1, co
if (depart.y() < arrivee.y()) {
// trajet descendant
if ((ori_depart == QET::North && (ori_arrivee == QET::South || ori_arrivee == QET::West)) || (ori_depart == QET::East && ori_arrivee == QET::West)) {
// cas "3"
// cas « 3 »
int ligne_inter_x = qRound(depart.x() + arrivee.x()) / 2;
while (ligne_inter_x % Diagram::xGrid) -- ligne_inter_x;
points << QPointF(ligne_inter_x, depart.y());
points << QPointF(ligne_inter_x, arrivee.y());
} else if ((ori_depart == QET::South && (ori_arrivee == QET::North || ori_arrivee == QET::East)) || (ori_depart == QET::West && ori_arrivee == QET::East)) {
// cas "4"
// cas « 4 »
int ligne_inter_y = qRound(depart.y() + arrivee.y()) / 2;
while (ligne_inter_y % Diagram::yGrid) -- ligne_inter_y;
points << QPointF(depart.x(), ligne_inter_y);
points << QPointF(arrivee.x(), ligne_inter_y);
} else if ((ori_depart == QET::North || ori_depart == QET::East) && (ori_arrivee == QET::North || ori_arrivee == QET::East)) {
points << QPointF(arrivee.x(), depart.y()); // cas "2"
points << QPointF(arrivee.x(), depart.y()); // cas « 2 »
} else {
points << QPointF(depart.x(), arrivee.y()); // cas "1"
points << QPointF(depart.x(), arrivee.y()); // cas « 1 »
}
} else {
// trajet montant
if ((ori_depart == QET::West && (ori_arrivee == QET::East || ori_arrivee == QET::South)) || (ori_depart == QET::North && ori_arrivee == QET::South)) {
// cas "3"
// cas « 3 »
int ligne_inter_y = qRound(depart.y() + arrivee.y()) / 2;
while (ligne_inter_y % Diagram::yGrid) -- ligne_inter_y;
points << QPointF(depart.x(), ligne_inter_y);
points << QPointF(arrivee.x(), ligne_inter_y);
} else if ((ori_depart == QET::East && (ori_arrivee == QET::West || ori_arrivee == QET::North)) || (ori_depart == QET::South && ori_arrivee == QET::North)) {
// cas "4"
// cas « 4 »
int ligne_inter_x = qRound(depart.x() + arrivee.x()) / 2;
while (ligne_inter_x % Diagram::xGrid) -- ligne_inter_x;
points << QPointF(ligne_inter_x, depart.y());
points << QPointF(ligne_inter_x, arrivee.y());
} else if ((ori_depart == QET::West || ori_depart == QET::North) && (ori_arrivee == QET::West || ori_arrivee == QET::North)) {
points << QPointF(depart.x(), arrivee.y()); // cas "2"
points << QPointF(depart.x(), arrivee.y()); // cas « 2 »
} else {
points << QPointF(arrivee.x(), depart.y()); // cas "1"
points << QPointF(arrivee.x(), depart.y()); // cas « 1 »
}
}
@@ -450,43 +439,23 @@ QPointF Conductor::extendTerminal(const QPointF &terminal, QET::Orientation term
@param options Les options de style pour le conducteur
@param qw Le QWidget sur lequel on dessine
*/
void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWidget *qw) {
Q_UNUSED(qw);
void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWidget */*qw*/) {
qp -> save();
qp -> setRenderHint(QPainter::Antialiasing, false);
// determine la couleur du conducteur
QColor final_conductor_color(properties_.color);
if (isSelected()) {
final_conductor_color = Qt::red;
} else {
if (Diagram *parent_diagram = diagram()) {
if (!parent_diagram -> drawColoredConductors()) {
final_conductor_color = Qt::black;
}
}
}
// affectation du QPen et de la QBrush modifies au QPainter
qp -> setBrush(conductor_brush);
QPen final_conductor_pen = conductor_pen;
// modification du QPen generique pour lui affecter la couleur et le style adequats
final_conductor_pen.setColor(final_conductor_color);
final_conductor_pen.setStyle(properties_.style);
final_conductor_pen.setJoinStyle(Qt::SvgMiterJoin); // meilleur rendu des pointilles
// utilisation d'un trait "cosmetique" en-dessous d'un certain zoom
if (options && options -> levelOfDetail < 1.0) {
final_conductor_pen.setCosmetic(true);
qp -> setPen(conductor_pen);
if (isSelected()) {
QPen tmp = qp -> pen();
tmp.setColor(Qt::red);
qp -> setPen(tmp);
}
qp -> setPen(final_conductor_pen);
// dessin du conducteur
qp -> drawPath(path());
if (properties_.type == ConductorProperties::Single) {
qp -> setBrush(final_conductor_color);
if (isSelected()) qp -> setBrush(Qt::red);
properties_.singleLineProperties.draw(
qp,
middleSegment() -> isHorizontal() ? QET::Horizontal : QET::Vertical,
@@ -495,8 +464,8 @@ void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWi
if (isSelected()) qp -> setBrush(Qt::NoBrush);
}
// decalage ideal pour le rendu centre d'un carre / cercle de 2.0 px de cote / diametre
qreal pretty_offset = (options -> levelOfDetail == 1 ? 1.0 : 1.0);
// decalage ideal pour le rendu centre d'un carre / cercle de 5.0 px de cote / diametre
qreal pretty_offset = (options -> levelOfDetail == 1 ? 2.0 : 2.5);
// dessin des points d'accroche du conducteur si celui-ci est selectionne
if (isSelected()) {
@@ -509,10 +478,10 @@ void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWi
if (i > 1) {
qp -> fillRect(
QRectF(
((previous_point.x() + point.x()) / 2.0 ) - pretty_offset * segments_squares_scale_,
((previous_point.y() + point.y()) / 2.0 ) - pretty_offset * segments_squares_scale_,
2.0 * segments_squares_scale_,
2.0 * segments_squares_scale_
((previous_point.x() + point.x()) / 2.0 ) - pretty_offset,
((previous_point.y() + point.y()) / 2.0 ) - pretty_offset,
5.0,
5.0
),
square_brush
);
@@ -524,13 +493,12 @@ void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWi
// dessine les eventuelles jonctions
QList<QPointF> junctions_list = junctions();
if (!junctions_list.isEmpty()) {
final_conductor_pen.setStyle(Qt::SolidLine);
QBrush junction_brush(final_conductor_color, Qt::SolidPattern);
qp -> setPen(final_conductor_pen);
QBrush junction_brush(Qt::SolidPattern);
junction_brush.setColor(isSelected() ? Qt::red : Qt::black);
qp -> setBrush(junction_brush);
qp -> setRenderHint(QPainter::Antialiasing, true);
foreach(QPointF point, junctions_list) {
qp -> drawEllipse(QRectF(point.x() - pretty_offset, point.y() - pretty_offset, 2.0, 2.0));
qp -> drawEllipse(QRectF(point.x() - pretty_offset, point.y() - pretty_offset, 5.0, 5.0));
}
}
qp -> restore();
@@ -595,11 +563,15 @@ void Conductor::mousePressEvent(QGraphicsSceneMouseEvent *e) {
if (hasClickedOn(press_point, segment -> secondPoint())) {
moving_point = true;
moving_segment = false;
previous_z_value = zValue();
setZValue(5000.0);
moved_segment = segment;
break;
} else if (hasClickedOn(press_point, segment -> middle())) {
moving_point = false;
moving_segment = true;
previous_z_value = zValue();
setZValue(5000.0);
moved_segment = segment;
break;
}
@@ -607,9 +579,6 @@ void Conductor::mousePressEvent(QGraphicsSceneMouseEvent *e) {
}
}
QGraphicsPathItem::mousePressEvent(e);
if (e -> modifiers() & Qt::ControlModifier) {
setSelected(!isSelected());
}
}
/**
@@ -628,7 +597,6 @@ void Conductor::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
mouse_x = qRound(mouse_x / (Diagram::xGrid * 1.0)) * Diagram::xGrid;
mouse_y = qRound(mouse_y / (Diagram::yGrid * 1.0)) * Diagram::yGrid;
}
if (moving_point) {
// la modification par points revient bientot
/*
@@ -676,36 +644,11 @@ void Conductor::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
saveProfile();
has_to_save_profile = false;
}
if (!(e -> modifiers() & Qt::ControlModifier)) {
setZValue(previous_z_value);
QGraphicsPathItem::mouseReleaseEvent(e);
}
calculateTextItemPosition();
}
/**
Gere l'entree de la souris dans la zone du conducteur
@param e Le QGraphicsSceneHoverEvent decrivant l'evenement
*/
void Conductor::hoverEnterEvent(QGraphicsSceneHoverEvent *e) {
Q_UNUSED(e);
segments_squares_scale_ = 2.0;
if (isSelected()) {
update();
}
}
/**
Gere la sortie de la souris de la zone du conducteur
@param e Le QGraphicsSceneHoverEvent decrivant l'evenement
*/
void Conductor::hoverLeaveEvent(QGraphicsSceneHoverEvent *e) {
Q_UNUSED(e);
segments_squares_scale_ = 1.0;
if (isSelected()) {
update();
}
}
/**
Gere les mouvements de souris au dessus du conducteur
@param e Le QGraphicsSceneHoverEvent decrivant l'evenement
@@ -732,27 +675,6 @@ void Conductor::hoverMoveEvent(QGraphicsSceneHoverEvent *e) {
QGraphicsPathItem::hoverMoveEvent(e);
}
/**
Gere les changements relatifs au conducteur
Reimplemente ici pour :
* positionner le conducteur en avant-plan lorsqu'il est selectionne
@param change
@param value
*/
QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value) {
if (change == QGraphicsItem::ItemSelectedChange) {
if (value.toBool()) {
// le conducteur vient de se faire selectionner
previous_z_value = zValue();
setZValue(qAbs(previous_z_value) + 10000);
} else {
// le conducteur vient de se faire deselectionner
setZValue(previous_z_value);
}
}
return(QGraphicsPathItem::itemChange(change, value));
}
/**
@return Le rectangle delimitant l'espace de dessin du conducteur
*/
@@ -809,7 +731,6 @@ QPainterPath Conductor::shape() const {
@param tobound valeur a borner
@param bound1 borne 1
@param bound2 borne 2
@param space marge interne ajoutee
@return La valeur bornee
*/
qreal Conductor::conductor_bound(qreal tobound, qreal bound1, qreal bound2, qreal space) {
@@ -952,15 +873,13 @@ bool Conductor::fromXml(QDomElement &e) {
QPointF t2 = terminal2 -> amarrageConductor();
qreal expected_width = t2.x() - t1.x();
qreal expected_height = t2.y() - t1.y();
// on considere que le trajet est incoherent a partir d'une unite de difference avec l'espacement entre les bornes
qreal precision = std::numeric_limits<qreal>::epsilon();
if (
qAbs(expected_width - width) > 1.0 ||
qAbs(expected_height - height) > 1.0
) {
qDebug() << "Conductor::fromXml : les segments du conducteur ne semblent pas coherents - utilisation d'un trajet automatique";
return(false);
}
expected_width > width + precision ||\
expected_width < width - precision ||\
expected_height > height + precision ||\
expected_height < height - precision
) return(false);
/* on recree les segments a partir des donnes XML */
// cree la liste de points
@@ -1003,13 +922,13 @@ QDomElement Conductor::toXml(QDomDocument &d, QHash<Terminal *, int> &table_adr_
foreach(ConductorSegment *segment, segmentsList()) {
current_segment = d.createElement("segment");
current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical");
current_segment.setAttribute("length", QString("%1").arg(segment -> length()));
current_segment.setAttribute("length", segment -> length());
e.appendChild(current_segment);
}
}
// exporte la "configuration" du conducteur
properties_.toXml(e);
properties_.toXml(d, e);
return(e);
}
@@ -1159,30 +1078,10 @@ ConductorProperties Conductor::properties() const {
Relit les proprietes et les applique
*/
void Conductor::readProperties() {
// la couleur n'est vraiment applicable que lors du rendu du conducteur
setText(properties_.text);
text_item -> setVisible(properties_.type == ConductorProperties::Multi);
}
/**
Met a jour les proprietes du conducteur apres modification du champ de texte affiche
*/
void Conductor::displayedTextChanged() {
// verifie que le texte a reellement change
if (text_item -> toPlainText() == properties_.text) return;
// initialise l'objet UndoCommand correspondant
if (Diagram *my_diagram = diagram()) {
ConductorProperties new_properties(properties_);
new_properties.text = text_item -> toPlainText();
ChangeConductorPropertiesCommand *ccpc = new ChangeConductorPropertiesCommand(this);
ccpc -> setOldSettings(properties_);
ccpc -> setNewSettings(new_properties);
my_diagram -> undoStack().push(ccpc);
}
}
/**
@return les conducteurs avec lesquels ce conducteur partage des bornes
communes
@@ -1195,33 +1094,6 @@ QSet<Conductor *> Conductor::relatedConductors() const {
return(other_conductors);
}
/**
@param a reel
@param b reel
@param c reel
@return true si a est entre b et c ou est egal a l'un des deux
*/
bool isBetween(qreal a, qreal b, qreal c) {
if (b <= c) {
return(a >= b && a <= c);
} else {
return(a <= b && a >= c);
}
}
/**
@param a point
@param b point
@param c point
@return true si le point a est contenu dans le rectangle delimite par les points b et c
*/
bool isContained(const QPointF &a, const QPointF &b, const QPointF &c) {
return(
isBetween(a.x(), b.x(), c.x()) &&
isBetween(a.y(), b.y(), c.y())
);
}
/**
@return la liste des positions des jonctions avec d'autres conducteurs
*/
@@ -1263,8 +1135,9 @@ QList<QPointF> Conductor::junctions() const {
// parcoure les segments a la recherche d'un point commun
for (int j = 0 ; j < c_segments.count() ; ++ j) {
ConductorSegment *segment = c_segments[j];
QRectF rect(segment -> firstPoint(), segment -> secondPoint());
// un point commun a ete trouve sur ce segment
if (isContained(conductor_point, segment -> firstPoint(), segment -> secondPoint())) {
if (rect.contains(conductor_point)) {
is_junction = true;
// ce point commun ne doit pas etre une bifurcation identique a celle-ci
QList<ConductorBend> other_conductor_bends = c -> bends();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -21,17 +21,15 @@
#include "terminal.h"
#include "conductorprofile.h"
#include "conductorproperties.h"
#include "diagramtextitem.h"
class ConductorSegment;
class DiagramTextItem;
class Element;
typedef QPair<QPointF, Qt::Corner> ConductorBend;
typedef QHash<Qt::Corner, ConductorProfile> ConductorProfilesGroup;
/**
Cette classe represente un conducteur. Un conducteur relie deux bornes d'element.
*/
class Conductor : public QObject, public QGraphicsPathItem {
Q_OBJECT
class Conductor : public QGraphicsPathItem {
// constructeurs, destructeur
public:
@@ -83,17 +81,11 @@ class Conductor : public QObject, public QGraphicsPathItem {
ConductorProfilesGroup profiles() const;
void readProperties();
public slots:
void displayedTextChanged();
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *);
virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
private:
/// caracteristiques du conducteur
@@ -122,8 +114,6 @@ class Conductor : public QObject, public QGraphicsPathItem {
static QBrush conductor_brush;
static QBrush square_brush;
static bool pen_and_brush_initialized;
/// facteur de taille du carre de saisie du segment
qreal segments_squares_scale_;
private:
void segmentsToPath();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -140,8 +140,7 @@ void SingleLineProperties::drawGround(QPainter *painter, QET::ConductorSegmentTy
@param center centre du cercle
@param size diametre du cercle
*/
void SingleLineProperties::drawNeutral(QPainter *painter, QET::ConductorSegmentType direction, QPointF center, qreal size) {
Q_UNUSED(direction);
void SingleLineProperties::drawNeutral(QPainter *painter, QET::ConductorSegmentType, QPointF center, qreal size) {
painter -> save();
// prepare le QPainter
@@ -160,18 +159,19 @@ void SingleLineProperties::drawNeutral(QPainter *painter, QET::ConductorSegmentT
}
/**
Exporte les parametres du conducteur unifilaire sous formes d'attributs XML
exporte les parametres du conducteur unifilaire sous formes d'attributs XML
ajoutes a l'element e.
@param d Document XML ; utilise pour ajouter (potentiellement) des elements XML
@param e Element XML auquel seront ajoutes des attributs
*/
void SingleLineProperties::toXml(QDomElement &e) const {
void SingleLineProperties::toXml(QDomDocument &, QDomElement &e) const {
e.setAttribute("ground", hasGround ? "true" : "false");
e.setAttribute("neutral", hasNeutral ? "true" : "false");
e.setAttribute("phase", phases);
}
/**
Importe les parametres du conducteur unifilaire a partir des attributs XML
importe les parametres du conducteur unifilaire a partir des attributs XML
de l'element e
@param e Element XML dont les attributs seront lus
*/
@@ -182,64 +182,26 @@ void SingleLineProperties::fromXml(QDomElement &e) {
}
/**
Constructeur : par defaut, les proprietes font un conducteur
multifilaire noir dont le texte est "_"
*/
ConductorProperties::ConductorProperties() :
type(Multi),
color(Qt::black),
text("_"),
style(Qt::SolidLine)
{
}
/**
Destructeur
*/
ConductorProperties::~ConductorProperties() {
}
/**
Exporte les parametres du conducteur sous formes d'attributs XML
exporte les parametres du conducteur sous formes d'attributs XML
ajoutes a l'element e.
@param d Document XML ; utilise pour ajouter (potentiellement) des elements XML
@param e Element XML auquel seront ajoutes des attributs
*/
void ConductorProperties::toXml(QDomElement &e) const {
void ConductorProperties::toXml(QDomDocument &d, QDomElement &e) const {
e.setAttribute("type", typeToString(type));
if (color != QColor(Qt::black)) {
e.setAttribute("color", color.name());
}
if (type == Single) {
singleLineProperties.toXml(e);
singleLineProperties.toXml(d, e);
} else if (type == Multi) {
e.setAttribute("num", text);
}
QString conductor_style = writeStyle();
if (!conductor_style.isEmpty()) {
e.setAttribute("style", conductor_style);
}
}
/**
Importe les parametres du conducteur unifilaire a partir des attributs XML
importe les parametres du conducteur unifilaire a partir des attributs XML
de l'element e
@param e Element XML dont les attributs seront lus
*/
void ConductorProperties::fromXml(QDomElement &e) {
// recupere la couleur du conducteur
QColor xml_color= QColor(e.attribute("color"));
if (xml_color.isValid()) {
color = xml_color;
} else {
color = QColor(Qt::black);
}
// lit le style du conducteur
readStyle(e.attribute("style"));
if (e.attribute("type") == typeToString(Single)) {
// recupere les parametres specifiques a un conducteur unifilaire
singleLineProperties.fromXml(e);
@@ -255,11 +217,9 @@ void ConductorProperties::fromXml(QDomElement &e) {
/**
@param settings Parametres a ecrire
@param prefix prefixe a ajouter devant les noms des parametres
@param prefix prefix a ajouter devant les noms des parametres
*/
void ConductorProperties::toSettings(QSettings &settings, const QString &prefix) const {
settings.setValue(prefix + "color", color.name());
settings.setValue(prefix + "style", writeStyle());
settings.setValue(prefix + "type", typeToString(type));
settings.setValue(prefix + "text", text);
singleLineProperties.toSettings(settings, prefix);
@@ -267,17 +227,9 @@ void ConductorProperties::toSettings(QSettings &settings, const QString &prefix)
/**
@param settings Parametres a lire
@param prefix prefixe a ajouter devant les noms des parametres
@param prefix prefix a ajouter devant les noms des parametres
*/
void ConductorProperties::fromSettings(QSettings &settings, const QString &prefix) {
// recupere la couleur dans les parametres
QColor settings_color = QColor(settings.value(prefix + "color").toString());
if (settings_color.isValid()) {
color = settings_color;
} else {
color = QColor(Qt::black);
}
QString setting_type = settings.value(prefix + "type", typeToString(Multi)).toString();
if (setting_type == typeToString(Single)) {
type = Single;
@@ -288,9 +240,6 @@ void ConductorProperties::fromSettings(QSettings &settings, const QString &prefi
}
singleLineProperties.fromSettings(settings, prefix);
text = settings.value(prefix + "text", "_").toString();
// lit le style du conducteur
readStyle(settings.value(prefix + "style").toString());
}
/**
@@ -312,8 +261,6 @@ QString ConductorProperties::typeToString(ConductorType t) {
int ConductorProperties::operator==(const ConductorProperties &other) {
return(
other.type == type &&\
other.color == color &&\
other.color == style &&\
other.text == text &&\
other.singleLineProperties == singleLineProperties
);
@@ -326,50 +273,11 @@ int ConductorProperties::operator==(const ConductorProperties &other) {
int ConductorProperties::operator!=(const ConductorProperties &other) {
return(
other.type != type ||\
other.color != color ||\
other.color != style ||\
other.text != text ||\
other.singleLineProperties != singleLineProperties
);
}
/**
Applique les styles passes en parametre dans cet objet
@param style_string Chaine decrivant le style du conducteur
*/
void ConductorProperties::readStyle(const QString &style_string) {
style = Qt::SolidLine; // style par defaut
if (style_string.isEmpty()) return;
// recupere la liste des couples style / valeur
QStringList styles = style_string.split(";", QString::SkipEmptyParts);
QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
foreach (QString style_str, styles) {
if (rx.exactMatch(style_str)) {
QString style_name = rx.cap(1);
QString style_value = rx.cap(2);
if (style_name == "line-style") {
if (style_value == "dashed") style = Qt::DashLine;
else if (style_value == "normal") style = Qt::SolidLine;
}
}
}
}
/**
Exporte le style du conducteur sous forme d'une chaine de caracteres
@return une chaine de caracteres decrivant le style du conducteur
*/
QString ConductorProperties::writeStyle() const {
if (style == Qt::DashLine) {
return("line-style: dashed;");
} else {
return(QString());
}
}
/**
@param other l'autre ensemble de proprietes avec lequel il faut effectuer la comparaison
@return true si les deux ensembles de proprietes sont identiques, false sinon

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -31,7 +31,7 @@ class SingleLineProperties {
void setPhasesCount(int);
unsigned short int phasesCount();
void draw(QPainter *, QET::ConductorSegmentType, const QRectF &);
void toXml(QDomElement &) const;
void toXml(QDomDocument &, QDomElement &) const;
void fromXml(QDomElement &);
void toSettings(QSettings &, const QString & = QString()) const;
void fromSettings(QSettings &, const QString & = QString());
@@ -57,8 +57,16 @@ class SingleLineProperties {
class ConductorProperties {
// constructeurs, destructeur
public:
ConductorProperties();
virtual ~ConductorProperties();
/**
Constructeur : par defaut, les proprietes font un conducteur
multifilaire dont le texte est "_"
*/
ConductorProperties() : type(Multi), text("_") {
}
/// Destructeur
virtual ~ConductorProperties() {
}
/**
Represente le type d'un conducteur :
@@ -71,18 +79,15 @@ class ConductorProperties {
// attributs
/// type du conducteur
ConductorType type;
/// couleur du conducteur
QColor color;
/// texte affiche si le conducteur est multifilaire
QString text;
/// style du conducteur (Qt::SolidLine ou Qt::DashLine)
Qt::PenStyle style;
/// proprietes si le conducteur est unifilaire
SingleLineProperties singleLineProperties;
// methodes
void toXml(QDomElement &) const;
void toXml(QDomDocument &, QDomElement &) const;
void fromXml(QDomElement &);
void toSettings(QSettings &, const QString & = QString()) const;
void fromSettings(QSettings &, const QString & = QString());
@@ -91,9 +96,5 @@ class ConductorProperties {
// operateurs
int operator==(const ConductorProperties &);
int operator!=(const ConductorProperties &);
private:
void readStyle(const QString &);
QString writeStyle() const;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -16,9 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "conductorpropertieswidget.h"
#include <QtGui>
#include "conductor.h"
#include "qeticons.h"
/**
Constructeur
@@ -45,10 +43,9 @@ ConductorPropertiesWidget::ConductorPropertiesWidget(const ConductorProperties &
/// construit l'interface du widget
void ConductorPropertiesWidget::buildInterface() {
setMinimumSize(380, 350);
setMinimumSize(380, 280);
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout -> setContentsMargins(0, 0, 0, 0);
QGroupBox *groupbox = new QGroupBox(tr("Type de conducteur"));
main_layout -> addWidget(groupbox);
@@ -69,7 +66,7 @@ void ConductorPropertiesWidget::buildInterface() {
QHBoxLayout *singleline_layout3 = new QHBoxLayout();
phase_checkbox = new QCheckBox(tr("phase"));
phase_checkbox -> setIcon(QET::Icons::Phase);
phase_checkbox -> setIcon(QIcon(":/ico/phase.png"));
phase_slider = new QSlider(Qt::Horizontal);
phase_slider -> setRange(1, 3);
phase_spinbox = new QSpinBox();
@@ -80,9 +77,9 @@ void ConductorPropertiesWidget::buildInterface() {
QVBoxLayout *singleline_layout2 = new QVBoxLayout();
ground_checkbox = new QCheckBox(tr("terre"));
ground_checkbox -> setIcon(QET::Icons::Ground);
ground_checkbox -> setIcon(QIcon(":/ico/ground.png"));
neutral_checkbox = new QCheckBox(tr("neutre"));
neutral_checkbox -> setIcon(QET::Icons::Neutral);
neutral_checkbox -> setIcon(QIcon(":/ico/neutral.png"));
singleline_layout2 -> addWidget(ground_checkbox);
singleline_layout2 -> addWidget(neutral_checkbox);
singleline_layout2 -> addLayout(singleline_layout3);
@@ -93,32 +90,12 @@ void ConductorPropertiesWidget::buildInterface() {
singleline_layout1 -> addWidget(preview);
singleline_layout1 -> addLayout(singleline_layout2);
QGroupBox *groupbox2 = new QGroupBox(tr("Apparence du conducteur"));
main_layout -> addWidget(groupbox2);
QVBoxLayout *groupbox2_layout = new QVBoxLayout();
groupbox2 -> setLayout(groupbox2_layout);
QHBoxLayout *color_layout = new QHBoxLayout();
QLabel *text1 = new QLabel(tr("Couleur :"));
color_button = new QPushButton("");
dashed_checkbox = new QCheckBox(tr("Trait en pointill\351s"));
color_layout -> addWidget(text1);
color_layout -> addWidget(color_button);
setColorButton(properties_.color);
dashed_checkbox -> setChecked(properties_.style == Qt::DashLine);
groupbox_layout -> addWidget(simple);
groupbox_layout -> addWidget(multiline);
groupbox_layout -> addLayout(multiline_layout);
groupbox_layout -> addWidget(singleline);
groupbox_layout -> addLayout(singleline_layout1);
groupbox2_layout -> addLayout(color_layout);
groupbox2_layout -> addWidget(dashed_checkbox);
radio_buttons = new QButtonGroup(this);
radio_buttons -> addButton(simple, ConductorProperties::Simple);
radio_buttons -> addButton(multiline, ConductorProperties::Multi);
@@ -138,37 +115,6 @@ void ConductorPropertiesWidget::buildConnections() {
connect(phase_slider, SIGNAL(valueChanged(int)), this, SLOT(updateConfig()));
connect(radio_buttons, SIGNAL(buttonClicked(int)), this, SLOT(updateConfig()));
connect(text_field, SIGNAL(textChanged(const QString &)), this, SLOT(updateConfig()));
connect(dashed_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig()));
connect(color_button, SIGNAL(clicked()), this, SLOT(chooseColor()));
}
/**
Demande a l'utilisateur de choisir une couleur via un dialogue approprie.
*/
void ConductorPropertiesWidget::chooseColor() {
QColor user_chosen_color = QColorDialog::getColor(properties_.color);
if (user_chosen_color.isValid()) {
setColorButton(user_chosen_color);
updateConfig();
}
}
/**
@return la couleur actuelle du bouton permettant de choisir la couleur du
conducteur
*/
QColor ConductorPropertiesWidget::colorButton() const {
return(color_button -> palette().color(QPalette::Button));
}
/**
Change la couleur du bouton permettant de choisir la couleur du conducteur
@param color Nouvelle couleur a afficher
*/
void ConductorPropertiesWidget::setColorButton(const QColor &color) {
QPalette palette;
palette.setColor(QPalette::Button, color);
color_button -> setPalette(palette);
}
/// Enleve les connexions signaux/slots
@@ -181,8 +127,6 @@ void ConductorPropertiesWidget::destroyConnections() {
disconnect(phase_slider, SIGNAL(valueChanged(int)), this, SLOT(updateConfig()));
disconnect(radio_buttons, SIGNAL(buttonClicked(int)), this, SLOT(updateConfig()));
disconnect(text_field, SIGNAL(textChanged(const QString &)), this, SLOT(updateConfig()));
disconnect(color_button, SIGNAL(clicked()), this, SLOT(chooseColor()));
disconnect(dashed_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig()));
}
/// Destructeur
@@ -192,8 +136,6 @@ ConductorPropertiesWidget::~ConductorPropertiesWidget() {
/// Met a jour les proprietes
void ConductorPropertiesWidget::updateConfig() {
properties_.type = static_cast<ConductorProperties::ConductorType>(radio_buttons -> checkedId());
properties_.color = colorButton();
properties_.style = dashed_checkbox -> isChecked() ? Qt::DashLine : Qt::SolidLine;
properties_.text = text_field -> text();
properties_.singleLineProperties.hasGround = ground_checkbox -> isChecked();
properties_.singleLineProperties.hasNeutral = neutral_checkbox -> isChecked();
@@ -207,8 +149,6 @@ void ConductorPropertiesWidget::updateDisplay() {
destroyConnections();
setConductorType(properties_.type);
setColorButton(properties_.color);
dashed_checkbox -> setChecked(properties_.style == Qt::DashLine);
text_field -> setText(properties_.text);
ground_checkbox -> setChecked(properties_.singleLineProperties.hasGround);
neutral_checkbox -> setChecked(properties_.singleLineProperties.hasNeutral);
@@ -268,26 +208,3 @@ void ConductorPropertiesWidget::setConductorProperties(const ConductorProperties
ConductorProperties ConductorPropertiesWidget::conductorProperties() const {
return(properties_);
}
/**
@return true si ce widget est en lecture seule, false sinon
*/
bool ConductorPropertiesWidget::isReadOnly() const {
return(text_field -> isReadOnly());
}
/**
@param ro true pour passer ce widget en lecture seule, false sinon
*/
void ConductorPropertiesWidget::setReadOnly(bool ro) {
simple -> setDisabled(ro);
multiline -> setDisabled(ro);
singleline -> setDisabled(ro);
text_field -> setReadOnly(ro);
phase_checkbox -> setDisabled(ro);
phase_spinbox -> setReadOnly(ro);
ground_checkbox -> setDisabled(ro);
neutral_checkbox -> setDisabled(ro);
color_button -> setDisabled(ro);
dashed_checkbox -> setDisabled(ro);
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -17,8 +17,8 @@
*/
#ifndef CONDUCTOR_PROPERTIES_WIDGET_H
#define CONDUCTOR_PROPERTIES_WIDGET_H
#include "conductorproperties.h"
#include <QWidget>
#include "conductor.h"
#include <QtGui>
/**
Ce widget permet a l utilisateur d'editer les proprietes d'un conducteur.
Par proprietes, on entend non pas le trajet effectue par le conducteur mais
@@ -40,19 +40,14 @@ class ConductorPropertiesWidget : public QWidget {
public:
void setConductorProperties(const ConductorProperties &);
ConductorProperties conductorProperties() const;
bool isReadOnly() const;
void setReadOnly(bool);
private:
void setConductorType(ConductorProperties::ConductorType);
void setColorButton(const QColor &);
QColor colorButton() const;
public slots:
void updatePreview();
void updateConfig();
void updateDisplay();
void chooseColor();
// attributs prives
private:
@@ -67,8 +62,6 @@ class ConductorPropertiesWidget : public QWidget {
QCheckBox *ground_checkbox;
QCheckBox *neutral_checkbox;
QLabel *preview;
QPushButton *color_button;
QCheckBox *dashed_checkbox;
ConductorProperties properties_;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -24,23 +24,20 @@
*/
ConfigDialog::ConfigDialog(QWidget *parent) : QDialog(parent) {
setWindowTitle(tr("Configurer QElectroTech", "window title"));
setWindowTitle(tr("Configurer QElectroTech"));
// liste des pages
pages_list = new QListWidget();
pages_list -> setViewMode(QListView::IconMode);
pages_list -> setIconSize(QSize(110, 110));
pages_list -> setIconSize(QSize(48, 48));
pages_list -> setMovement(QListView::Static);
pages_list -> setMinimumWidth(150);
pages_list -> setMaximumWidth(150);
pages_list -> setMinimumWidth(135);
pages_list -> setMaximumWidth(135);
pages_list -> setSpacing(4);
// pages
pages_widget = new QStackedWidget();
addPage(new GeneralConfigurationPage());
addPage(new NewDiagramPage());
addPage(new ExportConfigPage());
addPage(new PrintConfigPage());
buildPagesList();
// boutons

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify

136
configpages.cpp Normal file
View File

@@ -0,0 +1,136 @@
/*
Copyright 2006-2008 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 "configpages.h"
#include "qetapp.h"
/**
Constructeur
@param parent QWidget parent
*/
NewDiagramPage::NewDiagramPage(QWidget *parent) : ConfigPage(parent) {
// acces a la configuration de QElectroTech
QSettings &settings = QETApp::settings();
// recupere les dimensions du schema
int columns_count_value = settings.value("diagrameditor/defaultcols", 15).toInt();
int columns_width_value = qRound(settings.value("diagrameditor/defaultcolsize", 50.0).toDouble());
int columns_height_value = qRound(settings.value("diagrameditor/defaultheight", 500.0).toDouble());
QVBoxLayout *vlayout1 = new QVBoxLayout();
QLabel *title = new QLabel(tr("Nouveau sch\351ma"));
vlayout1 -> addWidget(title);
QFrame *horiz_line = new QFrame();
horiz_line -> setFrameShape(QFrame::HLine);
vlayout1 -> addWidget(horiz_line);
QHBoxLayout *hlayout1 = new QHBoxLayout();
QVBoxLayout *vlayout2 = new QVBoxLayout();
QGroupBox *diagram_size_box = new QGroupBox(tr("Dimensions du sch\351ma"));
diagram_size_box -> setMinimumWidth(300);
QGridLayout *diagram_size_box_layout = new QGridLayout(diagram_size_box);
QLabel *ds1 = new QLabel(tr("Colonnes :"));
columns_count = new QSpinBox(diagram_size_box);
columns_count -> setMinimum(3); /// @todo methode statique pour recuperer ca
columns_count -> setValue(columns_count_value);
columns_width = new QSpinBox(diagram_size_box);
columns_width -> setMinimum(1);
columns_width -> setSingleStep(10);
columns_width -> setValue(columns_width_value);
columns_width -> setPrefix(tr("\327"));
columns_width -> setSuffix(tr("px"));
QLabel *ds2 = new QLabel(tr("Hauteur :"));
columns_height = new QSpinBox(diagram_size_box);
columns_height -> setRange(80, 10000); /// @todo methode statique pour recuperer ca
columns_height -> setSingleStep(80);
columns_height -> setValue(columns_height_value);
diagram_size_box_layout -> addWidget(ds1, 0, 0);
diagram_size_box_layout -> addWidget(columns_count, 0, 1);
diagram_size_box_layout -> addWidget(columns_width, 0, 2);
diagram_size_box_layout -> addWidget(ds2, 1, 0);
diagram_size_box_layout -> addWidget(columns_height, 1, 1);
ipw = new InsetPropertiesWidget(QETDiagramEditor::defaultInsetProperties(), true, this);
// proprietes par defaut des conducteurs
ConductorProperties cp;
cp.fromSettings(settings, "diagrameditor/defaultconductor");
cpw = new ConductorPropertiesWidget(cp);
vlayout2 -> addWidget(diagram_size_box);
vlayout2 -> addWidget(ipw);
hlayout1 -> addLayout(vlayout2);
hlayout1 -> addWidget(cpw);
vlayout1 -> addLayout(hlayout1);
vlayout1 -> addStretch(1);
hlayout1 -> setAlignment(cpw, Qt::AlignTop);
setLayout(vlayout1);
}
/// Destructeur
NewDiagramPage::~NewDiagramPage() {
}
/**
Applique la configuration de cette page
*/
void NewDiagramPage::applyConf() {
QSettings &settings = QETApp::settings();
// dimensions des nouveaux schemas
settings.setValue("diagrameditor/defaultcols", columns_count -> value());
settings.setValue("diagrameditor/defaultcolsize", columns_width -> value());
settings.setValue("diagrameditor/defaultheight", columns_height -> value());
// proprietes du cartouche
InsetProperties inset = ipw-> insetProperties();
settings.setValue("diagrameditor/defaulttitle", inset.title);
settings.setValue("diagrameditor/defaultauthor", inset.author);
settings.setValue("diagrameditor/defaultfilename", inset.filename);
settings.setValue("diagrameditor/defaultfolio", inset.folio);
QString date_setting_value;
if (inset.useDate == InsetProperties::UseDateValue) {
if (inset.date.isNull()) date_setting_value = "null";
else date_setting_value = inset.date.toString("yyyyMMdd");
} else {
date_setting_value = "now";
}
settings.setValue("diagrameditor/defaultdate", date_setting_value);
// proprietes par defaut des conducteurs
cpw -> conductorProperties().toSettings(settings, "diagrameditor/defaultconductor");
}
/// @return l'icone de cette page
QIcon NewDiagramPage::icon() const {
return(QIcon(":/ico/conf_new_diagram.png"));
}
/// @return le titre de cette page
QString NewDiagramPage::title() const {
return(tr("Nouveau sch\351ma"));
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -18,10 +18,9 @@
#ifndef CONFIG_PAGES_H
#define CONFIG_PAGES_H
#include <QtGui>
class BorderPropertiesWidget;
class ConductorPropertiesWidget;
class InsetPropertiesWidget;
class ExportPropertiesWidget;
#include "conductorpropertieswidget.h"
#include "insetpropertieswidget.h"
/**
Cette classe abstraite contient les methodes que toutes les pages de
configuration doivent implementer.
@@ -64,88 +63,10 @@ class NewDiagramPage : public ConfigPage {
// attributs
public:
BorderPropertiesWidget *bpw; ///< Widget d'edition des dimensions du schema
QSpinBox *columns_count; ///< Widget d'edition du nombre par defaut de colonnes
QSpinBox *columns_width; ///< Widget d'edition de la largeur par defaut des colonnes
QSpinBox *columns_height; ///< Widget d'edition de la hauteur par defaut des colonnes
InsetPropertiesWidget *ipw; ///< Widget d'edition des proprietes par defaut du cartouche
ConductorPropertiesWidget *cpw; ///< Widget d'edition des proprietes par defaut des conducteurs
};
/**
Cette classe represente la page de configuration generale.
*/
class GeneralConfigurationPage : public ConfigPage {
Q_OBJECT
// constructeurs, destructeur
public:
GeneralConfigurationPage(QWidget * = 0);
virtual ~GeneralConfigurationPage();
private:
GeneralConfigurationPage(const GeneralConfigurationPage &);
// methodes
public:
void applyConf();
QString title() const;
QIcon icon() const;
// attributs
public:
QLabel *title_label_;
QFrame *horiz_line_;
QGroupBox *appearance_;
QCheckBox *use_system_colors_;
QGroupBox *projects_view_mode_;
QRadioButton *windowed_mode_;
QRadioButton *tabbed_mode_;
QLabel *warning_view_mode_;
QGroupBox *elements_management_;
QCheckBox *integrate_elements_;
QLabel *default_element_infos_label_;
QTextEdit *default_element_infos_textfield_;
};
/**
Cette classe represente la page de configuration du dialogue d'exportation
*/
class ExportConfigPage : public ConfigPage {
Q_OBJECT
// constructeurs, destructeur
public:
ExportConfigPage(QWidget * = 0);
virtual ~ExportConfigPage();
private:
ExportConfigPage(const ExportConfigPage &);
// methodes
public:
void applyConf();
QString title() const;
QIcon icon() const;
// attributs
public:
ExportPropertiesWidget *epw;
};
/**
Cette classe represente la page de configuration du dialogue d'impression
*/
class PrintConfigPage : public ConfigPage {
Q_OBJECT
// constructeurs, destructeur
public:
PrintConfigPage(QWidget * = 0);
virtual ~PrintConfigPage();
private:
PrintConfigPage(const PrintConfigPage &);
// methodes
public:
void applyConf();
QString title() const;
QIcon icon() const;
// attributs
public:
ExportPropertiesWidget *epw;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,151 +19,119 @@
#include "elementtextitem.h"
#include "diagram.h"
#include "qetapp.h"
#include "partline.h"
#include "elementdefinition.h"
#include <iostream>
/**
Constructeur de la classe CustomElement. Permet d'instancier un element
utilisable comme un element fixe a la difference que l'element perso est
construit a partir d'une description au format XML. Celle-ci est recuperee
a l'emplacement indique.
@param location Emplacement de la definition d'element a utiliser
Constructeur de la classe ElementPerso. Permet d'instancier un element
utilisable comme un element fixe a la difference que l'element perso lit
sa description (noms, dessin, comportement) dans un fichier XML a fournir
en parametre.
@param nom_fichier Le chemin du fichier XML decrivant l'element
@param qgi Le QGraphicsItem parent de cet element
@param s Le Schema affichant cet element
@param state Un pointeur facultatif vers un entier. La valeur de cet entier
@param etat Un pointeur facultatif vers un entier. La valeur de cet entier
sera changee de maniere a refleter le deroulement de l'instanciation :
- 0 : L'instanciation a reussi
- 1 : l'emplacement n'a pas permis d'acceder a une definition d'element
- 2 : la definition n'etait pas lisible
- 3 : la definition n'etait pas valide / exploitable / utilisable
- 4 : Le document XML n'est pas un element "definition"
- 1 : Le fichier n'existe pas
- 2 : Le fichier n'a pu etre ouvert
- 3 : Le fichier n'est pas un document XML
- 4 : Le document XML n'a pas une "definition" comme racine
- 5 : Les attributs de la definition ne sont pas presents et / ou valides
- 6 : La definition est vide
- 7 : L'analyse d'un element XML decrivant une partie du dessin de l'element a echoue
- 8 : Aucune partie du dessin n'a pu etre chargee
*/
CustomElement::CustomElement(const ElementsLocation &location, QGraphicsItem *qgi, Diagram *s, int *state) :
FixedElement(qgi, s),
elmt_state(-1),
location_(location),
forbid_antialiasing(false)
{
// recupere la definition de l'element
ElementsCollectionItem *element_item = QETApp::collectionItem(location);
ElementDefinition *element_definition;
if (
!element_item ||\
!element_item -> isElement() ||\
!(element_definition = qobject_cast<ElementDefinition *>(element_item))
) {
if (state) *state = 1;
elmt_state = 1;
CustomElement::CustomElement(QString &nom_fichier, QGraphicsItem *qgi, Diagram *s, int *etat) : FixedElement(qgi, s) {
nomfichier = nom_fichier;
// pessimisme inside : par defaut, ca foire
elmt_etat = -1;
// le fichier doit exister
QFileInfo infos_file(nomfichier);
if (!infos_file.exists() || !infos_file.isFile()) {
if (etat != NULL) *etat = 1;
elmt_etat = 1;
return;
}
if (!element_definition -> isReadable()) {
if (state) *state = 2;
elmt_state = 2;
// le fichier doit etre lisible
QFile fichier(nomfichier);
if (!fichier.open(QIODevice::ReadOnly)) {
if (etat != NULL) *etat = 2;
elmt_etat = 2;
return;
}
if (element_definition -> isNull()) {
if (state) *state = 3;
elmt_state = 3;
// le fichier doit etre un document XML
QDomDocument document_xml;
if (!document_xml.setContent(&fichier)) {
if (etat != NULL) *etat = 3;
elmt_etat = 3;
return;
}
buildFromXml(element_definition -> xml(), &elmt_state);
if (state) *state = elmt_state;
if (elmt_state) return;
if (state) *state = 0;
elmt_state = 0;
}
CustomElement::CustomElement(const QDomElement &xml_def_elmt, QGraphicsItem *qgi, Diagram *s, int *state) : FixedElement(qgi, s) {
int elmt_state = -1;
buildFromXml(xml_def_elmt, &elmt_state);
if (state) *state = elmt_state;
}
/**
Construit l'element personnalise a partir d'un element XML representant sa
definition.
@param xml_def_elmt
@param state Un pointeur facultatif vers un entier. La valeur de cet entier
sera changee de maniere a refleter le deroulement de l'instanciation :
- 0 : La construction s'est bien passee
- 4 : Le document XML n'est pas un element "definition"
- 5 : Les attributs de la definition ne sont pas presents et / ou valides
- 6 : La definition est vide
- 7 : L'analyse d'un element XML decrivant une partie du dessin de l'element a echoue
- 8 : Aucune partie du dessin n'a pu etre chargee
@return true si le chargement a reussi, false sinon
*/
bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state) {
if (xml_def_elmt.tagName() != "definition" || xml_def_elmt.attribute("type") != "element") {
if (state) *state = 4;
return(false);
// la racine est supposee etre une definition d'element
QDomElement racine = document_xml.documentElement();
if (racine.tagName() != "definition" || racine.attribute("type") != "element") {
if (etat != NULL) *etat = 4;
elmt_etat = 4;
return;
}
// verifie basiquement que la version actuelle est capable de lire ce fichier
if (xml_def_elmt.hasAttribute("version")) {
if (racine.hasAttribute("version")) {
bool conv_ok;
qreal element_version = xml_def_elmt.attribute("version").toDouble(&conv_ok);
qreal element_version = racine.attribute("version").toDouble(&conv_ok);
if (conv_ok && QET::version.toDouble() < element_version) {
std::cerr << qPrintable(
QObject::tr("Avertissement : l'\351l\351ment "
" a \351t\351 enregistr\351 avec une version"
QObject::tr("Avertissement : l'\351l\351ment ") + nom_fichier
+ QObject::tr(" a \351t\351 enregistr\351 avec une version"
" ult\351rieure de QElectroTech.")
) << std::endl;
);
}
}
// ces attributs doivent etre presents et valides
int w, h, hot_x, hot_y;
if (
!QET::attributeIsAnInteger(xml_def_elmt, QString("width"), &w) ||\
!QET::attributeIsAnInteger(xml_def_elmt, QString("height"), &h) ||\
!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_x"), &hot_x) ||\
!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_y"), &hot_y) ||\
!validOrientationAttribute(xml_def_elmt)
!QET::attributeIsAnInteger(racine, QString("width"), &w) ||\
!QET::attributeIsAnInteger(racine, QString("height"), &h) ||\
!QET::attributeIsAnInteger(racine, QString("hotspot_x"), &hot_x) ||\
!QET::attributeIsAnInteger(racine, QString("hotspot_y"), &hot_y) ||\
!validOrientationAttribute(racine)
) {
if (state) *state = 5;
return(false);
if (etat != NULL) *etat = 5;
elmt_etat = 5;
return;
}
// on peut d'ores et deja specifier la taille et le hotspot
setSize(w, h);
setHotspot(QPoint(hot_x, hot_y));
setInternalConnections(xml_def_elmt.attribute("ic") == "true");
setInternalConnections(racine.attribute("ic") == "true");
// la definition est supposee avoir des enfants
if (xml_def_elmt.firstChild().isNull()) {
if (state) *state = 6;
return(false);
if (racine.firstChild().isNull()) {
if (etat != NULL) *etat = 6;
elmt_etat = 6;
return;
}
// initialisation du QPainter (pour dessiner l'element)
QPainter qp;
qp.begin(&drawing);
QPainter low_zoom_qp;
low_zoom_qp.begin(&low_zoom_drawing);
QPen tmp;
tmp.setWidthF(1.0); // ligne vaudou pour prise en compte du setCosmetic - ne pas enlever
tmp.setCosmetic(true);
low_zoom_qp.setPen(tmp);
qp.begin(&dessin);
QPen t;
t.setColor(Qt::black);
t.setWidthF(1.0);
t.setJoinStyle(Qt::BevelJoin);
qp.setPen(t);
// extrait les noms de la definition XML
names.fromXml(xml_def_elmt);
setToolTip(name());
names.fromXml(racine);
setToolTip(nom());
// parcours des enfants de la definition : parties du dessin
int parsed_elements_count = 0;
for (QDomNode node = xml_def_elmt.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
int nb_elements_parses = 0;
for (QDomNode node = racine.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
QDomElement elmts = node.toElement();
if (elmts.isNull()) continue;
if (elmts.tagName() == "description") {
@@ -172,17 +140,11 @@ bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state) {
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
QDomElement qde = n.toElement();
if (qde.isNull()) continue;
if (parseElement(qde, qp)) {
++ parsed_elements_count;
QString current_tag = qde.tagName();
if (current_tag != "terminal" && current_tag != "input") {
forbid_antialiasing = true;
parseElement(qde, low_zoom_qp);
forbid_antialiasing = false;
}
} else {
if (state) *state = 7;
return(false);
if (parseElement(qde, qp)) ++ nb_elements_parses;
else {
if (etat != NULL) *etat = 7;
elmt_etat = 7;
return;
}
}
}
@@ -190,16 +152,19 @@ bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state) {
// fin du dessin
qp.end();
low_zoom_qp.end();
// il doit y avoir au moins un element charge
if (!parsed_elements_count) {
if (state) *state = 8;
return(false);
} else {
if (state) *state = 0;
return(true);
if (!nb_elements_parses) {
if (etat != NULL) *etat = 8;
elmt_etat = 8;
return;
}
// fermeture du fichier
fichier.close();
if (etat != NULL) *etat = 0;
elmt_etat = 0;
}
/**
@@ -220,15 +185,10 @@ QList<Conductor *> CustomElement::conductors() const {
return(conductors);
}
/// @return la liste des textes de cet element
QList<ElementTextItem *> CustomElement::texts() const {
return(list_texts_);
}
/**
@return Le nombre de bornes que l'element possede
*/
int CustomElement::terminalsCount() const {
int CustomElement::nbTerminals() const {
return(list_terminals.size());
}
@@ -237,12 +197,8 @@ int CustomElement::terminalsCount() const {
@param qp Le QPainter a utiliser pour dessiner l'element
@param options Les options graphiques
*/
void CustomElement::paint(QPainter *qp, const QStyleOptionGraphicsItem *options) {
if (options && options -> levelOfDetail < 1.0) {
low_zoom_drawing.play(qp);
} else {
drawing.play(qp);
}
void CustomElement::paint(QPainter *qp, const QStyleOptionGraphicsItem *) {
dessin.play(qp);
}
/**
@@ -255,12 +211,12 @@ void CustomElement::paint(QPainter *qp, const QStyleOptionGraphicsItem *options)
formes peuvent avoir un attribut style. @see setPainterStyle
@param e L'element XML a analyser
@param qp Le QPainter a utiliser pour dessiner l'element perso
@param s Le schema sur lequel sera affiche l'element perso
@return true si l'analyse reussit, false sinon
*/
bool CustomElement::parseElement(QDomElement &e, QPainter &qp) {
if (e.tagName() == "terminal") return(parseTerminal(e));
else if (e.tagName() == "line") return(parseLine(e, qp));
else if (e.tagName() == "rect") return(parseRect(e, qp));
else if (e.tagName() == "ellipse") return(parseEllipse(e, qp));
else if (e.tagName() == "circle") return(parseCircle(e, qp));
else if (e.tagName() == "arc") return(parseArc(e, qp));
@@ -283,129 +239,14 @@ bool CustomElement::parseElement(QDomElement &e, QPainter &qp) {
*/
bool CustomElement::parseLine(QDomElement &e, QPainter &qp) {
// verifie la presence et la validite des attributs obligatoires
qreal x1, y1, x2, y2;
double x1, y1, x2, y2;
if (!QET::attributeIsAReal(e, QString("x1"), &x1)) return(false);
if (!QET::attributeIsAReal(e, QString("y1"), &y1)) return(false);
if (!QET::attributeIsAReal(e, QString("x2"), &x2)) return(false);
if (!QET::attributeIsAReal(e, QString("y2"), &y2)) return(false);
QET::EndType first_end = QET::endTypeFromString(e.attribute("end1"));
QET::EndType second_end = QET::endTypeFromString(e.attribute("end2"));
qreal length1, length2;
if (!QET::attributeIsAReal(e, QString("length1"), &length1)) length1 = 1.5;
if (!QET::attributeIsAReal(e, QString("length2"), &length2)) length2 = 1.5;
qp.save();
setPainterStyle(e, qp);
QPen t = qp.pen();
t.setJoinStyle(Qt::MiterJoin);
qp.setPen(t);
QLineF line(x1, y1, x2, y2);
QPointF point1(line.p1());
QPointF point2(line.p2());
qreal line_length(line.length());
qreal pen_width = qp.pen().widthF();
// determine s'il faut dessiner les extremites
bool draw_1st_end, draw_2nd_end;
qreal reduced_line_length = line_length - (length1 * PartLine::requiredLengthForEndType(first_end));
draw_1st_end = first_end && reduced_line_length >= 0;
if (draw_1st_end) {
reduced_line_length -= (length2 * PartLine::requiredLengthForEndType(second_end));
} else {
reduced_line_length = line_length - (length2 * PartLine::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(PartLine::fourEndPoints(point1, point2, length1));
if (first_end == QET::Circle) {
qp.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) {
qp.drawPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3]);
start_point = four_points1[1];
} else if (first_end == QET::Simple) {
qp.drawPolyline(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
start_point = point1;
} else if (first_end == QET::Triangle) {
qp.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(PartLine::fourEndPoints(point2, point1, length2));
if (second_end == QET::Circle) {
qp.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) {
qp.drawPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1]);
stop_point = four_points2[1];
} else if (second_end == QET::Simple) {
qp.drawPolyline(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
stop_point = point2;
} else if (second_end == QET::Triangle) {
qp.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;
}
qp.drawLine(start_point, stop_point);
qp.restore();
return(true);
}
/**
Analyse un element XML suppose representer un rectangle. Si l'analyse
reussit, le rectangle est ajoute au dessin.
Le rectangle est defini par les attributs suivants :
- 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 e L'element XML a analyser
@param qp Le QPainter a utiliser pour dessiner l'element perso
@return true si l'analyse reussit, false sinon
*/
bool CustomElement::parseRect(QDomElement &e, QPainter &qp) {
// verifie la presence des attributs obligatoires
qreal rect_x, rect_y, rect_w, rect_h;
if (!QET::attributeIsAReal(e, QString("x"), &rect_x)) return(false);
if (!QET::attributeIsAReal(e, QString("y"), &rect_y)) return(false);
if (!QET::attributeIsAReal(e, QString("width"), &rect_w)) return(false);
if (!QET::attributeIsAReal(e, QString("height"), &rect_h)) return(false);
qp.save();
setPainterStyle(e, qp);
// force le type de jointures pour les rectangles
QPen p = qp.pen();
p.setJoinStyle(Qt::MiterJoin);
qp.setPen(p);
qp.drawRect(QRectF(rect_x, rect_y, rect_w, rect_h));
qp.drawLine(QLineF(x1, y1, x2, y2));
qp.restore();
return(true);
}
@@ -421,10 +262,11 @@ bool CustomElement::parseRect(QDomElement &e, QPainter &qp) {
@param e L'element XML a analyser
@param qp Le QPainter a utiliser pour dessiner l'element perso
@return true si l'analyse reussit, false sinon
@todo utiliser des attributs plus coherents : x et y = centre, rayon = vrai rayon
*/
bool CustomElement::parseCircle(QDomElement &e, QPainter &qp) {
// verifie la presence des attributs obligatoires
qreal cercle_x, cercle_y, cercle_r;
double cercle_x, cercle_y, cercle_r;
if (!QET::attributeIsAReal(e, QString("x"), &cercle_x)) return(false);
if (!QET::attributeIsAReal(e, QString("y"), &cercle_y)) return(false);
if (!QET::attributeIsAReal(e, QString("diameter"), &cercle_r)) return(false);
@@ -447,10 +289,11 @@ bool CustomElement::parseCircle(QDomElement &e, QPainter &qp) {
@param e L'element XML a analyser
@param qp Le QPainter a utiliser pour dessiner l'element perso
@return true si l'analyse reussit, false sinon
@todo utiliser des attributs plus coherents : x et y = centre
*/
bool CustomElement::parseEllipse(QDomElement &e, QPainter &qp) {
// verifie la presence des attributs obligatoires
qreal ellipse_x, ellipse_y, ellipse_l, ellipse_h;
double ellipse_x, ellipse_y, ellipse_l, ellipse_h;
if (!QET::attributeIsAReal(e, QString("x"), &ellipse_x)) return(false);
if (!QET::attributeIsAReal(e, QString("y"), &ellipse_y)) return(false);
if (!QET::attributeIsAReal(e, QString("width"), &ellipse_l)) return(false);
@@ -478,7 +321,7 @@ bool CustomElement::parseEllipse(QDomElement &e, QPainter &qp) {
*/
bool CustomElement::parseArc(QDomElement &e, QPainter &qp) {
// verifie la presence des attributs obligatoires
qreal arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
double arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
if (!QET::attributeIsAReal(e, QString("x"), &arc_x)) return(false);
if (!QET::attributeIsAReal(e, QString("y"), &arc_y)) return(false);
if (!QET::attributeIsAReal(e, QString("width"), &arc_l)) return(false);
@@ -547,7 +390,7 @@ bool CustomElement::parseText(QDomElement &e, QPainter &qp) {
qp.save();
setPainterStyle(e, qp);
qp.setFont(QETApp::diagramTextsFont(size));
qp.setFont(QFont(QString(QETApp::diagramTextsFont()), size));
qp.drawText(QPointF(pos_x, pos_y), e.attribute("text"));
qp.restore();
return(true);
@@ -562,26 +405,24 @@ bool CustomElement::parseText(QDomElement &e, QPainter &qp) {
- une taille
- le fait de subir les rotations de l'element ou non
@param e L'element XML a analyser
@return Un pointeur vers l'objet ElementTextItem ainsi cree si l'analyse reussit, 0 sinon
@param s Le schema sur lequel l'element perso sera affiche
@return true si l'analyse reussit, false sinon
*/
ElementTextItem *CustomElement::parseInput(QDomElement &e) {
bool CustomElement::parseInput(QDomElement &e) {
qreal pos_x, pos_y;
int size;
if (
!QET::attributeIsAReal(e, "x", &pos_x) ||\
!QET::attributeIsAReal(e, "y", &pos_y) ||\
!QET::attributeIsAnInteger(e, "size", &size)
) return(0);
) return(false);
ElementTextItem *eti = new ElementTextItem(e.attribute("text"), this);
eti -> setFont(QETApp::diagramTextsFont(size));
eti -> setFont(QFont(QETApp::diagramTextsFont(), size));
eti -> setPos(pos_x, pos_y);
eti -> setOriginalPos(QPointF(pos_x, pos_y));
if (e.attribute("rotate") == "true") eti -> setFollowParentRotations(true);
list_texts_ << eti;
return(eti);
return(true);
}
/**
@@ -592,24 +433,23 @@ ElementTextItem *CustomElement::parseInput(QDomElement &e) {
- orientation : orientation de la borne = Nord (n), Sud (s), Est (e) ou Ouest (w)
@param e L'element XML a analyser
@return Un pointeur vers l'objet Terminal ainsi cree, 0 sinon
@param s Le schema sur lequel l'element perso sera affiche
@return true si l'analyse reussit, false sinon
*/
Terminal *CustomElement::parseTerminal(QDomElement &e) {
bool CustomElement::parseTerminal(QDomElement &e) {
// verifie la presence et la validite des attributs obligatoires
qreal terminalx, terminaly;
double terminalx, terminaly;
QET::Orientation terminalo;
if (!QET::attributeIsAReal(e, QString("x"), &terminalx)) return(0);
if (!QET::attributeIsAReal(e, QString("y"), &terminaly)) return(0);
if (!e.hasAttribute("orientation")) return(0);
if (!QET::attributeIsAReal(e, QString("x"), &terminalx)) return(false);
if (!QET::attributeIsAReal(e, QString("y"), &terminaly)) return(false);
if (!e.hasAttribute("orientation")) return(false);
if (e.attribute("orientation") == "n") terminalo = QET::North;
else if (e.attribute("orientation") == "s") terminalo = QET::South;
else if (e.attribute("orientation") == "e") terminalo = QET::East;
else if (e.attribute("orientation") == "w") terminalo = QET::West;
else return(0);
Terminal *new_terminal = new Terminal(terminalx, terminaly, terminalo, this, qobject_cast<Diagram *>(scene()));
new_terminal -> setZValue(420); // valeur arbitraire pour maintenir les bornes au-dessus des champs de texte
list_terminals << new_terminal;
return(new_terminal);
else return(false);
list_terminals << new Terminal(terminalx, terminaly, terminalo, this, qobject_cast<Diagram *>(scene()));
return(true);
}
/**
@@ -618,7 +458,6 @@ Terminal *CustomElement::parseTerminal(QDomElement &e) {
@param aa Booleen a true pour activer l'antialiasing, a false pour le desactiver
*/
void CustomElement::setQPainterAntiAliasing(QPainter &qp, bool aa) {
if (forbid_antialiasing) aa = false;
qp.setRenderHint(QPainter::Antialiasing, aa);
qp.setRenderHint(QPainter::TextAntialiasing, aa);
qp.setRenderHint(QPainter::SmoothPixmapTransform, aa);
@@ -643,7 +482,7 @@ void CustomElement::setQPainterAntiAliasing(QPainter &qp, bool aa) {
@param e Element XML
@return true si l'attribut "orientation" est valide, false sinon
*/
bool CustomElement::validOrientationAttribute(const QDomElement &e) {
bool CustomElement::validOrientationAttribute(QDomElement &e) {
return(ori.fromString(e.attribute("orientation")));
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -15,14 +15,13 @@
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CUSTOM_ELEMENT_H
#define CUSTOM_ELEMENT_H
#ifndef ELEMENTPERSO_H
#define ELEMENTPERSO_H
#include "fixedelement.h"
#include <QtGui>
#include "nameslist.h"
#include "elementslocation.h"
class ElementTextItem;
class Terminal;
class CustomElementPart;
/**
Cette classe represente un element electrique. Elle est utilisable
comme un element fixe. La difference est que l'element perso lit
@@ -30,73 +29,65 @@ class Terminal;
en parametre.
*/
class CustomElement : public FixedElement {
Q_OBJECT
// constructeurs, destructeur
public:
CustomElement(const ElementsLocation &, QGraphicsItem * = 0, Diagram * = 0, int * = 0);
CustomElement(const QDomElement &, QGraphicsItem * = 0, Diagram * = 0, int * = 0);
CustomElement(QString &, QGraphicsItem * = 0, Diagram * = 0, int * = NULL);
virtual ~CustomElement();
friend class CustomElementPart;
private:
CustomElement(const CustomElement &);
// attributs
protected:
int elmt_state; // contient le code d'erreur si l'instanciation a echoue ou 0 si l'instanciation s'est bien passe
private:
int elmt_etat; // contient le code d'erreur si l'instanciation a echoue ou 0 si l'instanciation s'est bien passe
NamesList names;
ElementsLocation location_;
QPicture drawing;
QPicture low_zoom_drawing;
QString nomfichier;
QPicture dessin;
QList<Terminal *> list_terminals;
QList<ElementTextItem *> list_texts_;
bool forbid_antialiasing;
// methodes
public:
virtual QList<Terminal *> terminals() const;
virtual QList<Conductor *> conductors() const;
virtual QList<ElementTextItem *> texts() const;
virtual int terminalsCount() const;
virtual int nbTerminals() const;
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *);
QString typeId() const;
ElementsLocation location() const;
QString fichier() const;
bool isNull() const;
int state() const;
QString name() const;
int etat() const;
QString nom() const;
protected:
virtual bool buildFromXml(const QDomElement &, int * = 0);
virtual bool parseElement(QDomElement &, QPainter &);
virtual bool parseLine(QDomElement &, QPainter &);
virtual bool parseRect(QDomElement &, QPainter &);
virtual bool parseEllipse(QDomElement &, QPainter &);
virtual bool parseCircle(QDomElement &, QPainter &);
virtual bool parseArc(QDomElement &, QPainter &);
virtual bool parsePolygon(QDomElement &, QPainter &);
virtual bool parseText(QDomElement &, QPainter &);
virtual ElementTextItem *parseInput(QDomElement &);
virtual Terminal *parseTerminal(QDomElement &);
virtual void setQPainterAntiAliasing(QPainter &, bool);
virtual bool validOrientationAttribute(const QDomElement &);
virtual void setPainterStyle(QDomElement &, QPainter &);
private:
bool parseElement(QDomElement &, QPainter &);
bool parseLine(QDomElement &, QPainter &);
bool parseEllipse(QDomElement &, QPainter &);
bool parseCircle(QDomElement &, QPainter &);
bool parseArc(QDomElement &, QPainter &);
bool parsePolygon(QDomElement &, QPainter &);
bool parseText(QDomElement &, QPainter &);
bool parseInput(QDomElement &);
bool parseTerminal(QDomElement &);
void setQPainterAntiAliasing(QPainter &, bool);
bool validOrientationAttribute(QDomElement &);
void setPainterStyle(QDomElement &, QPainter &);
};
/**
@return L'ID du type de l'element ; pour un CustomElement, cela revient au
nom du fichier
@see location()
@see fichier()
*/
inline QString CustomElement::typeId() const {
return(location_.path());
return(nomfichier);
}
/**
@return L'adresse du fichier contenant la description XML de cet element
*/
inline ElementsLocation CustomElement::location() const {
return(location_);
inline QString CustomElement::fichier() const {
return(nomfichier);
}
/**
@@ -104,7 +95,7 @@ inline ElementsLocation CustomElement::location() const {
description XML a echoue
*/
inline bool CustomElement::isNull() const {
return(elmt_state);
return(elmt_etat != 0);
}
/**
@@ -119,15 +110,15 @@ inline bool CustomElement::isNull() const {
- 7 : L'analyse d'un element XML decrivant une partie du dessin de l'element a echoue
- 8 : Aucune partie du dessin n'a pu etre chargee
*/
inline int CustomElement::state() const {
return(elmt_state);
inline int CustomElement::etat() const {
return(elmt_etat);
}
/**
@return Le nom de l'element
*/
inline QString CustomElement::name() const {
return(names.name(location_.baseName()));
inline QString CustomElement::nom() const {
return(names.name(QFileInfo(nomfichier).baseName()));
}
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -20,12 +20,9 @@
#include "conductor.h"
#include "customelement.h"
#include "diagram.h"
#include "elementtextitem.h"
#include "exportdialog.h"
#include "ghostelement.h"
#include "diagramcommands.h"
#include "diagramcontent.h"
#include "diagramposition.h"
const int Diagram::xGrid = 10;
const int Diagram::yGrid = 10;
@@ -40,13 +37,9 @@ Diagram::Diagram(QObject *parent) :
draw_grid(true),
use_border(true),
moved_elements_fetched(false),
draw_terminals(true),
draw_colored_conductors_(true),
project_(0),
read_only_(false)
qgi_manager(this),
draw_terminals(true)
{
undo_stack = new QUndoStack();
qgi_manager = new QGIManager(this);
setBackgroundBrush(Qt::white);
conductor_setter = new QGraphicsLineItem(0, 0);
conductor_setter -> setZValue(1000000);
@@ -56,29 +49,18 @@ Diagram::Diagram(QObject *parent) :
t.setStyle(Qt::DashLine);
conductor_setter -> setPen(t);
conductor_setter -> setLine(QLineF(QPointF(0.0, 0.0), QPointF(0.0, 0.0)));
connect(this, SIGNAL(selectionChanged()), this, SLOT(slot_checkSelectionEmptinessChange()));
// lit les caracteristiques des conducteurs par defaut dans la configuration
defaultConductorProperties.fromSettings(QETApp::settings(), "diagrameditor/defaultconductor");
}
/**
Destructeur
*/
Diagram::~Diagram() {
// suppression de la liste des annulations - l'undo stack fait appel au qgimanager pour supprimer certains elements
delete undo_stack;
// suppression du QGIManager - tous les elements qu'il connait sont supprimes
delete qgi_manager;
// recense les items supprimables
QList<QGraphicsItem *> deletable_items;
foreach(QGraphicsItem *qgi, items()) {
if (qgi -> parentItem()) continue;
if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
deletable_items << qgi;
}
// suppression des items supprimables
foreach(QGraphicsItem *qgi_d, deletable_items) {
delete qgi_d;
}
if (conductor_setter -> scene()) removeItem(conductor_setter);
delete conductor_setter;
}
/**
@@ -111,13 +93,11 @@ void Diagram::drawBackground(QPainter *p, const QRectF &r) {
int g_y = (int)ceil(r.y());
while (g_y % yGrid) ++ g_y;
QPolygon points;
for (int gx = g_x ; gx < limite_x ; gx += xGrid) {
for (int gy = g_y ; gy < limite_y ; gy += yGrid) {
points << QPoint(gx, gy);
p -> drawPoint(gx, gy);
}
}
p -> drawPoints(points);
}
if (use_border) border_and_inset.draw(p, margin, margin);
@@ -129,7 +109,6 @@ void Diagram::drawBackground(QPainter *p, const QRectF &r) {
@param e QKeyEvent decrivant l'evenement clavier
*/
void Diagram::keyPressEvent(QKeyEvent *e) {
if (!isReadOnly()) {
QPointF movement;
switch(e -> key()) {
case Qt::Key_Left: movement = QPointF(-xGrid, 0.0); break;
@@ -140,7 +119,6 @@ void Diagram::keyPressEvent(QKeyEvent *e) {
if (!movement.isNull() && !focusItem()) {
moveElements(movement);
}
}
QGraphicsScene::keyPressEvent(e);
}
@@ -149,7 +127,6 @@ void Diagram::keyPressEvent(QKeyEvent *e) {
@param e QKeyEvent decrivant l'evenement clavier
*/
void Diagram::keyReleaseEvent(QKeyEvent *e) {
if (!isReadOnly()) {
// detecte le relachement d'une touche de direction ( = deplacement d'elements)
if (
(e -> key() == Qt::Key_Left || e -> key() == Qt::Key_Right ||\
@@ -161,7 +138,6 @@ void Diagram::keyReleaseEvent(QKeyEvent *e) {
invalidateMovedElements();
current_movement = QPointF();
}
}
QGraphicsScene::keyReleaseEvent(e);
}
@@ -235,14 +211,6 @@ QSize Diagram::imageSize() const {
return(QSizeF(image_width, image_height).toSize());
}
/**
@return true si le schema est considere comme vide, false sinon.
Un schema vide ne contient ni element, ni conducteur, ni champ de texte
*/
bool Diagram::isEmpty() const {
return(!items().count());
}
/**
Exporte tout ou partie du schema
@param diagram Booleen (a vrai par defaut) indiquant si le XML genere doit
@@ -263,18 +231,13 @@ QDomDocument Diagram::toXml(bool diagram) {
if (!border_and_inset.title().isNull()) racine.setAttribute("title", border_and_inset.title());
if (!border_and_inset.fileName().isNull()) racine.setAttribute("filename", border_and_inset.fileName());
if (!border_and_inset.folio().isNull()) racine.setAttribute("folio", border_and_inset.folio());
racine.setAttribute("cols", border_and_inset.nbColumns());
racine.setAttribute("colsize", QString("%1").arg(border_and_inset.columnsWidth()));
racine.setAttribute("rows", border_and_inset.nbRows());
racine.setAttribute("rowsize", QString("%1").arg(border_and_inset.rowsHeight()));
// attribut datant de la version 0.1 - laisse pour retrocompatibilite
racine.setAttribute("height", QString("%1").arg(border_and_inset.diagramHeight()));
racine.setAttribute("displaycols", border_and_inset.columnsAreDisplayed() ? "true" : "false");
racine.setAttribute("displayrows", border_and_inset.rowsAreDisplayed() ? "true" : "false");
racine.setAttribute("cols", border_and_inset.nbColumn());
racine.setAttribute("colsize", border_and_inset.columnsWidth());
racine.setAttribute("height", border_and_inset.columnsHeight());
// type de conducteur par defaut
QDomElement default_conductor = document.createElement("defaultconductor");
defaultConductorProperties.toXml(default_conductor);
defaultConductorProperties.toXml(document, default_conductor);
racine.appendChild(default_conductor);
}
document.appendChild(racine);
@@ -287,7 +250,7 @@ QDomDocument Diagram::toXml(bool diagram) {
QList<Conductor *> list_conductors;
QList<DiagramTextItem *> list_texts;
// Determine les elements a "XMLiser"
// Determine les elements a « XMLiser »
foreach(QGraphicsItem *qgi, items()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(qgi)) {
if (diagram) list_elements << elmt;
@@ -340,66 +303,20 @@ QDomDocument Diagram::toXml(bool diagram) {
}
/**
Importe le schema decrit dans un document XML. Si une position est
Importe le diagram 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 document Le document XML a analyser
@param position La position du schema importe
@param position La position du diagram importe
@param consider_informations Si vrai, les informations complementaires
(auteur, titre, ...) seront prises en compte
@param content_ptr si ce pointeur vers un DiagramContent est different de 0,
il sera rempli avec le contenu ajoute au schema par le fromXml
@param content_ptr si ce pointeur vers un DiagramContentn'est pas NULL, il
sera rempli avec le contenu ajoute au schema par le fromXml
@return true si l'import a reussi, false sinon
*/
bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_informations, DiagramContent *content_ptr) {
QDomElement root = document.documentElement();
return(fromXml(root, position, consider_informations, content_ptr));
}
/**
Importe le schema decrit dans un element XML. Cette methode delegue son travail a Diagram::fromXml
Si l'import reussit, cette methode initialise egalement le document XML
interne permettant de bien gerer l'enregistrement de ce schema dans le
projet auquel il appartient.
@see Diagram::fromXml
@param document Le document XML a analyser
@param position La position du schema importe
@param consider_informations Si vrai, les informations complementaires
(auteur, titre, ...) seront prises en compte
@param content_ptr si ce pointeur vers un DiagramContent est different de 0,
il sera rempli avec le contenu ajoute au schema par le fromXml
@return true si l'import a reussi, false sinon
*/
bool Diagram::initFromXml(QDomElement &document, QPointF position, bool consider_informations, DiagramContent *content_ptr) {
// import le contenu et les proprietes du schema depuis l'element XML fourni en parametre
bool from_xml = fromXml(document, position, consider_informations, content_ptr);
// initialise le document XML interne a partir de l'element XML fourni en parametre
if (from_xml) {
xml_document.clear();
xml_document.appendChild(xml_document.importNode(document, true));
// a ce stade, le document XML interne contient le code XML qui a ete importe, et non pas une version re-exporte par la methode toXml()
}
return(from_xml);
}
/**
Importe le schema decrit dans un element 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 document Le document XML a analyser
@param position La position du schema importe
@param consider_informations Si vrai, les informations complementaires
(auteur, titre, ...) seront prises en compte
@param content_ptr si ce pointeur vers un DiagramContent est different de 0,
il sera rempli avec le contenu ajoute au schema par le fromXml
@return true si l'import a reussi, false sinon
*/
bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_informations, DiagramContent *content_ptr) {
QDomElement root = document;
// le premier element doit etre un schema
if (root.tagName() != "diagram") return(false);
@@ -420,24 +337,9 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
double col_size = root.attribute("colsize").toDouble(&ok);
if (ok) border_and_inset.setColumnsWidth(col_size);
// retrocompatibilite : les schemas enregistres avec la 0.1 ont un attribut "height"
if (root.hasAttribute("rows") && root.hasAttribute("rowsize")) {
// nombre de lignes
int nb_rows = root.attribute("rows").toInt(&ok);
if (ok) border_and_inset.setNbRows(nb_rows);
// taille des lignes
double row_size = root.attribute("rowsize").toDouble(&ok);
if (ok) border_and_inset.setRowsHeight(row_size);
} else {
// hauteur du schema
double height = root.attribute("height").toDouble(&ok);
if (ok) border_and_inset.setDiagramHeight(height);
}
// affichage des lignes et colonnes
border_and_inset.displayColumns(root.attribute("displaycols") != "false");
border_and_inset.displayRows(root.attribute("displayrows") != "false");
if (ok) border_and_inset.setColumnsHeight(height);
border_and_inset.adjustInsetToColumns();
@@ -452,10 +354,7 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
}
// si la racine n'a pas d'enfant : le chargement est fini (schema vide)
if (root.firstChild().isNull()) {
write(document);
return(true);
}
if (root.firstChild().isNull()) return(true);
// chargement de tous les elements du fichier XML
QList<Element *> added_elements;
@@ -465,27 +364,23 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
// cree un element dont le type correspond a l'id type
QString type_id = e.attribute("type");
ElementsLocation element_location = ElementsLocation(type_id);
if (type_id.startsWith("embed://")) element_location.setProject(project_);
CustomElement *nvel_elmt = new CustomElement(element_location);
QString chemin_fichier = QETApp::realPath(type_id);
CustomElement *nvel_elmt = new CustomElement(chemin_fichier);
if (nvel_elmt -> isNull()) {
QString debug_message = QString("Diagram::fromXml() : Le chargement de la description de l'element %1 a echoue avec le code d'erreur %2").arg(element_location.path()).arg(nvel_elmt -> state());
qDebug() << qPrintable(debug_message);
QString debug_message = QString("Le chargement de la description de l'element %1 a echoue avec le code d'erreur %2").arg(chemin_fichier).arg(nvel_elmt -> etat());
delete nvel_elmt;
qDebug() << "Diagram::fromXml() : Utilisation d'un GhostElement en lieu et place de cet element.";
nvel_elmt = new GhostElement(element_location);
qDebug(debug_message.toLatin1().data());
continue;
}
// charge les caracteristiques de l'element
if (nvel_elmt -> fromXml(e, table_adr_id)) {
// ajout de l'element au schema et a la liste des elements ajoutes
addElement(nvel_elmt);
addItem(nvel_elmt);
added_elements << nvel_elmt;
} else {
delete nvel_elmt;
qDebug() << "Diagram::fromXml() : Le chargement des parametres d'un element a echoue";
qDebug("Le chargement des parametres d'un element a echoue");
}
}
@@ -494,7 +389,6 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
foreach (QDomElement f, QET::findInDomElement(root, "inputs", "input")) {
DiagramTextItem *dti = new DiagramTextItem(0, this);
dti -> fromXml(f);
addDiagramTextItem(dti);
added_texts << dti;
}
@@ -554,11 +448,11 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
added_conductors << c;
}
}
} else qDebug() << "Diagram::fromXml() : Le chargement du conducteur" << id_p1 << id_p2 << "a echoue";
} else qDebug() << "Le chargement du conductor" << id_p1 << id_p2 << "a echoue";
}
// remplissage des listes facultatives
if (content_ptr) {
if (content_ptr != NULL) {
content_ptr -> elements = added_elements;
content_ptr -> conductorsToMove = added_conductors;
content_ptr -> textFields = added_texts;
@@ -568,203 +462,17 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
}
/**
Enregistre le schema XML dans son document XML interne et emet le signal
written().
Verifie si la selection est passe d'un etat ou elle est vide a un etat ou
elle ne l'est pas, et inversement. Si c'est le cas, le signal
EmptinessChanged() est emis.
*/
void Diagram::write() {
qDebug() << qPrintable(QString("Diagram::write() : saving changes from diagram \"%1\" [%2]").arg(title()).arg(QET::pointerString(this)));
write(toXml().documentElement());
undoStack().setClean();
}
/**
Enregistre un element XML dans son document XML interne et emet le signal
written().
@param element xml a enregistrer
*/
void Diagram::write(const QDomElement &element) {
xml_document.clear();
xml_document.appendChild(xml_document.importNode(element, true));
emit(written());
}
/**
@return true si la fonction write a deja ete appele (pour etre plus exact :
si le document XML utilise en interne n'est pas vide), false sinon
*/
bool Diagram::wasWritten() const {
return(!xml_document.isNull());
}
/**
@return le schema en XML tel qu'il doit etre enregistre dans le fichier projet
@param xml_doc document XML a utiliser pour creer l'element
*/
QDomElement Diagram::writeXml(QDomDocument &xml_doc) const {
// si le schema n'a pas ete enregistre explicitement, on n'ecrit rien
if (!wasWritten()) return(QDomElement());
QDomElement diagram_elmt = xml_document.documentElement();
QDomNode new_node = xml_doc.importNode(diagram_elmt, true);
return(new_node.toElement());
}
/**
Ajoute un element sur le schema
@param element Element a ajouter
*/
void Diagram::addElement(Element *element) {
if (!element || isReadOnly()) return;
// ajoute l'element au schema
if (element -> scene() != this) {
addItem(element);
void Diagram::slot_checkSelectionEmptinessChange() {
static bool selection_was_empty = true;
bool selection_is_empty = selectedItems().isEmpty();
if (selection_was_empty != selection_is_empty) {
emit(selectionEmptinessChanged());
selection_was_empty = selection_is_empty;
}
// surveille les modifications de ses champs de texte
foreach(ElementTextItem *eti, element -> texts()) {
connect(
eti,
SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
this,
SLOT(diagramTextChanged(DiagramTextItem *, const QString &, const QString &))
);
}
}
/**
Ajoute un conducteur sur le schema
@param conductor Conducteur a ajouter
*/
void Diagram::addConductor(Conductor *conductor) {
if (!conductor || isReadOnly()) return;
// ajoute le conducteur au schema
if (conductor -> scene() != this) {
addItem(conductor);
conductor -> terminal1 -> addConductor(conductor);
conductor -> terminal2 -> addConductor(conductor);
}
}
/**
Aoute un champ de texte independant sur le schema
@param dti Champ de texte a ajouter
*/
void Diagram::addDiagramTextItem(DiagramTextItem *dti) {
if (!dti || isReadOnly()) return;
// ajoute le champ de texte au schema
if (dti -> scene() != this) {
addItem(dti);
}
// surveille les modifications apportees au champ de texte
connect(
dti,
SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
this,
SLOT(diagramTextChanged(DiagramTextItem *, const QString &, const QString &))
);
}
/**
Enleve un element du schema
@param element Element a enlever
*/
void Diagram::removeElement(Element *element) {
if (!element || isReadOnly()) return;
// enleve l'element au schema
removeItem(element);
// arrete la surveillance des modifications de ses champs de texte
foreach(ElementTextItem *eti, element -> texts()) {
disconnect(
eti,
SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
this,
SLOT(diagramTextChanged(DiagramTextItem *, const QString &, const QString &))
);
}
}
/**
Enleve un conducteur du schema
@param conductor Conducteur a enlever
*/
void Diagram::removeConductor(Conductor *conductor) {
if (!conductor || isReadOnly()) return;
// detache le conducteur sans le detruire
conductor -> terminal1 -> removeConductor(conductor);
conductor -> terminal2 -> removeConductor(conductor);
// enleve le conducteur du schema
removeItem(conductor);
}
/**
Enleve un champ de texte independant du schema
@param dti Champ de texte a enlever
*/
void Diagram::removeDiagramTextItem(DiagramTextItem *dti) {
if (!dti || isReadOnly()) return;
// enleve le champ de texte au schema
removeItem(dti);
// arrete la surveillance des modifications apportees au champ de texte
disconnect(
dti,
SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
this,
SLOT(diagramTextChanged(DiagramTextItem *, const QString &, const QString &))
);
}
/**
Gere le fait qu'un texte du schema ait ete modifie
@param text_item Texte modifie
@param old_text Ancien texte
@param new_text Nouveau texte
*/
void Diagram::diagramTextChanged(DiagramTextItem *text_item, const QString &old_text, const QString &new_text) {
if (!text_item) return;
undo_stack -> push(new ChangeDiagramTextCommand(text_item, old_text, new_text));
}
/**
Selectionne tous les objets du schema
*/
void Diagram::selectAll() {
if (items().isEmpty()) return;
blockSignals(true);
foreach(QGraphicsItem *qgi, items()) qgi -> setSelected(true);
blockSignals(false);
emit(selectionChanged());
}
/**
Deslectionne tous les objets selectionnes
*/
void Diagram::deselectAll() {
if (items().isEmpty()) return;
clearSelection();
}
/**
Inverse l'etat de selection de tous les objets du schema
*/
void Diagram::invertSelection() {
if (items().isEmpty()) return;
blockSignals(true);
foreach (QGraphicsItem *item, items()) item -> setSelected(!item -> isSelected());
blockSignals(false);
emit(selectionChanged());
}
/**
@@ -781,29 +489,7 @@ QRectF Diagram::border() const {
);
}
/**
@return le titre du cartouche
*/
QString Diagram::title() const {
return(border_and_inset.title());
}
/**
@return la liste des elements de ce schema
*/
QList<CustomElement *> Diagram::customElements() const {
QList<CustomElement *> elements_list;
foreach(QGraphicsItem *qgi, items()) {
if (CustomElement *elmt = qgraphicsitem_cast<CustomElement *>(qgi)) {
elements_list << elmt;
}
}
return(elements_list);
}
/**
Oublie la liste des elements et conducteurs en mouvement
*/
/// oublie la liste des elements et conducteurs en mouvement
void Diagram::invalidateMovedElements() {
if (!moved_elements_fetched) return;
moved_elements_fetched = false;
@@ -813,9 +499,7 @@ void Diagram::invalidateMovedElements() {
texts_to_move.clear();
}
/**
Reconstruit la liste des elements et conducteurs en mouvement
*/
/// reconstruit la liste des elements et conducteurs en mouvement
void Diagram::fetchMovedElements() {
// recupere les elements deplaces
foreach (QGraphicsItem *item, selectedItems()) {
@@ -864,7 +548,7 @@ void Diagram::moveElements(const QPointF &diff, QGraphicsItem *dontmove) {
// deplace les elements selectionnes
foreach(Element *element, elementsToMove()) {
if (dontmove && element == dontmove) continue;
if (dontmove != NULL && element == dontmove) continue;
element -> setPos(element -> pos() + diff);
}
@@ -881,71 +565,11 @@ void Diagram::moveElements(const QPointF &diff, QGraphicsItem *dontmove) {
// deplace les champs de texte
foreach(DiagramTextItem *dti, textsToMove()) {
if (dontmove && dti == dontmove) continue;
if (dontmove != NULL && dti == dontmove) continue;
dti -> setPos(dti -> pos() + diff);
}
}
/**
Permet de savoir si un element est utilise sur un schema
@param location Emplacement d'un element
@return true si l'element location est utilise sur ce schema, false sinon
*/
bool Diagram::usesElement(const ElementsLocation &location) {
foreach(CustomElement *element, customElements()) {
if (element -> location() == location) {
return(true);
}
}
return(false);
}
/**
Cette methode permet d'appliquer de nouvelles options de rendu tout en
accedant aux proprietes de rendu en cours.
@param new_properties Nouvelles options de rendu a appliquer
@return les options de rendu avant l'application de new_properties
*/
ExportProperties Diagram::applyProperties(const ExportProperties &new_properties) {
// exporte les options de rendu en cours
ExportProperties old_properties;
old_properties.draw_grid = displayGrid();
old_properties.draw_border = border_and_inset.borderIsDisplayed();
old_properties.draw_inset = border_and_inset.insetIsDisplayed();
old_properties.draw_terminals = drawTerminals();
old_properties.draw_colored_conductors = drawColoredConductors();
old_properties.exported_area = useBorder() ? QET::BorderArea : QET::ElementsArea;
// applique les nouvelles options de rendu
setUseBorder (new_properties.exported_area == QET::BorderArea);
setDrawTerminals (new_properties.draw_terminals);
setDrawColoredConductors (new_properties.draw_colored_conductors);
setDisplayGrid (new_properties.draw_grid);
border_and_inset.displayBorder(new_properties.draw_border);
border_and_inset.displayInset (new_properties.draw_inset);
// retourne les anciennes options de rendu
return(old_properties);
}
/**
@param pos Position cartesienne (ex : 10.3, 45.2) a transformer en position
dans la grille (ex : B2)
@return la position dans la grille correspondant a pos
*/
DiagramPosition Diagram::convertPosition(const QPointF &pos) {
// decale la position pour prendre en compte les marges en haut a gauche du schema
QPointF final_pos = pos - QPointF(margin, margin);
// delegue le calcul au BorderInset
DiagramPosition diagram_position = border_and_inset.convertPosition(final_pos);
// embarque la position cartesienne
diagram_position.setPosition(pos);
return(diagram_position);
}
/**
Definit s'il faut afficher ou non les bornes
@param dt true pour afficher les bornes, false sinon
@@ -958,15 +582,6 @@ void Diagram::setDrawTerminals(bool dt) {
}
}
/**
Definit s'il faut respecter ou non les couleurs des conducteurs.
Si non, les conducteurs sont tous dessines en noir.
@param dcc true pour respecter les couleurs, false sinon
*/
void Diagram::setDrawColoredConductors(bool dcc) {
draw_colored_conductors_ = dcc;
}
/**
@return la liste des conducteurs selectionnes sur le schema
*/
@@ -987,39 +602,6 @@ bool Diagram::clipboardMayContainDiagram() {
return(may_be_diagram);
}
/**
@return le projet auquel ce schema appartient ou 0 s'il s'agit d'un schema
independant.
*/
QETProject *Diagram::project() const {
return(project_);
}
/**
@param project le nouveau projet auquel ce schema appartient ou 0 s'il
s'agit d'un schema independant. Indiquer 0 pour rendre ce schema independant.
*/
void Diagram::setProject(QETProject *project) {
project_ = project;
}
/**
@return true si le schema est en lecture seule
*/
bool Diagram::isReadOnly() const {
return(read_only_);
}
/**
@param read_only true pour passer le schema en lecture seule, false sinon
*/
void Diagram::setReadOnly(bool read_only) {
if (read_only_ != read_only) {
read_only_ = read_only;
emit(readOnlyChanged(read_only_));
}
}
/**
@return Le contenu du schema. Les conducteurs sont tous places dans
conductorsToMove.
@@ -1064,20 +646,3 @@ DiagramContent Diagram::selectedContent() {
invalidateMovedElements();
return(dc);
}
/**
@return true s'il est possible de tourner les elements selectionnes.
Concretement, cette methode retourne true s'il y a des elements selectionnes
et qu'au moins l'un d'entre eux peut etre pivote.
*/
bool Diagram::canRotateSelection() const {
foreach(QGraphicsItem * qgi, selectedItems()) {
if (Element *e = qgraphicsitem_cast<Element *>(qgi)) {
// l'element est-il pivotable ?
if (e -> orientation().current() != e -> orientation().next()) {
return(true);
}
}
}
return(false);
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,19 +19,15 @@
#define SCHEMA_H
#include <QtGui>
#include <QtXml>
#include "qetdiagrameditor.h"
#include "borderinset.h"
#include "qgimanager.h"
#include "conductorproperties.h"
#include "exportproperties.h"
class Element;
class CustomElement;
class Terminal;
class Conductor;
class DiagramTextItem;
class DiagramContent;
class DiagramPosition;
class QETProject;
class ElementsLocation;
/**
Cette classe represente un schema electrique.
Elle gere les differents elements et conducteurs qui le composent
@@ -79,13 +75,9 @@ class Diagram : public QGraphicsScene {
QSet<Conductor *> conductors_to_move;
QHash<Conductor *, Terminal *> conductors_to_update;
QSet<DiagramTextItem *> texts_to_move;
QGIManager *qgi_manager;
QUndoStack *undo_stack;
QGIManager qgi_manager;
QUndoStack undo_stack;
bool draw_terminals;
bool draw_colored_conductors_;
QDomDocument xml_document;
QETProject *project_;
bool read_only_;
// methodes
protected:
@@ -96,14 +88,6 @@ class Diagram : public QGraphicsScene {
public:
static bool clipboardMayContainDiagram();
// fonctions relatives au projet parent
QETProject *project() const;
void setProject(QETProject *);
// fonctions relatives a la lecture seule
bool isReadOnly() const;
void setReadOnly(bool);
// fonctions relatives a la pose de conducteurs
void setConductor(bool);
void setConductorStart (QPointF);
@@ -111,46 +95,23 @@ class Diagram : public QGraphicsScene {
// fonctions relatives a l'import / export XML
QDomDocument toXml(bool = true);
bool initFromXml(QDomElement &, QPointF = QPointF(), bool = true, DiagramContent * = 0);
bool fromXml(QDomDocument &, QPointF = QPointF(), bool = true, DiagramContent * = 0);
bool fromXml(QDomElement &, QPointF = QPointF(), bool = true, DiagramContent * = 0);
void write();
void write(const QDomElement &);
bool wasWritten() const;
QDomElement writeXml(QDomDocument &) const;
// fonctions relative a l'ajout et a l'enlevement d'elements graphiques sur le schema
void addElement(Element *);
void addConductor(Conductor *);
void addDiagramTextItem(DiagramTextItem *);
void removeElement(Element *);
void removeConductor(Conductor *);
void removeDiagramTextItem(DiagramTextItem *);
bool fromXml(QDomDocument &, QPointF = QPointF(), bool = true, DiagramContent * = NULL);
// fonctions relatives aux options graphiques
ExportProperties applyProperties(const ExportProperties &);
void setDisplayGrid(bool);
bool displayGrid();
void setUseBorder(bool);
bool useBorder();
void setBorderOptions(BorderOptions);
BorderOptions borderOptions();
DiagramPosition convertPosition(const QPointF &);
bool drawTerminals() const;
void setDrawTerminals(bool);
bool drawColoredConductors() const;
void setDrawColoredConductors(bool);
QRectF border() const;
QString title() const;
bool toPaintDevice(QPaintDevice &, int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio);
QSize imageSize() const;
bool isEmpty() const;
QList<CustomElement *> customElements() const;
void invalidateMovedElements();
void fetchMovedElements();
const QSet<Element *> &elementsToMove();
@@ -160,28 +121,25 @@ class Diagram : public QGraphicsScene {
QSet<Conductor *> selectedConductors() const;
DiagramContent content() const;
DiagramContent selectedContent();
bool canRotateSelection() const;
void moveElements(const QPointF &, QGraphicsItem * = 0);
bool usesElement(const ElementsLocation &);
void moveElements(const QPointF &, QGraphicsItem * = NULL);
QUndoStack &undoStack();
QGIManager &qgiManager();
public slots:
void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
// fonctions relative a la selection sur le schema
void selectAll();
void deselectAll();
void invertSelection();
private slots:
void slot_checkSelectionEmptinessChange();
signals:
void written();
void readOnlyChanged(bool);
/**
Ce signal est emis lorsque la selection passe de l'etat rempli (par un
nombre quelconque d'elements et conducteurs) a l'etat vide et
vice-versa.
*/
void selectionEmptinessChanged();
};
/**
Permet d'ajouter ou enlever le "poseur de conducteur", c'est-a-dire la
Permet d'ajouter ou enlever le « poseur de conducteur », c'est-a-dire la
droite en pointilles qui apparait lorsqu'on pose un conducteur entre deux
bornes.
@param pf true pour ajouter le poseur de conducteur, false pour l'enlever
@@ -292,12 +250,12 @@ inline const QSet<DiagramTextItem *> &Diagram::textsToMove() {
/// @return la pile d'annulations de ce schema
inline QUndoStack &Diagram::undoStack() {
return(*undo_stack);
return(undo_stack);
}
/// @return le egstionnaire de QGraphicsItem de ce schema
inline QGIManager &Diagram::qgiManager() {
return(*qgi_manager);
return(qgi_manager);
}
/// @return true si les bornes sont affichees, false sinon
@@ -305,9 +263,4 @@ inline bool Diagram::drawTerminals() const {
return(draw_terminals);
}
/// @return true si les couleurs des conducteurs sont respectees, false sinon
inline bool Diagram::drawColoredConductors() const {
return(draw_colored_conductors_);
}
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -33,7 +33,7 @@ AddElementCommand::AddElementCommand(
const QPointF &p,
QUndoCommand *parent
) :
QUndoCommand(QString(QObject::tr("ajouter 1 %1", "undo caption - %1 is an element name")).arg(elmt -> name()), parent),
QUndoCommand(QObject::tr("ajouter 1 ") + elmt -> nom(), parent),
element(elmt),
diagram(d),
position(p)
@@ -48,12 +48,12 @@ AddElementCommand::~AddElementCommand() {
/// Annule l'ajout
void AddElementCommand::undo() {
diagram -> removeElement(element);
diagram -> removeItem(element);
}
/// Refait l'ajout
void AddElementCommand::redo() {
diagram -> addElement(element);
diagram -> addItem(element);
element -> setPos(position);
element -> setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
}
@@ -66,7 +66,7 @@ void AddElementCommand::redo() {
@param parent QUndoCommand parent
*/
AddTextCommand::AddTextCommand(Diagram *dia, DiagramTextItem *text, const QPointF &pos, QUndoCommand *parent) :
QUndoCommand(QObject::tr("Ajouter un champ de texte", "undo caption"), parent),
QUndoCommand(QObject::tr("Ajouter un champ de texte"), parent),
textitem(text),
diagram(dia),
position(pos)
@@ -81,12 +81,12 @@ AddTextCommand::~AddTextCommand() {
/// Annule l'ajout
void AddTextCommand::undo() {
diagram -> removeDiagramTextItem(textitem);
diagram -> removeItem(textitem);
}
/// Refait l'ajour
void AddTextCommand::redo() {
diagram -> addDiagramTextItem(textitem);
diagram -> addItem(textitem);
textitem -> setPos(position);
}
@@ -101,7 +101,7 @@ AddConductorCommand::AddConductorCommand(
Conductor *c,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("ajouter un conducteur", "undo caption"), parent),
QUndoCommand(QObject::tr("ajouter un conducteur"), parent),
conductor(c),
diagram(d)
{
@@ -115,12 +115,15 @@ AddConductorCommand::~AddConductorCommand() {
/// Annule l'ajout
void AddConductorCommand::undo() {
diagram -> removeConductor(conductor);
// detache le conducteur sans le detruire
conductor -> terminal1 -> removeConductor(conductor);
conductor -> terminal2 -> removeConductor(conductor);
diagram -> removeItem(conductor);
}
/// Refait l'ajout
void AddConductorCommand::redo() {
diagram -> addConductor(conductor);
diagram -> addItem(conductor);
}
/**
@@ -138,14 +141,7 @@ DeleteElementsCommand::DeleteElementsCommand(
removed_content(content),
diagram(dia)
{
setText(
QString(
QObject::tr(
"supprimer %1",
"undo caption - %1 is a sentence listing the removed content"
)
).arg(removed_content.sentence(DiagramContent::All))
);
setText(QObject::tr("supprimer ") + removed_content.sentence(DiagramContent::All));
diagram -> qgiManager().manage(removed_content.items(DiagramContent::All));
}
@@ -158,17 +154,19 @@ DeleteElementsCommand::~DeleteElementsCommand() {
void DeleteElementsCommand::undo() {
// remet les elements
foreach(Element *e, removed_content.elements) {
diagram -> addElement(e);
diagram -> addItem(e);
}
// remet les conducteurs
foreach(Conductor *c, removed_content.conductors(DiagramContent::AnyConductor)) {
diagram -> addConductor(c);
diagram -> addItem(c);
c -> terminal1 -> addConductor(c);
c -> terminal2 -> addConductor(c);
}
// remet les textes
foreach(DiagramTextItem *t, removed_content.textFields) {
diagram -> addDiagramTextItem(t);
diagram -> addItem(t);
}
}
@@ -176,17 +174,19 @@ void DeleteElementsCommand::undo() {
void DeleteElementsCommand::redo() {
// enleve les conducteurs
foreach(Conductor *c, removed_content.conductors(DiagramContent::AnyConductor)) {
diagram -> removeConductor(c);
c -> terminal1 -> removeConductor(c);
c -> terminal2 -> removeConductor(c);
diagram -> removeItem(c);
}
// enleve les elements
foreach(Element *e, removed_content.elements) {
diagram -> removeElement(e);
diagram -> removeItem(e);
}
// enleve les textes
foreach(DiagramTextItem *t, removed_content.textFields) {
diagram -> removeDiagramTextItem(t);
diagram -> removeItem(t);
}
}
@@ -208,14 +208,7 @@ PasteDiagramCommand::PasteDiagramCommand(
first_redo(true)
{
setText(
QString(
QObject::tr(
"coller %1",
"undo caption - %1 is a sentence listing the content to paste"
).arg(content.sentence(filter))
)
);
setText(QObject::tr("coller ") + content.sentence(filter));
diagram -> qgiManager().manage(content.items(filter));
}
@@ -227,13 +220,17 @@ PasteDiagramCommand::~PasteDiagramCommand() {
/// annule le coller
void PasteDiagramCommand::undo() {
// enleve les conducteurs
foreach(Conductor *c, content.conductorsToMove) diagram -> removeConductor(c);
foreach(Conductor *c, content.conductorsToMove) {
c -> terminal1 -> removeConductor(c);
c -> terminal2 -> removeConductor(c);
diagram -> removeItem(c);
}
// enleve les elements
foreach(Element *e, content.elements) diagram -> removeElement(e);
foreach(Element *e, content.elements) diagram -> removeItem(e);
// enleve les textes
foreach(DiagramTextItem *t, content.textFields) diagram -> removeDiagramTextItem(t);
foreach(DiagramTextItem *t, content.textFields) diagram -> removeItem(t);
}
/// refait le coller
@@ -241,13 +238,17 @@ void PasteDiagramCommand::redo() {
if (first_redo) first_redo = false;
else {
// pose les elements
foreach(Element *e, content.elements) diagram -> addElement(e);
foreach(Element *e, content.elements) diagram -> addItem(e);
// pose les conducteurs
foreach(Conductor *c, content.conductorsToMove) diagram -> addConductor(c);
foreach(Conductor *c, content.conductorsToMove) {
diagram -> addItem(c);
c -> terminal1 -> addConductor(c);
c -> terminal2 -> addConductor(c);
}
// pose les textes
foreach(DiagramTextItem *t, content.textFields) diagram -> addDiagramTextItem(t);
foreach(DiagramTextItem *t, content.textFields) diagram -> addItem(t);
}
foreach(Element *e, content.elements) e -> setSelected(true);
foreach(Conductor *c, content.conductorsToMove) c -> setSelected(true);
@@ -267,14 +268,7 @@ CutDiagramCommand::CutDiagramCommand(
) :
DeleteElementsCommand(dia, content, parent)
{
setText(
QString(
QObject::tr(
"couper %1",
"undo caption - %1 is a sentence listing the content to cut"
).arg(content.sentence(DiagramContent::All))
)
);
setText(QObject::tr("couper ") + content.sentence(DiagramContent::All));
}
/// Destructeur
@@ -300,21 +294,7 @@ MoveElementsCommand::MoveElementsCommand(
movement(m),
first_redo(true)
{
QString moved_content_sentence = content_to_move.sentence(
DiagramContent::Elements |
DiagramContent::TextFields |
DiagramContent::ConductorsToUpdate |
DiagramContent::ConductorsToMove
);
setText(
QString(
QObject::tr(
"d\351placer %1",
"undo caption - %1 is a sentence listing the moved content"
).arg(moved_content_sentence)
)
);
setText(QObject::tr("d\351placer ") + content_to_move.sentence(DiagramContent::Elements|DiagramContent::TextFields|DiagramContent::ConductorsToUpdate|DiagramContent::ConductorsToMove));
}
/// Destructeur
@@ -375,7 +355,7 @@ ChangeDiagramTextCommand::ChangeDiagramTextCommand(
const QString &after,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modifier le texte", "undo caption"), parent),
QUndoCommand(QObject::tr("modifier le texte"), parent),
text_item(dti),
text_before(before),
text_after(after),
@@ -408,17 +388,9 @@ void ChangeDiagramTextCommand::redo() {
@param parent QUndoCommand parent
*/
RotateElementsCommand::RotateElementsCommand(const QHash<Element *, QET::Orientation> &elements, QUndoCommand *parent) :
QUndoCommand(parent),
QUndoCommand(QObject::tr("pivoter ") + QET::ElementsAndConductorsSentence(elements.count(), 0), parent),
elements_to_rotate(elements)
{
setText(
QString(
QObject::tr(
"pivoter %1",
"undo caption - %1 is a sentence listing the rotated content"
)
).arg(QET::ElementsAndConductorsSentence(elements.count(), 0))
);
}
/// Destructeur
@@ -455,7 +427,7 @@ ChangeConductorCommand::ChangeConductorCommand(
Qt::Corner path_t,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modifier un conducteur", "undo caption"), parent),
QUndoCommand(QObject::tr("modifier un conducteur"), parent),
conductor(c),
old_profile(old_p),
new_profile(new_p),
@@ -488,15 +460,9 @@ ResetConductorCommand::ResetConductorCommand(
const QHash<Conductor *, ConductorProfilesGroup> &cp,
QUndoCommand *parent
) :
QUndoCommand(parent),
QUndoCommand(QObject::tr("R\351initialiser ") + QET::ElementsAndConductorsSentence(0, cp.count()), parent),
conductors_profiles(cp)
{
setText(
QObject::tr(
"R\351initialiser %1",
"undo caption - %1 is a sentence listing the reset content"
).arg(QET::ElementsAndConductorsSentence(0, cp.count()))
);
}
/// Destructeur
@@ -530,7 +496,7 @@ ChangeInsetCommand::ChangeInsetCommand(
const InsetProperties &new_ip,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modifier le cartouche", "undo caption"), parent),
QUndoCommand(QObject::tr("modifier le cartouche"), parent),
diagram(d),
old_inset(old_ip),
new_inset(new_ip)
@@ -556,15 +522,15 @@ void ChangeInsetCommand::redo() {
/**
Constructeur
@param dia Schema modifie
@param old_bp Anciennes proprietes du cadre du schema
@param new_bp Nouvelles proprietes du cadre du schema
@param parent QUndoCommand parent
*/
ChangeBorderCommand::ChangeBorderCommand(Diagram *dia, const BorderProperties &old_bp, const BorderProperties &new_bp, QUndoCommand *parent) :
QUndoCommand(QObject::tr("modifier les dimensions du sch\351ma", "undo caption"), parent),
ChangeBorderCommand::ChangeBorderCommand(Diagram *dia, QUndoCommand *parent) :
QUndoCommand(QObject::tr("modifier les dimensions du sch\351ma"), parent),
diagram(dia),
old_properties(old_bp),
new_properties(new_bp)
columnsCountDifference(0),
columnsHeightDifference(0.0),
columnsWidthDifference(0.0),
headersHeightDifference(0.0)
{
}
@@ -572,14 +538,39 @@ ChangeBorderCommand::ChangeBorderCommand(Diagram *dia, const BorderProperties &o
ChangeBorderCommand::~ChangeBorderCommand() {
}
/**
Applique les changements au schema
@param coeff comme les changements s'expriment sous forme de nombres dont
il suffit d'inverser le signe pour les annuler, ces valeurs sont ici
multipliees par le coefficient passe en parametre avant d'etre appliquees.
Pour resumer : 1 pour refaire, -1 pour annuler.
*/
void ChangeBorderCommand::applyChanges(int coeff) {
// reference vers l'objet border_and_inset du schema
BorderInset &border = diagram -> border_and_inset;
if (columnsCountDifference) {
border.setNbColumns(border.nbColumn() + (columnsCountDifference * coeff));
}
if (columnsHeightDifference) {
border.setColumnsHeight(border.columnsHeight() + (columnsHeightDifference * coeff));
}
if (columnsWidthDifference) {
border.setColumnsWidth(border.columnsWidth() + (columnsWidthDifference * coeff));
}
if (headersHeightDifference) {
border.setColumnsHeaderHeight(border.columnsHeaderHeight() + (headersHeightDifference * coeff));
}
border.adjustInsetToColumns();
}
/// Annule les changements apportes au schema
void ChangeBorderCommand::undo() {
diagram -> border_and_inset.importBorder(old_properties);
applyChanges(-1);
}
/// Refait les changements apportes au schema
void ChangeBorderCommand::redo() {
diagram -> border_and_inset.importBorder(new_properties);
applyChanges(1);
}
/**
@@ -588,7 +579,7 @@ void ChangeBorderCommand::redo() {
@param parent QUndoCommand parent
*/
ChangeConductorPropertiesCommand::ChangeConductorPropertiesCommand(Conductor *c, QUndoCommand *parent) :
QUndoCommand(QObject::tr("modifier les propri\351t\351s d'un conducteur", "undo caption"), parent),
QUndoCommand(QObject::tr("modifier les propri\351t\351s d'un conducteur"), parent),
conductor(c),
old_settings_set(false),
new_settings_set(false)

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -22,9 +22,7 @@
#include "diagramcontent.h"
#include "diagramtextitem.h"
#include "conductor.h"
#include "borderproperties.h"
#include "conductorproperties.h"
#include "insetproperties.h"
#include <QtGui>
/**
Cette classe represente l'action d'ajouter un element au schema
@@ -327,12 +325,16 @@ class ChangeInsetCommand : public QUndoCommand {
};
/**
Cette classe represente l'action de modifier les dimensions d'un schema
Cette classe represente l'action de modifier :
-le nombre de colonnes d'un schema
-la hauteur des colonnes
-la largeur des colonnes
-la hauteur des en-tetes des colonnes
*/
class ChangeBorderCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangeBorderCommand(Diagram *, const BorderProperties &, const BorderProperties &, QUndoCommand * = 0);
ChangeBorderCommand(Diagram *, QUndoCommand * = 0);
virtual ~ChangeBorderCommand();
private:
ChangeBorderCommand(const ChangeBorderCommand &);
@@ -341,16 +343,22 @@ class ChangeBorderCommand : public QUndoCommand {
public:
virtual void undo();
virtual void redo();
private:
virtual void applyChanges(int = 1);
// attributs
private:
/// schema modifie
Diagram *diagram;
public:
/// anciennes dimensions du schema
BorderProperties old_properties;
/// nouvelles dimensions du schema
BorderProperties new_properties;
/// nombre de colonnes ajoutees / enlevees
int columnsCountDifference;
/// delta pour la hauteur des colonnes
qreal columnsHeightDifference;
/// delta pour la largeur des colonnes
qreal columnsWidthDifference;
/// delta pour la hauteur des entetes des colonnes
qreal headersHeightDifference;
};
/**

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -54,11 +54,6 @@ QList<Conductor *> DiagramContent::conductors(int filter) const {
if (filter & ConductorsToMove) result += conductorsToMove;
if (filter & ConductorsToUpdate) result += conductorsToUpdate.keys();
if (filter & OtherConductors) result += otherConductors;
if (filter & SelectedOnly) {
foreach(Conductor *conductor, result) {
if (!conductor -> isSelected()) result.removeOne(conductor);
}
}
return(result);
}
@@ -82,11 +77,6 @@ QList<QGraphicsItem *> DiagramContent::items(int filter) const {
foreach(QGraphicsItem *qgi, conductors(filter)) items_list << qgi;
if (filter & Elements) foreach(QGraphicsItem *qgi, elements) items_list << qgi;
if (filter & TextFields) foreach(QGraphicsItem *qgi, textFields) items_list << qgi;
if (filter & SelectedOnly) {
foreach(QGraphicsItem *qgi, items_list) {
if (!qgi -> isSelected()) items_list.removeOne(qgi);
}
}
return(items_list);
}
@@ -96,19 +86,11 @@ QList<QGraphicsItem *> DiagramContent::items(int filter) const {
*/
int DiagramContent::count(int filter) const {
int count = 0;
if (filter & SelectedOnly) {
if (filter & Elements) foreach(Element *element, elements) { if (element -> isSelected()) ++ count; }
if (filter & TextFields) foreach(DiagramTextItem *dti, textFields) { if (dti -> isSelected()) ++ count; }
if (filter & ConductorsToMove) foreach(Conductor *conductor, conductorsToMove) { if (conductor -> isSelected()) ++ count; }
if (filter & ConductorsToUpdate) foreach(Conductor *conductor, conductorsToUpdate.keys()) { if (conductor -> isSelected()) ++ count; }
if (filter & OtherConductors) foreach(Conductor *conductor, otherConductors) { if (conductor -> isSelected()) ++ count; }
} else {
if (filter & Elements) count += elements.count();
if (filter & TextFields) count += textFields.count();
if (filter & ConductorsToMove) count += conductorsToMove.count();
if (filter & ConductorsToUpdate) count += conductorsToUpdate.count();
if (filter & OtherConductors) count += otherConductors.count();
}
return(count);
}
@@ -135,18 +117,14 @@ QString DiagramContent::sentence(int filter) const {
/**
Permet de debugger un contenu de schema
@param d Object QDebug a utiliser pour l'affichage des informations de debug
@param content Contenu de schema a debugger
@param c Contenu de schema a debugger
*/
QDebug &operator<<(QDebug d, DiagramContent &content) {
Q_UNUSED(content);
QDebug &operator<<(QDebug d, DiagramContent &c) {
d << "DiagramContent {" << "\n";
/*
FIXME Le double-heritage QObject / QGraphicsItem a casse cet operateur
d << " elements :" << c.elements << "\n";
d << " conductorsToUpdate :" << c.conductorsToUpdate.keys() << "\n";
d << " conductorsToMove :" << c.conductorsToMove << "\n";
d << " otherConductors :" << c.otherConductors << "\n";
*/
d << "}";
return(d.space());
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -46,8 +46,7 @@ class DiagramContent {
ConductorsToUpdate = 8,
OtherConductors = 16,
AnyConductor = 28,
All = 31,
SelectedOnly = 32
All = 31
};
/// Elements de texte du schema

302
diagramprintdialog.cpp Normal file
View File

@@ -0,0 +1,302 @@
/*
Copyright 2006-2007 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 "diagramprintdialog.h"
#include <math.h>
/**
Constructeur
@param dia Schema a imprimer
@param printer Imprimante a utiliser
@param parent Widget parent du dialogue
*/
DiagramPrintDialog::DiagramPrintDialog(Diagram *dia, QWidget *parent) :
QWidget(parent),
diagram(dia),
dialog(0)
{
// initialise l'imprimante
printer = new QPrinter();
}
/**
Destructeur
*/
DiagramPrintDialog::~DiagramPrintDialog() {
delete dialog;
delete printer;
}
/**
Definit le nom du PDF si l'utilisateur choisit une sortie vers un PDF
*/
void DiagramPrintDialog::setPDFName(const QString &name) {
pdf_name = name;
}
/**
@return le nom du PDF
*/
QString DiagramPrintDialog::PDFName() const {
return(pdf_name);
}
/**
Execute le dialogue d'impression
*/
void DiagramPrintDialog::exec() {
// affichage du dialogue d'impression standard
QPrintDialog print_dialog(printer);
print_dialog.setEnabledOptions(QAbstractPrintDialog::PrintToFile);
#ifndef Q_OS_WIN32
if (!pdf_name.isEmpty()) printer -> setOutputFileName(pdf_name);
#endif
if (print_dialog.exec() == QDialog::Rejected) return;
/*
Apres l'execution de ce premier dialogue, on connait le format papier a
utiliser, son orientation et on est sur que tout cela est supporte par
l'imprimante.
On peut donc en deduire le nombre de pages a imprimer
*/
// affichage d'un second dialogue, non standard, pour connaitre les pages a imprimer
buildDialog();
if (dialog -> exec() == QDialog::Rejected) return;
// effectue l'impression en elle-meme
print();
}
/**
@param fullPage true pour utiliser toute la feuille dans le calcul
@return Le nombre de pages necessaires pour imprimer le schema
avec l'orientation et le format papier utilise dans l'imprimante en cours.
*/
int DiagramPrintDialog::pagesCount(bool fullpage) const {
return(horizontalPagesCount(fullpage) * verticalPagesCount(fullpage));
}
/**
@param fullPage true pour utiliser toute la feuille dans le calcul
@return La largeur du "poster" en nombre de pages pour imprimer le schema
avec l'orientation et le format papier utilise dans l'imprimante en cours.
*/
int DiagramPrintDialog::horizontalPagesCount(bool fullpage) const {
// note : pageRect et Paper Rect tiennent compte de l'orientation du papier
QRect printable_area = fullpage ? printer -> paperRect() : printer -> pageRect();
QRect diagram_rect = diagram -> border().toRect();
int h_pages_count = int(ceil(qreal(diagram_rect.width()) / qreal(printable_area.width())));
return(h_pages_count);
}
/**
@param fullPage true pour utiliser toute la feuille dans le calcul
@return La largeur du "poster" en nombre de pages pour imprimer le schema
avec l'orientation et le format papier utilise dans l'imprimante en cours.
*/
int DiagramPrintDialog::verticalPagesCount(bool fullpage) const {
// note : pageRect et Paper Rect tiennent compte de l'orientation du papier
QRect printable_area = fullpage ? printer -> paperRect() : printer -> pageRect();
QRect diagram_rect = diagram -> border().toRect();
int v_pages_count = int(ceil(qreal(diagram_rect.height()) / qreal(printable_area.height())));
return(v_pages_count);
}
/**
Construit un dialogue non standard pour demander les pages a imprimer a l'utilisateur
*/
void DiagramPrintDialog::buildDialog() {
dialog = new QDialog();
dialog -> setWindowTitle(tr("Options d'impression"));
options_label = new QLabel();
use_full_page = new QCheckBox(tr("Utiliser toute la feuille"));
fit_diagram_to_page = new QCheckBox(tr("Adapter le sch\351ma \340 la page"));
range_from_label = new QLabel(tr("Plage de "));
start_page = new QSpinBox();
to_label = new QLabel(tr(" \340 "));
end_page = new QSpinBox();
buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
QHBoxLayout *pages_layout = new QHBoxLayout();
pages_layout -> addWidget(range_from_label);
pages_layout -> addWidget(start_page);
pages_layout -> addWidget(to_label);
pages_layout -> addWidget(end_page);
QVBoxLayout *dialog_layout = new QVBoxLayout(dialog);
dialog_layout -> addWidget(options_label);
dialog_layout -> addWidget(use_full_page);
dialog_layout -> addWidget(fit_diagram_to_page);
dialog_layout -> addLayout(pages_layout);
dialog_layout -> addStretch();
dialog_layout -> addWidget(buttons);
connect(use_full_page, SIGNAL(stateChanged(int)), this, SLOT(updateDialog()));
connect(fit_diagram_to_page, SIGNAL(stateChanged(int)), this, SLOT(updateDialog()));
connect(start_page, SIGNAL(valueChanged(int)), this, SLOT(checkStartPage()));
connect(end_page, SIGNAL(valueChanged(int)), this, SLOT(checkEndPage()));
connect(buttons, SIGNAL(accepted()), dialog, SLOT(accept()));
connect(buttons, SIGNAL(rejected()), dialog, SLOT(reject()));
updateDialog();
}
/**
Assure la coherence du dialogue
*/
void DiagramPrintDialog::updateDialog() {
int pages_count;
// si on adapte le schema a la page, alors il n'y a qu'une page a imprimer
if (fit_diagram_to_page -> isChecked()) {
pages_count = 1;
} else {
pages_count = pagesCount(use_full_page -> isChecked());
}
options_label -> setText(tr("Nombre total de pages : ") + QString("%1").arg(pages_count));
setPagesRangeVisible(pages_count > 1);
start_page -> setRange(1, pages_count);
end_page -> setRange(1, pages_count);
end_page -> setValue(pages_count);
}
/**
S'assure que la premiere page ne soit pas superieure a la derniere page
*/
void DiagramPrintDialog::checkStartPage() {
if (start_page -> value() > end_page -> value()) {
start_page -> blockSignals(true);
start_page -> setValue(end_page -> value());
start_page -> blockSignals(false);
}
}
/**
S'assure que la derniere page ne soit pas inferieure a la premiere page
*/
void DiagramPrintDialog::checkEndPage() {
if (end_page -> value() < start_page -> value()) {
end_page -> blockSignals(true);
end_page -> setValue(start_page -> value());
end_page -> blockSignals(false);
}
}
/**
@param visible true pour afficher les pages, false sinon
*/
void DiagramPrintDialog::setPagesRangeVisible(bool visible) {
range_from_label -> setVisible(visible);
start_page -> setVisible(visible);
to_label -> setVisible(visible);
end_page -> setVisible(visible);
}
/**
Effectue l'impression elle-meme
*/
void DiagramPrintDialog::print() {
// recupere les informations collectees dans le second dialogue
bool full_page = use_full_page -> isChecked();
bool fit_page = fit_diagram_to_page -> isChecked();
int first_page = start_page -> value();
int last_page = end_page -> value();
// parametre l'imprimante
printer -> setFullPage(full_page);
// QPainter utiliser pour effectuer le rendu
QPainter qp(printer);
// impression physique (!= fichier PDF)
if (printer -> outputFileName().isEmpty()) {
// lorsqu'on imprime en paysage sur imprimante reelle, il faut pivoter soi-meme le rendu
if (printer -> orientation() == QPrinter::Landscape) {
qp.rotate(90.0);
qp.translate(0.0, -printer -> pageRect().height());
}
}
diagram -> setDisplayGrid(false);
diagram -> setDrawTerminals(false);
if (fit_page) {
// impression adaptee sur une seule page
diagram -> render(&qp, QRectF(), diagram -> border(), Qt::KeepAspectRatio);
} else {
// impression sur une ou plusieurs pages
QRect diagram_rect = diagram -> border().toRect();
QRect printed_area = full_page ? printer -> paperRect() : printer -> pageRect();
int used_width = printed_area.width();
int used_height = printed_area.height();
int h_pages_count = horizontalPagesCount(full_page);
int v_pages_count = verticalPagesCount(full_page);
QVector< QVector< QRect > > pages_grid;
// le schema est imprime sur une matrice de feuilles
// parcourt les lignes de la matrice
int y_offset = 0;
for (int i = 0 ; i < v_pages_count ; ++ i) {
pages_grid << QVector< QRect >();
// parcourt les feuilles de la ligne
int x_offset = 0;
for (int j = 0 ; j < h_pages_count ; ++ j) {
pages_grid.last() << QRect(
QPoint(x_offset, y_offset),
QSize(
qMin(used_width, diagram_rect.width() - x_offset),
qMin(used_height, diagram_rect.height() - y_offset)
)
);
x_offset += used_width;
}
y_offset += used_height;
}
// ne retient que les pages a imprimer
QVector<QRect> pages_to_print;
for (int i = 0 ; i < v_pages_count ; ++ i) {
for (int j = 0 ; j < h_pages_count ; ++ j) {
int page_number = (i * h_pages_count) + j + 1;
if (page_number >= first_page && page_number <= last_page) {
pages_to_print << pages_grid.at(i).at(j);
}
}
}
// parcourt les pages pour impression
for (int i = 0 ; i < pages_to_print.count() ; ++ i) {
QRect current_rect(pages_to_print.at(i));
diagram -> render(
&qp,
QRect(QPoint(0,0), current_rect.size()),
current_rect.translated(diagram_rect.topLeft()),
Qt::KeepAspectRatio
);
if (i != pages_to_print.count() - 1) {
printer -> newPage();
}
}
}
diagram -> setDrawTerminals(true);
diagram -> setDisplayGrid(true);
}

71
diagramprintdialog.h Normal file
View File

@@ -0,0 +1,71 @@
/*
Copyright 2006-2007 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 DIAGRAM_PRINT_DIALOG_H
#define DIAGRAM_PRINT_DIALOG_H
#include <QtGui>
#include "diagram.h"
/**
Cette classe represente le dialogue de configuration de l'impression d'un
schema electrique.
Elle se charge egalement de l'impression elle-meme
*/
class DiagramPrintDialog : public QWidget {
Q_OBJECT
// Constructeurs, destructeur
public:
DiagramPrintDialog(Diagram *, QWidget * = 0);
virtual ~DiagramPrintDialog();
private:
DiagramPrintDialog(const DiagramPrintDialog &);
// methodes
public:
void setPDFName(const QString &);
QString PDFName() const;
int pagesCount(bool = false) const;
int horizontalPagesCount(bool = false) const;
int verticalPagesCount(bool = false) const;
void exec();
private:
void buildDialog();
void print();
private slots:
void updateDialog();
void checkStartPage();
void checkEndPage();
void setPagesRangeVisible(bool);
// attributs
private:
Diagram *diagram;
QPrinter *printer;
QString pdf_name;
QDialog *dialog;
QLabel *options_label;
QLabel *range_from_label;
QLabel *to_label;
QCheckBox *use_full_page;
QCheckBox *fit_diagram_to_page;
QSpinBox *start_page;
QSpinBox *end_page;
QDialogButtonBox *buttons;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -17,7 +17,6 @@
*/
#include "diagramtextitem.h"
#include "diagramcommands.h"
#include "qetapp.h"
/**
Constructeur
@@ -28,7 +27,6 @@ DiagramTextItem::DiagramTextItem(QGraphicsItem *parent, QGraphicsScene *scene) :
QGraphicsTextItem(parent, scene)
{
setDefaultTextColor(Qt::black);
setFont(QETApp::diagramTextsFont());
setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
}
@@ -44,7 +42,6 @@ DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent, QGr
previous_text(text)
{
setDefaultTextColor(Qt::black);
setFont(QETApp::diagramTextsFont());
setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
}
@@ -63,11 +60,13 @@ Diagram *DiagramTextItem::diagram() const {
*/
void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
QGraphicsTextItem::focusOutEvent(e);
// signale la modification du texte si besoin
// si le texte a ete modifie
if (toPlainText() != previous_text) {
emit(diagramTextChanged(this, previous_text, toPlainText()));
if (Diagram *dia = diagram()) {
dia -> undoStack().push(new ChangeDiagramTextCommand(this, previous_text, toPlainText()));
previous_text = toPlainText();
}
}
// deselectionne le texte
QTextCursor cursor = textCursor();
@@ -99,8 +98,8 @@ void DiagramTextItem::fromXml(const QDomElement &e) {
*/
QDomElement DiagramTextItem::toXml(QDomDocument &document) const {
QDomElement result = document.createElement("input");
result.setAttribute("x", QString("%1").arg(pos().x()));
result.setAttribute("y", QString("%1").arg(pos().y()));
result.setAttribute("x", pos().x());
result.setAttribute("y", pos().y());
result.setAttribute("text", toPlainText());
return(result);
}
@@ -131,16 +130,6 @@ void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
}
}
/**
Gere le clic sur le champ de texte
*/
void DiagramTextItem::mousePressEvent(QGraphicsSceneMouseEvent *e) {
if (e -> modifiers() & Qt::ControlModifier) {
setSelected(!isSelected());
}
QGraphicsTextItem::mousePressEvent(e);
}
/**
Gere les mouvements de souris lies au champ de texte
*/
@@ -175,9 +164,7 @@ void DiagramTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
}
diagram_ptr -> invalidateMovedElements();
}
if (!(e -> modifiers() & Qt::ControlModifier)) {
QGraphicsTextItem::mouseReleaseEvent(e);
}
}
/**

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -52,7 +52,6 @@ class DiagramTextItem : public QGraphicsTextItem {
protected:
virtual void focusOutEvent(QFocusEvent *);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
@@ -60,8 +59,6 @@ class DiagramTextItem : public QGraphicsTextItem {
signals:
/// signal emis lorsque le champ de texte perd le focus
void lostFocus();
/// signal emis lorsque le champ de texte a ete modifie
void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
// slots
public slots:

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -18,12 +18,9 @@
#ifndef DIAGRAMVIEW_H
#define DIAGRAMVIEW_H
#include <QtGui>
#include "elementslocation.h"
class Conductor;
class Diagram;
class DiagramTextItem;
class Element;
class QETDiagramEditor;
class Conductor;
/**
Classe representant graphiquement un schema electrique
*/
@@ -32,37 +29,42 @@ class DiagramView : public QGraphicsView {
// constructeurs, destructeur
public:
DiagramView(Diagram * = 0, QWidget * = 0);
DiagramView(QWidget * = 0);
virtual ~DiagramView();
private:
DiagramView(const DiagramView &);
// attributs
public:
/// Nom de fichier du schema edite
QString file_name;
private:
Diagram *scene;
QMenu *context_menu;
QAction *paste_here;
QAction *find_element_;
QPoint paste_here_pos;
bool is_adding_text;
ElementsLocation next_location_;
QPoint next_position_;
// methodes
public:
QString title() const;
void editDiagramProperties();
bool open(QString, int * = NULL);
void closeEvent(QCloseEvent *);
bool save();
bool saveAs();
void dialogExport();
void dialogEditInfos();
void dialogPrint();
void addColumn();
void removeColumn();
void addRow();
void removeRow();
void expand();
void shrink();
/// @return Le schema visualise par ce DiagramView
Diagram *diagram() { return(scene); }
QETDiagramEditor *diagramEditor() const;
bool hasSelectedItems();
void addText();
DiagramTextItem *addDiagramTextAtPos(const QPointF &);
protected:
virtual void mouseDoubleClickEvent(QMouseEvent *);
@@ -71,14 +73,13 @@ class DiagramView : public QGraphicsView {
virtual bool event(QEvent *);
private:
bool saveDiagramToFile(QString &);
void mousePressEvent(QMouseEvent *);
void dragEnterEvent(QDragEnterEvent *);
void dragLeaveEvent(QDragLeaveEvent *);
void dragMoveEvent(QDragMoveEvent *);
void dropEvent(QDropEvent *);
QRectF viewedSceneRect() const;
bool mustIntegrateElement(const ElementsLocation &) const;
bool addElementAtPos(const ElementsLocation &, const QPoint &);
signals:
/// Signal emis lorsque la selection change
@@ -87,14 +88,6 @@ class DiagramView : public QGraphicsView {
void modeChanged();
/// Signal emis lorsqu'un texte a ete pose
void textAdded(bool);
/// Signal emis lorsque le titre du schema change
void titleChanged(DiagramView *, const QString &);
/// Signal emis avant l'integration d'un element
void aboutToAddElement();
/// Signal emis lorsque l'utilisateur souhaite retrouver un element du schema dans les collections
void findElementRequired(const ElementsLocation &);
/// Signal emis lorsque l'utilisateur souhaite editer un element du schema
void editElementRequired(const ElementsLocation &);
public slots:
void selectNothing();
@@ -114,16 +107,12 @@ class DiagramView : public QGraphicsView {
void pasteHere();
void adjustSceneRect();
void updateWindowTitle();
void editSelectionProperties();
void editElement(Element *);
void editConductor();
void editConductor(Conductor *);
void resetConductors();
void editDefaultConductorProperties();
private slots:
void addDroppedElement();
void adjustGridToZoom();
void applyReadOnly();
};
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -16,7 +16,6 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "arceditor.h"
#include "styleeditor.h"
#include "partarc.h"
/**
@@ -25,11 +24,10 @@
@param arc L'arc a editer
@param parent le Widget parent
*/
ArcEditor::ArcEditor(QETElementEditor *editor, PartArc *arc, QWidget *parent) :
ElementItemEditor(editor, parent),
part(arc)
{
style_ = new StyleEditor(editor);
ArcEditor::ArcEditor(QETElementEditor *editor, PartArc *arc, QWidget *parent) : ElementItemEditor(editor, parent) {
part = arc;
x = new QLineEdit();
y = new QLineEdit();
h = new QLineEdit();
@@ -44,11 +42,9 @@ ArcEditor::ArcEditor(QETElementEditor *editor, PartArc *arc, QWidget *parent) :
h -> setValidator(new QDoubleValidator(h));
v -> setValidator(new QDoubleValidator(v));
QVBoxLayout *v_layout = new QVBoxLayout(this);
QGridLayout *grid = new QGridLayout();
QGridLayout *grid = new QGridLayout(this);
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
grid -> addWidget(new QLabel("x"), 1, 0, Qt::AlignRight);
grid -> addWidget(new QLabel("x"), 1, 0);
grid -> addWidget(x, 1, 1);
grid -> addWidget(new QLabel("y"), 1, 2);
grid -> addWidget(y, 1, 3);
@@ -61,10 +57,6 @@ ArcEditor::ArcEditor(QETElementEditor *editor, PartArc *arc, QWidget *parent) :
grid -> addWidget(start_angle, 5, 1);
grid -> addWidget(new QLabel(tr("Angle :")), 6, 0);
grid -> addWidget(angle, 6, 1);
v_layout -> addWidget(style_);
v_layout -> addLayout(grid);
updateForm();
activeConnections(true);
@@ -74,48 +66,16 @@ ArcEditor::ArcEditor(QETElementEditor *editor, PartArc *arc, QWidget *parent) :
ArcEditor::~ArcEditor() {
}
/**
Permet de specifier a cet editeur quelle primitive il doit editer. A noter
qu'un editeur peut accepter ou refuser d'editer une primitive.
L'editeur d'arc acceptera d'editer la primitive new_part s'il s'agit d'un
objet de la classe PartArc.
@param new_part Nouvelle primitive a editer
@return true si l'editeur a accepter d'editer la primitive, false sinon
*/
bool ArcEditor::setPart(CustomElementPart *new_part) {
if (!new_part) {
part = 0;
style_ -> setPart(0);
return(true);
}
if (PartArc *part_arc = dynamic_cast<PartArc *>(new_part)) {
part = part_arc;
style_ -> setPart(part);
updateForm();
return(true);
} else {
return(false);
}
}
/**
@return la primitive actuellement editee, ou 0 si ce widget n'en edite pas
*/
CustomElementPart *ArcEditor::currentPart() const {
return(part);
}
/**
Met a jour l'arc a partir a partir des donnees du formulaire
*/
void ArcEditor::updateArc() {
if (!part) return;
part -> setProperty("x", x -> text().toDouble());
part -> setProperty("y", y -> text().toDouble());
part -> setProperty("diameter_h", h -> text().toDouble());
part -> setProperty("diameter_v", v -> text().toDouble());
part -> setProperty("start_angle", -start_angle -> value() + 90);
part -> setProperty("angle", -angle -> value());
part -> setStartAngle(-start_angle -> value() + 90);
part -> setAngle(-angle -> value());
}
/// Met a jour l'abscisse du centre de l'arc et cree un objet d'annulation
@@ -135,7 +95,6 @@ void ArcEditor::updateArcA() { addChangePartCommand(tr("angle"),
Met a jour le formulaire d'edition
*/
void ArcEditor::updateForm() {
if (!part) return;
activeConnections(false);
x -> setText(part -> property("x").toString());
y -> setText(part -> property("y").toString());

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -20,7 +20,6 @@
#include <QtGui>
#include "elementitemeditor.h"
class PartArc;
class StyleEditor;
/**
Cette classe represente le widget d'edition d'un arc dans l'editeur
d'element.
@@ -29,23 +28,18 @@ class ArcEditor : public ElementItemEditor {
Q_OBJECT
//constructeurs, destructeur
public:
ArcEditor(QETElementEditor *, PartArc * = 0, QWidget * = 0);
virtual ~ArcEditor();
ArcEditor(QETElementEditor *, PartArc *, QWidget * = 0);
~ArcEditor();
private:
ArcEditor(const ArcEditor &);
// attributs
private:
PartArc *part;
StyleEditor *style_;
QLineEdit *x, *y, *h, *v;
QSpinBox *angle, *start_angle;
// methodes
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
public slots:
void updateArc();
void updateArcX();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -16,7 +16,6 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "circleeditor.h"
#include "styleeditor.h"
#include "partcircle.h"
/**
@@ -25,11 +24,9 @@
@param circle Le cercle a editer
@param parent le Widget parent
*/
CircleEditor::CircleEditor(QETElementEditor *editor, PartCircle *circle, QWidget *parent) :
ElementItemEditor(editor, parent),
part(circle)
{
style_ = new StyleEditor(editor);
CircleEditor::CircleEditor(QETElementEditor *editor, PartCircle *circle, QWidget *parent) : ElementItemEditor(editor, parent) {
part = circle;
x = new QLineEdit();
y = new QLineEdit();
@@ -39,20 +36,15 @@ CircleEditor::CircleEditor(QETElementEditor *editor, PartCircle *circle, QWidget
y -> setValidator(new QDoubleValidator(y));
r -> setValidator(new QDoubleValidator(r));
QVBoxLayout *v_layout = new QVBoxLayout(this);
QGridLayout *grid = new QGridLayout();
QGridLayout *grid = new QGridLayout(this);
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
grid -> addWidget(new QLabel("x"), 1, 0, Qt::AlignRight);
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("Diam\350tre : ")), 2, 0);
grid -> addWidget(r, 2, 1);
v_layout -> addWidget(style_);
v_layout -> addLayout(grid);
activeConnections(true);
updateForm();
}
@@ -61,42 +53,10 @@ CircleEditor::CircleEditor(QETElementEditor *editor, PartCircle *circle, QWidget
CircleEditor::~CircleEditor() {
}
/**
Permet de specifier a cet editeur quelle primitive il doit editer. A noter
qu'un editeur peut accepter ou refuser d'editer une primitive.
L'editeur de cercle acceptera d'editer la primitive new_part s'il s'agit
d'un objet de la classe PartCircle.
@param new_part Nouvelle primitive a editer
@return true si l'editeur a accepter d'editer la primitive, false sinon
*/
bool CircleEditor::setPart(CustomElementPart *new_part) {
if (!new_part) {
part = 0;
style_ -> setPart(0);
return(true);
}
if (PartCircle *part_circle = dynamic_cast<PartCircle *>(new_part)) {
part = part_circle;
style_ -> setPart(part);
updateForm();
return(true);
} else {
return(false);
}
}
/**
@return la primitive actuellement editee, ou 0 si ce widget n'en edite pas
*/
CustomElementPart *CircleEditor::currentPart() const {
return(part);
}
/**
met a jour le cercle a partir des donnees du formulaire
*/
void CircleEditor::updateCircle() {
if (!part) return;
part -> setProperty("x", x -> text().toDouble());
part -> setProperty("y", y -> text().toDouble());
part -> setProperty("diameter", r -> text().toDouble());
@@ -115,7 +75,6 @@ void CircleEditor::updateCircleD() { addChangePartCommand(tr("diam\350tre"), par
Met a jour le formulaire d'edition
*/
void CircleEditor::updateForm() {
if (!part) return;
activeConnections(false);
x -> setText(part -> property("x").toString());
y -> setText(part -> property("y").toString());

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -20,7 +20,6 @@
#include <QtGui>
#include "elementitemeditor.h"
class PartCircle;
class StyleEditor;
/**
Cette classe represente un editeur de cercle.
Elle permet d'editer a travers une interface graphique les
@@ -30,7 +29,7 @@ class CircleEditor : public ElementItemEditor {
Q_OBJECT
// Constructeurs, destructeur
public:
CircleEditor(QETElementEditor *, PartCircle * = 0, QWidget * = 0);
CircleEditor(QETElementEditor *, PartCircle *, QWidget * = 0);
virtual ~CircleEditor();
private:
CircleEditor(const CircleEditor &);
@@ -38,14 +37,9 @@ class CircleEditor : public ElementItemEditor {
// attributs
private:
PartCircle *part;
StyleEditor *style_;
QLineEdit *x, *y, *r;
// methodes
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
public slots:
void updateCircle();
void updateCircleX();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -83,6 +83,9 @@ void CustomElementGraphicPart::stylesFromXml(const QDomElement &qde) {
// recupere l'antialiasing
_antialiased = qde.attribute("antialias") == "true";
// met a jour l'editeur de style
style_editor -> updateForm();
}
/**
@@ -139,6 +142,13 @@ void CustomElementGraphicPart::applyStylesToQPainter(QPainter &painter) const {
painter.setBrush(brush);
}
/**
@return Le widget permettant d'editer les styles
*/
QWidget *CustomElementGraphicPart::elementInformations() {
return(style_editor);
}
/**
Specifie la valeur d'une propriete de style donnee.
@param property propriete a modifier. Valeurs acceptees :
@@ -167,6 +177,9 @@ void CustomElementGraphicPart::setProperty(const QString &property, const QVaria
setAntialiased(value.toBool());
change_made = true;
}
if (change_made) {
style_editor -> updateForm();
}
}
/**

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -69,10 +69,12 @@ class CustomElementGraphicPart : public CustomElementPart {
_color(BlackColor),
_antialiased(false)
{
style_editor = new StyleEditor(elementEditor(), this);
};
/// Destructeur
virtual ~CustomElementGraphicPart() {
delete style_editor;
};
// attributs
@@ -83,6 +85,10 @@ class CustomElementGraphicPart : public CustomElementPart {
Color _color;
bool _antialiased;
protected:
/// Widget d'edition des styles de cette partie graphique
StyleEditor *style_editor;
//methodes
public:
void setLineStyle(LineStyle);
@@ -97,6 +103,7 @@ class CustomElementGraphicPart : public CustomElementPart {
Color color() const;
bool antialiased() const;
QWidget *elementInformations();
void setProperty(const QString &, const QVariant &);
QVariant property(const QString &);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -24,16 +24,6 @@ QETElementEditor *CustomElementPart::elementEditor() const {
return(element_editor);
}
/**
Appelle le slot updateCurrentPartEditor de l'editeur
@see QETElementEditor::updateCurrentPartEditor()
*/
void CustomElementPart::updateCurrentPartEditor() const {
if (element_editor) {
element_editor -> updateCurrentPartEditor();
}
}
/// @return l'ElementScene contenant les parties editees par cet editeur
ElementScene *CustomElementPart::elementScene() const {
return(element_editor -> elementScene());

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -59,6 +59,8 @@ class CustomElementPart {
Enregistre la partie dans un document XML
*/
virtual const QDomElement toXml(QDomDocument &) const = 0;
/// @return un widget suppose decrire et/ou permettre de modifier la partie
virtual QWidget *elementInformations() = 0;
/**
Permet de modifier une des proprietes de la partie
*/
@@ -75,18 +77,11 @@ class CustomElementPart {
virtual bool isUseless() const = 0;
/// @return un pointeur vers l'editeur d'element parent
virtual QETElementEditor *elementEditor() const;
/**
Appelle le slot updateCurrentPartEditor de l'editeur
@see QETElementEditor::updateCurrentPartEditor()
*/
virtual void updateCurrentPartEditor() const;
/// @return un pointeur vers la scene d'edition parente
virtual ElementScene *elementScene() const;
/// @return la pile d'annulations a utiliser
virtual QUndoStack &undoStack() const;
/// @return le nom de la partie
virtual QString name() const = 0;
/// @return le nom qui sera utilise pour nommer l'element XML lors de l'export
virtual QString xmlName() const = 0;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 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", "undo caption"), parent),
QUndoCommand(QObject::tr("suppression"), parent),
deleted_parts(parts),
editor_scene(scene)
{
@@ -47,116 +47,16 @@ DeletePartsCommand::~DeletePartsCommand() {
/// Restaure les parties supprimees
void DeletePartsCommand::undo() {
editor_scene -> blockSignals(true);
foreach(QGraphicsItem *qgi, deleted_parts) {
editor_scene -> addItem(qgi);
}
editor_scene -> blockSignals(false);
}
/// Supprime les parties
void DeletePartsCommand::redo() {
editor_scene -> blockSignals(true);
foreach(QGraphicsItem *qgi, deleted_parts) {
editor_scene -> removeItem(qgi);
}
editor_scene -> blockSignals(false);
}
/*** CutPartsCommand ***/
/**
Constructeur
@param view ElementView concernee
@param c 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
editor_scene_ -> blockSignals(true);
foreach(QGraphicsItem *part, content_) {
editor_scene_ -> removeItem(part);
}
editor_scene_ -> blockSignals(false);
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
editor_scene_ -> blockSignals(true);
foreach(QGraphicsItem *part, content_) {
editor_scene_ -> addItem(part);
}
editor_scene_ -> blockSignals(false);
if (uses_offset) {
editor_view_ -> offset_paste_count_ = new_offset_paste_count_;
editor_view_ -> start_top_left_corner_ = new_start_top_left_corner_;
}
}
editor_scene_ -> slot_select(content_);
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 ***/
@@ -173,7 +73,7 @@ MovePartsCommand::MovePartsCommand(
const QList<QGraphicsItem *> parts,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("d\351placement", "undo caption"), parent),
QUndoCommand(QObject::tr("d\351placement"), parent),
movement(m),
first_redo(true)
{
@@ -214,7 +114,7 @@ AddPartCommand::AddPartCommand(
QGraphicsItem *p,
QUndoCommand *parent
) :
QUndoCommand(QString(QObject::tr("ajout %1", "undo caption")).arg(name), parent),
QUndoCommand(QObject::tr("ajout ") + name, parent),
part(p),
editor_scene(scene),
first_redo(true)
@@ -261,7 +161,7 @@ ChangePartCommand::ChangePartCommand(
const QVariant &new_v,
QUndoCommand *parent
) :
QUndoCommand(QString(QObject::tr("modification %1", "undo caption")).arg(name), parent),
QUndoCommand(QObject::tr("modification ") + name, parent),
cep(part),
property(prop),
old_value(old_v),
@@ -296,7 +196,7 @@ ChangePolygonPointsCommand::ChangePolygonPointsCommand(
const QVector<QPointF> &n_points,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modification points polygone", "undo caption"), parent),
QUndoCommand(QObject::tr("modification points polygone"), parent),
polygon(p),
old_points(o_points),
new_points(n_points)
@@ -336,7 +236,7 @@ ChangeHotspotCommand::ChangeHotspotCommand(
const QPoint &o,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modification dimensions/hotspot", "undo caption"), parent),
QUndoCommand(QObject::tr("modification dimensions/hotspot"), parent),
element(element_scene),
size_before(size_1),
size_after(size_2),
@@ -397,7 +297,7 @@ ChangeNamesCommand::ChangeNamesCommand(
const NamesList &after,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modification noms", "undo caption"), parent),
QUndoCommand(QObject::tr("modification noms"), parent),
names_before(before),
names_after(after),
element(element_scene)
@@ -431,7 +331,7 @@ ChangeOrientationsCommand::ChangeOrientationsCommand(
const OrientationSet &after,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modification orientations", "undo caption"), parent),
QUndoCommand(QObject::tr("modification orientations"), parent),
ori_before(before),
ori_after(after),
element(element_scene)
@@ -475,16 +375,16 @@ ChangeZValueCommand::ChangeZValueCommand(
// choisit le nom en fonction du traitement
if (option == BringForward) {
setText(QObject::tr("amener au premier plan", "undo caption"));
setText(QObject::tr("amener au premier plan"));
applyBringForward(items_list);
} else if (option == Raise) {
setText(QObject::tr("rapprocher", "undo caption"));
setText(QObject::tr("rapprocher"));
applyRaise(items_list);
} else if (option == Lower) {
setText(QObject::tr("\351loigner", "undo caption"));
setText(QObject::tr("\351loigner"));
applyLower(items_list);
} else if (option == SendBackward) {
setText(QObject::tr("envoyer au fond", "undo caption"));
setText(QObject::tr("envoyer au fond"));
applySendBackward(items_list);
}
}
@@ -583,7 +483,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", "undo caption"), parent),
QUndoCommand(QObject::tr("modification connexions internes"), parent),
element(elmt),
ic(allow)
{
@@ -602,32 +502,3 @@ void AllowInternalConnectionsCommand::undo() {
void AllowInternalConnectionsCommand::redo() {
element -> setInternalConnections(ic);
}
/**
Constructeur
@param elmt ElementScene concernee
@param old_infos Informations complementaires precedentes
@param old_infos Nouvelles informations complementaires
@param parent QUndoCommand parent
*/
ChangeInformationsCommand::ChangeInformationsCommand(ElementScene *elmt, const QString &old_infos, const QString &new_infos, QUndoCommand *parent) :
QUndoCommand(QObject::tr("modification informations complementaires", "undo caption"), parent),
element(elmt),
old_informations_(old_infos),
new_informations_(new_infos)
{
}
/// Destructeur
ChangeInformationsCommand::~ChangeInformationsCommand() {
}
/// Annule le changement d'autorisation pour les connexions internes
void ChangeInformationsCommand::undo() {
element -> setInformations(old_informations_);
}
/// Refait le changement d'autorisation pour les connexions internes
void ChangeInformationsCommand::redo() {
element -> setInformations(new_informations_);
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,9 +19,7 @@
#define EDITOR_COMMANDS_H
#include "customelementpart.h"
#include "partpolygon.h"
#include "elementview.h"
#include "elementscene.h"
#include "elementcontent.h"
#include "qgimanager.h"
#include <QtGui>
/**
@@ -49,52 +47,6 @@ 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
@@ -356,31 +308,4 @@ class AllowInternalConnectionsCommand : public QUndoCommand {
/// autorisation des connexions internes apres modification
bool ic;
};
/**
Cette classe represente l'action de changer les informations
complementaires d'un element.
*/
class ChangeInformationsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangeInformationsCommand(ElementScene *, const QString &, const QString &, QUndoCommand * = 0);
virtual ~ChangeInformationsCommand();
private:
ChangeInformationsCommand(const ChangeInformationsCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// Element edite auquel il faut appliquer les modifications
ElementScene *element;
/// Informations avant modification
QString old_informations_;
/// Informations apres modification
QString new_informations_;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -47,23 +47,15 @@ QUndoStack &ElementItemEditor::undoStack() const {
/**
Ajoute une ChangePartCommand a l'UndoStack. L'ancienne valeur sera
automatiquement recuperee. A noter que cette methode ne fait rien si
l'ancienne valeur et la nouvelle sont egales ou encore si part vaut 0
automatiquement recuperee.
@param desc nom de la propriete modifiee
@param part partie modifiee
@param prop propriete modifiee
@param new_v nouvelle valeur
*/
void ElementItemEditor::addChangePartCommand(const QString &desc, CustomElementPart *part, const QString &prop, const QVariant &new_v) {
// ne fait rien si part vaut 0
if (!part) return;
// recupere l'ancienne valeur
QVariant old_v = part -> property(prop);
// ne fait rien si l'ancienne valeur et la nouvelle sont egales
if (old_v == new_v) return;
undoStack().push(
new ChangePartCommand(
desc + " " + element_type_name,
@@ -84,12 +76,3 @@ QString ElementItemEditor::elementTypeName() const {
void ElementItemEditor::setElementTypeName(const QString &name) {
element_type_name = name;
}
/**
Detache l'editeur de la primitive qu'il edite.
Equivaut a setPart(0)
@see setPart
*/
void ElementItemEditor::detach() {
setPart(0);
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 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 parties dans
Cette classe est la classe de base pour les editeurs de aprties 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.
@@ -44,10 +44,6 @@ class ElementItemEditor : public QWidget {
virtual void addChangePartCommand(const QString &, CustomElementPart *, const QString &, const QVariant &);
virtual QString elementTypeName() const;
virtual void setElementTypeName(const QString &);
virtual void detach();
virtual bool setPart(CustomElementPart *) = 0;
virtual CustomElementPart *currentPart() const = 0;
virtual void updateForm() = 0;
// attributs
private:

732
editor/elementscene.cpp Normal file
View File

@@ -0,0 +1,732 @@
/*
Copyright 2006-2007 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 "elementscene.h"
#include "qetelementeditor.h"
#include <cmath>
#include "partline.h"
#include "partellipse.h"
#include "partcircle.h"
#include "partpolygon.h"
#include "partterminal.h"
#include "parttext.h"
#include "parttextfield.h"
#include "partarc.h"
#include "hotspoteditor.h"
#include "editorcommands.h"
const int ElementScene::xGrid = 10;
const int ElementScene::yGrid = 10;
/**
Constructeur
@param editor L'editeur d'element concerne
@param parent le Widget parent
*/
ElementScene::ElementScene(QETElementEditor *editor, QObject *parent) :
QGraphicsScene(parent),
_width(3),
_height(7),
_hotspot(15, 35),
internal_connections(false),
qgi_manager(this),
element_editor(editor)
{
current_polygon = NULL;
undo_stack.setClean();
}
/// Destructeur
ElementScene::~ElementScene() {
}
/**
Passe la scene en mode "selection et deplacement de parties"
*/
void ElementScene::slot_move() {
behavior = Normal;
}
/**
Passe la scene en mode "ajout de ligne"
*/
void ElementScene::slot_addLine() {
behavior = Line;
}
/**
Passe la scene en mode "ajout de cercle"
*/
void ElementScene::slot_addCircle() {
behavior = Circle;
}
/**
Passe la scene en mode "ajout d'ellipse"
*/
void ElementScene::slot_addEllipse() {
behavior = Ellipse;
}
/**
Passe la scene en mode "ajout de polygone"
*/
void ElementScene::slot_addPolygon() {
behavior = Polygon;
}
/**
Passe la scene en mode "ajout de texte statique"
*/
void ElementScene::slot_addText() {
behavior = Text;
}
/**
Passe la scene en mode "ajout de borne"
*/
void ElementScene::slot_addTerminal() {
behavior = Terminal;
}
/**
Passe la scene en mode "ajout d'arc de cercle"
*/
void ElementScene::slot_addArc() {
behavior = Arc;
}
/**
Passe la scene en mode "ajout de champ de texte"
*/
void ElementScene::slot_addTextField() {
behavior = TextField;
}
/**
Gere les mouvements de la souris
@param e objet decrivant l'evenement
*/
void ElementScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
QRectF temp_rect;
qreal radius;
QPointF temp_point;
QPolygonF temp_polygon;
if (e -> buttons() & Qt::LeftButton) {
switch(behavior) {
case Line:
current_line -> setLine(QLineF(current_line -> line().p1(), e -> scenePos()));
break;
case Ellipse:
temp_rect = current_ellipse -> rect();
temp_rect.setBottomRight(e -> scenePos());
current_ellipse -> setRect(temp_rect);
break;
case Arc:
temp_rect = current_arc -> rect();
temp_rect.setBottomRight(e -> scenePos());
current_arc -> setRect(temp_rect);
break;
case Circle:
temp_rect = current_circle -> rect();
temp_point = e -> scenePos() - 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),
QSizeF(2.0 * radius, 2.0 * radius)
);
current_circle -> setRect(temp_rect);
break;
case Polygon:
if (current_polygon == NULL) break;
temp_polygon = current_polygon -> polygon();
temp_polygon.pop_back();
temp_polygon << e -> scenePos();
current_polygon -> setPolygon(temp_polygon);
break;
case Normal:
default:
QGraphicsScene::mouseMoveEvent(e);
}
} else if (behavior == Polygon && current_polygon != NULL) {
temp_polygon = current_polygon -> polygon();
temp_polygon.pop_back();
temp_polygon << e -> scenePos();
current_polygon -> setPolygon(temp_polygon);
} else QGraphicsScene::mouseMoveEvent(e);
}
/**
Gere les appuis sur les boutons de la souris
@param e objet decrivant l'evenement
*/
void ElementScene::mousePressEvent(QGraphicsSceneMouseEvent *e) {
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()));
break;
case Ellipse:
current_ellipse = new PartEllipse(element_editor, 0, this);
current_ellipse -> setRect(QRectF(e -> scenePos(), 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 -> 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 -> setProperty("antialias", true);
break;
case Polygon:
if (current_polygon == NULL) {
current_polygon = new PartPolygon(element_editor, 0, this);
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();
current_polygon -> setPolygon(temp_polygon);
break;
case Normal:
default:
QGraphicsScene::mousePressEvent(e);
if (!selectedItems().isEmpty()) fsi_pos = selectedItems().first() -> scenePos();
}
} else QGraphicsScene::mousePressEvent(e);
}
/**
Gere les relachements de boutons de la souris
@param e objet decrivant l'evenement
*/
void ElementScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
PartTerminal *terminal;
PartText *text;
PartTextField *textfield;
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
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());
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());
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());
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());
break;
case Terminal:
terminal = new PartTerminal(element_editor, 0, this);
terminal -> setPos(e -> scenePos());
undo_stack.push(new AddPartCommand(tr("borne"), this, terminal));
emit(partsAdded());
break;
case Text:
text = new PartText(element_editor, 0, this);
text -> setPos(e -> scenePos());
undo_stack.push(new AddPartCommand(tr("texte"), this, text));
emit(partsAdded());
break;
case TextField:
textfield = new PartTextField(element_editor, 0, this);
textfield -> setPos(e -> scenePos());
undo_stack.push(new AddPartCommand(tr("champ de texte"), this, textfield));
emit(partsAdded());
break;
case Normal:
default:
QGraphicsScene::mouseReleaseEvent(e);
// detecte les deplacements de parties
if (!selectedItems().isEmpty()) {
QPointF movement = selectedItems().first() -> scenePos() - fsi_pos;
if (!movement.isNull()) {
undo_stack.push(new MovePartsCommand(movement, this, selectedItems()));
}
}
}
} 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());
} else QGraphicsScene::mouseReleaseEvent(e);
} else QGraphicsScene::mouseReleaseEvent(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 ElementScene::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(-_hotspot.x(), -_hotspot.y(), width(), height());
p -> setPen(Qt::black);
p -> setBrush(Qt::NoBrush);
p -> drawRect(drawable_area);
if (r.width() < 2500 && r.height() < 2500) {
// 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 % xGrid) ++ g_x;
int g_y = (int)ceil(r.y());
while (g_y % yGrid) ++ g_y;
for (int gx = g_x ; gx < limite_x ; gx += xGrid) {
for (int gy = g_y ; gy < limite_y ; gy += yGrid) {
p -> drawPoint(gx, gy);
}
}
}
p -> restore();
}
/**
Dessine l'arriere-plan de l'editeur, cad l'indicateur de hotspot.
@param p Le QPainter a utiliser pour dessiner
@param r Le rectangle de la zone a dessiner
*/
void ElementScene::drawForeground(QPainter *p, const QRectF &) {
p -> save();
// desactive tout antialiasing, sauf pour le texte
p -> setRenderHint(QPainter::Antialiasing, false);
p -> setRenderHint(QPainter::TextAntialiasing, true);
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
p -> setPen(Qt::red);
p -> setBrush(Qt::NoBrush);
p -> drawLine(QLineF(0.0, -_hotspot.y(), 0.0, height() - _hotspot.y()));
p -> drawLine(QLineF(-_hotspot.x(), 0.0, width() - _hotspot.x(), 0.0));
p -> restore();
}
/**
Exporte l'element en XML
@return un document XML decrivant l'element
*/
const QDomDocument ElementScene::toXml() const {
// document XML
QDomDocument xml_document;
// racine du document XML
QDomElement root = xml_document.createElement("definition");
root.setAttribute("type", "element");
root.setAttribute("width", QString("%1").arg(_width * 10));
root.setAttribute("height", QString("%1").arg(_height * 10));
root.setAttribute("hotspot_x", QString("%1").arg(_hotspot.x()));
root.setAttribute("hotspot_y", QString("%1").arg(_hotspot.y()));
root.setAttribute("orientation", ori.toString());
root.setAttribute("version", QET::version);
if (internal_connections) root.setAttribute("ic", "true");
// noms de l'element
root.appendChild(_names.toXml(xml_document));
QDomElement description = xml_document.createElement("description");
// description de l'element
foreach(QGraphicsItem *qgi, zItems(true)) {
if (CustomElementPart *ce = dynamic_cast<CustomElementPart *>(qgi)) {
if (ce -> isUseless()) continue;
description.appendChild(ce -> toXml(xml_document));
}
}
root.appendChild(description);
xml_document.appendChild(root);
return(xml_document);
}
/**
Lit un element depuis un document XML
@param xml_document un document XML decrivant l'element
*/
void ElementScene::fromXml(const QDomDocument &xml_document) {
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);
}
// 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);
}
}
}
}
}
/**
@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 la pile d'annulations de cet editeur d'element
*/
QUndoStack &ElementScene::undoStack() {
return(undo_stack);
}
/**
@return le gestionnaire de QGraphicsItem de cet editeur d'element
*/
QGIManager &ElementScene::qgiManager() {
return(qgi_manager);
}
/**
Selectionne tout
*/
void ElementScene::slot_selectAll() {
foreach(QGraphicsItem *qgi, items()) qgi -> setSelected(true);
}
/**
Deselectionne tout
*/
void ElementScene::slot_deselectAll() {
clearSelection();
}
/**
Inverse la selection
*/
void ElementScene::slot_invertSelection() {
foreach(QGraphicsItem *qgi, items()) qgi -> setSelected(!qgi -> isSelected());
}
/**
Supprime les elements selectionnes
*/
void ElementScene::slot_delete() {
// verifie qu'il y a qqc de selectionne
QList<QGraphicsItem *> selected_items = selectedItems();
if (selected_items.isEmpty()) return;
// efface tout ce qui est selectionne
undo_stack.push(new DeletePartsCommand(this, selected_items));
emit(partsRemoved());
}
/**
Lance un dialogue pour editer les dimensions et le point de saisie
(hotspot) de l'element.
*/
void ElementScene::slot_editSizeHotSpot() {
// cree un dialogue
QDialog dialog_sh;
dialog_sh.setModal(true);
dialog_sh.setMinimumSize(400, 230);
dialog_sh.setWindowTitle(tr("\311diter la taille et le point de saisie"));
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_sh);
// ajoute un HotspotEditor au dialogue
HotspotEditor *hotspot_editor = new HotspotEditor();
hotspot_editor -> setElementWidth(static_cast<uint>(width() / 10));
hotspot_editor -> setElementHeight(static_cast<uint>(height() / 10));
hotspot_editor -> setHotspot(hotspot());
hotspot_editor -> setOldHotspot(hotspot());
hotspot_editor -> setPartsRect(itemsBoundingRect());
hotspot_editor -> setPartsRectEnabled(true);
dialog_layout -> addWidget(hotspot_editor);
// ajoute deux boutons au dialogue
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog_layout -> addWidget(dialog_buttons);
connect(dialog_buttons, SIGNAL(accepted()), &dialog_sh, SLOT(accept()));
connect(dialog_buttons, SIGNAL(rejected()), &dialog_sh, SLOT(reject()));
// lance le dialogue
if (dialog_sh.exec() != QDialog::Accepted) return;
QSize new_size(hotspot_editor -> elementSize());
QSize old_size(width(), height());
QPoint new_hotspot(hotspot_editor -> hotspot());
QPoint old_hotspot(_hotspot);
if (new_size != old_size || new_hotspot != old_hotspot) {
undo_stack.push(new ChangeHotspotCommand(this, old_size, new_size, old_hotspot, new_hotspot, hotspot_editor -> offsetParts()));
}
}
/**
Lance un dialogue pour editer les noms de cete element
*/
void ElementScene::slot_editOrientations() {
// cree un dialogue
QDialog dialog_ori;
dialog_ori.setModal(true);
dialog_ori.setMinimumSize(400, 260);
dialog_ori.setWindowTitle(tr("\311diter les orientations"));
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_ori);
// ajoute un champ explicatif au dialogue
QLabel *information_label = new QLabel(tr("L'orientation par d\351faut est l'orientation dans laquelle s'effectue la cr\351ation de l'\351l\351ment."));
information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
information_label -> setWordWrap(true);
dialog_layout -> addWidget(information_label);
// ajoute un OrientationSetWidget au dialogue
OrientationSetWidget *ori_widget = new OrientationSetWidget();
ori_widget -> setOrientationSet(ori);
dialog_layout -> addWidget(ori_widget);
// ajoute une case a cocher pour les connexions internes
QCheckBox *ic_checkbox = new QCheckBox(tr("Autoriser les connexions internes"));
ic_checkbox -> setChecked(internal_connections);
dialog_layout -> addWidget(ic_checkbox);
dialog_layout -> addStretch();
// ajoute deux boutons au dialogue
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog_layout -> addWidget(dialog_buttons);
connect(dialog_buttons, SIGNAL(accepted()), &dialog_ori, SLOT(accept()));
connect(dialog_buttons, SIGNAL(rejected()), &dialog_ori, SLOT(reject()));
// lance le dialogue
if (dialog_ori.exec() == QDialog::Accepted) {
OrientationSet new_ori = ori_widget -> orientationSet();
if (new_ori != ori) {
undoStack().push(new ChangeOrientationsCommand(this, ori, new_ori));
}
if (ic_checkbox -> isChecked() != internal_connections) {
undoStack().push(new AllowInternalConnectionsCommand(this, ic_checkbox -> isChecked()));
}
}
}
/**
Lance un dialogue pour editer les noms de cet element
*/
void ElementScene::slot_editNames() {
// cree un dialogue
QDialog dialog;
dialog.setModal(true);
dialog.setMinimumSize(400, 330);
dialog.setWindowTitle(tr("\311diter les noms"));
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog);
// ajoute un champ explicatif au dialogue
QLabel *information_label = new QLabel(tr("Vous pouvez sp\351cifier le nom de l'\351l\351ment dans plusieurs langues."));
information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
information_label -> setWordWrap(true);
dialog_layout -> addWidget(information_label);
// ajoute un NamesListWidget au dialogue
NamesListWidget *names_widget = new NamesListWidget();
names_widget -> setNames(_names);
dialog_layout -> addWidget(names_widget);
// ajoute deux boutons au dialogue
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog_layout -> addWidget(dialog_buttons);
connect(dialog_buttons, SIGNAL(accepted()), names_widget, SLOT(check()));
connect(names_widget, SIGNAL(inputChecked()), &dialog, SLOT(accept()));
connect(dialog_buttons, SIGNAL(rejected()), &dialog, SLOT(reject()));
// lance le dialogue
if (dialog.exec() == QDialog::Accepted) {
NamesList new_names(names_widget -> names());
if (new_names != _names) undoStack().push(new ChangeNamesCommand(this, _names, new_names));
}
}
/**
Amene les elements selectionnes au premier plan
*/
void ElementScene::slot_bringForward() {
undoStack().push(new ChangeZValueCommand(this, ChangeZValueCommand::BringForward));
emit(partsZValueChanged());
}
/**
Remonte les elements selectionnes d'un plan
*/
void ElementScene::slot_raise() {
undoStack().push(new ChangeZValueCommand(this, ChangeZValueCommand::Raise));
emit(partsZValueChanged());
}
/**
Descend les elements selectionnes d'un plan
*/
void ElementScene::slot_lower() {
undoStack().push(new ChangeZValueCommand(this, ChangeZValueCommand::Lower));
emit(partsZValueChanged());
}
/**
Envoie les elements selectionnes au fond
*/
void ElementScene::slot_sendBackward() {
undoStack().push(new ChangeZValueCommand(this, ChangeZValueCommand::SendBackward));
emit(partsZValueChanged());
}
/**
@param include_terminals true pour inclure les bornes, false sinon
@return les parties de l'element ordonnes par zValue croissante
*/
QList<QGraphicsItem *> ElementScene::zItems(bool include_terminals) const {
// recupere les elements
QList<QGraphicsItem *> all_items_list(items());
// enleve les bornes
QList<QGraphicsItem *> terminals;
foreach(QGraphicsItem *qgi, all_items_list) {
if (qgraphicsitem_cast<PartTerminal *>(qgi)) {
all_items_list.removeAt(all_items_list.indexOf(qgi));
terminals << qgi;
}
}
// ordonne les parties par leur zValue
QMultiMap<qreal, QGraphicsItem *> mm;
foreach(QGraphicsItem *qgi, all_items_list) mm.insert(qgi -> zValue(), qgi);
all_items_list.clear();
QMapIterator<qreal, QGraphicsItem *> i(mm);
while (i.hasNext()) {
i.next();
all_items_list << i.value();
}
// rajoute eventuellement les bornes
if (include_terminals) all_items_list += terminals;
return(all_items_list);
}
/**
Supprime les parties de l'element et les objets d'annulations.
Les autres caracteristiques sont conservees.
*/
void ElementScene::reset() {
// supprime les objets d'annulation
undoStack().clear();
// enleve les elements de la scene
foreach (QGraphicsItem *qgi, items()) {
removeItem(qgi);
qgiManager().release(qgi);
}
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -22,10 +22,8 @@
#include "nameslistwidget.h"
#include "orientationsetwidget.h"
#include "qgimanager.h"
#include "elementcontent.h"
class QETElementEditor;
class PartLine;
class PartRectangle;
class PartEllipse;
class PartCircle;
class PartPolygon;
@@ -40,7 +38,7 @@ class ElementScene : public QGraphicsScene {
Q_OBJECT
// enum
enum Behavior { Normal, Line, Rectangle, Circle, Ellipse, Polygon, Text, Terminal, Arc, TextField, PasteArea };
enum Behavior { Normal, Line, Circle, Ellipse, Polygon, Text, Terminal, Arc, TextField };
// constructeurs, destructeur
public:
@@ -51,6 +49,10 @@ 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;
@@ -64,44 +66,22 @@ class ElementScene : public QGraphicsScene {
OrientationSet ori;
/// booleen indiquant si les bornes de l'element peuvent etre reliees a des bornes de ce meme element
bool internal_connections;
/// Chaine contenant les informations complementaires de l'element
QString informations_;
/// Gestionnaire de QGraphicsItem
QGIManager qgi_manager;
/// Pile des actions annulables
QUndoStack undo_stack;
/**
fsi_pos (first selected item pos) : Position du premier item
selectionne : utilise pour annuler les deplacements a la souris ;
egalement utilise pour gerer les deplacements avec les fleches du
clavier.
*/
/// 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 &);
@@ -116,54 +96,24 @@ class ElementScene : public QGraphicsScene {
void setOrientations(const OrientationSet &);
bool internalConnections();
void setInternalConnections(bool);
QString informations() const;
void setInformations(const QString &);
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 const QDomDocument toXml() const;
virtual void fromXml(const QDomDocument &);
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;
bool containsTerminals() const;
QUndoStack &undoStack();
QGIManager &qgiManager();
static bool clipboardMayContainElement();
bool wasCopiedFromThisElement(const QString &);
void cut();
void copy();
void paste();
protected:
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
virtual void keyPressEvent(QKeyEvent *);
virtual void keyReleaseEvent(QKeyEvent *);
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();
@@ -171,7 +121,6 @@ class ElementScene : public QGraphicsScene {
void slot_addArc();
void slot_addTerminal();
void slot_addTextField();
void slot_select(const ElementContent &);
void slot_selectAll();
void slot_deselectAll();
void slot_invertSelection();
@@ -179,7 +128,6 @@ class ElementScene : public QGraphicsScene {
void slot_editSizeHotSpot();
void slot_editNames();
void slot_editOrientations();
void slot_editAuthorInformations();
void slot_bringForward();
void slot_raise();
void slot_lower();
@@ -197,8 +145,6 @@ 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 &);
};
/**
@@ -289,18 +235,4 @@ inline void ElementScene::setInternalConnections(bool ic) {
internal_connections = ic;
}
/**
@return les informations complementaires de cet element
*/
inline QString ElementScene::informations() const {
return(informations_);
}
/**
@param infos les nouvelles informations complementaires de cet element
*/
inline void ElementScene::setInformations(const QString &infos) {
informations_ = infos;
}
#endif

128
editor/elementview.cpp Normal file
View File

@@ -0,0 +1,128 @@
/*
Copyright 2006-2007 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 "elementview.h"
/**
Constructeur
@param scene ElementScene visualisee par cette ElementView
@param parent QWidget parent de cette ElementView
*/
ElementView::ElementView(ElementScene *scene, QWidget *parent) :
QGraphicsView(scene, parent),
scene_(scene)
{
setInteractive(true);
setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
zoomReset();
}
/// Destructeur
ElementView::~ElementView() {
}
/// @return l'ElementScene visualisee par cette ElementView
ElementScene *ElementView::scene() const {
return(scene_);
}
/**
Definit l'ElementScene visualisee par cette ElementView
@param s l'ElementScene visualisee par cette ElementView
*/
void ElementView::setScene(ElementScene *s) {
QGraphicsView::setScene(s);
scene_ = s;
}
/**
Gere les evenements envoyes a la vue.
Methode reimplentee pour gerer le conflit de raccourcis avec Suppr
(supprimer une partie ou supprimer le caractere suivant)
@param e evenement a gerer
*/
bool ElementView::event(QEvent *e) {
if (e -> type() == QEvent::ShortcutOverride && scene_ -> focusItem()) {
e -> accept();
return(true);
}
return(QGraphicsView::event(e));
}
/**
Agrandit le schema (+33% = inverse des -25 % de zoomMoins())
*/
void ElementView::zoomIn() {
scale(4.0/3.0, 4.0/3.0);
}
/**
Retrecit le schema (-25% = inverse des +33 % de zoomPlus())
*/
void ElementView::zoomOut() {
scale(0.75, 0.75);
}
/**
Agrandit ou rectrecit le schema de facon a ce que tous les elements du
schema soient visibles a l'ecran. S'il n'y a aucun element sur le schema,
le zoom est reinitialise
*/
void ElementView::zoomFit() {
adjustSceneRect();
fitInView(sceneRect(), Qt::KeepAspectRatio);
}
/**
Reinitialise le zoom
*/
void ElementView::zoomReset() {
resetMatrix();
scale(4.0, 4.0);
}
/**
Ajuste le sceneRect (zone du schema visualisee par l'ElementView) afin que
celui inclut a la fois les parties dans et en dehors du cadre et le cadre
lui-meme.
*/
void ElementView::adjustSceneRect() {
QRectF old_scene_rect = scene_ -> sceneRect();
QRectF new_scene_rect = scene_ -> sceneContent();
setSceneRect(new_scene_rect);
// met a jour la scene
scene_ -> update(old_scene_rect.united(new_scene_rect));
}
/**
Gere les actions liees a la rollette de la souris
@param e QWheelEvent decrivant l'evenement rollette
*/
void ElementView::wheelEvent(QWheelEvent *e) {
// si la touche Ctrl est enfoncee, on zoome / dezoome
if (e -> modifiers() & Qt::ControlModifier) {
if (e -> delta() > 0) {
zoomIn();
} else {
zoomOut();
}
} else {
QAbstractScrollArea::wheelEvent(e);
}
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -25,8 +25,6 @@
*/
class ElementView : public QGraphicsView {
Q_OBJECT
friend class PastePartsCommand;
// constructeurs, destructeur
public:
ElementView(ElementScene *, QWidget * = 0);
@@ -39,16 +37,9 @@ 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:
@@ -57,23 +48,9 @@ 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

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -16,7 +16,6 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ellipseeditor.h"
#include "styleeditor.h"
#include "partellipse.h"
/**
@@ -25,11 +24,9 @@
@param ellipse L'ellipse a editer
@param parent le Widget parent
*/
EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *ellipse, QWidget *parent) :
ElementItemEditor(editor, parent),
part(ellipse)
{
style_ = new StyleEditor(editor);
EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *ellipse, QWidget *parent) : ElementItemEditor(editor, parent) {
part = ellipse;
x = new QLineEdit();
y = new QLineEdit();
@@ -41,11 +38,9 @@ EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *ellipse, QWi
h -> setValidator(new QDoubleValidator(h));
v -> setValidator(new QDoubleValidator(v));
QVBoxLayout *v_layout = new QVBoxLayout(this);
QGridLayout *grid = new QGridLayout();
QGridLayout *grid = new QGridLayout(this);
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
grid -> addWidget(new QLabel("x"), 1, 0, Qt::AlignRight);
grid -> addWidget(new QLabel("x"), 1, 0);
grid -> addWidget(x, 1, 1);
grid -> addWidget(new QLabel("y"), 1, 2);
grid -> addWidget(y, 1, 3);
@@ -55,9 +50,6 @@ EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *ellipse, QWi
grid -> addWidget(new QLabel(tr("vertical :")), 4, 0);
grid -> addWidget(v, 4, 1);
v_layout -> addWidget(style_);
v_layout -> addLayout(grid);
activeConnections(true);
updateForm();
}
@@ -66,46 +58,14 @@ EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *ellipse, QWi
EllipseEditor::~EllipseEditor() {
}
/**
Permet de specifier a cet editeur quelle primitive il doit editer. A noter
qu'un editeur peut accepter ou refuser d'editer une primitive.
L'editeur d'ellipse acceptera d'editer la primitive new_part s'il s'agit
d'un objet de la classe PartEllipse.
@param new_part Nouvelle primitive a editer
@return true si l'editeur a accepter d'editer la primitive, false sinon
*/
bool EllipseEditor::setPart(CustomElementPart *new_part) {
if (!new_part) {
part = 0;
style_ -> setPart(0);
return(true);
}
if (PartEllipse *part_ellipse = dynamic_cast<PartEllipse *>(new_part)) {
part = part_ellipse;
style_ -> setPart(part);
updateForm();
return(true);
} else {
return(false);
}
}
/**
@return la primitive actuellement editee, ou 0 si ce widget n'en edite pas
*/
CustomElementPart *EllipseEditor::currentPart() const {
return(part);
}
/**
Met a jour l'ellipse a partir des donnees du formulaire
*/
void EllipseEditor::updateEllipse() {
if (!part) return;
part -> setProperty("x", x -> text().toDouble());
part -> setProperty("y", y -> text().toDouble());
part -> setProperty("diameter_h", h -> text().toDouble());
part -> setProperty("diameter_v", v -> text().toDouble());
part -> setProperty("y", x -> text().toDouble());
part -> setProperty("diameter_h", x -> text().toDouble());
part -> setProperty("diameter_v", x -> text().toDouble());
}
/// Met a jour l'abscisse du centre de l'ellipse et cree un objet d'annulation
@@ -121,7 +81,6 @@ void EllipseEditor::updateEllipseV() { addChangePartCommand(tr("diam\350tre vert
Met a jour le formulaire d'edition
*/
void EllipseEditor::updateForm() {
if (!part) return;
activeConnections(false);
x -> setText(part -> property("x").toString());
y -> setText(part -> property("y").toString());

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -20,7 +20,6 @@
#include <QtGui>
#include "elementitemeditor.h"
class PartEllipse;
class StyleEditor;
/**
Cette classe represente le widget d'edition d'une ellipse dans l'editeur
d'element.
@@ -29,22 +28,17 @@ class EllipseEditor : public ElementItemEditor {
Q_OBJECT
//constructeurs, destructeur
public:
EllipseEditor(QETElementEditor *, PartEllipse * = 0, QWidget * = 0);
virtual ~EllipseEditor();
EllipseEditor(QETElementEditor *, PartEllipse *, QWidget * = 0);
~EllipseEditor();
private:
EllipseEditor(const EllipseEditor &);
// attributs
private:
PartEllipse *part;
StyleEditor *style_;
QLineEdit *x, *y, *h, *v;
// methodes
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
public slots:
void updateEllipse();
void updateEllipseX();

115
editor/lineeditor.cpp Normal file
View File

@@ -0,0 +1,115 @@
/*
Copyright 2006-2007 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 "lineeditor.h"
#include "partline.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param line La ligne a editer
@param parent le Widget parent
*/
LineEditor::LineEditor(QETElementEditor *editor, PartLine *line, QWidget *parent) : ElementItemEditor(editor, parent) {
part = line;
x1 = new QLineEdit();
y1 = new QLineEdit();
x2 = new QLineEdit();
y2 = new QLineEdit();
x1 -> setValidator(new QDoubleValidator(x1));
y1 -> setValidator(new QDoubleValidator(y1));
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);
updateForm();
}
/// Destructeur
LineEditor::~LineEditor() {
}
/**
Met a jour la ligne a partir des donnees du formulaire
*/
void LineEditor::updateLine() {
part -> setLine(
QLineF(
part -> mapFromScene(
x1 -> text().toDouble(),
y1 -> text().toDouble()
),
part -> mapFromScene(
x2 -> text().toDouble(),
y2 -> text().toDouble()
)
)
);
}
/// Met a jour l'abscisse du premier point de la ligne et cree un objet d'annulation
void LineEditor::updateLineX1() { addChangePartCommand(tr("abscisse point 1"), part, "x1", x1 -> text().toDouble()); }
/// Met a jour l'ordonnee du premier point de la ligne et cree un objet d'annulation
void LineEditor::updateLineY1() { addChangePartCommand(tr("ordonn\351e point 1"), part, "y1", y1 -> text().toDouble()); }
/// Met a jour l'abscisse du second point de la ligne et cree un objet d'annulation
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 formulaire d'edition
*/
void LineEditor::updateForm() {
activeConnections(false);
QPointF p1(part -> sceneP1());
QPointF p2(part -> sceneP2());
x1 -> setText(QString("%1").arg(p1.x()));
y1 -> setText(QString("%1").arg(p1.y()));
x2 -> setText(QString("%1").arg(p2.x()));
y2 -> setText(QString("%1").arg(p2.y()));
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 LineEditor::activeConnections(bool active) {
if (active) {
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()));
} 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()));
}
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -20,7 +20,6 @@
#include <QtGui>
#include "elementitemeditor.h"
class PartLine;
class StyleEditor;
/**
Cette classe represente le widget d'edition d'une ligne dans l'editeur
d'element.
@@ -29,34 +28,23 @@ class LineEditor : public ElementItemEditor {
Q_OBJECT
//constructeurs, destructeur
public:
LineEditor(QETElementEditor *, PartLine * = 0, QWidget * = 0);
virtual ~LineEditor();
LineEditor(QETElementEditor *, PartLine *, QWidget * = 0);
~LineEditor();
private:
LineEditor(const LineEditor &);
// attributs
private:
PartLine *part;
StyleEditor *style_;
QLineEdit *x1, *y1, *x2, *y2;
QComboBox *end1_type, *end2_type;
QLineEdit *end1_length, *end2_length;
// methodes
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
public slots:
void updateLine();
void updateLineX1();
void updateLineY1();
void updateLineX2();
void updateLineY2();
void updateLineEndType1();
void updateLineEndLength1();
void updateLineEndType2();
void updateLineEndLength2();
void updateForm();
private:

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -16,6 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "partarc.h"
#include "arceditor.h"
/**
Constructeur
@@ -30,10 +31,11 @@ PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene
start_angle(0)
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
#endif
setAcceptedMouseButtons(Qt::LeftButton);
informations = new ArcEditor(elementEditor(), this);
informations -> setElementTypeName(name());
style_editor -> appendWidget(informations);
style_editor -> setElementTypeName(name());
}
/// Destructeur
@@ -46,15 +48,11 @@ PartArc::~PartArc() {
@param options Options pour affiner le rendu
@param widget Widget sur lequel le rendu est effectue
*/
void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
Q_UNUSED(widget);
void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
// enleve systematiquement la couleur de fond
painter -> setBrush(Qt::NoBrush);
QPen t = painter -> pen();
t.setCosmetic(options && options -> levelOfDetail < 1.0);
painter -> setPen(t);
if (isSelected()) {
// dessine l'ellipse en noir
painter -> drawEllipse(rect());
@@ -63,7 +61,6 @@ void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options,
t.setColor(Qt::red);
painter -> setPen(t);
}
painter -> drawArc(rect(), start_angle * 16, _angle * 16);
if (isSelected()) {
// dessine la croix au centre de l'ellipse
@@ -83,12 +80,12 @@ void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options,
const QDomElement PartArc::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("arc");
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()));
xml_element.setAttribute("start", QString("%1").arg(start_angle));
xml_element.setAttribute("angle", QString("%1").arg(_angle));
xml_element.setAttribute("x", top_left.x());
xml_element.setAttribute("y", top_left.y());
xml_element.setAttribute("width", rect().width());
xml_element.setAttribute("height", rect().height());
xml_element.setAttribute("start", start_angle);
xml_element.setAttribute("angle", _angle);
stylesToXml(xml_element);
return(xml_element);
}
@@ -162,7 +159,6 @@ void PartArc::setProperty(const QString &property, const QVariant &value) {
} else if (property == "angle") {
setAngle(value.toInt());
}
update();
}
/**
@@ -204,8 +200,8 @@ QVariant PartArc::property(const QString &property) {
*/
QVariant PartArc::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
updateCurrentPartEditor();
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsEllipseItem::itemChange(change, value));

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,6 +19,7 @@
#define PART_ARC_H
#include <QtGui>
#include "customelementgraphicpart.h"
class ArcEditor;
/**
Cette classe represente un arc pouvant etre utilise pour composer le
dessin d'un element dans l'editeur d'element.
@@ -34,6 +35,7 @@ class PartArc : public QGraphicsEllipseItem, public CustomElementGraphicPart {
// attributs
private:
ArcEditor *informations;
int _angle;
int start_angle;
@@ -46,8 +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", "element part name")); }
virtual QString xmlName() const { return(QString("arc")); }
virtual QString name() const { return(QObject::tr("arc")); }
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneTopLeft() const;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -16,6 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "partcircle.h"
#include "circleeditor.h"
/**
Constructeur
@@ -25,10 +26,11 @@
*/
PartCircle::PartCircle(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsEllipseItem(parent, scene), CustomElementGraphicPart(editor) {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
#endif
setAcceptedMouseButtons(Qt::LeftButton);
informations = new CircleEditor(elementEditor(), this);
informations -> setElementTypeName(name());
style_editor -> appendWidget(informations);
style_editor -> setElementTypeName(name());
}
/// Destructeur
@@ -41,15 +43,13 @@ PartCircle::~PartCircle() {
@param options Options pour affiner le rendu
@param widget Widget sur lequel le rendu est effectue
*/
void PartCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
Q_UNUSED(widget);
void PartCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
t.setCosmetic(options && options -> levelOfDetail < 1.0);
if (isSelected()) {
t.setColor(Qt::red);
}
painter -> setPen(t);
}
painter -> drawEllipse(rect());
if (isSelected()) {
painter -> setRenderHint(QPainter::Antialiasing, false);
@@ -68,9 +68,9 @@ void PartCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
const QDomElement PartCircle::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("circle");
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("diameter", QString("%1").arg(rect().width()));
xml_element.setAttribute("x", top_left.x());
xml_element.setAttribute("y", top_left.y());
xml_element.setAttribute("diameter", rect().width());
stylesToXml(xml_element);
return(xml_element);
}
@@ -125,7 +125,6 @@ void PartCircle::setProperty(const QString &property, const QVariant &value) {
current_rect.setSize(QSizeF(new_diameter, new_diameter));
setRect(current_rect);
}
update();
}
/**
@@ -158,8 +157,8 @@ QVariant PartCircle::property(const QString &property) {
*/
QVariant PartCircle::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
updateCurrentPartEditor();
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsEllipseItem::itemChange(change, value));

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,6 +19,7 @@
#define PART_CIRCLE_H
#include <QtGui>
#include "customelementgraphicpart.h"
class CircleEditor;
/**
Cette classe represente un cercle pouvant etre utilise pour composer le
dessin d'un element dans l'editeur d'element.
@@ -32,6 +33,10 @@ class PartCircle : public QGraphicsEllipseItem, public CustomElementGraphicPart
private:
PartCircle(const PartCircle &);
// attributs
private:
CircleEditor *informations;
// methodes
public:
enum { Type = UserType + 1102 };
@@ -41,8 +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", "element part name")); }
virtual QString xmlName() const { return(QString("circle")); }
virtual QString name() const { return(QObject::tr("cercle")); }
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneTopLeft() const;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -16,6 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "partellipse.h"
#include "ellipseeditor.h"
/**
Constructeur
@@ -25,10 +26,11 @@
*/
PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsEllipseItem(parent, scene), CustomElementGraphicPart(editor) {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
#endif
setAcceptedMouseButtons(Qt::LeftButton);
informations = new EllipseEditor(elementEditor(), this);
informations -> setElementTypeName(name());
style_editor -> appendWidget(informations);
style_editor -> setElementTypeName(name());
}
/// Destructeur
@@ -41,15 +43,13 @@ PartEllipse::~PartEllipse() {
@param options Options pour affiner le rendu
@param widget Widget sur lequel le rendu est effectue
*/
void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
Q_UNUSED(widget);
void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
t.setCosmetic(options && options -> levelOfDetail < 1.0);
if (isSelected()) {
t.setColor(Qt::red);
}
painter -> setPen(t);
}
painter -> drawEllipse(rect());
if (isSelected()) {
painter -> setRenderHint(QPainter::Antialiasing, false);
@@ -68,10 +68,10 @@ void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("ellipse");
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()));
xml_element.setAttribute("x", top_left.x());
xml_element.setAttribute("y", top_left.y());
xml_element.setAttribute("width", rect().width());
xml_element.setAttribute("height", rect().height());
stylesToXml(xml_element);
return(xml_element);
}
@@ -129,7 +129,6 @@ void PartEllipse::setProperty(const QString &property, const QVariant &value) {
current_rect.setHeight(new_height);
setRect(current_rect);
}
update();
}
/**
@@ -165,8 +164,8 @@ QVariant PartEllipse::property(const QString &property) {
*/
QVariant PartEllipse::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
updateCurrentPartEditor();
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsEllipseItem::itemChange(change, value));

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,6 +19,7 @@
#define PART_ELLIPSE_H
#include <QtGui>
#include "customelementgraphicpart.h"
class EllipseEditor;
/**
Cette classe represente une ellipse pouvant etre utilisee pour composer le
dessin d'un element dans l'editeur d'element.
@@ -32,6 +33,10 @@ class PartEllipse : public QGraphicsEllipseItem, public CustomElementGraphicPart
private:
PartEllipse(const PartEllipse &);
// attributs
private:
EllipseEditor *informations;
// methodes
public:
enum { Type = UserType + 1103 };
@@ -41,8 +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", "element part name")); }
virtual QString xmlName() const { return(QString("ellipse")); }
virtual QString name() const { return(QObject::tr("ellipse")); }
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneTopLeft() const;

253
editor/partline.cpp Normal file
View File

@@ -0,0 +1,253 @@
/*
Copyright 2006-2007 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 "partline.h"
#include "lineeditor.h"
#include <cmath>
/**
Constructeur
@param editor L'editeur d'element concerne
@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) {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptedMouseButtons(Qt::LeftButton);
informations = new LineEditor(elementEditor(), this);
informations -> setElementTypeName(name());
style_editor -> appendWidget(informations);
style_editor -> setElementTypeName(name());
}
/// Destructeur
PartLine::~PartLine() {
}
/**
Dessine la ligne
@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 PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem */*q*/, QWidget */*w*/) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
if (isSelected()) {
t.setColor(Qt::red);
painter -> setPen(t);
}
painter -> setBrush(Qt::NoBrush);
painter -> drawLine(line());
}
/**
Exporte la ligne en XML
@param xml_document Document XML a utiliser pour creer l'element XML
@return un element XML decrivant la ligne
*/
const QDomElement PartLine::toXml(QDomDocument &xml_document) const {
QPointF p1(sceneP1());
QPointF p2(sceneP2());
QDomElement xml_element = xml_document.createElement("line");
xml_element.setAttribute("x1", p1.x());
xml_element.setAttribute("y1", p1.y());
xml_element.setAttribute("x2", p2.x());
xml_element.setAttribute("y2", p2.y());
stylesToXml(xml_element);
return(xml_element);
}
/**
Importe les proprietes d'une ligne depuis un element XML
@param qde Element XML a lire
*/
void PartLine::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
setLine(
QLineF(
mapFromScene(
qde.attribute("x1", "0").toDouble(),
qde.attribute("y1", "0").toDouble()
),
mapFromScene(
qde.attribute("x2", "0").toDouble(),
qde.attribute("y2", "0").toDouble()
)
)
);
}
/**
Specifie la valeur d'une propriete donnee de la ligne
@param property propriete a modifier. Valeurs acceptees :
* x1 : abscisse du premier point
* y1 : ordonnee du second point
* x2 : abscisse du premier point
* y2 : ordonnee du second point
@param value Valeur a attribuer a la propriete
*/
void PartLine::setProperty(const QString &property, const QVariant &value) {
CustomElementGraphicPart::setProperty(property, value);
if (!value.canConvert(QVariant::Double)) return;
QPointF new_p1(sceneP1()), new_p2(sceneP2());
bool setline = true;
if (property == "x1") {
new_p1.setX(value.toDouble());
} else if (property == "y1") {
new_p1.setY(value.toDouble());
} else if (property == "x2") {
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)));
}
/**
Permet d'acceder a la valeur d'une propriete donnee de la ligne
@param property propriete lue. Valeurs acceptees :
* x1 : abscisse du premier point
* y1 : ordonnee du second point
* x2 : abscisse du premier point
* y2 : ordonnee du second point
@return La valeur de la propriete property
*/
QVariant PartLine::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 == "x1") {
return(sceneP1().x());
} else if (property == "y1") {
return(sceneP1().y());
} else if (property == "x2") {
return(sceneP2().x());
} else if (property == "y2") {
return(sceneP2().y());
}
return(QVariant());
}
/**
Gere les changements intervenant sur cette partie
@param change Type de changement
@param value Valeur numerique relative au changement
*/
QVariant PartLine::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsLineItem::itemChange(change, value));
}
/**
@return le premier point, dans les coordonnees de la scene.
*/
QPointF PartLine::sceneP1() const {
return(mapToScene(line().p1()));
}
/**
@return le second point, dans les coordonnees de la scene.
*/
QPointF PartLine::sceneP2() const {
return(mapToScene(line().p2()));
}
/**
@return la forme selectionnable de la ligne
*/
QPainterPath PartLine::shape() const {
QList<QPointF> points = fourShapePoints();
QPainterPath t;
t.setFillRule(Qt::WindingFill);
t.moveTo(points.at(0));
t.lineTo(points.at(1));
t.lineTo(points.at(2));
t.lineTo(points.at(3));
t.lineTo(points.at(0));
return(t);
}
/**
@return une liste contenant les deux points de la droite + les 4 points entourant ces deux points
*/
QList<QPointF> PartLine::fourShapePoints() const {
const qreal marge = 2.0;
// on a donc A(xa , ya) et B(xb, yb)
QPointF a = line().p1();
QPointF b = line().p2();
QList<QPointF> result;
// cas particulier : la droite se ramene a un point
if (a == b) {
result << QPointF(a.x() - marge, a.y() - marge);
result << QPointF(a.x() - marge, a.y() + marge);
result << QPointF(a.x() + marge, a.y() + marge);
result << QPointF(a.x() + marge, a.y() - marge);
} else {
// on calcule le vecteur AB : (xb-xa, yb-ya)
QPointF v_ab = b - a;
// et la distance AB : racine des coordonnees du vecteur au carre
qreal ab = sqrt(pow(v_ab.x(), 2) + pow(v_ab.y(), 2));
// ensuite on definit le vecteur u(a, b) qui est egal au vecteur AB divise
// par sa longueur et multiplie par la longueur de la marge que tu veux
// laisser
QPointF u = v_ab / ab * marge;
// on definit le vecteur v(-b , a) qui est perpendiculaire a AB
QPointF v(-u.y(), u.x());
QPointF m = -u + v; // on a le vecteur M = -u + v
QPointF n = -u - v; // et le vecteur N=-u-v
QPointF h = a + m; // H = A + M
QPointF k = a + n; // K = A + N
QPointF i = b - n; // I = B - N
QPointF j = b - m; // J = B - M
result << h << i << j << k;
}
return(result);
}
/**
@return le rectangle delimitant cette partie.
*/
QRectF PartLine::boundingRect() const {
qreal adjust = 1.5;
QRectF r(QGraphicsLineItem::boundingRect());
r.adjust(-adjust, -adjust, adjust, adjust);
return(r);
}
/**
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
conservee / enregistree.
Une ligne est pertinente des lors que ses deux points sont differents
*/
bool PartLine::isUseless() const {
return(sceneP1() == sceneP2());
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -15,37 +15,43 @@
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
#ifndef PART_LINE_H
#define PART_LINE_H
#include <QtGui>
#include "customelementgraphicpart.h"
class LineEditor;
/**
Cette classe represente un rectangle pouvant etre utilise pour composer le
Cette classe represente une ligne pouvant etre utilisee pour composer le
dessin d'un element dans l'editeur d'element.
*/
class PartRectangle : public QGraphicsRectItem, public CustomElementGraphicPart {
class PartLine : public QGraphicsLineItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartRectangle(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartRectangle();
PartLine(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartLine();
private:
PartRectangle(const PartRectangle &);
PartLine(const PartLine &);
// attributs
private:
LineEditor *informations;
// methodes
public:
enum { Type = UserType + 1109 };
enum { Type = UserType + 1104 };
/**
permet de caster un QGraphicsItem en PartRectangle avec qgraphicsitem_cast
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("rectangle", "element part name")); }
virtual QString xmlName() const { return(QString("rect")); }
virtual QString name() const { return(QObject::tr("ligne")); }
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneTopLeft() const;
virtual QPointF sceneP1() const;
virtual QPointF sceneP2() const;
virtual QPainterPath shape() const;
virtual QRectF boundingRect() const;
virtual void setProperty(const QString &, const QVariant &);
virtual QVariant property(const QString &);
@@ -53,5 +59,8 @@ class PartRectangle : public QGraphicsRectItem, public CustomElementGraphicPart
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
private:
QList<QPointF> fourShapePoints() const;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -17,6 +17,7 @@
*/
#include "partpolygon.h"
#include "qet.h"
#include "polygoneditor.h"
/**
Constructeur
@@ -30,10 +31,11 @@ PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent, QGraph
closed(false)
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
#endif
setAcceptedMouseButtons(Qt::LeftButton);
informations = new PolygonEditor(elementEditor(), this);
informations -> setElementTypeName(name());
style_editor -> appendWidget(informations);
style_editor -> setElementTypeName(name());
}
/// Destructeur
@@ -92,13 +94,13 @@ const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const {
@param options Options pour affiner le rendu
@param widget Widget sur lequel le rendu est effectue
*/
void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
Q_UNUSED(widget);
void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
t.setCosmetic(options && options -> levelOfDetail < 1.0);
if (isSelected()) t.setColor(Qt::red);
if (isSelected()) {
t.setColor(Qt::red);
painter -> setPen(t);
}
if (closed) painter -> drawPolygon(polygon());
else painter -> drawPolyline(polygon());
}
@@ -112,7 +114,6 @@ void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
void PartPolygon::setProperty(const QString &property, const QVariant &value) {
CustomElementGraphicPart::setProperty(property, value);
if (property == "closed") closed = value.toBool();
update();
}
/**
@@ -137,8 +138,8 @@ QVariant PartPolygon::property(const QString &property) {
*/
QVariant PartPolygon::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
updateCurrentPartEditor();
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsPolygonItem::itemChange(change, value));

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,6 +19,7 @@
#define PART_POLYGON_H
#include <QtGui>
#include "customelementgraphicpart.h"
class PolygonEditor;
/**
Cette classe represente un polygone pouvant etre utilise pour composer le
dessin d'un element dans l'editeur d'element.
@@ -35,7 +36,20 @@ class PartPolygon : public QGraphicsPolygonItem, public CustomElementGraphicPart
// attributs
private:
bool closed;
PolygonEditor *informations;
/**
constructeur
paint()
widget bidon pour l'edition
methode pour poser le polygone :
-mousePressEvent = pose un nouveau point
-mouseMoveEvent = deplace ce point
-mouveReleaseEvent = finalise ce point
utiliser QPolygonF ; memoriser le point en cours (tout comme le
partploygon en cours) et ne l'ajouter au qpolygonf que lors du
mouseReleaseEvent
*/
// methodes
public:
enum { Type = UserType + 1105 };
@@ -44,8 +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", "element part name")); }
virtual QString xmlName() const { return(QString("polygon")); }
virtual QString name() const { return(QObject::tr("polygone")); }
void fromXml(const QDomElement &);
const QDomElement toXml(QDomDocument &) const;
virtual QRectF boundingRect() const;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -17,6 +17,7 @@
*/
#include "partterminal.h"
#include "terminal.h"
#include "terminaleditor.h"
/**
Constructeur
@@ -29,17 +30,17 @@ PartTerminal::PartTerminal(QETElementEditor *editor, QGraphicsItem *parent, QGra
QGraphicsItem(parent, scene),
_orientation(QET::North)
{
informations = new TerminalEditor(elementEditor(), this);
informations -> setElementTypeName(name());
updateSecondPoint();
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
#endif
setZValue(100000);
}
/// Destructeur
PartTerminal::~PartTerminal() {
}
delete informations;
};
/**
Importe les proprietes d'une borne depuis un element XML
@@ -75,14 +76,20 @@ const QDomElement PartTerminal::toXml(QDomDocument &xml_document) const {
return(xml_element);
}
/**
@return Le widget permettant d'editer cette borne
*/
QWidget *PartTerminal::elementInformations() {
return(informations);
}
/**
Dessine la borne
@param p QPainter a utiliser pour rendre le dessin
@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 PartTerminal::paint(QPainter *p, const QStyleOptionGraphicsItem *options, QWidget *widget) {
Q_UNUSED(widget);
void PartTerminal::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) {
p -> save();
// annulation des renderhints
@@ -92,7 +99,6 @@ void PartTerminal::paint(QPainter *p, const QStyleOptionGraphicsItem *options, Q
QPen t;
t.setWidthF(1.0);
t.setCosmetic(options && options -> levelOfDetail < 1.0);
// dessin de la borne en rouge
t.setColor(isSelected() ? Terminal::couleur_neutre : Qt::red);
@@ -140,6 +146,7 @@ void PartTerminal::setOrientation(QET::Orientation ori) {
prepareGeometryChange();
_orientation = ori;
updateSecondPoint();
informations -> updateForm();
}
/**
@@ -189,8 +196,8 @@ QVariant PartTerminal::property(const QString &property) {
*/
QVariant PartTerminal::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
updateCurrentPartEditor();
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsItem::itemChange(change, value));

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -20,6 +20,8 @@
#include "customelementpart.h"
#include "qet.h"
#include <QtGui>
class TerminalEditor;
class QETElementEditor;
/**
Cette classe represente une borne pouvant etre utilisee pour composer le
dessin d'un element dans l'editeur d'element.
@@ -36,6 +38,7 @@ class PartTerminal : public CustomElementPart, public QGraphicsItem {
private:
QET::Orientation _orientation;
QPointF second_point;
TerminalEditor *informations;
// methodes
public:
@@ -45,10 +48,10 @@ 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", "element part name")); }
virtual QString xmlName() const { return(QString("terminal")); }
virtual QString name() const { return(QObject::tr("borne")); }
virtual void fromXml(const QDomElement &);
virtual const QDomElement toXml(QDomDocument &) const;
virtual QWidget *elementInformations();
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
virtual QRectF boundingRect() const;
QET::Orientation orientation() const;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -32,16 +32,16 @@ PartText::PartText(QETElementEditor *editor, QGraphicsItem *parent, ElementScene
CustomElementPart(editor)
{
setDefaultTextColor(Qt::black);
setFont(QETApp::diagramTextsFont());
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
#endif
setPlainText(QObject::tr("T", "default text when adding a text in the element editor"));
setPlainText(QObject::tr("T"));
infos = new TextEditor(elementEditor(), this);
infos -> setElementTypeName(name());
}
/// Destructeur
PartText::~PartText() {
delete infos;
}
/**
@@ -53,7 +53,7 @@ void PartText::fromXml(const QDomElement &xml_element) {
int font_size = xml_element.attribute("size").toInt(&ok);
if (!ok || font_size < 1) font_size = 20;
setFont(QETApp::diagramTextsFont(font_size));
setFont(QFont(QString(QETApp::diagramTextsFont()), font_size));
setPlainText(xml_element.attribute("text"));
setPos(
xml_element.attribute("x").toDouble(),
@@ -75,6 +75,13 @@ const QDomElement PartText::toXml(QDomDocument &xml_document) const {
return(xml_element);
}
/**
@return Le widget permettant d'editer ce texte statique
*/
QWidget *PartText::elementInformations() {
return(infos);
}
/**
Retourne la position du texte, l'origine etant le point en bas a gauche du
texte (et pas du cadre)
@@ -123,7 +130,7 @@ void PartText::focusOutEvent(QFocusEvent *e) {
if (previous_text != toPlainText()) {
undoStack().push(
new ChangePartCommand(
TextEditor::tr("contenu") + " " + name(),
TextEditor::tr("texte") + " " + name(),
this,
"text",
previous_text,
@@ -132,14 +139,7 @@ void PartText::focusOutEvent(QFocusEvent *e) {
);
previous_text = toPlainText();
}
// deselectionne le texte
QTextCursor qtc = textCursor();
qtc.clearSelection();
setTextCursor(qtc);
setTextInteractionFlags(Qt::NoTextInteraction);
setFlag(QGraphicsItem::ItemIsFocusable, false);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
}
/**
@@ -147,7 +147,7 @@ void PartText::focusOutEvent(QFocusEvent *e) {
@param e Le QGraphicsSceneMouseEvent qui decrit le double-clic
*/
void PartText::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) {
setFlag(QGraphicsItem::ItemIsFocusable, true);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
setTextInteractionFlags(Qt::TextEditorInteraction);
previous_text = toPlainText();
QGraphicsTextItem::mouseDoubleClickEvent(e);
@@ -172,11 +172,10 @@ void PartText::setProperty(const QString &property, const QVariant &value) {
setPos(pos().x(), value.toDouble());
} else if (property == "size") {
if (!value.canConvert(QVariant::Int)) return;
setFont(QETApp::diagramTextsFont(value.toInt()));
setFont(QFont(font().family(), value.toInt()));
} else if (property == "text") {
setPlainText(value.toString());
}
update();
}
/**
@@ -209,7 +208,7 @@ QVariant PartText::property(const QString &property) {
QVariant PartText::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
updateCurrentPartEditor();
infos -> updateForm();
}
}
return(QGraphicsTextItem::itemChange(change, value));

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -33,6 +33,9 @@ class PartText : public QGraphicsTextItem, public CustomElementPart {
private:
PartText(const PartText &);
// attributs
TextEditor *infos;
// methodes
public:
enum { Type = UserType + 1107 };
@@ -41,10 +44,10 @@ 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", "element part name")); }
virtual QString xmlName() const { return(QString("text")); }
virtual QString name() const { return(QObject::tr("texte")); }
void fromXml(const QDomElement &);
const QDomElement toXml(QDomDocument &) const;
QWidget *elementInformations();
QPointF pos() const;
void setPos(const QPointF &);
void setPos(qreal, qreal);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -32,16 +32,15 @@ PartTextField::PartTextField(QETElementEditor *editor, QGraphicsItem *parent, QG
follow_parent_rotations(true)
{
setDefaultTextColor(Qt::black);
setFont(QETApp::diagramTextsFont());
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
#endif
setPlainText(QObject::tr("_", "default text when adding a textfield in the element editor"));
setPlainText(QObject::tr("_"));
infos = new TextFieldEditor(elementEditor(), this);
infos -> setElementTypeName(name());
}
/// Destructeur
PartTextField::~PartTextField() {
delete infos;
}
/**
@@ -53,7 +52,7 @@ void PartTextField::fromXml(const QDomElement &xml_element) {
int font_size = xml_element.attribute("size").toInt(&ok);
if (!ok || font_size < 1) font_size = 20;
setFont(QETApp::diagramTextsFont(font_size));
setFont(QFont(QString(QETApp::diagramTextsFont()), font_size));
setPlainText(xml_element.attribute("text"));
setPos(
xml_element.attribute("x").toDouble(),
@@ -78,6 +77,13 @@ const QDomElement PartTextField::toXml(QDomDocument &xml_document) const {
return(xml_element);
}
/**
@return Le widget permettant d'editer ce champ de texte
*/
QWidget *PartTextField::elementInformations() {
return(infos);
}
/**
Retourne la position du texte, l'origine etant le point en bas a gauche du
texte (et pas du cadre)
@@ -142,7 +148,7 @@ void PartTextField::focusOutEvent(QFocusEvent *e) {
if (previous_text != toPlainText()) {
undoStack().push(
new ChangePartCommand(
TextFieldEditor::tr("contenu") + " " + name(),
TextFieldEditor::tr("texte") + " " + name(),
this,
"text",
previous_text,
@@ -151,14 +157,7 @@ void PartTextField::focusOutEvent(QFocusEvent *e) {
);
previous_text = toPlainText();
}
// deselectionne le texte
QTextCursor qtc = textCursor();
qtc.clearSelection();
setTextCursor(qtc);
setTextInteractionFlags(Qt::NoTextInteraction);
setFlag(QGraphicsItem::ItemIsFocusable, false);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
}
/**
@@ -166,7 +165,7 @@ void PartTextField::focusOutEvent(QFocusEvent *e) {
@param e Le QGraphicsSceneMouseEvent qui decrit le double-clic
*/
void PartTextField::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) {
setFlag(QGraphicsItem::ItemIsFocusable, true);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
setTextInteractionFlags(Qt::TextEditorInteraction);
previous_text = toPlainText();
QGraphicsTextItem::mouseDoubleClickEvent(e);
@@ -192,13 +191,12 @@ void PartTextField::setProperty(const QString &property, const QVariant &value)
setPos(pos().x(), value.toDouble());
} else if (property == "size") {
if (!value.canConvert(QVariant::Int)) return;
setFont(QETApp::diagramTextsFont(value.toInt()));
setFont(QFont(font().family(), value.toInt()));
} else if (property == "text") {
setPlainText(value.toString());
} else if (property == "rotate") {
follow_parent_rotations = value.toBool();
}
update();
}
/**
@@ -234,7 +232,7 @@ QVariant PartTextField::property(const QString &property) {
QVariant PartTextField::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
updateCurrentPartEditor();
infos -> updateForm();
}
}
return(QGraphicsTextItem::itemChange(change, value));

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -37,6 +37,7 @@ class PartTextField : public QGraphicsTextItem, public CustomElementPart {
PartTextField(const PartTextField &);
// attributs
TextFieldEditor *infos;
bool follow_parent_rotations;
// methodes
@@ -47,10 +48,10 @@ 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", "element part name")); }
virtual QString xmlName() const { return(QString("input")); }
virtual QString name() const { return(QObject::tr("champ de texte")); }
void fromXml(const QDomElement &);
const QDomElement toXml(QDomDocument &) const;
QWidget *elementInformations();
QPointF pos() const;
void setPos(const QPointF &);
void setPos(qreal, qreal);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,7 +19,6 @@
#include "partpolygon.h"
#include "elementscene.h"
#include "editorcommands.h"
#include "qetmessagebox.h"
/**
Constructeur
@@ -29,12 +28,10 @@
*/
PolygonEditor::PolygonEditor(QETElementEditor *editor, PartPolygon *p, QWidget *parent) :
ElementItemEditor(editor, parent),
part(p),
points_list(this),
close_polygon(tr("Polygone ferm\351"), this)
{
style_ = new StyleEditor(editor);
part = p;
// prepare la liste de points
points_list.setColumnCount(2);
QStringList headers;
@@ -45,7 +42,6 @@ PolygonEditor::PolygonEditor(QETElementEditor *editor, PartPolygon *p, QWidget *
// layout
QVBoxLayout *layout = new QVBoxLayout(this);
layout -> addWidget(style_);
layout -> addWidget(new QLabel(tr("Points du polygone :")));
layout -> addWidget(&points_list);
layout -> addWidget(&close_polygon);
@@ -69,13 +65,12 @@ void PolygonEditor::updatePolygon() {
Met a jour les points du polygone et cree un objet d'annulation
*/
void PolygonEditor::updatePolygonPoints() {
if (!part) return;
QVector<QPointF> points = getPointsFromTree();
if (points.count() < 2) {
QET::MessageBox::warning(
QMessageBox::warning(
this,
tr("Erreur", "message box title"),
tr("Le polygone doit comporter au moins deux points.", "message box content")
tr("Erreur"),
tr("Le polygone doit comporter au moins deux points.")
);
return;
}
@@ -86,7 +81,6 @@ void PolygonEditor::updatePolygonPoints() {
Met a jour l'etat ferme ou non du polygone
*/
void PolygonEditor::updatePolygonClosedState() {
if (!part) return;
undoStack().push(
new ChangePartCommand(
tr("fermeture du polygone"),
@@ -102,9 +96,8 @@ void PolygonEditor::updatePolygonClosedState() {
Met a jour le formulaire d'edition
*/
void PolygonEditor::updateForm() {
if (!part) return;
activeConnections(false);
while(points_list.takeTopLevelItem(0)) {}
while(points_list.takeTopLevelItem(0));
foreach(QPointF point, part -> polygon()) {
point = part -> mapToScene(point);
QStringList qsl;
@@ -117,43 +110,11 @@ void PolygonEditor::updateForm() {
activeConnections(true);
}
/**
Permet de specifier a cet editeur quelle primitive il doit editer. A noter
qu'un editeur peut accepter ou refuser d'editer une primitive.
L'editeur de polygone acceptera d'editer la primitive new_part s'il s'agit
d'un objet de la classe PartPolygon.
@param new_part Nouvelle primitive a editer
@return true si l'editeur a accepter d'editer la primitive, false sinon
*/
bool PolygonEditor::setPart(CustomElementPart *new_part) {
if (!new_part) {
part = 0;
style_ -> setPart(0);
return(true);
}
if (PartPolygon *part_polygon = dynamic_cast<PartPolygon *>(new_part)) {
part = part_polygon;
style_ -> setPart(part);
updateForm();
return(true);
} else {
return(false);
}
}
/**
@return la primitive actuellement editee, ou 0 si ce widget n'en edite pas
*/
CustomElementPart *PolygonEditor::currentPart() const {
return(part);
}
/**
@return Un vecteur contenant les points composant le polygone a partir du
formulaire d'edition
*/
QVector<QPointF> PolygonEditor::getPointsFromTree() {
if (!part) return(QVector<QPointF>());
QVector<QPointF> points;
for(int i = 0 ; i < points_list.topLevelItemCount() ; ++ i) {
QTreeWidgetItem *qtwi = points_list.topLevelItem(i);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -19,7 +19,6 @@
#define POLYGON_EDITOR_H
#include "elementitemeditor.h"
class PartPolygon;
class StyleEditor;
/**
Cette classe represente le widget d'edition d'un polygone dans l'editeur
d'element.
@@ -30,7 +29,7 @@ class PolygonEditor : public ElementItemEditor {
// constructeurs, destructeur
public:
PolygonEditor(QETElementEditor *, PartPolygon * = 0, QWidget * = 0);
PolygonEditor(QETElementEditor *, PartPolygon *, QWidget * = 0);
virtual ~PolygonEditor();
private:
@@ -39,15 +38,10 @@ class PolygonEditor : public ElementItemEditor {
// attributs
private:
PartPolygon *part;
StyleEditor *style_;
QTreeWidget points_list;
QCheckBox close_polygon;
// methodes
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
private:
QVector<QPointF> getPointsFromTree();

784
editor/qetelementeditor.cpp Normal file
View File

@@ -0,0 +1,784 @@
/*
Copyright 2006-2007 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 "qetelementeditor.h"
#include "qetapp.h"
#include "elementscene.h"
#include "elementview.h"
#include "customelementpart.h"
#include "newelementwizard.h"
#include "elementitemeditor.h"
/**
Constructeur
@param parent QWidget parent
*/
QETElementEditor::QETElementEditor(QWidget *parent) :
QMainWindow(parent),
read_only(false),
min_title(tr("QElectroTech - \311diteur d'\351l\351ment")),
_filename(QString())
{
setWindowTitle(min_title);
setWindowIcon(QIcon(":/ico/qet.png"));
setupInterface();
setupActions();
setupMenus();
// la fenetre est maximisee par defaut
setMinimumSize(QSize(500, 350));
setWindowState(Qt::WindowMaximized);
// lecture des parametres
readSettings();
// affichage
show();
}
/// Destructeur
QETElementEditor::~QETElementEditor() {
}
/**
Met en place les actions
*/
void QETElementEditor::setupActions() {
new_element = new QAction(QIcon(":/ico/new.png"), tr("&Nouveau"), this);
open = new QAction(QIcon(":/ico/open.png"), tr("&Ouvrir"), this);
save = new QAction(QIcon(":/ico/save.png"), tr("&Enregistrer"), this);
save_as = new QAction(QIcon(":/ico/saveas.png"), tr("Enregistrer sous"), 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);
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);
zoom_out = new QAction(QIcon(":/ico/viewmag-.png"), tr("Zoom arri\350re"), this);
zoom_fit = new QAction(QIcon(":/ico/viewmagfit.png"), tr("Zoom adapt\351"), this);
zoom_reset = new QAction(QIcon(":/ico/viewmag.png"), tr("Pas de zoom"), this);
edit_size_hs = new QAction(QIcon(":/ico/hotspot.png"), tr("\311diter la taille et le point de saisie"), this);
edit_names = new QAction(QIcon(":/ico/names.png"), tr("\311diter les noms"), this);
edit_ori = new QAction(QIcon(":/ico/orientations.png"), tr("\311diter les orientations"), this);
edit_raise = new QAction(QIcon(":/ico/raise.png"), tr("Rapprocher"), this);
edit_lower = new QAction(QIcon(":/ico/lower.png"), tr("\311loigner"), this);
edit_backward = new QAction(QIcon(":/ico/send_backward.png"),tr("Envoyer au fond"), this);
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_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);
add_text = new QAction(QIcon(":/ico/text.png"), tr("Ajouter du texte"), this);
add_arc = new QAction(QIcon(":/ico/arc.png"), tr("Ajouter un arc de cercle"), this);
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);
undo = ce_scene -> undoStack().createUndoAction(this, tr("Annuler"));
redo = ce_scene -> undoStack().createRedoAction(this, tr("Refaire"));
undo -> setIcon(QIcon(":/ico/undo.png"));
redo -> setIcon(QIcon(":/ico/redo.png"));
undo -> setShortcuts(QKeySequence::Undo);
redo -> setShortcuts(QKeySequence::Redo);
new_element -> setShortcut(QKeySequence::New);
open -> setShortcut(QKeySequence::Open);
save -> setShortcut(QKeySequence::Save);
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")));
edit_delete -> setShortcut(QKeySequence(tr("Suppr")));
zoom_in -> setShortcut(QKeySequence::ZoomIn);
zoom_out -> setShortcut(QKeySequence::ZoomOut);
zoom_fit -> setShortcut(QKeySequence(tr("Ctrl+9")));
zoom_reset -> setShortcut(QKeySequence(tr("Ctrl+0")));
edit_names -> setShortcut(QKeySequence(tr("Ctrl+E")));
edit_size_hs -> setShortcut(QKeySequence(tr("Ctrl+R")));
edit_ori -> setShortcut(QKeySequence(tr("Ctrl+T")));
edit_raise -> setShortcut(QKeySequence(tr("Ctrl+Shift+Up")));
edit_lower -> setShortcut(QKeySequence(tr("Ctrl+Shift+Down")));
edit_backward -> setShortcut(QKeySequence(tr("Ctrl+Shift+End")));
edit_forward -> setShortcut(QKeySequence(tr("Ctrl+Shift+Home")));
connect(new_element, SIGNAL(triggered()), this, SLOT(slot_new()));
connect(open, SIGNAL(triggered()), this, SLOT(slot_open()));
connect(save, SIGNAL(triggered()), this, SLOT(slot_save()));
connect(save_as, SIGNAL(triggered()), this, SLOT(slot_saveAs()));
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(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()));
connect(zoom_reset, SIGNAL(triggered()), ce_view, SLOT(zoomReset()));
connect(edit_delete, SIGNAL(triggered()), ce_scene, SLOT(slot_delete()));
connect(edit_size_hs, SIGNAL(triggered()), ce_scene, SLOT(slot_editSizeHotSpot()));
connect(edit_names, SIGNAL(triggered()), ce_scene, SLOT(slot_editNames()));
connect(edit_ori, SIGNAL(triggered()), ce_scene, SLOT(slot_editOrientations()));
connect(edit_forward, SIGNAL(triggered()), ce_scene, SLOT(slot_bringForward()));
connect(edit_raise, SIGNAL(triggered()), ce_scene, SLOT(slot_raise()));
connect(edit_lower, SIGNAL(triggered()), ce_scene, SLOT(slot_lower()));
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_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()));
connect(add_text, SIGNAL(triggered()), ce_scene, SLOT(slot_addText()));
connect(add_arc, SIGNAL(triggered()), ce_scene, SLOT(slot_addArc()));
connect(add_terminal, SIGNAL(triggered()), ce_scene, SLOT(slot_addTerminal()));
connect(add_textfield, SIGNAL(triggered()), ce_scene, SLOT(slot_addTextField()));
connect(move, SIGNAL(triggered()), this, SLOT(slot_setRubberBandToView()));
connect(add_line, 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()));
connect(add_text, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_arc, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_terminal, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_textfield, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(ce_scene, SIGNAL(needNormalMode()), this, SLOT(slot_setNormalMode()));
move -> setCheckable(true);
add_line -> setCheckable(true);
add_ellipse -> setCheckable(true);
add_circle -> setCheckable(true);
add_polygon -> setCheckable(true);
add_text -> setCheckable(true);
add_arc -> setCheckable(true);
add_terminal -> setCheckable(true);
add_textfield -> setCheckable(true);
parts = new QActionGroup(this);
parts -> addAction(move);
parts -> addAction(add_line);
parts -> addAction(add_ellipse);
parts -> addAction(add_circle);
parts -> addAction(add_polygon);
parts -> addAction(add_text);
parts -> addAction(add_arc);
parts -> addAction(add_textfield);
parts -> addAction(add_terminal);
parts -> setExclusive(true);
parts_toolbar = new QToolBar(tr("Parties"), this);
parts_toolbar -> setObjectName("parts");
foreach (QAction *action, parts -> actions()) parts_toolbar -> addAction(action);
move -> setChecked(true);
parts_toolbar -> setAllowedAreas(Qt::AllToolBarAreas);
/*
QAction *xml_preview = new QAction(QIcon(":/ico/info.png"), tr("XML"), this);
connect(xml_preview, SIGNAL(triggered()), this, SLOT(xmlPreview()));
parts_toolbar -> addAction(xml_preview);
*/
main_toolbar = new QToolBar(tr("Outils"), this);
main_toolbar -> setObjectName("main_toolbar");
view_toolbar = new QToolBar(tr("Affichage"), this);
view_toolbar -> setObjectName("display");
element_toolbar = new QToolBar(tr("\311l\351ment"), this);
element_toolbar -> setObjectName("element_toolbar");
depth_toolbar = new QToolBar(tr("Profondeur"), this);
depth_toolbar -> setObjectName("depth_toolbar");
main_toolbar -> addAction(new_element);
main_toolbar -> addAction(open);
main_toolbar -> addAction(save);
main_toolbar -> addAction(save_as);
main_toolbar -> addAction(reload);
main_toolbar -> addSeparator();
main_toolbar -> addAction(undo);
main_toolbar -> addAction(redo);
main_toolbar -> addSeparator();
main_toolbar -> addAction(edit_delete);
view_toolbar -> addAction(zoom_in);
view_toolbar -> addAction(zoom_out);
view_toolbar -> addAction(zoom_fit);
view_toolbar -> addAction(zoom_reset);
element_toolbar -> addAction(edit_size_hs);
element_toolbar -> addAction(edit_names);
element_toolbar -> addAction(edit_ori);
depth_toolbar -> addAction(edit_forward);
depth_toolbar -> addAction(edit_raise);
depth_toolbar -> addAction(edit_lower);
depth_toolbar -> addAction(edit_backward);
addToolBar(Qt::TopToolBarArea, main_toolbar);
addToolBar(Qt::TopToolBarArea, view_toolbar);
addToolBar(Qt::TopToolBarArea, element_toolbar);
addToolBar(Qt::TopToolBarArea, depth_toolbar);
addToolBar(Qt::LeftToolBarArea, parts_toolbar);
connect(ce_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updateInformations()));
connect(ce_scene, SIGNAL(selectionChanged()), 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()));
}
/**
Met en place les menus.
*/
void QETElementEditor::setupMenus() {
file_menu = new QMenu(tr("Fichier"), this);
edit_menu = new QMenu(tr("\311dition"), this);
display_menu = new QMenu(tr("Affichage"), this);
tools_menu = new QMenu(tr("Outils"), this);
help_menu = new QMenu(tr("Aide"), this);
file_menu -> setTearOffEnabled(true);
edit_menu -> setTearOffEnabled(true);
display_menu -> setTearOffEnabled(true);
tools_menu -> setTearOffEnabled(true);
help_menu -> setTearOffEnabled(true);
file_menu -> addAction(new_element);
file_menu -> addAction(open);
file_menu -> addAction(save);
file_menu -> addAction(save_as);
file_menu -> addSeparator();
file_menu -> addAction(reload);
file_menu -> addSeparator();
file_menu -> addAction(quit);
edit_menu -> addAction(undo);
edit_menu -> addAction(redo);
edit_menu -> addSeparator();
edit_menu -> addAction(selectall);
edit_menu -> addAction(deselectall);
edit_menu -> addAction(inv_select);
edit_menu -> addSeparator();
edit_menu -> addAction(edit_delete);
edit_menu -> addSeparator();
edit_menu -> addAction(edit_names);
edit_menu -> addAction(edit_size_hs);
edit_menu -> addAction(edit_ori);
edit_menu -> addSeparator();
edit_menu -> addAction(edit_forward);
edit_menu -> addAction(edit_raise);
edit_menu -> addAction(edit_lower);
edit_menu -> addAction(edit_backward);
// menu Affichage > Afficher
QMenu *display_toolbars = createPopupMenu();
display_toolbars -> setTearOffEnabled(true);
display_toolbars -> setTitle(tr("Afficher"));
display_menu -> addMenu(display_toolbars);
menuBar() -> addMenu(file_menu);
menuBar() -> addMenu(edit_menu);
menuBar() -> addMenu(display_menu);
/*
menuBar() -> addMenu(tools_menu);
menuBar() -> addMenu(help_menu);
*/
}
/**
Met a jour les menus
*/
void QETElementEditor::slot_updateMenus() {
bool selected_items = !ce_scene -> selectedItems().isEmpty();
edit_delete -> setEnabled(selected_items);
edit_forward -> setEnabled(selected_items);
edit_raise -> setEnabled(selected_items);
edit_lower -> setEnabled(selected_items);
edit_backward -> setEnabled(selected_items);
save -> setEnabled(!ce_scene -> undoStack().isClean());
}
/**
Met a jour le titre de la fenetre
*/
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]");
}
setWindowTitle(title);
}
/**
Met en place l'interface
*/
void QETElementEditor::setupInterface() {
// editeur
ce_scene = new ElementScene(this, this);
ce_scene -> slot_move();
ce_view = new ElementView(ce_scene, this);
slot_setRubberBandToView();
setCentralWidget(ce_view);
// widget par defaut dans le QDockWidget
default_informations = new QLabel();
// panel sur le cote pour editer les parties
tools_dock = new QDockWidget(tr("Informations"), this);
tools_dock -> setObjectName("informations");
tools_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
tools_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
tools_dock -> setMinimumWidth(290);
addDockWidget(Qt::RightDockWidgetArea, tools_dock);
QWidget *info_widget = new QWidget();
info_widget -> setLayout(new QVBoxLayout(info_widget));
tools_dock -> setWidget(info_widget);
// panel sur le cote pour les annulations
undo_dock = new QDockWidget(tr("Annulations"), this);
undo_dock -> setObjectName("undo");
undo_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
undo_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
undo_dock -> setMinimumWidth(290);
addDockWidget(Qt::RightDockWidgetArea, undo_dock);
QUndoView* undo_view = new QUndoView(&(ce_scene -> undoStack()), this);
undo_view -> setEmptyLabel(tr("Aucune modification"));
undo_dock -> setWidget(undo_view);
// panel sur le cote pour la liste des parties
parts_list = new QListWidget(this);
parts_list -> setSelectionMode(QAbstractItemView::ExtendedSelection);
connect(ce_scene, SIGNAL(partsAdded()), this, SLOT(slot_createPartsList()));
connect(ce_scene, SIGNAL(partsRemoved()), this, SLOT(slot_createPartsList()));
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 -> setObjectName("parts_list");
parts_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
parts_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
parts_dock -> setMinimumWidth(290);
tabifyDockWidget(undo_dock, parts_dock);
parts_dock -> setWidget(parts_list);
slot_updateInformations();
slot_createPartsList();
// barre d'etat
statusBar() -> showMessage(tr("\311diteur d'\351l\351ments"));
}
/**
Passe l'editeur d'element en mode selection : le pointeur deplace les
elements selectionnes et il est possible d'utiliser un rectangle de selection.
*/
void QETElementEditor::slot_setRubberBandToView() {
ce_view -> setDragMode(QGraphicsView::RubberBandDrag);
}
/**
Passe l'editeur d'element en mode immobile (utilise pour la lecture seule)
*/
void QETElementEditor::slot_setNoDragToView() {
ce_view -> setDragMode(QGraphicsView::NoDrag);
}
/**
Passe l'editeur en mode normal
*/
void QETElementEditor::slot_setNormalMode() {
if (!move -> isChecked()) move -> setChecked(true);
ce_view -> setDragMode(QGraphicsView::RubberBandDrag);
ce_scene -> slot_move();
}
/**
Met a jour la zone d'information et d'edition.
Si plusieurs parties sont selectionnees, seul leur nombre est affiche.
Sinon, le widget d'edition de la partie est insere.
@see CustomElementPart::elementInformations()
*/
void QETElementEditor::slot_updateInformations() {
QList<QGraphicsItem *> selected_qgis = ce_scene -> selectedItems();
QList<CustomElementPart *> selected_parts;
foreach(QGraphicsItem *qgi, selected_qgis) {
if (CustomElementPart *cep = dynamic_cast<CustomElementPart *>(qgi)) {
selected_parts.append(cep);
}
}
// 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 (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();
} else {
default_informations -> setText(
selected_parts.size() ?
QString("%1").arg(selected_parts.size()) + tr(" parties s\351lectionn\351es.") :
tr("Aucune partie s\351lectionn\351e.")
);
layout -> addWidget(default_informations);
default_informations -> show();
}
}
/**
Affiche le code XML correspondant a l'element dans son etat actuel dans
une boite de dialogue.
*/
void QETElementEditor::xmlPreview() {
QMessageBox::information(
this,
"Export XML",
ce_scene -> toXml().toString(4)
);
}
/**
Charge un fichier
@param filepath Chemin du fichier a charger
*/
void QETElementEditor::fromFile(const QString &filepath) {
bool state = true;
QString error_message;
// le fichier doit exister
QFileInfo infos_file(filepath);
if (!infos_file.exists() || !infos_file.isFile()) {
state = false;
error_message = tr("Le fichier ") + filepath + tr(" n'existe pas.");
}
// le fichier doit etre lisible
QFile file(filepath);
if (state) {
if (!file.open(QIODevice::ReadOnly)) {
state = false;
error_message = tr("Impossible d'ouvrir le fichier ") + filepath + ".";
}
}
// le fichier doit etre un document XML
QDomDocument document_xml;
if (state) {
if (!document_xml.setContent(&file)) {
state = false;
error_message = tr("Ce fichier n'est pas un document XML valide");
}
file.close();
}
if (!state) {
QMessageBox::critical(this, tr("Erreur"), error_message);
return;
}
// chargement de l'element
ce_scene -> fromXml(document_xml);
slot_createPartsList();
// gestion de la lecture seule
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.")
);
setReadOnly(true);
}
// memorise le fichier
setFileName(filepath);
slot_updateMenus();
}
/**
Enregistre l'element vers un fichier
@param fn Chemin du fichier a enregistrer
@return true en cas de reussite, false sinon
*/
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"));
return(false);
}
QTextStream out(&file);
out.setCodec("UTF-8");
out << ce_scene -> toXml().toString(4);
file.close();
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
*/
void QETElementEditor::setReadOnly(bool ro) {
read_only = ro;
// active / desactive les actions
foreach (QAction *action, parts -> actions()) action -> setEnabled(!ro);
// active / desactive les interactions avec la scene
ce_view -> setInteractive(!ro);
// active / desactive l'edition de la taille, du hotspot, des noms et des orientations
selectall -> setEnabled(!ro);
deselectall -> setEnabled(!ro);
inv_select -> setEnabled(!ro);
undo -> setEnabled(!ro);
redo -> setEnabled(!ro);
edit_delete -> setEnabled(!ro);
edit_size_hs -> setEnabled(!ro);
edit_names -> setEnabled(!ro);
edit_ori -> setEnabled(!ro);
parts_list -> setEnabled(!ro);
}
/**
@return true si l'editeur d'element est en mode lecture seule
*/
bool QETElementEditor::isReadOnly() const {
return(read_only);
}
/**
Lance l'assistant de creation d'un nouvel element.
*/
void QETElementEditor::slot_new() {
NewElementWizard new_element_wizard;
new_element_wizard.exec();
}
/**
Ouvre un fichier
*/
void QETElementEditor::slot_open() {
// 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 (*)")
);
if (user_filename.isEmpty()) return;
QETElementEditor *cee = new QETElementEditor();
cee -> fromFile(user_filename);
cee -> show();
}
/**
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 ?"),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
QMessageBox::Cancel
);
if (answer != QMessageBox::Yes) return;
}
// recharge l'element
ce_scene -> reset();
fromFile(_filename);
}
/**
Enregistre l'element en cours d'edition.
Si le nom du fichier en cours n'est pas connu, cette methode equivaut a
l'action "Enregistrer sous"
@see slot_saveAs()
*/
bool QETElementEditor::slot_save() {
// 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();
return(result_save);
}
/**
Demande un nom de fichier a l'utilisateur et enregistre l'element
*/
bool QETElementEditor::slot_saveAs() {
// 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)")
);
// si aucun nom n'est entre, renvoie faux.
if (fn.isEmpty()) return(false);
// si le nom ne se termine pas par l'extension .elmt, celle-ci est ajoutee
if (!fn.endsWith(".elmt", Qt::CaseInsensitive)) fn += ".elmt";
// tente d'enregistrer le fichier
bool result_save = toFile(fn);
// si l'enregistrement reussit, le nom du fichier est conserve
if (result_save) {
setFileName(fn);
ce_scene -> undoStack().setClean();
}
// retourne un booleen representatif de la reussite de l'enregistrement
return(result_save);
}
/**
@return true si l'element peut etre ferme.
Un element peut etre ferme s'il ne comporte aucune modification.
Si l'element comporte des modifications, la question est posee a
l'utilisateur.
*/
bool QETElementEditor::canClose() {
if (ce_scene -> undoStack().isClean()) return(true);
// 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,
QMessageBox::Cancel
);
bool result;
switch(answer) {
case QMessageBox::Cancel: result = false; break; // l'utilisateur annule : echec de la fermeture
case QMessageBox::Yes: result = slot_save(); break; // l'utilisateur dit oui : la reussite depend de l'enregistrement
default: result = true; // l'utilisateur dit non ou ferme le dialogue: c'est reussi
}
return(result);
}
/**
Permet de quitter l'editeur lors de la fermeture de la fenetre principale
@param qce Le QCloseEvent correspondant a l'evenement de fermeture
*/
void QETElementEditor::closeEvent(QCloseEvent *qce) {
if (canClose()) {
writeSettings();
setAttribute(Qt::WA_DeleteOnClose);
qce -> accept();
} else qce -> ignore();
}
/**
Remplit la liste des parties
*/
void QETElementEditor::slot_createPartsList() {
parts_list -> blockSignals(true);
parts_list -> clear();
QList<QGraphicsItem *> qgis = ce_scene -> zItems(true);
for (int j = qgis.count() - 1 ; j >= 0 ; -- j) {
QGraphicsItem *qgi = qgis[j];
if (CustomElementPart *cep = dynamic_cast<CustomElementPart *>(qgi)) {
QString part_desc = cep -> name();
QListWidgetItem *qlwi = new QListWidgetItem(part_desc);
QVariant v;
v.setValue<QGraphicsItem *>(qgi);
qlwi -> setData(42, v);
parts_list -> addItem(qlwi);
qlwi -> setSelected(qgi -> isSelected());
}
}
parts_list -> blockSignals(false);
}
/**
Met a jour la selection dans la liste des parties
*/
void QETElementEditor::slot_updatePartsList() {
if (parts_list -> count() != ce_scene -> items().count()) {
slot_createPartsList();
} else {
parts_list -> blockSignals(true);
int i = 0;
QList<QGraphicsItem *> items = ce_scene -> zItems(true);
for (int j = items.count() - 1 ; j >= 0 ; -- j) {
QGraphicsItem *qgi = items[j];
QListWidgetItem *qlwi = parts_list -> item(i);
if (qlwi) qlwi -> setSelected(qgi -> isSelected());
++ i;
}
parts_list -> blockSignals(false);
}
}
/**
Met a jour la selection des parties de l'element a partir de la liste des
parties
*/
void QETElementEditor::slot_updateSelectionFromPartsList() {
ce_scene -> blockSignals(true);
parts_list -> blockSignals(true);
for (int i = 0 ; i < parts_list -> count() ; ++ i) {
QListWidgetItem *qlwi = parts_list -> item(i);
QGraphicsItem *qgi = qlwi -> data(42).value<QGraphicsItem *>();
if (qgi) {
qgi -> setSelected(qlwi -> isSelected());
}
}
parts_list -> blockSignals(false);
ce_scene -> blockSignals(false);
slot_updateInformations();
}
/// Lit les parametres de l'editeur d'element
void QETElementEditor::readSettings() {
QSettings &settings = QETApp::settings();
// dimensions et position de la fenetre
QVariant geometry = settings.value("elementeditor/geometry");
if (geometry.isValid()) restoreGeometry(geometry.toByteArray());
// etat de la fenetre (barres d'outils, docks...)
QVariant state = settings.value("elementeditor/state");
if (state.isValid()) restoreState(state.toByteArray());
}
/// Enregistre les parametres de l'editeur d'element
void QETElementEditor::writeSettings() {
QSettings &settings = QETApp::settings();
settings.setValue("elementeditor/geometry", saveGeometry());
settings.setValue("elementeditor/state", saveState());
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -18,11 +18,8 @@
#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 ElementItemEditor;
class ElementView;
/**
Cette classe represente un editeur d'element. Elle permet a l'utilisateur
@@ -44,21 +41,13 @@ class QETElementEditor : public QMainWindow {
/// booleen indiquant si l'editeur est en mode "lecture seule" ou non
bool read_only;
/// menus
QMenu *file_menu, *edit_menu, *paste_from_menu, *display_menu, *tools_menu, *config_menu, *help_menu;
QMenu *file_menu, *edit_menu, *display_menu, *tools_menu, *help_menu;
/// vue sur la scene d'edition
ElementView *ce_view;
/// scene d'edition
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;
/// Hash permettant d'acceder aux widgets d'editions disponibles
QHash<QString, ElementItemEditor *> editors_;
/// 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
@@ -66,35 +55,25 @@ class QETElementEditor : public QMainWindow {
/// Liste des parties
QListWidget *parts_list;
/// actions du menu fichier
QAction *new_element, *open, *open_file, *save, *save_as, *save_as_file, *reload, *quit;
QAction *new_element, *open, *save, *save_as, *reload, *quit;
/// actions du menu edition
QAction *selectall, *deselectall, *inv_select;
QAction *cut, *copy, *paste, *paste_in_area, *paste_from_file, *paste_from_elmt;
QAction *undo, *redo;
QAction *edit_delete, *edit_size_hs, *edit_names, *edit_ori, *edit_author;
QAction *edit_raise, *edit_lower, *edit_backward, *edit_forward;
/// actions du menu affichage
QAction *zoom_in, *zoom_out, *zoom_fit, *zoom_reset;
/// actions du menu configurer
QAction *fullscreen; ///< Passe en mode plein ecran ou en sort
QAction *configure; ///< Lance le dialogue de configuration de QElectroTech
/// actions du menu aide
QAction *about_qet; ///< Lance le dialogue "A propos de QElectroTech"
QAction *about_qt; ///< Lance le dialogue "A propos de Qt"
QAction *edit_delete, *edit_size_hs, *edit_names, *edit_ori;
QAction *edit_raise, *edit_lower, *edit_backward, *edit_forward;
/// barres d'outils
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_rectangle, *add_ellipse, *add_polygon, *add_text;
QAction *move, *add_line, *add_circle, *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 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;
/// Nom de fichier
QString _filename;
// methodes
public:
@@ -105,63 +84,41 @@ 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 &);
bool isEditing(const ElementsLocation &);
bool isEditing(const QString &);
ElementScene *elementScene() const;
void readSettings();
void writeSettings();
static QPointF pasteOffset();
static QET::OrientedMovement pasteMovement();
static QString getOpenElementFileName(QWidget * = 0, const QString & = QString());
protected:
void closeEvent(QCloseEvent *);
virtual bool event(QEvent *);
private:
void setupActions();
void setupMenus();
void setupInterface();
bool canClose();
QWidget *clearToolsDock();
void copyAndPasteXml(const QDomDocument &);
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();
void slot_updateInformations();
void slot_updateMenus();
void slot_updateFullScreenAction();
void slot_updateTitle();
void slot_createPartsList();
void slot_updatePartsList();
void slot_updateSelectionFromPartsList();
void toggleFullScreen();
void xmlPreview();
bool checkElement();
void pasteFromFile();
void pasteFromElement();
void updateCurrentPartEditor();
};
/**
@@ -219,36 +176,19 @@ inline OrientationSet QETElementEditor::orientations() const {
return(ce_scene -> orientations());
}
/**
@param el Le nouvel emplacement de l'element edite
*/
inline void QETElementEditor::setLocation(const ElementsLocation &el) {
location_ = el;
opened_from_file = false;
slot_updateTitle();
}
/**
@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;
_filename = fn;
slot_updateTitle();
}
/**
@return le nom de fichier de l'element edite
@return le nomde fichier de l'element edite
*/
inline QString QETElementEditor::fileName() const {
return(filename_);
return(_filename);
}
/**

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -24,32 +24,29 @@
@param p La partie a editer
@param parent le Widget parent
*/
StyleEditor::StyleEditor(QETElementEditor *editor, CustomElementGraphicPart *p, QWidget *parent) :
ElementItemEditor(editor, parent),
part(p)
{
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", "element part color")), CustomElementGraphicPart::BlackColor);
color -> addButton(white_color = new QRadioButton(tr("Blanc", "element part color")), CustomElementGraphicPart::WhiteColor);
color -> addButton(black_color = new QRadioButton(tr("Noir")), CustomElementGraphicPart::BlackColor);
color -> addButton(white_color = new QRadioButton(tr("Blanc")), CustomElementGraphicPart::WhiteColor);
// style
style = new QButtonGroup(this);
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);
normal_style -> setChecked(true);
style -> addButton(normal_style = new QRadioButton(tr("Normal")), CustomElementGraphicPart::NormalStyle);
style -> addButton(dashed_style = new QRadioButton(tr("Pointill\351")), CustomElementGraphicPart::DashedStyle);
style -> button(part -> lineStyle()) -> setChecked(true);
// epaisseur
weight = new QButtonGroup(this);
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);
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);
// remplissage
filling = new QButtonGroup(this);
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);
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);
// antialiasing
antialiasing = new QCheckBox(tr("Antialiasing"));
@@ -105,7 +102,6 @@ StyleEditor::~StyleEditor() {
Met a jour le style de la partie a partir des donnees du formulaire
*/
void StyleEditor::updatePart() {
if (!part) return;
// applique l'antialiasing
part -> setAntialiased(antialiasing -> isChecked());
@@ -137,7 +133,6 @@ void StyleEditor::updatePartFilling() { addChangePartCommand("style rempl
Met a jour le formulaire d'edition
*/
void StyleEditor::updateForm() {
if (!part) return;
activeConnections(false);
// lit l'antialiasing
antialiasing -> setChecked(part -> antialiased());
@@ -157,32 +152,11 @@ void StyleEditor::updateForm() {
}
/**
Permet de specifier a cet editeur quelle primitive il doit editer. A noter
qu'un editeur peut accepter ou refuser d'editer une primitive.
L'editeur de ligne acceptera d'editer la primitive new_part s'il s'agit d'un
objet de la classe CustomElementGraphicPart.
@param new_part Nouvelle primitive a editer
@return true si l'editeur a accepter d'editer la primitive, false sinon
Ajoute un widget en bas de l'editeur de style
@param w Widget a inserer
*/
bool StyleEditor::setPart(CustomElementPart *new_part) {
if (!new_part) {
part = 0;
return(true);
}
if (CustomElementGraphicPart *part_graphic = dynamic_cast<CustomElementGraphicPart *>(new_part)) {
part = part_graphic;
updateForm();
return(true);
} else {
return(false);
}
}
/**
@return la primitive actuellement editee, ou 0 si ce widget n'en edite pas
*/
CustomElementPart *StyleEditor::currentPart() const {
return(part);
void StyleEditor::appendWidget(QWidget *w) {
main_layout -> insertWidget(7, w);
}
/**

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -30,7 +30,7 @@ class StyleEditor : public ElementItemEditor {
Q_OBJECT
// constructeurs, destructeur
public:
StyleEditor(QETElementEditor *, CustomElementGraphicPart * = 0, QWidget * = 0);
StyleEditor(QETElementEditor *, CustomElementGraphicPart *, QWidget * = 0);
virtual ~StyleEditor();
private:
@@ -46,10 +46,9 @@ class StyleEditor : public ElementItemEditor {
QRadioButton *black_filling, *white_filling;
QCheckBox *antialiasing;
// methodes
//methodes
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
void appendWidget(QWidget *w);
public slots:
void updatePart();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -17,7 +17,6 @@
*/
#include "terminaleditor.h"
#include "partterminal.h"
#include "qeticons.h"
/**
Constructeur
@@ -25,10 +24,9 @@
@param term La borne a editer
@param parent QWidget parent de ce widget
*/
TerminalEditor::TerminalEditor(QETElementEditor *editor, PartTerminal *term, QWidget *parent) :
ElementItemEditor(editor, parent),
part(term)
{
TerminalEditor::TerminalEditor(QETElementEditor *editor, PartTerminal *term, QWidget *parent) : ElementItemEditor(editor, parent) {
part = term;
qle_x = new QLineEdit();
qle_y = new QLineEdit();
@@ -36,10 +34,10 @@ TerminalEditor::TerminalEditor(QETElementEditor *editor, PartTerminal *term, QWi
qle_y -> setValidator(new QDoubleValidator(qle_y));
orientation = new QComboBox();
orientation -> addItem(QET::Icons::North, tr("Nord"), QET::North);
orientation -> addItem(QET::Icons::East, tr("Est"), QET::East);
orientation -> addItem(QET::Icons::South, tr("Sud"), QET::South);
orientation -> addItem(QET::Icons::West, tr("Ouest"), QET::West);
orientation -> addItem(QIcon(":/ico/north.png"), tr("Nord"), QET::North);
orientation -> addItem(QIcon(":/ico/east.png"), tr("Est"), QET::East);
orientation -> addItem(QIcon(":/ico/south.png"), tr("Sud"), QET::South);
orientation -> addItem(QIcon(":/ico/west.png"), tr("Ouest"), QET::West);
QVBoxLayout *main_layout = new QVBoxLayout();
main_layout -> addWidget(new QLabel(tr("Position : ")));
@@ -66,40 +64,10 @@ TerminalEditor::TerminalEditor(QETElementEditor *editor, PartTerminal *term, QWi
TerminalEditor::~TerminalEditor() {
};
/**
Permet de specifier a cet editeur quelle primitive il doit editer. A noter
qu'un editeur peut accepter ou refuser d'editer une primitive.
L'editeur de borne acceptera d'editer la primitive new_part s'il s'agit d'un
objet de la classe PartTerminal.
@param new_part Nouvelle primitive a editer
@return true si l'editeur a accepter d'editer la primitive, false sinon
*/
bool TerminalEditor::setPart(CustomElementPart *new_part) {
if (!new_part) {
part = 0;
return(true);
}
if (PartTerminal *part_terminal = dynamic_cast<PartTerminal *>(new_part)) {
part = part_terminal;
updateForm();
return(true);
} else {
return(false);
}
}
/**
@return la primitive actuellement editee, ou 0 si ce widget n'en edite pas
*/
CustomElementPart *TerminalEditor::currentPart() const {
return(part);
}
/**
Met a jour la borne a partir des donnees du formulaire
*/
void TerminalEditor::updateTerminal() {
if (!part) return;
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
part -> setOrientation(
static_cast<QET::Orientation>(
@@ -121,7 +89,6 @@ void TerminalEditor::updateTerminalO() { addChangePartCommand(tr("orientation"),
Met a jour le formulaire d'edition
*/
void TerminalEditor::updateForm() {
if (!part) return;
activeConnections(false);
qle_x -> setText(part -> property("x").toString());
qle_y -> setText(part -> property("y").toString());

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -29,7 +29,7 @@ class TerminalEditor : public ElementItemEditor {
Q_OBJECT
// Constructeurs, destructeur
public:
TerminalEditor(QETElementEditor *, PartTerminal * = 0, QWidget * = 0);
TerminalEditor(QETElementEditor *, PartTerminal *, QWidget * = 0);
virtual ~TerminalEditor();
private:
TerminalEditor(const TerminalEditor &);
@@ -41,10 +41,6 @@ class TerminalEditor : public ElementItemEditor {
QComboBox *orientation;
// methodes
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
public slots:
void updateTerminal();
void updateTerminalX();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -24,10 +24,9 @@
@param text Champ de texte a editer
@param parent QWidget parent de ce widget
*/
TextEditor::TextEditor(QETElementEditor *editor, PartText *text, QWidget *parent) :
ElementItemEditor(editor, parent),
part(text)
{
TextEditor::TextEditor(QETElementEditor *editor, PartText *text, QWidget *parent) : ElementItemEditor(editor, parent) {
part = text;
qle_x = new QLineEdit();
qle_y = new QLineEdit();
qle_text = new QLineEdit();
@@ -68,40 +67,10 @@ TextEditor::TextEditor(QETElementEditor *editor, PartText *text, QWidget *parent
TextEditor::~TextEditor() {
}
/**
Permet de specifier a cet editeur quelle primitive il doit editer. A noter
qu'un editeur peut accepter ou refuser d'editer une primitive.
L'editeur de texte statique acceptera d'editer la primitive new_part s'il
s'agit d'un objet de la classe PartText.
@param new_part Nouvelle primitive a editer
@return true si l'editeur a accepter d'editer la primitive, false sinon
*/
bool TextEditor::setPart(CustomElementPart *new_part) {
if (!new_part) {
part = 0;
return(true);
}
if (PartText *part_text = dynamic_cast<PartText *>(new_part)) {
part = part_text;
updateForm();
return(true);
} else {
return(false);
}
}
/**
@return la primitive actuellement editee, ou 0 si ce widget n'en edite pas
*/
CustomElementPart *TextEditor::currentPart() const {
return(part);
}
/**
Met a jour le champ de texte a partir des donnees du formulaire
*/
void TextEditor::updateText() {
if (!part) return;
part -> setProperty("size", font_size -> value());
part -> setPlainText(qle_text -> text());
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
@@ -112,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("contenu"), part, "text", qle_text -> text()); }
void TextEditor::updateTextT() { addChangePartCommand(tr("texte"), 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()); }
@@ -120,7 +89,6 @@ void TextEditor::updateTextS() { addChangePartCommand(tr("taille"), part, "
Met a jour le formulaire a partir du champ de texte
*/
void TextEditor::updateForm() {
if (!part) return;
activeConnections(false);
qle_x -> setText(part -> property("x").toString());
qle_y -> setText(part -> property("y").toString());

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -29,7 +29,7 @@ class TextEditor : public ElementItemEditor {
Q_OBJECT
// Constructeurs, destructeur
public:
TextEditor(QETElementEditor *, PartText * = 0, QWidget * = 0);
TextEditor(QETElementEditor *, PartText *, QWidget * = 0);
virtual ~TextEditor();
private:
TextEditor(const TextEditor &);
@@ -41,10 +41,6 @@ class TextEditor : public ElementItemEditor {
QSpinBox *font_size;
// methodes
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
public slots:
void updateText();
void updateTextX();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -24,10 +24,9 @@
@param textfield Le champ de texte a editer
@param parent QWidget parent
*/
TextFieldEditor::TextFieldEditor(QETElementEditor *editor, PartTextField *textfield, QWidget *parent) :
ElementItemEditor(editor, parent),
part(textfield)
{
TextFieldEditor::TextFieldEditor(QETElementEditor *editor, PartTextField *textfield, QWidget *parent) : ElementItemEditor(editor, parent) {
part = textfield;
qle_x = new QLineEdit();
qle_y = new QLineEdit();
qle_text = new QLineEdit();
@@ -72,40 +71,10 @@ TextFieldEditor::TextFieldEditor(QETElementEditor *editor, PartTextField *textfi
TextFieldEditor::~TextFieldEditor() {
}
/**
Permet de specifier a cet editeur quelle primitive il doit editer. A noter
qu'un editeur peut accepter ou refuser d'editer une primitive.
L'editeur de texte dynamique acceptera d'editer la primitive new_part s'il
s'agit d'un objet de la classe PartTextField.
@param new_part Nouvelle primitive a editer
@return true si l'editeur a accepter d'editer la primitive, false sinon
*/
bool TextFieldEditor::setPart(CustomElementPart *new_part) {
if (!new_part) {
part = 0;
return(true);
}
if (PartTextField *part_textfield = dynamic_cast<PartTextField *>(new_part)) {
part = part_textfield;
updateForm();
return(true);
} else {
return(false);
}
}
/**
@return la primitive actuellement editee, ou 0 si ce widget n'en edite pas
*/
CustomElementPart *TextFieldEditor::currentPart() const {
return(part);
}
/**
Met a jour le champ de texte a partir des donnees du formulaire
*/
void TextFieldEditor::updateTextField() {
if (!part) return;
part -> setProperty("size", font_size -> value());
part -> setPlainText(qle_text -> text());
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
@@ -117,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("contenu"), part, "text", qle_text -> text()); }
void TextFieldEditor::updateTextFieldT() { addChangePartCommand(tr("texte"), 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
@@ -127,7 +96,6 @@ void TextFieldEditor::updateTextFieldR() { addChangePartCommand(tr("propri\351t\
Met a jour le formulaire d'edition
*/
void TextFieldEditor::updateForm() {
if (!part) return;
activeConnections(false);
qle_x -> setText(part -> property("x").toString());
qle_y -> setText(part -> property("y").toString());

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2007 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -30,7 +30,7 @@ class TextFieldEditor : public ElementItemEditor {
Q_OBJECT
// Constructeurs, destructeur
public:
TextFieldEditor(QETElementEditor *, PartTextField * = 0, QWidget * = 0);
TextFieldEditor(QETElementEditor *, PartTextField *, QWidget * = 0);
virtual ~TextFieldEditor();
private:
TextFieldEditor(const TextFieldEditor &);
@@ -43,10 +43,6 @@ class TextFieldEditor : public ElementItemEditor {
QCheckBox *rotate;
// methodes
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
public slots:
void updateTextField();
void updateTextFieldX();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -27,7 +27,6 @@
Constructeur pour un element sans scene ni parent
*/
Element::Element(QGraphicsItem *parent, Diagram *scene) :
QObject(),
QGraphicsItem(parent, scene),
internal_connections(false)
{
@@ -48,9 +47,9 @@ Element::~Element() {
*/
void Element::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
#ifndef Q_WS_WIN
#ifdef Q_WS_X11
// corrige un bug de rendu ne se produisant que lors du rendu sur QGraphicsScene sous X11 au zoom par defaut
static bool must_correct_rendering_bug = QETApp::settings().value("correct-rendering", false).toBool();
static bool must_correct_rendering_bug = QETApp::settings().value("correct-rendering", true).toBool();
if (must_correct_rendering_bug) {
Diagram *dia = diagram();
if (dia && options -> levelOfDetail == 1.0 && widget) {
@@ -95,13 +94,6 @@ QSize Element::setSize(int wid, int hei) {
return(dimensions = QSize(wid, hei));
}
/**
@return la taille de l'element sur le schema
*/
QSize Element::size() const {
return(dimensions);
}
/**
Definit le hotspot de l'element par rapport au coin superieur gauche de son rectangle delimitant.
Necessite que la taille ait deja ete definie
@@ -145,8 +137,8 @@ void Element::deselect() {
@return La pixmap de l'element
*/
QPixmap Element::pixmap() {
if (preview.isNull()) updatePixmap(); // on genere la pixmap si ce n'est deja fait
return(preview);
if (apercu.isNull()) updatePixmap(); // on genere la pixmap si ce n'est deja fait
return(apercu);
}
/**
@@ -163,7 +155,7 @@ bool Element::setOrientation(QET::Orientation o) {
rotate(rotation_value);
ori.setCurrent(o);
update();
foreach(QGraphicsItem *qgi, childItems()) {
foreach(QGraphicsItem *qgi, children()) {
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) p -> updateConductor();
else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(qgi)) {
// applique une rotation contraire si besoin
@@ -188,8 +180,7 @@ bool Element::setOrientation(QET::Orientation o) {
@param painter Le QPainter a utiliser pour dessiner les axes
@param options Les options de style a prendre en compte
*/
void Element::drawAxes(QPainter *painter, const QStyleOptionGraphicsItem *options) {
Q_UNUSED(options);
void Element::drawAxes(QPainter *painter, const QStyleOptionGraphicsItem *) {
painter -> setPen(Qt::blue);
painter -> drawLine(0, 0, 10, 0);
painter -> drawLine(7,-3, 10, 0);
@@ -204,11 +195,10 @@ void Element::drawAxes(QPainter *painter, const QStyleOptionGraphicsItem *option
/**
Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
@param painter Le QPainter a utiliser pour dessiner les bornes.
@param qp Le QPainter a utiliser pour dessiner les bornes.
@param options Les options de style a prendre en compte
*/
void Element::drawSelection(QPainter *painter, const QStyleOptionGraphicsItem *options) {
Q_UNUSED(options);
void Element::drawSelection(QPainter *painter, const QStyleOptionGraphicsItem *) {
painter -> save();
// Annulation des renderhints
painter -> setRenderHint(QPainter::Antialiasing, false);
@@ -229,10 +219,10 @@ void Element::drawSelection(QPainter *painter, const QStyleOptionGraphicsItem *o
*/
void Element::updatePixmap() {
// Pixmap transparente faisant la taille de base de l'element
preview = QPixmap(dimensions);
preview.fill(QColor(255, 255, 255, 0));
apercu = QPixmap(dimensions);
apercu.fill(QColor(255, 255, 255, 0));
// QPainter sur la pixmap, avec antialiasing
QPainter p(&preview);
QPainter p(&apercu);
p.setRenderHint(QPainter::Antialiasing, true);
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
// Translation de l'origine du repere de la pixmap
@@ -272,8 +262,8 @@ void Element::setPos(qreal x, qreal y) {
Gere l'enfoncement d'un bouton de la souris
*/
void Element::mousePressEvent(QGraphicsSceneMouseEvent *e) {
if (e -> modifiers() & Qt::ControlModifier) {
setSelected(!isSelected());
if (!isSelected() && e -> modifiers() & Qt::ControlModifier) {
setSelected(true);
}
QGraphicsItem::mousePressEvent(e);
}
@@ -311,9 +301,7 @@ void Element::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
}
diagram_ptr -> invalidateMovedElements();
}
if (!(e -> modifiers() & Qt::ControlModifier)) {
QGraphicsItem::mouseReleaseEvent(e);
}
}
/**
@@ -366,7 +354,7 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
QHash<int, Terminal *> priv_id_adr;
int terminals_non_trouvees = 0;
foreach(QGraphicsItem *qgi, childItems()) {
foreach(QGraphicsItem *qgi, children()) {
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
bool terminal_trouvee = false;
foreach(QDomElement qde, liste_terminals) {
@@ -398,7 +386,7 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
// importe les valeurs des champs de texte
QList<QDomElement> inputs = QET::findInDomElement(e, "inputs", "input");
foreach(QGraphicsItem *qgi, childItems()) {
foreach(QGraphicsItem *qgi, children()) {
if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(qgi)) {
foreach(QDomElement input, inputs) eti -> fromXml(input);
}
@@ -427,11 +415,13 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
QDomElement element = document.createElement("element");
// type
element.setAttribute("type", typeId());
QString chemin_elmt = typeId();
QString type_elmt = QETApp::symbolicPath(chemin_elmt);
element.setAttribute("type", type_elmt);
// position, selection et orientation
element.setAttribute("x", QString("%1").arg(pos().x()));
element.setAttribute("y", QString("%1").arg(pos().y()));
element.setAttribute("x", pos().x());
element.setAttribute("y", pos().y());
element.setAttribute("orientation", QString("%1").arg(ori.current()));
/* recupere le premier id a utiliser pour les bornes de cet element */
@@ -446,22 +436,30 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
}
// enregistrement des bornes de l'appareil
QDomElement xml_terminals = document.createElement("terminals");
QDomElement terminals = document.createElement("terminals");
// pour chaque enfant de l'element
foreach(Terminal *t, terminals()) {
foreach(QGraphicsItem *child, children()) {
// si cet enfant est une borne
if (Terminal *t = qgraphicsitem_cast<Terminal *>(child)) {
// alors on enregistre la borne
QDomElement terminal = t -> toXml(document);
terminal.setAttribute("id", id_terminal);
table_adr_id.insert(t, id_terminal ++);
xml_terminals.appendChild(terminal);
terminals.appendChild(terminal);
}
element.appendChild(xml_terminals);
}
element.appendChild(terminals);
// enregistrement des champ de texte de l'appareil
QDomElement inputs = document.createElement("inputs");
foreach(ElementTextItem *eti, texts()) {
// pour chaque enfant de l'element
foreach(QGraphicsItem *child, children()) {
// si cet enfant est un champ de texte
if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(child)) {
// alors on enregistre le champ de texte
inputs.appendChild(eti -> toXml(document));
}
}
element.appendChild(inputs);
return(element);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -21,13 +21,10 @@
#include "terminal.h"
#include "orientationset.h"
class Diagram;
class ElementTextItem;
/**
Cette classe abstraite represente un element electrique.
*/
class Element : public QObject, public QGraphicsItem {
Q_OBJECT
class Element : public QGraphicsItem {
// constructeurs, destructeur
public:
@@ -54,7 +51,7 @@ class Element : public QObject, public QGraphicsItem {
private:
QSize dimensions;
QPoint hotspot_coord;
QPixmap preview;
QPixmap apercu;
// methodes
public:
@@ -69,14 +66,12 @@ class Element : public QObject, public QGraphicsItem {
virtual QList<Terminal *> terminals() const = 0;
/// @return la liste des conducteurs relies a cet element
virtual QList<Conductor *> conductors() const = 0;
/// @return la liste des champs de textes de cet element
virtual QList<ElementTextItem *> texts() const = 0;
/// @return le nombre de bornes actuel de cet element
virtual int terminalsCount() const = 0;
virtual int nbTerminals() const = 0;
/// @return le nombre de bornes minimum de cet element
virtual int minTerminalsCount() const = 0;
virtual int nbTerminalsMin() const = 0;
/// @return le nombre de bornes maximum de cet element
virtual int maxTerminalsCount() const = 0;
virtual int nbTerminalsMax() const = 0;
/**
Dessine l'element
*/
@@ -84,13 +79,12 @@ class Element : public QObject, public QGraphicsItem {
/// @return L'ID du type de l'element
virtual QString typeId() const = 0;
/// @return Le nom de l'element
virtual QString name() const = 0;
virtual QString nom() const = 0;
Diagram *diagram() const;
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
QRectF boundingRect() const;
QSize setSize(int, int);
QSize size() const;
QPixmap pixmap();
// methodes relatives au point de saisie

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -16,26 +16,16 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "elementdeleter.h"
#include "qetapp.h"
#include "qetmessagebox.h"
/**
Constructeur
@param elmt_path Chemin virtuel du fichier representant l'element a supprimer
@param elmt_path Chemin du fichier representant l'element a supprimer
@param parent QWidget parent
*/
ElementDeleter::ElementDeleter(const ElementsLocation &elmt_path, QWidget *parent) :
ElementDeleter::ElementDeleter(const QString &elmt_path, QWidget *parent) :
QWidget(parent),
element(0)
element_path(elmt_path)
{
// recupere l'element a supprimer
ElementsCollectionItem *element_item = QETApp::collectionItem(elmt_path);
if (!element_item) return;
// on exige un element
if (!element_item -> isElement()) return;
element = element_item;
}
/// Destructeur
@@ -46,31 +36,27 @@ ElementDeleter::~ElementDeleter() {
Supprime l'element : verifie l'existence du fichier, demande confirmation a
l'utilisateur et avertit ce dernier si la suppression a echoue.
*/
bool ElementDeleter::exec() {
void ElementDeleter::exec() {
// verifie l'existence de l'element
if (!element || !element -> isElement()) return(false);
QFile elmt_file(element_path);
if (!elmt_file.exists()) return;
// confirmation #1
QMessageBox::StandardButton answer_1 = QET::MessageBox::question(
QMessageBox::StandardButton answer_1 = QMessageBox::question(
this,
tr("Supprimer l'\351l\351ment ?", "message box title"),
tr("\312tes-vous s\373r de vouloir supprimer cet \351l\351ment ?\n", "message box content"),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel
tr("Supprimer l'\351l\351ment ?"),
tr("\312tes-vous s\373r de vouloir supprimer cet \351l\351ment ?\n"),
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel
);
if (answer_1 != QMessageBox::Yes) return(false);
/**
@todo Regression : rafficher le chemin de l'element
*/
if (answer_1 != QMessageBox::Yes) return;
// supprime l'element
if (!element -> remove()) {
QET::MessageBox::warning(
if (!elmt_file.remove()) {
QMessageBox::warning(
this,
tr("Suppression de l'\351l\351ment", "message box title"),
tr("La suppression de l'\351l\351ment a \351chou\351.", "message box content")
tr("Suppression de l'\351l\351ment"),
tr("La suppression de l'\351l\351ment a \351chou\351.\n"
"V\351rifiez vos droits sur le fichier ") + element_path + tr(".")
);
return(false);
}
return(true);
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2010 Xavier Guerrin
Copyright 2006-2008 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -18,28 +18,27 @@
#ifndef ELEMENT_DELETER_H
#define ELEMENT_DELETER_H
#include "elementscategory.h"
#include "elementslocation.h"
#include <QtGui>
/**
Cette classe represente une couche d'abstraction pour supprimer
un element de la collection d'elements.
Elle demande notamment confirmation a l'utilisateur.
Elle demande notamment confirmation a l'utilisateur
*/
class ElementDeleter : public QWidget {
Q_OBJECT
// constructeurs, destructeur
public:
ElementDeleter(const ElementsLocation &, QWidget * = 0);
ElementDeleter(const QString &, QWidget * = 0);
virtual ~ElementDeleter();
private:
ElementDeleter(const ElementsCategory &);
// methodes
public slots:
bool exec();
void exec();
// attributs
private:
ElementsCollectionItem *element;
QString element_path;
};
#endif

View File

@@ -1,20 +0,0 @@
<definition width="80" version="0.2" hotspot_x="30" hotspot_y="50" height="110" type="element" ic="true" orientation="dyyy" >
<names>
<name lang="ru" >Вход</name>
<name lang="en" >Input</name>
<name lang="fr" >Entrée</name>
<name lang="es" >Entrada</name>
<name lang="cs" >Vstup</name>
<name lang="pt" >Entrada</name>
</names>
<informations>Author: The QElectroTech team
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
<description>
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="40" y2="0" x2="20" />
<input x="25" y="-10" size="8" rotate="true" text="_" />
<input x="-25" y="50" size="9" rotate="true" text="_" />
<text x="-2" y="5" size="12" text="I" />
<rect width="40" x="-20" y="-35" antialias="false" height="70" style="line-style:normal;line-weight:normal;filling:none;color:black" />
<terminal x="40" y="0" orientation="e" />
</description>
</definition>

View File

@@ -1,26 +0,0 @@
<definition width="100" version="0.2" hotspot_x="50" hotspot_y="50" height="110" type="element" ic="true" orientation="dyyy" >
<names>
<name lang="ru" >И</name>
<name lang="en" >AND</name>
<name lang="fr" >ET</name>
<name lang="es" >Y</name>
<name lang="cs" >A</name>
<name lang="pt" >E</name>
</names>
<informations>Author: The QElectroTech team
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
<description>
<input x="-46" y="10" size="8" rotate="true" text="_" />
<input x="-46" y="-30" size="8" rotate="true" text="_" />
<input x="25" y="-10" size="8" rotate="true" text="_" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-20" x1="-40" y2="-20" x2="-21" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="20" x1="-40" y2="20" x2="-21" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="40" y2="0" x2="21" />
<input x="-25" y="50" size="9" rotate="true" text="_" />
<text x="-6" y="5" size="12" text="&amp;" />
<rect width="40" x="-20" y="-35" antialias="false" height="70" style="line-style:normal;line-weight:normal;filling:none;color:black" />
<terminal x="40" y="0" orientation="e" />
<terminal x="-40" y="-20" orientation="w" />
<terminal x="-40" y="20" orientation="w" />
</description>
</definition>

View File

@@ -1,29 +0,0 @@
<definition width="100" version="0.2" hotspot_x="50" hotspot_y="50" height="110" type="element" ic="true" orientation="dyyy" >
<names>
<name lang="ru" >И, трёхвходовый</name>
<name lang="en" >AND 3 inputs</name>
<name lang="fr" >ET 3 entrées</name>
<name lang="es" >Y 3 entradas</name>
<name lang="cs" >A 3 vstupy</name>
<name lang="pt" >E 3 entradas</name>
</names>
<informations>Author: The QElectroTech team
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
<description>
<input x="-46" y="-10" size="8" rotate="true" text="_" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-40" y2="0" x2="-20" />
<input x="-46" y="10" size="8" rotate="true" text="_" />
<input x="-46" y="-30" size="8" rotate="true" text="_" />
<input x="25" y="-10" size="8" rotate="true" text="_" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-20" x1="-40" y2="-20" x2="-21" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="20" x1="-40" y2="20" x2="-21" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="40" y2="0" x2="21" />
<input x="-25" y="50" size="9" rotate="true" text="_" />
<text x="-6" y="5" size="12" text="&amp;" />
<rect width="40" x="-20" y="-35" antialias="false" height="70" style="line-style:normal;line-weight:normal;filling:none;color:black" />
<terminal x="40" y="0" orientation="e" />
<terminal x="-40" y="-20" orientation="w" />
<terminal x="-40" y="20" orientation="w" />
<terminal x="-40" y="0" orientation="w" />
</description>
</definition>

View File

@@ -1,27 +0,0 @@
<definition width="100" version="0.2" hotspot_x="50" hotspot_y="50" height="110" type="element" ic="true" orientation="dyyy" >
<names>
<name lang="ru" >И-НЕ</name>
<name lang="en" >NAND</name>
<name lang="fr" >NON-ET (NAND)</name>
<name lang="es" >NO-Y (NAND)</name>
<name lang="cs" >Ne-A (NAND)</name>
<name lang="pt" >NÃO-E (NAND)</name>
</names>
<informations>Author: The QElectroTech team
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
<description>
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="40" y2="0" x2="26" />
<circle x="20.5" y="-2.5" antialias="true" style="line-style:normal;line-weight:normal;filling:none;color:black" diameter="5" />
<input x="-46" y="10" size="8" rotate="true" text="_" />
<input x="-46" y="-30" size="8" rotate="true" text="_" />
<input x="25" y="-10" size="8" rotate="true" text="_" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-20" x1="-40" y2="-20" x2="-21" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="20" x1="-40" y2="20" x2="-21" />
<input x="-25" y="50" size="9" rotate="true" text="_" />
<text x="-6" y="5" size="12" text="&amp;" />
<rect width="40" x="-20" y="-35" antialias="false" height="70" style="line-style:normal;line-weight:normal;filling:none;color:black" />
<terminal x="40" y="0" orientation="e" />
<terminal x="-40" y="-20" orientation="w" />
<terminal x="-40" y="20" orientation="w" />
</description>
</definition>

View File

@@ -1,24 +0,0 @@
<definition width="100" version="0.2" hotspot_x="50" hotspot_y="50" height="110" type="element" ic="true" orientation="dyyy" >
<names>
<name lang="ru" >НЕ</name>
<name lang="en" >NOT</name>
<name lang="fr" >NON</name>
<name lang="es" >NO</name>
<name lang="cs" >Ne</name>
<name lang="pt" >NÃO</name>
</names>
<informations>Author: The QElectroTech team
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
<description>
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="40" y2="0" x2="26" />
<circle x="20.5" y="-2.5" antialias="true" style="line-style:normal;line-weight:normal;filling:none;color:black" diameter="5" />
<input x="-46" y="-10" size="8" rotate="true" text="_" />
<input x="25" y="-10" size="8" rotate="true" text="_" />
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-39" y2="0" x2="-20" />
<input x="-25" y="50" size="9" rotate="true" text="_" />
<text x="-5" y="5" size="12" text="1" />
<rect width="40" x="-20" y="-35" antialias="false" height="70" style="line-style:normal;line-weight:normal;filling:none;color:black" />
<terminal x="-40" y="0" orientation="w" />
<terminal x="40" y="0" orientation="e" />
</description>
</definition>

Some files were not shown because too many files have changed in this diff Show More