Compare commits

..

310 Commits

Author SHA1 Message Date
xavierqet 4d5a4fdf4f Tag de la version 0.1 finale
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/tags/0.1@313 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-03-08 15:43:41 +00:00
xavierqet 507183cf04 Mise a jour du fichier CREDIT (remerciements)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@312 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-03-08 15:36:51 +00:00
benoit 71ff71d7c1 Ajout sonnerie sirene et avertisseur.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@311 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-03-08 15:26:34 +00:00
xavierqet f28ec9c891 Arrondi des coordonnees dans la collection officielle
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@310 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-03-06 19:43:05 +00:00
xavierqet c746eaf19d Traduction des convertisseurs
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@309 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-03-03 19:12:39 +00:00
benoit 5a309dca33 Ajout de convertisseurs.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@308 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-03-03 17:06:36 +00:00
xavierqet a65a7c548d Ajout d'une categorie principale dans le .desktop
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@306 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-03-02 15:47:08 +00:00
xavierqet 91e3f9e2da Correction d'un bug lors du deplacement d'un element en maintenant Ctrl enfonce.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@305 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-03-01 17:39:44 +00:00
xavierqet 943a9d348a La compensation du bug de rendu de la QGraphicsView se fait desormais en fonction d'un parametre dans la configuration.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@304 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-02-25 18:28:19 +00:00
xavierqet 68e3bbcb37 Correction de la correction pour Windows.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@303 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-02-24 20:55:10 +00:00
xavierqet 9c9ecad579 Corrections pour Windows.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@302 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-02-24 20:50:27 +00:00
xavierqet 801d1acaaa Amelioration du support de l'impression
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@301 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-02-24 20:13:45 +00:00
xavierqet 854336e569 L'installation ajoute desormais une icone et un .desktop sous UNIX
Mise a jour de la DTD, toujours inutilisee


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@300 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-02-23 13:22:23 +00:00
xavierqet 5c7044fbdb L'installation copie desormais les fichiers CREDIT et README avec le fichier LICENSE
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@299 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-02-06 22:44:59 +00:00
xavierqet c3ea627d9c Mise a jour des mentions legales dans le code et dans le dialogue "A propos"
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@298 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-02-06 19:40:45 +00:00
xavierqet c44a8cb51a L'edition directe d'un texte ou d'un champ de texte genere desormais un objet d'annulation
La liste des parties se rafraichit desormais lors d'un annuler/refaire


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@296 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-29 21:22:13 +00:00
benoit b42bc62e9e Mise a jour des sources multifilaires : probleme de rendu a l'impression.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@295 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-27 19:45:17 +00:00
xavierqet 74e301e655 Correction des noms des elements du commit precedent
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@294 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-27 14:36:08 +00:00
benoit 81f18ba8a8 Ajout elements : Tore de courants + bornes.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@293 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-27 14:06:15 +00:00
xavierqet ac19515895 Traduction des elements des deux revisions precedentes
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@292 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-25 19:08:23 +00:00
benoit d6f81b64da Ajout des sources multifilaires
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@291 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-25 18:55:22 +00:00
benoit ea87ae0ee8 Suppression de l'interrupteur laisse pour compatibilite.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@290 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-25 18:40:19 +00:00
benoit 8b5b005a55 ajout composant et modification mineur
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@289 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-25 18:38:49 +00:00
xavierqet 8d3962b71c Traduction des noms de quelques categories
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@288 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-20 21:18:59 +00:00
xavierqet 1a79cd5a94 Correction du commit precedent
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@287 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-20 21:04:09 +00:00
xavierqet e12e4f7076 Traduction en anglais de la categorie des porte-fusibles
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@286 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-20 20:58:26 +00:00
benoit f55421c0c2 Ajout des porte-fusibles.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@285 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-20 20:51:45 +00:00
xavierqet 4d0c61937c Correction dans l'editeur pour le trace d'un polygone
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@284 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-20 20:28:52 +00:00
xavierqet cec010c1e7 Ajout d'un bouton pour effacer le filtre dans le panel d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@283 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-20 18:50:10 +00:00
xavierqet fe06bfd425 Traduction des noms des semi-conducteurs
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@282 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-20 17:27:53 +00:00
benoit 43182b73a0 Retouche qualite symboles + premiers semiconducteurs.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@281 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-20 17:00:33 +00:00
xavierqet cf66a18795 Recharger le panel d'elements reapplique desormais le filtre
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@280 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-19 19:19:11 +00:00
xavierqet 01f4eb4a21 Ajout du fichier spec pour le packaging en RPM
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@279 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-19 18:05:14 +00:00
xavierqet 1e23544364 Corrections sur les noms des elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@278 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-19 00:32:54 +00:00
benoit 71cbc8af6b Probleme d'antialiasing.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@277 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-18 18:36:23 +00:00
benoit 5792d964e7 Ajout d'interrupteurs a plusieurs positions.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@276 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-18 14:47:11 +00:00
benoit 3f0a44cb6a Mise a jour de l'interrupteur (conservation de l'interrupteur non mis a jour pour compatibilite).
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@275 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-18 14:41:54 +00:00
benoit c7a6d7cf67 Ajout moteur et generatrice continue.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@274 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-18 14:20:21 +00:00
benoit c67c2a402e Ajout de composant (lampe clignotante & Lader)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@273 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-18 13:39:14 +00:00
xavierqet 61ce4af8b3 Utilisation du style de jointure "Bevel" plutot que "Miter" dans l'editeur de schemas = harmonisation avec les autres rendus (editeur, depot sur le site)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@272 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-14 21:26:24 +00:00
xavierqet 263b6ba8a7 Correction du nom du fichier pour la borne de continuite
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@271 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-13 16:00:07 +00:00
benoit 717d826078 Ajout de composants
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@270 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-12 19:14:53 +00:00
xavierqet d560883c6b Correction d'un bug lors de l'enregistrement d'un champ de texte sur element avec plusieurs lignes
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@269 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-11 20:01:27 +00:00
xavierqet d2c5fbd8c2 Ajout d'une description et d'un resume rapide de la procedure d'installation.
Mise a jour du fichier CREDIT.
Le tout en anglais et en francais.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@268 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-09 18:01:46 +00:00
xavierqet 8cd94b3137 Correction dans la description du projet : make install copie desormais le binaire sur le systeme
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@267 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-08 20:35:22 +00:00
xavierqet 3fe46a9f3b Ajout du zoom dans l'editeur d'element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@266 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-07 19:40:08 +00:00
xavierqet 7a1ffcbd7f Ajout de barres d'outils a l'editeur d'element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@265 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-07 18:51:18 +00:00
xavierqet ba01ad5cf1 Correction de l'antialiasing sur un moteur
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@264 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-07 18:49:51 +00:00
benoit b561b8394b Ajout d'un moteur triphase a double enroulement.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@263 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-06 14:37:23 +00:00
xavierqet 3ca301ddb4 Correction du conflit de raccourci clavier dans l'editeur d'elements.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@262 bfdf4180-ca20-0410-9c96-a3a8aa849046
2008-01-04 18:55:05 +00:00
xavierqet e5007a1b8b "Panel d'Appareils" renomme en "Panel d'Elements"
Mise a jour des traductions


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@261 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-30 19:10:51 +00:00
benoit ab562f780b Ajout des contacts specifiques aux relais thermiques.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@260 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-30 17:29:16 +00:00
xavierqet 64c92fe23e Corrections des noms de certains elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@259 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-30 16:57:07 +00:00
benoit 45c07ee6b5 Ajout des fins de courses.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@258 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-30 16:29:16 +00:00
benoit 1ba0c114de Ajout du moteur monophase
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@257 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-30 15:46:04 +00:00
xavierqet 8e1ae1233b Dans l'editeur d'elements, le premier niveau des collections est desormais etendu par defaut
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@256 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-29 19:05:50 +00:00
xavierqet 396dd54e8e Ajout d'un champ de texte pour filtrer le contenu du panel d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@255 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-29 15:00:30 +00:00
xavierqet 6bf8eed171 Correction des positions des bornes du sectionneur triphase
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@254 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-23 19:55:37 +00:00
xavierqet 5928bebe35 Correction de l'antialiasing de quelques segments
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@252 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-23 15:55:40 +00:00
xavierqet e30ed320be Ajout de la nouvelle collection
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@251 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-23 15:47:24 +00:00
xavierqet 0562c49480 Suppression de l'ancienne collection
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@250 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-23 15:46:01 +00:00
xavierqet 6b980273a3 Le panel d'elements affiche desormais des categories repliees par defaut
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@249 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-23 01:53:18 +00:00
xavierqet 55ad8c152c Amelioration des messages d'avertissement lors de la suppression d'une categorie
Meilleure gestion des caracteres interdits lors de la creation d'une categorie ou d'un element
Mise a jour des traductions


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@248 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-23 01:15:16 +00:00
xavierqet e9d603d767 Petites ameliorations sur les elements : arrondis de certains valeurs notamment
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@247 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-23 00:01:22 +00:00
xavierqet 314852ce56 Correction d'un bug dans l'editeur d'element : selectionner une partie dans la liste n'affichait pas le widget d'edition de cette partie
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@246 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-22 22:29:42 +00:00
xavierqet e3bd116fd7 Simplification au niveau des methodes selectionChanged
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@245 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-22 16:07:14 +00:00
xavierqet 492751508b Ajustements du sceneRect plus frquents dans l'editeur de schemas.
Ajout du fichier CREDIT avec le texte suivant :
  Merci a Trolltech pour la bibliotheque Qt ( http://trolltech.com/ ), sous licence GNU/GPL.
  Merci a Everaldo Coelho pour le theme d'icones Crystal SVG ( http://www.everaldo.com/crystal/ ) sous licence LGPL, ainsi qu'au projet KDE ( http://www.kde.org/ ).
  Merci a Loic pour ses explications d'ordre mathematique.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@244 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-22 14:59:38 +00:00
xavierqet 8576a3a9d2 Correction d'un bug lors du double-clic sur un champ de texte isole
La barre d'outils de l'editeur d'element peut desormais etre positionnee partout


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@243 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-21 23:53:36 +00:00
xavierqet 591d3f22ff Centralisation du nom de la police a utiliser pour le rendu de texte
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@242 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-21 18:20:18 +00:00
xavierqet 4952f6b531 Ajout d'icones dans le panel d'elements et dans l'editeur d'element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@241 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-20 19:18:31 +00:00
xavierqet 2ad72279a2 Amelioration de la gestion de l'agrandissement des dialogues
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@240 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-19 21:44:43 +00:00
xavierqet a3de8c7d2e Les categories de la collection commune sont desormais editables des le moment ou elles sont accessibles en ecriture
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@239 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-18 21:19:41 +00:00
xavierqet 75e722f1fd Ajout de validateurs dans les widgets d'edition des parties dans l'editeur d'element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@238 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-17 20:37:10 +00:00
xavierqet 0b7c2c917d Ajout de documentation
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@237 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-16 14:05:39 +00:00
xavierqet 9b66975445 Ajout de 10 elements realises par Benoit (correction commit 232)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@236 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-16 14:04:32 +00:00
xavierqet fe19644ec7 Ajout de documentation
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@235 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-16 13:21:28 +00:00
xavierqet b58489fdf3 Amelioration de la gestion des points de jonction : les bifurcations d'un conducteur sont desormais bien detectees.
Le chemin par defaut d'un element colle desormais mieux a la grille.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@234 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-16 12:19:04 +00:00
xavierqet 4fbac85316 Amelioration de la purge des parties non pertinentes a l'enregistrement dans l'editeur d'element.
Il n'est desormais plus possible d'ajouter plusieurs fois le meme objet Part* sur la scene.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@233 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-15 21:57:00 +00:00
xavierqet 675b7a53f9 Ajout de 10 elements realises par Benoit
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@232 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-15 20:39:45 +00:00
xavierqet bddfff8fe6 Correction d'un bug dans l'editeur d'element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@231 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-15 18:59:57 +00:00
xavierqet 9f4db7f582 Ajout de 8 elements realises par Benoit
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@230 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-09 14:06:55 +00:00
xavierqet ec11064f37 Mise a jour des traductions
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@229 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-09 12:05:23 +00:00
xavierqet 289827cc56 Ajout d'une action "Recharger" dans l'editeur d'element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@228 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-09 12:00:11 +00:00
xavierqet 2e77efce00 Il est desormais possible d'autoriser ou non les connexions internes dans l'editeur d'element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@227 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-09 10:54:59 +00:00
xavierqet 649c74d8b2 Connexions internes :
* methodes renommees dans l'editeur de schemas
	* attribut, lecture et ecriture ajoutes dans l'editeur d'element


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@226 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-09 10:30:35 +00:00
xavierqet b4b61ad6f0 Ajout de documentation
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@225 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-09 10:07:33 +00:00
xavierqet 09ed881f0d Ajout de documentation
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@224 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-05 21:16:01 +00:00
xavierqet 826c5180a1 Double-cliquer sur un conducteur permet desormais de l'editer
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@223 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-02 20:41:19 +00:00
xavierqet 3bd1a70faf Sous Windows, QET utilise desormais la variable d'environnement APPDATA
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@222 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-01 21:19:01 +00:00
xavierqet 4fb9b65609 Correction d'un bug dans le listing des parties dans l'editeur d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@221 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-01 19:07:59 +00:00
xavierqet 12c9ec5e03 Double-cliquer sur le cartouche ou les colonnes affiche desormais le dialogue d'edition des informations du schema
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@220 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-01 12:42:31 +00:00
xavierqet 0c66277d74 Ajout du texte de la GNU/GPL au debut de chaque fichier source (*.h, *.cpp)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@219 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-01 10:47:15 +00:00
xavierqet 17d47a34c3 Factorisation de code : ajout de la classe InsetPropertiesWidget
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@218 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-12-01 10:29:03 +00:00
xavierqet e0a2d02ab1 Complement au commit precedent : la verification de version ne prend plus place sur les schemas mais sur les projets
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@217 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-24 22:20:39 +00:00
xavierqet 8e799bed66 Les schemas sont desormais encapsules dans un pseudo-projet.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@216 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-24 18:29:33 +00:00
xavierqet 15185bbc4a Ajout d'un panneau de configuration avec une premiere page pour parametrer les nouveaux schemas
Amelioration de la gestion de la date du cartouche
Mise a jour du --help
Mise a jour des traductions


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@215 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-18 00:22:19 +00:00
xavierqet f0edf251d6 Sont desormais lus dans le fichier de configuration pour les nouveaux schemas :
*les caracteristiques des conducteurs par defaut
	*les dimensions par defaut
	*les informations par defaut du cartouche


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@214 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-14 20:27:45 +00:00
xavierqet 5a17c6fdbb La geometrie et l'etat des fenetres sont desormais enregistrees dans le fichier de configuration.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@213 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-12 15:21:14 +00:00
xavierqet 4856b3dd7b Amelioration de la classe DiagramContent
Modifications pour corriger quelques regressions


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@212 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-11 16:12:45 +00:00
xavierqet be6ba77656 Ajout d'une option d'execution --config-dir pour redefinir le dossier de configuration (et donc la collection d'elements perso)
Cette option d'execution peut etre desactivee avec l'option de compilation QET_ALLOW_OVERRIDE_CD_OPTION
Correction pour l'impression sous Windows


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@211 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-10 17:52:30 +00:00
xavierqet 3abe0be705 Ajout d'une liste des modifications dans l'editeur de schemas
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@210 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-09 15:16:54 +00:00
xavierqet b537214456 Correction d'un warning (gcc 4.1) / d'une erreur (gcc 4.2) a la compilation
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@209 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-09 13:44:30 +00:00
xavierqet bbefc5da8a Ajout d'une classe DiagramContent pour eviter de passer plusieurs listes en parametre lorsqu'on veut transmettre tout ou partie du contenu du schema.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@208 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-09 13:06:51 +00:00
xavierqet 0343517f43 La liste des parties est desormais un onglet a cote de la liste des annulations.
La liste des parties se desactive lors de l'ouverture d'un element en lecture seule.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@207 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-08 18:06:50 +00:00
xavierqet bca6059c39 Ajout d'une liste des parties dans l'editeur d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@206 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-07 20:23:24 +00:00
xavierqet 68629991be Ajout de la nouvelle collection d'elements par Benoit
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@205 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-07 13:56:51 +00:00
xavierqet 317256b134 Corrections diverses
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@204 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-04 17:37:10 +00:00
xavierqet 6c4a7ace87 Activation/desactivation de l'action "Coller ici" en fonction de l'etat du presse-papier
Mise a jour des traductions


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@203 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-03 20:20:34 +00:00
xavierqet 4fa3e665d9 Ajout d'un menu contextuel sur le schema
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@202 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-02 18:04:13 +00:00
xavierqet 937f732782 La couleur des textes est desormais forcee a etre noire
Utilisation de boutons radios dans le menu Fenetres


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@201 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-11-01 23:56:19 +00:00
xavierqet 556b626880 Ajout d'icones sur les boutons lors de l'utilisation du style Plastique
Correction d'un bug avec le menu contextuel du panel d'elements


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@200 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-30 14:00:11 +00:00
xavierqet 3d64380a96 Implementation de 'make install'
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@199 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-28 22:22:56 +00:00
xavierqet e1716f46cf Remplacement des icones 16x16 par des icones 22x22 si possible
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@198 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-28 16:13:51 +00:00
xavierqet 66194ba970 Ajout d'un menu contextuel dans le panel d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@197 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-28 16:03:18 +00:00
xavierqet 5c1260fe0c Ajout des options --help, -v,--version et --license
Le fichier gnugpl.txt s'appelle desormais LICENSE et est integre au binaire QET


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@196 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-28 01:32:57 +00:00
xavierqet 4780f87cb9 Amelioration de la reactivite lors de la selection dans les schemas
Ameliorations mineures dans l'interface


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@195 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-28 00:16:32 +00:00
xavierqet 0ce4341885 Mise a jour des traductions
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@194 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-27 20:08:17 +00:00
xavierqet bece0588cb Possibilite d'ajouter des champs de texte independants au schema
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@193 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-27 13:18:17 +00:00
xavierqet 20a9a5158c Changement dans l'algorithme de modification des conducteurs : un conducteur a desormais 4 profils au lieu d'un
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@192 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-22 20:27:39 +00:00
xavierqet 8d774aa4d6 Ajout de documentation
Ajout du fichier Doxyfile pour parametrer la generation de la documentation


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@191 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-21 16:10:21 +00:00
xavierqet 17e637b7e1 Les dialogues pour ouvrir et enregistrer des fichiers gerent mieux le dossier a afficher par defaut
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@190 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-21 12:53:57 +00:00
xavierqet 22969aabd7 Premier jet pour l'implementation des jonctions de conducteurs
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@189 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-20 19:27:16 +00:00
xavierqet 21cc2c67a6 Correction du bug d'affichage du menu du systray lors de son premier affichage
Correction de 3 avertissements a la compilation dans qetapp.cpp


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@188 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-19 16:21:35 +00:00
xavierqet 3ee3ca48e5 Correction dans une valeur XML : multi au lieu de mutli
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@187 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-17 13:40:53 +00:00
xavierqet 5defabf130 Mise a jour des traductions
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@186 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-16 20:27:10 +00:00
xavierqet 88c117dea1 Recharger la collection ne remet plus systematiquement en haut de l'arborescence
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@185 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-16 12:49:04 +00:00
xavierqet 5cb269af57 Recharger la collection ne developpe plus toute l'arborescence
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@184 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-16 12:04:08 +00:00
xavierqet b545155f7a Le cartouche se rafraichit desormais des la fermture du dialogue d'edition
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@183 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-15 19:42:18 +00:00
xavierqet 2b76d87e36 Petite modification dans le comportement du bouton Zoom ajuste
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@182 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-15 17:44:46 +00:00
xavierqet c5acb79239 Correction dans le code pour contenter gcc
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@181 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-15 17:21:15 +00:00
xavierqet 4786911022 Les conducteurs par defaut sont desormais sauvegardes dans les schemas
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@180 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-14 21:38:27 +00:00
xavierqet 140b258345 L'etat selectionne des elements n'est plus enregistre dans les fichiers
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@179 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-14 18:36:35 +00:00
xavierqet 3f1f84debf Ajout d'une action permettant de specifier le type de conducteur par defaut
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@178 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-14 15:16:37 +00:00
xavierqet 0216eac0be Factorisation de code : reunion des 3 proprietes (type, singleLineProperties et texte) au sein d'une meme classe ConductorProperties
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@177 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-14 14:44:33 +00:00
xavierqet ceb022807d Fichiers conductorproperties.{h,cpp} renommes en conductorpropertieswidget.{h,cpp}
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@176 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-14 10:09:46 +00:00
xavierqet ef515cd424 Modification de l'agencement des menus et barres d'outils
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@175 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-13 17:04:52 +00:00
xavierqet 174fad9e16 Le champ "Fichier" dans Fichier > Exporter est desormais pourvu de l'auto-completion
Amelioration des options de compilation : plus besoin d'entourer les chemins par des \\"
Amelioration mineure du rendu des points de selection sur les conducteurs


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@174 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-13 15:26:01 +00:00
xavierqet 7690fbcccb Ajout du type de conducteur "simple" : ni symbole ni champ de texte
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@173 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-12 18:33:28 +00:00
xavierqet ea9ebb8ec6 Les actions "agrandir le schema" et "retrecir le schema" ajoutent/retirent desormais 80px au lieu de 20px a la hauteur du schema
Amelioration du dialogue pour editer les proprietes du schema


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@172 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-12 12:54:25 +00:00
xavierqet a42ac3a4dc Correction d'un conflit sur le schema lors de l'edition d'un champ de texte : les fleches de directions ne deplacent plus l'element parent du champ de texte
Nettoyage de la correction du conflit sur la touche Suppr (cf commit 154)


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@171 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-12 10:58:57 +00:00
xavierqet 0f86911493 Correction d'un bug dans l'initialisation de la classe Diagram
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@170 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-11 12:51:56 +00:00
xavierqet 0d77b8154d Ajout d'un "workaround" pour eviter un bug ne se produisant que lors du rendu des schemas sur QGraphicsScene sous X11 au zoom par defaut
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@169 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-11 12:34:53 +00:00
xavierqet b91b418c95 Correction d'un bug dans la modification des conducteurs apres un deplacement d'elements
Implementation partielle de l'alignement des conducteurs sur la grille. Lors de la modification manuelle des conducteurs, les segments se fixent sur la grille. L'ancien comportement peut etre obtenu en maintenant la touche Shift enfoncee.
Optimisation des fonctions "Selectionner tout" et "Deselectionner tout"
Remplacement des #define par des attributs static const


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@168 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-10 22:35:32 +00:00
xavierqet 08b01bccb0 Mise a jour de la documentation (sauf dossier editor/)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@167 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-10 17:50:26 +00:00
xavierqet 8e244b17ef Ajout d'icones et mise a jour des traductions
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@166 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-07 19:13:11 +00:00
xavierqet 438d169b36 Gestion de la profondeur dans l'editeur d'element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@165 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-07 18:52:01 +00:00
xavierqet 07e7661cae Mise a jour des traductions
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@164 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-07 11:24:11 +00:00
xavierqet 4369a59d6f Avertissements lors de l'ouverture de documents presentant un numero de version superieur a celui de QET
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@163 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-06 22:32:08 +00:00
xavierqet 0b401487c8 Dans Fichier > Exporter :
*suppression de l'option "conserver les couleurs"
*desactivation par defaut de l'option "dessiner la grille"
Dans l'editeur d'element :
*activation par defaut de l'antialiasing sur les cercles, ellipses et arcs de
cercles poses par l'utilisateur
*le dernier element pose est automatiquement selectionne


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@162 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-06 19:46:44 +00:00
xavierqet 06d95fa90a Implementation d'un menu reinitialiser les conducteurs modifies
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@161 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-06 18:37:21 +00:00
xavierqet d8f96e1ea9 Amelioration du support de l'impression :
*pour le moment, le schema est adapte a la taille de la feuille sans autre possibilite
*necessite le paquet cupsys-bsd sous X11
*L'option QPrinter::HighResolution n'est pas encore exploitee


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@160 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-05 14:42:56 +00:00
xavierqet 579783bba5 Fichier > exporter permet desormais d'enregistrer les schemas au format SVG.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@159 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-05 12:06:39 +00:00
xavierqet 7b71cbb7ae * Option Compile-Time pour definir le chemin du dossier des fichiers de traduction : QET_LANG_PATH
* Option Compile-Time pour definir le chemin du dossier des elements communs : QET_COMMON_COLLECTION_PATH
  * Option Run-Time pour definir le chemin de la collection principale : --common-elements-dir=/path/to/elements/
  * Option Compile-Time pour autoriser ou non l'utilisation de l'option Run-Time precedente : QET_ALLOW_OVERRIDE_CED_OPTION
Les options Compile-Time sont a definir dans le fichier .pro


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@158 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-04 20:34:29 +00:00
xavierqet 0dfed41a75 Ajout du numero de version de QET (pour l'instant, celui de la prochaine release = 0.1) dans :
*le menu "A propos de QET"
*les fichiers *.elmt decrivant les elements
*les fichiers *.qet decrivant les schemas
...et ce afin de gerer les inevitables changements que subiront les formats de fichier a l'avenir.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@157 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-04 17:32:41 +00:00
xavierqet 6fe35cfde8 Amelioration du rendu des symboles sur les conducteurs unifilaires.
Amelioration mineure du rendu de l'effet hover sur les bornes.
Ctrl + Rollette permet desormais de zoomer / dezoomer sur le schema.
Correction d'un bug dans l'editeur de proprietes des conducteurs.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@156 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-04 14:30:52 +00:00
xavierqet 8138b5b86c L'application verifie desormais les fenetres cachees avant de quitter lors de la fermeture de la derniere fenetre visible
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@155 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-04 12:19:01 +00:00
xavierqet 7158935743 Ajout de raccourcis clavier dans l'editeur pour editer les noms, le hotspot et les orientations.
Suppr est desormais le raccourci clavier pour supprimer du texte ou des elements, sans conflit, dans l'editeur de schemas comme dans l'editeur d'elements.
DEL/LED renommee en Voyant/Indicator.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@154 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-03 23:09:05 +00:00
xavierqet 2293cf1f37 Classe Conducer renommee en Conductor
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@153 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-03 17:02:39 +00:00
xavierqet bb00094c0a Les modifications apportees aux proprietes des conducteurs sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@152 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-03 15:51:04 +00:00
xavierqet eb3ed0f99a Implementation d'un menu pour editer un conducteur deja pose
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@151 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-03 13:11:47 +00:00
xavierqet a83a5161df Implementation des methodes et attributs relatifs aux conducteurs unifilaires
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@150 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-10-01 14:08:11 +00:00
xavierqet 7aa903c7a4 Correction d'un bug lors du deplacement d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@149 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-30 14:20:38 +00:00
xavierqet e6fc33f2bd Ajout d'une option pour exporter le schema sans dessiner les bornes
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@148 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-30 12:35:25 +00:00
xavierqet 4e11e516f1 Correction mineure dans les traductions
Correction mineure dans le fichier .pro
Correction d'un bug dans DiagramView::shrink()


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@147 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-29 15:22:38 +00:00
xavierqet 5406224a4f Mise a jour des traductions
Nettoyage des entetes des classes QETDiagramEditor et DiagramView


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@146 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-29 12:54:01 +00:00
xavierqet 90fd503a38 Implementation de la gestion du cleanState dans l'editeur de schemas
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@145 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-29 09:52:35 +00:00
xavierqet e2fc6f4993 Correction d'un bug lors du chargement d'un conducteur modifie
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@144 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-28 21:58:42 +00:00
xavierqet 0405ac447d Les modifications concernant la taille du schema sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@143 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-28 21:48:59 +00:00
xavierqet d9d966e4e9 Simplification du code gerant la mise a jour du sceneRect en cas de modification de la bordure du schema
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@142 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-28 21:02:53 +00:00
xavierqet 9bdbf3aea5 Les editions du cartouche sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@141 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-28 17:39:30 +00:00
xavierqet 2c184a46da Les modifications de conducteur sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@140 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-27 17:42:02 +00:00
xavierqet 27e8ced638 Les pivotements d'elements sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@139 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-27 15:36:15 +00:00
xavierqet bc650ea347 Les editions de champs (conducteurs et elements) sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@138 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-26 22:57:53 +00:00
xavierqet 5150cb38ad Les deplacements d'elements sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@137 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-26 17:14:09 +00:00
xavierqet 099d568f84 Deplacement du fichier qet.cpp
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@136 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-26 12:39:19 +00:00
xavierqet 7be7b90f91 Il est desormais possible d'annuler les couper et les coller
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@135 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-26 12:36:31 +00:00
xavierqet 3c43edb2ee Debut d'implementation des annulations lors de l'edition des schemas
Sont desormais annulables :
-les ajouts d'elements
-les ajouts de conducteurs
-les suppressions d'elements et de conducteurs


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@134 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-25 23:24:36 +00:00
xavierqet a434d2d7fc Ajout d'une icone pour le binaire Windows
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@133 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-22 22:20:58 +00:00
xavierqet c3d16fe173 Amelioration du menu contextuel de l'icone dans le systray
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@132 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-22 13:27:14 +00:00
xavierqet 4ee7fbdb47 La reduction dans le systray tient desormais compte des barres d'outils et docks flottants.
Ajout d'un menu permettant de choisir les barres d'outils et docks affiches dans l'editeur d'element.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@131 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-21 18:59:43 +00:00
xavierqet 2ad6c27998 Le systray reduit ou restaure desormais toutes les fenetres
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@130 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-21 18:07:05 +00:00
xavierqet 438c7ae69e Ajout de la classe QETApp
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@129 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-21 17:13:11 +00:00
xavierqet 0fd59d89ae Retour de la classe QETApp mais comme derivee de QApplication cette fois
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@128 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-21 13:22:18 +00:00
xavierqet 5935ffddcf Classe QETApp renommee en QETDiagramEditor
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@127 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-21 12:35:28 +00:00
xavierqet 459c97467c Correction du bug rendant imprecis l'annulation des deplacements dans l'editeur d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@126 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-21 11:48:37 +00:00
xavierqet 109476589b Implementation d'un nouvel algorithme de modification des conducteurs
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@125 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-20 20:16:08 +00:00
xavierqet 86f62aa972 Ajout d'info-bulles sur les elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@124 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-16 16:46:00 +00:00
xavierqet ca4103b75a Il est desormais possible de deplacer les elements d'un schema avec les fleches du clavier
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@123 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-15 23:45:27 +00:00
xavierqet 271775c8a4 Optimisation du deplacement des elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@122 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-15 22:14:23 +00:00
xavierqet 55c79617e1 Dans l'editeur d'elements, les changements d'orientations sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@121 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-10 22:11:47 +00:00
xavierqet a2a65b78a8 Dans l'editeur d'elements, les changements de noms sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@120 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-10 21:50:17 +00:00
xavierqet b1ea7d6249 Dans l'editeur d'elements, les changements de dimensions et de point de saisie sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@119 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-10 21:12:49 +00:00
xavierqet 2e3afaa13d Retrait des debugs dans les destructeurs de l'editeur
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@118 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-10 19:42:16 +00:00
xavierqet a1cd40ded0 Desormais, tous les menus en rapport avec un schema se desactivent lorsqu'il n'y a plus aucun schema ouvert.
Correction sur la fermeture des schemas.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@117 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-08 19:40:27 +00:00
xavierqet b044ee009c Correction de deux bugs dans la gestion des fenetres MDI
Amelioration du mode de visualisation
Activation des flags d'optimisation dans DiagramView - A tester sur le long terme


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@116 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-08 19:09:59 +00:00
xavierqet 2d7e9fc6b5 Conversion de NewElementWizard en QWizard
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@115 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-07 08:42:36 +00:00
xavierqet 9e1655601f Amelioration des traductions Qt fr
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@114 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-05 22:52:13 +00:00
xavierqet 13f3ec8684 Mise a jour des traductions
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@113 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-05 22:11:45 +00:00
xavierqet 041493a509 Modifications mineures
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@112 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-05 20:42:08 +00:00
xavierqet 7a5ce6d84d Le nombre de segments pour les conducteurs n'est desormais plus limite par les algorithmes.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@111 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-04 20:19:44 +00:00
xavierqet b47dea1460 Amelioration de la gestion de la grille en fonction du zoom utilise
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@110 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-09-04 18:15:41 +00:00
xavierqet d3ef7a5f02 Ajout de boutons pour gerer les collections et elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@109 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-28 21:17:11 +00:00
xavierqet 0fb7b02285 Ajout d'une icone qet-16.png
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@108 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-25 18:18:51 +00:00
xavierqet 853827f25c Gestion du "Clean State" dans l'editeur
Correction d'un bug avec les polygones.
Amelioration du mode lecture seule.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@107 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-25 15:46:09 +00:00
xavierqet 1dd23c8af8 Les modifications de points sur les polygones sont desormais annulables
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@106 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-25 15:04:45 +00:00
xavierqet 4203f869fb Ajout de raccourcis clavier.
L'editeur s'ouvre maintenant dans une fenetre maximisee.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@105 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-25 04:33:32 +00:00
xavierqet 5210bd7a1d Classe CustomElementEditor renommee en QETElementEditor.
Classe EditorScene renommee en ElementScene.
Ajout de la classe ElementView.
Ajout de la classe ElementItemeditor, classe parente des widgets d'edition.
Modification des classes relatives a l'editeur afin que toutes aient acces a l'editeur, a la scene et au QUndoStack. Tous les widgets d'edition heritent donc de ElementItemEditor.
Ajout des methodes abstraites property() et setproperty() dans la classe CustomElementPart et de leur implementation dans les classes qui en derivent.
Sont desormais annulables les modifications : de style, sur les arcs, sur les bornes, sur les ellipses, sur les cercles, sur les champs de texte, sur les textes et sur les lignes.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@104 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-25 03:43:05 +00:00
xavierqet 4ffa080830 Correction pour eviter une segfault lors de la fermeture de l'editeur d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@103 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-23 21:06:15 +00:00
xavierqet 9e7005a829 Debut du support des annulations dans l'editeur d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@102 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-23 15:33:55 +00:00
xavierqet dea9381090 Amelioration mineure de l'editeur de hotspot
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@101 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-19 12:17:44 +00:00
xavierqet 4fbb1f7dd4 Gestion de la modification des dimensions et du point de saisie dans l'editeur
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@100 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-18 22:59:10 +00:00
xavierqet 92a43deb78 Gestion des champs de textes editables dans l'editeur
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@99 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-18 04:42:39 +00:00
xavierqet 900439c00e Prise en compte d'un cas particulier pour les lignes dans l'editeur d'elements.
Si une ligne equivalait a un point (= avait ses deux points egaux), la fonction pour calculer les quatre points delimitant la shape renvoyait un resultat stupide, ce qui genereait de nombreux avertissements en mode release et l'echec d'un assert en mode debug.
De plus, l'enregistrement de ce genre de lignes est desormais evite dans la methode toXml().



git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@98 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-13 23:01:48 +00:00
xavierqet 8fc2bd154b Corrections pour eviter des avertissements avec la lib Qt 4.3
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@97 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-07-18 15:41:13 +00:00
xavierqet 7e5e61c869 Verification de la presence du dossier de configuration lors de la creation d'un objet QETApp
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@96 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-07-16 15:16:58 +00:00
xavierqet ea887f555f Correction d'un bug lors de l'enregistrement des polygones.
Ajout de la gestion des arcs de cercle dans l'editeur d'element.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@95 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-07-10 22:54:22 +00:00
xavierqet 75ca8fd3f2 Ajout de l'editeur d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@94 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-06-30 17:41:07 +00:00
xavierqet 0472392977 La classe CustomElement utilise desormais la classe NamesList pour gerer ses noms
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@93 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-16 20:38:58 +00:00
xavierqet 8cb3499469 Nettoyage d'une bidouille pour prendre en compte la precision lors d'une comparaison entre doubles
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@92 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-16 18:00:18 +00:00
xavierqet fc8b612f33 Correction d'un bug lros de la pose d'un conducteur en zoomant sur le schema
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@91 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-15 19:53:23 +00:00
xavierqet 942109a753 Desactivation des changements de curseur (trop foireux pour l'instant)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@90 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-15 19:22:54 +00:00
xavierqet 003517d4ad Correction d'un bug dans l'assistant de creation d'un nouvel element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@89 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-15 19:14:19 +00:00
xavierqet 0816e0d07b Introduction de la nouvelle classe NamesList
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@88 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-13 15:48:00 +00:00
xavierqet 6894a83ad5 Classe NamesList renommee en NamesListWidget
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@87 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-13 11:50:16 +00:00
xavierqet 22d9d385f4 Mise a jour des traductions
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@86 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-12 22:36:32 +00:00
xavierqet 4135197421 Nettoyage
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@85 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-12 03:13:13 +00:00
xavierqet 7d25e6091f Documentation des methodes non documentees
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@84 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-09 02:56:47 +00:00
xavierqet 79e057c186 Implementation de l'assistant de creation d'un nouvel element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@83 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-04-07 19:25:38 +00:00
xavierqet 86da559748 git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@82 bfdf4180-ca20-0410-9c96-a3a8aa849046 2007-04-07 02:37:57 +00:00
xavierqet 22cd7541fd git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@81 bfdf4180-ca20-0410-9c96-a3a8aa849046 2007-04-06 02:47:25 +00:00
xavierqet df322aeeaf git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@80 bfdf4180-ca20-0410-9c96-a3a8aa849046 2007-04-05 18:02:40 +00:00
xavierqet 0347680f03 git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@79 bfdf4180-ca20-0410-9c96-a3a8aa849046 2007-04-05 02:06:20 +00:00
xavierqet f384a6c073 git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@78 bfdf4180-ca20-0410-9c96-a3a8aa849046 2007-04-05 01:13:14 +00:00
xavierqet b0ff172ee7 git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@77 bfdf4180-ca20-0410-9c96-a3a8aa849046 2007-04-04 02:13:14 +00:00
xavierqet 1ddd93826c Passage des elements XML des schemas en anglais
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@76 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-03-09 19:18:55 +00:00
xavierqet e90a2271a6 Support (basique) des numeros sur les conducteurs
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@75 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-03-08 20:29:13 +00:00
xavierqet b6588177bb Amelioration de la gestion de la scene (prise en compte du cadre et de ses modifications)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@74 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-03-03 23:35:14 +00:00
xavierqet c13c36796f Les modifications faites au schema (colonnes et hauteur) sont desormais enregistrees et relues dans les fichiers
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@73 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-28 20:48:11 +00:00
xavierqet 20fbce3f15 Ajout de l'icone reload.png
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@72 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-27 12:33:59 +00:00
xavierqet 5f437a5bd5 Ajout d'un bouton permettant d'actualiser le panel d'element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@71 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-26 22:42:46 +00:00
xavierqet 6d5927cbe7 Amelioration de la vitesse du rectangle de selection
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@70 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-25 17:53:16 +00:00
xavierqet feaa1f39dd Modifications de certains raccourcis clavier pour eviter des conflits pendant l'edition des champs de texte des elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@69 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-24 20:06:53 +00:00
xavierqet 89885422eb Les champs de texte sont dorenavant sauvegardes dans / lus depuis les fichiers *.qet
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@68 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-24 19:56:29 +00:00
xavierqet cbc12b8aef Ameliorations internes : les classes Conducer et Element ont desormais des methodes fromXml() et toXml()
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@67 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-24 18:37:07 +00:00
xavierqet d9176b5cbf Possibilite d'ajouter des champs de texte editables aux elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@66 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-24 00:26:04 +00:00
xavierqet 73a78a4628 Mise a jour des traductions
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@65 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-23 01:51:13 +00:00
xavierqet c71ede3403 Lifting des moteurs et transformateurs
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@64 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-22 20:18:58 +00:00
xavierqet 831cc2a515 Ajout de la possibilite de mettre des polygones non fermes lors du dessin des elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@63 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-22 19:20:02 +00:00
xavierqet dcfc774518 Ajout de la possibilite de mettre du texte statique lors du dessin des elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@62 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-22 18:46:51 +00:00
xavierqet 7da7f48ef6 Correction d'un bug de la revision 60
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@61 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-18 21:45:44 +00:00
xavierqet b59040234a Il est desormais possible d'enregistrer les conducteurs modifies dans les fichiers
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@60 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-18 19:33:15 +00:00
xavierqet c1f9d430b6 Traduction des attributs et noms des tags XML utilises pour les descriptions des elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@59 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-18 00:06:36 +00:00
xavierqet bc79ea04b8 Remplissage en blanc de quelques elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@58 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-17 22:10:40 +00:00
xavierqet 4df127b6f7 Retrait du menu et des fonctions liees a l'antialiasing du DiagramView
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@57 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-17 18:59:18 +00:00
xavierqet 8e56774ad9 Correction dans l'algorithme du commit 54
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@56 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-15 21:57:53 +00:00
xavierqet e73773ea55 Le curseur change lorsqu'on le passe au-dessus des points de modification des conducteurs.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@55 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-15 20:00:20 +00:00
xavierqet 8c491de218 Desactivation temporaire de l'edition des conducteurs par les points de jonction ; Implementation de l'edition des conducteurs par des points de saisie situes en leur milieu
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@54 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-14 01:08:29 +00:00
xavierqet 1e486712cc Ajout de la possibilite de modifier la hauteur du schema
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@53 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-03 02:00:18 +00:00
xavierqet 039949c0ee Correction pour Fichier > Exporter
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@52 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-02 19:10:59 +00:00
xavierqet 6e5b5c30b7 Correction dans le fichier *.pro
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@51 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-02 17:46:58 +00:00
xavierqet f3417a609a Amelioration de l'interface Fichier > Exporter (Oui, encore)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@50 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-02 17:40:07 +00:00
xavierqet 982b2bce9a Fichier > exporter exporte desormais le contenu du cadre
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@49 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-02-01 01:07:26 +00:00
xavierqet a5cc50f5ab Classes "ElementPerso" et "PanelAppareils" renommees en "CustomElement" et "ElementsPanel"
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@48 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-01-30 22:32:21 +00:00
xavierqet 29d35a2007 Classe "ElementFixe" renommee en "FixedElement"
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@47 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-01-30 21:49:42 +00:00
xavierqet 9d14e21360 Classe "Conducteur" renommee en "Conducer"
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@46 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-01-29 20:32:38 +00:00
xavierqet 628494ae80 Classe "Borne" renommee en "Terminal"
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@45 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-01-29 20:14:26 +00:00
xavierqet 2140671394 Classes "Schema" et "SchemaVue" renommees en "Diagram" et "DiagramView"
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@44 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-01-29 00:41:12 +00:00
xavierqet 647a0a8985 Apparition d'un ensemble Cadre + cartouche (classe BorderInset)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@43 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-01-28 00:53:17 +00:00
xavierqet 9a45f81f98 Amelioration de l'interface Fichier > Exporter
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@42 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-01-20 18:11:42 +00:00
xavierqet 7537202a6a Possibilite de modifier les conducteurs. Attention, version encore buggee.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@41 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-01-05 14:29:08 +00:00
xavierqet 3136233065 Prolongement des bornes pour ajouter des points d'accroche ulterieurement
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@40 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-12-03 17:44:20 +00:00
xavierqet cebf9f5675 Petite amelioration empechant de selectionner un conducteur par inadvertance lorsqu'on veut en poser un
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@39 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-12-03 12:48:33 +00:00
xavierqet 04b594ab2c Amelioration du rendu lors des deplacements d'elements, mais sans les bugs du commit 37 ; correction d'un bug : les conducteurs ne se mettaient pas bien a jour lors de la rotation d'un element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@38 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-12-02 23:42:59 +00:00
xavierqet 4cb641fa2b Amelioration du rendu des conducteurs lors du deplacement d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@37 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-30 18:05:02 +00:00
xavierqet f1bfb71f1e Ajout de la possibilite de selectionner et supprimer des conducteurs
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@36 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-26 21:35:05 +00:00
xavierqet 8258854558 Documentation de la classe ElementPerso
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@35 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-21 21:25:45 +00:00
xavierqet 8b630b12dd Implementation des arcs de cercle
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@34 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-21 10:26:43 +00:00
xavierqet dfc4f26144 Meilleure gestion des styles de traits (epaisseur, style) et de formes (remplissage) ; ajout de la forme "ellipse"
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@33 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-21 09:42:34 +00:00
xavierqet 6305019380 Gestion multilingue des noms des elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@32 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-20 17:46:13 +00:00
xavierqet f1c5d494b3 Gestion multilingue des noms des categories dans le panel d'appareils
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@31 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-19 22:04:15 +00:00
xavierqet b3396c10a3 Ajout de la possibilite de modifier les attributs du schema : titre, auteur, date
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@30 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-19 18:40:03 +00:00
benoit 552db3c903 Probleme de nom du capteur NF
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@29 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-19 14:27:57 +00:00
benoit e7ef708dbe le capteur NF (erreur de svn)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@28 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-19 14:16:19 +00:00
xavierqet eb62046353 Amelioration de la version francaise
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@27 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-19 13:57:45 +00:00
benoit 423a586c75 Ajout du Capteur NF et ajout des commentaire des les elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@26 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-18 18:14:26 +00:00
benoit 6d92b1c49c Correction au niveau des libertes de rotation sur les elements.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@25 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-17 16:06:20 +00:00
benoit 9794eaf690 Ajout des nouveaux elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@24 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-17 15:29:49 +00:00
xavierqet 451f1ce793 Suppression des anciens elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@23 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-17 15:21:42 +00:00
xavierqet 332f106763 Correctifs pour Windows
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@22 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-16 19:27:29 +00:00
xavierqet 01d7e97099 Debut de prise en charge de l'internationalisation : la langue de l'interface est choisie en fonction de la langue du systeme (locale)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@21 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-16 18:27:53 +00:00
xavierqet c4e7712004 Gestion des categories sous forme de dossiers, deuxieme partie
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@20 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-15 22:49:34 +00:00
xavierqet 0f3b2926bc Debut de gestion des categories sous forme de dossiers
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@19 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-11 18:25:42 +00:00
xavierqet dd3a9f8894 Amelioration des indications de la barre de statut (en francais et en anglais) et documentation de la classe QETApp
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@18 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-11 13:56:40 +00:00
xavierqet 446acbf7a2 Mise a jour de la traduction anglaise, amelioration du dialogue "A propos" et possible resolution de la segfault survenant apres la rotation et l'effacement d'un element
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@17 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-10 21:31:18 +00:00
xavierqet fb0dc4f705 Correction du bug du curseur qui ne chanegait pas en passant du mode visualisation au mode selection
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@16 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-09 21:43:20 +00:00
xavierqet ddf173b47b Mise en place du nouveau systeme de gestion de la rotation des elements - attention : changements dans l'interpretation de certains attributs des fichiers XML => les "sens" des elements sont desormais un chiffre : 0 = nord, 1 = est, 2 = sud, 3 = ouest
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@15 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-09 19:19:51 +00:00
xavierqet c51ca764dd Possibilite de faire des traits pointilles avec <ligne style="dashed"
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@14 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-04 14:27:54 +00:00
xavierqet 58152e33eb Modification permettant de definir qu'un element peut avoir un conducteur entre ses propres bornes
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@13 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-04 13:57:40 +00:00
xavierqet f0a0eb6661 Correction d'une erreur lors du chargement des elements persos
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@12 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-04 11:06:07 +00:00
xavierqet 2ee25ee7b2 Petite modification pour exporter les images sans la grille
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@11 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-11-03 23:09:29 +00:00
xavierqet 6ebd094c83 Introduction d'un semblant de debut de simulacre de DTD pour decrire les definitions des elements.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@10 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-31 23:24:16 +00:00
xavierqet 27a2809f57 Petite modification pour les compilateurs chiants comme euh.. au hasard... gcc 4.1.x ?
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@9 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-30 19:28:16 +00:00
xavierqet 859c7c5857 Amelioration de l'apparence du panel d'appareils
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@8 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-29 17:52:57 +00:00
xavierqet 45a71bc573 Correction pour la gestion du dossier perso sous Windows
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@7 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-28 20:28:44 +00:00
xavierqet f0c4be6a43 Gestion de deux dossiers distincts pour les descriptions XML des elements ; amelioration du panel d'appareils.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@6 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-28 19:39:43 +00:00
xavierqet 60fe06f126 Petite modification pour faciliter la fermeture des fichiers
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-28 13:41:50 +00:00
xavierqet 21beb6de35 Suppression des classes correspondant a des elements codes en durs au profit des descriptions XML chargeables par la classe ElementPerso
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-28 13:35:02 +00:00
xavierqet 186e9751d5 Gestion du dessin des elements persos avec des coordonnees reelles
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-28 13:17:50 +00:00
xavierqet 0de5b7ebfd Correction d'un bug lors de la fermeture de la fenetre de l'application (annuler fermait quand meme la fenetre)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@2 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-28 11:17:14 +00:00
xavierqet 5cadf173c7 Import initial
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@1 bfdf4180-ca20-0410-9c96-a3a8aa849046
2006-10-27 15:47:22 +00:00
406 changed files with 35355 additions and 164 deletions
+23
View File
@@ -0,0 +1,23 @@
[en]
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 Nicolas for the Mac OS X experimentations.
Thanks to Remi Collet for the Fedora packaging.
Thanks to TuxFamily ( http://tuxfamily.org ) for hosting the project.
Thanks to `Nishiki' for his elements and his support.
[fr]
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 à Nicolas pour les expérimentations Mac OS X.
Merci à Remi Collet pour les paquets Fedora.
Merci à TuxFamily ( http://tuxfamily.org ) pour l'hébergement du projet.
Merci à `Nishiki' pour ses éléments et son soutien.
+239
View File
@@ -0,0 +1,239 @@
# Doxyfile 1.5.1-KDevelop
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = QElectroTech
PROJECT_NUMBER = 0.1
OUTPUT_DIRECTORY =
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = French
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH = /home/data/chaos/projets/qet/qelectrotech/
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
BUILTIN_STL_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = NO
GENERATE_TESTLIST = NO
GENERATE_BUGLIST = NO
GENERATE_DEPRECATEDLIST= NO
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = /home/data/chaos/projets/qet/qelectrotech
FILE_PATTERNS = *.h \
*.cpp
RECURSIVE = YES
EXCLUDE = moc_* \
.svn \
release \
debug
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE = QElectroTech.tag
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = YES
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
+19
View File
@@ -0,0 +1,19 @@
[en]
Requirements :
libQt4 (see packages libqt4*)
cupsys-bsd for printing
Howto compile :
$ qmake (qmake-qt4 for Debian-based systems)
$ make
# make install
[fr]
Pré-requis :
libQt4 (paquets libqt4*)
cupsys-bsd pour l'impression
Comment compiler :
$ qmake (qmake-qt4 pour les systèmes basés sur Debian)
$ make
# make install
+342
View File
@@ -0,0 +1,342 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
+9
View File
@@ -0,0 +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.
[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.
+138
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 « A propos »
*/
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 « Auteurs »
*/
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 « Accord de Licence »
*/
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);
}
+43
View File
@@ -0,0 +1,43 @@
/*
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/>.
*/
#ifndef ABOUTQET_H
#define ABOUTQET_H
#include <QtGui>
/**
Cette classe represente la boite de dialogue
« A propos de QElectroTech »
*/
class AboutQET : public QDialog {
Q_OBJECT
// constructeurs, destructeur
public:
AboutQET(QWidget * = 0);
virtual ~AboutQET();
private:
AboutQET(AboutQET &);
// methodes
private:
QWidget *titre() const;
QWidget *ongletAPropos() const;
QWidget *ongletAuteurs() const;
QWidget *ongletLicence() const;
};
#endif
+231
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());
}
+182
View File
@@ -0,0 +1,182 @@
/*
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/>.
*/
#ifndef BORDERINSET_H
#define BORDERINSET_H
#include "insetproperties.h"
#include <QObject>
#include <QRectF>
#include <QPainter>
#include <QDate>
/**
Cette classe represente l'ensemble bordure + cartouche qui encadre le
schema electrique.
*/
class BorderInset : public QObject {
Q_OBJECT
// constructeurs, destructeur
public:
BorderInset(QObject * = 0);
virtual ~BorderInset();
private:
BorderInset(const BorderInset &);
// methodes
public:
void draw(QPainter *, qreal = 0.0, qreal = 0.0);
// methodes d'acces en lecture aux dimensions
/// @return le nombre de colonnes du schema
int nbColumn() const { return(nb_columns); }
/// @return la taille des colonnes en pixels
qreal columnsWidth() const { return(columns_width); }
/// @return la hauteur, en pixels, des en-tetes des colonnes
qreal columnsHeaderHeight() const { return(columns_header_height); }
/// @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); }
/// @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
QString author() const { return(bi_author); }
/// @return le champ "Date" du cartouche
QDate date() const { return(bi_date); }
/// @return le champ "Titre" du cartouche
QString title() const { return(bi_title); }
/// @return le champ "Folio" du cartouche
QString folio() const { return(bi_folio); }
/// @return le champ "Fichier" du cartouche
QString fileName() const { return(bi_filename); }
// methodes d'acces en lecture aux options
/// @return true si le cartouche est affiche, false sinon
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 la bordure est affichee, false sinon
bool borderIsDisplayed() const { return(display_border); }
// methodes d'acces en ecriture aux dimensions
void addColumn ();
void removeColumn ();
void setNbColumns (int);
void setColumnsWidth (const qreal &);
void setColumnsHeaderHeight(const qreal &);
void setColumnsHeight (const qreal &);
void setInsetWidth (const qreal &);
void setInsetHeight (const qreal &);
void adjustInsetToColumns ();
// 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) { bi_title = title; }
/// @param folio le nouveau contenu du champ "Folio"
void setFolio (const QString &folio) { bi_folio = folio; }
/// @param filename le nouveau contenu du champ "Fichier"
void setFileName (const QString &filename) { bi_filename = filename; }
/// @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
/// @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();
// signaux
signals:
/**
Signal emis lorsque la bordure change
@param old_border Ancienne bordure
@param new_border Nouvelle bordure
*/
void borderChanged(QRectF old_border, QRectF new_border);
// attributs
private:
// informations du cartouche
QString bi_author;
QDate bi_date;
QString bi_title;
QString bi_folio;
QString bi_filename;
// dimensions du cadre et du cartouche
int nb_columns;
int min_nb_columns;
qreal columns_width;
qreal columns_header_height;
qreal columns_height;
qreal min_columns_height;
qreal inset_width;
qreal inset_height;
// rectangles utilises pour le dessin
QRectF border;
QRectF inset;
QRectF inset_author;
QRectF inset_date;
QRectF inset_title;
QRectF inset_file;
QRectF inset_folio;
// booleens pour les options de dessin
bool display_inset;
bool display_columns;
bool display_border;
};
#endif
+1279
View File
File diff suppressed because it is too large Load Diff
+141
View File
@@ -0,0 +1,141 @@
/*
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/>.
*/
#ifndef CONDUCTOR_H
#define CONDUCTOR_H
#include <QtGui>
#include "terminal.h"
#include "conductorprofile.h"
#include "conductorproperties.h"
#include "diagramtextitem.h"
class ConductorSegment;
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 QGraphicsPathItem {
// constructeurs, destructeur
public:
Conductor(Terminal *, Terminal *, Element * = 0, QGraphicsScene * = 0);
virtual ~Conductor();
private:
Conductor(const Conductor &);
// attributs
public:
enum { Type = UserType + 1001 };
/// premiere borne a laquelle le fil est rattache
Terminal *terminal1;
/// deuxieme borne a laquelle le fil est rattache
Terminal *terminal2;
// methodes
public:
/**
permet de caster un QGraphicsItem en Conductor avec qgraphicsitem_cast
@return le type de QGraphicsItem
*/
virtual int type() const { return Type; }
void destroy();
/// @return true si ce conducteur est detruit
bool isDestroyed() const { return(destroyed); }
Diagram *diagram() const;
void updateWithNewPos(const QRectF &, const Terminal *, const QPointF &);
void update(const QRectF & = QRectF());
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
QRectF boundingRect() const;
virtual QPainterPath shape() const;
qreal length();
ConductorSegment *middleSegment();
bool containsPoint(const QPointF &) const;
QString text() const;
void setText(const QString &);
static bool valideXml(QDomElement &);
bool fromXml(QDomElement &);
QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
const QList<ConductorSegment *> segmentsList() const;
void setProperties(const ConductorProperties &);
ConductorProperties properties() const;
void setProfile(const ConductorProfile &, Qt::Corner);
ConductorProfile profile(Qt::Corner) const;
void setProfiles(const ConductorProfilesGroup &);
ConductorProfilesGroup profiles() const;
void readProperties();
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *);
private:
/// caracteristiques du conducteur
ConductorProperties properties_;
/// booleen indiquant si le fil est encore valide
bool destroyed;
/// champ de texte editable pour les conducteurs non unifilaires
DiagramTextItem *text_item;
/// segments composant le conducteur
ConductorSegment *segments;
/// attributs lies aux manipulations a la souris
QPointF press_point;
bool moving_point;
bool moving_segment;
int moved_point;
qreal previous_z_value;
ConductorSegment *moved_segment;
/// booleen indiquant si le conducteur a ete modifie manuellement par l'utilisateur
bool modified_path;
/// booleen indiquant s'il faut sauver le profil courant au plus tot
bool has_to_save_profile;
/// profil du conducteur : "photo" de ce a quoi le conducteur doit ressembler - il y a un profil par type de trajet
ConductorProfilesGroup conductor_profiles;
/// QPen et QBrush utilises pour dessiner les conducteurs
static QPen conductor_pen;
static QBrush conductor_brush;
static QBrush square_brush;
static bool pen_and_brush_initialized;
private:
void segmentsToPath();
void saveProfile(bool = true);
void priv_calculeConductor(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
void priv_modifieConductor(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
uint nbSegments(QET::ConductorSegmentType = QET::Both) const;
QList<QPointF> segmentsToPoints() const;
QSet<Conductor *> relatedConductors() const;
QList<ConductorBend> bends() const;
QList<QPointF> junctions() const;
void pointsToSegments(QList<QPointF>);
bool hasClickedOn(QPointF, QPointF) const;
void calculateTextItemPosition();
Qt::Corner currentPathType() const;
void deleteSegments();
static int getCoeff(const qreal &, const qreal &);
static int getSign(const qreal &);
QHash<ConductorSegmentProfile *, qreal> shareOffsetBetweenSegments(const qreal &offset, const QList<ConductorSegmentProfile *> &, const qreal & = 0.01) const;
static QPointF extendTerminal(const QPointF &, QET::Orientation, qreal = 9.0);
static qreal conductor_bound(qreal, qreal, qreal, qreal = 0.0);
static qreal conductor_bound(qreal, qreal, bool);
static Qt::Corner movementType(const QPointF &, const QPointF &);
};
#endif
+157
View File
@@ -0,0 +1,157 @@
/*
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 "conductorprofile.h"
#include "conductor.h"
#include "conductorsegmentprofile.h"
/// Constructeur
ConductorProfile::ConductorProfile() {
}
/**
Constructeur
@param conductor conducteur dont il faut extraire le profil
*/
ConductorProfile::ConductorProfile(Conductor *conductor) {
fromConductor(conductor);
}
/**
Constructeur de copie
@param c autre conducteur
*/
ConductorProfile::ConductorProfile(const ConductorProfile &c) {
beginOrientation = c.beginOrientation;
endOrientation = c.endOrientation;
foreach(ConductorSegmentProfile *csp, c.segments) {
segments << new ConductorSegmentProfile(*csp);
}
}
/**
Operateur =
@param c autre conducteur
*/
ConductorProfile &ConductorProfile::operator=(const ConductorProfile &c) {
if (&c == this) return(*this);
// supprime ses informations
setNull();
// copie les informations de l'autre profil de conducteur
beginOrientation = c.beginOrientation;
endOrientation = c.endOrientation;
foreach(ConductorSegmentProfile *csp, c.segments) {
segments << new ConductorSegmentProfile(*csp);
}
return(*this);
}
/// destructeur
ConductorProfile::~ConductorProfile() {
setNull();
}
/// @return true si le profil est nul
bool ConductorProfile::isNull() const {
return(segments.isEmpty());
}
/// supprime les segments du profil de conducteur
void ConductorProfile::setNull() {
foreach(ConductorSegmentProfile *csp, segments) delete csp;
segments.clear();
}
/// @return la largeur occupee par le conducteur
qreal ConductorProfile::width() const {
qreal width = 0.0;
foreach(ConductorSegmentProfile *csp, segments) {
if (csp -> isHorizontal) width += csp -> length;
}
return(width);
}
/// @return la hauteur occupee par le conducteur
qreal ConductorProfile::height() const{
qreal height = 0.0;
foreach(ConductorSegmentProfile *csp, segments) {
if (!csp -> isHorizontal) height += csp -> length;
}
return(height);
}
/**
@param type Type de Segments
@return Le nombre de segments composant le conducteur.
*/
uint ConductorProfile::nbSegments(QET::ConductorSegmentType type) const {
if (type == QET::Both) return(segments.count());
uint nb_seg = 0;
foreach(ConductorSegmentProfile *csp, segments) {
if (type == QET::Horizontal && csp -> isHorizontal) ++ nb_seg;
else if (type == QET::Vertical && !csp -> isHorizontal) ++ nb_seg;
}
return(nb_seg);
}
/// @return les segments horizontaux de ce profil
QList<ConductorSegmentProfile *> ConductorProfile::horizontalSegments() {
QList<ConductorSegmentProfile *> segments_list;
foreach(ConductorSegmentProfile *csp, segments) {
if (csp -> isHorizontal) segments_list << csp;
}
return(segments_list);
}
/// @return les segments verticaux de ce profil
QList<ConductorSegmentProfile *> ConductorProfile::verticalSegments() {
QList<ConductorSegmentProfile *> segments_list;
foreach(ConductorSegmentProfile *csp, segments) {
if (!csp -> isHorizontal) segments_list << csp;
}
return(segments_list);
}
/**
Reconstruit le profil a partir d'un conducteur existant
*/
void ConductorProfile::fromConductor(Conductor *conductor) {
// supprime les segments precedents
setNull();
foreach(ConductorSegment *conductor_segment, conductor -> segmentsList()) {
segments << new ConductorSegmentProfile(conductor_segment);
}
beginOrientation = conductor -> terminal1 -> orientation();
endOrientation = conductor -> terminal2 -> orientation();
}
/**
Permet de debugger un profil de conducteur
@param d Object QDebug a utiliser pour l'affichage des informations de debug
@param t Profil de conducteur a debugger
*/
QDebug &operator<<(QDebug d, ConductorProfile &t) {
d << "ConductorProfile {";
foreach(ConductorSegmentProfile *csp, t.segments) {
d << "CSP" << (csp -> isHorizontal ? "horizontal" : "vertical") << ":" << csp -> length << ",";
}
d << "}";
return(d.space());
}
+58
View File
@@ -0,0 +1,58 @@
/*
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/>.
*/
#ifndef CONDUCTOR_PROFILE_H
#define CONDUCTOR_PROFILE_H
#include <QList>
#include "qet.h"
class Conductor;
class ConductorSegmentProfile;
/**
Cette classe contient le profil (= les caracteristiques essentielles) d'un
conducteur.
*/
class ConductorProfile {
public:
// constructeurs, destructeur
ConductorProfile();
ConductorProfile(Conductor *conductor);
ConductorProfile(const ConductorProfile &);
ConductorProfile &operator=(const ConductorProfile &);
virtual ~ConductorProfile();
// attributs
public:
/// Segment composant le profil du conducteur
QList<ConductorSegmentProfile *> segments;
/// Orientation de la borne de depart du profil
QET::Orientation beginOrientation;
/// Orientation de la borne d'arrivee du profil
QET::Orientation endOrientation;
// methodes
public:
bool isNull() const;
void setNull();
qreal width() const;
qreal height() const;
uint nbSegments(QET::ConductorSegmentType) const;
QList<ConductorSegmentProfile *> horizontalSegments();
QList<ConductorSegmentProfile *> verticalSegments();
void fromConductor(Conductor *);
};
QDebug &operator<<(QDebug d, ConductorProfile &);
#endif
+319
View File
@@ -0,0 +1,319 @@
/*
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 "conductorproperties.h"
/**
Constructeur par defaut
*/
SingleLineProperties::SingleLineProperties() :
hasGround(true),
hasNeutral(true),
phases(1)
{
}
/// Destructeur
SingleLineProperties::~SingleLineProperties() {
}
/**
Definit le nombre de phases (0, 1, 2, ou 3)
@param n Nombre de phases
*/
void SingleLineProperties::setPhasesCount(int n) {
phases = qBound(0, n, 3);
}
/// @return le nombre de phases (0, 1, 2, ou 3)
unsigned short int SingleLineProperties::phasesCount() {
return(phases);
}
/**
Dessine les symboles propres a un conducteur unifilaire
@param painter QPainter a utiliser pour dessiner les symboles
@param direction direction du segment sur lequel les symboles apparaitront
@param rect rectangle englobant le dessin ; utilise pour specifier a la fois la position et la taille du dessin
*/
void SingleLineProperties::draw(QPainter *painter, QET::ConductorSegmentType direction, const QRectF &rect) {
// s'il n'y a rien a dessiner, on retourne immediatement
if (!hasNeutral && !hasGround && !phases) return;
// prepare le QPainter
painter -> save();
QPen pen(painter -> pen());
pen.setCapStyle(Qt::FlatCap);
pen.setJoinStyle(Qt::MiterJoin);
painter -> setPen(pen);
painter -> setRenderHint(QPainter::Antialiasing, true);
uint symbols_count = (hasNeutral ? 1 : 0) + (hasGround ? 1 : 0) + phases;
qreal interleave;
qreal symbol_width;
if (direction == QET::Horizontal) {
interleave = rect.width() / (symbols_count + 1);
symbol_width = rect.width() / 12;
for (uint i = 1 ; i <= symbols_count ; ++ i) {
// dessine le tronc du symbole
QPointF symbol_p1(rect.x() + (i * interleave) + symbol_width, rect.y() + rect.height() * 0.75);
QPointF symbol_p2(rect.x() + (i * interleave) - symbol_width, rect.y() + rect.height() * 0.25);
painter -> drawLine(QLineF(symbol_p1, symbol_p2));
// dessine le reste des symboles terre et neutre
if (hasGround && i == 1) {
drawGround(painter, direction, symbol_p2, symbol_width * 2.0);
} else if (hasNeutral && ((i == 1 && !hasGround) || (i == 2 && hasGround))) {
drawNeutral(painter, direction, symbol_p2, symbol_width * 1.35);
}
}
} else {
interleave = rect.height() / (symbols_count + 1);
symbol_width = rect.height() / 12;
for (uint i = 1 ; i <= symbols_count ; ++ i) {
// dessine le tronc du symbole
QPointF symbol_p2(rect.x() + rect.width() * 0.75, rect.y() + (i * interleave) - symbol_width);
QPointF symbol_p1(rect.x() + rect.width() * 0.25, rect.y() + (i * interleave) + symbol_width);
painter -> drawLine(QLineF(symbol_p1, symbol_p2));
// dessine le reste des symboles terre et neutre
if (hasGround && i == 1) {
drawGround(painter, direction, symbol_p2, symbol_width * 2.0);
} else if (hasNeutral && ((i == 1 && !hasGround) || (i == 2 && hasGround))) {
drawNeutral(painter, direction, symbol_p2, symbol_width * 1.5);
}
}
}
painter -> restore();
}
/**
Dessine le segment correspondant au symbole de la terre sur un conducteur unifilaire
@param painter QPainter a utiliser pour dessiner le segment
@param direction direction du segment sur lequel le symbole apparaitra
@param center centre du segment
@param size taille du segment
*/
void SingleLineProperties::drawGround(QPainter *painter, QET::ConductorSegmentType direction, QPointF center, qreal size) {
painter -> save();
// prepare le QPainter
painter -> setRenderHint(QPainter::Antialiasing, false);
QPen pen2(painter -> pen());
pen2.setCapStyle(Qt::SquareCap);
painter -> setPen(pen2);
// dessine le segment representant la terre
qreal half_size = size / 2.0;
QPointF offset_point(
(direction == QET::Horizontal) ? half_size : 0.0,
(direction == QET::Horizontal) ? 0.0 : half_size
);
painter -> drawLine(
QLineF(
center + offset_point,
center - offset_point
)
);
painter -> restore();
}
/**
Dessine le cercle correspondant au symbole du neutre sur un conducteur unifilaire
@param painter QPainter a utiliser pour dessiner le segment
@param direction direction du segment sur lequel le symbole apparaitra
@param center centre du cercle
@param size diametre du cercle
*/
void SingleLineProperties::drawNeutral(QPainter *painter, QET::ConductorSegmentType, QPointF center, qreal size) {
painter -> save();
// prepare le QPainter
if (painter -> brush() == Qt::NoBrush) painter -> setBrush(Qt::black);
painter -> setPen(Qt::NoPen);
// desine le cercle representant le neutre
painter -> drawEllipse(
QRectF(
center - QPointF(size / 2.0, size / 2.0),
QSizeF(size, size)
)
);
painter -> restore();
}
/**
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(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
de l'element e
@param e Element XML dont les attributs seront lus
*/
void SingleLineProperties::fromXml(QDomElement &e) {
hasGround = e.attribute("ground") == "true";
hasNeutral = e.attribute("neutral") == "true";
setPhasesCount(e.attribute("phase").toInt());
}
/**
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(QDomDocument &d, QDomElement &e) const {
e.setAttribute("type", typeToString(type));
if (type == Single) {
singleLineProperties.toXml(d, e);
} else if (type == Multi) {
e.setAttribute("num", text);
}
}
/**
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) {
if (e.attribute("type") == typeToString(Single)) {
// recupere les parametres specifiques a un conducteur unifilaire
singleLineProperties.fromXml(e);
type = Single;
} else if (e.attribute("type") == typeToString(Simple)) {
type = Simple;
} else {
// recupere le champ de texte
text = e.attribute("num");
type = Multi;
}
}
/**
@param settings Parametres a ecrire
@param prefix prefix a ajouter devant les noms des parametres
*/
void ConductorProperties::toSettings(QSettings &settings, const QString &prefix) const {
settings.setValue(prefix + "type", typeToString(type));
settings.setValue(prefix + "text", text);
singleLineProperties.toSettings(settings, prefix);
}
/**
@param settings Parametres a lire
@param prefix prefix a ajouter devant les noms des parametres
*/
void ConductorProperties::fromSettings(QSettings &settings, const QString &prefix) {
QString setting_type = settings.value(prefix + "type", typeToString(Multi)).toString();
if (setting_type == typeToString(Single)) {
type = Single;
} else if (setting_type == typeToString(Simple)) {
type = Simple;
} else {
type = Multi;
}
singleLineProperties.fromSettings(settings, prefix);
text = settings.value(prefix + "text", "_").toString();
}
/**
@param t type du conducteur
*/
QString ConductorProperties::typeToString(ConductorType t) {
switch(t) {
case Simple: return("simple");
case Single: return("single");
case Multi: return("multi");
default: 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
*/
int ConductorProperties::operator==(const ConductorProperties &other) {
return(
other.type == type &&\
other.text == text &&\
other.singleLineProperties == singleLineProperties
);
}
/**
@param other l'autre ensemble de proprietes avec lequel il faut effectuer la comparaison
@return true si les deux ensembles de proprietes sont differents, false sinon
*/
int ConductorProperties::operator!=(const ConductorProperties &other) {
return(
other.type != type ||\
other.text != text ||\
other.singleLineProperties != singleLineProperties
);
}
/**
@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
*/
int SingleLineProperties::operator==(const SingleLineProperties &other) const {
return(
other.hasGround == hasGround &&\
other.hasNeutral == hasNeutral &&\
other.phases == phases
);
}
/**
@param other l'autre ensemble de proprietes avec lequel il faut effectuer la comparaison
@return true si les deux ensembles de proprietes sont differents, false sinon
*/
int SingleLineProperties::operator!=(const SingleLineProperties &other) const {
return(!(other == (*this)));
}
/**
@param settings Parametres a ecrire
@param prefix prefix a ajouter devant les noms des parametres
*/
void SingleLineProperties::toSettings(QSettings &settings, const QString &prefix) const {
settings.setValue(prefix + "hasGround", hasGround);
settings.setValue(prefix + "hasNeutral", hasNeutral);
settings.setValue(prefix + "phases", phases);
}
/**
@param settings Parametres a lire
@param prefix prefix a ajouter devant les noms des parametres
*/
void SingleLineProperties::fromSettings(QSettings &settings, const QString &prefix) {
hasGround = settings.value(prefix + "hasGround", true).toBool();
hasNeutral = settings.value(prefix + "hasNeutral", true).toBool();
phases = settings.value(prefix + "phases", 1).toInt();
}
+100
View File
@@ -0,0 +1,100 @@
/*
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/>.
*/
#ifndef CONDUCTOR_PROPERTIES_H
#define CONDUCTOR_PROPERTIES_H
#include "qet.h"
#include <QtGui>
#include <QtXml>
/**
Cette classe represente les proprietes specifiques a un conducteur unifilaire
*/
class SingleLineProperties {
public:
SingleLineProperties();
virtual ~SingleLineProperties();
void setPhasesCount(int);
unsigned short int phasesCount();
void draw(QPainter *, QET::ConductorSegmentType, const QRectF &);
void toXml(QDomDocument &, QDomElement &) const;
void fromXml(QDomElement &);
void toSettings(QSettings &, const QString & = QString()) const;
void fromSettings(QSettings &, const QString & = QString());
/// indique si le conducteur unifilaire doit afficher le symbole terre
bool hasGround;
/// indique si le conducteur unifilaire doit afficher le symbole neutre
bool hasNeutral;
int operator==(const SingleLineProperties &) const;
int operator!=(const SingleLineProperties &) const;
private:
unsigned short int phases;
void drawGround (QPainter *, QET::ConductorSegmentType, QPointF, qreal);
void drawNeutral(QPainter *, QET::ConductorSegmentType, QPointF, qreal);
};
/**
Cette classe represente les proprietes specifiques a un conducteur,
en dehors de ses bornes et de son trajet.
*/
class ConductorProperties {
// constructeurs, destructeur
public:
/**
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 :
* Simple : ni symbole ni champ de texte
* Single : symboles unifilaires, pas de champ de texte
* Multi : champ de texte, pas de symbole
*/
enum ConductorType { Simple, Single, Multi };
// attributs
/// type du conducteur
ConductorType type;
/// texte affiche si le conducteur est multifilaire
QString text;
/// proprietes si le conducteur est unifilaire
SingleLineProperties singleLineProperties;
// methodes
void toXml(QDomDocument &, QDomElement &) const;
void fromXml(QDomElement &);
void toSettings(QSettings &, const QString & = QString()) const;
void fromSettings(QSettings &, const QString & = QString());
static QString typeToString(ConductorType);
// operateurs
int operator==(const ConductorProperties &);
int operator!=(const ConductorProperties &);
};
#endif
+210
View File
@@ -0,0 +1,210 @@
/*
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 "conductorpropertieswidget.h"
#include "conductor.h"
/**
Constructeur
@param parent QWidget parent
*/
ConductorPropertiesWidget::ConductorPropertiesWidget(QWidget *parent) :
QWidget(parent)
{
buildInterface();
}
/**
Constructeur
@param parent QWidget parent
@param cp Proprietes a editer
*/
ConductorPropertiesWidget::ConductorPropertiesWidget(const ConductorProperties &cp, QWidget *parent) :
QWidget(parent)
{
buildInterface();
setConductorProperties(cp);
}
/// construit l'interface du widget
void ConductorPropertiesWidget::buildInterface() {
setMinimumSize(380, 280);
QVBoxLayout *main_layout = new QVBoxLayout(this);
QGroupBox *groupbox = new QGroupBox(tr("Type de conducteur"));
main_layout -> addWidget(groupbox);
QVBoxLayout *groupbox_layout = new QVBoxLayout();
groupbox -> setLayout(groupbox_layout);
simple = new QRadioButton(tr("Simple"));
multiline = new QRadioButton(tr("Multifilaire"));
QHBoxLayout *multiline_layout = new QHBoxLayout();
QLabel *text = new QLabel(tr("Texte :"));
text_field = new QLineEdit();
multiline_layout -> addWidget(text);
multiline_layout -> addWidget(text_field);
singleline = new QRadioButton(tr("Unifilaire"));
QHBoxLayout *singleline_layout3 = new QHBoxLayout();
phase_checkbox = new QCheckBox(tr("phase"));
phase_checkbox -> setIcon(QIcon(":/ico/phase.png"));
phase_slider = new QSlider(Qt::Horizontal);
phase_slider -> setRange(1, 3);
phase_spinbox = new QSpinBox();
phase_spinbox -> setRange(1, 3);
singleline_layout3 -> addWidget(phase_checkbox);
singleline_layout3 -> addWidget(phase_slider);
singleline_layout3 -> addWidget(phase_spinbox);
QVBoxLayout *singleline_layout2 = new QVBoxLayout();
ground_checkbox = new QCheckBox(tr("terre"));
ground_checkbox -> setIcon(QIcon(":/ico/ground.png"));
neutral_checkbox = new QCheckBox(tr("neutre"));
neutral_checkbox -> setIcon(QIcon(":/ico/neutral.png"));
singleline_layout2 -> addWidget(ground_checkbox);
singleline_layout2 -> addWidget(neutral_checkbox);
singleline_layout2 -> addLayout(singleline_layout3);
QHBoxLayout *singleline_layout1 = new QHBoxLayout();
preview = new QLabel();
preview -> setFixedSize(96, 96);
singleline_layout1 -> addWidget(preview);
singleline_layout1 -> addLayout(singleline_layout2);
groupbox_layout -> addWidget(simple);
groupbox_layout -> addWidget(multiline);
groupbox_layout -> addLayout(multiline_layout);
groupbox_layout -> addWidget(singleline);
groupbox_layout -> addLayout(singleline_layout1);
radio_buttons = new QButtonGroup(this);
radio_buttons -> addButton(simple, ConductorProperties::Simple);
radio_buttons -> addButton(multiline, ConductorProperties::Multi);
radio_buttons -> addButton(singleline, ConductorProperties::Single);
buildConnections();
setConductorType(ConductorProperties::Multi);
}
/// Met en place les connexions signaux/slots
void ConductorPropertiesWidget::buildConnections() {
connect(phase_slider, SIGNAL(valueChanged(int)), phase_spinbox, SLOT(setValue(int)));
connect(phase_spinbox, SIGNAL(valueChanged(int)), phase_slider, SLOT(setValue(int)));
connect(ground_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig()));
connect(neutral_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig()));
connect(phase_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig()));
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()));
}
/// Enleve les connexions signaux/slots
void ConductorPropertiesWidget::destroyConnections() {
disconnect(phase_slider, SIGNAL(valueChanged(int)), phase_spinbox, SLOT(setValue(int)));
disconnect(phase_spinbox, SIGNAL(valueChanged(int)), phase_slider, SLOT(setValue(int)));
disconnect(ground_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig()));
disconnect(neutral_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig()));
disconnect(phase_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig()));
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()));
}
/// Destructeur
ConductorPropertiesWidget::~ConductorPropertiesWidget() {
}
/// Met a jour les proprietes
void ConductorPropertiesWidget::updateConfig() {
properties_.type = static_cast<ConductorProperties::ConductorType>(radio_buttons -> checkedId());
properties_.text = text_field -> text();
properties_.singleLineProperties.hasGround = ground_checkbox -> isChecked();
properties_.singleLineProperties.hasNeutral = neutral_checkbox -> isChecked();
properties_.singleLineProperties.setPhasesCount(phase_checkbox -> isChecked() ? phase_spinbox -> value() : 0);
updateDisplay();
}
/// Met a jour l'affichage des proprietes
void ConductorPropertiesWidget::updateDisplay() {
destroyConnections();
setConductorType(properties_.type);
text_field -> setText(properties_.text);
ground_checkbox -> setChecked(properties_.singleLineProperties.hasGround);
neutral_checkbox -> setChecked(properties_.singleLineProperties.hasNeutral);
phase_spinbox -> setValue(properties_.singleLineProperties.phasesCount());
phase_slider -> setValue(properties_.singleLineProperties.phasesCount());
phase_checkbox -> setChecked(properties_.singleLineProperties.phasesCount());
buildConnections();
updatePreview();
}
/// Met a jour la previsualisation des attributs unifilaires
void ConductorPropertiesWidget::updatePreview() {
const QRect pixmap_rect(0, 0, 96, 96);
QPixmap pixmap(pixmap_rect.width(), pixmap_rect.height());
QPainter painter;
painter.begin(&pixmap);
painter.eraseRect(pixmap_rect);
painter.drawRect(pixmap_rect.adjusted(0,0,-1,-1));
painter.drawLine(QLineF(0, pixmap_rect.height() / 2, pixmap_rect.width(), pixmap_rect.height() / 2));
properties_.singleLineProperties.draw(&painter, QET::Horizontal, pixmap_rect);
painter.end();
preview -> setPixmap(pixmap);
}
/**
Passe le widget en mode simple, unifilaire ou multifilaire
@param t le type de conducteur
*/
void ConductorPropertiesWidget::setConductorType(ConductorProperties::ConductorType t) {
// widgets lies au simple
simple -> setChecked(t == ConductorProperties::Simple);
// widgets lies au mode multifilaire
multiline -> setChecked(t == ConductorProperties::Multi);
text_field -> setEnabled(t == ConductorProperties::Multi);
// widgets lies au mode unifilaire
bool sl = (t == ConductorProperties::Single);
singleline -> setChecked(sl);
preview -> setEnabled(sl);
phase_checkbox -> setEnabled(sl);
phase_slider -> setEnabled(sl);
phase_spinbox -> setEnabled(sl);
ground_checkbox -> setEnabled(sl);
neutral_checkbox -> setEnabled(sl);
}
/// @param p les nouvelles proprietes
void ConductorPropertiesWidget::setConductorProperties(const ConductorProperties &p) {
properties_ = p;
updateDisplay();
}
/// @return les proprietes editees
ConductorProperties ConductorPropertiesWidget::conductorProperties() const {
return(properties_);
}
+73
View File
@@ -0,0 +1,73 @@
/*
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/>.
*/
#ifndef CONDUCTOR_PROPERTIES_WIDGET_H
#define CONDUCTOR_PROPERTIES_WIDGET_H
#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
les options supplementaires : symboles unifilaires, presence ou non d'un
champ de texte, contenu de ce champ de texte, etc.
*/
class ConductorPropertiesWidget : public QWidget {
Q_OBJECT
// constructeurs, destructeur
public:
ConductorPropertiesWidget(QWidget * = 0);
ConductorPropertiesWidget(const ConductorProperties &, QWidget * = 0);
virtual ~ConductorPropertiesWidget();
private:
ConductorPropertiesWidget(const ConductorPropertiesWidget &);
// methodes
public:
void setConductorProperties(const ConductorProperties &);
ConductorProperties conductorProperties() const;
private:
void setConductorType(ConductorProperties::ConductorType);
public slots:
void updatePreview();
void updateConfig();
void updateDisplay();
// attributs prives
private:
QButtonGroup *radio_buttons;
QRadioButton *simple;
QRadioButton *multiline;
QLineEdit *text_field;
QRadioButton *singleline;
QCheckBox *phase_checkbox;
QSlider *phase_slider;
QSpinBox *phase_spinbox;
QCheckBox *ground_checkbox;
QCheckBox *neutral_checkbox;
QLabel *preview;
ConductorProperties properties_;
// methodes privees
void buildInterface();
void buildConnections();
void destroyConnections();
};
#endif
+521
View File
@@ -0,0 +1,521 @@
/*
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 "conductorsegment.h"
#include <QDebug>
/**
Constructeur
@param p1 Le point
@param p2
@param cs1 Le segment precedent
@param cs2 Le segment suivant
*/
ConductorSegment::ConductorSegment(
const QPointF &p1,
const QPointF &p2,
ConductorSegment *cs1,
ConductorSegment *cs2
) :
point1(p1),
point2(p2)
{
setPreviousSegment(cs1);
setNextSegment(cs2);
}
/**
Destructeur - Relie le segment precedent au suivant
*/
ConductorSegment::~ConductorSegment() {
if (hasPreviousSegment()) previousSegment() -> setNextSegment(nextSegment());
if (hasNextSegment()) nextSegment() -> setPreviousSegment(previousSegment());
}
/**
Permet de savoir s'il est possible de deplacer le premier point du segment
sans creer d'incoherence. La valeur du mouvement maximum qu'il est possible de faire
sans incoherence est stockee dans le second parametre.
@param asked_dx La valeur du mouvement demande
@param possible_dx La valeur du mouvement possible (au maximum)
@return true si le mouvement est possible ; false s'il doit etre limite
*/
bool ConductorSegment::canMove1stPointX(const qreal &asked_dx, qreal &possible_dx) const {
Q_ASSERT_X(isVertical(), "ConductorSegment::canMove1stPointX", "segment non vertical");
/// On ne bouge jamais le premier point d'un segment statique.
if (isStatic()) {
possible_dx = 0.0;
return(false);
}
// a ce stade, on a forcement un segment precedent
/// Si le segment precedent n'est pas statique, le mouvement est possible.
if (previous_segment -> hasPreviousSegment()) {
possible_dx = asked_dx;
return(true);
}
// a ce stade, le segment precedent est forcement statique
/// Si le segment precedent est vertical, le mouvement est possible :
/// il induira la creation d'un segment horizontal supplementaire.
if (previous_segment -> isVertical()) {
possible_dx = asked_dx;
return(true);
}
// a ce stade, le segment precedent est forcement horizontal
// recupere quelques donnees
qreal prev_segment_first_x = previous_segment -> point1.x();
qreal first_x = point1.x();
/// Il se peut que le mouvement doive etre limite de facon a ce
/// que le segment statique conserve une taille minimale.
if (previous_segment -> length() > 0.0) {
if (first_x + asked_dx < prev_segment_first_x + 12.0) {
possible_dx = -first_x + prev_segment_first_x + 12.0;
return(false);
} else {
possible_dx = asked_dx;
return(true);
}
} else {
if (first_x + asked_dx >= prev_segment_first_x - 12.0) {
possible_dx = prev_segment_first_x - 12.0 - first_x;
return(false);
} else {
possible_dx = asked_dx;
return(true);
}
}
}
/**
Permet de savoir s'il est possible de deplacer le second point du segment
sans creer d'incoherence. La valeur du mouvement maximum qu'il est possible de faire
sans incoherence est stockee dans le second parametre.
@param asked_dx La valeur du mouvement demande
@param possible_dx La valeur du mouvement possible (au maximum)
@return true si le mouvement est possible ; false s'il doit etre limite
*/
bool ConductorSegment::canMove2ndPointX(const qreal &asked_dx, qreal &possible_dx) const {
Q_ASSERT_X(isVertical(), "ConductorSegment::canMove2ndPointX", "segment non vertical");
/// On ne modifie jamais l'abscisse du second point d'un segment statique.
if (isStatic()) {
possible_dx = 0.0;
return(false);
}
// a ce stade, on a forcement un segment suivant
/// Si le segment suivant n'est pas statique, le mouvement est possible.
if (next_segment -> hasNextSegment()) {
possible_dx = asked_dx;
return(true);
}
// a ce stade, le segment suivant est forcement statique
/// Si le segment suivant est vertical, le mouvement est possible :
/// il induira la creation d'un segment horizontal supplementaire.
if (next_segment -> isVertical()) {
possible_dx = asked_dx;
return(true);
}
// a ce stade, le segment suivant est forcement horizontal
// recupere quelques donnees
qreal next_segment_second_x = next_segment -> point2.x();
qreal second_x = point2.x();
/// Il se peut que le mouvement doive etre limite de facon a ce
/// que le segment statique conserve une taille minimale.
if (next_segment -> length() < 0.0) {
if (second_x + asked_dx < next_segment_second_x + 12.0) {
possible_dx = -second_x + next_segment_second_x + 12.0;
return(false);
} else {
possible_dx = asked_dx;
return(true);
}
} else {
if (second_x + asked_dx >= next_segment_second_x - 12.0) {
possible_dx = next_segment_second_x - 12.0 - second_x;
return(false);
} else {
possible_dx = asked_dx;
return(true);
}
}
}
/**
Permet de savoir s'il est possible de deplacer le premier point du segment
sans creer d'incoherence. La valeur du mouvement maximum qu'il est possible de faire
sans incoherence est stockee dans le second parametre.
@param asked_dy La valeur du mouvement demande
@param possible_dy La valeur du mouvement possible (au maximum)
@return true si le mouvement est possible ; false s'il doit etre limite
*/
bool ConductorSegment::canMove1stPointY(const qreal &asked_dy, qreal &possible_dy) const {
Q_ASSERT_X(isHorizontal(), "ConductorSegment::canMove1stPointY", "segment non horizontal");
/// On ne bouge jamais le premier point d'un segment statique.
if (isStatic()) {
possible_dy = 0.0;
return(false);
}
// a ce stade, on a forcement un segment precedent
/// Si le segment precedent n'est pas statique, le mouvement est possible.
if (previous_segment -> hasPreviousSegment()) {
possible_dy = asked_dy;
return(true);
}
// a ce stade, le segment precedent est forcement statique
/// Si le segment precedent est horizontal, le mouvement est possible :
/// il induira la creation d'un segment vertical supplementaire.
if (previous_segment -> isHorizontal()) {
possible_dy = asked_dy;
return(true);
}
// a ce stade, le segment precedent est forcement vertical
// recupere quelques donnees
qreal prev_segment_first_y = previous_segment -> point1.y();
qreal first_y = point1.y();
/// Il se peut que le mouvement doive etre limite de facon a ce
/// que le segment statique conserve une taille minimale.
if (previous_segment -> length() > 0.0) {
if (first_y + asked_dy < prev_segment_first_y + 12.0) {
possible_dy = -first_y + prev_segment_first_y + 12.0;
return(false);
} else {
possible_dy = asked_dy;
return(true);
}
} else {
if (first_y + asked_dy >= prev_segment_first_y - 12.0) {
possible_dy = prev_segment_first_y - 12.0 - first_y;
return(false);
} else {
possible_dy = asked_dy;
return(true);
}
}
}
/**
Permet de savoir s'il est possible de deplacer le second point du segment
sans creer d'incoherence. La valeur du mouvement maximum qu'il est possible de faire
sans incoherence est stockee dans le second parametre.
@param asked_dy La valeur du mouvement demande
@param possible_dy La valeur du mouvement possible (au maximum)
@return true si le mouvement est possible ; false s'il doit etre limite
*/
bool ConductorSegment::canMove2ndPointY(const qreal &asked_dy, qreal &possible_dy) const {
Q_ASSERT_X(isHorizontal(), "ConductorSegment::canMove2ndPointY", "segment non horizontal");
/// On ne modifie jamais l'abscisse du second point d'un segment statique.
if (isStatic()) {
possible_dy = 0.0;
return(false);
}
// a ce stade, on a forcement un segment suivant
/// Si le segment suivant n'est pas statique, le mouvement est possible.
if (next_segment -> hasNextSegment()) {
possible_dy = asked_dy;
return(true);
}
// a ce stade, le segment suivant est forcement statique
/// Si le segment suivant est horizontal, le mouvement est possible :
/// il induira la creation d'un segment vertical supplementaire.
if (next_segment -> isHorizontal()) {
possible_dy = asked_dy;
return(true);
}
// a ce stade, le segment suivant est forcement vertical
// recupere quelques donnees
qreal next_segment_second_y = next_segment -> point2.y();
qreal second_y = point2.y();
/// Il se peut que le mouvement doive etre limite de facon a ce
/// que le segment statique conserve une taille minimale.
if (next_segment -> length() < 0.0) {
if (second_y + asked_dy < next_segment_second_y + 12.0) {
possible_dy = -second_y + next_segment_second_y + 12.0;
return(false);
} else {
possible_dy = asked_dy;
return(true);
}
} else {
if (second_y + asked_dy >= next_segment_second_y - 12.0) {
possible_dy = next_segment_second_y - 12.0 - second_y;
return(false);
} else {
possible_dy = asked_dy;
return(true);
}
}
}
/**
Gere les mouvements sur l'axe horizontal
@param dx taille du deplacement en pixels
*/
void ConductorSegment::moveX(const qreal &dx) {
if (isHorizontal()) return;
Q_ASSERT_X(isVertical(), "ConductorSegment::moveX", "segment non vertical");
bool has_prev_segment = hasPreviousSegment();
bool has_next_segment = hasNextSegment();
if (isStatic()) return;
// determine si le mouvement demande doit etre limite et, le cas echeant, a quelle valeur il faut le limiter
qreal real_dx_for_1st_point = 0.0;
qreal real_dx_for_2nd_point = 0.0;
canMove1stPointX(dx, real_dx_for_1st_point);
canMove2ndPointX(dx, real_dx_for_2nd_point);
qreal final_movement = (dx <= 0.0) ? qMax(real_dx_for_1st_point, real_dx_for_2nd_point) : qMin(real_dx_for_1st_point, real_dx_for_2nd_point);
// applique le mouvement au premier point
if (has_prev_segment) {
point1.rx() += final_movement;
if (previous_segment -> isFirstSegment()) {
new ConductorSegment(
previous_segment -> point2,
point1,
previous_segment,
this
);
} else previous_segment -> setSecondPoint(point1);
}
// applique le mouvement au second point
if (has_next_segment) {
point2.rx() += final_movement;
if (next_segment -> isLastSegment()) {
new ConductorSegment(
point2,
next_segment -> point1,
this,
next_segment
);
} else next_segment -> setFirstPoint(point2);
}
}
/**
Gere les mouvements sur l'axe vertical
@param dy taille du deplacement en pixels
*/
void ConductorSegment::moveY(const qreal &dy) {
if (isVertical()) return;
Q_ASSERT_X(isHorizontal(), "ConductorSegment::moveY", "segment non horizontal");
bool has_prev_segment = hasPreviousSegment();
bool has_next_segment = hasNextSegment();
if (isStatic()) return;
// determine si le mouvement demande doit etre limite et, le cas echeant, a quelle valeur il faut le limiter
qreal real_dy_for_1st_point = 0.0;
qreal real_dy_for_2nd_point = 0.0;
canMove1stPointY(dy, real_dy_for_1st_point);
canMove2ndPointY(dy, real_dy_for_2nd_point);
qreal final_movement = (dy <= 0.0) ? qMax(real_dy_for_1st_point, real_dy_for_2nd_point) : qMin(real_dy_for_1st_point, real_dy_for_2nd_point);
// applique le mouvement au premier point
if (has_prev_segment) {
point1.ry() += final_movement;
if (previous_segment -> isFirstSegment()) {
new ConductorSegment(
previous_segment -> point2,
point1,
previous_segment,
this
);
} else previous_segment -> setSecondPoint(point1);
}
// applique le mouvement au second point
if (has_next_segment) {
point2.ry() += final_movement;
if (next_segment -> isLastSegment()) {
new ConductorSegment(
point2,
next_segment -> point1,
this,
next_segment
);
} else next_segment -> setFirstPoint(point2);
}
}
/**
Change le segment precedent
@param ps Le nouveau segment precedent
*/
void ConductorSegment::setPreviousSegment(ConductorSegment *ps) {
previous_segment = ps;
if (hasPreviousSegment()) {
if (previousSegment() -> nextSegment() != this) previousSegment() -> setNextSegment(this);
}
}
/**
Change le segment suivant
@param ns Le nouveau segment suivant
*/
void ConductorSegment::setNextSegment(ConductorSegment *ns) {
next_segment = ns;
if (hasNextSegment()) {
if (nextSegment() -> previousSegment() != this) nextSegment() -> setPreviousSegment(this);
}
}
/// @return true si ce segment est un segment statique, cad un segment relie a une borne
bool ConductorSegment::isStatic() const {
return(isFirstSegment() || isLastSegment());
}
/// @return true si ce segment est le premier du conducteur
bool ConductorSegment::isFirstSegment() const {
return(!hasPreviousSegment());
}
/// @return true si ce segment est le dernier du conducteur
bool ConductorSegment::isLastSegment() const {
return(!hasNextSegment());
}
/**
@return Le segment precedent
*/
ConductorSegment *ConductorSegment::previousSegment() const {
return(previous_segment);
}
/**
@return Le segment suivant
*/
ConductorSegment *ConductorSegment::nextSegment() const {
return(next_segment);
}
/**
@return true si le segment est vertical, false sinon
*/
bool ConductorSegment::isVertical() const {
return(point1.x() == point2.x());
}
/**
@return true si le segment est horizontal, false sinon
*/
bool ConductorSegment::isHorizontal() const {
return(point1.y() == point2.y());
}
/**
@return le premier point du segment
*/
QPointF ConductorSegment::firstPoint() const {
return(point1);
}
/**
@return le second point du segment
*/
QPointF ConductorSegment::secondPoint() const {
return(point2);
}
/**
Permet de changer la position du premier point du segment
@param p La nouvelle position du premier point
*/
void ConductorSegment::setFirstPoint(const QPointF &p) {
point1 = p;
}
/**
Permet de changer la position du second point du segment
@param p La nouvelle position du second point
*/
void ConductorSegment::setSecondPoint(const QPointF &p) {
point2 = p;
}
/**
@return true si le segment a un segment precedent, false sinon
*/
bool ConductorSegment::hasPreviousSegment() const {
return(previous_segment != NULL);
}
/**
@return true si le segment a un segment suivant, false sinon
*/
bool ConductorSegment::hasNextSegment() const {
return(next_segment != NULL);
}
/**
@return Le centre du rectangle delimitant le conducteur
*/
QPointF ConductorSegment::middle() const {
return(
QPointF(
(point1.x() + point2.x()) / 2.0,
(point1.y() + point2.y()) / 2.0
)
);
}
/**
@return La longueur du conducteur
*/
qreal ConductorSegment::length() const {
if (isHorizontal()) {
return(secondPoint().x() - firstPoint().x());
} else {
return(secondPoint().y() - firstPoint().y());
}
}
/// @return QET::Horizontal si le segment est horizontal, QET::Vertical sinon
QET::ConductorSegmentType ConductorSegment::type() const {
return(isHorizontal() ? QET::Horizontal : QET::Vertical);
}
/// @return true si les deux points constituant le segment sont egaux
bool ConductorSegment::isPoint() const {
return(point1 == point2);
}
+70
View File
@@ -0,0 +1,70 @@
/*
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/>.
*/
#ifndef CONDUCTOR_SEGMENT_H
#define CONDUCTOR_SEGMENT_H
#include <QPointF>
#include "qet.h"
/**
Cette classe represente un segment de conducteur.
*/
class ConductorSegment {
// constructeurs, destructeur
public:
ConductorSegment(const QPointF &, const QPointF &, ConductorSegment * = NULL, ConductorSegment * = NULL);
virtual ~ConductorSegment();
private:
ConductorSegment(const ConductorSegment &);
// attributs
private:
ConductorSegment *previous_segment;
ConductorSegment *next_segment;
QPointF point1;
QPointF point2;
// methodes
public:
void moveX(const qreal &);
void moveY(const qreal &);
ConductorSegment *previousSegment() const;
ConductorSegment *nextSegment() const;
bool hasPreviousSegment() const;
bool hasNextSegment() const;
void setPreviousSegment(ConductorSegment *);
void setNextSegment(ConductorSegment *);
bool isStatic() const;
bool isFirstSegment() const;
bool isLastSegment() const;
QPointF firstPoint() const;
QPointF secondPoint() const;
void setFirstPoint(const QPointF &);
void setSecondPoint(const QPointF &);
QPointF middle() const;
bool isHorizontal() const;
bool isVertical() const;
QET::ConductorSegmentType type() const;
qreal length() const;
bool isPoint() const;
bool canMove1stPointX(const qreal &, qreal &) const;
bool canMove2ndPointX(const qreal &, qreal &) const;
bool canMove1stPointY(const qreal &, qreal &) const;
bool canMove2ndPointY(const qreal &, qreal &) const;
};
#endif
+61
View File
@@ -0,0 +1,61 @@
/*
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/>.
*/
#ifndef CONDUCTOR_SEGMENT_PROFILE_H
#define CONDUCTOR_SEGMENT_PROFILE_H
#include <QtCore>
#include "conductorsegment.h"
/**
Cette classe contient le profil (= les caracteristiques essentielles) d'un
segment de conducteur.
*/
class ConductorSegmentProfile {
// constructeurs, destructeur
public:
/**
Constructeur
@param l longueur du segment
@param ori true si le segment est horizontal, false s'il est vertical
*/
ConductorSegmentProfile(qreal l, bool ori = true) :
length(l),
isHorizontal(ori)
{
}
/**
Constructeur
@param segment ConductorSegment dont il faut extraire le profil
*/
ConductorSegmentProfile(ConductorSegment *segment) :
length(segment -> length()),
isHorizontal(segment -> isHorizontal())
{
}
/// Destructeur
virtual ~ConductorSegmentProfile() {
}
// attributs
public:
/// longueur du segment
qreal length;
/// orientation du segment
bool isHorizontal;
};
#endif
+105
View File
@@ -0,0 +1,105 @@
/*
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 "configdialog.h"
#include "qetapp.h"
/**
Constructeur
@param parent QWidget parent
*/
ConfigDialog::ConfigDialog(QWidget *parent) : QDialog(parent) {
setWindowTitle(tr("Configurer QElectroTech"));
// liste des pages
pages_list = new QListWidget();
pages_list -> setViewMode(QListView::IconMode);
pages_list -> setIconSize(QSize(48, 48));
pages_list -> setMovement(QListView::Static);
pages_list -> setMinimumWidth(135);
pages_list -> setMaximumWidth(135);
pages_list -> setSpacing(4);
// pages
pages_widget = new QStackedWidget();
addPage(new NewDiagramPage());
buildPagesList();
// boutons
buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
// layouts
QHBoxLayout *hlayout1 = new QHBoxLayout();
hlayout1 -> addWidget(pages_list);
hlayout1 -> addWidget(pages_widget);
QVBoxLayout *vlayout1 = new QVBoxLayout();
vlayout1 -> addLayout(hlayout1);
vlayout1 -> addWidget(buttons);
setLayout(vlayout1);
// connexion signaux / slots
connect(buttons, SIGNAL(accepted()), this, SLOT(applyConf()));
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
connect(pages_list, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(changePage(QListWidgetItem *, QListWidgetItem*)));
}
/// Destructeur
ConfigDialog::~ConfigDialog() {
}
/**
Gere les changements de page dans le dialogue de configuration
*/
void ConfigDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) {
if (!current) current = previous;
pages_widget -> setCurrentIndex(pages_list -> row(current));
}
/**
Construit la liste des pages sur la gauche
*/
void ConfigDialog::buildPagesList() {
pages_list -> clear();
foreach(ConfigPage *page, pages) {
QListWidgetItem *new_button = new QListWidgetItem(pages_list);
new_button -> setIcon(page -> icon());
new_button -> setText(page -> title());
new_button -> setTextAlignment(Qt::AlignHCenter);
new_button -> setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
}
}
/**
Applique la configuration de toutes les pages
*/
void ConfigDialog::applyConf() {
foreach(ConfigPage *page, pages) {
page -> applyConf();
}
accept();
}
/**
Ajoute une page au dialogue de configuration
*/
void ConfigDialog::addPage(ConfigPage *page) {
if (!page || pages.contains(page)) return;
pages << page;
pages_widget -> addWidget(page);
}
+56
View File
@@ -0,0 +1,56 @@
/*
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/>.
*/
#ifndef CONFIG_DIALOG_H
#define CONFIG_DIALOG_H
#include <QDialog>
#include "configpages.h"
class QListWidget;
class QListWidgetItem;
class QStackedWidget;
class QDialogButtonBox;
/**
Cette classe represente le dialogue de configuration de QElectroTech.
Il s'agit d'un dialogue affichant des "pages de configuration".
Chaque page de configuration doit fournir une icone et un titre.
*/
class ConfigDialog : public QDialog {
Q_OBJECT
// constructeurs, destructeur
public:
ConfigDialog(QWidget * = 0);
virtual ~ConfigDialog();
private:
ConfigDialog(const ConfigDialog &);
// methodes
public slots:
void changePage(QListWidgetItem *, QListWidgetItem *);
void applyConf();
void addPage(ConfigPage *);
private:
void buildPagesList();
// attributs
private:
QListWidget *pages_list;
QStackedWidget *pages_widget;
QDialogButtonBox *buttons;
QList<ConfigPage *> pages;
};
#endif
+136
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"));
}
+72
View File
@@ -0,0 +1,72 @@
/*
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/>.
*/
#ifndef CONFIG_PAGES_H
#define CONFIG_PAGES_H
#include <QtGui>
#include "conductorpropertieswidget.h"
#include "insetpropertieswidget.h"
/**
Cette classe abstraite contient les methodes que toutes les pages de
configuration doivent implementer.
*/
class ConfigPage : public QWidget {
Q_OBJECT
public:
/**
Constructeur
@param parent QWidget parent
*/
ConfigPage(QWidget *parent) : QWidget(parent) {};
/// Destructeur
virtual ~ConfigPage() {};
/// Applique la configuration saisie par l'utilisateur dans la page de configuration
virtual void applyConf() = 0;
/// @return le titre de la page de configuration
virtual QString title() const = 0;
/// @return l'icone de la page de configuration
virtual QIcon icon() const = 0;
};
/**
Cette classe represente la page de configuration des nouveaux schemas.
*/
class NewDiagramPage : public ConfigPage {
Q_OBJECT
// constructeurs, destructeur
public:
NewDiagramPage(QWidget * = 0);
virtual ~NewDiagramPage();
private:
NewDiagramPage(const NewDiagramPage &);
// methodes
public:
void applyConf();
QString title() const;
QIcon icon() const;
// attributs
public:
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
};
#endif
+566
View File
@@ -0,0 +1,566 @@
/*
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 "customelement.h"
#include "elementtextitem.h"
#include "diagram.h"
#include "qetapp.h"
#include <iostream>
/**
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 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 : 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(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;
}
// le fichier doit etre lisible
QFile fichier(nomfichier);
if (!fichier.open(QIODevice::ReadOnly)) {
if (etat != NULL) *etat = 2;
elmt_etat = 2;
return;
}
// le fichier doit etre un document XML
QDomDocument document_xml;
if (!document_xml.setContent(&fichier)) {
if (etat != NULL) *etat = 3;
elmt_etat = 3;
return;
}
// 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 (racine.hasAttribute("version")) {
bool 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 ") + nom_fichier
+ QObject::tr(" a \351t\351 enregistr\351 avec une version"
" ult\351rieure de QElectroTech.")
);
}
}
// ces attributs doivent etre presents et valides
int w, h, hot_x, hot_y;
if (
!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 (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(racine.attribute("ic") == "true");
// la definition est supposee avoir des enfants
if (racine.firstChild().isNull()) {
if (etat != NULL) *etat = 6;
elmt_etat = 6;
return;
}
// initialisation du QPainter (pour dessiner l'element)
QPainter qp;
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(racine);
setToolTip(nom());
// parcours des enfants de la definition : parties du dessin
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") {
// gestion de la description graphique de l'element
// = parcours des differentes parties du dessin
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
QDomElement qde = n.toElement();
if (qde.isNull()) continue;
if (parseElement(qde, qp)) ++ nb_elements_parses;
else {
if (etat != NULL) *etat = 7;
elmt_etat = 7;
return;
}
}
}
}
// fin du dessin
qp.end();
// il doit y avoir au moins un element charge
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;
}
/**
Destructeur
*/
CustomElement::~CustomElement() {
}
/// @return la liste des bornes de cet element
QList<Terminal *> CustomElement::terminals() const {
return(list_terminals);
}
/// @return la liste des conducteurs rattaches a cet element
QList<Conductor *> CustomElement::conductors() const {
QList<Conductor *> conductors;
foreach(Terminal *t, list_terminals) conductors << t -> conductors();
return(conductors);
}
/**
@return Le nombre de bornes que l'element possede
*/
int CustomElement::nbTerminals() const {
return(list_terminals.size());
}
/**
Dessine le composant sur le Diagram
@param qp Le QPainter a utiliser pour dessiner l'element
@param options Les options graphiques
*/
void CustomElement::paint(QPainter *qp, const QStyleOptionGraphicsItem *) {
dessin.play(qp);
}
/**
Analyse et prend en compte un element XML decrivant une partie du dessin
de l'element perso. Si l'analyse reussit, la partie est ajoutee au dessin.
Cette partie peut etre une borne, une ligne, une ellipse, un cercle, un arc
de cercle ou un polygone. Cette methode renvoie false si l'analyse
d'une de ces formes echoue. Si l'analyse reussit ou dans le cas d'une forme
inconnue, cette methode renvoie true. A l'exception des bornes, toutes les
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() == "ellipse") return(parseEllipse(e, qp));
else if (e.tagName() == "circle") return(parseCircle(e, qp));
else if (e.tagName() == "arc") return(parseArc(e, qp));
else if (e.tagName() == "polygon") return(parsePolygon(e, qp));
else if (e.tagName() == "text") return(parseText(e, qp));
else if (e.tagName() == "input") return(parseInput(e));
else return(true); // on n'est pas chiant, on ignore l'element inconnu
}
/**
Analyse un element XML suppose representer une ligne. Si l'analyse
reussit, la ligne est ajoutee au dessin.
La ligne est definie par les attributs suivants :
- x1, y1 : reels, coordonnees d'une extremite de la ligne
- x2, y2 : reels, coordonnees de l'autre extremite de la ligne
@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::parseLine(QDomElement &e, QPainter &qp) {
// verifie la presence et la validite des attributs obligatoires
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);
qp.save();
setPainterStyle(e, qp);
qp.drawLine(QLineF(x1, y1, x2, y2));
qp.restore();
return(true);
}
/**
Analyse un element XML suppose representer un cercle. Si l'analyse
reussit, le cercle est ajoute au dessin.
Le cercle est defini par les attributs suivants :
- x : abscisse du coin superieur gauche de la quadrature du cercle
- y : ordonnee du coin superieur gauche de la quadrature du cercle
- diameter : diametre du cercle
@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
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);
qp.save();
setPainterStyle(e, qp);
qp.drawEllipse(QRectF(cercle_x, cercle_y, cercle_r, cercle_r));
qp.restore();
return(true);
}
/**
Analyse un element XML suppose representer une ellipse. Si l'analyse
reussit, l'ellipse est ajoutee au dessin.
L'ellipse est definie par les attributs suivants :
- x : abscisse du coin superieur gauche du rectangle dans lequel s'inscrit l'ellipse
- y : ordonnee du coin superieur gauche du rectangle dans lequel s'inscrit l'ellipse
- width : dimension de la diagonale horizontale de l'ellipse
- height : dimension de la diagonale verticale de l'ellipse
@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
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);
if (!QET::attributeIsAReal(e, QString("height"), &ellipse_h)) return(false);
qp.save();
setPainterStyle(e, qp);
qp.drawEllipse(QRectF(ellipse_x, ellipse_y, ellipse_l, ellipse_h));
qp.restore();
return(true);
}
/**
Analyse un element XML suppose representer un arc de cercle. Si l'analyse
reussit, l'arc de cercle est ajoute au dessin.
L'arc de cercle est defini par les quatres parametres d'une ellipse (en fait
l'ellipse dans laquelle s'inscrit l'arc de cercle) auxquels s'ajoutent les
attributs suivants :
- start : angle de depart : l'angle "0 degre" est a trois heures
- angle : etendue (en degres) de l'arc de cercle ; une valeur positive
va dans le sens contraire des aiguilles d'une montre
@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::parseArc(QDomElement &e, QPainter &qp) {
// verifie la presence des attributs obligatoires
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);
if (!QET::attributeIsAReal(e, QString("height"), &arc_h)) return(false);
if (!QET::attributeIsAReal(e, QString("start"), &arc_s)) return(false);
if (!QET::attributeIsAReal(e, QString("angle"), &arc_a)) return(false);
qp.save();
setPainterStyle(e, qp);
qp.drawArc(QRectF(arc_x, arc_y, arc_l, arc_h), (int)(arc_s * 16), (int)(arc_a * 16));
qp.restore();
return(true);
}
/**
Analyse un element XML suppose representer un polygone. Si l'analyse
reussit, le polygone est ajoute au dessin.
Le polygone est defini par une serie d'attributs x1, x2, ..., xn et autant
d'attributs y1, y2, ..., yn representant les coordonnees des differents
points du polygone.
Il est possible d'obtenir un polygone non ferme en utilisant closed="false"
@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::parsePolygon(QDomElement &e, QPainter &qp) {
int i = 1;
while(true) {
if (QET::attributeIsAReal(e, QString("x%1").arg(i)) && QET::attributeIsAReal(e, QString("y%1").arg(i))) ++ i;
else break;
}
if (i < 3) return(false);
QPointF points[i-1];
for (int j = 1 ; j < i ; ++ j) {
points[j-1] = QPointF(
e.attribute(QString("x%1").arg(j)).toDouble(),
e.attribute(QString("y%1").arg(j)).toDouble()
);
}
qp.save();
setPainterStyle(e, qp);
if (e.attribute("closed") == "false") qp.drawPolyline(points, i-1);
else qp.drawPolygon(points, i-1);
qp.restore();
return(true);
}
/**
Analyse un element XML suppose representer un texte. Si l'analyse
reussit, le texte est ajoute au dessin.
Le texte est defini par une position, une chaine de caracteres et une
taille.
@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::parseText(QDomElement &e, QPainter &qp) {
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) ||\
!e.hasAttribute("text")
) return(false);
qp.save();
setPainterStyle(e, qp);
qp.setFont(QFont(QString(QETApp::diagramTextsFont()), size));
qp.drawText(QPointF(pos_x, pos_y), e.attribute("text"));
qp.restore();
return(true);
}
/**
Analyse un element XML suppose representer un champ de texte editable par
l'utilisateur. Si l'analyse reussit, le champ est ajoute au dessin.
Le texte est defini par :
- une position
- une chaine de caracteres facultative utilisee comme valeur par defaut
- une taille
- le fait de subir les rotations de l'element ou non
@param e L'element XML a analyser
@param s Le schema sur lequel l'element perso sera affiche
@return true si l'analyse reussit, false sinon
*/
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(false);
ElementTextItem *eti = new ElementTextItem(e.attribute("text"), this);
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);
return(true);
}
/**
Analyse un element XML suppose representer une borne. Si l'analyse
reussit, la borne est ajoutee a l'element.
Une borne est definie par les attributs suivants :
- x, y : coordonnees de la borne
- orientation : orientation de la borne = Nord (n), Sud (s), Est (e) ou Ouest (w)
@param e L'element XML a analyser
@param s Le schema sur lequel l'element perso sera affiche
@return true si l'analyse reussit, false sinon
*/
bool CustomElement::parseTerminal(QDomElement &e) {
// verifie la presence et la validite des attributs obligatoires
double terminalx, terminaly;
QET::Orientation terminalo;
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(false);
list_terminals << new Terminal(terminalx, terminaly, terminalo, this, qobject_cast<Diagram *>(scene()));
return(true);
}
/**
Active / desactive l'antialiasing sur un QPainter
@param qp Le QPainter a modifier
@param aa Booleen a true pour activer l'antialiasing, a false pour le desactiver
*/
void CustomElement::setQPainterAntiAliasing(QPainter &qp, bool aa) {
qp.setRenderHint(QPainter::Antialiasing, aa);
qp.setRenderHint(QPainter::TextAntialiasing, aa);
qp.setRenderHint(QPainter::SmoothPixmapTransform, aa);
}
/**
Verifie si l'attribut "orientation" de l'element XML e correspond bien a la
syntaxe decrivant les orientations possibles pour un element.
Cette syntaxe comprend exactement 4 lettres :
- une pour le Nord
- une pour l'Est
- une pour le Sud
- une pour l'Ouest
Pour chaque orientation, on indique si elle est :
- l'orientation par defaut : d
- une orientation autorisee : y
- une orientation interdire : n
Exemple : "dnny" represente un element par defaut oriente vers le nord et qui
peut etre oriente vers l'ouest mais pas vers le sud ou vers l'est.
@param e Element XML
@return true si l'attribut "orientation" est valide, false sinon
*/
bool CustomElement::validOrientationAttribute(QDomElement &e) {
return(ori.fromString(e.attribute("orientation")));
}
/**
Applique les parametres de style definis dans l'attribut "style" de
l'element XML e au QPainter qp
Les styles possibles sont :
- line-style : style du trait
- dashed : trait en pointilles
- normal : trait plein [par defaut]
- line-weight : epaiseur du trait
- thin : trait fin
- normal : trait d'epaisseur 1 [par defaut]
- filling : remplissage de la forme
- white : remplissage blanc
- black : remplissage noir
- none : pas de remplissage [par defaut]
- color : couleur du trait et du texte
- white : trait noir [par defaut]
- black : trait blanc
Les autres valeurs ne sont pas prises en compte.
@param e L'element XML a parser
@param qp Le QPainter a modifier en fonction des styles
*/
void CustomElement::setPainterStyle(QDomElement &e, QPainter &qp) {
// recupere le QPen et la QBrush du QPainter
QPen pen = qp.pen();
QBrush brush = qp.brush();
// attributs par defaut
pen.setJoinStyle(Qt::BevelJoin);
pen.setCapStyle(Qt::SquareCap);
pen.setColor(Qt::black);
pen.setStyle(Qt::SolidLine);
pen.setWidthF(1.0);
brush.setStyle(Qt::NoBrush);
// recupere la liste des couples style / valeur
QStringList styles = e.attribute("style").split(";", QString::SkipEmptyParts);
// agit sur le QPen et la QBrush en fonction des valeurs rencontrees
QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
foreach (QString style, styles) {
if (rx.exactMatch(style)) {
QString style_name = rx.cap(1);
QString style_value = rx.cap(2);
if (style_name == "line-style") {
if (style_value == "dashed") pen.setStyle(Qt::DashLine);
else if (style_value == "normal") pen.setStyle(Qt::SolidLine);
} else if (style_name == "line-weight") {
if (style_value == "thin") pen.setWidth(0);
else if (style_value == "normal") pen.setWidthF(1.0);
else if (style_value == "none") pen.setColor(QColor(0, 0, 0, 0));
} else if (style_name == "filling") {
if (style_value == "white") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::white);
} else if (style_value == "black") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::black);
} else if (style_value == "none") {
brush.setStyle(Qt::NoBrush);
}
} else if (style_name == "color") {
if (style_value == "black") {
pen.setColor(QColor(0, 0, 0, pen.color().alpha()));
} else if (style_value == "white") {
pen.setColor(QColor(255, 255, 255, pen.color().alpha()));
}
}
}
}
// affectation du QPen et de la QBrush modifies au QPainter
qp.setPen(pen);
qp.setBrush(brush);
// mise en place (ou non) de l'antialiasing
setQPainterAntiAliasing(qp, e.attribute("antialias") == "true");
}
+124
View File
@@ -0,0 +1,124 @@
/*
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/>.
*/
#ifndef ELEMENTPERSO_H
#define ELEMENTPERSO_H
#include "fixedelement.h"
#include <QtGui>
#include "nameslist.h"
class CustomElementPart;
/**
Cette classe represente un element electrique. Elle est utilisable
comme un element fixe. La difference est que l'element perso lit
sa description (noms, dessin, comportement) dans un fichier XML a fournir
en parametre.
*/
class CustomElement : public FixedElement {
// constructeurs, destructeur
public:
CustomElement(QString &, QGraphicsItem * = 0, Diagram * = 0, int * = NULL);
virtual ~CustomElement();
friend class CustomElementPart;
private:
CustomElement(const CustomElement &);
// attributs
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;
QString nomfichier;
QPicture dessin;
QList<Terminal *> list_terminals;
// methodes
public:
virtual QList<Terminal *> terminals() const;
virtual QList<Conductor *> conductors() const;
virtual int nbTerminals() const;
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *);
QString typeId() const;
QString fichier() const;
bool isNull() const;
int etat() const;
QString nom() const;
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 fichier()
*/
inline QString CustomElement::typeId() const {
return(nomfichier);
}
/**
@return L'adresse du fichier contenant la description XML de cet element
*/
inline QString CustomElement::fichier() const {
return(nomfichier);
}
/**
@return true si cet element est nul, c'est-a-dire si le chargement de sa
description XML a echoue
*/
inline bool CustomElement::isNull() const {
return(elmt_etat != 0);
}
/**
@return Un entier representant l'etat de l'element :
- 0 : L'instanciation a reussi
- 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
*/
inline int CustomElement::etat() const {
return(elmt_etat);
}
/**
@return Le nom de l'element
*/
inline QString CustomElement::nom() const {
return(names.name(QFileInfo(nomfichier).baseName()));
}
#endif
+648
View File
@@ -0,0 +1,648 @@
/*
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 <math.h>
#include "qetapp.h"
#include "conductor.h"
#include "customelement.h"
#include "diagram.h"
#include "exportdialog.h"
#include "diagramcommands.h"
#include "diagramcontent.h"
const int Diagram::xGrid = 10;
const int Diagram::yGrid = 10;
const qreal Diagram::margin = 5.0;
/**
Constructeur
@param parent Le QObject parent du schema
*/
Diagram::Diagram(QObject *parent) :
QGraphicsScene(parent),
draw_grid(true),
use_border(true),
moved_elements_fetched(false),
qgi_manager(this),
draw_terminals(true)
{
setBackgroundBrush(Qt::white);
conductor_setter = new QGraphicsLineItem(0, 0);
conductor_setter -> setZValue(1000000);
QPen t;
t.setColor(Qt::black);
t.setWidthF(1.5);
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() {
if (conductor_setter -> scene()) removeItem(conductor_setter);
delete conductor_setter;
}
/**
Dessine l'arriere-plan du schema, cad la grille.
@param p Le QPainter a utiliser pour dessiner
@param r Le rectangle de la zone a dessiner
*/
void Diagram::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);
if (draw_grid) {
// dessine les points de la grille
p -> setPen(Qt::black);
p -> setBrush(Qt::NoBrush);
qreal limite_x = r.x() + r.width();
qreal limite_y = r.y() + r.height();
int g_x = (int)ceil(r.x());
while (g_x % 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);
}
}
}
if (use_border) border_and_inset.draw(p, margin, margin);
p -> restore();
}
/**
Gere les enfoncements de touches du clavier
@param e QKeyEvent decrivant l'evenement clavier
*/
void Diagram::keyPressEvent(QKeyEvent *e) {
QPointF movement;
switch(e -> key()) {
case Qt::Key_Left: movement = QPointF(-xGrid, 0.0); break;
case Qt::Key_Right: movement = QPointF(+xGrid, 0.0); break;
case Qt::Key_Up: movement = QPointF(0.0, -yGrid); break;
case Qt::Key_Down: movement = QPointF(0.0, +yGrid); break;
}
if (!movement.isNull() && !focusItem()) {
moveElements(movement);
}
QGraphicsScene::keyPressEvent(e);
}
/**
Gere les relachements de touches du clavier
@param e QKeyEvent decrivant l'evenement clavier
*/
void Diagram::keyReleaseEvent(QKeyEvent *e) {
// detecte le relachement d'une touche de direction ( = deplacement d'elements)
if (
(e -> key() == Qt::Key_Left || e -> key() == Qt::Key_Right ||\
e -> key() == Qt::Key_Up || e -> key() == Qt::Key_Down) &&\
!current_movement.isNull() && !e -> isAutoRepeat()
) {
// cree un objet d'annulation pour le mouvement qui vient de se finir
undoStack().push(new MoveElementsCommand(this, selectedContent(), current_movement));
invalidateMovedElements();
current_movement = QPointF();
}
QGraphicsScene::keyReleaseEvent(e);
}
/**
Exporte le schema vers une image
@return Une QImage representant le schema
*/
bool Diagram::toPaintDevice(QPaintDevice &pix, int width, int height, Qt::AspectRatioMode aspectRatioMode) {
// determine la zone source = contenu du schema + marges
QRectF source_area;
if (!use_border) {
source_area = itemsBoundingRect();
source_area.translate(-margin, -margin);
source_area.setWidth (source_area.width () + 2.0 * margin);
source_area.setHeight(source_area.height() + 2.0 * margin);
} else {
source_area = QRectF(
0.0,
0.0,
border_and_inset.borderWidth () + 2.0 * margin,
border_and_inset.borderHeight() + 2.0 * margin
);
}
// si les dimensions ne sont pas precisees, l'image est exportee a l'echelle 1:1
QSize image_size = (width == -1 && height == -1) ? source_area.size().toSize() : QSize(width, height);
// prepare le rendu
QPainter p;
if (!p.begin(&pix)) return(false);
// rendu antialiase
p.setRenderHint(QPainter::Antialiasing, true);
p.setRenderHint(QPainter::TextAntialiasing, true);
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
// deselectionne tous les elements
QList<QGraphicsItem *> selected_elmts = selectedItems();
foreach (QGraphicsItem *qgi, selected_elmts) qgi -> setSelected(false);
// effectue le rendu lui-meme
render(&p, QRect(QPoint(0, 0), image_size), source_area, aspectRatioMode);
p.end();
// restaure les elements selectionnes
foreach (QGraphicsItem *qgi, selected_elmts) qgi -> setSelected(true);
return(true);
}
/**
Permet de connaitre les dimensions qu'aura l'image generee par la methode toImage()
@return La taille de l'image generee par toImage()
*/
QSize Diagram::imageSize() const {
// determine la zone source = contenu du schema + marges
qreal image_width, image_height;
if (!use_border) {
QRectF items_rect = itemsBoundingRect();
image_width = items_rect.width();
image_height = items_rect.height();
} else {
image_width = border_and_inset.borderWidth();
image_height = border_and_inset.borderHeight();
}
image_width += 2.0 * margin;
image_height += 2.0 * margin;
// renvoie la taille de la zone source
return(QSizeF(image_width, image_height).toSize());
}
/**
Exporte tout ou partie du schema
@param diagram Booleen (a vrai par defaut) indiquant si le XML genere doit
representer tout le schema ou seulement les elements selectionnes
@return Un Document XML (QDomDocument)
*/
QDomDocument Diagram::toXml(bool diagram) {
// document
QDomDocument document;
// racine de l'arbre XML
QDomElement racine = document.createElement("diagram");
// proprietes du schema
if (diagram) {
if (!border_and_inset.author().isNull()) racine.setAttribute("author", border_and_inset.author());
if (!border_and_inset.date().isNull()) racine.setAttribute("date", border_and_inset.date().toString("yyyyMMdd"));
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.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(document, default_conductor);
racine.appendChild(default_conductor);
}
document.appendChild(racine);
// si le schema ne contient pas d'element (et donc pas de conducteurs), on retourne de suite le document XML
if (items().isEmpty()) return(document);
// creation de trois listes : une qui contient les elements, une qui contient les conducteurs, une qui contient les champs de texte
QList<Element *> list_elements;
QList<Conductor *> list_conductors;
QList<DiagramTextItem *> list_texts;
// Determine les elements a « XMLiser »
foreach(QGraphicsItem *qgi, items()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(qgi)) {
if (diagram) list_elements << elmt;
else if (elmt -> isSelected()) list_elements << elmt;
} else if (Conductor *f = qgraphicsitem_cast<Conductor *>(qgi)) {
if (diagram) list_conductors << f;
// lorsqu'on n'exporte pas tout le diagram, il faut retirer les conducteurs non selectionnes
// et pour l'instant, les conducteurs non selectionnes sont les conducteurs dont un des elements n'est pas relie
else if (f -> terminal1 -> parentItem() -> isSelected() && f -> terminal2 -> parentItem() -> isSelected()) list_conductors << f;
} else if (DiagramTextItem *dti = qgraphicsitem_cast<DiagramTextItem *>(qgi)) {
if (!dti -> parentItem()) {
if (diagram) list_texts << dti;
else if (dti -> isSelected()) list_texts << dti;
}
}
}
// table de correspondance entre les adresses des bornes et leurs ids
QHash<Terminal *, int> table_adr_id;
// enregistrement des elements
if (!list_elements.isEmpty()) {
QDomElement elements = document.createElement("elements");
foreach(Element *elmt, list_elements) {
elements.appendChild(elmt -> toXml(document, table_adr_id));
}
racine.appendChild(elements);
}
// enregistrement des conducteurs
if (!list_conductors.isEmpty()) {
QDomElement conductors = document.createElement("conductors");
foreach(Conductor *cond, list_conductors) {
conductors.appendChild(cond -> toXml(document, table_adr_id));
}
racine.appendChild(conductors);
}
// enregistrement des champs de texte
if (!list_texts.isEmpty()) {
QDomElement inputs = document.createElement("inputs");
foreach(DiagramTextItem *dti, list_texts) {
inputs.appendChild(dti -> toXml(document));
}
racine.appendChild(inputs);
}
// on retourne le document XML ainsi genere
return(document);
}
/**
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 diagram importe
@param consider_informations Si vrai, les informations complementaires
(auteur, titre, ...) seront prises en compte
@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();
// le premier element doit etre un schema
if (root.tagName() != "diagram") return(false);
// lecture des attributs de ce schema
if (consider_informations) {
border_and_inset.setAuthor(root.attribute("author"));
border_and_inset.setTitle(root.attribute("title"));
border_and_inset.setDate(QDate::fromString(root.attribute("date"), "yyyyMMdd"));
border_and_inset.setFileName(root.attribute("filename"));
border_and_inset.setFolio(root.attribute("folio"));
bool ok;
// nombre de colonnes
int nb_cols = root.attribute("cols").toInt(&ok);
if (ok) border_and_inset.setNbColumns(nb_cols);
// taille des colonnes
double col_size = root.attribute("colsize").toDouble(&ok);
if (ok) border_and_inset.setColumnsWidth(col_size);
// hauteur du schema
double height = root.attribute("height").toDouble(&ok);
if (ok) border_and_inset.setColumnsHeight(height);
border_and_inset.adjustInsetToColumns();
// repere le permier element "defaultconductor"
for (QDomNode node = root.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
QDomElement elmts = node.toElement();
if(elmts.isNull() || elmts.tagName() != "defaultconductor") continue;
defaultConductorProperties.fromXml(elmts);
break;
}
}
// si la racine n'a pas d'enfant : le chargement est fini (schema vide)
if (root.firstChild().isNull()) return(true);
// chargement de tous les elements du fichier XML
QList<Element *> added_elements;
QHash<int, Terminal *> table_adr_id;
foreach (QDomElement e, QET::findInDomElement(root, "elements", "element")) {
if (!Element::valideXml(e)) continue;
// cree un element dont le type correspond a l'id type
QString type_id = e.attribute("type");
QString chemin_fichier = QETApp::realPath(type_id);
CustomElement *nvel_elmt = new CustomElement(chemin_fichier);
if (nvel_elmt -> isNull()) {
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(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
addItem(nvel_elmt);
added_elements << nvel_elmt;
} else {
delete nvel_elmt;
qDebug("Le chargement des parametres d'un element a echoue");
}
}
// chargement de tous les textes du fichiers XML
QList<DiagramTextItem *> added_texts;
foreach (QDomElement f, QET::findInDomElement(root, "inputs", "input")) {
DiagramTextItem *dti = new DiagramTextItem(0, this);
dti -> fromXml(f);
added_texts << dti;
}
// gere la translation des nouveaux elements et texte si celle-ci est demandee
if (position != QPointF()) {
// determine quel est le coin superieur gauche du rectangle entourant les elements ajoutes
qreal minimum_x = 0, minimum_y = 0;
bool init = false;
QList<QGraphicsItem *> added_items;
foreach (Element *added_element, added_elements) added_items << added_element;
foreach (DiagramTextItem *added_text, added_texts) added_items << added_text;
foreach (QGraphicsItem *item, added_items) {
QPointF csg = item -> mapToScene(item -> boundingRect()).boundingRect().topLeft();
qreal px = csg.x();
qreal py = csg.y();
if (!init) {
minimum_x = px;
minimum_y = py;
init = true;
} else {
if (px < minimum_x) minimum_x = px;
if (py < minimum_y) minimum_y = py;
}
}
qreal diff_x = position.x() - minimum_x;
qreal diff_y = position.y() - minimum_y;
foreach (Element *added_element, added_elements) {
added_element -> setPos(added_element -> pos().x() + diff_x, added_element -> pos().y() + diff_y);
}
foreach (DiagramTextItem *added_text, added_texts) {
added_text -> setPos(added_text -> pos().x() + diff_x, added_text -> pos().y() + diff_y);
}
}
// chargement de tous les Conducteurs du fichier XML
QList<Conductor *> added_conductors;
foreach (QDomElement f, QET::findInDomElement(root, "conductors", "conductor")) {
if (!Conductor::valideXml(f)) continue;
// verifie que les bornes que le conducteur relie sont connues
int id_p1 = f.attribute("terminal1").toInt();
int id_p2 = f.attribute("terminal2").toInt();
if (table_adr_id.contains(id_p1) && table_adr_id.contains(id_p2)) {
// pose le conducteur... si c'est possible
Terminal *p1 = table_adr_id.value(id_p1);
Terminal *p2 = table_adr_id.value(id_p2);
if (p1 != p2) {
bool can_add_conductor = true;
bool cia = ((Element *)p2 -> parentItem()) -> internalConnections();
if (!cia) {
foreach(QGraphicsItem *item, p2 -> parentItem() -> children()) {
if (item == p1) can_add_conductor = false;
}
}
if (can_add_conductor) {
Conductor *c = new Conductor(table_adr_id.value(id_p1), table_adr_id.value(id_p2), 0, this);
c -> fromXml(f);
added_conductors << c;
}
}
} else qDebug() << "Le chargement du conductor" << id_p1 << id_p2 << "a echoue";
}
// remplissage des listes facultatives
if (content_ptr != NULL) {
content_ptr -> elements = added_elements;
content_ptr -> conductorsToMove = added_conductors;
content_ptr -> textFields = added_texts;
}
return(true);
}
/**
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::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;
}
}
/**
@return Le rectangle (coordonnees par rapport a la scene) delimitant le bord du schema
*/
QRectF Diagram::border() const {
return(
QRectF(
margin,
margin,
border_and_inset.borderWidth(),
border_and_inset.borderHeight()
)
);
}
/// oublie la liste des elements et conducteurs en mouvement
void Diagram::invalidateMovedElements() {
if (!moved_elements_fetched) return;
moved_elements_fetched = false;
elements_to_move.clear();
conductors_to_move.clear();
conductors_to_update.clear();
texts_to_move.clear();
}
/// reconstruit la liste des elements et conducteurs en mouvement
void Diagram::fetchMovedElements() {
// recupere les elements deplaces
foreach (QGraphicsItem *item, selectedItems()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(item)) {
elements_to_move << elmt;
} else if (DiagramTextItem *t = qgraphicsitem_cast<DiagramTextItem *>(item)) {
if (!t -> parentItem()) texts_to_move << t;
}
}
// pour chaque element deplace, determine les conducteurs qui seront modifies
foreach(Element *elmt, elements_to_move) {
foreach(Terminal *terminal, elmt -> terminals()) {
foreach(Conductor *conductor, terminal -> conductors()) {
Terminal *other_terminal;
if (conductor -> terminal1 == terminal) {
other_terminal = conductor -> terminal2;
} else {
other_terminal = conductor -> terminal1;
}
// si les deux elements du conducteur sont deplaces
if (elements_to_move.contains(static_cast<Element *>(other_terminal -> parentItem()))) {
conductors_to_move << conductor;
} else {
conductors_to_update.insert(conductor, terminal);
}
}
}
}
moved_elements_fetched = true;
}
/**
Deplace les elements, conducteurs et textes selectionnes en gerant au
mieux les conducteurs (seuls les conducteurs dont un seul des elements
est deplace sont recalcules, les autres sont deplaces).
@param diff Translation a effectuer
@param dontmove QGraphicsItem (optionnel) a ne pas deplacer ; note : ce
parametre ne concerne que les elements et les champs de texte.
*/
void Diagram::moveElements(const QPointF &diff, QGraphicsItem *dontmove) {
// inutile de deplacer les autres elements s'il n'y a pas eu de mouvement concret
if (diff.isNull()) return;
current_movement += diff;
// deplace les elements selectionnes
foreach(Element *element, elementsToMove()) {
if (dontmove != NULL && element == dontmove) continue;
element -> setPos(element -> pos() + diff);
}
// deplace certains conducteurs
foreach(Conductor *conductor, conductorsToMove()) {
conductor -> setPos(conductor -> pos() + diff);
}
// recalcule les autres conducteurs
const QHash<Conductor *, Terminal *> &conductors_modify = conductorsToUpdate();
foreach(Conductor *conductor, conductors_modify.keys()) {
conductor -> updateWithNewPos(QRectF(), conductors_modify[conductor], conductors_modify[conductor] -> amarrageConductor());
}
// deplace les champs de texte
foreach(DiagramTextItem *dti, textsToMove()) {
if (dontmove != NULL && dti == dontmove) continue;
dti -> setPos(dti -> pos() + diff);
}
}
/**
Definit s'il faut afficher ou non les bornes
@param dt true pour afficher les bornes, false sinon
*/
void Diagram::setDrawTerminals(bool dt) {
foreach(QGraphicsItem *qgi, items()) {
if (Terminal *t = qgraphicsitem_cast<Terminal *>(qgi)) {
t -> setVisible(dt);
}
}
}
/**
@return la liste des conducteurs selectionnes sur le schema
*/
QSet<Conductor *> Diagram::selectedConductors() const {
QSet<Conductor *> conductors_set;
foreach(QGraphicsItem *qgi, selectedItems()) {
if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) {
conductors_set << c;
}
}
return(conductors_set);
}
/// @return true si le presse-papier semble contenir un schema
bool Diagram::clipboardMayContainDiagram() {
QString clipboard_text = QApplication::clipboard() -> text().trimmed();
bool may_be_diagram = clipboard_text.startsWith("<diagram") && clipboard_text.endsWith("</diagram>");
return(may_be_diagram);
}
/**
@return Le contenu du schema. Les conducteurs sont tous places dans
conductorsToMove.
*/
DiagramContent Diagram::content() const {
DiagramContent dc;
foreach(QGraphicsItem *qgi, items()) {
if (Element *e = qgraphicsitem_cast<Element *>(qgi)) {
dc.elements << e;
} else if (DiagramTextItem *dti = qgraphicsitem_cast<DiagramTextItem *>(qgi)) {
dc.textFields << dti;
} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) {
dc.conductorsToMove << c;
}
}
return(dc);
}
/**
@return le contenu selectionne du schema.
*/
DiagramContent Diagram::selectedContent() {
invalidateMovedElements();
DiagramContent dc;
dc.elements = elementsToMove().toList();
dc.textFields = textsToMove().toList();
dc.conductorsToMove = conductorsToMove().toList();
dc.conductorsToUpdate = conductorsToUpdate();
// recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables)
foreach(QGraphicsItem *qgi, items()) {
if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) {
if (
c -> isSelected() &&\
!c -> terminal1 -> parentItem() -> isSelected() &&\
!c -> terminal2 -> parentItem() -> isSelected()
) {
dc.otherConductors << c;
}
}
}
invalidateMovedElements();
return(dc);
}
+266
View File
@@ -0,0 +1,266 @@
/*
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/>.
*/
#ifndef SCHEMA_H
#define SCHEMA_H
#include <QtGui>
#include <QtXml>
#include "qetdiagrameditor.h"
#include "borderinset.h"
#include "qgimanager.h"
#include "conductorproperties.h"
class Element;
class Terminal;
class Conductor;
class DiagramTextItem;
class DiagramContent;
/**
Cette classe represente un schema electrique.
Elle gere les differents elements et conducteurs qui le composent
et en effectue le rendu graphique.
*/
class Diagram : public QGraphicsScene {
Q_OBJECT
// constructeurs, destructeur
public:
Diagram(QObject * = 0);
virtual ~Diagram();
private:
Diagram(const Diagram &diagram);
// attributs
public:
/**
Represente les options possibles pour l'affichage du schema :
* EmptyBorder : N'afficher que la bordure
* Inset : Afficher le cartouche
* Columns : Afficher les colonnes
*/
enum BorderOptions { EmptyBorder, Inset, Columns };
/// Proprietes par defaut des nouveaux conducteurs
ConductorProperties defaultConductorProperties;
/// Dimensions et cartouches du schema
BorderInset border_and_inset;
/// Mouvement en cours lors d'un deplacement d'elements et conducteurs
QPointF current_movement;
/// taille de la grille en abscisse
static const int xGrid;
/// taille de la grille en ordonnee
static const int yGrid;
/// marge autour du schema
static const qreal margin;
private:
QGraphicsLineItem *conductor_setter;
bool draw_grid;
bool use_border;
bool moved_elements_fetched;
QSet<Element *> elements_to_move;
QSet<Conductor *> conductors_to_move;
QHash<Conductor *, Terminal *> conductors_to_update;
QSet<DiagramTextItem *> texts_to_move;
QGIManager qgi_manager;
QUndoStack undo_stack;
bool draw_terminals;
// methodes
protected:
virtual void drawBackground(QPainter *, const QRectF &);
virtual void keyPressEvent(QKeyEvent *);
virtual void keyReleaseEvent(QKeyEvent *);
public:
static bool clipboardMayContainDiagram();
// fonctions relatives a la pose de conducteurs
void setConductor(bool);
void setConductorStart (QPointF);
void setConductorStop(QPointF);
// fonctions relatives a l'import / export XML
QDomDocument toXml(bool = true);
bool fromXml(QDomDocument &, QPointF = QPointF(), bool = true, DiagramContent * = NULL);
// fonctions relatives aux options graphiques
void setDisplayGrid(bool);
bool displayGrid();
void setUseBorder(bool);
bool useBorder();
void setBorderOptions(BorderOptions);
BorderOptions borderOptions();
bool drawTerminals() const;
void setDrawTerminals(bool);
QRectF border() const;
bool toPaintDevice(QPaintDevice &, int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio);
QSize imageSize() const;
void invalidateMovedElements();
void fetchMovedElements();
const QSet<Element *> &elementsToMove();
const QSet<Conductor *> &conductorsToMove();
const QHash<Conductor *, Terminal *> &conductorsToUpdate();
const QSet<DiagramTextItem *> &textsToMove();
QSet<Conductor *> selectedConductors() const;
DiagramContent content() const;
DiagramContent selectedContent();
void moveElements(const QPointF &, QGraphicsItem * = NULL);
QUndoStack &undoStack();
QGIManager &qgiManager();
private slots:
void slot_checkSelectionEmptinessChange();
signals:
/**
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
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
*/
inline void Diagram::setConductor(bool pf) {
if (pf) {
if (!conductor_setter -> scene()) addItem(conductor_setter);
} else {
if (conductor_setter -> scene()) removeItem(conductor_setter);
}
}
/**
Specifie les coordonnees du point de depart du poseur de conducteur
@param d Le nouveau point de depart du poseur de conducteur
*/
inline void Diagram::setConductorStart(QPointF d) {
conductor_setter -> setLine(QLineF(d, conductor_setter -> line().p2()));
}
/**
Specifie les coordonnees du point d'arrivee du poseur de conducteur
@param a Le nouveau point d'arrivee du poseur de conducteur
*/
inline void Diagram::setConductorStop(QPointF a) {
conductor_setter -> setLine(QLineF(conductor_setter -> line().p1(), a));
}
/**
Permet de specifier si la grille du schema doit etre dessinee ou non
@param dg true pour afficher la grille, false pour ne pas l'afficher
*/
inline void Diagram::setDisplayGrid(bool dg) {
draw_grid = dg;
}
/**
Permet de savoir si la grille du schema est dessinee ou non
@return true si la grille est affichee , false sinon
*/
inline bool Diagram::displayGrid() {
return(draw_grid);
}
/**
Permet de specifier si le cadre du schema doit etre pris en compte pour
determiner le contour du schema.
@param ub true pour prendre le schema en compte, false sinon
*/
inline void Diagram::setUseBorder(bool ub) {
use_border = ub;
}
/**
Permet de savoir si le cadre du schema est pris en compte pour
determiner le contour du schema.
*/
inline bool Diagram::useBorder() {
return(use_border);
}
/**
Permet de definir les options du cadre, des colonnes et du cartouche.
@param bo Un OU binaire entre les options possibles
@see BorderOptions
*/
inline void Diagram::setBorderOptions(Diagram::BorderOptions bo) {
border_and_inset.displayBorder(!(bo & EmptyBorder));
border_and_inset.displayColumns(bo & Columns);
border_and_inset.displayInset(bo & Inset);
}
/**
Permet de savoir les options du cadre, des colonnes et du cartouche.
@return Un OU binaire entre les options possibles
@see BorderOptions
*/
inline Diagram::BorderOptions Diagram::borderOptions() {
BorderOptions retour = EmptyBorder;
if (border_and_inset.insetIsDisplayed()) retour = (BorderOptions)(retour|Inset);
if (border_and_inset.columnsAreDisplayed()) retour = (BorderOptions)(retour|Columns);
return(retour);
}
/// @return la liste des elements a deplacer
inline const QSet<Element *> &Diagram::elementsToMove() {
if (!moved_elements_fetched) fetchMovedElements();
return(elements_to_move);
}
/// @return la liste des conducteurs a deplacer
inline const QSet<Conductor *> &Diagram::conductorsToMove() {
if (!moved_elements_fetched) fetchMovedElements();
return(conductors_to_move);
}
/// @return la liste des conducteurs a modifier (typiquement les conducteurs dont seul un element est deplace)
inline const QHash<Conductor *, Terminal *> &Diagram::conductorsToUpdate() {
if (!moved_elements_fetched) fetchMovedElements();
return(conductors_to_update);
}
/// @return la liste des textes a deplacer
inline const QSet<DiagramTextItem *> &Diagram::textsToMove() {
if (!moved_elements_fetched) fetchMovedElements();
return(texts_to_move);
}
/// @return la pile d'annulations de ce schema
inline QUndoStack &Diagram::undoStack() {
return(undo_stack);
}
/// @return le egstionnaire de QGraphicsItem de ce schema
inline QGIManager &Diagram::qgiManager() {
return(qgi_manager);
}
/// @return true si les bornes sont affichees, false sinon
inline bool Diagram::drawTerminals() const {
return(draw_terminals);
}
#endif
+625
View File
@@ -0,0 +1,625 @@
/*
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 "diagramcommands.h"
#include "element.h"
#include "conductor.h"
#include "diagram.h"
#include "qgimanager.h"
/**
Constructeur
@param d Schema auquel on ajoute un element
@param elmt Element ajoute
@param p Position a laquelle l'element est ajoute
@param parent QUndoCommand parent
*/
AddElementCommand::AddElementCommand(
Diagram *d,
Element *elmt,
const QPointF &p,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("ajouter 1 ") + elmt -> nom(), parent),
element(elmt),
diagram(d),
position(p)
{
diagram -> qgiManager().manage(element);
}
/// Destructeur
AddElementCommand::~AddElementCommand() {
diagram -> qgiManager().release(element);
}
/// Annule l'ajout
void AddElementCommand::undo() {
diagram -> removeItem(element);
}
/// Refait l'ajout
void AddElementCommand::redo() {
diagram -> addItem(element);
element -> setPos(position);
element -> setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
}
/**
Constructeur
@param dia Schema auquel on ajoute du texte
@param text Texte ajoute
@param pos Position a laquelle le texte est ajoute
@param parent QUndoCommand parent
*/
AddTextCommand::AddTextCommand(Diagram *dia, DiagramTextItem *text, const QPointF &pos, QUndoCommand *parent) :
QUndoCommand(QObject::tr("Ajouter un champ de texte"), parent),
textitem(text),
diagram(dia),
position(pos)
{
diagram -> qgiManager().manage(textitem);
}
/// Destructeur
AddTextCommand::~AddTextCommand() {
diagram -> qgiManager().release(textitem);
}
/// Annule l'ajout
void AddTextCommand::undo() {
diagram -> removeItem(textitem);
}
/// Refait l'ajour
void AddTextCommand::redo() {
diagram -> addItem(textitem);
textitem -> setPos(position);
}
/**
Constructeur
@param d Schema auquel on ajoute un conducteur
@param c Conducteur ajoute
@param parent QUndoCommand parent
*/
AddConductorCommand::AddConductorCommand(
Diagram *d,
Conductor *c,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("ajouter un conducteur"), parent),
conductor(c),
diagram(d)
{
diagram -> qgiManager().manage(conductor);
}
/// Destructeur
AddConductorCommand::~AddConductorCommand() {
diagram -> qgiManager().release(conductor);
}
/// Annule l'ajout
void AddConductorCommand::undo() {
// detache le conducteur sans le detruire
conductor -> terminal1 -> removeConductor(conductor);
conductor -> terminal2 -> removeConductor(conductor);
diagram -> removeItem(conductor);
}
/// Refait l'ajout
void AddConductorCommand::redo() {
diagram -> addItem(conductor);
}
/**
Constructeur
@param dia Schema dont on supprime des elements et conducteurs
@param content Contenu supprime
@param parent QUndoCommand parent
*/
DeleteElementsCommand::DeleteElementsCommand(
Diagram *dia,
const DiagramContent &content,
QUndoCommand *parent
) :
QUndoCommand(parent),
removed_content(content),
diagram(dia)
{
setText(QObject::tr("supprimer ") + removed_content.sentence(DiagramContent::All));
diagram -> qgiManager().manage(removed_content.items(DiagramContent::All));
}
/// Destructeur
DeleteElementsCommand::~DeleteElementsCommand() {
diagram -> qgiManager().release(removed_content.items(DiagramContent::All));
}
/// annule les suppressions
void DeleteElementsCommand::undo() {
// remet les elements
foreach(Element *e, removed_content.elements) {
diagram -> addItem(e);
}
// remet les conducteurs
foreach(Conductor *c, removed_content.conductors(DiagramContent::AnyConductor)) {
diagram -> addItem(c);
c -> terminal1 -> addConductor(c);
c -> terminal2 -> addConductor(c);
}
// remet les textes
foreach(DiagramTextItem *t, removed_content.textFields) {
diagram -> addItem(t);
}
}
/// refait les suppressions
void DeleteElementsCommand::redo() {
// enleve les conducteurs
foreach(Conductor *c, removed_content.conductors(DiagramContent::AnyConductor)) {
c -> terminal1 -> removeConductor(c);
c -> terminal2 -> removeConductor(c);
diagram -> removeItem(c);
}
// enleve les elements
foreach(Element *e, removed_content.elements) {
diagram -> removeItem(e);
}
// enleve les textes
foreach(DiagramTextItem *t, removed_content.textFields) {
diagram -> removeItem(t);
}
}
/**
Constructeur
@param dia Schema sur lequel on colle les elements et conducteurs
@param c Contenu a coller sur le schema
@param parent QUndoCommand parent
*/
PasteDiagramCommand::PasteDiagramCommand(
Diagram *dia,
const DiagramContent &c,
QUndoCommand *parent
) :
QUndoCommand(parent),
content(c),
diagram(dia),
filter(DiagramContent::Elements|DiagramContent::TextFields|DiagramContent::ConductorsToMove),
first_redo(true)
{
setText(QObject::tr("coller ") + content.sentence(filter));
diagram -> qgiManager().manage(content.items(filter));
}
/// Destructeur
PasteDiagramCommand::~PasteDiagramCommand() {
diagram -> qgiManager().release(content.items(filter));
}
/// annule le coller
void PasteDiagramCommand::undo() {
// enleve les conducteurs
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 -> removeItem(e);
// enleve les textes
foreach(DiagramTextItem *t, content.textFields) diagram -> removeItem(t);
}
/// refait le coller
void PasteDiagramCommand::redo() {
if (first_redo) first_redo = false;
else {
// pose les elements
foreach(Element *e, content.elements) diagram -> addItem(e);
// pose les conducteurs
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 -> addItem(t);
}
foreach(Element *e, content.elements) e -> setSelected(true);
foreach(Conductor *c, content.conductorsToMove) c -> setSelected(true);
foreach(DiagramTextItem *t, content.textFields) t -> setSelected(true);
}
/**
Constructeur
@param dia Schema dont on coupe des elements et conducteurs
@param content Contenu coupe
@param parent QUndoCommand parent
*/
CutDiagramCommand::CutDiagramCommand(
Diagram *dia,
const DiagramContent &content,
QUndoCommand *parent
) :
DeleteElementsCommand(dia, content, parent)
{
setText(QObject::tr("couper ") + content.sentence(DiagramContent::All));
}
/// Destructeur
CutDiagramCommand::~CutDiagramCommand() {
}
/**
Constructeur
@param dia Schema sur lequel on deplace des elements
@param diagram_content Contenu a deplacer
@param m translation subie par les elements
@param parent QUndoCommand parent
*/
MoveElementsCommand::MoveElementsCommand(
Diagram *dia,
const DiagramContent &diagram_content,
const QPointF &m,
QUndoCommand *parent
) :
QUndoCommand(parent),
diagram(dia),
content_to_move(diagram_content),
movement(m),
first_redo(true)
{
setText(QObject::tr("d\351placer ") + content_to_move.sentence(DiagramContent::Elements|DiagramContent::TextFields|DiagramContent::ConductorsToUpdate|DiagramContent::ConductorsToMove));
}
/// Destructeur
MoveElementsCommand::~MoveElementsCommand() {
}
/// annule le deplacement
void MoveElementsCommand::undo() {
move(-movement);
}
/// refait le deplacement
void MoveElementsCommand::redo() {
if (first_redo) first_redo = false;
else move(movement);
}
/**
deplace les elements et conducteurs
@param actual_movement translation a effectuer sur les elements et conducteurs
*/
void MoveElementsCommand::move(const QPointF &actual_movement) {
// deplace les elements
foreach(Element *element, content_to_move.elements) {
element -> setPos(element -> pos() + actual_movement);
}
// deplace certains conducteurs
foreach(Conductor *conductor, content_to_move.conductorsToMove) {
conductor -> setPos(conductor -> pos() + actual_movement);
}
// recalcule les autres conducteurs
foreach(Conductor *conductor, content_to_move.conductorsToUpdate.keys()) {
conductor -> updateWithNewPos(
QRectF(),
content_to_move.conductorsToUpdate[conductor],
content_to_move.conductorsToUpdate[conductor] -> amarrageConductor()
);
}
// deplace les textes
foreach(DiagramTextItem *text, content_to_move.textFields) {
text -> setPos(text -> pos() + actual_movement);
}
}
/**
Constructeur
@param dti Champ de texte modifie
@param before texte avant
@param after texte apres
@param parent QUndoCommand parent
*/
ChangeDiagramTextCommand::ChangeDiagramTextCommand(
DiagramTextItem *dti,
const QString &before,
const QString &after,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modifier le texte"), parent),
text_item(dti),
text_before(before),
text_after(after),
first_redo(true)
{
}
/// destructeur
ChangeDiagramTextCommand::~ChangeDiagramTextCommand() {
}
/// annule la modification de texte
void ChangeDiagramTextCommand::undo() {
text_item -> setPlainText(text_before);
text_item -> previous_text = text_before;
}
/// refait la modification de texte
void ChangeDiagramTextCommand::redo() {
if (first_redo) first_redo = false;
else {
text_item -> setPlainText(text_after);
text_item -> previous_text = text_after;
}
}
/**
Constructeur
@param elements Elements a pivoter associes a leur orientation d'origine
@param parent QUndoCommand parent
*/
RotateElementsCommand::RotateElementsCommand(const QHash<Element *, QET::Orientation> &elements, QUndoCommand *parent) :
QUndoCommand(QObject::tr("pivoter ") + QET::ElementsAndConductorsSentence(elements.count(), 0), parent),
elements_to_rotate(elements)
{
}
/// Destructeur
RotateElementsCommand::~RotateElementsCommand() {
}
/// defait le pivotement
void RotateElementsCommand::undo() {
foreach(Element *e, elements_to_rotate.keys()) {
e -> setOrientation(elements_to_rotate[e]);
}
}
/// refait le pivotement
void RotateElementsCommand::redo() {
foreach(Element *e, elements_to_rotate.keys()) {
e -> setOrientation(e -> orientation().next());
e -> update();
}
}
/**
Constructeur
@param c Conducteur modifie
@param old_p ancien profil du conducteur
@param new_p nouveau profil du conducteur
@param path_t Trajectoire du trajet modifie
@param parent QUndoCommand parent
*/
ChangeConductorCommand::ChangeConductorCommand(
Conductor *c,
const ConductorProfile &old_p,
const ConductorProfile &new_p,
Qt::Corner path_t,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modifier un conducteur"), parent),
conductor(c),
old_profile(old_p),
new_profile(new_p),
path_type(path_t),
first_redo(true)
{
}
/// Destructeur
ChangeConductorCommand::~ChangeConductorCommand() {
}
/// Annule la modification du conducteur
void ChangeConductorCommand::undo() {
conductor -> setProfile(old_profile, path_type);
}
/// Refait la modification du conducteur
void ChangeConductorCommand::redo() {
if (first_redo) first_redo = false;
else conductor -> setProfile(new_profile, path_type);
}
/**
Constructeur
@param cp Conducteurs reinitialises, associes a leur ancien profil
@param parent QUndoCommand parent
*/
ResetConductorCommand::ResetConductorCommand(
const QHash<Conductor *, ConductorProfilesGroup> &cp,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("R\351initialiser ") + QET::ElementsAndConductorsSentence(0, cp.count()), parent),
conductors_profiles(cp)
{
}
/// Destructeur
ResetConductorCommand::~ResetConductorCommand() {
}
/// Annule la reinitialisation des conducteurs
void ResetConductorCommand::undo() {
foreach(Conductor *c, conductors_profiles.keys()) {
c -> setProfiles(conductors_profiles[c]);
}
}
/// Refait la reinitialisation des conducteurs
void ResetConductorCommand::redo() {
foreach(Conductor *c, conductors_profiles.keys()) {
c -> setProfiles(ConductorProfilesGroup());
}
}
/**
Constructeur
@param d Schema dont on modifie le cartouche
@param old_ip Anciennes proprietes du cartouche
@param new_ip Nouvelles proprietes du cartouche
@param parent QUndoCommand parent
*/
ChangeInsetCommand::ChangeInsetCommand(
Diagram *d,
const InsetProperties &old_ip,
const InsetProperties &new_ip,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modifier le cartouche"), parent),
diagram(d),
old_inset(old_ip),
new_inset(new_ip)
{
}
/// Destructeur
ChangeInsetCommand::~ChangeInsetCommand() {
}
/// Annule la modification de cartouche
void ChangeInsetCommand::undo() {
diagram -> border_and_inset.importInset(old_inset);
diagram -> invalidate(diagram -> border());
}
/// Refait la modification de cartouche
void ChangeInsetCommand::redo() {
diagram -> border_and_inset.importInset(new_inset);
diagram -> invalidate(diagram -> border());
}
/**
Constructeur
@param dia Schema modifie
@param parent QUndoCommand parent
*/
ChangeBorderCommand::ChangeBorderCommand(Diagram *dia, QUndoCommand *parent) :
QUndoCommand(QObject::tr("modifier les dimensions du sch\351ma"), parent),
diagram(dia),
columnsCountDifference(0),
columnsHeightDifference(0.0),
columnsWidthDifference(0.0),
headersHeightDifference(0.0)
{
}
/// Destructeur
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() {
applyChanges(-1);
}
/// Refait les changements apportes au schema
void ChangeBorderCommand::redo() {
applyChanges(1);
}
/**
Constructeur
@param c Le conducteur dont on modifie les proprietes
@param parent QUndoCommand parent
*/
ChangeConductorPropertiesCommand::ChangeConductorPropertiesCommand(Conductor *c, QUndoCommand *parent) :
QUndoCommand(QObject::tr("modifier les propri\351t\351s d'un conducteur"), parent),
conductor(c),
old_settings_set(false),
new_settings_set(false)
{
}
/// Destructeur
ChangeConductorPropertiesCommand::~ChangeConductorPropertiesCommand() {
}
/// definit l'ancienne configuration
void ChangeConductorPropertiesCommand::setOldSettings(const ConductorProperties &properties) {
old_properties = properties;
old_settings_set = true;
}
/// definit la nouvelle configuration
void ChangeConductorPropertiesCommand::setNewSettings(const ConductorProperties &properties) {
new_properties = properties;
new_settings_set = true;
}
/**
Annule les changements - Attention : les anciens et nouveaux parametres
doivent avoir ete definis a l'aide de setNewSettings et setOldSettings
*/
void ChangeConductorPropertiesCommand::undo() {
if (old_settings_set && new_settings_set) {
conductor -> setProperties(old_properties);
conductor -> update();
}
}
/**
Refait les changements - Attention : les anciens et nouveaux parametres
doivent avoir ete definis a l'aide de setNewSettings et setOldSettings
*/
void ChangeConductorPropertiesCommand::redo() {
if (old_settings_set && new_settings_set) {
conductor -> setProperties(new_properties);
conductor -> update();
}
}
+394
View File
@@ -0,0 +1,394 @@
/*
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/>.
*/
#ifndef DIAGRAM_COMMANDS_H
#define DIAGRAM_COMMANDS_H
#include "qet.h"
#include "diagram.h"
#include "diagramcontent.h"
#include "diagramtextitem.h"
#include "conductor.h"
#include "conductorproperties.h"
#include <QtGui>
/**
Cette classe represente l'action d'ajouter un element au schema
*/
class AddElementCommand : public QUndoCommand {
// constructeurs, destructeur
public:
AddElementCommand(Diagram *, Element *, const QPointF &, QUndoCommand * = 0);
virtual ~AddElementCommand();
private:
AddElementCommand(const AddElementCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// element ajoute
Element *element;
/// schema sur lequel on ajoute l'element
Diagram *diagram;
/// position de l'element sur le schema
QPointF position;
};
/**
Cette classe represente l'action d'ajouter du texte au schema
*/
class AddTextCommand : public QUndoCommand {
// constructeurs, destructeur
public:
AddTextCommand(Diagram *, DiagramTextItem *, const QPointF &, QUndoCommand * = 0);
virtual ~AddTextCommand();
private:
AddTextCommand(const AddTextCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// texte ajoute
DiagramTextItem *textitem;
/// schema sur lequel on ajoute le texte
Diagram *diagram;
/// position du texte sur le schema
QPointF position;
};
/**
Cette classe represente l'action d'ajouter un conducteur au schema
*/
class AddConductorCommand : public QUndoCommand {
// constructeurs, destructeur
public:
AddConductorCommand(Diagram *, Conductor *, QUndoCommand * = 0);
virtual ~AddConductorCommand();
private:
AddConductorCommand(const AddConductorCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// conducteur ajoute
Conductor *conductor;
/// schema auquel on ajoute le conducteur
Diagram *diagram;
};
/**
Cette classe represente l'action de supprimer des elements et / ou
conducteurs d'un schema
*/
class DeleteElementsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
DeleteElementsCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
virtual ~DeleteElementsCommand();
private:
DeleteElementsCommand(const DeleteElementsCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// contenu enleve
DiagramContent removed_content;
/// schema dont on supprime des elements et conducteurs
Diagram *diagram;
};
/**
Cette classe represente l'action de coller quelque chose sur un schema
*/
class PasteDiagramCommand : public QUndoCommand {
// constructeurs, destructeur
public:
PasteDiagramCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
virtual ~PasteDiagramCommand();
private:
PasteDiagramCommand(const PasteDiagramCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// contenu ajoute
DiagramContent content;
/// schema sur lequel on colle les elements et conducteurs
Diagram *diagram;
/// entien pour filtrer le contenu du schema
int filter;
/// booleen pour empecher le premier appel a redo
bool first_redo;
};
/**
Cette classe represente l'action de supprimer des elements et / ou
conducteurs d'un schema
*/
class CutDiagramCommand : public DeleteElementsCommand {
// constructeurs, destructeur
public:
CutDiagramCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
virtual ~CutDiagramCommand();
private:
CutDiagramCommand(const CutDiagramCommand &);
};
/**
Cette classe represente l'action de deplacer des elements et des
conducteurs sur un schema
*/
class MoveElementsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
MoveElementsCommand(Diagram *, const DiagramContent &, const QPointF &m, QUndoCommand * = 0);
virtual ~MoveElementsCommand();
private:
MoveElementsCommand(const MoveElementsCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
virtual void move(const QPointF &);
// attributs
private:
/// schema sur lequel on deplace les elements
Diagram *diagram;
/// contenu a deplacer
DiagramContent content_to_move;
/// mouvement effectue
QPointF movement;
/// booleen pour ne pas executer le premier redo()
bool first_redo;
};
/**
Cette classe represente la modification d'un champ de texte
*/
class ChangeDiagramTextCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangeDiagramTextCommand(DiagramTextItem *, const QString &before, const QString &after, QUndoCommand * = 0);
virtual ~ChangeDiagramTextCommand();
private:
ChangeDiagramTextCommand(const ChangeDiagramTextCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// DiagramTextItem modifie
DiagramTextItem *text_item;
/// texte avant changement
QString text_before;
/// texte apres changement
QString text_after;
/// booleen pour ne pas executer le premier redo()
bool first_redo;
};
/**
Cette classe represente l'action de pivoter plusieurs elements
*/
class RotateElementsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
RotateElementsCommand(const QHash<Element *, QET::Orientation> &elements, QUndoCommand * = 0);
virtual ~RotateElementsCommand();
private:
RotateElementsCommand(const RotateElementsCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// elements pivotes associes a leur ancienne orientation
QHash<Element *, QET::Orientation> elements_to_rotate;
};
/**
Cette classe represente l'action de modifier un conducteur
*/
class ChangeConductorCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangeConductorCommand(Conductor *, const ConductorProfile &, const ConductorProfile &, Qt::Corner, QUndoCommand * = 0);
virtual ~ChangeConductorCommand();
private:
ChangeConductorCommand(const ChangeConductorCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// conducteur modifie
Conductor *conductor;
/// profil avant changement
ConductorProfile old_profile;
/// profil apres changement
ConductorProfile new_profile;
/// Type de trajet
Qt::Corner path_type;
/// booleen pour ne pas executer le premier redo()
bool first_redo;
};
/**
Cette classe represente l'action de reinitialiser des conducteurs
*/
class ResetConductorCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ResetConductorCommand(const QHash<Conductor *, ConductorProfilesGroup> &, QUndoCommand * = 0);
virtual ~ResetConductorCommand();
private:
ResetConductorCommand(const ResetConductorCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// conducteurs reinitialises associes a leur ancien profil
QHash<Conductor *, ConductorProfilesGroup> conductors_profiles;
};
/**
Cette classe represente l'action de modifier les informations du cartouche d'un schema
*/
class ChangeInsetCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangeInsetCommand(Diagram *, const InsetProperties &, const InsetProperties &, QUndoCommand * = 0);
virtual ~ChangeInsetCommand();
private:
ChangeInsetCommand(const ChangeInsetCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// schema modifie
Diagram *diagram;
/// proprietes avant changement
InsetProperties old_inset;
/// proprietes apres changement
InsetProperties new_inset;
};
/**
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 *, QUndoCommand * = 0);
virtual ~ChangeBorderCommand();
private:
ChangeBorderCommand(const ChangeBorderCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
private:
virtual void applyChanges(int = 1);
// attributs
private:
/// schema modifie
Diagram *diagram;
public:
/// 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;
};
/**
Cette classe represente l'action de modifier les proprietes d'un conducteur
*/
class ChangeConductorPropertiesCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangeConductorPropertiesCommand(Conductor *, QUndoCommand * = 0);
virtual ~ChangeConductorPropertiesCommand();
private:
ChangeConductorPropertiesCommand(const ChangeConductorPropertiesCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
virtual void setOldSettings(const ConductorProperties &);
virtual void setNewSettings(const ConductorProperties &);
// attributs
private:
/// conducteur modifie
Conductor *conductor;
/// anciennes proprietes
ConductorProperties old_properties;
/// nouvelles proprietes
ConductorProperties new_properties;
/// booleens indiquant si les proprietes ont ete definies ou non
bool old_settings_set;
bool new_settings_set;
};
#endif
+130
View File
@@ -0,0 +1,130 @@
/*
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 "diagramcontent.h"
#include <QGraphicsItem>
#include "element.h"
#include "diagramtextitem.h"
#include "conductor.h"
/**
Constructeur par defaut. Ne contient rien.
*/
DiagramContent::DiagramContent() {
}
/**
Constructeur de copie.
*/
DiagramContent::DiagramContent(const DiagramContent &other) :
elements(other.elements),
textFields(other.textFields),
conductorsToUpdate(other.conductorsToUpdate),
conductorsToMove(other.conductorsToMove),
otherConductors(other.otherConductors)
{
}
/**
Constructeur
*/
DiagramContent::~DiagramContent() {
}
/**
@param filter Types de conducteurs desires
@return tous les conducteurs
*/
QList<Conductor *> DiagramContent::conductors(int filter) const {
QList<Conductor *> result;
if (filter & ConductorsToMove) result += conductorsToMove;
if (filter & ConductorsToUpdate) result += conductorsToUpdate.keys();
if (filter & OtherConductors) result += otherConductors;
return(result);
}
/**
Vide le conteneur
*/
void DiagramContent::clear() {
elements.clear();
textFields.clear();
conductorsToUpdate.clear();
conductorsToMove.clear();
otherConductors.clear();
}
/**
@param filter Types desires
@return la liste des items formant le contenu du schema
*/
QList<QGraphicsItem *> DiagramContent::items(int filter) const {
QList<QGraphicsItem *> items_list;
foreach(QGraphicsItem *qgi, conductors(filter)) items_list << qgi;
if (filter & Elements) foreach(QGraphicsItem *qgi, elements) items_list << qgi;
if (filter & TextFields) foreach(QGraphicsItem *qgi, textFields) items_list << qgi;
return(items_list);
}
/**
@param filter Types desires
@return le nombre d'items formant le contenu du schema
*/
int DiagramContent::count(int filter) const {
int count = 0;
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);
}
/**
Permet de composer rapidement la proposition "x elements, y conducteurs et
z champs de texte".
@param filter Types desires
@return la proposition decrivant le contenu.
*/
QString DiagramContent::sentence(int filter) const {
int elements_count = (filter & Elements) ? elements.count() : 0;
int conductors_count = conductors(filter).count();
int textfields_count = (filter & TextFields) ? textFields.count() : 0;
return(
QET::ElementsAndConductorsSentence(
elements_count,
conductors_count,
textfields_count
)
);
}
/**
Permet de debugger un contenu de schema
@param d Object QDebug a utiliser pour l'affichage des informations de debug
@param c Contenu de schema a debugger
*/
QDebug &operator<<(QDebug d, DiagramContent &c) {
d << "DiagramContent {" << "\n";
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());
}
+70
View File
@@ -0,0 +1,70 @@
/*
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/>.
*/
#ifndef DIAGRAM_CONTENT_H
#define DIAGRAM_CONTENT_H
#include <QtGui>
class Conductor;
class Element;
class Terminal;
class DiagramTextItem;
/**
Cette classe est un conteneur pour passer facilement le contenu d'un schema
a une fonction. Il permet d'acceder rapidement aux differents types de
composants que l'on peut trouver sur un schema, comme les elements, les
champs de texte, les conducteurs (a deplacer ou a mettre a jour, en cas de
deplacements), etc.
A noter que ce container ne contient pas systematiquement l'integralite
d'un schema. Il peut n'en contenir qu'une partie, typiquement les
composants selectionnes.
*/
class DiagramContent {
public:
DiagramContent();
DiagramContent(const DiagramContent &);
~DiagramContent();
/// Permet de filtrer facilement les differentes parties d'un schema
enum Filter {
Elements = 1,
TextFields = 2,
ConductorsToMove = 4,
ConductorsToUpdate = 8,
OtherConductors = 16,
AnyConductor = 28,
All = 31
};
/// Elements de texte du schema
QList<Element *> elements;
/// Champs de texte du schema
QList<DiagramTextItem *> textFields;
/// Conducteurs a mettre a jour du schema
QHash<Conductor *, Terminal *> conductorsToUpdate;
/// Conducteurs a deplacer du schema
QList<Conductor *> conductorsToMove;
/// Conducteurs isoles (ni a deplacer, ni a mettre a jour)
QList<Conductor *> otherConductors;
QList<Conductor *> conductors(int = AnyConductor) const;
QList<QGraphicsItem *> items(int = All) const;
QString sentence(int = All) const;
int count(int = All) const;
void clear();
};
QDebug &operator<<(QDebug, DiagramContent &);
#endif
+302
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
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
+200
View File
@@ -0,0 +1,200 @@
/*
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 "diagramtextitem.h"
#include "diagramcommands.h"
/**
Constructeur
@param parent Le QGraphicsItem parent du champ de texte
@param scene La scene a laquelle appartient le champ de texte
*/
DiagramTextItem::DiagramTextItem(QGraphicsItem *parent, QGraphicsScene *scene) :
QGraphicsTextItem(parent, scene)
{
setDefaultTextColor(Qt::black);
setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
}
/**
Constructeur
@param parent Le QGraphicsItem parent du champ de texte
@param scene La scene a laquelle appartient le champ de texte
@param text Le texte affiche par le champ de texte
*/
DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent, QGraphicsScene *scene) :
QGraphicsTextItem(text, parent, scene),
previous_text(text)
{
setDefaultTextColor(Qt::black);
setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
}
/// Destructeur
DiagramTextItem::~DiagramTextItem() {
}
/// @return le Diagram auquel ce texte appartient, ou 0 si ce texte est independant
Diagram *DiagramTextItem::diagram() const {
return(qobject_cast<Diagram *>(scene()));
}
/**
gere la perte de focus du champ de texte
*/
void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
QGraphicsTextItem::focusOutEvent(e);
// si le texte a ete modifie
if (toPlainText() != previous_text) {
if (Diagram *dia = diagram()) {
dia -> undoStack().push(new ChangeDiagramTextCommand(this, previous_text, toPlainText()));
previous_text = toPlainText();
}
}
// deselectionne le texte
QTextCursor cursor = textCursor();
cursor.clearSelection();
setTextCursor(cursor);
if (flags() & QGraphicsItem::ItemIsMovable) {
// hack a la con pour etre re-entrant
setTextInteractionFlags(Qt::NoTextInteraction);
QTimer::singleShot(0, this, SIGNAL(lostFocus()));
}
}
/**
Permet de lire le texte a mettre dans le champ a partir d'un element XML.
Cette methode se base sur la position du champ pour assigner ou non la
valeur a ce champ.
@param e L'element XML representant le champ de texte
*/
void DiagramTextItem::fromXml(const QDomElement &e) {
setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
setPlainText(e.attribute("text"));
previous_text = e.attribute("text");
}
/**
@param document Le document XML a utiliser
@return L'element XML representant ce champ de texte
*/
QDomElement DiagramTextItem::toXml(QDomDocument &document) const {
QDomElement result = document.createElement("input");
result.setAttribute("x", pos().x());
result.setAttribute("y", pos().y());
result.setAttribute("text", toPlainText());
return(result);
}
/**
Gere les double-clics sur ce champ de texte.
@param event un QGraphicsSceneMouseEvent decrivant le double-clic
*/
void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
if (flags() & QGraphicsItem::ItemIsMovable && !(textInteractionFlags() & Qt::TextEditable)) {
// rend le champ de texte editable
setTextInteractionFlags(Qt::TextEditorInteraction);
// simule un clic simple, ce qui edite le champ de texte
QGraphicsSceneMouseEvent *mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMousePress);
mouseEvent -> setAccepted(true);
mouseEvent -> setPos(event -> pos());
mouseEvent -> setScenePos(event -> scenePos());
mouseEvent -> setScreenPos(event -> screenPos());
mouseEvent -> setButtonDownPos(Qt::LeftButton, event -> buttonDownPos(Qt::LeftButton));
mouseEvent -> setButtonDownScreenPos(Qt::LeftButton, event -> buttonDownScreenPos(Qt::LeftButton));
mouseEvent -> setButtonDownScenePos(Qt::LeftButton, event -> buttonDownScenePos(Qt::LeftButton));
mouseEvent -> setWidget(event -> widget());
QGraphicsTextItem::mousePressEvent(mouseEvent);
delete mouseEvent;
} else {
QGraphicsTextItem::mouseDoubleClickEvent(event);
}
}
/**
Gere les mouvements de souris lies au champ de texte
*/
void DiagramTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if (textInteractionFlags() & Qt::TextEditable) {
QGraphicsTextItem::mouseMoveEvent(e);
} else if ((flags() & QGraphicsItem::ItemIsMovable) && (e -> buttons() & Qt::LeftButton)) {
QPointF oldPos = pos();
setPos(mapToParent(e -> pos()) - matrix().map(e -> buttonDownPos(Qt::LeftButton)));
if (Diagram *diagram_ptr = diagram()) {
diagram_ptr -> moveElements(pos() - oldPos, this);
}
} else e -> ignore();
}
/**
Gere le relachement de souris
Cette methode a ete reimplementee pour tenir a jour la liste des elements
et conducteurs a deplacer au niveau du schema.
*/
void DiagramTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
if (Diagram *diagram_ptr = diagram()) {
if ((flags() & QGraphicsItem::ItemIsMovable) && (!diagram_ptr -> current_movement.isNull())) {
diagram_ptr -> undoStack().push(
new MoveElementsCommand(
diagram_ptr,
diagram_ptr -> selectedContent(),
diagram_ptr -> current_movement
)
);
diagram_ptr -> current_movement = QPointF();
}
diagram_ptr -> invalidateMovedElements();
}
QGraphicsTextItem::mouseReleaseEvent(e);
}
/**
Change la position du champ de texte en veillant a ce qu'il
reste sur la grille du schema auquel il appartient.
@param p Nouvelles coordonnees de l'element
*/
void DiagramTextItem::setPos(const QPointF &p) {
if (p == pos()) return;
// pas la peine de positionner sur la grille si l'element n'est pas sur un Diagram
if (scene()) {
// arrondit l'abscisse a 10 px pres
int p_x = qRound(p.x() / (Diagram::xGrid * 1.0)) * Diagram::xGrid;
// arrondit l'ordonnee a 10 px pres
int p_y = qRound(p.y() / (Diagram::yGrid * 1.0)) * Diagram::yGrid;
QGraphicsTextItem::setPos(p_x, p_y);
} else QGraphicsTextItem::setPos(p);
}
/**
Change la position du champ de texte en veillant a ce que l'il
reste sur la grille du schema auquel il appartient.
@param x Nouvelle abscisse de l'element
@param y Nouvelle ordonnee de l'element
*/
void DiagramTextItem::setPos(qreal x, qreal y) {
setPos(QPointF(x, y));
}
/// Rend le champ de texte non focusable
void DiagramTextItem::setNonFocusable() {
setFlag(QGraphicsTextItem::ItemIsFocusable, false);
}
+67
View File
@@ -0,0 +1,67 @@
/*
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/>.
*/
#ifndef DIAGRAM_TEXT_ITEM_H
#define DIAGRAM_TEXT_ITEM_H
#include <QtGui>
#include "diagram.h"
/**
Cette classe represente un champ de texte editable sur le schema.
*/
class DiagramTextItem : public QGraphicsTextItem {
Q_OBJECT
// constructeurs, destructeur
public:
DiagramTextItem(QGraphicsItem * = 0, QGraphicsScene * = 0);
DiagramTextItem(const QString &, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~DiagramTextItem();
// attributs
public:
enum { Type = UserType + 1004 };
/// Texte precedent
QString previous_text;
// methodes
public:
/**
Cette methode permet d'utiliser qgraphicsitem_cast sur cet objet
@return le type de QGraphicsItem
*/
virtual int type() const { return Type; }
Diagram *diagram() const;
virtual void fromXml(const QDomElement &);
virtual QDomElement toXml(QDomDocument &) const;
virtual void setPos(const QPointF &);
virtual void setPos(qreal, qreal);
protected:
virtual void focusOutEvent(QFocusEvent *);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
// signaux
signals:
/// signal emis lorsque le champ de texte perd le focus
void lostFocus();
// slots
public slots:
void setNonFocusable();
};
#endif
+950
View File
@@ -0,0 +1,950 @@
/*
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 "diagramview.h"
#include "diagram.h"
#include "customelement.h"
#include "exportdialog.h"
#include "diagramprintdialog.h"
#include "conductor.h"
#include "diagramcommands.h"
#include "conductorpropertieswidget.h"
#include "insetpropertieswidget.h"
/**
Constructeur
@param parent Le QWidegt parent de cette vue de schema
*/
DiagramView::DiagramView(QWidget *parent) : QGraphicsView(parent), is_adding_text(false) {
setInteractive(true);
setCacheMode(QGraphicsView::CacheBackground);
setOptimizationFlags(QGraphicsView::DontSavePainterState|QGraphicsView::DontAdjustForAntialiasing);
// active l'antialiasing
setRenderHint(QPainter::Antialiasing, true);
setRenderHint(QPainter::TextAntialiasing, true);
setRenderHint(QPainter::SmoothPixmapTransform, true);
setScene(scene = new Diagram(this));
scene -> undoStack().setClean();
setDragMode(RubberBandDrag);
setAcceptDrops(true);
setWindowIcon(QIcon(":/ico/qet-16.png"));
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
setAlignment(Qt::AlignLeft | Qt::AlignTop);
adjustSceneRect();
updateWindowTitle();
context_menu = new QMenu(this);
paste_here = new QAction(QIcon(":/ico/paste.png"), tr("Coller ici"), this);
connect(paste_here, SIGNAL(triggered()), this, SLOT(pasteHere()));
connect(scene, SIGNAL(selectionEmptinessChanged()), this, SIGNAL(selectionChanged()));
connect(&(scene -> border_and_inset), SIGNAL(borderChanged(QRectF, QRectF)), this, SLOT(adjustSceneRect()));
connect(&(scene -> undoStack()), SIGNAL(cleanChanged(bool)), this, SLOT(updateWindowTitle()));
}
/**
Destructeur
*/
DiagramView::~DiagramView() {
}
/**
appelle la methode select sur tous les elements de la liste d'elements
*/
void DiagramView::selectAll() {
if (scene -> items().isEmpty()) return;
QPainterPath path;
path.addRect(scene -> itemsBoundingRect());
scene -> setSelectionArea(path);
}
/**
appelle la methode deselect sur tous les elements de la liste d'elements
*/
void DiagramView::selectNothing() {
if (scene -> items().isEmpty()) return;
scene -> clearSelection();
}
/**
Inverse l'etat de selection de tous les elements de la liste d'elements
*/
void DiagramView::selectInvert() {
if (scene -> items().isEmpty()) return;
foreach (QGraphicsItem *item, scene -> items()) item -> setSelected(!item -> isSelected());
}
/**
Supprime les composants selectionnes
*/
void DiagramView::deleteSelection() {
DiagramContent removed_content = scene -> selectedContent();
scene -> clearSelection();
scene -> undoStack().push(new DeleteElementsCommand(scene, removed_content));
adjustSceneRect();
}
/**
Pivote les composants selectionnes
*/
void DiagramView::rotateSelection() {
QHash<Element *, QET::Orientation> elements_to_rotate;
foreach (QGraphicsItem *item, scene -> selectedItems()) {
if (Element *e = qgraphicsitem_cast<Element *>(item)) {
elements_to_rotate.insert(e, e -> orientation().current());
}
}
if (elements_to_rotate.isEmpty()) return;
scene -> undoStack().push(new RotateElementsCommand(elements_to_rotate));
}
/**
accepte ou refuse le drag'n drop en fonction du type de donnees entrant
@param e le QDragEnterEvent correspondant au drag'n drop tente
*/
void DiagramView::dragEnterEvent(QDragEnterEvent *e) {
if (e -> mimeData() -> hasFormat("text/plain")) e -> acceptProposedAction();
else e-> ignore();
}
/**
gere les dragleaveevent
@param e le QDragEnterEvent correspondant au drag'n drop sortant
*/
void DiagramView::dragLeaveEvent(QDragLeaveEvent *) {
}
/**
accepte ou refuse le drag'n drop en fonction du type de donnees entrant
@param e le QDragMoveEvent correspondant au drag'n drop tente
*/
void DiagramView::dragMoveEvent(QDragMoveEvent *e) {
if (e -> mimeData() -> hasFormat("text/plain")) e -> acceptProposedAction();
else e-> ignore();
}
/**
gere les depots (drop) acceptes sur le Diagram
@param e le QDropEvent correspondant au drag'n drop effectue
*/
void DiagramView::dropEvent(QDropEvent *e) {
QString fichier = e -> mimeData() -> text();
int etat;
Element *el = new CustomElement(fichier, 0, 0, &etat);
if (etat) delete el;
else {
diagram() -> undoStack().push(new AddElementCommand(diagram(), el, mapToScene(e -> pos())));
adjustSceneRect();
}
}
/**
Passe le Diagram en mode visualisation
*/
void DiagramView::setVisualisationMode() {
setDragMode(ScrollHandDrag);
setInteractive(false);
emit(modeChanged());
}
/**
Passe le Diagram en mode Selection
*/
void DiagramView::setSelectionMode() {
setDragMode(RubberBandDrag);
setInteractive(true);
emit(modeChanged());
}
/**
Agrandit le schema (+33% = inverse des -25 % de zoomMoins())
*/
void DiagramView::zoomIn() {
scale(4.0/3.0, 4.0/3.0);
adjustGridToZoom();
}
/**
Retrecit le schema (-25% = inverse des +33 % de zoomPlus())
*/
void DiagramView::zoomOut() {
scale(0.75, 0.75);
adjustGridToZoom();
}
/**
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 DiagramView::zoomFit() {
adjustSceneRect();
fitInView(sceneRect(), Qt::KeepAspectRatio);
adjustGridToZoom();
}
/**
Reinitialise le zoom
*/
void DiagramView::zoomReset() {
resetMatrix();
adjustGridToZoom();
}
/**
copie les elements selectionnes du schema dans le presse-papier puis les supprime
*/
void DiagramView::cut() {
copy();
DiagramContent cut_content = scene -> selectedContent();
scene -> clearSelection();
scene -> undoStack().push(new CutDiagramCommand(scene, cut_content));
}
/**
copie les elements selectionnes du schema dans le presse-papier
*/
void DiagramView::copy() {
QClipboard *presse_papier = QApplication::clipboard();
QString contenu_presse_papier = scene -> toXml(false).toString(4);
if (presse_papier -> supportsSelection()) presse_papier -> setText(contenu_presse_papier, QClipboard::Selection);
presse_papier -> setText(contenu_presse_papier);
}
/**
Importe les elements contenus dans le presse-papier dans le schema
@param pos coin superieur gauche (en coordonnees de la scene) du rectangle
englobant le contenu colle
@param clipboard_mode Type de presse-papier a prendre en compte
*/
void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) {
QString texte_presse_papier = QApplication::clipboard() -> text(clipboard_mode);
if ((texte_presse_papier).isEmpty()) return;
QDomDocument document_xml;
if (!document_xml.setContent(texte_presse_papier)) return;
// objet pour recuperer le contenu ajoute au schema par le coller
DiagramContent content_pasted;
scene -> fromXml(document_xml, pos, false, &content_pasted);
// si quelque chose a effectivement ete ajoute au schema, on cree un objet d'annulation
if (content_pasted.count()) {
scene -> clearSelection();
scene -> undoStack().push(new PasteDiagramCommand(scene, content_pasted));
adjustSceneRect();
}
}
/// Colle le contenu du presse-papier sur le schema a la position de la souris
void DiagramView::pasteHere() {
paste(mapToScene(paste_here_pos));
}
/**
gere les clics et plus particulierement le clic du milieu (= coller pour X11)
*/
void DiagramView::mousePressEvent(QMouseEvent *e) {
if (e -> buttons() == Qt::MidButton) {
paste(mapToScene(e -> pos()), QClipboard::Selection);
} else {
if (is_adding_text && e -> buttons() == Qt::LeftButton) {
DiagramTextItem *dti = new DiagramTextItem();
dti -> setPlainText("_");
dti -> previous_text = "_";
scene -> undoStack().push(new AddTextCommand(scene, dti, e -> pos()));
adjustSceneRect();
is_adding_text = false;
emit(textAdded(false));
}
QGraphicsView::mousePressEvent(e);
}
}
/**
Ouvre un fichier *.qet dans cette DiagramView
@param n_fichier Nom du fichier a ouvrir
@param erreur Si le pointeur est specifie, cet entier est mis a 0 en cas de reussite de l'ouverture, 1 si le fichier n'existe pas, 2 si le fichier n'est pas lisible, 3 si le fichier n'est pas un element XML, 4 si l'ouverture du fichier a echoue pour une autre raison (c'est pas ca qui manque ^^)
@return true si l'ouverture a reussi, false sinon
*/
bool DiagramView::open(QString n_fichier, int *erreur) {
// verifie l'existence du fichier
if (!QFileInfo(n_fichier).exists()) {
if (erreur != NULL) *erreur = 1;
return(false);
}
// ouvre le fichier
QFile fichier(n_fichier);
if (!fichier.open(QIODevice::ReadOnly)) {
if (erreur != NULL) *erreur = 2;
return(false);
}
// lit son contenu dans un QDomDocument
QDomDocument document;
if (!document.setContent(&fichier)) {
if (erreur != NULL) *erreur = 3;
fichier.close();
return(false);
}
fichier.close();
/**
La notion de projet (ensemble de documents [schemas, nomenclatures,
...] et d'elements) n'est pas encore geree.
Toutefois, pour gerer au mieux la transition de la 0.1 a la 0.2,
les schemas enregistres (element XML "diagram") sont integres dans un
pseudo projet (element XML "project").
S'il y a plusieurs schemas dans un projet, tous les schemas seront
ouverts comme etant des fichiers separes
*/
// repere les schemas dans le fichier
QDomElement root = document.documentElement();
// cas 1 : l'element racine est un "diagram" : un seul schema, pas de probleme
if (root.tagName() == "diagram") {
// construit le schema a partir du QDomDocument
QDomDocument &doc = document;
if (scene -> fromXml(doc)) {
if (erreur != NULL) *erreur = 0;
file_name = n_fichier;
scene -> undoStack().setClean();
updateWindowTitle();
return(true);
} else {
if (erreur != NULL) *erreur = 4;
return(false);
}
// cas 2 : l'element racine est un "project"
} else if (root.tagName() == "project") {
// verifie basiquement que la version actuelle est capable de lire ce fichier
if (root.hasAttribute("version")) {
bool conv_ok;
qreal diagram_version = root.attribute("version").toDouble(&conv_ok);
if (conv_ok && QET::version.toDouble() < diagram_version) {
QMessageBox::warning(
0,
tr("Avertissement"),
tr("Ce document semble avoir \351t\351 enregistr\351 avec une "
"version ult\351rieure de QElectroTech. Il est possible que "
"l'ouverture de tout ou partie de ce document \351choue.")
);
}
}
// compte le nombre de schemas dans le projet
QList<QDomElement> diagrams;
QDomNodeList diagram_nodes = root.elementsByTagName("diagram");
for (uint i = 0 ; i < diagram_nodes.length() ; ++ i) {
if (diagram_nodes.at(i).isElement()) {
diagrams << diagram_nodes.at(i).toElement();
}
}
// il n'y aucun schema la-dedans
if (!diagrams.count()) {
if (erreur != NULL) *erreur = 4;
return(false);
} else {
bool keep_doc_name = diagrams.count() == 1;
bool current_dv_loaded = false;
for (int i = 0 ; i < diagrams.count() ; ++ i) {
// cree un QDomDocument representant le schema
QDomDocument diagram_doc;
diagram_doc.appendChild(diagram_doc.importNode(diagrams[i], true));
// charge le premier schema valide et cree de nouveau DiagramView pour les suivants
if (!current_dv_loaded) {
if (scene -> fromXml(diagram_doc)) {
if (keep_doc_name) file_name = n_fichier;
scene -> undoStack().setClean();
updateWindowTitle();
current_dv_loaded = true;
}
} else {
DiagramView *new_dv = new DiagramView(parentWidget());
if (new_dv -> scene -> fromXml(diagram_doc)) {
if (keep_doc_name) new_dv -> file_name = n_fichier;
new_dv -> scene -> undoStack().setClean();
new_dv -> updateWindowTitle();
diagramEditor() -> addDiagramView(new_dv);
} else {
delete(new_dv);
}
}
}
return(true);
}
} else {
if (erreur != NULL) *erreur = 4;
return(false);
}
}
/**
Gere la fermeture du schema.
@param event Le QCloseEvent decrivant l'evenement
*/
void DiagramView::closeEvent(QCloseEvent *event) {
bool retour;
// si le schema est modifie
if (!isWindowModified()) {
retour = true;
} else {
// demande d'abord a l'utilisateur s'il veut enregistrer le schema en cours
QMessageBox::StandardButton reponse = QMessageBox::question(
this,
tr("Enregistrer le sch\351ma en cours ?"),
tr("Voulez-vous enregistrer le sch\351ma ") + windowTitle() + tr(" ?"),
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
QMessageBox::Cancel
);
switch(reponse) {
case QMessageBox::Cancel: retour = false; break; // l'utilisateur annule : echec de la fermeture
case QMessageBox::Yes: retour = save(); break; // l'utilisateur dit oui : la reussite depend de l'enregistrement
default: retour = true; // l'utilisateur dit non ou ferme le dialogue: c'est reussi
}
}
if (retour) {
event -> accept();
delete this;
} else event -> ignore();
}
/**
Methode enregistrant le schema dans le dernier nom de fichier connu.
Si aucun nom de fichier n'est connu, cette methode appelle la methode saveAs
@return true si l'enregistrement a reussi, false sinon
*/
bool DiagramView::save() {
if (file_name.isEmpty()) return(saveAs());
else return(saveDiagramToFile(file_name));
}
/**
Cette methode demande un nom de fichier a l'utilisateur pour enregistrer le schema
Si aucun nom n'est entre, elle renvoie faux.
Si le nom ne se termine pas par l'extension .qet, celle-ci est ajoutee.
Si l'enregistrement reussit, le nom du fichier est conserve et la fonction renvoie true.
Sinon, faux est renvoye.
@return true si l'enregistrement a reussi, false sinon
*/
bool DiagramView::saveAs() {
// demande un nom de fichier a l'utilisateur pour enregistrer le schema
QString n_fichier = QFileDialog::getSaveFileName(
this,
tr("Enregistrer sous"),
(file_name.isEmpty() ? QDir::homePath() : QDir(file_name)).absolutePath(),
tr("Sch\351ma QElectroTech (*.qet)")
);
// si aucun nom n'est entre, renvoie faux.
if (n_fichier.isEmpty()) return(false);
// si le nom ne se termine pas par l'extension .qet, celle-ci est ajoutee
if (!n_fichier.endsWith(".qet", Qt::CaseInsensitive)) n_fichier += ".qet";
// tente d'enregistrer le fichier
bool resultat_enregistrement = saveDiagramToFile(n_fichier);
// si l'enregistrement reussit, le nom du fichier est conserve
if (resultat_enregistrement) {
file_name = n_fichier;
updateWindowTitle();
}
// retourne un booleen representatif de la reussite de l'enregistrement
return(resultat_enregistrement);
}
/**
Gere les actions liees a la rollette de la souris
@param e QWheelEvent decrivant l'evenement rollette
*/
void DiagramView::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);
}
}
/**
Methode privee gerant l'enregistrement du fichier XML. S'il n'est pas possible
d'ecrire dans le fichier, cette fonction affiche un message d'erreur et renvoie false.
Autrement, elle renvoie true.
@param n_fichier Nom du fichier dans lequel l'arbre XML doit etre ecrit
@return true si l'enregistrement a reussi, false sinon
*/
bool DiagramView::saveDiagramToFile(QString &n_fichier) {
QFile fichier(n_fichier);
if (!fichier.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Erreur"), tr("Impossible d'ecrire dans ce fichier"));
return(false);
}
QTextStream out(&fichier);
out.setCodec("UTF-8");
// l'export XML du schema est encapsule dans un pseudo-projet
QDomDocument final_document;
QDomElement project_root = final_document.createElement("project");
project_root.setAttribute("version", QET::version);
project_root.appendChild(final_document.importNode(scene -> toXml().documentElement(), true));
final_document.appendChild(project_root);
out << final_document.toString(4);
fichier.close();
scene -> undoStack().setClean();
return(true);
}
/**
Exporte le schema.
*/
void DiagramView::dialogExport() {
ExportDialog ed(scene, this);
ed.exec();
}
/**
Imprime le schema.
*/
void DiagramView::dialogPrint() {
// determine un nom possible pour le pdf
QString pdf_file_name;
if (!file_name.isEmpty()) {
pdf_file_name = file_name;
pdf_file_name.replace(QRegExp("\\.qet$", Qt::CaseInsensitive), "");
} else {
pdf_file_name = QDir::homePath() + tr("schema");
}
pdf_file_name += ".pdf";
DiagramPrintDialog print_dialog(scene, this);
print_dialog.setPDFName(pdf_file_name);
print_dialog.exec();
}
/**
Edite les informations du schema.
*/
void DiagramView::dialogEditInfos() {
// recupere le cartouche du schema
InsetProperties inset = scene -> border_and_inset.exportInset();
// recupere les dimensions du schema
int columns_count_value = scene -> border_and_inset.nbColumn();
int columns_width_value = qRound(scene -> border_and_inset.columnsWidth());
int columns_height_value = qRound(scene -> border_and_inset.columnsHeight());
// construit le dialogue
QDialog popup;
popup.setMinimumWidth(400);
popup.setWindowTitle(tr("Propri\351t\351s du sch\351ma"));
QGroupBox *diagram_size_box = new QGroupBox(tr("Dimensions du sch\351ma"), &popup);
QGridLayout diagram_size_box_layout(diagram_size_box);
QLabel *ds1 = new QLabel(tr("Colonnes :"));
QSpinBox *columns_count = new QSpinBox(diagram_size_box);
columns_count -> setMinimum(scene -> border_and_inset.minNbColumns());
columns_count -> setValue(columns_count_value);
QSpinBox *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 :"));
QSpinBox *columns_height = new QSpinBox(diagram_size_box);
columns_height -> setRange(qRound(scene -> border_and_inset.minColumnsHeight()), 10000);
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);
diagram_size_box_layout.setColumnStretch(0, 1);
diagram_size_box_layout.setColumnStretch(1, 1);
diagram_size_box_layout.setColumnStretch(2, 1);
diagram_size_box_layout.setColumnStretch(3, 500);
InsetPropertiesWidget *inset_infos = new InsetPropertiesWidget(inset, false, &popup);
// boutons
QDialogButtonBox boutons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(&boutons, SIGNAL(accepted()), &popup, SLOT(accept()));
connect(&boutons, SIGNAL(rejected()), &popup, SLOT(reject()));
// ajout dans une disposition verticale
QVBoxLayout layout_v(&popup);
layout_v.addWidget(diagram_size_box);
layout_v.addWidget(inset_infos);
layout_v.addStretch();
layout_v.addWidget(&boutons);
// si le dialogue est accepte
if (popup.exec() == QDialog::Accepted) {
InsetProperties new_inset = inset_infos -> insetProperties();
// s'il y a des modifications au cartouche
if (new_inset != inset) {
scene -> undoStack().push(new ChangeInsetCommand(scene, inset, new_inset));
}
// s'il y a des modifications aux dimensions du schema
if (
columns_count_value != columns_count -> value() ||\
columns_width_value != columns_width -> value() ||\
columns_height_value != columns_height -> value()
) {
ChangeBorderCommand *cbc = new ChangeBorderCommand(scene);
cbc -> columnsCountDifference = columns_count -> value() - columns_count_value;
cbc -> columnsWidthDifference = columns_width -> value() - columns_width_value;
cbc -> columnsHeightDifference = columns_height -> value() - columns_height_value;
scene -> undoStack().push(cbc);
}
}
}
/**
@return true s'il y a des elements selectionnes sur le schema, false sinon
*/
bool DiagramView::hasSelectedItems() {
return(scene -> selectedItems().size() > 0);
}
/**
Ajoute une colonne au schema.
*/
void DiagramView::addColumn() {
ChangeBorderCommand *cbc = new ChangeBorderCommand(scene);
cbc -> columnsCountDifference = 1;
scene -> undoStack().push(cbc);
}
/**
Enleve une colonne au schema.
*/
void DiagramView::removeColumn() {
ChangeBorderCommand *cbc = new ChangeBorderCommand(scene);
cbc -> columnsCountDifference = -1;
scene -> undoStack().push(cbc);
}
/**
Agrandit le schema en hauteur
*/
void DiagramView::expand() {
ChangeBorderCommand *cbc = new ChangeBorderCommand(scene);
cbc -> columnsHeightDifference = 80.0;
scene -> undoStack().push(cbc);
}
/**
Retrecit le schema en hauteur
*/
void DiagramView::shrink() {
ChangeBorderCommand *cbc = new ChangeBorderCommand(scene);
cbc -> columnsHeightDifference = -80.0;
scene -> undoStack().push(cbc);
}
/**
Ajuste le sceneRect (zone du schema visualisee par le DiagramView) afin que
celui inclut a la fois les elements dans et en dehors du cadre et le cadre
lui-meme.
*/
void DiagramView::adjustSceneRect() {
QRectF old_scene_rect = sceneRect();
// rectangle delimitant l'ensemble des elements
QRectF elements_bounding_rect = scene -> itemsBoundingRect();
// rectangle contenant le cadre = colonnes + cartouche
QRectF border_bounding_rect = scene -> border().adjusted(-Diagram::margin, -Diagram::margin, Diagram::margin, Diagram::margin);
// ajuste la sceneRect
QRectF new_scene_rect = elements_bounding_rect.united(border_bounding_rect);
setSceneRect(new_scene_rect);
// met a jour la scene
scene -> update(old_scene_rect.united(new_scene_rect));
}
/**
Met a jour le titre du widget
*/
void DiagramView::updateWindowTitle() {
QString window_title;
if (file_name.isNull()) window_title += tr("nouveau sch\351ma");
else window_title += file_name;
window_title += "[*]";
setWindowTitle(window_title);
setWindowModified(!(scene -> undoStack().isClean()));
}
/**
Active ou desactive le dessin de grille selon la quantite de pixels affichee
*/
void DiagramView::adjustGridToZoom() {
QRectF viewed_scene = viewedSceneRect();
scene -> setDisplayGrid(viewed_scene.width() < 2000 || viewed_scene.height() < 2000);
}
/**
@return le rectangle du schema (classe Diagram) visualise par ce DiagramView
*/
QRectF DiagramView::viewedSceneRect() const {
// recupere la taille du widget viewport
QSize viewport_size = viewport() -> size();
// recupere la transformation viewport -> scene
QTransform view_to_scene = viewportTransform().inverted();
// mappe le coin superieur gauche et le coin inferieur droit de la viewport sur la scene
QPointF scene_left_top = view_to_scene.map(QPointF(0.0, 0.0));
QPointF scene_right_bottom = view_to_scene.map(QPointF(viewport_size.width(), viewport_size.height()));
// en deduit le rectangle visualise par la scene
return(QRectF(scene_left_top, scene_right_bottom));
}
/**
Affiche un dialogue permettant d'editer le conducteur selectionne.
Ne fait rien s'il y a 0 ou plusieurs conducteurs selectionnes.
*/
void DiagramView::editConductor() {
QList<Conductor *> selected_conductors(scene -> selectedConductors().toList());
// on ne peut editer qu'un conducteur a la fois
if (selected_conductors.count() != 1) return;
Conductor *edited_conductor = selected_conductors.first();
editConductor(edited_conductor);
}
/**
Edite le conducteur passe en parametre
@param edited_conductor Conducteur a editer
*/
void DiagramView::editConductor(Conductor *edited_conductor) {
if (!edited_conductor) return;
// initialise l'editeur de proprietes pour le conducteur
ConductorProperties old_properties = edited_conductor -> properties();
ConductorPropertiesWidget *cpw = new ConductorPropertiesWidget(old_properties);
// l'insere dans un dialogue
QDialog conductor_dialog;
conductor_dialog.setWindowTitle(tr("\311diter les propri\351t\351s d'un conducteur"));
QVBoxLayout *dialog_layout = new QVBoxLayout(&conductor_dialog);
dialog_layout -> addWidget(cpw);
dialog_layout -> addStretch();
QDialogButtonBox *dbb = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog_layout -> addWidget(dbb);
connect(dbb, SIGNAL(accepted()), &conductor_dialog, SLOT(accept()));
connect(dbb, SIGNAL(rejected()), &conductor_dialog, SLOT(reject()));
// execute le dialogue et met a jour le conducteur
if (conductor_dialog.exec() == QDialog::Accepted) {
// recupere les nouvelles proprietes
ConductorProperties new_properties = cpw -> conductorProperties();
if (new_properties != old_properties) {
// initialise l'objet UndoCommand correspondant
ChangeConductorPropertiesCommand *ccpc = new ChangeConductorPropertiesCommand(edited_conductor);
ccpc -> setOldSettings(old_properties);
ccpc -> setNewSettings(new_properties);
diagram() -> undoStack().push(ccpc);
}
}
}
/**
Reinitialise le profil des conducteurs selectionnes
*/
void DiagramView::resetConductors() {
// recupere les conducteurs selectionnes
QSet<Conductor *> selected_conductors = scene -> selectedConductors();
// repere les conducteurs modifies (= profil non nul)
QHash<Conductor *, ConductorProfilesGroup> conductors_and_profiles;
foreach(Conductor *conductor, selected_conductors) {
ConductorProfilesGroup profile = conductor -> profiles();
if (
!profile[Qt::TopLeftCorner].isNull() ||\
!profile[Qt::TopRightCorner].isNull() ||\
!profile[Qt::BottomLeftCorner].isNull() ||\
!profile[Qt::BottomRightCorner].isNull()
) {
conductors_and_profiles.insert(conductor, profile);
}
}
if (conductors_and_profiles.isEmpty()) return;
scene -> undoStack().push(new ResetConductorCommand(conductors_and_profiles));
}
/**
Lance un dialogue permettant de modifier les proprietes par defaut des
futurs nouveaux conducteurs
*/
void DiagramView::editDefaultConductorProperties() {
// initialise l'editeur de proprietes pour le conducteur
ConductorPropertiesWidget *cpw = new ConductorPropertiesWidget(scene -> defaultConductorProperties);
// l'insere dans un dialogue
QDialog conductor_dialog;
conductor_dialog.setWindowTitle(tr("\311diter les propri\351t\351s par d\351faut des conducteurs"));
QVBoxLayout *dialog_layout = new QVBoxLayout(&conductor_dialog);
dialog_layout -> addWidget(cpw);
QDialogButtonBox *dbb = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog_layout -> addWidget(dbb);
connect(dbb, SIGNAL(accepted()), &conductor_dialog, SLOT(accept()));
connect(dbb, SIGNAL(rejected()), &conductor_dialog, SLOT(reject()));
// execute le dialogue et met a jour le conducteur
if (conductor_dialog.exec() == QDialog::Accepted) {
scene -> defaultConductorProperties = cpw -> conductorProperties();
}
}
/**
Gere les evenements de la DiagramView
@param e Evenement
*/
bool DiagramView::event(QEvent *e) {
// fait en sorte que les raccourcis clavier arrivent prioritairement sur la
// vue plutot que de remonter vers les QMenu / QAction
if (e -> type() == QEvent::ShortcutOverride && scene -> focusItem()) {
e -> accept();
return(true);
}
return(QGraphicsView::event(e));
}
/**
Passe le DiagramView en mode "ajout de texte". Un clic cree alors un
nouveau champ de texte.
*/
void DiagramView::addText() {
is_adding_text = true;
}
/**
Gere le menu contextuel
@param e Evenement decrivant la demande de menu contextuel
*/
void DiagramView::contextMenuEvent(QContextMenuEvent *e) {
if (QGraphicsItem *qgi = scene -> itemAt(mapToScene(e -> pos()))) {
if (!qgi -> isSelected()) scene -> clearSelection();
qgi -> setSelected(true);
}
if (QETDiagramEditor *qde = diagramEditor()) {
context_menu -> clear();
if (scene -> selectedItems().isEmpty()) {
paste_here_pos = e -> pos();
paste_here -> setEnabled(Diagram::clipboardMayContainDiagram());
context_menu -> addAction(paste_here);
context_menu -> addSeparator();
context_menu -> addAction(qde -> infos_diagram);
context_menu -> addAction(qde -> add_column);
context_menu -> addAction(qde -> remove_column);
context_menu -> addAction(qde -> expand_diagram);
context_menu -> addAction(qde -> shrink_diagram);
} else {
context_menu -> addAction(qde -> cut);
context_menu -> addAction(qde -> copy);
context_menu -> addSeparator();
context_menu -> addAction(qde -> delete_selection);
context_menu -> addAction(qde -> rotate_selection);
context_menu -> addSeparator();
context_menu -> addAction(qde -> conductor_prop);
context_menu -> addAction(qde -> conductor_reset);
}
// affiche le menu contextuel
context_menu -> popup(e -> globalPos());
}
e -> accept();
}
/// @return l'editeur de schemas parent ou 0
QETDiagramEditor *DiagramView::diagramEditor() const {
// remonte la hierarchie des widgets
QWidget *w = const_cast<DiagramView *>(this);
while (w -> parentWidget() && !w -> isWindow()) {
w = w -> parentWidget();
}
// la fenetre est supposee etre un QETDiagramEditor
return(qobject_cast<QETDiagramEditor *>(w));
}
/**
Gere les double-clics sur le schema
*/
void DiagramView::mouseDoubleClickEvent(QMouseEvent *e) {
BorderInset &bi = scene -> border_and_inset;
// recupere le rectangle corespondant au cartouche
QRectF inset_rect(
Diagram::margin,
Diagram::margin + bi.columnsHeight(),
bi.insetWidth(),
bi.insetHeight()
);
// recupere le rectangle correspondant aux en-tetes des colonnes
QRectF columns_rect(
Diagram::margin,
Diagram::margin,
bi.borderWidth(),
bi.columnsHeaderHeight()
);
// coordonnees du clic par rapport au schema
QPointF click_pos = viewportTransform().inverted().map(e -> pos());
// detecte le double-clic sur le cartouche ou les colonnes
if (QGraphicsItem *qgi = itemAt(e -> pos())) {
if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) {
editConductor(c);
} else {
QGraphicsView::mouseDoubleClickEvent(e);
}
} else if (inset_rect.contains(click_pos) || columns_rect.contains(click_pos)) {
// edite les proprietes du schema
dialogEditInfos();
} else {
QGraphicsView::mouseDoubleClickEvent(e);
}
}
+118
View File
@@ -0,0 +1,118 @@
/*
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/>.
*/
#ifndef DIAGRAMVIEW_H
#define DIAGRAMVIEW_H
#include <QtGui>
class Diagram;
class QETDiagramEditor;
class Conductor;
/**
Classe representant graphiquement un schema electrique
*/
class DiagramView : public QGraphicsView {
Q_OBJECT
// constructeurs, destructeur
public:
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;
QPoint paste_here_pos;
bool is_adding_text;
// methodes
public:
bool open(QString, int * = NULL);
void closeEvent(QCloseEvent *);
bool save();
bool saveAs();
void dialogExport();
void dialogEditInfos();
void dialogPrint();
void addColumn();
void removeColumn();
void expand();
void shrink();
/// @return Le schema visualise par ce DiagramView
Diagram *diagram() { return(scene); }
QETDiagramEditor *diagramEditor() const;
bool hasSelectedItems();
void addText();
protected:
virtual void mouseDoubleClickEvent(QMouseEvent *);
virtual void contextMenuEvent(QContextMenuEvent *);
virtual void wheelEvent(QWheelEvent *);
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;
signals:
/// Signal emis lorsque la selection change
void selectionChanged();
/// Signal emis lorsque le mode de selection change
void modeChanged();
/// Signal emis lorsqu'un texte a ete pose
void textAdded(bool);
public slots:
void selectNothing();
void selectAll();
void selectInvert();
void deleteSelection();
void rotateSelection();
void setVisualisationMode();
void setSelectionMode();
void zoomIn();
void zoomOut();
void zoomFit();
void zoomReset();
void cut();
void copy();
void paste(const QPointF & = QPointF(), QClipboard::Mode = QClipboard::Clipboard);
void pasteHere();
void adjustSceneRect();
void updateWindowTitle();
void editConductor();
void editConductor(Conductor *);
void resetConductors();
void editDefaultConductorProperties();
private slots:
void adjustGridToZoom();
};
#endif
+128
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 "arceditor.h"
#include "partarc.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param arc L'arc a editer
@param parent le Widget parent
*/
ArcEditor::ArcEditor(QETElementEditor *editor, PartArc *arc, QWidget *parent) : ElementItemEditor(editor, parent) {
part = arc;
x = new QLineEdit();
y = new QLineEdit();
h = new QLineEdit();
v = new QLineEdit();
start_angle = new QSpinBox();
angle = new QSpinBox();
start_angle -> setRange(-360, 360);
angle -> setRange(-360, 360);
x -> setValidator(new QDoubleValidator(x));
y -> setValidator(new QDoubleValidator(y));
h -> setValidator(new QDoubleValidator(h));
v -> setValidator(new QDoubleValidator(v));
QGridLayout *grid = new QGridLayout(this);
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
grid -> addWidget(new QLabel("x"), 1, 0);
grid -> addWidget(x, 1, 1);
grid -> addWidget(new QLabel("y"), 1, 2);
grid -> addWidget(y, 1, 3);
grid -> addWidget(new QLabel(tr("Diam\350tres : ")), 2, 0);
grid -> addWidget(new QLabel(tr("horizontal :")), 3, 0);
grid -> addWidget(h, 3, 1);
grid -> addWidget(new QLabel(tr("vertical :")), 4, 0);
grid -> addWidget(v, 4, 1);
grid -> addWidget(new QLabel(tr("Angle de d\351part :")), 5, 0);
grid -> addWidget(start_angle, 5, 1);
grid -> addWidget(new QLabel(tr("Angle :")), 6, 0);
grid -> addWidget(angle, 6, 1);
updateForm();
activeConnections(true);
}
/// Destructeur
ArcEditor::~ArcEditor() {
}
/**
Met a jour l'arc a partir a partir des donnees du formulaire
*/
void ArcEditor::updateArc() {
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 -> 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
void ArcEditor::updateArcX() { addChangePartCommand(tr("abscisse"), part, "x", x -> text().toDouble()); }
/// Met a jour l'ordonnee du centre de l'arc et cree un objet d'annulation
void ArcEditor::updateArcY() { addChangePartCommand(tr("ordonn\351e"), part, "y", y -> text().toDouble()); }
/// Met a jour le diametre horizontal de l'arc et cree un objet d'annulation
void ArcEditor::updateArcH() { addChangePartCommand(tr("diam\350tre horizontal"), part, "diameter_h", h -> text().toDouble()); }
/// Met a jour le diametre vertical de l'arc et cree un objet d'annulation
void ArcEditor::updateArcV() { addChangePartCommand(tr("diam\350tre vertical"), part, "diameter_v", v -> text().toDouble()); }
/// Met a jour l'angle de depart de l'arc et cree un objet d'annulation
void ArcEditor::updateArcS() { addChangePartCommand(tr("angle de d\351part"), part, "start_angle", -start_angle -> value() + 90); }
/// Met a jour l'etendue de l'arc et cree un objet d'annulation
void ArcEditor::updateArcA() { addChangePartCommand(tr("angle"), part, "angle", -angle -> value()); }
/**
Met a jour le formulaire d'edition
*/
void ArcEditor::updateForm() {
activeConnections(false);
x -> setText(part -> property("x").toString());
y -> setText(part -> property("y").toString());
h -> setText(part -> property("diameter_h").toString());
v -> setText(part -> property("diameter_v").toString());
start_angle -> setValue(-part -> startAngle() + 90);
angle -> setValue(-part -> angle());
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 ArcEditor::activeConnections(bool active) {
if (active) {
connect(x, SIGNAL(editingFinished()), this, SLOT(updateArcX()));
connect(y, SIGNAL(editingFinished()), this, SLOT(updateArcY()));
connect(h, SIGNAL(editingFinished()), this, SLOT(updateArcH()));
connect(v, SIGNAL(editingFinished()), this, SLOT(updateArcV()));
connect(start_angle, SIGNAL(editingFinished()), this, SLOT(updateArcS()));
connect(angle, SIGNAL(editingFinished()), this, SLOT(updateArcA()));
} else {
disconnect(x, SIGNAL(editingFinished()), this, SLOT(updateArcX()));
disconnect(y, SIGNAL(editingFinished()), this, SLOT(updateArcY()));
disconnect(h, SIGNAL(editingFinished()), this, SLOT(updateArcH()));
disconnect(v, SIGNAL(editingFinished()), this, SLOT(updateArcV()));
disconnect(start_angle, SIGNAL(editingFinished()), this, SLOT(updateArcS()));
disconnect(angle, SIGNAL(editingFinished()), this, SLOT(updateArcA()));
}
}
+56
View File
@@ -0,0 +1,56 @@
/*
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 ARC_EDITOR_H
#define ARC_EDITOR_H
#include <QtGui>
#include "elementitemeditor.h"
class PartArc;
/**
Cette classe represente le widget d'edition d'un arc dans l'editeur
d'element.
*/
class ArcEditor : public ElementItemEditor {
Q_OBJECT
//constructeurs, destructeur
public:
ArcEditor(QETElementEditor *, PartArc *, QWidget * = 0);
~ArcEditor();
private:
ArcEditor(const ArcEditor &);
// attributs
private:
PartArc *part;
QLineEdit *x, *y, *h, *v;
QSpinBox *angle, *start_angle;
// methodes
public slots:
void updateArc();
void updateArcX();
void updateArcY();
void updateArcH();
void updateArcV();
void updateArcS();
void updateArcA();
void updateForm();
private:
void activeConnections(bool);
};
#endif
+99
View File
@@ -0,0 +1,99 @@
/*
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 "circleeditor.h"
#include "partcircle.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param circle Le cercle a editer
@param parent le Widget parent
*/
CircleEditor::CircleEditor(QETElementEditor *editor, PartCircle *circle, QWidget *parent) : ElementItemEditor(editor, parent) {
part = circle;
x = new QLineEdit();
y = new QLineEdit();
r = new QLineEdit();
x -> setValidator(new QDoubleValidator(x));
y -> setValidator(new QDoubleValidator(y));
r -> setValidator(new QDoubleValidator(r));
QGridLayout *grid = new QGridLayout(this);
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
grid -> addWidget(new QLabel("x"), 1, 0);
grid -> addWidget(x, 1, 1);
grid -> addWidget(new QLabel("y"), 1, 2);
grid -> addWidget(y, 1, 3);
grid -> addWidget(new QLabel(tr("Diam\350tre : ")), 2, 0);
grid -> addWidget(r, 2, 1);
activeConnections(true);
updateForm();
}
/// Destructeur
CircleEditor::~CircleEditor() {
}
/**
met a jour le cercle a partir des donnees du formulaire
*/
void CircleEditor::updateCircle() {
part -> setProperty("x", x -> text().toDouble());
part -> setProperty("y", y -> text().toDouble());
part -> setProperty("diameter", r -> text().toDouble());
}
/// Met a jour l'abscisse du cercle et cree un objet d'annulation
void CircleEditor::updateCircleX() { addChangePartCommand(tr("abscisse"), part, "x", x -> text().toDouble()); }
/// Met a jour l'ordonnee du cercle et cree un objet d'annulation
void CircleEditor::updateCircleY() { addChangePartCommand(tr("ordonn\351e"), part, "y", y -> text().toDouble()); }
/// Met a jour le diametre du cercle et cree un objet d'annulation
void CircleEditor::updateCircleD() { addChangePartCommand(tr("diam\350tre"), part, "diameter", r -> text().toDouble()); }
/**
Met a jour le formulaire d'edition
*/
void CircleEditor::updateForm() {
activeConnections(false);
x -> setText(part -> property("x").toString());
y -> setText(part -> property("y").toString());
r -> setText(part -> property("diameter").toString());
activeConnections(true);
}
/**
Active ou desactive les connexionx signaux/slots entre les widgets internes.
@param active true pour activer les connexions, false pour les desactiver
*/
void CircleEditor::activeConnections(bool active) {
if (active) {
connect(x, SIGNAL(editingFinished()), this, SLOT(updateCircleX()));
connect(y, SIGNAL(editingFinished()), this, SLOT(updateCircleY()));
connect(r, SIGNAL(editingFinished()), this, SLOT(updateCircleD()));
} else {
disconnect(x, SIGNAL(editingFinished()), this, SLOT(updateCircleX()));
disconnect(y, SIGNAL(editingFinished()), this, SLOT(updateCircleY()));
disconnect(r, SIGNAL(editingFinished()), this, SLOT(updateCircleD()));
}
}
+53
View File
@@ -0,0 +1,53 @@
/*
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 CIRCLE_EDITOR_H
#define CIRCLE_EDITOR_H
#include <QtGui>
#include "elementitemeditor.h"
class PartCircle;
/**
Cette classe represente un editeur de cercle.
Elle permet d'editer a travers une interface graphique les
proprietes d'une cercle composant le dessin d'un element.
*/
class CircleEditor : public ElementItemEditor {
Q_OBJECT
// Constructeurs, destructeur
public:
CircleEditor(QETElementEditor *, PartCircle *, QWidget * = 0);
virtual ~CircleEditor();
private:
CircleEditor(const CircleEditor &);
// attributs
private:
PartCircle *part;
QLineEdit *x, *y, *r;
// methodes
public slots:
void updateCircle();
void updateCircleX();
void updateCircleY();
void updateCircleD();
void updateForm();
private:
void activeConnections(bool);
};
#endif
+208
View File
@@ -0,0 +1,208 @@
/*
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 "customelementgraphicpart.h"
/**
Ecrit les attributs de style dans un element XML
@param qde L'element XML a modifier
*/
void CustomElementGraphicPart::stylesToXml(QDomElement &qde) const {
QString css_like_styles;
css_like_styles += "line-style:";
if (_linestyle == DashedStyle) css_like_styles += "dashed";
else if (_linestyle == NormalStyle) css_like_styles += "normal";
css_like_styles += ";line-weight:";
if (_lineweight == NoneWeight) css_like_styles += "none";
else if (_lineweight == ThinWeight) css_like_styles += "thin";
else if (_lineweight == NormalWeight) css_like_styles += "normal";
css_like_styles += ";filling:";
if (_filling == NoneFilling) css_like_styles += "none";
else if (_filling == BlackFilling) css_like_styles += "black";
else if (_filling == WhiteFilling) css_like_styles += "white";
css_like_styles += ";color:";
if (_color == WhiteColor) css_like_styles += "white";
else if (_color == BlackColor) css_like_styles += "black";
qde.setAttribute("style", css_like_styles);
qde.setAttribute("antialias", _antialiased ? "true" : "false");
}
/**
Lit les attributs de style depuis un element XML
@param qde L'element XML a analyser
*/
void CustomElementGraphicPart::stylesFromXml(const QDomElement &qde) {
resetStyles();
// recupere la liste des couples style / valeur
QStringList styles = qde.attribute("style").split(";", QString::SkipEmptyParts);
// analyse chaque couple
QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
foreach (QString style, styles) {
if (!rx.exactMatch(style)) continue;
QString style_name = rx.cap(1);
QString style_value = rx.cap(2);
if (style_name == "line-style") {
if (style_value == "dashed") _linestyle = DashedStyle;
else if (style_value == "normal") _linestyle = NormalStyle;
// il n'y a pas de else car les valeurs non conformes sont ignorees (idem par la suite)
} else if (style_name == "line-weight") {
if (style_value == "thin") _lineweight = ThinWeight;
else if (style_value == "normal") _lineweight = NormalWeight;
else if (style_value == "none") _lineweight = NoneWeight;
} else if (style_name == "filling") {
if (style_value == "white") _filling = WhiteFilling;
else if (style_value == "black") _filling = BlackFilling;
else if (style_value == "none") _filling = NoneFilling;
} else if (style_name == "color") {
if (style_value == "black") _color = BlackColor;
else if (style_value == "white") _color = WhiteColor;
}
}
// recupere l'antialiasing
_antialiased = qde.attribute("antialias") == "true";
// met a jour l'editeur de style
style_editor -> updateForm();
}
/**
Remet les styles par defaut
*/
void CustomElementGraphicPart::resetStyles() {
_linestyle = NormalStyle;
_lineweight = NormalWeight;
_filling = NoneFilling;
_color = BlackColor;
_antialiased = false;
}
/**
Applique les styles a un Qpainter
@param painter QPainter a modifier
*/
void CustomElementGraphicPart::applyStylesToQPainter(QPainter &painter) const {
// recupere le QPen et la QBrush du QPainter
QPen pen = painter.pen();
QBrush brush = painter.brush();
// applique le style de trait
if (_linestyle == DashedStyle) pen.setStyle(Qt::DashLine);
else if (_linestyle == NormalStyle) pen.setStyle(Qt::SolidLine);
// applique l'epaisseur de trait
if (_lineweight == NoneWeight) pen.setColor(QColor(0, 0, 0, 0));
else if (_lineweight == ThinWeight) pen.setWidth(0);
else if (_lineweight == NormalWeight) pen.setWidthF(1.0);
// applique le remplissage
if (_filling == NoneFilling) {
brush.setStyle(Qt::NoBrush);
} else if (_filling == BlackFilling) {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::black);
} else if (_filling == WhiteFilling) {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::white);
}
// applique la couleur de trait
if (_color == WhiteColor) pen.setColor(QColor(255, 255, 255, pen.color().alpha()));
else if (_color == BlackColor) pen.setColor(QColor( 0, 0, 0, pen.color().alpha()));
// applique l'antialiasing
painter.setRenderHint(QPainter::Antialiasing, _antialiased);
painter.setRenderHint(QPainter::TextAntialiasing, _antialiased);
painter.setRenderHint(QPainter::SmoothPixmapTransform, _antialiased);
painter.setPen(pen);
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 :
* line-style : type de trait (@see LineStyle)
* line-weight : epaisseur du traut (@see LineWeight)
* filling : couleur de remplissage (@see Color)
* color : couleur du trait (@see Color)
* antialias : utiliser l'antialiasing ou non (booleen)
@param value Valeur a attribuer a la propriete
*/
void CustomElementGraphicPart::setProperty(const QString &property, const QVariant &value) {
bool change_made = false;
if (property == "line-style") {
setLineStyle(static_cast<LineStyle>(value.toInt()));
change_made = true;
} else if (property == "line-weight") {
setLineWeight(static_cast<LineWeight>(value.toInt()));
change_made = true;
} else if (property == "filling") {
setFilling(static_cast<Filling>(value.toInt()));
change_made = true;
} else if (property == "color") {
setColor(static_cast<Color>(value.toInt()));
change_made = true;
} else if (property == "antialias") {
setAntialiased(value.toBool());
change_made = true;
}
if (change_made) {
style_editor -> updateForm();
}
}
/**
Permet d'acceder a la valeur d'une propriete de style donnee.
@param property propriete lue. Valeurs acceptees :
* line-style : type de trait (@see LineStyle)
* line-weight : epaisseur du traut (@see LineWeight)
* filling : couleur de remplissage (@see Color)
* color : couleur du trait (@see Color)
* antialias : utiliser l'antialiasing ou non (booleen)
@return La valeur de la propriete property
*/
QVariant CustomElementGraphicPart::property(const QString &property) {
if (property == "line-style") {
return(lineStyle());
} else if (property == "line-weight") {
return(lineWeight());
} else if (property == "filling") {
return(filling());
} else if (property == "color") {
return(color());
} else if (property == "antialias") {
return(antialiased());
}
return(QVariant());
}
+192
View File
@@ -0,0 +1,192 @@
/*
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 CUSTOM_ELEMENT_GRAPHIC_PART_H
#define CUSTOM_ELEMENT_GRAPHIC_PART_H
#include <QPainter>
#include "customelementpart.h"
#include "styleeditor.h"
class QETElementEditor;
typedef CustomElementGraphicPart CEGP;
/**
Cette classe represente une partie graphique d'element
Elle encapsule des methodes afin de gerer les attributs de style communs
a la plupart des parties d'elements
*/
class CustomElementGraphicPart : public CustomElementPart {
public:
/// Qualifie le style de ligne utilise pour dessiner la partie
enum LineStyle {
NormalStyle, ///< Ligne pleine
DashedStyle ///< Ligne pointillee
};
/// Qualifie l'epaisseur de ligne utilisee pour dessiner la partie
enum LineWeight {
NormalWeight, ///< Ligne normale
ThinWeight, ///< Ligne fine
NoneWeight ///< Ligne invisible
};
/// Qualifie la couleur utilisee pour remplir la partie
enum Filling {
NoneFilling, ///< Remplissage transparent
BlackFilling, ///< Remplissage en noir
WhiteFilling ///< Remplissage en blanc
};
/// Qualifie la couleur de ligne utilisee pour dessiner la partie
enum Color {
BlackColor, ///< Ligne noire
WhiteColor ///< Ligne blanche
};
// constructeurs, destructeur
public:
/**
Constructeur
@param editor Editeur d'element auquel cette partie est rattachee
*/
CustomElementGraphicPart(QETElementEditor *editor) :
CustomElementPart(editor),
_linestyle(NormalStyle),
_lineweight(NormalWeight),
_filling(NoneFilling),
_color(BlackColor),
_antialiased(false)
{
style_editor = new StyleEditor(elementEditor(), this);
};
/// Destructeur
virtual ~CustomElementGraphicPart() {
delete style_editor;
};
// attributs
private:
LineStyle _linestyle;
LineWeight _lineweight;
Filling _filling ;
Color _color;
bool _antialiased;
protected:
/// Widget d'edition des styles de cette partie graphique
StyleEditor *style_editor;
//methodes
public:
void setLineStyle(LineStyle);
void setLineWeight(LineWeight);
void setFilling(Filling);
void setColor(Color);
void setAntialiased(bool);
LineStyle lineStyle() const;
LineWeight lineWeight() const;
Filling filling() const;
Color color() const;
bool antialiased() const;
QWidget *elementInformations();
void setProperty(const QString &, const QVariant &);
QVariant property(const QString &);
protected:
void stylesToXml(QDomElement &) const;
void stylesFromXml(const QDomElement &);
void resetStyles();
void applyStylesToQPainter(QPainter &) const;
};
/**
Change le style de trait
@param ls Le nouveau style de trait
*/
inline void CustomElementGraphicPart::setLineStyle(LineStyle ls) {
_linestyle = ls;
}
/**
Change l'epaisseur de trait
@param lw La nouvelle epaisseur de trait
*/
inline void CustomElementGraphicPart::setLineWeight(LineWeight lw) {
_lineweight = lw;
}
/**
Change la couleur de remplissage
@param f La nouvelle couleur de remplissage
*/
inline void CustomElementGraphicPart::setFilling(Filling f) {
_filling = f;
}
/**
Change la couleur de trait
@param c La nouvelle couleur de trait
*/
inline void CustomElementGraphicPart::setColor(Color c) {
_color = c;
}
/**
@return Le style de trait
*/
inline CustomElementGraphicPart::LineStyle CustomElementGraphicPart::lineStyle() const {
return(_linestyle);
}
/**
@return L'epaisseur de trait
*/
inline CustomElementGraphicPart::LineWeight CustomElementGraphicPart::lineWeight() const {
return(_lineweight);
}
/**
@return La couleur de remplissage
*/
inline CustomElementGraphicPart::Filling CustomElementGraphicPart::filling() const {
return(_filling);
}
/**
@return La couleur de trait
*/
inline CustomElementGraphicPart::Color CustomElementGraphicPart::color() const {
return(_color);
}
/**
Definit si la partie doit etre antialiasee ou non
@param aa True pour activer l'antialiasing, false pour le desactiver
*/
inline void CustomElementGraphicPart::setAntialiased(bool aa) {
_antialiased = aa;
}
/**
@return true si la partie est antialiasee, false sinon
*/
inline bool CustomElementGraphicPart::antialiased() const {
return(_antialiased);
}
#endif
+35
View File
@@ -0,0 +1,35 @@
/*
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 "customelementpart.h"
#include "customelement.h"
#include "qetelementeditor.h"
/// @return le QETElementEditor auquel cet editeur appartient
QETElementEditor *CustomElementPart::elementEditor() const {
return(element_editor);
}
/// @return l'ElementScene contenant les parties editees par cet editeur
ElementScene *CustomElementPart::elementScene() const {
return(element_editor -> elementScene());
}
/// @return la QUndoStack a utiliser pour les annulations
QUndoStack &CustomElementPart::undoStack() const {
return(elementScene() -> undoStack());
}
+87
View File
@@ -0,0 +1,87 @@
/*
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 CUSTOM_ELEMENT_PART_H
#define CUSTOM_ELEMENT_PART_H
#include <QtGui>
#include <QtXml>
#include <QImage>
class CustomElement;
class QETElementEditor;
class ElementScene;
/**
Cette classe abstraite represente une partie de la representation graphique
d'un element de schema electrique. Les attributs et methodes qu'elle
encapsule ne sont pas integres directement dans la classe CustomElement
afin de ne pas alourdir celle-ci. Il est en effet inutile pour cette classe
de retenir sa conception graphique autrement que sous la forme d'une
QImage.
*/
class CustomElementPart {
// constructeurs, destructeur
public:
/**
Constructeur
@param editor Editeur d'element auquel cette partie est rattachee
*/
CustomElementPart(QETElementEditor *editor) : element_editor(editor) {}
/// Destructeur
virtual ~CustomElementPart() {}
private:
CustomElementPart(const CustomElementPart &);
// attributs
private:
QETElementEditor *element_editor;
// methodes
public:
/**
Charge la partie depuis un element XML sense le decrire
*/
virtual void fromXml(const QDomElement &) = 0;
/**
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
*/
virtual void setProperty(const QString &, const QVariant &) = 0;
/**
Permet de lire une des proprietes de la partie
*/
virtual QVariant property(const QString &) = 0;
/**
@return true si la partie n'est pas pertinente, false sinon
Typiquement, une partie non pertinente n'est pas conservee lors de
l'enregistrement de l'element.
*/
virtual bool isUseless() const = 0;
/// @return un pointeur vers l'editeur d'element parent
virtual QETElementEditor *elementEditor() 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;
};
#endif
+504
View File
@@ -0,0 +1,504 @@
/*
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 "editorcommands.h"
/*** DeletePartsCommand ***/
/**
Constructeur
@param scene ElementScene concernee
@param parts Liste des parties supprimees
@param parent QUndoCommand parent
*/
DeletePartsCommand::DeletePartsCommand(
ElementScene *scene,
const QList<QGraphicsItem *> parts,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("suppression"), parent),
deleted_parts(parts),
editor_scene(scene)
{
foreach(QGraphicsItem *qgi, deleted_parts) {
editor_scene -> qgiManager().manage(qgi);
}
}
/// Destructeur : detruit egalement les parties supprimees
DeletePartsCommand::~DeletePartsCommand() {
foreach(QGraphicsItem *qgi, deleted_parts) {
editor_scene -> qgiManager().release(qgi);
}
}
/// Restaure les parties supprimees
void DeletePartsCommand::undo() {
foreach(QGraphicsItem *qgi, deleted_parts) {
editor_scene -> addItem(qgi);
}
}
/// Supprime les parties
void DeletePartsCommand::redo() {
foreach(QGraphicsItem *qgi, deleted_parts) {
editor_scene -> removeItem(qgi);
}
}
/*** MovePartsCommand ***/
/**
Constructeur
@param m Mouvement sous forme de QPointF
@param scene ElementScene concernee
@param parts Liste des parties deplacees
@param parent QUndoCommand parent
*/
MovePartsCommand::MovePartsCommand(
const QPointF &m,
ElementScene *scene,
const QList<QGraphicsItem *> parts,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("d\351placement"), parent),
movement(m),
first_redo(true)
{
moved_parts = parts;
editor_scene = scene;
}
/// Destructeur
MovePartsCommand::~MovePartsCommand() {
}
/// Annule le deplacement
void MovePartsCommand::undo() {
foreach(QGraphicsItem *qgi, moved_parts) qgi -> moveBy(-movement.x(), -movement.y());
}
/// Refait le deplacement
void MovePartsCommand::redo() {
// le premier appel a redo, lors de la construction de l'objet, ne doit pas se faire
if (first_redo) {
first_redo = false;
return;
}
foreach(QGraphicsItem *qgi, moved_parts) qgi -> moveBy(movement.x(), movement.y());
}
/*** AddPartCommand ***/
/**
Constructeur
@param name Nom de la partie ajoutee
@param scene ElementScene concernee
@param p partie ajoutee
@param parent QUndoCommand parent
*/
AddPartCommand::AddPartCommand(
const QString &name,
ElementScene *scene,
QGraphicsItem *p,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("ajout ") + name, parent),
part(p),
editor_scene(scene),
first_redo(true)
{
editor_scene -> qgiManager().manage(part);
}
/// Destructeur
AddPartCommand::~AddPartCommand() {
editor_scene -> qgiManager().release(part);
}
/// Annule l'ajout
void AddPartCommand::undo() {
editor_scene -> removeItem(part);
}
/// Refait l'ajout
void AddPartCommand::redo() {
// le premier appel a redo, lors de la construction de l'objet, ne doit pas se faire
if (first_redo) {
editor_scene -> clearSelection();
part -> setSelected(true);
first_redo = false;
return;
}
editor_scene -> addItem(part);
}
/**
Constructeur
@param name nom de la propriete modifiee
@param part partie modifiee
@param prop propriete modifiee
@param old_v ancienne valeur
@param new_v nouvelle valeur
@param parent qUndoCommand parent
*/
ChangePartCommand::ChangePartCommand(
const QString &name,
CustomElementPart *part,
const QString &prop,
const QVariant &old_v,
const QVariant &new_v,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modification ") + name, parent),
cep(part),
property(prop),
old_value(old_v),
new_value(new_v)
{
}
/// Destructeur
ChangePartCommand::~ChangePartCommand() {
}
/// Annule le changement
void ChangePartCommand::undo() {
cep -> setProperty(property, old_value);
}
/// Refait le changement
void ChangePartCommand::redo() {
cep -> setProperty(property, new_value);
}
/**
Constructeur
@param p Polygone edite
@param o_points points avant le changement
@param n_points points apres le changement
@param parent QUndoCommand parent
*/
ChangePolygonPointsCommand::ChangePolygonPointsCommand(
PartPolygon *p,
const QVector<QPointF> &o_points,
const QVector<QPointF> &n_points,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modification points polygone"), parent),
polygon(p),
old_points(o_points),
new_points(n_points)
{
}
/// Destructeur
ChangePolygonPointsCommand::~ChangePolygonPointsCommand() {
}
/// Annule le changement
void ChangePolygonPointsCommand::undo() {
polygon -> setPolygon(old_points);
}
/// Refait le changement
void ChangePolygonPointsCommand::redo() {
polygon -> setPolygon(new_points);
}
/**
Constructeur
@param element_scene Element edite
@param size_1 Dimensions de l'element avant le changement
@param size_2 Dimensions de l'element apres le changement
@param hotspot_1 Point de saisie de l'element avant le changement
@param hotspot_2 Point de saisie de l'element apres le changement
@param o Eventuel decalage a appliquer aux parties de l'element edite
@param parent QUndoCommand parent
*/
ChangeHotspotCommand::ChangeHotspotCommand(
ElementScene *element_scene,
const QSize &size_1,
const QSize &size_2,
const QPoint &hotspot_1,
const QPoint &hotspot_2,
const QPoint &o,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modification dimensions/hotspot"), parent),
element(element_scene),
size_before(size_1),
size_after(size_2),
hotspot_before(hotspot_1),
hotspot_after(hotspot_2),
offset(o)
{
}
/// Destructeur
ChangeHotspotCommand::~ChangeHotspotCommand() {
}
/// Annule le changement
void ChangeHotspotCommand::undo() {
QRectF sc(element -> sceneContent());
element -> setWidth(size_before.width());
element -> setHeight(size_before.height());
element -> setHotspot(hotspot_before);
if (!offset.isNull()) applyOffset(-offset);
element -> update(element -> sceneContent().unite(sc));
}
/// Refait le changement
void ChangeHotspotCommand::redo() {
QRectF sc(element -> sceneContent());
element -> setWidth(size_after.width());
element -> setHeight(size_after.height());
element -> setHotspot(hotspot_after);
if (!offset.isNull()) applyOffset(offset);
element -> update(element -> sceneContent().unite(sc));
}
/**
Applique une translation aux parties de l'element edite
@param o Translation a appliquer
*/
void ChangeHotspotCommand::applyOffset(const QPointF &o) {
foreach(QGraphicsItem *qgi, element -> items()) {
qgi -> translate(o.x(), o.y());
}
}
/**
Constructeur
@param element_scene Element edite
@param before Listes des noms avant changement
@param after Listes des noms apres changement
@param parent QUndoCommand parent
*/
ChangeNamesCommand::ChangeNamesCommand(
ElementScene *element_scene,
const NamesList &before,
const NamesList &after,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modification noms"), parent),
names_before(before),
names_after(after),
element(element_scene)
{
}
/// Destructeur
ChangeNamesCommand::~ChangeNamesCommand() {
}
/// Annule le changement
void ChangeNamesCommand::undo() {
element -> setNames(names_before);
}
/// Refait le changement
void ChangeNamesCommand::redo() {
element -> setNames(names_after);
}
/**
Constructeur
@param element_scene Element edite
@param before Orientations avant changement
@param after Orientations apres changement
@param parent QUndoCommand parent
*/
ChangeOrientationsCommand::ChangeOrientationsCommand(
ElementScene *element_scene,
const OrientationSet &before,
const OrientationSet &after,
QUndoCommand *parent
) :
QUndoCommand(QObject::tr("modification orientations"), parent),
ori_before(before),
ori_after(after),
element(element_scene)
{
}
/// Destructeur
ChangeOrientationsCommand::~ChangeOrientationsCommand() {
}
/// Annule le changement
void ChangeOrientationsCommand::undo() {
element -> setOrientations(ori_before);
}
/// Refait le changement
void ChangeOrientationsCommand::redo() {
element -> setOrientations(ori_after);
}
/**
Constructeur
@param elmt ElementScene concernee
@param o Option decrivant le type de traitement applique aux zValues des parties de l'element
@param parent QUndoCommand parent
*/
ChangeZValueCommand::ChangeZValueCommand(
ElementScene *elmt,
ChangeZValueCommand::Option o,
QUndoCommand *parent
) :
QUndoCommand(parent),
element(elmt),
option(o)
{
// recupere les parties de l'elements, sauf les bornes
QList<QGraphicsItem *> items_list = element -> zItems();
// prend un snapshot des zValues
foreach(QGraphicsItem *qgi, items_list) undo_hash.insert(qgi, qgi -> zValue());
// choisit le nom en fonction du traitement
if (option == BringForward) {
setText(QObject::tr("amener au premier plan"));
applyBringForward(items_list);
} else if (option == Raise) {
setText(QObject::tr("rapprocher"));
applyRaise(items_list);
} else if (option == Lower) {
setText(QObject::tr("\351loigner"));
applyLower(items_list);
} else if (option == SendBackward) {
setText(QObject::tr("envoyer au fond"));
applySendBackward(items_list);
}
}
/// Destructeur
ChangeZValueCommand::~ChangeZValueCommand() {
}
/// Annule les changements de zValue
void ChangeZValueCommand::undo() {
foreach(QGraphicsItem *qgi, undo_hash.keys()) qgi -> setZValue(undo_hash[qgi]);
}
/// Refait les changements de zValue
void ChangeZValueCommand::redo() {
foreach(QGraphicsItem *qgi, redo_hash.keys()) qgi -> setZValue(redo_hash[qgi]);
}
/**
Amene les elements selectionnes au premier plan
@param items_list Liste des elements (selectionnes et non selectionnes)
*/
void ChangeZValueCommand::applyBringForward(const QList<QGraphicsItem *> &items_list) {
QList<QGraphicsItem *> non_selected_items = items_list;
QList<QGraphicsItem *> selected_items;
foreach(QGraphicsItem *qgi, non_selected_items) {
if (qgi -> isSelected()) {
selected_items << qgi;
non_selected_items.removeAt(non_selected_items.indexOf(qgi));
}
}
int z = 1;
foreach(QGraphicsItem *qgi, non_selected_items) redo_hash.insert(qgi, z ++);
foreach(QGraphicsItem *qgi, selected_items) redo_hash.insert(qgi, z ++);
}
/**
Remonte les elements selectionnes d'un plan
@param items_list Liste des elements (selectionnes et non selectionnes)
*/
void ChangeZValueCommand::applyRaise(const QList<QGraphicsItem *> &items_list) {
QList<QGraphicsItem *> my_items_list = items_list;
for (int i = my_items_list.count() - 2 ; i >= 0 ; -- i) {
if (my_items_list[i] -> isSelected()) {
if (!my_items_list[i +1] -> isSelected()) {
my_items_list.swap(i, i + 1);
}
}
}
int z = 1;
foreach(QGraphicsItem *qgi, my_items_list) redo_hash.insert(qgi, z ++);
}
/**
Descend les elements selectionnes d'un plan
@param items_list Liste des elements (selectionnes et non selectionnes)
*/
void ChangeZValueCommand::applyLower(const QList<QGraphicsItem *> &items_list) {
QList<QGraphicsItem *> my_items_list = items_list;
for (int i = 1 ; i < my_items_list.count() ; ++ i) {
if (my_items_list[i] -> isSelected()) {
if (!my_items_list[i - 1] -> isSelected()) {
my_items_list.swap(i, i - 1);
}
}
}
int z = 1;
foreach(QGraphicsItem *qgi, my_items_list) redo_hash.insert(qgi, z ++);
}
/**
Envoie les elements selectionnes au fond
@param items_list Liste des elements (selectionnes et non selectionnes)
*/
void ChangeZValueCommand::applySendBackward(const QList<QGraphicsItem *> &items_list) {
QList<QGraphicsItem *> non_selected_items = items_list;
QList<QGraphicsItem *> selected_items;
foreach(QGraphicsItem *qgi, non_selected_items) {
if (qgi -> isSelected()) {
selected_items << qgi;
non_selected_items.removeAt(non_selected_items.indexOf(qgi));
}
}
int z = 1;
foreach(QGraphicsItem *qgi, selected_items) redo_hash.insert(qgi, z ++);
foreach(QGraphicsItem *qgi, non_selected_items) redo_hash.insert(qgi, z ++);
}
/**
Constructeur
@param elmt ElementScene concernee
@param allow true pour que les connexions internes soient acceptees, false sinon
@param parent QUndoCommand parent
*/
AllowInternalConnectionsCommand::AllowInternalConnectionsCommand(ElementScene *elmt, bool allow, QUndoCommand *parent) :
QUndoCommand(QObject::tr("modification connexions internes"), parent),
element(elmt),
ic(allow)
{
}
/// Destructeur
AllowInternalConnectionsCommand::~AllowInternalConnectionsCommand() {
}
/// Annule le changement d'autorisation pour les connexions internes
void AllowInternalConnectionsCommand::undo() {
element -> setInternalConnections(!ic);
}
/// Refait le changement d'autorisation pour les connexions internes
void AllowInternalConnectionsCommand::redo() {
element -> setInternalConnections(ic);
}
+311
View File
@@ -0,0 +1,311 @@
/*
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 EDITOR_COMMANDS_H
#define EDITOR_COMMANDS_H
#include "customelementpart.h"
#include "partpolygon.h"
#include "elementscene.h"
#include "qgimanager.h"
#include <QtGui>
/**
Cette classe represente l'action de supprimer une ou plusieurs
parties lors de l'edition d'un element
*/
class DeletePartsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
DeletePartsCommand(ElementScene *, const QList<QGraphicsItem *>, QUndoCommand * = 0);
virtual ~DeletePartsCommand();
private:
DeletePartsCommand(const DeletePartsCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// Liste des parties supprimees
QList<QGraphicsItem *> deleted_parts;
/// scene sur laquelle se produisent les actions
ElementScene *editor_scene;
};
/**
Cette classe represente l'action de deplacer une ou plusieurs
parties lors de l'edition d'un element
*/
class MovePartsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
MovePartsCommand(const QPointF &, ElementScene *, const QList<QGraphicsItem *>, QUndoCommand * = 0);
virtual ~MovePartsCommand();
private:
MovePartsCommand(const MovePartsCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// Liste des parties supprimees
QList<QGraphicsItem *> moved_parts;
/// scene sur laquelle se produisent les actions
ElementScene *editor_scene;
/// translation appliquee
QPointF movement;
/// booleen pour eviter d'appeler redo() lors de la construction de l'objet
bool first_redo;
};
/**
Cette classe represente l'action d'ajouter une partie lors de l'edition
d'un element
*/
class AddPartCommand : public QUndoCommand {
// constructeurs, destructeur
public:
AddPartCommand(const QString &, ElementScene *, QGraphicsItem *, QUndoCommand * = 0);
virtual ~AddPartCommand();
private:
AddPartCommand(const AddPartCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// Liste des parties supprimees
QGraphicsItem *part;
/// scene sur laquelle se produisent les actions
ElementScene *editor_scene;
/// booleen pour eviter d'appeler redo() lors de la construction de l'objet
bool first_redo;
};
/**
Cette classe represente l'action de modifier une propriete d'une partie
lors de l'edition d'un element
*/
class ChangePartCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangePartCommand(const QString &, CustomElementPart *, const QString &, const QVariant &, const QVariant &, QUndoCommand * = 0);
virtual ~ChangePartCommand();
private:
ChangePartCommand(const ChangePartCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// Partie modifiee
CustomElementPart *cep;
/// Propriete modifiee
QString property;
/// ancienne valeur
QVariant old_value;
/// nouvelle valeur
QVariant new_value;
};
/**
Cette classe represente l'action de modifier les points composants un polygone
*/
class ChangePolygonPointsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangePolygonPointsCommand(PartPolygon *, const QVector<QPointF> &, const QVector<QPointF> &, QUndoCommand * = 0);
virtual ~ChangePolygonPointsCommand();
private:
ChangePolygonPointsCommand(const ChangePolygonPointsCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
/// Polygone modifie
PartPolygon *polygon;
/// anciens points
QVector<QPointF> old_points;
/// nouveaux points
QVector<QPointF> new_points;
};
/**
Cette classe represente l'action de modifier les dimensions et le point de saisie d'un element
*/
class ChangeHotspotCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangeHotspotCommand(ElementScene *, const QSize &, const QSize &, const QPoint &, const QPoint &, const QPoint & = QPoint(), QUndoCommand * = 0);
virtual ~ChangeHotspotCommand();
private:
ChangeHotspotCommand(const ChangeHotspotCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
private:
void applyOffset(const QPointF &);
// attributs
/// Element edite auquel il faut appliquer les modifications
ElementScene *element;
/// dimensions avant l'action
QSize size_before;
/// dimensions apres l'action
QSize size_after;
/// point de saisie avant l'action
QPoint hotspot_before;
/// point de saisie apres l'action
QPoint hotspot_after;
/// decalage a appliquer aux elements
QPoint offset;
};
/**
Cette classe represente l'action de changer les noms d'un element
*/
class ChangeNamesCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangeNamesCommand(ElementScene *, const NamesList &, const NamesList &, QUndoCommand * = 0);
virtual ~ChangeNamesCommand();
private:
ChangeNamesCommand(const ChangeNamesCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// Liste des noms avant changement
NamesList names_before;
/// Liste des noms apres changement
NamesList names_after;
/// Element edite auquel il faut appliquer les modifications
ElementScene *element;
};
/**
Cette classe represente l'action de changer les noms d'un element
*/
class ChangeOrientationsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
ChangeOrientationsCommand(ElementScene *, const OrientationSet &, const OrientationSet &, QUndoCommand * = 0);
virtual ~ChangeOrientationsCommand();
private:
ChangeOrientationsCommand(const ChangeOrientationsCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// Orientations avant changement
OrientationSet ori_before;
/// Orientations apres changement
OrientationSet ori_after;
/// Element edite auquel il faut appliquer les modifications
ElementScene *element;
};
/**
Cette classe represente l'action de changer les noms d'un element
*/
class ChangeZValueCommand : public QUndoCommand {
// constructeurs, destructeur
public:
/// Qualifie le type de changement de zValue
enum Option {
BringForward, ///< Amene la partie a l'avant-plan ; elle a alors la plus haute zValue
Raise, ///< Amene la partie un plan au-dessus ; la zValue de la partie est incrementee
Lower, ///< Envoie la partie un plan en-dessous ; la zValue de la partie est decrementee
SendBackward ///< Envoie la partie a l'arriere-plan ; elle a alors la plus faible zValue
};
ChangeZValueCommand(ElementScene *, Option, QUndoCommand * = 0);
virtual ~ChangeZValueCommand();
private:
ChangeZValueCommand(const ChangeZValueCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
private:
void applyBringForward(const QList<QGraphicsItem *> &);
void applyRaise(const QList<QGraphicsItem *> &);
void applyLower(const QList<QGraphicsItem *> &);
void applySendBackward(const QList<QGraphicsItem *> &);
// attributs
private:
/// zValues avant changement
QHash<QGraphicsItem *, qreal> undo_hash;
/// zValues apres changement
QHash<QGraphicsItem *, qreal> redo_hash;
/// Element edite auquel il faut appliquer les modifications
ElementScene *element;
/// type de traitement
Option option;
};
/**
Cette classe represente l'action d'autoriser ou non les connexions
internes pour un element.
*/
class AllowInternalConnectionsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
AllowInternalConnectionsCommand(ElementScene *, bool, QUndoCommand * = 0);
virtual ~AllowInternalConnectionsCommand();
private:
AllowInternalConnectionsCommand(const AllowInternalConnectionsCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// Element edite auquel il faut appliquer les modifications
ElementScene *element;
/// autorisation des connexions internes apres modification
bool ic;
};
#endif
+78
View File
@@ -0,0 +1,78 @@
/*
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 "elementitemeditor.h"
#include "qetelementeditor.h"
#include "editorcommands.h"
/**
Constructeur
@param editor QETElementEditor auquel cet editeur appartient
@param parent QWidget parent de cet editeur
*/
ElementItemEditor::ElementItemEditor(QETElementEditor *editor, QWidget *parent) :
QWidget(parent),
element_editor(editor)
{
}
/// @return le QETElementEditor auquel cet editeur appartient
QETElementEditor *ElementItemEditor::elementEditor() const {
return(element_editor);
}
/// @return l'ElementScene contenant les parties editees par cet editeur
ElementScene *ElementItemEditor::elementScene() const {
return(element_editor -> elementScene());
}
/// @return la QUndoStack a utiliser pour les annulations
QUndoStack &ElementItemEditor::undoStack() const {
return(elementScene() -> undoStack());
}
/**
Ajoute une ChangePartCommand a l'UndoStack. L'ancienne valeur sera
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) {
QVariant old_v = part -> property(prop);
if (old_v == new_v) return;
undoStack().push(
new ChangePartCommand(
desc + " " + element_type_name,
part,
prop,
old_v,
new_v
)
);
}
/// @return Le nom du type d'element edite
QString ElementItemEditor::elementTypeName() const {
return(element_type_name);
}
/// @param name Nom du type d'element edite
void ElementItemEditor::setElementTypeName(const QString &name) {
element_type_name = name;
}
+53
View File
@@ -0,0 +1,53 @@
/*
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 ELEMENT_ITEM_EDITOR_H
#define ELEMENT_ITEM_EDITOR_H
#include <QtGui>
class QETElementEditor;
class ElementScene;
class CustomElementPart;
/**
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.
*/
class ElementItemEditor : public QWidget {
Q_OBJECT
// constructeurs, destructeur
public:
ElementItemEditor(QETElementEditor *, QWidget * = 0);
virtual ~ElementItemEditor() {};
private:
ElementItemEditor(const ElementItemEditor &);
// methodes
public:
virtual QETElementEditor *elementEditor() const;
virtual ElementScene *elementScene() const;
virtual QUndoStack &undoStack() const;
virtual void addChangePartCommand(const QString &, CustomElementPart *, const QString &, const QVariant &);
virtual QString elementTypeName() const;
virtual void setElementTypeName(const QString &);
// attributs
private:
QETElementEditor *element_editor;
QString element_type_name;
};
#endif
+732
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);
}
}
+238
View File
@@ -0,0 +1,238 @@
/*
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 ELEMENT_SCENE_H
#define ELEMENT_SCENE_H
#include <QtGui>
#include <QtXml>
#include "nameslistwidget.h"
#include "orientationsetwidget.h"
#include "qgimanager.h"
class QETElementEditor;
class PartLine;
class PartEllipse;
class PartCircle;
class PartPolygon;
class PartArc;
/**
Cette classe est le canevas permettant l'edition d'un element electrique.
Elle regroupe les differentes parties composant le dessin de l'element mais
egalement les informations complementaires : dimensions, orientations,
noms.
*/
class ElementScene : public QGraphicsScene {
Q_OBJECT
// enum
enum Behavior { Normal, Line, Circle, Ellipse, Polygon, Text, Terminal, Arc, TextField };
// constructeurs, destructeur
public:
ElementScene(QETElementEditor *, QObject * = 0);
virtual ~ElementScene();
private:
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;
/// hauteur de l'element en dizaines de pixels
uint _height;
/// position du point de saisie
QPoint _hotspot;
/// Liste des noms de l'element
NamesList _names;
/// Liste des orientations de l'element
OrientationSet ori;
/// booleen indiquant si les bornes de l'element peuvent etre reliees a des bornes de ce meme element
bool internal_connections;
/// Gestionnaire de QGraphicsItem
QGIManager qgi_manager;
/// Pile des actions annulables
QUndoStack undo_stack;
/// Position du premier item selectionne (utilise pour annuler les deplacements)
QPointF fsi_pos;
/// Variables relatives a la gestion du dessin des parties sur la scene
Behavior behavior;
PartLine *current_line;
PartEllipse *current_ellipse;
PartCircle *current_circle;
PartPolygon *current_polygon;
PartArc *current_arc;
QETElementEditor *element_editor;
// methodes
public:
void setWidth(const uint &);
uint width() const;
void setHeight(const uint &);
uint height() const;
void setHotspot(const QPoint &);
QPoint hotspot() const;
void setNames(const NamesList &);
NamesList names() const;
OrientationSet orientations();
void setOrientations(const OrientationSet &);
bool internalConnections();
void setInternalConnections(bool);
virtual const QDomDocument toXml() const;
virtual void fromXml(const QDomDocument &);
virtual void reset();
virtual QList<QGraphicsItem *> zItems(bool = false) const;
QRectF sceneContent() const;
QUndoStack &undoStack();
QGIManager &qgiManager();
protected:
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
virtual void drawBackground(QPainter *, const QRectF &);
virtual void drawForeground(QPainter *, const QRectF &);
public slots:
void slot_move();
void slot_addLine();
void slot_addCircle();
void slot_addEllipse();
void slot_addPolygon();
void slot_addText();
void slot_addArc();
void slot_addTerminal();
void slot_addTextField();
void slot_selectAll();
void slot_deselectAll();
void slot_invertSelection();
void slot_delete();
void slot_editSizeHotSpot();
void slot_editNames();
void slot_editOrientations();
void slot_bringForward();
void slot_raise();
void slot_lower();
void slot_sendBackward();
signals:
/**
Signal emis lorsque la scene exige que l'editeur d'element repasse
en mode normal
*/
void needNormalMode();
/// Signal emis lorsqu'une ou plusieurs parties sont ajoutees
void partsAdded();
/// Signal emis lorsqu'une ou plusieurs parties sont enlevees
void partsRemoved();
/// Signal emis lorsque la zValue d'une ou plusieurs parties change
void partsZValueChanged();
};
/**
@param wid Nouvelle largeur de l'element edite
*/
inline void ElementScene::setWidth(const uint &wid) {
_width = wid;
while (_width % 10) ++ _width;
_width /= 10;
}
/**
@return la largeur de l'element edite
*/
inline uint ElementScene::width() const {
return(_width * 10);
}
/**
@param hei Nouvelle hauteur de l'element edite
*/
inline void ElementScene::setHeight(const uint &hei) {
_height = hei;
while (_height % 10) ++ _height;
_height /= 10;
}
/**
@return la largeur de l'element edite
*/
inline uint ElementScene::height() const {
return(_height * 10);
}
/**
@param hs Nouveau point de saisie de l'element edite
*/
inline void ElementScene::setHotspot(const QPoint &hs) {
_hotspot = hs;
}
/**
@return le point de saisie de l'element edite
*/
inline QPoint ElementScene::hotspot() const {
return(_hotspot);
}
/**
@param nameslist Nouvel ensemble de noms de l'element edite
*/
inline void ElementScene::setNames(const NamesList &nameslist) {
_names = nameslist;
}
/**
@return l'ensemble de noms de l'element edite
*/
inline NamesList ElementScene::names() const {
return(_names);
}
/**
@return l'ensemble d'orientations de l'element edite
*/
inline OrientationSet ElementScene::orientations() {
return(ori);
}
/**
@param orientation_set Nouvel ensemble d'orientations de l'element edite
*/
inline void ElementScene::setOrientations(const OrientationSet &orientation_set) {
ori = orientation_set;
}
/**
@return true si les connexions internes sont acceptees, false sinon
*/
inline bool ElementScene::internalConnections() {
return(internal_connections);
}
/**
@param ic true pour que les connexions internes soient acceptees, false sinon
*/
inline void ElementScene::setInternalConnections(bool ic) {
internal_connections = ic;
}
#endif
+128
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);
}
}
+56
View File
@@ -0,0 +1,56 @@
/*
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 ELEMENT_VIEW_H
#define ELEMENT_VIEW_H
#include <QGraphicsView>
#include "elementscene.h"
/**
Cette classe represente un widget permettant de visualiser une
ElementScene, c'est-a-dire la classe d'edition des elements.
*/
class ElementView : public QGraphicsView {
Q_OBJECT
// constructeurs, destructeur
public:
ElementView(ElementScene *, QWidget * = 0);
virtual ~ElementView();
private:
ElementView(const ElementView &);
// methodes
public:
ElementScene *scene() const;
void setScene(ElementScene *);
protected:
bool event(QEvent *);
void wheelEvent(QWheelEvent *);
// slots
public slots:
void zoomIn();
void zoomOut();
void zoomFit();
void zoomReset();
void adjustSceneRect();
//attributs
private:
ElementScene *scene_;
};
#endif
+108
View File
@@ -0,0 +1,108 @@
/*
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 "ellipseeditor.h"
#include "partellipse.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param ellipse L'ellipse a editer
@param parent le Widget parent
*/
EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *ellipse, QWidget *parent) : ElementItemEditor(editor, parent) {
part = ellipse;
x = new QLineEdit();
y = new QLineEdit();
h = new QLineEdit();
v = new QLineEdit();
x -> setValidator(new QDoubleValidator(x));
y -> setValidator(new QDoubleValidator(y));
h -> setValidator(new QDoubleValidator(h));
v -> setValidator(new QDoubleValidator(v));
QGridLayout *grid = new QGridLayout(this);
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
grid -> addWidget(new QLabel("x"), 1, 0);
grid -> addWidget(x, 1, 1);
grid -> addWidget(new QLabel("y"), 1, 2);
grid -> addWidget(y, 1, 3);
grid -> addWidget(new QLabel(tr("Diam\350tres : ")), 2, 0);
grid -> addWidget(new QLabel(tr("horizontal :")), 3, 0);
grid -> addWidget(h, 3, 1);
grid -> addWidget(new QLabel(tr("vertical :")), 4, 0);
grid -> addWidget(v, 4, 1);
activeConnections(true);
updateForm();
}
/// Destructeur
EllipseEditor::~EllipseEditor() {
}
/**
Met a jour l'ellipse a partir des donnees du formulaire
*/
void EllipseEditor::updateEllipse() {
part -> setProperty("x", x -> text().toDouble());
part -> setProperty("y", x -> text().toDouble());
part -> setProperty("diameter_h", x -> text().toDouble());
part -> setProperty("diameter_v", x -> text().toDouble());
}
/// Met a jour l'abscisse du centre de l'ellipse et cree un objet d'annulation
void EllipseEditor::updateEllipseX() { addChangePartCommand(tr("abscisse"), part, "x", x -> text().toDouble()); }
/// Met a jour l'ordonnee du centre de l'ellipse et cree un objet d'annulation
void EllipseEditor::updateEllipseY() { addChangePartCommand(tr("ordonn\351e"), part, "y", y -> text().toDouble()); }
/// Met a jour le diametre horizontal de l'ellipse et cree un objet d'annulation
void EllipseEditor::updateEllipseH() { addChangePartCommand(tr("diam\350tre horizontal"), part, "diameter_h", h -> text().toDouble()); }
/// Met a jour le diametre vertical de l'ellipse et cree un objet d'annulation
void EllipseEditor::updateEllipseV() { addChangePartCommand(tr("diam\350tre vertical"), part, "diameter_v", v -> text().toDouble()); }
/**
Met a jour le formulaire d'edition
*/
void EllipseEditor::updateForm() {
activeConnections(false);
x -> setText(part -> property("x").toString());
y -> setText(part -> property("y").toString());
h -> setText(part -> property("diameter_h").toString());
v -> setText(part -> property("diameter_v").toString());
activeConnections(true);
}
/**
Active ou desactive les connexionx signaux/slots entre les widgets internes.
@param active true pour activer les connexions, false pour les desactiver
*/
void EllipseEditor::activeConnections(bool active) {
if (active) {
connect(x, SIGNAL(editingFinished()), this, SLOT(updateEllipseX()));
connect(y, SIGNAL(editingFinished()), this, SLOT(updateEllipseY()));
connect(h, SIGNAL(editingFinished()), this, SLOT(updateEllipseH()));
connect(v, SIGNAL(editingFinished()), this, SLOT(updateEllipseV()));
} else {
disconnect(x, SIGNAL(editingFinished()), this, SLOT(updateEllipseX()));
disconnect(y, SIGNAL(editingFinished()), this, SLOT(updateEllipseY()));
disconnect(h, SIGNAL(editingFinished()), this, SLOT(updateEllipseH()));
disconnect(v, SIGNAL(editingFinished()), this, SLOT(updateEllipseV()));
}
}
+53
View File
@@ -0,0 +1,53 @@
/*
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 ELLIPSE_EDITOR_H
#define ELLIPSE_EDITOR_H
#include <QtGui>
#include "elementitemeditor.h"
class PartEllipse;
/**
Cette classe represente le widget d'edition d'une ellipse dans l'editeur
d'element.
*/
class EllipseEditor : public ElementItemEditor {
Q_OBJECT
//constructeurs, destructeur
public:
EllipseEditor(QETElementEditor *, PartEllipse *, QWidget * = 0);
~EllipseEditor();
private:
EllipseEditor(const EllipseEditor &);
// attributs
private:
PartEllipse *part;
QLineEdit *x, *y, *h, *v;
// methodes
public slots:
void updateEllipse();
void updateEllipseX();
void updateEllipseY();
void updateEllipseH();
void updateEllipseV();
void updateForm();
private:
void activeConnections(bool);
};
#endif
+115
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()));
}
}
+53
View File
@@ -0,0 +1,53 @@
/*
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 LINE_EDITOR_H
#define LINE_EDITOR_H
#include <QtGui>
#include "elementitemeditor.h"
class PartLine;
/**
Cette classe represente le widget d'edition d'une ligne dans l'editeur
d'element.
*/
class LineEditor : public ElementItemEditor {
Q_OBJECT
//constructeurs, destructeur
public:
LineEditor(QETElementEditor *, PartLine *, QWidget * = 0);
~LineEditor();
private:
LineEditor(const LineEditor &);
// attributs
private:
PartLine *part;
QLineEdit *x1, *y1, *x2, *y2;
// methodes
public slots:
void updateLine();
void updateLineX1();
void updateLineY1();
void updateLineX2();
void updateLineY2();
void updateForm();
private:
void activeConnections(bool);
};
#endif
+263
View File
@@ -0,0 +1,263 @@
/*
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 "partarc.h"
#include "arceditor.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de cet arc
@param scene La scene sur laquelle figure cet arc
*/
PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
QGraphicsEllipseItem(parent, scene),
CustomElementGraphicPart(editor),
_angle(-90),
start_angle(0)
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptedMouseButtons(Qt::LeftButton);
informations = new ArcEditor(elementEditor(), this);
informations -> setElementTypeName(name());
style_editor -> appendWidget(informations);
style_editor -> setElementTypeName(name());
}
/// Destructeur
PartArc::~PartArc() {
}
/**
Dessine l'arc de cercle
@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 PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
// enleve systematiquement la couleur de fond
painter -> setBrush(Qt::NoBrush);
QPen t = painter -> pen();
if (isSelected()) {
// dessine l'ellipse en noir
painter -> drawEllipse(rect());
// dessine l'arc en rouge
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
painter -> setRenderHint(QPainter::Antialiasing, false);
painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
QPointF center = rect().center();
painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
}
}
/**
Exporte l'arc de cercle en XML
@param xml_document Document XML a utiliser pour creer l'element XML
@return un element XML decrivant l'arc de cercle
*/
const QDomElement PartArc::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("arc");
QPointF top_left(sceneTopLeft());
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);
}
/**
Importe les proprietes d'un arc de cercle depuis un element XML
@param qde Element XML a lire
*/
void PartArc::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
setRect(
QRectF(
mapFromScene(
qde.attribute("x", "0").toDouble(),
qde.attribute("y", "0").toDouble()
),
QSizeF(
qde.attribute("width", "0").toDouble(),
qde.attribute("height", "0").toDouble()
)
)
);
setStartAngle(qde.attribute("start", "0").toInt());
setAngle(qde.attribute("angle", "-90").toInt());
}
/**
@return le coin superieur gauche du rectangle dans lequel s'inscrit
l'ellipse dont fait partie cet arc, dans les coordonnees de la scene.
*/
QPointF PartArc::sceneTopLeft() const {
return(mapToScene(rect().topLeft()));
}
/**
Specifie la valeur d'une propriete donnee de l'arc
@param property propriete a modifier. Valeurs acceptees :
* x : abscisse du centre de l'ellipse dont fait partie l'arc
* y : ordonnee du centre de l'ellipse dont fait partie l'arc
* diameter_h : diametre horizontal de l'ellipse dont fait partie l'arc
* diameter_v : diametre vertical de l'ellipse dont fait partie l'arc
* start_angle : angle de depart
* angle : taille de l'arc de cercle
@param value Valeur a attribuer a la propriete
*/
void PartArc::setProperty(const QString &property, const QVariant &value) {
CustomElementGraphicPart::setProperty(property, value);
if (!value.canConvert(QVariant::Double)) return;
if (property == "x") {
QRectF current_rect = rect();
QPointF current_pos = mapToScene(current_rect.center());
setRect(current_rect.translated(value.toDouble() - current_pos.x(), 0.0));
} else if (property == "y") {
QRectF current_rect = rect();
QPointF current_pos = mapToScene(current_rect.center());
setRect(current_rect.translated(0.0, value.toDouble() - current_pos.y()));
} else if (property == "diameter_h") {
qreal new_width = qAbs(value.toDouble());
QRectF current_rect = rect();
current_rect.translate((new_width - current_rect.width()) / -2.0, 0.0);
current_rect.setWidth(new_width);
setRect(current_rect);
} else if (property == "diameter_v") {
qreal new_height = qAbs(value.toDouble());
QRectF current_rect = rect();
current_rect.translate(0.0, (new_height - current_rect.height()) / -2.0);
current_rect.setHeight(new_height);
setRect(current_rect);
} else if (property == "start_angle") {
setStartAngle(value.toInt() );
} else if (property == "angle") {
setAngle(value.toInt());
}
}
/**
Permet d'acceder a la valeur d'une propriete donnee de l'arc de cercle
@param property propriete lue. Valeurs acceptees :
* x : abscisse du centre de l'ellipse dont fait partie l'arc
* y : ordonnee du centre de l'ellipse dont fait partie l'arc
* diameter_h : diametre horizontal de l'ellipse dont fait partie l'arc
* diameter_v : diametre vertical de l'ellipse dont fait partie l'arc
* start_angle : angle de depart
* angle : taille de l'arc de cercle
@return La valeur de la propriete property
*/
QVariant PartArc::property(const QString &property) {
// appelle la methode property de CustomElementGraphicpart pour les styles
QVariant style_property = CustomElementGraphicPart::property(property);
if (style_property != QVariant()) return(style_property);
if (property == "x") {
return(mapToScene(rect().center()).x());
} else if (property == "y") {
return(mapToScene(rect().center()).y());
} else if (property == "diameter_h") {
return(rect().width());
} else if (property == "diameter_v") {
return(rect().height());
} else if (property == "start_angle") {
return(start_angle);
} else if (property == "angle") {
return(_angle);
}
return(QVariant());
}
/**
Gere les changements intervenant sur cette partie
@param change Type de changement
@param value Valeur numerique relative au changement
*/
QVariant PartArc::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsEllipseItem::itemChange(change, value));
}
/**
Permet de modifier l'etendue de l'arc de cercle.
Il s'agit d'un angle, exprime en degres.
Si l'angle est positif, l'arc s'etendra dans le sens des aiguilles d'une
montre.
@param a la nouvelle taille de l'arc de cercle
*/
void PartArc::setAngle(int a) {
_angle = a;
}
/**
Permet de modifier la position de depart de l'arc de cercle.
Il s'agit d'un angle, exprime en degres.
l'angle "0 degre" est situe a "3 heures".
@param a la nouvelle taille de l'arc de cercle
*/
void PartArc::setStartAngle(int a) {
start_angle = a;
}
/**
@return l'etendue de l'arc de cercle
*/
int PartArc::angle() const {
return(_angle);
}
/**
@return la position de depart de l'arc de cercle
*/
int PartArc::startAngle() const {
return(start_angle);
}
/**
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
conservee / enregistree.
Un arc est pertinent des lors que ses dimensions et son etendue ne sont
pas nulles.
*/
bool PartArc::isUseless() const {
return(rect().isNull() || !angle());
}
/**
@return le rectangle delimitant cette partie.
*/
QRectF PartArc::boundingRect() const {
qreal adjust = 1.5;
QRectF r(QGraphicsEllipseItem::boundingRect().normalized());
r.adjust(-adjust, -adjust, adjust, adjust);
return(r);
}
+67
View File
@@ -0,0 +1,67 @@
/*
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 PART_ARC_H
#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.
*/
class PartArc : public QGraphicsEllipseItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartArc(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartArc();
private:
PartArc(const PartArc &);
// attributs
private:
ArcEditor *informations;
int _angle;
int start_angle;
// methodes
public:
enum { Type = UserType + 1101 };
/**
permet de caster un QGraphicsItem en PartArc 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("arc")); }
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneTopLeft() const;
virtual QRectF boundingRect() const;
virtual void setAngle(int);
virtual void setStartAngle(int);
virtual int angle() const;
virtual int startAngle() const;
virtual void setProperty(const QString &, const QVariant &);
virtual QVariant property(const QString &);
virtual bool isUseless() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
};
#endif
+199
View File
@@ -0,0 +1,199 @@
/*
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 "partcircle.h"
#include "circleeditor.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de ce cercle
@param scene La scene sur laquelle figure ce cercle
*/
PartCircle::PartCircle(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsEllipseItem(parent, scene), CustomElementGraphicPart(editor) {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptedMouseButtons(Qt::LeftButton);
informations = new CircleEditor(elementEditor(), this);
informations -> setElementTypeName(name());
style_editor -> appendWidget(informations);
style_editor -> setElementTypeName(name());
}
/// Destructeur
PartCircle::~PartCircle() {
}
/**
Dessine le cercle
@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 PartCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
if (isSelected()) {
t.setColor(Qt::red);
painter -> setPen(t);
}
painter -> drawEllipse(rect());
if (isSelected()) {
painter -> setRenderHint(QPainter::Antialiasing, false);
painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
QPointF center = rect().center();
painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
}
}
/**
Exporte le cercle en XML
@param xml_document Document XML a utiliser pour creer l'element XML
@return un element XML decrivant le cercle
*/
const QDomElement PartCircle::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("circle");
QPointF top_left(sceneTopLeft());
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);
}
/**
Importe les proprietes d'un cercle depuis un element XML
@param qde Element XML a lire
*/
void PartCircle::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
qreal diameter = qde.attribute("diameter", "0").toDouble();
setRect(
QRectF(
mapFromScene(
qde.attribute("x", "0").toDouble(),
qde.attribute("y", "0").toDouble()
),
QSizeF(
diameter,
diameter
)
)
);
}
/**
Specifie la valeur d'une propriete donnee du cercle
@param property propriete a modifier. Valeurs acceptees :
* x : abscisse du centre du cercle
* y : ordonnee du centre du cercle
* diameter : diametre du cercle
@param value Valeur a attribuer a la propriete
*/
void PartCircle::setProperty(const QString &property, const QVariant &value) {
CustomElementGraphicPart::setProperty(property, value);
if (!value.canConvert(QVariant::Double)) return;
if (property == "x") {
QRectF current_rect = rect();
QPointF current_pos = mapToScene(current_rect.center());
setRect(current_rect.translated(value.toDouble() - current_pos.x(), 0.0));
} else if (property == "y") {
QRectF current_rect = rect();
QPointF current_pos = mapToScene(current_rect.center());
setRect(current_rect.translated(0.0, value.toDouble() - current_pos.y()));
} else if (property == "diameter") {
QRectF current_rect = rect();
qreal new_diameter = qAbs(value.toDouble());
current_rect.translate(
(new_diameter - current_rect.width()) / -2.0,
(new_diameter - current_rect.height()) / -2.0
);
current_rect.setSize(QSizeF(new_diameter, new_diameter));
setRect(current_rect);
}
}
/**
Permet d'acceder a la valeur d'une propriete de style donnee.
@param property propriete lue. Valeurs acceptees :
* x : abscisse du centre du cercle
* y : ordonnee du centre du cercle
* diameter : diametre du cercle
@return La valeur de la propriete property
*/
QVariant PartCircle::property(const QString &property) {
// appelle la methode property de CustomElementGraphicpart pour les styles
QVariant style_property = CustomElementGraphicPart::property(property);
if (style_property != QVariant()) return(style_property);
if (property == "x") {
return(mapToScene(rect().center()).x());
} else if (property == "y") {
return(mapToScene(rect().center()).y());
} else if (property == "diameter") {
return(rect().width());
}
return(QVariant());
}
/**
Gere les changements intervenant sur cette partie
@param change Type de changement
@param value Valeur numerique relative au changement
*/
QVariant PartCircle::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsEllipseItem::itemChange(change, value));
}
/**
@return le coin superieur gauche du rectangle dans lequel s'inscrit
le cercle, dans les coordonnees de la scene.
*/
QPointF PartCircle::sceneTopLeft() const {
return(mapToScene(rect().topLeft()));
}
/**
@return le centre du cercle, dans les coordonnees de la scene.
*/
QPointF PartCircle::sceneCenter() const {
return(mapToScene(rect().center()));
}
/**
@return le rectangle delimitant cette partie.
*/
QRectF PartCircle::boundingRect() const {
qreal adjust = 1.5;
QRectF r(QGraphicsEllipseItem::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.
Un cercle est pertinent des lors que son rayon n'est pas nul
*/
bool PartCircle::isUseless() const {
return(rect().isNull());
}
+62
View File
@@ -0,0 +1,62 @@
/*
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 PART_CIRCLE_H
#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.
*/
class PartCircle : public QGraphicsEllipseItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartCircle(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartCircle();
private:
PartCircle(const PartCircle &);
// attributs
private:
CircleEditor *informations;
// methodes
public:
enum { Type = UserType + 1102 };
/**
permet de caster un QGraphicsItem en PartCircle 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("cercle")); }
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneTopLeft() const;
virtual QRectF boundingRect() const;
QPointF sceneCenter() const;
virtual void setProperty(const QString &, const QVariant &);
virtual QVariant property(const QString &);
virtual bool isUseless() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
};
#endif
+199
View File
@@ -0,0 +1,199 @@
/*
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 "partellipse.h"
#include "ellipseeditor.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de cette ellipse
@param scene La scene sur laquelle figure cette ellipse
*/
PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsEllipseItem(parent, scene), CustomElementGraphicPart(editor) {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptedMouseButtons(Qt::LeftButton);
informations = new EllipseEditor(elementEditor(), this);
informations -> setElementTypeName(name());
style_editor -> appendWidget(informations);
style_editor -> setElementTypeName(name());
}
/// Destructeur
PartEllipse::~PartEllipse() {
}
/**
Dessine l'ellipse
@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 PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
if (isSelected()) {
t.setColor(Qt::red);
painter -> setPen(t);
}
painter -> drawEllipse(rect());
if (isSelected()) {
painter -> setRenderHint(QPainter::Antialiasing, false);
painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
QPointF center = rect().center();
painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
}
}
/**
Exporte l'ellipse en XML
@param xml_document Document XML a utiliser pour creer l'element XML
@return un element XML decrivant l'ellipse
*/
const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("ellipse");
QPointF top_left(sceneTopLeft());
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);
}
/**
Importe les proprietes d'une ellipse depuis un element XML
@param qde Element XML a lire
*/
void PartEllipse::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
setRect(
QRectF(
mapFromScene(
qde.attribute("x", "0").toDouble(),
qde.attribute("y", "0").toDouble()
),
QSizeF(
qde.attribute("width", "0").toDouble(),
qde.attribute("height", "0").toDouble()
)
)
);
}
/**
Specifie la valeur d'une propriete donnee de l'ellipse
@param property propriete a modifier. Valeurs acceptees :
* x : abscisse du centre de l'ellipse
* y : ordonnee du centre de l'ellipse
* diameter_h : diametre horizontal de l'ellipse
* diameter_v : diametre vertical de l'ellipse
@param value Valeur a attribuer a la propriete
*/
void PartEllipse::setProperty(const QString &property, const QVariant &value) {
CustomElementGraphicPart::setProperty(property, value);
if (!value.canConvert(QVariant::Double)) return;
if (property == "x") {
QRectF current_rect = rect();
QPointF current_pos = mapToScene(current_rect.center());
setRect(current_rect.translated(value.toDouble() - current_pos.x(), 0.0));
} else if (property == "y") {
QRectF current_rect = rect();
QPointF current_pos = mapToScene(current_rect.center());
setRect(current_rect.translated(0.0, value.toDouble() - current_pos.y()));
} else if (property == "diameter_h") {
qreal new_width = qAbs(value.toDouble());
QRectF current_rect = rect();
current_rect.translate((new_width - current_rect.width()) / -2.0, 0.0);
current_rect.setWidth(new_width);
setRect(current_rect);
} else if (property == "diameter_v") {
qreal new_height = qAbs(value.toDouble());
QRectF current_rect = rect();
current_rect.translate(0.0, (new_height - current_rect.height()) / -2.0);
current_rect.setHeight(new_height);
setRect(current_rect);
}
}
/**
Permet d'acceder a la valeur d'une propriete donnee de l'ellipse
@param property propriete lue. Valeurs acceptees :
* x : abscisse du centre de l'ellipse
* y : ordonnee du centre de l'ellipse
* diameter_h : diametre horizontal de l'ellipse
* diameter_v : diametre vertical de l'ellipse
@return La valeur de la propriete property
*/
QVariant PartEllipse::property(const QString &property) {
// appelle la methode property de CustomElementGraphicpart pour les styles
QVariant style_property = CustomElementGraphicPart::property(property);
if (style_property != QVariant()) return(style_property);
if (property == "x") {
return(mapToScene(rect().center()).x());
} else if (property == "y") {
return(mapToScene(rect().center()).y());
} else if (property == "diameter_h") {
return(rect().width());
} else if (property == "diameter_v") {
return(rect().height());
}
return(QVariant());
}
/**
Gere les changements intervenant sur cette partie
@param change Type de changement
@param value Valeur numerique relative au changement
*/
QVariant PartEllipse::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsEllipseItem::itemChange(change, value));
}
/**
@return le coin superieur gauche du rectangle dans lequel s'inscrit
l'ellipse, dans les coordonnees de la scene.
*/
QPointF PartEllipse::sceneTopLeft() const {
return(mapToScene(rect().topLeft()));
}
/**
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
conservee / enregistree.
Une ellipse est pertinente des lors que ses dimensions ne sont pas nulles
*/
bool PartEllipse::isUseless() const {
return(rect().isNull());
}
/**
@return le rectangle delimitant cette partie.
*/
QRectF PartEllipse::boundingRect() const {
qreal adjust = 1.5;
QRectF r(QGraphicsEllipseItem::boundingRect().normalized());
r.adjust(-adjust, -adjust, adjust, adjust);
return(r);
}
+61
View File
@@ -0,0 +1,61 @@
/*
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 PART_ELLIPSE_H
#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.
*/
class PartEllipse : public QGraphicsEllipseItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartEllipse(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartEllipse();
private:
PartEllipse(const PartEllipse &);
// attributs
private:
EllipseEditor *informations;
// methodes
public:
enum { Type = UserType + 1103 };
/**
permet de caster un QGraphicsItem en PartEllipse 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("ellipse")); }
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneTopLeft() const;
virtual QRectF boundingRect() const;
virtual void setProperty(const QString &, const QVariant &);
virtual QVariant property(const QString &);
virtual bool isUseless() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
};
#endif
+253
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());
}
+66
View File
@@ -0,0 +1,66 @@
/*
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 PART_LINE_H
#define PART_LINE_H
#include <QtGui>
#include "customelementgraphicpart.h"
class LineEditor;
/**
Cette classe represente une ligne pouvant etre utilisee pour composer le
dessin d'un element dans l'editeur d'element.
*/
class PartLine : public QGraphicsLineItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartLine(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartLine();
private:
PartLine(const PartLine &);
// attributs
private:
LineEditor *informations;
// methodes
public:
enum { Type = UserType + 1104 };
/**
permet de caster un QGraphicsItem en PartLine avec qgraphicsitem_cast
@return le type de QGraphicsItem
*/
virtual int type() const { return Type; }
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
virtual QString name() const { return(QObject::tr("ligne")); }
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
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 &);
virtual bool isUseless() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
private:
QList<QPointF> fourShapePoints() const;
};
#endif
+175
View File
@@ -0,0 +1,175 @@
/*
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 "partpolygon.h"
#include "qet.h"
#include "polygoneditor.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de ce polygone
@param scene La scene sur laquelle figure ce polygone
*/
PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
QGraphicsPolygonItem(parent, scene),
CustomElementGraphicPart(editor),
closed(false)
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptedMouseButtons(Qt::LeftButton);
informations = new PolygonEditor(elementEditor(), this);
informations -> setElementTypeName(name());
style_editor -> appendWidget(informations);
style_editor -> setElementTypeName(name());
}
/// Destructeur
PartPolygon::~PartPolygon() {
}
/**
Importe les proprietes d'un polygone depuis un element XML
@param qde Element XML a lire
*/
void PartPolygon::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
int i = 1;
while(true) {
if (
QET::attributeIsAReal(qde, QString("x%1").arg(i)) &&\
QET::attributeIsAReal(qde, QString("y%1").arg(i))
) ++ i;
else break;
}
QPolygonF temp_polygon;
for (int j = 1 ; j < i ; ++ j) {
temp_polygon << QPointF(
qde.attribute(QString("x%1").arg(j)).toDouble(),
qde.attribute(QString("y%1").arg(j)).toDouble()
);
}
setPolygon(temp_polygon);
closed = qde.attribute("closed") != "false";
}
/**
Exporte le polygone en XML
@param xml_document Document XML a utiliser pour creer l'element XML
@return un element XML decrivant le polygone
*/
const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("polygon");
int i = 1;
foreach(QPointF point, polygon()) {
point = mapToScene(point);
xml_element.setAttribute(QString("x%1").arg(i), point.x());
xml_element.setAttribute(QString("y%1").arg(i), point.y());
++ i;
}
if (!closed) xml_element.setAttribute("closed", "false");
stylesToXml(xml_element);
return(xml_element);
}
/**
Dessine le polygone
@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 PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
if (isSelected()) {
t.setColor(Qt::red);
painter -> setPen(t);
}
if (closed) painter -> drawPolygon(polygon());
else painter -> drawPolyline(polygon());
}
/**
Specifie la valeur d'une propriete donnee du polygone
@param property propriete a modifier. Valeurs acceptees :
* closed : true pour fermer le polygone, false sinon
@param value Valeur a attribuer a la propriete
*/
void PartPolygon::setProperty(const QString &property, const QVariant &value) {
CustomElementGraphicPart::setProperty(property, value);
if (property == "closed") closed = value.toBool();
}
/**
Permet d'acceder a la valeur d'une propriete donnee de la ligne
@param property propriete lue. Valeurs acceptees :
* closed : true pour fermer le polygone, false sinon
@return La valeur de la propriete property
*/
QVariant PartPolygon::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 == "closed") return(closed);
return(QVariant());
}
/**
Gere les changements intervenant sur cette partie
@param change Type de changement
@param value Valeur numerique relative au changement
*/
QVariant PartPolygon::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsPolygonItem::itemChange(change, value));
}
/**
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
conservee / enregistree.
Un polygone est pertinent des lors qu'il possede deux points differents.
*/
bool PartPolygon::isUseless() const {
QPolygonF poly(polygon());
if (polygon().count() < 2) return(true);
QPointF previous_point;
for (int i = 1 ; i < poly.count() ; ++ i) {
if (poly[i] != poly[i-1]) return(false);
}
return(true);
}
/**
@return le rectangle delimitant cette partie.
*/
QRectF PartPolygon::boundingRect() const {
qreal adjust = 1.5;
QRectF r(QGraphicsPolygonItem::boundingRect());
r.adjust(-adjust, -adjust, adjust, adjust);
return(r);
}
+92
View File
@@ -0,0 +1,92 @@
/*
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 PART_POLYGON_H
#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.
*/
class PartPolygon : public QGraphicsPolygonItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartPolygon(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartPolygon();
private:
PartPolygon(const PartPolygon &);
// 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 };
/**
permet de caster un QGraphicsItem en PartPolygon avec qgraphicsitem_cast
@return le type de QGraphicsItem
*/
virtual int type() const { return Type; }
virtual QString name() const { return(QObject::tr("polygone")); }
void fromXml(const QDomElement &);
const QDomElement toXml(QDomDocument &) const;
virtual QRectF boundingRect() const;
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
void setClosed(bool c);
bool isClosed() const;
void setProperty(const QString &, const QVariant &);
virtual QVariant property(const QString &);
virtual bool isUseless() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
};
/**
Specifie si le polygone doit etre ferme
@param c true pour un polygone ferme, false sinon
*/
inline void PartPolygon::setClosed(bool c) {
closed = c;
}
/**
Indique si le polygone est ferme
@return true si le polygone est ferme, false sinon
*/
inline bool PartPolygon::isClosed() const {
return(closed);
}
#endif
+228
View File
@@ -0,0 +1,228 @@
/*
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 "partterminal.h"
#include "terminal.h"
#include "terminaleditor.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de cette borne
@param scene La scene sur laquelle figure cette borne
*/
PartTerminal::PartTerminal(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
CustomElementPart(editor),
QGraphicsItem(parent, scene),
_orientation(QET::North)
{
informations = new TerminalEditor(elementEditor(), this);
informations -> setElementTypeName(name());
updateSecondPoint();
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setZValue(100000);
}
/// Destructeur
PartTerminal::~PartTerminal() {
delete informations;
};
/**
Importe les proprietes d'une borne depuis un element XML
@param xml_elmt Element XML a lire
*/
void PartTerminal::fromXml(const QDomElement &xml_elmt) {
// lit la position de la borne
qreal term_x = 0.0, term_y = 0.0;
QET::attributeIsAReal(xml_elmt, "x", &term_x);
QET::attributeIsAReal(xml_elmt, "y", &term_y);
setPos(QPointF(term_x, term_y));
// lit l'orientation de la borne
_orientation = QET::orientationFromString(xml_elmt.attribute("orientation"));
updateSecondPoint();
}
/**
Exporte la borne en XML
@param xml_document Document XML a utiliser pour creer l'element XML
@return un element XML decrivant la borne
*/
const QDomElement PartTerminal::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("terminal");
// ecrit la position de la borne
xml_element.setAttribute("x", QString("%1").arg(scenePos().x()));
xml_element.setAttribute("y", QString("%1").arg(scenePos().y()));
// ecrit l'orientation de la borne
xml_element.setAttribute("orientation", orientationToString(_orientation));
return(xml_element);
}
/**
@return Le widget permettant d'editer cette borne
*/
QWidget *PartTerminal::elementInformations() {
return(informations);
}
/**
Dessine la borne
@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 *, QWidget *) {
p -> save();
// annulation des renderhints
p -> setRenderHint(QPainter::Antialiasing, false);
p -> setRenderHint(QPainter::TextAntialiasing, false);
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
QPen t;
t.setWidthF(1.0);
// dessin de la borne en rouge
t.setColor(isSelected() ? Terminal::couleur_neutre : Qt::red);
p -> setPen(t);
p -> drawLine(QPointF(0.0, 0.0), second_point);
// dessin du point d'amarrage au conducteur en bleu
t.setColor(isSelected() ? Qt::red : Terminal::couleur_neutre);
p -> setPen(t);
p -> setBrush(Terminal::couleur_neutre);
p -> drawPoint(QPointF(0.0, 0.0));
p -> restore();
}
/**
@return le rectangle delimitant cette partie.
*/
QRectF PartTerminal::boundingRect() const {
QPointF p1, p2;
if (second_point.x() <= 0.0 && second_point.y() <= 0.0) {
p1 = second_point;
p2 = QPointF(0.0, 0.0);
} else {
p1 = QPointF(0.0, 0.0);
p2 = second_point;
}
QRectF br;
br.setTopLeft (p1 - QPointF(2.0, 2.0));
br.setBottomRight(p2 + QPointF(2.0, 2.0));
return(br);
}
/**
@return L'orientation de la borne
*/
QET::Orientation PartTerminal::orientation() const {
return(_orientation);
}
/**
Definit l'orientation de la borne
@param ori la nouvelle orientation de la borne
*/
void PartTerminal::setOrientation(QET::Orientation ori) {
prepareGeometryChange();
_orientation = ori;
updateSecondPoint();
informations -> updateForm();
}
/**
Specifie la valeur d'une propriete donnee de la borne
@param property propriete a modifier. Valeurs acceptees :
* x : abscisse de la borne
* y : ordonnee de la borne
* orientation : orientation de la borne
@param value Valeur a attribuer a la propriete
*/
void PartTerminal::setProperty(const QString &property, const QVariant &value) {
if (property == "x") {
if (!value.canConvert(QVariant::Double)) return;
setPos(value.toDouble(), pos().y());
} else if (property == "y") {
if (!value.canConvert(QVariant::Double)) return;
setPos(pos().x(), value.toDouble());
} else if (property == "orientation") {
if (!value.canConvert(QVariant::Int)) return;
setOrientation(static_cast<QET::Orientation>(value.toInt()));
}
}
/**
Permet d'acceder a la valeur d'une propriete donnee de la borne
@param property propriete lue. Valeurs acceptees :
* x : abscisse de la borne
* y : ordonnee de la borne
* orientation : orientation de la borne
@return La valeur de la propriete property
*/
QVariant PartTerminal::property(const QString &property) {
if (property == "x") {
return(scenePos().x());
} else if (property == "y") {
return(scenePos().y());
} else if (property == "orientation") {
return(_orientation);
}
return(QVariant());
}
/**
Gere les changements intervenant sur cette partie
@param change Type de changement
@param value Valeur numerique relative au changement
*/
QVariant PartTerminal::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsItem::itemChange(change, value));
}
/**
Met a jour la position du second point en fonction de la position et de
l'orientation de la borne.
*/
void PartTerminal::updateSecondPoint() {
qreal ts = 4.0; // terminal size
switch(_orientation) {
case QET::North: second_point = QPointF(0.0, ts); break;
case QET::East : second_point = QPointF(-ts, 0.0); break;
case QET::South: second_point = QPointF(0.0, -ts); break;
case QET::West : second_point = QPointF(ts, 0.0); break;
}
}
/**
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
conservee / enregistree.
Une borne est toujours pertinente ; cette fonction renvoie donc
toujours false
*/
bool PartTerminal::isUseless() const {
return(false);
}
+69
View File
@@ -0,0 +1,69 @@
/*
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 PART_TERMINAL_H
#define PART_TERMINAL_H
#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.
*/
class PartTerminal : public CustomElementPart, public QGraphicsItem {
public:
// constructeurs, destructeur
PartTerminal(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartTerminal();
private:
PartTerminal(const PartTerminal &);
// attributs
private:
QET::Orientation _orientation;
QPointF second_point;
TerminalEditor *informations;
// methodes
public:
enum { Type = UserType + 1106 };
/**
permet de caster un QGraphicsItem en PartTerminal avec qgraphicsitem_cast
@return le type de QGraphicsItem
*/
virtual int type() const { return Type; }
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;
void setOrientation(QET::Orientation);
virtual void setProperty(const QString &, const QVariant &);
virtual QVariant property(const QString &);
virtual bool isUseless() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
private:
void updateSecondPoint();
};
#endif
+233
View File
@@ -0,0 +1,233 @@
/*
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 "parttext.h"
#include "texteditor.h"
#include "editorcommands.h"
#include "elementscene.h"
#include "qetapp.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de ce texte statique
@param scene La scene sur laquelle figure ce texte statique
*/
PartText::PartText(QETElementEditor *editor, QGraphicsItem *parent, ElementScene *scene) :
QGraphicsTextItem(parent, scene),
CustomElementPart(editor)
{
setDefaultTextColor(Qt::black);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setPlainText(QObject::tr("T"));
infos = new TextEditor(elementEditor(), this);
infos -> setElementTypeName(name());
}
/// Destructeur
PartText::~PartText() {
delete infos;
}
/**
Importe les proprietes d'un texte statique depuis un element XML
@param xml_element Element XML a lire
*/
void PartText::fromXml(const QDomElement &xml_element) {
bool ok;
int font_size = xml_element.attribute("size").toInt(&ok);
if (!ok || font_size < 1) font_size = 20;
setFont(QFont(QString(QETApp::diagramTextsFont()), font_size));
setPlainText(xml_element.attribute("text"));
setPos(
xml_element.attribute("x").toDouble(),
xml_element.attribute("y").toDouble()
);
}
/**
Exporte le texte statique en XML
@param xml_document Document XML a utiliser pour creer l'element XML
@return un element XML decrivant le texte statique
*/
const QDomElement PartText::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("text");
xml_element.setAttribute("x", QString("%1").arg((scenePos() + margin()).x()));
xml_element.setAttribute("y", QString("%1").arg((scenePos() + margin()).y()));
xml_element.setAttribute("text", toPlainText());
xml_element.setAttribute("size", font().pointSize());
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)
@return la position du texte
*/
QPointF PartText::pos() const {
return(QGraphicsTextItem::pos() + margin());
}
/**
Specifie la position du texte statique
@param left_corner_pos Nouvelle position
*/
void PartText::setPos(const QPointF &left_corner_pos) {
QGraphicsTextItem::setPos(left_corner_pos - margin());
}
/**
Specifie la position du texte statique
@param x abscisse de la nouvelle position
@param y ordonnee de la nouvelle position
*/
void PartText::setPos(qreal x, qreal y) {
QGraphicsTextItem::setPos(QPointF(x, y) - margin());
}
/**
@return Les coordonnees du point situe en bas a gauche du texte.
*/
QPointF PartText::margin() const {
QFont used_font = font();
QFontMetrics qfm(used_font);
QPointF margin(
(boundingRect().width () - qfm.width(toPlainText())) / 2.0,
((boundingRect().height() - used_font.pointSizeF()) / 3.0) + used_font.pointSizeF()
);
return(margin);
}
/**
Permet a l'element texte de redevenir deplacable a la fin de l'edition de texte
@param e Le QFocusEvent decrivant la perte de focus
*/
void PartText::focusOutEvent(QFocusEvent *e) {
QGraphicsTextItem::focusOutEvent(e);
if (previous_text != toPlainText()) {
undoStack().push(
new ChangePartCommand(
TextEditor::tr("texte") + " " + name(),
this,
"text",
previous_text,
toPlainText()
)
);
previous_text = toPlainText();
}
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
}
/**
Permet a l'element texte de devenir editable lorsqu'on double-clique dessus
@param e Le QGraphicsSceneMouseEvent qui decrit le double-clic
*/
void PartText::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
setTextInteractionFlags(Qt::TextEditorInteraction);
previous_text = toPlainText();
QGraphicsTextItem::mouseDoubleClickEvent(e);
setFocus(Qt::MouseFocusReason);
}
/**
Specifie la valeur d'une propriete donnee du texte statique
@param property propriete a modifier. Valeurs acceptees :
* x : abscisse de la position
* y : ordonnee de la position
* size : taille du texte
* text : texte
@param value Valeur a attribuer a la propriete
*/
void PartText::setProperty(const QString &property, const QVariant &value) {
if (property == "x") {
if (!value.canConvert(QVariant::Double)) return;
setPos(value.toDouble(), pos().y());
} else if (property == "y") {
if (!value.canConvert(QVariant::Double)) return;
setPos(pos().x(), value.toDouble());
} else if (property == "size") {
if (!value.canConvert(QVariant::Int)) return;
setFont(QFont(font().family(), value.toInt()));
} else if (property == "text") {
setPlainText(value.toString());
}
}
/**
Permet d'acceder a la valeur d'une propriete donnee du texte statique
@param property propriete lue. Valeurs acceptees :
* x : abscisse de la position
* y : ordonnee de la position
* size : taille du texte
* text : texte
@return La valeur de la propriete property
*/
QVariant PartText::property(const QString &property) {
if (property == "x") {
return((scenePos() + margin()).x());
} else if (property == "y") {
return((scenePos() + margin()).y());
} else if (property == "size") {
return(font().pointSize());
} else if (property == "text") {
return(toPlainText());
}
return(QVariant());
}
/**
Gere les changements intervenant sur cette partie
@param change Type de changement
@param value Valeur numerique relative au changement
*/
QVariant PartText::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
infos -> updateForm();
}
}
return(QGraphicsTextItem::itemChange(change, value));
}
/**
@return le rectangle delimitant cette partie.
*/
QRectF PartText::boundingRect() const {
QRectF r = QGraphicsTextItem::boundingRect();
r.adjust(0.0, -2.0, 0.0, 0.0);
return(r);
}
/**
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
conservee / enregistree.
Un texte statique n'est pas pertinent lorsque son texte est vide.
*/
bool PartText::isUseless() const {
return(toPlainText().isEmpty());
}
+68
View File
@@ -0,0 +1,68 @@
/*
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 PART_TEXT_H
#define PART_TEXT_H
#include <QtGui>
#include "customelementpart.h"
class TextEditor;
/**
Cette classe represente un texte pouvant etre utilise pour composer le
dessin d'un element dans l'editeur d'element.
*/
class PartText : public QGraphicsTextItem, public CustomElementPart {
// constructeurs, destructeur
public:
PartText(QETElementEditor *, QGraphicsItem * = 0, ElementScene * = 0);
virtual ~PartText();
private:
PartText(const PartText &);
// attributs
TextEditor *infos;
// methodes
public:
enum { Type = UserType + 1107 };
/**
permet de caster un QGraphicsItem en PartText avec qgraphicsitem_cast
@return le type de QGraphicsItem
*/
virtual int type() const { return Type; }
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);
virtual void setProperty(const QString &, const QVariant &);
virtual QVariant property(const QString &);
virtual bool isUseless() const;
protected:
virtual void focusOutEvent(QFocusEvent *);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
QRectF boundingRect() const;
private:
QPointF margin() const;
QString previous_text;
};
#endif
+258
View File
@@ -0,0 +1,258 @@
/*
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 "parttextfield.h"
#include "textfieldeditor.h"
#include "editorcommands.h"
#include "qetapp.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de ce champ de texte
@param scene La scene sur laquelle figure ce champ de texte
*/
PartTextField::PartTextField(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
QGraphicsTextItem(parent, scene),
CustomElementPart(editor),
follow_parent_rotations(true)
{
setDefaultTextColor(Qt::black);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setPlainText(QObject::tr("_"));
infos = new TextFieldEditor(elementEditor(), this);
infos -> setElementTypeName(name());
}
/// Destructeur
PartTextField::~PartTextField() {
delete infos;
}
/**
Importe les proprietes d'un champ de texte depuis un element XML
@param xml_element Element XML a lire
*/
void PartTextField::fromXml(const QDomElement &xml_element) {
bool ok;
int font_size = xml_element.attribute("size").toInt(&ok);
if (!ok || font_size < 1) font_size = 20;
setFont(QFont(QString(QETApp::diagramTextsFont()), font_size));
setPlainText(xml_element.attribute("text"));
setPos(
xml_element.attribute("x").toDouble(),
xml_element.attribute("y").toDouble()
);
follow_parent_rotations = (xml_element.attribute("rotate") == "true");
}
/**
Exporte le champ de texte en XML
@param xml_document Document XML a utiliser pour creer l'element XML
@return un element XML decrivant le champ de texte
*/
const QDomElement PartTextField::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("input");
xml_element.setAttribute("x", QString("%1").arg((scenePos() + margin()).x()));
xml_element.setAttribute("y", QString("%1").arg((scenePos() + margin()).y()));
xml_element.setAttribute("text", toPlainText());
xml_element.setAttribute("size", font().pointSize());
if (follow_parent_rotations) xml_element.setAttribute("rotate", "true");
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)
@return la position du texte
*/
QPointF PartTextField::pos() const {
return(QGraphicsTextItem::pos() + margin());
}
/**
Specifie la position du champ de texte
@param left_corner_pos Nouvelle position
*/
void PartTextField::setPos(const QPointF &left_corner_pos) {
QGraphicsTextItem::setPos(left_corner_pos - margin());
}
/**
Specifie la position du champ de texte
@param x abscisse de la nouvelle position
@param y ordonnee de la nouvelle position
*/
void PartTextField::setPos(qreal x, qreal y) {
QGraphicsTextItem::setPos(QPointF(x, y) - margin());
}
/**
@return true si le champ de texte suit les rotation de l'element, false
sinon
*/
bool PartTextField::followParentRotations() {
return(follow_parent_rotations);
}
/**
@param fpr true pour que le champ de texte suive les rotation de
l'element, false sinon
*/
void PartTextField::setFollowParentRotations(bool fpr) {
follow_parent_rotations = fpr;
}
/**
@return Les coordonnees du point situe en bas a gauche du texte.
*/
QPointF PartTextField::margin() const {
QFont used_font = font();
QFontMetrics qfm(used_font);
QPointF margin(
(boundingRect().width () - qfm.width(toPlainText())) / 2.0,
((boundingRect().height() - used_font.pointSizeF()) / 3.0) + used_font.pointSizeF()
);
return(margin);
}
/**
Permet a l'element texte de redevenir deplacable a la fin de l'edition de texte
@param e Le QFocusEvent decrivant la perte de focus
*/
void PartTextField::focusOutEvent(QFocusEvent *e) {
QGraphicsTextItem::focusOutEvent(e);
if (previous_text != toPlainText()) {
undoStack().push(
new ChangePartCommand(
TextFieldEditor::tr("texte") + " " + name(),
this,
"text",
previous_text,
toPlainText()
)
);
previous_text = toPlainText();
}
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
}
/**
Permet a l'element texte de devenir editable lorsqu'on double-clique dessus
@param e Le QGraphicsSceneMouseEvent qui decrit le double-clic
*/
void PartTextField::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
setTextInteractionFlags(Qt::TextEditorInteraction);
previous_text = toPlainText();
QGraphicsTextItem::mouseDoubleClickEvent(e);
setFocus(Qt::MouseFocusReason);
}
/**
Specifie la valeur d'une propriete donnee du champ de texte
@param property propriete a modifier. Valeurs acceptees :
* x : abscisse de la position
* y : ordonnee de la position
* size : taille du texte
* text : texte
* rotate : suivi de la rotation de l'element parent
@param value Valeur a attribuer a la propriete
*/
void PartTextField::setProperty(const QString &property, const QVariant &value) {
if (property == "x") {
if (!value.canConvert(QVariant::Double)) return;
setPos(value.toDouble(), pos().y());
} else if (property == "y") {
if (!value.canConvert(QVariant::Double)) return;
setPos(pos().x(), value.toDouble());
} else if (property == "size") {
if (!value.canConvert(QVariant::Int)) return;
setFont(QFont(font().family(), value.toInt()));
} else if (property == "text") {
setPlainText(value.toString());
} else if (property == "rotate") {
follow_parent_rotations = value.toBool();
}
}
/**
Permet d'acceder a la valeur d'une propriete donnee du champ de texte
@param property propriete lue. Valeurs acceptees :
* x : abscisse de la position
* y : ordonnee de la position
* size : taille du texte
* text : texte
* rotate : suivi de la rotation de l'element parent
@return La valeur de la propriete property
*/
QVariant PartTextField::property(const QString &property) {
if (property == "x") {
return((scenePos() + margin()).x());
} else if (property == "y") {
return((scenePos() + margin()).y());
} else if (property == "size") {
return(font().pointSize());
} else if (property == "text") {
return(toPlainText());
} else if (property == "rotate") {
return(follow_parent_rotations);
}
return(QVariant());
}
/**
Gere les changements intervenant sur cette partie
@param change Type de changement
@param value Valeur numerique relative au changement
*/
QVariant PartTextField::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
infos -> updateForm();
}
}
return(QGraphicsTextItem::itemChange(change, value));
}
/**
@return le rectangle delimitant cette partie.
*/
QRectF PartTextField::boundingRect() const {
QRectF r = QGraphicsTextItem::boundingRect();
r.adjust(0.0, -2.0, 0.0, 0.0);
return(r);
}
/**
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
conservee / enregistree.
Un champ de texte est toujours pertinent ; cette fonction renvoie donc
toujours false
*/
bool PartTextField::isUseless() const {
return(false);
}
+74
View File
@@ -0,0 +1,74 @@
/*
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 PART_TEXTFIELD_H
#define PART_TEXTFIELD_H
#include <QtGui>
#include "customelementpart.h"
class TextFieldEditor;
class QETElementEditor;
/**
Cette classe represente un champ de texte editable pouvant etre utilise
pour composer le dessin d'un element dans l'editeur d'element.
L'utilisateur peut specifier un valeur par defaut. Le champ sera editable
lorsque l'element sera pose sur un schema.
*/
class PartTextField : public QGraphicsTextItem, public CustomElementPart {
// constructeurs, destructeur
public:
PartTextField(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartTextField();
private:
PartTextField(const PartTextField &);
// attributs
TextFieldEditor *infos;
bool follow_parent_rotations;
// methodes
public:
enum { Type = UserType + 1108 };
/**
permet de caster un QGraphicsItem en PartTextField avec qgraphicsitem_cast
@return le type de QGraphicsItem
*/
virtual int type() const { return Type; }
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);
bool followParentRotations();
void setFollowParentRotations(bool);
virtual void setProperty(const QString &, const QVariant &);
virtual QVariant property(const QString &);
virtual bool isUseless() const;
protected:
virtual void focusOutEvent(QFocusEvent *);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
QRectF boundingRect() const;
private:
QPointF margin() const;
QString previous_text;
};
#endif
+155
View File
@@ -0,0 +1,155 @@
/*
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 "polygoneditor.h"
#include "partpolygon.h"
#include "elementscene.h"
#include "editorcommands.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param p Le polygone a editer
@param parent le Widget parent
*/
PolygonEditor::PolygonEditor(QETElementEditor *editor, PartPolygon *p, QWidget *parent) :
ElementItemEditor(editor, parent),
points_list(this),
close_polygon(tr("Polygone ferm\351"), this)
{
part = p;
// prepare la liste de points
points_list.setColumnCount(2);
QStringList headers;
headers << tr("x") << tr("y");
points_list.setHeaderLabels(headers);
points_list.setRootIsDecorated(false);
updateForm();
// layout
QVBoxLayout *layout = new QVBoxLayout(this);
layout -> addWidget(new QLabel(tr("Points du polygone :")));
layout -> addWidget(&points_list);
layout -> addWidget(&close_polygon);
updateForm();
}
/// Destructeur
PolygonEditor::~PolygonEditor() {
}
/**
Met a jour le polygone a partir des donnees du formulaire : points et etat ferme ou non
*/
void PolygonEditor::updatePolygon() {
updatePolygonPoints();
updatePolygonClosedState();
}
/**
Met a jour les points du polygone et cree un objet d'annulation
*/
void PolygonEditor::updatePolygonPoints() {
QVector<QPointF> points = getPointsFromTree();
if (points.count() < 2) {
QMessageBox::warning(
this,
tr("Erreur"),
tr("Le polygone doit comporter au moins deux points.")
);
return;
}
undoStack().push(new ChangePolygonPointsCommand(part, part -> polygon(), points));
}
/**
Met a jour l'etat ferme ou non du polygone
*/
void PolygonEditor::updatePolygonClosedState() {
undoStack().push(
new ChangePartCommand(
tr("fermeture du polygone"),
part,
"closed",
QVariant(!close_polygon.isChecked()),
QVariant(close_polygon.isChecked())
)
);
}
/**
Met a jour le formulaire d'edition
*/
void PolygonEditor::updateForm() {
activeConnections(false);
while(points_list.takeTopLevelItem(0));
foreach(QPointF point, part -> polygon()) {
point = part -> mapToScene(point);
QStringList qsl;
qsl << QString("%1").arg(point.x()) << QString("%1").arg(point.y());
QTreeWidgetItem *qtwi = new QTreeWidgetItem(qsl);
qtwi -> setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
points_list.addTopLevelItem(qtwi);
}
close_polygon.setChecked(part -> isClosed());
activeConnections(true);
}
/**
@return Un vecteur contenant les points composant le polygone a partir du
formulaire d'edition
*/
QVector<QPointF> PolygonEditor::getPointsFromTree() {
QVector<QPointF> points;
for(int i = 0 ; i < points_list.topLevelItemCount() ; ++ i) {
QTreeWidgetItem *qtwi = points_list.topLevelItem(i);
bool x_convert_ok, y_convert_ok;
qreal x = qtwi -> text(0).toDouble(&x_convert_ok);
qreal y = qtwi -> text(1).toDouble(&y_convert_ok);
if (!x_convert_ok || !y_convert_ok) continue;
points << part -> mapFromScene(QPointF(x, y));
}
return(points);
}
/**
@param qtwi QTreeWidgetItem a valider
@param column Colonne exacte du QTreeWidgetItem a valider
*/
void PolygonEditor::validColumn(QTreeWidgetItem *qtwi, int column) {
bool convert_ok;
qtwi -> text(column).toDouble(&convert_ok);
if (convert_ok) {
points_list.closePersistentEditor(qtwi, column);
updatePolygonPoints();
} else points_list.openPersistentEditor(qtwi, column);
}
/**
Active ou desactive les connexionx signaux/slots entre les widgets internes.
@param active true pour activer les connexions, false pour les desactiver
*/
void PolygonEditor::activeConnections(bool active) {
if (active) {
connect(&close_polygon, SIGNAL(stateChanged(int)), this, SLOT(updatePolygonClosedState()));
connect(&points_list, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(validColumn(QTreeWidgetItem *, int)));
} else {
disconnect(&close_polygon, SIGNAL(stateChanged(int)), this, SLOT(updatePolygonClosedState()));
disconnect(&points_list, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(validColumn(QTreeWidgetItem *, int)));
}
}
+58
View File
@@ -0,0 +1,58 @@
/*
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 POLYGON_EDITOR_H
#define POLYGON_EDITOR_H
#include "elementitemeditor.h"
class PartPolygon;
/**
Cette classe represente le widget d'edition d'un polygone dans l'editeur
d'element.
*/
class PolygonEditor : public ElementItemEditor {
Q_OBJECT
// constructeurs, destructeur
public:
PolygonEditor(QETElementEditor *, PartPolygon *, QWidget * = 0);
virtual ~PolygonEditor();
private:
PolygonEditor(const PolygonEditor &);
// attributs
private:
PartPolygon *part;
QTreeWidget points_list;
QCheckBox close_polygon;
// methodes
private:
QVector<QPointF> getPointsFromTree();
public slots:
void updatePolygon();
void updatePolygonPoints();
void updatePolygonClosedState();
void updateForm();
void validColumn(QTreeWidgetItem *qtwi, int column);
private:
void activeConnections(bool);
};
#endif
+784
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());
}
+201
View File
@@ -0,0 +1,201 @@
/*
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 CUSTOM_ELEMENT_EDITOR_H
#define CUSTOM_ELEMENT_EDITOR_H
#include <QtGui>
#include "elementscene.h"
#include "orientationset.h"
class ElementView;
/**
Cette classe represente un editeur d'element. Elle permet a l'utilisateur
de dessiner, modifier et parametrer un element electrique. Le dessin se
fait par ajout de parties (Part).
*/
class QETElementEditor : public QMainWindow {
Q_OBJECT
// constructeur, destructeur
public:
QETElementEditor(QWidget * = 0);
virtual ~QETElementEditor();
private:
QETElementEditor(const QETElementEditor &);
// attributs
private:
/// booleen indiquant si l'editeur est en mode "lecture seule" ou non
bool read_only;
/// menus
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;
/// container pour la liste des annulations
QDockWidget *undo_dock;
/// Container pour la liste des parties
QDockWidget *parts_dock;
/// Liste des parties
QListWidget *parts_list;
/// actions du menu fichier
QAction *new_element, *open, *save, *save_as, *reload, *quit;
/// actions du menu edition
QAction *selectall, *deselectall, *inv_select;
QAction *undo, *redo;
QAction *zoom_in, *zoom_out, *zoom_fit, *zoom_reset;
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_ellipse, *add_polygon, *add_text;
QAction *add_arc, *add_terminal, *add_textfield;
/// label affiche lors de la selection de plusieurs elements
QLabel *default_informations;
/// titre minimal
QString min_title;
/// Nom de fichier
QString _filename;
// methodes
public:
void setSize(const QSize &);
QSize size() const;
void setHotspot(const QPoint &);
QPoint hotspot() const;
void setNames(const NamesList &);
void setOrientations(const OrientationSet &orientation_set);
OrientationSet orientations() const;
void setFileName(const QString &);
QString fileName() const;
void setReadOnly(bool);
bool isReadOnly() const;
void fromFile(const QString &);
bool toFile(const QString &);
ElementScene *elementScene() const;
void readSettings();
void writeSettings();
protected:
void closeEvent(QCloseEvent *);
private:
void setupActions();
void setupMenus();
void setupInterface();
bool canClose();
public slots:
void slot_new();
void slot_open();
void slot_reload();
bool slot_save();
bool slot_saveAs();
void slot_setRubberBandToView();
void slot_setNoDragToView();
void slot_setNormalMode();
void slot_updateInformations();
void slot_updateMenus();
void slot_updateTitle();
void slot_createPartsList();
void slot_updatePartsList();
void slot_updateSelectionFromPartsList();
void xmlPreview();
};
/**
@param siz La nouvelle taille de l'element edite
*/
inline void QETElementEditor::setSize(const QSize &siz) {
ce_scene -> setWidth(siz.width());
ce_scene -> setHeight(siz.height());
}
/**
@return la taille de l'element edite
*/
inline QSize QETElementEditor::size() const {
return(
QSize(
ce_scene -> width(),
ce_scene -> height()
)
);
}
/**
@param hs Le nouveau point de saisie de l'element edite
*/
inline void QETElementEditor::setHotspot(const QPoint &hs) {
ce_scene -> setHotspot(hs);
}
/**
@return le point de saisie de l'element edite
*/
inline QPoint QETElementEditor::hotspot() const {
return(ce_scene -> hotspot());
}
/**
@param nameslist le nouvel ensemble de noms de l'element edite
*/
inline void QETElementEditor::setNames(const NamesList &nameslist) {
ce_scene -> setNames(nameslist);
}
/**
@param orientation_set le nouvel ensemble d'orientations de l'element edite
*/
inline void QETElementEditor::setOrientations(const OrientationSet &orientation_set) {
ce_scene -> setOrientations(orientation_set);
}
/**
@return le nouvel ensemble d'orientations de l'element edite
*/
inline OrientationSet QETElementEditor::orientations() const {
return(ce_scene -> orientations());
}
/**
@param fn Le nouveau nom de fichier de l'element edite
*/
inline void QETElementEditor::setFileName(const QString &fn) {
_filename = fn;
slot_updateTitle();
}
/**
@return le nomde fichier de l'element edite
*/
inline QString QETElementEditor::fileName() const {
return(_filename);
}
/**
@return la scene d'edition de l'element
*/
inline ElementScene *QETElementEditor::elementScene() const {
return(ce_scene);
}
#endif
+180
View File
@@ -0,0 +1,180 @@
/*
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 "styleeditor.h"
#include "customelementgraphicpart.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param p La partie a editer
@param parent le Widget parent
*/
StyleEditor::StyleEditor(QETElementEditor *editor, CustomElementGraphicPart *p, QWidget *parent) : ElementItemEditor(editor, parent), part(p) {
// couleur
color = new QButtonGroup(this);
color -> addButton(black_color = new QRadioButton(tr("Noir")), CustomElementGraphicPart::BlackColor);
color -> addButton(white_color = new QRadioButton(tr("Blanc")), CustomElementGraphicPart::WhiteColor);
// style
style = new QButtonGroup(this);
style -> addButton(normal_style = new QRadioButton(tr("Normal")), CustomElementGraphicPart::NormalStyle);
style -> addButton(dashed_style = new QRadioButton(tr("Pointill\351")), CustomElementGraphicPart::DashedStyle);
style -> button(part -> lineStyle()) -> setChecked(true);
// epaisseur
weight = new QButtonGroup(this);
weight -> addButton(none_weight = new QRadioButton(tr("Nulle")), CustomElementGraphicPart::NoneWeight);
weight -> addButton(thin_weight = new QRadioButton(tr("Fine")), CustomElementGraphicPart::ThinWeight);
weight -> addButton(normal_weight = new QRadioButton(tr("Normale")), CustomElementGraphicPart::NormalWeight);
// remplissage
filling = new QButtonGroup(this);
filling -> addButton(no_filling = new QRadioButton(tr("Aucun")), CustomElementGraphicPart::NoneFilling );
filling -> addButton(black_filling = new QRadioButton(tr("Noir")), CustomElementGraphicPart::BlackFilling);
filling -> addButton(white_filling = new QRadioButton(tr("Blanc")), CustomElementGraphicPart::WhiteFilling);
// antialiasing
antialiasing = new QCheckBox(tr("Antialiasing"));
updateForm();
main_layout = new QVBoxLayout();
main_layout -> addWidget(antialiasing);
main_layout -> addWidget(new QLabel("<u>" + tr("Trait :") + "</u> "));
QHBoxLayout *color_layout = new QHBoxLayout();
color_layout -> addWidget(new QLabel(tr("Couleur : ")));
color_layout -> addWidget(black_color);
color_layout -> addWidget(white_color);
color_layout -> addStretch();
main_layout -> addItem(color_layout);
QHBoxLayout *style_layout = new QHBoxLayout();
style_layout -> addWidget(new QLabel(tr("Style : ")));
style_layout -> addWidget(normal_style);
style_layout -> addWidget(dashed_style);
style_layout -> addStretch();
main_layout -> addItem(style_layout);
QHBoxLayout *weight_layout = new QHBoxLayout();
weight_layout -> addWidget(new QLabel(tr("\311paisseur : ")));
weight_layout -> addWidget(none_weight);
weight_layout -> addWidget(thin_weight);
weight_layout -> addWidget(normal_weight);
weight_layout -> addStretch();
main_layout -> addItem(weight_layout);
main_layout -> addWidget(new QLabel("<u>" + tr("Remplissage :") + "</u> "));
QHBoxLayout *filling_layout = new QHBoxLayout();
filling_layout -> addWidget(no_filling);
filling_layout -> addWidget(black_filling);
filling_layout -> addWidget(white_filling);
filling_layout -> addStretch();
main_layout -> addItem(filling_layout);
main_layout -> addStretch();
setLayout(main_layout);
}
/// Destructeur
StyleEditor::~StyleEditor() {
}
/**
Met a jour le style de la partie a partir des donnees du formulaire
*/
void StyleEditor::updatePart() {
// applique l'antialiasing
part -> setAntialiased(antialiasing -> isChecked());
// applique la couleur
part -> setColor(static_cast<CEGP::Color>(color -> checkedId()));
// applique le style
part -> setLineStyle(static_cast<CEGP::LineStyle>(style -> checkedId()));
// applique l'epaisseur
part -> setLineWeight(static_cast<CEGP::LineWeight>(weight -> checkedId()));
// applique le remplissage
part -> setFilling(static_cast<CEGP::Filling>(filling -> checkedId()));
}
/// Met a jour l'antialiasing et cree un objet d'annulation
void StyleEditor::updatePartAntialiasing() { addChangePartCommand("style antialiasing", part, "antialias", antialiasing -> isChecked()); }
/// Met a jour la couleur du trait et cree un objet d'annulation
void StyleEditor::updatePartColor() { addChangePartCommand("style couleur", part, "color", color -> checkedId()); }
/// Met a jour le style du trait et cree un objet d'annulation
void StyleEditor::updatePartLineStyle() { addChangePartCommand("style ligne", part, "line-style", style -> checkedId()); }
/// Met a jour l'epaisseur du trait et cree un objet d'annulation
void StyleEditor::updatePartLineWeight() { addChangePartCommand("style epaisseur", part, "line-weight", weight -> checkedId()); }
/// Met a jour la couleur de fond et cree un objet d'annulation
void StyleEditor::updatePartFilling() { addChangePartCommand("style remplissage", part, "filling", filling -> checkedId()); }
/**
Met a jour le formulaire d'edition
*/
void StyleEditor::updateForm() {
activeConnections(false);
// lit l'antialiasing
antialiasing -> setChecked(part -> antialiased());
// lit la couleur
color -> button(part -> color()) -> setChecked(true);
// lit le style
style -> button(part -> lineStyle()) -> setChecked(true);
// lit l'epaisseur
weight -> button(part -> lineWeight()) -> setChecked(true);
// lit le remplissage
filling -> button(part -> filling()) -> setChecked(true);
activeConnections(true);
}
/**
Ajoute un widget en bas de l'editeur de style
@param w Widget a inserer
*/
void StyleEditor::appendWidget(QWidget *w) {
main_layout -> insertWidget(7, w);
}
/**
Active ou desactive les connexionx signaux/slots entre les widgets internes.
@param active true pour activer les connexions, false pour les desactiver
*/
void StyleEditor::activeConnections(bool active) {
if (active) {
connect(color, SIGNAL(buttonClicked(int)), this, SLOT(updatePartColor()));
connect(style, SIGNAL(buttonClicked(int)), this, SLOT(updatePartLineStyle()));
connect(weight, SIGNAL(buttonClicked(int)), this, SLOT(updatePartLineWeight()));
connect(filling, SIGNAL(buttonClicked(int)), this, SLOT(updatePartFilling()));
connect(antialiasing, SIGNAL(stateChanged(int)), this, SLOT(updatePartAntialiasing()));
} else {
disconnect(color, SIGNAL(buttonClicked(int)), this, SLOT(updatePartColor()));
disconnect(style, SIGNAL(buttonClicked(int)), this, SLOT(updatePartLineStyle()));
disconnect(weight, SIGNAL(buttonClicked(int)), this, SLOT(updatePartLineWeight()));
disconnect(filling, SIGNAL(buttonClicked(int)), this, SLOT(updatePartFilling()));
disconnect(antialiasing, SIGNAL(stateChanged(int)), this, SLOT(updatePartAntialiasing()));
}
}
+65
View File
@@ -0,0 +1,65 @@
/*
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 STYLE_EDITOR_H
#define STYLE_EDITOR_H
#include <QtGui>
#include "elementitemeditor.h"
class CustomElementGraphicPart;
/**
Cette classe represente un widget d'edition des styles que peut comporter
une partie d'elements (couleur, epaisseur et style du trait, remplissage,
antialiasing). Elle peut accueillir un widget sous cette interface grace a
la methode appendWidget.
*/
class StyleEditor : public ElementItemEditor {
Q_OBJECT
// constructeurs, destructeur
public:
StyleEditor(QETElementEditor *, CustomElementGraphicPart *, QWidget * = 0);
virtual ~StyleEditor();
private:
StyleEditor(const StyleEditor &);
// attributs
private:
CustomElementGraphicPart *part;
QVBoxLayout *main_layout;
QButtonGroup *color, *style, *weight, *filling;
QRadioButton *black_color, *white_color, *normal_style, *dashed_style;
QRadioButton *none_weight, *thin_weight, *normal_weight, *no_filling;
QRadioButton *black_filling, *white_filling;
QCheckBox *antialiasing;
//methodes
public:
void appendWidget(QWidget *w);
public slots:
void updatePart();
void updateForm();
void updatePartAntialiasing();
void updatePartColor();
void updatePartLineStyle();
void updatePartLineWeight();
void updatePartFilling();
private:
void activeConnections(bool);
};
#endif
+113
View File
@@ -0,0 +1,113 @@
/*
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 "terminaleditor.h"
#include "partterminal.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@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;
qle_x = new QLineEdit();
qle_y = new QLineEdit();
qle_x -> setValidator(new QDoubleValidator(qle_x));
qle_y -> setValidator(new QDoubleValidator(qle_y));
orientation = new QComboBox();
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 : ")));
QHBoxLayout *position = new QHBoxLayout();
position -> addWidget(new QLabel(tr("x : ")));
position -> addWidget(qle_x );
position -> addWidget(new QLabel(tr("y : ")));
position -> addWidget(qle_y );
main_layout -> addLayout(position);
QHBoxLayout *ori = new QHBoxLayout();
ori -> addWidget(new QLabel(tr("Orientation : ")));
ori -> addWidget(orientation );
main_layout -> addLayout(ori);
main_layout -> addStretch();
setLayout(main_layout);
activeConnections(true);
updateForm();
}
/// Destructeur
TerminalEditor::~TerminalEditor() {
};
/**
Met a jour la borne a partir des donnees du formulaire
*/
void TerminalEditor::updateTerminal() {
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
part -> setOrientation(
static_cast<QET::Orientation>(
orientation -> itemData(
orientation -> currentIndex()
).toInt()
)
);
}
/// Met a jour l'abscisse de la position de la borne et cree un objet d'annulation
void TerminalEditor::updateTerminalX() { addChangePartCommand(tr("abscisse"), part, "x", qle_x -> text().toDouble()); updateForm(); }
/// Met a jour l'ordonnee de la position de la borne et cree un objet d'annulation
void TerminalEditor::updateTerminalY() { addChangePartCommand(tr("ordonn\351e"), part, "y", qle_y -> text().toDouble()); updateForm(); }
/// Met a jour l'orientation de la borne et cree un objet d'annulation
void TerminalEditor::updateTerminalO() { addChangePartCommand(tr("orientation"), part, "orientation", orientation -> itemData(orientation -> currentIndex()).toInt()); }
/**
Met a jour le formulaire d'edition
*/
void TerminalEditor::updateForm() {
activeConnections(false);
qle_x -> setText(part -> property("x").toString());
qle_y -> setText(part -> property("y").toString());
orientation -> setCurrentIndex(static_cast<int>(part -> orientation()));
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 TerminalEditor::activeConnections(bool active) {
if (active) {
connect(qle_x, SIGNAL(editingFinished()), this, SLOT(updateTerminalX()));
connect(qle_y, SIGNAL(editingFinished()), this, SLOT(updateTerminalY()));
connect(orientation, SIGNAL(activated(int)), this, SLOT(updateTerminalO()));
} else {
disconnect(qle_x, SIGNAL(editingFinished()), this, SLOT(updateTerminalX()));
disconnect(qle_y, SIGNAL(editingFinished()), this, SLOT(updateTerminalY()));
disconnect(orientation, SIGNAL(activated(int)), this, SLOT(updateTerminalO()));
}
}
+54
View File
@@ -0,0 +1,54 @@
/*
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 TERMINAL_EDITOR_H
#define TERMINAL_EDITOR_H
#include <QtGui>
#include "elementitemeditor.h"
class PartTerminal;
/**
Cette classe represente un editeur de borne.
Elle permet d'editer a travers une interface graphique les
proprietes d'une borne d'element.
*/
class TerminalEditor : public ElementItemEditor {
Q_OBJECT
// Constructeurs, destructeur
public:
TerminalEditor(QETElementEditor *, PartTerminal *, QWidget * = 0);
virtual ~TerminalEditor();
private:
TerminalEditor(const TerminalEditor &);
// attributs
private:
PartTerminal *part;
QLineEdit *qle_x, *qle_y;
QComboBox *orientation;
// methodes
public slots:
void updateTerminal();
void updateTerminalX();
void updateTerminalY();
void updateTerminalO();
void updateForm();
private:
void activeConnections(bool);
};
#endif
+112
View File
@@ -0,0 +1,112 @@
/*
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 "texteditor.h"
#include "parttext.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@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;
qle_x = new QLineEdit();
qle_y = new QLineEdit();
qle_text = new QLineEdit();
font_size = new QSpinBox();
font_size -> setRange(0, 144);
qle_x -> setValidator(new QDoubleValidator(qle_x));
qle_y -> setValidator(new QDoubleValidator(qle_y));
QVBoxLayout *main_layout = new QVBoxLayout();
main_layout -> addWidget(new QLabel(tr("Position : ")));
QHBoxLayout *position = new QHBoxLayout();
position -> addWidget(new QLabel(tr("x : ")));
position -> addWidget(qle_x );
position -> addWidget(new QLabel(tr("y : ")));
position -> addWidget(qle_y );
main_layout -> addLayout(position);
QHBoxLayout *fs = new QHBoxLayout();
fs -> addWidget(new QLabel(tr("Taille : ")));
fs -> addWidget(font_size);
main_layout -> addLayout(fs);
QHBoxLayout *t = new QHBoxLayout();
t -> addWidget(new QLabel(tr("Texte : ")));
t -> addWidget(qle_text);
main_layout -> addLayout(t);
main_layout -> addStretch();
setLayout(main_layout);
updateForm();
}
/**
Destructeur
*/
TextEditor::~TextEditor() {
}
/**
Met a jour le champ de texte a partir des donnees du formulaire
*/
void TextEditor::updateText() {
part -> setProperty("size", font_size -> value());
part -> setPlainText(qle_text -> text());
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
}
/// Met a jour l'abscisse de la position du texte et cree un objet d'annulation
void TextEditor::updateTextX() { addChangePartCommand(tr("abscisse"), part, "x", qle_x -> text().toDouble()); updateForm(); }
/// Met a jour l'ordonnee de la position du texte et cree un objet d'annulation
void TextEditor::updateTextY() { addChangePartCommand(tr("ordonn\351e"), part, "y", qle_y -> text().toDouble()); updateForm(); }
/// Met a jour le texte et cree un objet d'annulation
void TextEditor::updateTextT() { addChangePartCommand(tr("texte"), part, "text", qle_text -> text()); }
/// Met a jour la taille du texte et cree un objet d'annulation
void TextEditor::updateTextS() { addChangePartCommand(tr("taille"), part, "size", font_size -> value()); }
/**
Met a jour le formulaire a partir du champ de texte
*/
void TextEditor::updateForm() {
activeConnections(false);
qle_x -> setText(part -> property("x").toString());
qle_y -> setText(part -> property("y").toString());
qle_text -> setText(part -> property("text").toString());
font_size -> setValue(part -> property("size").toInt());
activeConnections(true);
}
void TextEditor::activeConnections(bool active) {
if (active) {
connect(qle_x, SIGNAL(editingFinished()), this, SLOT(updateTextX()));
connect(qle_y, SIGNAL(editingFinished()), this, SLOT(updateTextY()));
connect(qle_text, SIGNAL(editingFinished()), this, SLOT(updateTextT()));
connect(font_size, SIGNAL(editingFinished()), this, SLOT(updateTextS()));
} else {
disconnect(qle_x, SIGNAL(editingFinished()), this, SLOT(updateTextX()));
disconnect(qle_y, SIGNAL(editingFinished()), this, SLOT(updateTextY()));
disconnect(qle_text, SIGNAL(editingFinished()), this, SLOT(updateTextT()));
disconnect(font_size, SIGNAL(editingFinished()), this, SLOT(updateTextS()));
}
}
+55
View File
@@ -0,0 +1,55 @@
/*
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 TEXT_EDITOR_H
#define TEXT_EDITOR_H
#include <QtGui>
#include "elementitemeditor.h"
class PartText;
/**
Cette classe represente un editeur de champ de texte non editable
Elle permet d'editer a travers une interface graphique les
proprietes d'un champ de texte non editable.
*/
class TextEditor : public ElementItemEditor {
Q_OBJECT
// Constructeurs, destructeur
public:
TextEditor(QETElementEditor *, PartText *, QWidget * = 0);
virtual ~TextEditor();
private:
TextEditor(const TextEditor &);
// attributs
private:
PartText *part;
QLineEdit *qle_x, *qle_y, *qle_text;
QSpinBox *font_size;
// methodes
public slots:
void updateText();
void updateTextX();
void updateTextY();
void updateTextT();
void updateTextS();
void updateForm();
private:
void activeConnections(bool);
};
#endif
+126
View File
@@ -0,0 +1,126 @@
/*
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 "textfieldeditor.h"
#include "parttextfield.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@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;
qle_x = new QLineEdit();
qle_y = new QLineEdit();
qle_text = new QLineEdit();
font_size = new QSpinBox();
font_size -> setRange(0, 144);
rotate = new QCheckBox(tr("Maintenir horizontal malgr\351\n les rotations de l'\351l\351ment"));
rotate -> setChecked(true);
qle_x -> setValidator(new QDoubleValidator(qle_x));
qle_y -> setValidator(new QDoubleValidator(qle_y));
QVBoxLayout *main_layout = new QVBoxLayout();
main_layout -> addWidget(new QLabel(tr("Position : ")));
QHBoxLayout *position = new QHBoxLayout();
position -> addWidget(new QLabel(tr("x : ")));
position -> addWidget(qle_x );
position -> addWidget(new QLabel(tr("y : ")));
position -> addWidget(qle_y );
main_layout -> addLayout(position);
QHBoxLayout *fs = new QHBoxLayout();
fs -> addWidget(new QLabel(tr("Taille : ")));
fs -> addWidget(font_size);
main_layout -> addLayout(fs);
QHBoxLayout *t = new QHBoxLayout();
t -> addWidget(new QLabel(tr("Texte par d\351faut : ")));
t -> addWidget(qle_text);
main_layout -> addLayout(t);
QHBoxLayout *r = new QHBoxLayout();
r -> addWidget(rotate);
main_layout -> addLayout(r);
main_layout -> addStretch();
setLayout(main_layout);
updateForm();
}
/// Destructeur
TextFieldEditor::~TextFieldEditor() {
}
/**
Met a jour le champ de texte a partir des donnees du formulaire
*/
void TextFieldEditor::updateTextField() {
part -> setProperty("size", font_size -> value());
part -> setPlainText(qle_text -> text());
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
part -> setFollowParentRotations(!rotate -> isChecked());
}
/// Met a jour l'abscisse de la position du champ de texte et cree un objet d'annulation
void TextFieldEditor::updateTextFieldX() { addChangePartCommand(tr("abscisse"), part, "x", qle_x -> text().toDouble()); updateForm(); }
/// Met a jour l'ordonnee de la position du champ de texte et cree un objet d'annulation
void TextFieldEditor::updateTextFieldY() { addChangePartCommand(tr("ordonn\351e"), part, "y", qle_y -> text().toDouble()); updateForm(); }
/// Met a jour le texte du champ de texte et cree un objet d'annulation
void TextFieldEditor::updateTextFieldT() { addChangePartCommand(tr("texte"), part, "text", qle_text -> text()); }
/// 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
void TextFieldEditor::updateTextFieldR() { addChangePartCommand(tr("propri\351t\351"), part, "rotate", !rotate -> isChecked()); }
/**
Met a jour le formulaire d'edition
*/
void TextFieldEditor::updateForm() {
activeConnections(false);
qle_x -> setText(part -> property("x").toString());
qle_y -> setText(part -> property("y").toString());
qle_text -> setText(part -> property("text").toString());
font_size -> setValue(part -> property("size").toInt());
rotate -> setChecked(!part -> property("rotate").toBool());
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 TextFieldEditor::activeConnections(bool active) {
if (active) {
connect(qle_x, SIGNAL(editingFinished()), this, SLOT(updateTextFieldX()));
connect(qle_y, SIGNAL(editingFinished()), this, SLOT(updateTextFieldY()));
connect(qle_text, SIGNAL(editingFinished()), this, SLOT(updateTextFieldT()));
connect(font_size, SIGNAL(editingFinished()), this, SLOT(updateTextFieldS()));
connect(rotate, SIGNAL(stateChanged(int)), this, SLOT(updateTextFieldR()));
} else {
disconnect(qle_x, SIGNAL(editingFinished()), this, SLOT(updateTextFieldX()));
disconnect(qle_y, SIGNAL(editingFinished()), this, SLOT(updateTextFieldY()));
disconnect(qle_text, SIGNAL(editingFinished()), this, SLOT(updateTextFieldT()));
disconnect(font_size, SIGNAL(editingFinished()), this, SLOT(updateTextFieldS()));
disconnect(rotate, SIGNAL(stateChanged(int)), this, SLOT(updateTextFieldR()));
}
}
+58
View File
@@ -0,0 +1,58 @@
/*
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 TEXTFIELD_EDITOR_H
#define TEXTFIELD_EDITOR_H
#include <QtGui>
#include "elementitemeditor.h"
class PartTextField;
/**
Cette classe represente un editeur de champ de texte
Elle permet d'editer a travers une interface graphique les
proprietes d'un champ de texte : taille de la police, texte par
defaut et position.
*/
class TextFieldEditor : public ElementItemEditor {
Q_OBJECT
// Constructeurs, destructeur
public:
TextFieldEditor(QETElementEditor *, PartTextField *, QWidget * = 0);
virtual ~TextFieldEditor();
private:
TextFieldEditor(const TextFieldEditor &);
// attributs
private:
PartTextField *part;
QLineEdit *qle_x, *qle_y, *qle_text;
QSpinBox *font_size;
QCheckBox *rotate;
// methodes
public slots:
void updateTextField();
void updateTextFieldX();
void updateTextFieldY();
void updateTextFieldT();
void updateTextFieldS();
void updateTextFieldR();
void updateForm();
private:
void activeConnections(bool);
};
#endif
+471
View File
@@ -0,0 +1,471 @@
/*
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 "element.h"
#include "qetapp.h"
#include "diagram.h"
#include "conductor.h"
#include "elementtextitem.h"
#include "diagramcommands.h"
#include <QtDebug>
/**
Constructeur pour un element sans scene ni parent
*/
Element::Element(QGraphicsItem *parent, Diagram *scene) :
QGraphicsItem(parent, scene),
internal_connections(false)
{
setZValue(10);
}
/**
Destructeur
*/
Element::~Element() {
}
/**
Methode principale de dessin de l'element
@param painter Le QPainter utilise pour dessiner l'elment
@param options Les options de style a prendre en compte
@param widget Le widget sur lequel on dessine
*/
void Element::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
#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", true).toBool();
if (must_correct_rendering_bug) {
Diagram *dia = diagram();
if (dia && options -> levelOfDetail == 1.0 && widget) {
// calcule la rotation qu'a subi l'element
qreal applied_rotation = 90.0 * (ori.current() - ori.defaultOrientation());
while (applied_rotation < 360.0) applied_rotation += 360.0;
while (applied_rotation > 360.0) applied_rotation -= 360.0;
if (applied_rotation == 90.0) painter -> translate(1.0, -1.0);
else if (applied_rotation == 180.0) painter -> translate(-1.0, -1.0);
else if (applied_rotation == 270.0) painter -> translate(-1.0, 1.0);
}
}
#endif
// Dessin de l'element lui-meme
paint(painter, options);
// Dessin du cadre de selection si necessaire
if (isSelected()) drawSelection(painter, options);
}
/**
@return Le rectangle delimitant le contour de l'element
*/
QRectF Element::boundingRect() const {
return(QRectF(QPointF(-hotspot_coord.x(), -hotspot_coord.y()), dimensions));
}
/**
Definit la taille de l'element sur le schema. Les tailles doivent etre
des multiples de 10 ; si ce n'est pas le cas, les dimensions indiquees
seront arrrondies aux dizaines superieures.
@param wid Largeur de l'element
@param hei Hauteur de l'element
@return La taille finale de l'element
*/
QSize Element::setSize(int wid, int hei) {
prepareGeometryChange();
// chaque dimension indiquee est arrondie a la dizaine superieure
while (wid % 10) ++ wid;
while (hei % 10) ++ hei;
// les dimensions finales sont conservees et retournees
return(dimensions = QSize(wid, hei));
}
/**
Definit le hotspot de l'element par rapport au coin superieur gauche de son rectangle delimitant.
Necessite que la taille ait deja ete definie
@param hs Coordonnees du hotspot
*/
QPoint Element::setHotspot(QPoint hs) {
// la taille doit avoir ete definie
prepareGeometryChange();
if (dimensions.isNull()) hotspot_coord = QPoint(0, 0);
else {
// les coordonnees indiquees ne doivent pas depasser les dimensions de l'element
int hsx = qMin(hs.x(), dimensions.width());
int hsy = qMin(hs.y(), dimensions.height());
hotspot_coord = QPoint(hsx, hsy);
}
return(hotspot_coord);
}
/**
@return Le hotspot courant de l'element
*/
QPoint Element::hotspot() const {
return(hotspot_coord);
}
/**
Selectionne l'element
*/
void Element::select() {
setSelected(true);
}
/**
Deselectionne l'element
*/
void Element::deselect() {
setSelected(false);
}
/**
@return La pixmap de l'element
*/
QPixmap Element::pixmap() {
if (apercu.isNull()) updatePixmap(); // on genere la pixmap si ce n'est deja fait
return(apercu);
}
/**
Permet de specifier l'orientation de l'element
@param o la nouvelle orientation de l'objet
@return true si l'orientation a pu etre appliquee, false sinon
*/
bool Element::setOrientation(QET::Orientation o) {
// verifie que l'orientation demandee est acceptee
if (!ori.accept(o)) return(false);
prepareGeometryChange();
// rotation en consequence et rafraichissement de l'element graphique
qreal rotation_value = 90.0 * (o - ori.current());
rotate(rotation_value);
ori.setCurrent(o);
update();
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
if (!eti -> followParentRotations()) {
QMatrix new_matrix = eti -> matrix();
qreal dx = eti -> boundingRect().width() / 2.0;
qreal dy = eti -> boundingRect().height() / 2.0;
new_matrix.translate(dx, dy);
new_matrix.rotate(-rotation_value);
new_matrix.translate(-dx, -dy);
eti -> setMatrix(new_matrix);
}
}
}
return(true);
}
/*** Methodes protegees ***/
/**
Dessine un petit repere (axes x et y) relatif a l'element
@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 *) {
painter -> setPen(Qt::blue);
painter -> drawLine(0, 0, 10, 0);
painter -> drawLine(7,-3, 10, 0);
painter -> drawLine(7, 3, 10, 0);
painter -> setPen(Qt::red);
painter -> drawLine(0, 0, 0, 10);
painter -> drawLine(0, 10,-3, 7);
painter -> drawLine(0, 10, 3, 7);
}
/*** Methodes privees ***/
/**
Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
@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 *) {
painter -> save();
// Annulation des renderhints
painter -> setRenderHint(QPainter::Antialiasing, false);
painter -> setRenderHint(QPainter::TextAntialiasing, false);
painter -> setRenderHint(QPainter::SmoothPixmapTransform, false);
// Dessin du cadre de selection en gris
QPen t;
t.setColor(Qt::gray);
t.setStyle(Qt::DashDotLine);
painter -> setPen(t);
// Le dessin se fait a partir du rectangle delimitant
painter -> drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10);
painter -> restore();
}
/**
Fonction initialisant et dessinant la pixmap de l'element.
*/
void Element::updatePixmap() {
// Pixmap transparente faisant la taille de base de l'element
apercu = QPixmap(dimensions);
apercu.fill(QColor(255, 255, 255, 0));
// QPainter sur la pixmap, avec antialiasing
QPainter p(&apercu);
p.setRenderHint(QPainter::Antialiasing, true);
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
// Translation de l'origine du repere de la pixmap
p.translate(hotspot_coord);
// L'element se dessine sur la pixmap
paint(&p, 0);
}
/**
Change la position de l'element en veillant a ce que l'element
reste sur la grille du Diagram auquel il appartient.
@param p Nouvelles coordonnees de l'element
*/
void Element::setPos(const QPointF &p) {
if (p == pos()) return;
// pas la peine de positionner sur la grille si l'element n'est pas sur un Diagram
if (scene()) {
// arrondit l'abscisse a 10 px pres
int p_x = qRound(p.x() / (Diagram::xGrid * 1.0)) * Diagram::xGrid;
// arrondit l'ordonnee a 10 px pres
int p_y = qRound(p.y() / (Diagram::yGrid * 1.0)) * Diagram::yGrid;
QGraphicsItem::setPos(p_x, p_y);
} else QGraphicsItem::setPos(p);
}
/**
Change la position de l'element en veillant a ce que l'element
reste sur la grille du Diagram auquel il appartient.
@param x Nouvelle abscisse de l'element
@param y Nouvelle ordonnee de l'element
*/
void Element::setPos(qreal x, qreal y) {
setPos(QPointF(x, y));
}
/**
Gere l'enfoncement d'un bouton de la souris
*/
void Element::mousePressEvent(QGraphicsSceneMouseEvent *e) {
if (!isSelected() && e -> modifiers() & Qt::ControlModifier) {
setSelected(true);
}
QGraphicsItem::mousePressEvent(e);
}
/**
Gere les mouvements de souris lies a l'element
*/
void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if (isSelected() && e -> buttons() & Qt::LeftButton) {
QPointF oldPos = pos();
setPos(mapToParent(e -> pos()) - matrix().map(e -> buttonDownPos(Qt::LeftButton)));
if (Diagram *diagram_ptr = diagram()) {
diagram_ptr -> moveElements(pos() - oldPos, this);
}
} else e -> ignore();
}
/**
Gere le relachement de souris
Cette methode a ete reimplementee pour tenir a jour la liste des elements
et conducteurs a deplacer au niveau du schema.
*/
void Element::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
Diagram *diagram_ptr = diagram();
if (diagram_ptr) {
if (!diagram_ptr -> current_movement.isNull()) {
diagram_ptr -> undoStack().push(
new MoveElementsCommand(
diagram_ptr,
diagram_ptr -> selectedContent(),
diagram_ptr -> current_movement
)
);
diagram_ptr -> current_movement = QPointF();
}
diagram_ptr -> invalidateMovedElements();
}
QGraphicsItem::mouseReleaseEvent(e);
}
/**
Permet de savoir si un element XML (QDomElement) represente bien un element
@param e Le QDomElement a valide
@return true si l'element XML est un Element, false sinon
*/
bool Element::valideXml(QDomElement &e) {
// verifie le nom du tag
if (e.tagName() != "element") return(false);
// verifie la presence des attributs minimaux
if (!e.hasAttribute("type")) return(false);
if (!e.hasAttribute("x")) return(false);
if (!e.hasAttribute("y")) return(false);
bool conv_ok;
// parse l'abscisse
e.attribute("x").toDouble(&conv_ok);
if (!conv_ok) return(false);
// parse l'ordonnee
e.attribute("y").toDouble(&conv_ok);
if (!conv_ok) return(false);
return(true);
}
/**
Methode d'import XML. Cette methode est appelee lors de l'import de contenu
XML (coller, import, ouverture de fichier...) afin que l'element puisse
gerer lui-meme l'importation de ses bornes. Ici, comme cette classe est
caracterisee par un nombre fixe de bornes, l'implementation exige de
retrouver exactement ses bornes dans le fichier XML.
@param e L'element XML a analyser.
@param table_id_adr Reference vers la table de correspondance entre les IDs
du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
ajouter les bons couples (id, adresse).
@return true si l'import a reussi, false sinon
*/
bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
/*
les bornes vont maintenant etre recensees pour associer leurs id a leur adresse reelle
ce recensement servira lors de la mise en place des fils
*/
QList<QDomElement> liste_terminals;
foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) {
if (Terminal::valideXml(qde)) liste_terminals << qde;
}
QHash<int, Terminal *> priv_id_adr;
int terminals_non_trouvees = 0;
foreach(QGraphicsItem *qgi, children()) {
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
bool terminal_trouvee = false;
foreach(QDomElement qde, liste_terminals) {
if (p -> fromXml(qde)) {
priv_id_adr.insert(qde.attribute("id").toInt(), p);
terminal_trouvee = true;
break;
}
}
if (!terminal_trouvee) ++ terminals_non_trouvees;
}
}
if (terminals_non_trouvees > 0) {
return(false);
} else {
// verifie que les associations id / adr n'entrent pas en conflit avec table_id_adr
foreach(int id_trouve, priv_id_adr.keys()) {
if (table_id_adr.contains(id_trouve)) {
// cet element possede un id qui est deja reference (= conflit)
return(false);
}
}
// copie des associations id / adr
foreach(int id_trouve, priv_id_adr.keys()) {
table_id_adr.insert(id_trouve, priv_id_adr.value(id_trouve));
}
}
// importe les valeurs des champs de texte
QList<QDomElement> inputs = QET::findInDomElement(e, "inputs", "input");
foreach(QGraphicsItem *qgi, children()) {
if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(qgi)) {
foreach(QDomElement input, inputs) eti -> fromXml(input);
}
}
// position, selection et orientation
setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
bool conv_ok;
int read_ori = e.attribute("orientation").toInt(&conv_ok);
if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = ori.defaultOrientation();
setOrientation((QET::Orientation)read_ori);
return(true);
}
/**
Permet d'exporter l'element en XML
@param document Document XML a utiliser
@param table_adr_id Table de correspondance entre les adresses des bornes
et leur id dans la representation XML ; cette table completee par cette
methode
@return L'element XML representant cet element electrique
*/
QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table_adr_id) const {
QDomElement element = document.createElement("element");
// type
QString chemin_elmt = typeId();
QString type_elmt = QETApp::symbolicPath(chemin_elmt);
element.setAttribute("type", type_elmt);
// position, selection et orientation
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 */
int id_terminal = 0;
if (!table_adr_id.isEmpty()) {
// trouve le plus grand id
int max_id_t = -1;
foreach (int id_t, table_adr_id.values()) {
if (id_t > max_id_t) max_id_t = id_t;
}
id_terminal = max_id_t + 1;
}
// enregistrement des bornes de l'appareil
QDomElement terminals = document.createElement("terminals");
// pour chaque enfant de l'element
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 ++);
terminals.appendChild(terminal);
}
}
element.appendChild(terminals);
// enregistrement des champ de texte de l'appareil
QDomElement inputs = document.createElement("inputs");
// 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);
}
/// @return le Diagram auquel cet element appartient, ou 0 si cet element est independant
Diagram *Element::diagram() const {
return(qobject_cast<Diagram *>(scene()));
}
+154
View File
@@ -0,0 +1,154 @@
/*
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/>.
*/
#ifndef ELEMENT_H
#define ELEMENT_H
#include <QtGui>
#include "terminal.h"
#include "orientationset.h"
class Diagram;
/**
Cette classe abstraite represente un element electrique.
*/
class Element : public QGraphicsItem {
// constructeurs, destructeur
public:
Element(QGraphicsItem * = 0, Diagram * = 0);
virtual ~Element();
private:
Element(const Element &);
// attributs
public:
enum { Type = UserType + 1000 };
protected:
/**
orientations de l'element :
* autorisations
* orientation en cours
* orientation par defaut
@see OrientationSet
*/
OrientationSet ori;
private:
QSize dimensions;
QPoint hotspot_coord;
QPixmap apercu;
// methodes
public:
/**
permet de caster un QGraphicsItem en Element avec qgraphicsitem_cast
@return le type de QGraphicsItem
*/
virtual int type() const { return Type; }
// methodes virtuelles pures a definir dans les classes enfants
/// @return la liste des bornes de cet element
virtual QList<Terminal *> terminals() const = 0;
/// @return la liste des conducteurs relies a cet element
virtual QList<Conductor *> conductors() const = 0;
/// @return le nombre de bornes actuel de cet element
virtual int nbTerminals() const = 0;
/// @return le nombre de bornes minimum de cet element
virtual int nbTerminalsMin() const = 0;
/// @return le nombre de bornes maximum de cet element
virtual int nbTerminalsMax() const = 0;
/**
Dessine l'element
*/
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
/// @return L'ID du type de l'element
virtual QString typeId() const = 0;
/// @return Le nom de l'element
virtual QString nom() const = 0;
Diagram *diagram() const;
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
QRectF boundingRect() const;
QSize setSize(int, int);
QPixmap pixmap();
// methodes relatives au point de saisie
QPoint setHotspot(QPoint);
QPoint hotspot() const;
// methodes relatives a la selection
void select();
void deselect();
// methodes relatives a la position
void setPos(const QPointF &);
void setPos(qreal, qreal);
// methodes relatives aux connexions internes
bool internalConnections();
void setInternalConnections(bool);
// methodes relatives aux fichiers XML
static bool valideXml(QDomElement &);
virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &);
virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
// methodes d'acces aux possibilites d'orientation
bool setOrientation(QET::Orientation o);
const OrientationSet &orientation() const;
protected:
void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
void mousePressEvent(QGraphicsSceneMouseEvent *);
void mouseMoveEvent(QGraphicsSceneMouseEvent *);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
private:
bool internal_connections;
void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
void updatePixmap();
};
/**
Permet de savoir si l'element accepte les connexions internes,
c'est-a-dire que ses bornes peuvent etre reliees entre elles
@return true si l'element accepte les connexions internes, false sinon
*/
inline bool Element::internalConnections() {
return(internal_connections);
}
/**
Permet de specifier si l'element accepte les connexions internes,
c'est-a-dire que ses bornes peuvent etre reliees entre elles
@param ic true pour que l'element accepte les connexions internes, false pour
qu'il les interdise
*/
inline void Element::setInternalConnections(bool ic) {
internal_connections = ic;
}
/**
Permet de connaitre l'orientation actuelle de l'element
@return L'orientation actuelle de l'element
*/
inline const OrientationSet & Element::orientation() const {
return(ori);
}
#endif
+62
View File
@@ -0,0 +1,62 @@
/*
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 "elementdeleter.h"
/**
Constructeur
@param elmt_path Chemin du fichier representant l'element a supprimer
@param parent QWidget parent
*/
ElementDeleter::ElementDeleter(const QString &elmt_path, QWidget *parent) :
QWidget(parent),
element_path(elmt_path)
{
}
/// Destructeur
ElementDeleter::~ElementDeleter() {
}
/**
Supprime l'element : verifie l'existence du fichier, demande confirmation a
l'utilisateur et avertit ce dernier si la suppression a echoue.
*/
void ElementDeleter::exec() {
// verifie l'existence de l'element
QFile elmt_file(element_path);
if (!elmt_file.exists()) return;
// confirmation #1
QMessageBox::StandardButton answer_1 = QMessageBox::question(
this,
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;
// supprime l'element
if (!elmt_file.remove()) {
QMessageBox::warning(
this,
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(".")
);
}
}
+44
View File
@@ -0,0 +1,44 @@
/*
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/>.
*/
#ifndef ELEMENT_DELETER_H
#define ELEMENT_DELETER_H
#include "elementscategory.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
*/
class ElementDeleter : public QWidget {
Q_OBJECT
// constructeurs, destructeur
public:
ElementDeleter(const QString &, QWidget * = 0);
virtual ~ElementDeleter();
private:
ElementDeleter(const ElementsCategory &);
// methodes
public slots:
void exec();
// attributs
private:
QString element_path;
};
#endif
@@ -0,0 +1,15 @@
<definition width="50" version="0.1" hotspot_x="25" hotspot_y="30" height="40" type="element" orientation="dnnn" >
<names>
<name lang="en" >Input</name>
<name lang="fr" >Entrée</name>
</names>
<description>
<input x="-18" y="-10" size="9" rotate="true" text="_" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="5" x1="10" y2="-5" x2="10" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-5" x1="-10" y2="5" x2="-10" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="10" y2="0" x2="24" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-24" y2="0" x2="-10" />
<terminal x="24" y="0" orientation="e" />
<terminal x="-24" y="0" orientation="w" />
</description>
</definition>
@@ -0,0 +1,16 @@
<definition width="50" version="0.1" hotspot_x="25" hotspot_y="30" height="40" type="element" orientation="dnnn" >
<names>
<name lang="en" >Input (down front)</name>
<name lang="fr" >Entrée (front descendant)</name>
</names>
<description>
<text x="-4.25" y="5.25" size="9" text="N" />
<input x="-18" y="-10" size="9" rotate="true" text="_" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="5" x1="10" y2="-5" x2="10" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-5" x1="-10" y2="5" x2="-10" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="10" y2="0" x2="24" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-24" y2="0" x2="-10" />
<terminal x="24" y="0" orientation="e" />
<terminal x="-24" y="0" orientation="w" />
</description>
</definition>
@@ -0,0 +1,16 @@
<definition width="50" version="0.1" hotspot_x="25" hotspot_y="30" height="40" type="element" orientation="dnnn" >
<names>
<name lang="en" >Input (up front)</name>
<name lang="fr" >Entrée (front montant)</name>
</names>
<description>
<text x="-3.5" y="5.25" size="9" text="P" />
<input x="-18" y="-10" size="9" rotate="true" text="_" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="5" x1="10" y2="-5" x2="10" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-5" x1="-10" y2="5" x2="-10" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="10" y2="0" x2="24" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-24" y2="0" x2="-10" />
<terminal x="24" y="0" orientation="e" />
<terminal x="-24" y="0" orientation="w" />
</description>
</definition>
@@ -0,0 +1,16 @@
<definition width="50" version="0.1" hotspot_x="25" hotspot_y="30" height="40" type="element" orientation="dnnn" >
<names>
<name lang="en" >Input (negative logic)</name>
<name lang="fr" >Entrée (NF)</name>
</names>
<description>
<line antialias="true" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="5" x1="-7" y2="-5" x2="7" />
<input x="-18" y="-10" size="9" rotate="true" text="_" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="5" x1="10" y2="-5" x2="10" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-5" x1="-10" y2="5" x2="-10" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="10" y2="0" x2="24" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-24" y2="0" x2="-10" />
<terminal x="24" y="0" orientation="e" />
<terminal x="-24" y="0" orientation="w" />
</description>
</definition>
@@ -0,0 +1,6 @@
<qet-directory>
<names>
<name lang="en" >Inputs</name>
<name lang="fr" >Entrées</name>
</names>
</qet-directory>
@@ -0,0 +1,6 @@
<qet-directory>
<names>
<name lang="en" >Outputs</name>
<name lang="fr" >Sorties</name>
</names>
</qet-directory>
@@ -0,0 +1,14 @@
<definition width="50" version="0.1" hotspot_x="25" hotspot_y="30" height="40" type="element" orientation="dnnn" >
<names>
<name lang="en" >Output</name>
<name lang="fr" >Sortie</name>
</names>
<description>
<arc width="4" x="6" y="-5" antialias="true" height="10" style="line-style:normal;line-weight:normal;filling:none;color:black" start="80" angle="-160" />
<input x="-18" y="-10" size="9" rotate="true" text="_" />
<arc width="4" x="-10" y="-5" antialias="true" height="10" style="line-style:normal;line-weight:normal;filling:none;color:black" start="-100" angle="-160" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="10" y2="0" x2="24" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-24" y2="0" x2="-10" />
<terminal x="-24" y="0" orientation="w" />
</description>
</definition>
@@ -0,0 +1,15 @@
<definition width="50" version="0.1" hotspot_x="25" hotspot_y="30" height="40" type="element" orientation="dnnn" >
<names>
<name lang="en" >Output (reset)</name>
<name lang="fr" >Sortie (reset)</name>
</names>
<description>
<text x="-4.25" y="5.25" size="9" text="R" />
<arc width="4" x="6" y="-5" antialias="true" height="10" style="line-style:normal;line-weight:normal;filling:none;color:black" start="80" angle="-160" />
<input x="-18" y="-10" size="9" rotate="true" text="_" />
<arc width="4" x="-10" y="-5" antialias="true" height="10" style="line-style:normal;line-weight:normal;filling:none;color:black" start="-100" angle="-160" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="10" y2="0" x2="24" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-24" y2="0" x2="-10" />
<terminal x="-24" y="0" orientation="w" />
</description>
</definition>
@@ -0,0 +1,15 @@
<definition width="50" version="0.1" hotspot_x="25" hotspot_y="30" height="40" type="element" orientation="dnnn" >
<names>
<name lang="en" >Output (set)</name>
<name lang="fr" >Sortie (set)</name>
</names>
<description>
<arc width="4" x="6" y="-5" antialias="true" height="10" style="line-style:normal;line-weight:normal;filling:none;color:black" start="80" angle="-160" />
<input x="-18" y="-10" size="9" rotate="true" text="_" />
<arc width="4" x="-10" y="-5" antialias="true" height="10" style="line-style:normal;line-weight:normal;filling:none;color:black" start="-100" angle="-160" />
<text x="-4.25" y="5.25" size="9" text="S" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="10" y2="0" x2="24" />
<line antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-24" y2="0" x2="-10" />
<terminal x="-24" y="0" orientation="w" />
</description>
</definition>
+6
View File
@@ -0,0 +1,6 @@
<qet-directory>
<names>
<name lang="fr">Ladder</name>
<name lang="en">Ladder</name>
</names>
</qet-directory>

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