mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-18 05:00:33 +01:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13817f9133 |
267
CREDIT
267
CREDIT
@@ -1,260 +1,17 @@
|
||||
[en]
|
||||
Thanks to Qt Software for their Qt library ( http://www.qtsoftware.com/ ), licensed under GNU/GPL.
|
||||
Thanks to Everaldo Coelho for the Crystal SVG icons theme ( http://www.iconfinder.com/iconsets/crystalproject) licensed under LGPL.
|
||||
Thanks to Nuno Pinheiro for the Oxygen icons theme ( http://www.oxygen-icons.org/ ) licensed under LGPL but also for the QElectroTech-dedicated icons.
|
||||
Thanks to the KDE project ( http://www.kde.org/ ).
|
||||
Thanks to Trolltech for their Qt library ( http://trolltech.com/ ), licensed
|
||||
under GNU/GPL.
|
||||
Thanks to Everaldo Coelho for the Crystal SVG icons theme (
|
||||
http://www.everaldo.com/crystal/ ) licensed under LGPL, and to the KDE
|
||||
project (http://www.kde.org/ ).
|
||||
Thanks to Loic for his mathematics-related explanations.
|
||||
Thanks to Remi Collet for the Fedora packaging.
|
||||
Thanks to Laurent Trinques for the Debian packaging.
|
||||
Thanks to `trem' for the Mandriva packaging.
|
||||
Thanks to TuxFamily ( http://tuxfamily.org/ ) for hosting the project.
|
||||
Thanks to `Nishiki' for his elements and his support.
|
||||
Thanks to qtcentre.org for their SingleApplication class.
|
||||
Thanks to Alfredo Carreto for his Spanish translations and fixing Spanish translations ( http://electronicosmx.net )
|
||||
Thanks to 'Dr.Slump' and Sivio for their translations in Italian
|
||||
Thanks to Jose Carlos Martins for his translations in Portuguese
|
||||
Thanks to Pavel Fric for his translations in Czech
|
||||
Thanks to Pawel Smiech for His Polish translations
|
||||
Thanks to Yuriy Litkevich for his translations into Russian
|
||||
Thanks to Youssef Ouamalkran for his translations Catatan
|
||||
Thanks to Gabi Mandoc for his translations in Romanian
|
||||
Thanks to Markus Budde and Jonas Stein and Noah Braden for his translations into German
|
||||
Thanks to Mohamed Souabni for his translations into Arabic
|
||||
Thanks to Uroš Platiše for his translations into Slovenian
|
||||
Thanks to Antun Marakovic for his translations Croatian
|
||||
Thanks to Nikos Papadopoylos && Yannis Gyftomitros their Greek translations
|
||||
Thanks to Markos Chandras for Gentoo packaging
|
||||
Thanks to David for packaging Slackware
|
||||
Thanks to Chipsterjulien for packaging Archlinux AUR packages
|
||||
Thanks to Elbert from the NL for packaging OS/2
|
||||
Thanks to zloidemon from for packaging FreeBsd (port GCC)
|
||||
Thanks to Mrbit for ebuild Gentoo packaging.
|
||||
Thanks to Nicolas for the Mac OS X Packaging.
|
||||
|
||||
[fr]
|
||||
Merci à Qt Software pour la bibliothèque Qt ( http://www.qtsoftware.com/ ), sous licence GNU/GPL.
|
||||
Merci à Everaldo Coelho pour le thème d'icônes Crystal SVG ( http://www.iconfinder.com/iconsets/crystalproject ) sous licence LGPL.
|
||||
Merci à Nuno Pinheiro pour le thème d'icônes Oxygen ( http://www.oxygen-icons.org/ ) sous licence LGPL mais aussi pour les icônes dédiées à QElectroTech
|
||||
Merci au projet KDE ( http://www.kde.org/ ).
|
||||
Merci à Trolltech pour la bibliothèque Qt ( http://trolltech.com/ ), sous
|
||||
licence GNU/GPL.
|
||||
Merci à Everaldo Coelho pour le thème d'icônes Crystal SVG (
|
||||
http://www.everaldo.com/crystal/ ) sous licence LGPL, ainsi qu'au projet KDE (
|
||||
http://www.kde.org/ ).
|
||||
Merci à Loic pour ses explications d'ordre mathématique.
|
||||
Merci à Remi Collet pour les paquets Fedora.
|
||||
Merci à Laurent Trinques pour les paquets Debian.
|
||||
Merci à `trem' pour les paquets Mandriva.
|
||||
Merci à TuxFamily ( http://tuxfamily.org/ ) pour l'hébergement du projet.
|
||||
Merci à `Nishiki' pour ses éléments et son soutien.
|
||||
Merci à qtcentre.org pour leur classe SingleApplication.
|
||||
Merci à Alfredo Carreto pour ses traductions et corrections en espagnol ( http://electronicosmx.net )
|
||||
Merci à 'Dr.Slump' et Sivio pour leurs traductions en italien
|
||||
Merci à Jose Carlos Martins pour ses traductions en portugais
|
||||
Merci à Pavel Fric pour ses traductions en Tchèque
|
||||
Merci à Pawel Smiech pour ses traductions en polonais
|
||||
Merci à Yuriy Litkevich pour ses traductions en russe
|
||||
Merci à Youssef Ouamalkran pour ses traductions en catatan
|
||||
Merci à Gabi Mandoc pour ses traductions en Roumain
|
||||
Merci à Markus Budde et Jonas Stein et Noah Braden pour ses traductions en allemand
|
||||
Merci à Mohamed Souabni pour ses traductions en arabe
|
||||
Merci à Uroš Platiše pour ses traductions en Slovene
|
||||
Merci à Antun Marakovic pour ses traductions Croate
|
||||
Merci à Nikos Papadopoylos && Yannis Gyftomitros pour leurs traductions en grec
|
||||
Merci à Markos Chandras pour les paquets Gentoo
|
||||
Merci à David les paquets Slackware
|
||||
Merci à Chipsterjulien les paquets Archlinux AUR packages
|
||||
Merci à Elbert from the NL les paquets OS/2
|
||||
Merci à Zloidemon from for les paquets (port GCC)
|
||||
Merci à Mrbit for ebuild les paquets Gentoo
|
||||
|
||||
[ru]
|
||||
Спасибо Qt Software за их библиотеку Qt ( http://www.qtsoftware.com/ ), лицензированную на условиях GNU/GPL.
|
||||
Спасибо Everaldo Coelho за тему значков Crystal SVG ( http://www.iconfinder.com/iconsets/crystalproject ) лицензированную на условиях LGPL.
|
||||
Спасибо Nuno Pinheiro за тему значков Oxygen ( http://www.oxygen-icons.org/ ) лицензированную на условиях LGPL, а также за значки связанные с QElectroTech.
|
||||
Спасибо проекту KDE ( http://www.kde.org/ ).
|
||||
Спасибо Loic за объяснения связанные с математикой.
|
||||
Спасибо Remi Collet за пакет для Fedora.
|
||||
Спасибо Laurent Trinques за пакет для Debian.
|
||||
Спасибо `trem' за пакет для Mandriva.
|
||||
Спасибо TuxFamily ( http://tuxfamily.org/ ) за хостинг для проекта.
|
||||
Спасибо `Nishiki' за элементы и поддержку.
|
||||
Спасибо qtcentre.org за их класс SingleApplication.
|
||||
Спасибо Alfredo Carreto за исправления и перевод на испанский ( http://electronicosmx.net )
|
||||
Спасибо 'Dr.Slump' за исправления и перевод
|
||||
|
||||
[pt]
|
||||
Agradecimentos a Qt Software pela sua biblioteca Qt ( http://www.qtsoftware.com/ ), licenciada de acordo com a GNU/GPL.
|
||||
Agradecimentos a Everaldo Coelho pelo tema de ícones Crystal SVG ( http://www.iconfinder.com/iconsets/crystalproject ), licenciado de acordo com a LGPL.
|
||||
Agradecimentos a Nuno Pinheiro pelo tema de ícones Oxygen e em especial pelos ícones dedicados ao programa QElectroTech ( http://www.oxygen-icons.org/ ), lincenciado de acordo com a LGPL.
|
||||
Agradecimentos ao projecto KDE ( http://www.kde.org/ ).
|
||||
Agradecimentos a Loic pelas suas explicações relacionadas com problemas matemáticos.
|
||||
Agradecimentos a Remi Collet pela criação dos pacotes para Fedora.
|
||||
Agradecimentos a Laurent Trinques pela criação dos pacotes para Debian.
|
||||
Agradecimentos a "trem" pela criação dos pacotes para Mandriva.
|
||||
Agradecimentos a TuxFamily ( http://tuxfamily.org/ ) por albergarem este projecto.
|
||||
Agradecimentos a "Nishiki" pela criação de elementos e o seu suporte.
|
||||
Agradecimentos a qtcentre.org pela classe SingleApplication.
|
||||
Agradecimentos a Alfredo Carreto pela tradução para Espanhol e pela correcção de traduções em Espanhol ( http://electronicosmx.net ).
|
||||
Agradecimentos a 'Dr.Slump'pela tradução para italiano
|
||||
|
||||
[es]
|
||||
Agradecimientos a Qt Software por su biblioteca Qt ( http://www.qtsoftware.com/ ), licenciada bajo GNU/GPL.
|
||||
Agradecimientos a Everaldo Coelho por el tema de icónos Crystal SVG ( http://www.iconfinder.com/iconsets/crystalproject ), licenciado bajo LGPL.
|
||||
Agradecimientos a Nuno Pinheiro por el tema de icónos Oxygen y especialmente por los icónos dedicados al programa QElectroTech ( http://www.oxygen-icons.org/ ), licenciado bajo LGPL.
|
||||
Agradecimientos al proyecto KDE ( http://www.kde.org/ ).
|
||||
Agradecimientos a Loic por sus explicaciones relacionadas con problemas matemáticos.
|
||||
Agradecimientos a Remi Collet por criación de paquetes para Fedora.
|
||||
Agradecimientos a Laurent Trinques por la creación de paquetes para Debian.
|
||||
Agradecimientos a "trem" por creación de paquetes para Mandriva.
|
||||
Agradecimientos a TuxFamily ( http://tuxfamily.org/ ) por el alojamiento de este proyecto.
|
||||
Agradecimientos a "Nishiki" por creación de elementos e de su suporte.
|
||||
Agradecimientos a qtcentre.org por classe SingleApplication.
|
||||
Agradecimientos a Alfredo Carreto por sus traducciones en español y correcciones de traducción en español ( http://electronicosmx.net)
|
||||
Agradecimientos a 'Dr.Slump' por sus traducciones en italiano
|
||||
|
||||
[cs]
|
||||
Díky Qt Software za jejich knihovnu Qt ( http://www.qtsoftware.com/ ), pod licencí GNU/GPL.
|
||||
Díky Everaldovi Coelho za téma Crystal SVG icons theme ( http://www.iconfinder.com/iconsets/crystalproject ) pod licencí LGPL.
|
||||
Díky Nunovi Pinheirovi za téma ikon Oxygen ( http://www.oxygen-icons.org/ ) pod licencí LGPL ale také za ikony věnované QElectroTech.
|
||||
Díky projektu KDE ( http://www.kde.org/ ).
|
||||
Díky Loicovi za jeho vysvětlení vztahující se k matematice.
|
||||
Díky Remi Colletovi za balíček pro Fedoru.
|
||||
Díky Laurentu Trinquesovi za balíček pro Debian.
|
||||
Díky `trem' za balíček pro Mandrivu.
|
||||
Díky TuxFamily ( http://tuxfamily.org/ ) za poskytování hostingu pro projekt.
|
||||
Díky `Nishiki' za jeho prvky a jeho podporu.
|
||||
Díky qtcentre.org za jejich třídu SingleApplication.
|
||||
Poděkování Alfredovi Carretovi za jeho španělský překlad a opravy španělského překladu ( http://electronicosmx.net )
|
||||
Dìky 'Dr.Slump' za jeho italianský překlad
|
||||
|
||||
[pl]
|
||||
Podziękowania dla Qt Software, za biblioteki Qt (http://www.qtsoftware.com/) na licencji GNU / GPL.
|
||||
Podziękowania dla Everaldo Coelho, za ikony Crystal SVG ( http://www.iconfinder.com/iconsets/crystalproject) na licencji LGPL.
|
||||
Podziękowania dla Nun Pinheiro, za ikony Oxygen (http://www.oxygen-icons.org/) na licencji LGPL, a także za ikony przeznaczone do projektu QElectroTech.
|
||||
Podziękowania dla projektu KDE (http://www.kde.org/).
|
||||
Podziękowania dla Loic, za pomoc w rozwiązaniu problemów matematycznych.
|
||||
Podziękowania dla Remi Collet, za pakiety dla Fedory.
|
||||
Podziękowania dla Laurent Trinquesovi, za pakiety dla Debiana.
|
||||
Podziękowania dla "trem", za pakiety dla Mandrivy.
|
||||
Podziękowania dla TuxFamily (http://tuxfamily.org/), za organizację projektu.
|
||||
Podziękowanie dla "Nishiki", zajego elementy i poparcie.
|
||||
Podziękowania dla qtcentre.org, za klasę SingleApplication.
|
||||
Podziękowania dla Alfredo Carreto, za jego tłumaczenie na język hiszpański i korektę ( http://electronicosmx.net)
|
||||
|
||||
[it]
|
||||
Grazie a Qt Software per le loro librerie Qt (http://www.qtsoftware.com/), licenzate sotto GNU/GPL.
|
||||
Grazie a Everaldo Coelho per il tema icone Crystal SVG ( http://www.iconfinder.com/iconsets/crystalproject) licenzato sotto LGPL.
|
||||
Grazie a Nuno Pinheiro per il tema icone Oxygen (http://www.oxygen-icons.org/) licenzato sotto LGPL ma anche per le icone dedicate a QElectroTech.
|
||||
Grazie al progetto KDE (http://www.kde.org/).
|
||||
Grazie a Loic per le sue spiegazioni matematiche.
|
||||
Grazie a Remi Collet per i pacchetti per Fedora.
|
||||
Grazie a Laurent Trinques per i pacchetti per Debian.
|
||||
Grazie a `trem' per i pacchetti per Mandriva.
|
||||
Grazie a TuxFamily (http://tuxfamily.org/) per l'ospitalità al progetto.
|
||||
Grazie a `Nishiki' per i suoi elementi ed il supporto.
|
||||
Grazie a qtcentre.org per la loro classe SingleApplication.
|
||||
Grazie a Alfredo Carreto per le traduzioni e le correzioni in spagnolo (http://electronicosmx.net).
|
||||
Grazie a 'Dr.Slump' e 'Silvio' per la traduzione in italiano.
|
||||
Grazie a Jose Carlos Martins per la traduzione in portoghese.
|
||||
Grazie a Pavel Fric per la traduzione in ceco.
|
||||
Grazie a Pawel Smiech per la traduzione in polacco.
|
||||
Grazie a Yuriy Litkevich per la traduzione in russo .
|
||||
Grazie a Youssef Ouamalkran per la traduzione in catalano.
|
||||
Grazie a Gabi Mandoc per la traduzione in rumeno.
|
||||
Grazie a Markus Budde e Jonas Stein per la traduzione in tedesco.
|
||||
Grazie a Mohammed Souabni per la traduzione in arabo.
|
||||
Grazie a Uroš Platiše per la traduzione in sloveno.
|
||||
Grazie a Antun Marakovic per la traduzione in croato.
|
||||
Grazie a Nikos Papadopoylos e Yannis Gyftomitros per la traduzione in greco.
|
||||
Grazie a Markos Chandras per i pacchetti per Gentoo.
|
||||
|
||||
[el]
|
||||
Ευχαριστίες στην Qt Software για την βιβλιοθήκη Qt ( http://www.qtsoftware.com/ ), αδειοδοτημένο ως GNU/GPL.
|
||||
Ευχαριστίες στον Everaldo Coelho για τα εικονίδια του θέματος Crystal SVG ( http://www.iconfinder.com/iconsets/crystalproject) αδειοδοτημένο ως LGPL.
|
||||
Ευχαριστίες to Nuno Pinheiro για τα εικονίδια του θέματος Oxygen ( http://www.oxygen-icons.org/ ) αδειοδοτημένο ως LGPL και επίσης για τα εικονίδια ειδικά για το QElectroTech.
|
||||
Ευχαριστίες στο έργο KDE ( http://www.kde.org/ ).
|
||||
Ευχαριστίες στον Loic για τις εξηγήσεις σχετικές με μαθηματικά.
|
||||
Ευχαριστίες στον Remi Collet για τα πακέτα Fedora.
|
||||
Ευχαριστίες στον Laurent Trinques για τα πακέτα Debian.
|
||||
Ευχαριστίες στον `trem' για τα πακέτα Mandriva.
|
||||
Ευχαριστίες στο TuxFamily ( http://tuxfamily.org/ ) για τη φιλοξενία του έργου.
|
||||
Ευχαριστίες στον `Nishiki' για τα στοιχεία και την υποστήριξη του.
|
||||
Ευχαριστίες στο qtcentre.org για την κλάση SingleApplication.
|
||||
Ευχαριστίες στον Alfredo Carreto για τις μεταφράσεις του και για την επισκευή της Ισπανικής μετάφρασης ( http://electronicosmx.net )
|
||||
Ευχαριστίες στον 'Dr.Slump' και τον Sivio για τις μεταφράσεις τους στα Ιταλικά
|
||||
Ευχαριστίες στον Jose Carlos Martins για την μετάφραση στα Πορτογαλικά
|
||||
Ευχαριστίες στον Pavel Fric Για την μετάφραση στα Τσέχικα
|
||||
Ευχαριστίες στον Pawel Smiech για την Πολωνική μετάφραση
|
||||
Ευχαριστίες στον Yuriy Litkevich για τις μεταφράσεις του στα Ρώσικα
|
||||
Ευχαριστίες στον Youssef Ouamalkran για τις μεταφράσεις του στα Καταλανικά
|
||||
Ευχαριστίες στον Gabi Mandoc για τις μεταφράσεις του στα Ρουμανικά
|
||||
Ευχαριστίες στους Markus Budde και Jonas Stein για τις μεταφράσεις τους στα Γερμανικά
|
||||
Ευχαριστίες στον Mohamed Souabni για τις μεταφράσεις του στα Αραβικά
|
||||
Ευχαριστίες στον Uroš Platiše για τις μεταφράσεις του στα Σλοβένικα
|
||||
Ευχαριστίες στον Antun Marakovic για τις μεταφράσεις του στα Κροατικά
|
||||
Ευχαριστίες στους Νίκο Παπαδόπουλο και Γιάννη Γυφτομήτρο για τις μεταφράσεις τους στα Ελληνικά
|
||||
Ευχαριστίες στον Markos Chandras για τα πακέτα Gentoo
|
||||
Ευχαριστίες στον David για τα πακέτα Slackware
|
||||
Ευχαριστίες στον Chipsterjulien για τα πακέτα Archlinux AUR
|
||||
Ευχαριστίες στον Elbert για τα πακέτα OS/2
|
||||
Ευχαριστίες στον zloidemon για τα πακέτα FreeBsd (port GCC)
|
||||
Ευχαριστίες στον Mrbit για τα πακέτα ebuild για Gentoo.
|
||||
|
||||
[nl]
|
||||
Dank aan Qt Software voor hun Qt library ( http://www.qtsoftware.com/ ) , onder de GNU / GPL licentie .
|
||||
Dank aan Everaldo Coelho voor de Crystal SVG iconen thema ( http://www.iconfinder.com/iconsets/crystalproject ) gelicenseerd onder LGPL .
|
||||
Dank aan Nuno Pinheiro voor de Oxygen iconen thema ( http://www.oxygen-icons.org/ ) gelicenseerd onder LGPL maar ook voor de QElectroTech -dedicated iconen.
|
||||
Dank aan het KDE-project ( http://www.kde.org/ ) .
|
||||
Dank aan Loic voor zijn wiskunde - gerelateerde verklaringen .
|
||||
Met dank aan Remi Collet voor de Fedora pakket.
|
||||
Met dank aan Laurent Trinques voor de Debian pakket.
|
||||
Dank aan ` tremolo ' voor de Mandriva pakket.
|
||||
Dank aan TuxFamily ( http://tuxfamily.org/ ) voor het hosten van het project .
|
||||
Dank aan ` Nishiki ' voor zijn elementen en zijn steun .
|
||||
Dank aan qtcentre.org voor hun SingleApplication klasse .
|
||||
Dank aan Alfredo Carreto voor zijn Spaanse vertalingen en tot vaststelling Spaanse vertalingen ( http://electronicosmx.net )
|
||||
Dank aan ' Dr.Slump ' en Sivio voor hun vertalingen in het Italiaans
|
||||
Met dank aan Jose Carlos Martins voor zijn vertalingen in het Portugees
|
||||
Met dank aan Pavel Fric voor zijn vertalingen in het Tsjechisch
|
||||
Dank aan Pawel miech voor zijn Poolse vertalingen
|
||||
Dank aan Yuriy Litkevich voor zijn vertalingen in het Russisch
|
||||
Dank aan Youssef Ouamalkran voor zijn vertalingen Catatan
|
||||
Met dank aan Gabi Mandoc voor zijn vertalingen in het Roemeens
|
||||
Dank aan Markus Budde en Jonas Stein en Noah Braden voor zijn vertalingen in het Duits
|
||||
Met dank aan Mohamed Souabni voor zijn vertalingen in het Arabisch
|
||||
Dank aan Uro ? Plati ? E voor zijn vertalingen in het Sloveens
|
||||
Dank aan Antun Marakovic voor zijn vertalingen Kroatisch
|
||||
Dank aan Nikos Papadopoylos && Yannis Gyftomitros hun Griekse vertalingen
|
||||
Dank aan Markos Chandras voor Gentoo pakket
|
||||
Met dank aan David voor het verpakken van Slackware
|
||||
Dank aan Chipsterjulien voor het verpakken van Archlinux AUR pakketten
|
||||
Dank aan Elbert uit de NL voor het pakket van OS/2
|
||||
Dank aan zloidemon voor het verpakken van FreeBSD ( poort GCC )
|
||||
Dank aan Mrbit voor ebuild Gentoo pakket.
|
||||
|
||||
[be]
|
||||
Dank aan Qt Software bibliotheek voor Qt ( http://www.qtsoftware.com/ ), onder licentie van GNU/GPL.
|
||||
Dank aan Everaldo Coelho voor het pictogram thema Crystal SVG ( http://www.iconfinder.com/iconsets/crystalproject )onder licentie van licence LGPL.
|
||||
Dank aan Nuno Pinheiro voor het pictogram thema Oxygen ( http://www.oxygen-icons.org/ ) onder licentie van LGPL maar ook voor de iconen opgedragen aan QElectroTech
|
||||
Dank aan project KDE ( http://www.kde.org/ ).
|
||||
Dank aan Loic voor zijn uitleg van de mathematische orde.
|
||||
Dank aan Remi Collet voor de pakketten Fedora.
|
||||
Dank aan Laurent Trinques voor de pakkette Debian.
|
||||
Dank aan `trem' voor de pakketten Mandriva.
|
||||
Dank aan TuxFamily ( http://tuxfamily.org/ ) voor het hosten van het project.
|
||||
Dank aan `Nishiki' voor zijn elementen en ondersteuning.
|
||||
Dank aan qtcentre.org voor hun SingleApplication klasse.
|
||||
Dank aan Alfredo Carreto voor zijn vertalingen en correcties in het Spaans ( http://electronicosmx.net )
|
||||
Dank aan 'Dr.Slump' en Sivio hun vertaling in het Italiaans
|
||||
Dank aan Jose Carlos Martins voor zijn vertalingen in het Portugees
|
||||
Dank aan Pavel Fric voor zijn vertalingen in het Tsjechisch
|
||||
Dank aan Pawel Smiech voor zijn vertaling in het Pools
|
||||
Dank aan Yuriy Litkevich voor zijn vertalingen in het Russisch
|
||||
Dank aan Youssef Ouamalkran voor zijn vertalingen Catatan
|
||||
Dank aan Gabi Mandoc voor zijn vertalingen in het Roemeens
|
||||
Dank aan Markus Budde en Jonas Stein et Noah Braden voor hun vertaling in het Duitse
|
||||
Dank aan Mohamed Souabni voor zijn vertalingen in het Arabisch
|
||||
Dank aan Uroš Platiše zijn onze vertalingen Sloveense
|
||||
Dank aan Antun Marakovic voor zijn vertalingen Kroatisch
|
||||
Dank aan Nikos Papadopoylos en Yannis Gyftomitros hun vertalingen in het Grieks
|
||||
Dank aan Markos Chandras voor de pakkette Gentoo
|
||||
Dank aan David voor de pakkette Slackware
|
||||
Dank aan Chipsterjulien voor de pakkette Archlinux AUR
|
||||
Dank aan Elbert voor de pakkette OS/2
|
||||
Dank aan Zloidemon fvoor de pakkette (port GCC)
|
||||
Dank aan Mrbit van ebuild voor de pakkette Gentoo
|
||||
Merci à Nicolas pour le packaging pour Mac OS X.
|
||||
|
||||
269
ChangeLog
269
ChangeLog
@@ -1,269 +0,0 @@
|
||||
====== ChangeLog from 0.5 to 0.6 ======
|
||||
In the official collection, there are now 4081 elements, and 539 categoris for a total of 4620 files
|
||||
|
||||
* Improved performance, added multithreading to speed up the loading of items when launching QET.
|
||||
* RAM consumption has been considerably reduced.
|
||||
* New "collections" panel.
|
||||
* Automatic numberings (autonum), Variables and prefix.
|
||||
* Folio generator
|
||||
* Management Policy
|
||||
* New thickness properties for conductors.
|
||||
* The thickness of the lines of all basic shapes (lines, rectangles, ellipses, polygons) can be changed from 0,2px to 50,0px.
|
||||
* The color of lines and fillings of basic shapes can be choosed from a color palette or set with a html color code.
|
||||
* Added Copy/paste from another project.
|
||||
* Online documentation and links to download the latest packages of the version under development for Windows and MacOS are available directly from the software.
|
||||
* Resetting the layout of the summary pages.
|
||||
* In the panel left split the view into a several docks.
|
||||
* High-DPI support (Qt 5.6.0)
|
||||
* new python plugin to generate terminal block.
|
||||
|
||||
|
||||
====== ChangeLog from 0.4 to 0.5 ======
|
||||
In the official collection, there are now 2625 elements, and 418 catégoris for a total of 3043 files.
|
||||
|
||||
* Port to Qt 5 framework
|
||||
* New QSettings native format for config files.
|
||||
* In the diagram editor, the grid is not displayed by default outside the diagram, the minimum zoom is blocked. A button allows you to un-validate this operation.
|
||||
* It is now possible to put the tittle block on the right vertical mode.
|
||||
* The default tittle block can be defined for the next folios of the project.
|
||||
* The summary now takes the font set in the QElectroTech.conf
|
||||
* The floating dock is now operational, variables, actions are taken into account on the fly.
|
||||
* A transformation tool transforms quickly and finely each primitive by handles.
|
||||
* Add UUID tag for element XML.
|
||||
* The database enables faster loading a large number of managing symbols in tables changes pixmaps collections, it no longer compares the modification date of the files but their use UUID attributes to update the cache .
|
||||
* In terms of basic shapes, the transform tool works directly on vectors, it replaces the reduction tool / enlargement that has just been deleted as unnecessary.
|
||||
* Improve Undo command by QPropertyUndoCommand class.
|
||||
|
||||
|
||||
|
||||
====== ChangeLog from 0.3 to 0.4 ======
|
||||
In the official collection, there are now 2298 elements, and 376 catégoris for a total of 2674 files.
|
||||
|
||||
* We have removed the flag '-fno-ipa-sra "This settled the compilation problems on Mac OS X and FreeBSD clang.
|
||||
* The official collection has been redesigned, through the work of Nuri a new structure is in place.
|
||||
* A menu has been added, allowing you to change the application language.
|
||||
* we added a summary creation tool.
|
||||
* Added button "export the nomenclature" transforms data from diagrams to CSV file for spreadsheet.
|
||||
Arun wrote a detailed manual in English.
|
||||
* New tools have been added, they can create mechanical connections and draw cabinets, desks, junction boxes, or areas on the schematic (line tool, rectangle, ellipse, polygon type: respect for style dashes).
|
||||
* An aid in positioning cross, drawing, was added.
|
||||
* The locked state images and basic forms (basic shapes) is now stored in the project.
|
||||
* The "control" during the movement of an element, text field disables snapping to the grid, for free positioning.
|
||||
It is now possible to choose the background folios in white or gray.
|
||||
* Add supports trackpad gestures (multitouch).
|
||||
The dates of the cartridges are now using the short system date and date format according to the language detected setting in the OS.
|
||||
We take advantage of the transition to standard C ++ 11, and a big cleanup in the code was done.
|
||||
* The undo action or redo the undo stack are now animated graphically.
|
||||
When the action save, save as, the status bar displays the name and path of the backup job.
|
||||
Qet is now able to come to load a style sheet (stylesheet) directly from the conf directory.
|
||||
* A DXF export has been added, the entire project folios can be exported in this format.
|
||||
* Added reports folio, Cross references.
|
||||
* Added a variable font size for text of conductors.
|
||||
* Added new properties to all conductors at the same potential, even through referrals.
|
||||
* When several conductors have the same value potential equalization, it is not useful to display on all conductors.
|
||||
* Added button to activates the automatic connection of the conductors of the element when moving it.
|
||||
* Numbering rules are now available for the entire project.
|
||||
Qet detects the Windows version and applies the appropriate graphic style, depending on the version of Windows.
|
||||
|
||||
|
||||
====== ChangeLog from 0.3 rc to 0.3 ======
|
||||
First, the collection of symbols has made a big step forward, with about 1560 new elements.
|
||||
There are now symbols for pneumatics, hydraulics, process, solar, cold, etc. Considerable effort has been done to organize the collection in a better way.
|
||||
We hope that the new organisation is clearer for all. We would like to thank all the contributors who send us symbols.
|
||||
|
||||
=====-Element Editor: =====
|
||||
Considerable work has be done to replace the manual defining zone of the symbol, aka hotspot.And fix bugs, It is now automatic. You do not have to care about it anymore.
|
||||
Primary colors have been added for the drawing shapes.
|
||||
A contextual menu (right click) has been added. So, you can now work more quickly with symbols. It is also more user-friendly.
|
||||
|
||||
====== ChangeLog from v0.3 rc ======
|
||||
|
||||
=====-Element Editor: =====
|
||||
* Replacing checkboxes with lists of colors.
|
||||
* Removed the manual hotspot, it is now automatic and you do not have to worry.
|
||||
Officially Collection: a large classification work on the structure was realized. It should be clear to everyone.
|
||||
The collection is enriched with 1711 items in 286 categories (ie 1997 files)
|
||||
|
||||
=====-Schema Editor:=====
|
||||
* Added import image, image rotation, image resizing and saving the file in the project.
|
||||
(Double click on the image called a widget and cursor that reduce or enlarge the selected image.)
|
||||
NB: Following the "edit image" entry will also be added in the right click menu.
|
||||
* F5 keyboard shortcut can recharge symbol collections.
|
||||
Some bugs have been resolved, and the translation status continues to grow.
|
||||
|
||||
|
||||
======ChangeLog from v0.3 beta ======
|
||||
Two more items for the changelog:
|
||||
* In the official collection, there are now 1672 elements and 256 categoris for a total of 1928 files. In version 0.3 alpha, there were 1465 elements and 233 categories, while version 0.22 had153 elements and 51 categories.
|
||||
|
||||
*Progress in the translation (see http://qelectrotech.org/wiki/doc/translation/stats for current state)
|
||||
* Functions (edit element and find in panel) have been moved to the context
|
||||
Here is the changelog, for version 0.3 beta:
|
||||
* Functions (edit element and find in panel) have been moved to the context menu, that can be accessed with right click. This is more user friendly.
|
||||
* Refresh of categories when an element is moved.
|
||||
* DateNow button added in the "Diagram property" dialog.
|
||||
* Dotted lines can now been added between conductors.
|
||||
* Rich text can be added to the diagram text fields.
|
||||
[screenshot]
|
||||
* HTML WYSIWYG editor for rich text: bold, italic, underlined, font size from 6 to 72 pixels, font colour, etc.
|
||||
* You can change between the two modes(Selection mode <-> View mode) with the scroll button.
|
||||
* Symbol editor: focus on the new value for language, languages sorted in alphabetical order.
|
||||
* Added a widget that reflects the loading of a big project.
|
||||
* Automated numbering of conductors according to your rules. See note from Joshua http://qelectrotech.org/wiki/doc/autonum
|
||||
* Added a dialog to automatically rotate the text if the associated conductor is vertical or horizontal. Parameters are saved in qelectrotech.conf
|
||||
* Added basic colours on the tools for lines and for the filling of the primitives, and also for the style line and point in the element editor.
|
||||
* Added several protection to prevent from saving an element if one of its primitive is beyond the hotspot.
|
||||
|
||||
|
||||
====== ChangeLog from 0.22 to 0.3a ======
|
||||
|
||||
===== Application =====
|
||||
|
||||
Elements collection: QElectroTech now provides 1465 elements within 233 categories (0.22 provided 153 elements within 51 categories). Most elements are related to electricity though some relate to chillers, solar, hydraulic and pneumatic engineering.
|
||||
A new kind of collections appeared to store title block templates; as for elements, there is a distinction between common (system-wide) templates and custom (user-wide) templates.
|
||||
Translations:
|
||||
English, Spanish, French, Portuguese and Czech translations have been maintained.
|
||||
Russian translations have been removed because they are not maintained anymore.
|
||||
Polish, German, Italian, Arabic and Croatian translations have been added.
|
||||
Following translation to Arabic, some work was done to improve Right-To-Left languages support.
|
||||
Elements names are fully translated to English, French, Czech and Polish.
|
||||
Main windows: added a “What's this?” action.
|
||||
QElectroTech now handles *.titleblock files.
|
||||
|
||||
===== Diagram editor =====
|
||||
|
||||
It is now possible to move and rotate all texts on a diagram : element texts, conductor texts and independent texts.
|
||||
When moving a text related to an electrical element, this element is highlighted.
|
||||
Texts related to a conductor cannot be moved too far away from it.
|
||||
It is now possible to create diagrams with more than 100 rows/columns.
|
||||
Elements panel:
|
||||
During a drag and drop operation, the hovered item is now expanded after a short time not moving the mouse.
|
||||
Items are now expanded/collapsed by a double click.
|
||||
Common, custom and embedded collections of title block templates are displayed within the elements panel.
|
||||
Elements previews and names are now cached into a SQLite database stored in the user configuration directory, thus speeding up the elements panel (re)loading
|
||||
The elements panel now displays the folio index before each diagram title.
|
||||
UI consistency: renamed “Import element” to “Open an element file”, separated this action from those related to the current selection, and ensured elements-related actions are disabled when selecting a project/diagram/title block template.
|
||||
Freshly integrated elements are now highlighted in the elements panel – this behaviour can be disabled though.
|
||||
When clearing the search field, the panel state is restored to its previous state.
|
||||
Title blocks are now rendered using templates:
|
||||
For each diagram, users can choose the template to be used in the diagram properties.
|
||||
They may also drag and drop it from the elements panel to the diagram.
|
||||
Title block templates are always integrated within the parent project.
|
||||
Fixed a bug in the print preview dialog.
|
||||
Added a F2 shortcut for the widget “Edit the color of the given conductor”.
|
||||
As elements, diagrams now have a “version” attribute for compatibility purposes.
|
||||
Better handling of file opening for documents saved with newer versions of QElectroTech.
|
||||
Diagram loading: removed an optimization that could lead to conductors not being loaded when several terminals share the same coordinates.
|
||||
Users may now enter visualisation mode by pressing Ctrl and Shift.
|
||||
Printing: when printing diagrams with no title block, use the space left by the title block.
|
||||
Added a few status and “What's this?” tips.
|
||||
Got rid of the green icon used for projects, changed a few other icons.
|
||||
|
||||
===== Element editor =====
|
||||
|
||||
Both static and dynamic texts can now be rotated
|
||||
Added “dotted” line style
|
||||
Added white color for texts
|
||||
Newly added parts are placed above existing ones.
|
||||
|
||||
===== Title block template editor =====
|
||||
|
||||
A third kind of editor was implemented so users can create their own title block templates:
|
||||
|
||||
It allows users to customize the layout and content of cells that constitute the title block.
|
||||
Cells can be merged and splitted.
|
||||
Their width can be fixed, relative to the total width or relative to the remaining widths.
|
||||
Their height is a simple fixed length.
|
||||
They contain either a logo (be it in SVG or a usual bitmap format) or some text.
|
||||
The text value is optionally preceded by a label.
|
||||
As other texts within QElectroTech, labels and texts can be translated to other languages.
|
||||
Texts and labels may contain variables (e.g. %company-name); these variables are replaced by real world values once the template is applied to a diagram.
|
||||
Those real-world values can be set among the diagram properties.
|
||||
|
||||
|
||||
====== Changelog 0.11 -> 0.2 ======
|
||||
À partir de la version 0.2, QElectroTech est disponible en français, anglais, mais aussi :
|
||||
* en espagnol, grâce aux traductions de Youssef ;
|
||||
* en russe, grâce aux traductions de Yuriy ;
|
||||
* en portugais, grâce aux traductions de José.
|
||||
L'application utilise désormais le thème d'icônes Oxygen, réalisé par Nuno Pinheiro pour le projet KDE.
|
||||
|
||||
===== Notion de fichier projet =====
|
||||
Un fichier .qet peut désormais contenir zéro, un ou plusieurs schémas électriques. Les éléments composant ces schémas sont embarqués dans le fichier projet au moment où ils sont posés sur un schéma. Le panel d'éléments affiche donc désormais :
|
||||
* les projets ouverts, avec, sous chaque projet :
|
||||
* les schémas de ce projet,
|
||||
* la collection embarquée du projet (catégories et éléments utilisés dans les schémas)
|
||||
* la collection commune fournie par QET,
|
||||
* et la collection personnelle de l'utilisateur.
|
||||
|
||||
===== Éditeur de schémas =====
|
||||
* Il est désormais possible de déplacer et copier les catégories et éléments par simple glisser-déposer (drag'n drop) dans le panel d'éléments.
|
||||
* La collection embarquée est manipulable au même titre que la collection utilisateur. Les éléments inutilisés dans le projet apparaissent sur fond rouge et un dialogue permet de les purger rapidement.
|
||||
* Chaque projet embarque également (au niveau de ses propriétés) les paramétrages par défaut pour les nouveaux schémas, cartouches et conducteurs.
|
||||
* Il est possible de changer l'ordre des schémas dans le projet en déplaçant les onglets qui les représente. Dans le champ "Folio" des cartouches, on peut se référer à la position du schéma courant ou au nombre total de schémas dans le projet en écrivant respectivement %id et %total.
|
||||
* Lors du chargement d'un fichier .qet, si des éléments ne sont pas trouvés, ils sont remplacés par un élément "fantôme", ce qui évite de perdre certaines informations lors de l'enregistrement du fichier.
|
||||
* Le rendu avec un zoom réduit a été amélioré.
|
||||
* Enfin, le logiciel gère l'ouverture en lecture seule d'un fichier projet.
|
||||
|
||||
==== Impression et export ====
|
||||
|
||||
À partir de la version 0.2, QElectroTech :
|
||||
* propose d'utiliser une imprimante réelle ou bien de générer un document PDF ou PostScript, et ce sous Windows comme sous X11.
|
||||
* génère un aperçu avant l'impression d'un projet. Cet aperçu permet de choisir les options d'impression mais également les schémas à imprimer ou non.
|
||||
|
||||
À noter toutefois une limitation pour les impressions PDF/PS sous Windows : le dialogue de mise en page, permettant de spécifier le format du papier ainsi que ses marges, n'est pas disponible.
|
||||
|
||||
Le dialogue "Exporter" (pour générer un fichier image d'un schéma) a également été refait dans l'optique d'un export simultané de tous les schémas du projet.
|
||||
|
||||
===== Éditeur d'éléments =====
|
||||
|
||||
* Lorsque l'on dessine une ligne dans l'éditeur d'éléments, il est possible de choisir un embout différent pour chaque extrémité, comme par exemple une flèche, un cercle, un carré ou, tout simplement, un bout de ligne normal.
|
||||
* La forme "Rectangle" a été ajoutée.
|
||||
* On peut enregistrer un élément en désignant un fichier (= comportement en 0.11) ou bien en choisissant un élément cible dans une liste reprenant l'arborescence du panel d'éléments.
|
||||
* Si l'on maintient la touche Shift lorsque l'on ajoute une partie (droite, cercle, texte, ...), l'outil en cours est conservé après le dessin. Sinon l'éditeur repasse sur l'outil de sélection.
|
||||
* La grille a été améliorée : sa densité varie en fonction du zoom ; les points correspondant à ceux de la grille de l'éditeur de schémas sont mis en valeur.
|
||||
* L'accrochage à la grille (aka "snap to grid", également connu sous le nom de grille magnétique ou encore grille aimantée) a été ajouté. Le dessin s'y accroche désormais avec une précision de 1px. On peut travailler en coordonnées libres en maintenant la touche Ctrl enfoncée durant le dessin.
|
||||
* Le copier-coller a été implémenté : il est possible de coller :
|
||||
* avec le bouton du milieu de la souris
|
||||
* en choisissant une "zone de collage" sur l'élément (Ctrl+Shift+V)
|
||||
* directement (Ctrl+V) : les parties collées sont placées à côté des parties copiées ; si on recolle les parties, elles sont collées encore un cran à côté, et ce de manière incrémentale.
|
||||
* Des contrôles sont désormais effectués à l'enregistrement : présence de bornes, respect du cadre, etc.
|
||||
* Uniformisation des menus par rapport à l'éditeur de schémas
|
||||
|
||||
====== Changelog 0.1 -> 0.11 ======
|
||||
|
||||
===== Fonctionnalités et interface =====
|
||||
|
||||
* L'application est désormais capable d'ouvrir un fichier élément passe en paramètre
|
||||
* L'application se lance désormais une seule fois par utilisateur
|
||||
* Lors de l'ouverture d'un fichier en dehors de l'application alors que QET est déjà démarré celui-ci essaye de s'afficher ou d'attirer l'attention de l'utilisateur.
|
||||
* L'application vérifie que ce fichier n'est pas déjà ouvert dans tous les éditeurs de schémas / éléments.
|
||||
* Ajout de fichiers permettant d'automatiser les associations de fichiers sous Windows (.bat et .reg) et X11 (.desktop et .xml)
|
||||
* Ajout de menus "Récemment ouverts" pour accéder aux fichiers récents dans les éditeurs de schémas et éléments.
|
||||
* Ajout d'un splash screen
|
||||
* La hauteur du schéma est désormais gérée via un système de lignes, dont le nombre et la hauteur sont ajustables.
|
||||
* Il est également possible d'afficher ou non les en-têtes des lignes et/ou des colonnes.
|
||||
* Ajout d'une option --lang-dir
|
||||
* Ajout d'une description dans le dialogue des options d'impression
|
||||
* Ajout de pages de manuel Unix (`man') en anglais et en français
|
||||
|
||||
===== Corrections de bugs =====
|
||||
|
||||
* Bug #12 : QET provoquait une erreur de segmentation dès son démarrage dans un environnement sans systray
|
||||
* Bug #14 : il manquait un / dans le chemin proposé lors de l'impression vers un PDF
|
||||
* Bug #15 : Mauvais positionnement des champs de texte sur le schéma
|
||||
* Bug #16 : Mauvaise gestion des modifications du texte d'un conducteur
|
||||
* La classe DiagramView écrivait sur la sortie d'erreur sans fin de ligne
|
||||
* L'option --config-dir était mal prise en compte
|
||||
* Après fermeture d'un schema, le menu Fenêtres n'était pas correctement mis à jour
|
||||
* Les textes des éléments, des conducteurs, du cartouche ainsi que les textes indépendants utilisent désormais tous la même police.
|
||||
* Remise à niveau de l'impression suite au passage à Qt 4.4
|
||||
|
||||
===== Code et détails techniques =====
|
||||
|
||||
* Corrections pour que QET compile avec gcc-4.3
|
||||
* Les classes Conductor et Element héritent désormais de QObject (dépendance sur Qt 4.4)
|
||||
* Affinage du constructeur de la classe QETApp
|
||||
* Moins d'avertissements à la compilation (testé avec gcc 4.3)
|
||||
* Moins d'inclusions non pertinentes
|
||||
* Nettoyage du trunk : déplacement des sources dans un sous-répertoire
|
||||
177
ELEMENTS.LICENSE
177
ELEMENTS.LICENSE
@@ -1,177 +0,0 @@
|
||||
[en]
|
||||
The elements collection provided along with QElectroTech is provided as is and
|
||||
without any warranty of fitness for your purpose or working.
|
||||
The usage, the modification and the integration of the elements into electric
|
||||
diagrams is allowed without any condition, whatever the final license of the
|
||||
diagrams is.
|
||||
If you redistribute all or a part of the QElectroTech collection, with or
|
||||
without any modification, out of an electric diagram, you must respect the
|
||||
conditions of the CC-BY license:
|
||||
This work is licensed under the Creative Commons Attribution 3.0 License.
|
||||
To view a copy of this license, visit
|
||||
http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
|
||||
[fr]
|
||||
La collection d'éléments fournie avec QElectroTech est fournie telle quelle et
|
||||
sans la moindre garantie qu'elle convienne à votre utilisation ou qu'elle
|
||||
fonctionne.
|
||||
L'utilisation, la modification et l'intégration des éléments dans des schémas
|
||||
électriques est autorisée sans condition, quelle que soit la licence finale des
|
||||
schémas.
|
||||
Si vous redistribuez tout ou partie de la collection QElectroTech, avec ou sans
|
||||
modification, en dehors d'un schéma électrique, vous devrez respecter les
|
||||
conditions de la licence CC-BY :
|
||||
Cette création est mise à disposition selon le Contrat Paternité 3.0
|
||||
disponible en ligne http://creativecommons.org/licenses/by/3.0/ ou par
|
||||
courrier postal à Creative Commons, 171 Second Street, Suite 300, San Francisco,
|
||||
California 94105, USA.
|
||||
|
||||
[ru]
|
||||
Коллекция элементов, поставляемая вместе с QElectroTech, поставляется "как есть"
|
||||
и без каких-либо гарантий пригодности для той или иной цели или работы.
|
||||
Использование, изменение и интеграция элементов в электрическую
|
||||
схему разрешается без каких-либо условий, безотносительно конечной лицензии на
|
||||
схему.
|
||||
Если Вы распространяете всю или часть коллекции QElectroTech, с или без
|
||||
изменений, отдельно от электрической схемы, Вы должны соблюдать условия лицензии
|
||||
CC-BY:
|
||||
Эта работа лицензирована на условиях Creative Commons Attribution 3.0 License.
|
||||
Чтобы увидеть копию этой лицензии, посетите
|
||||
http://creativecommons.org/licenses/by/3.0/ или отправте письмо в Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
(данный перевод, на русский язык, является вольным и выполнен не юристом!)
|
||||
|
||||
[pt]
|
||||
A colecção de elementos fornecida com o programa QElectroTech é fornecida como é
|
||||
e sem nenhuma garantia da aptidão para o seu uso e sem garantia de que funciona.
|
||||
É permitido, sem condição alguma, qualquer que seja a licença final, usar,
|
||||
editar e incluir estes elementos em esquemas eléctricos.
|
||||
Se você redistribuir uma parte ou toda a colecção de elementos do programa
|
||||
QElectroTech, tendo editado ou não os elementos, sem ser num esquema eléctrico,
|
||||
tem de respeitar as condições da licença CC-BY:
|
||||
Este trabalho está licenciado de acordo com os termos da licença Creative
|
||||
Commons Attribution 3.0 License.
|
||||
Para ver uma cópia da licença visite http://creativecommons.org/licenses/by/3.0/
|
||||
ou envie uma carta para o endereço Creative Commons, 171 Second Street, Suite
|
||||
300, San Francisco, California, 94105, USA.
|
||||
|
||||
[es]
|
||||
La colección de elementos QElectrotech es distruibida tal cual y sin ninguna
|
||||
garantía a la conveniencia de su uso y sin garantía de que funciona.
|
||||
Se permite sin condicion alguna, cualquiera que sea la licencia final, usar,
|
||||
editar, e incluir estos elementos en esquemas eléctricos.
|
||||
Si usted redistribuye una parte de la colección o toda la collección de
|
||||
QElectrotech, con o sin ediciones, fuera de un esquema eléctrico, tiene que
|
||||
respetar las condiciones de la licencia CC-BY:
|
||||
Esta obra está bajo una licencia Reconocimiento 3.0 de Creative Commons.
|
||||
Para ver una copia de esta licencia, visite
|
||||
http://creativecommons.org/licenses/by/3.0/ o envie una carta a Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.
|
||||
|
||||
[ca]
|
||||
La col·lecció de símbols QElectrotech és distribuïda tal qual i sense cap
|
||||
garantia d'idoneïtat d'ús ni de funcionament.
|
||||
Es permet incondicionalment, amb independència de la llicència final, emprar,
|
||||
editar, i incloure aquests símbols en esquemes elèctrics.
|
||||
Si vostè redistribueix una part de la col·lecció de QElectrotech o tota ella,
|
||||
amb condicions o sense, separadament d'un esquema elèctric, haurà de respectar
|
||||
les condicions de la llicència CC-BY:
|
||||
Aquesta obra es troba sota una llicència Reconeixement 3.0 de Creative Commons.
|
||||
Per veure una còpia d'aquesta llicència visiti
|
||||
http://creativecommons.org/licenses/by/3.0/ o enviï una carta a Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California 94105,
|
||||
|
||||
[cs]
|
||||
Sbírka prvků poskytovaná společně s QElectroTechem je poskytována tak, jak je,
|
||||
bez záruky nebo vhodnosti pro váš účal nebo práci.
|
||||
Používání, úpravy a začlenění prvků do nákresů elektrických
|
||||
obvodů se povoluje bez jakýchkoli podmínek, cokoli je konečná licence nákresu.
|
||||
Pokud rozdáte celou nebo část ze sbírky QElectroTechu, s nebo bez
|
||||
jakýchkoli úprav, mimo elektrický nákres, musíte brát ohledy na podmínky
|
||||
licence CC-BY:
|
||||
tato práce je licencována pod licencí Creative Commons Attribution 3.0 License.
|
||||
Kopii této licence si můžete prohlédnout, navštivte
|
||||
http://creativecommons.org/licenses/by/3.0/ nebo pošlete dopis Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
|
||||
[pl]
|
||||
Biblioteka elementów dostarczana wraz z QElectroTech jest w formie "taka jaka jest",
|
||||
bez żadnych gwarancji przydatności.
|
||||
Dozwolona jest edycja, modyfikacja i użytkowanie elementów bez żadnych warunków
|
||||
i bez względu na końcową licencję tworzonych schematów.
|
||||
W przypadku wykorzystywania całości lub części biblioteki elementów QElectroTech
|
||||
do innych celów niż tworzenie schematów elektrycznych, należy przestrzegać
|
||||
warunków licencji CC-BY:
|
||||
Niniejsza praca jest licencjonowana na zasadach Creative Commons Attribution 3.0 License.
|
||||
Aby zobaczyć kopię licencji, należy odwiedzić stronę internetową:
|
||||
http://creativecommons.org/licenses/by/3.0/ lub wysłać list do Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, Kalifornia 94105, USA.
|
||||
|
||||
[it]
|
||||
La collezione di elementi che si trova in QElectroTech è fornita così com'è
|
||||
senza alcuna garanzia di usabilità o funzionamento.
|
||||
L'uso, la modifica e l'integrazione degli elementi negli schemi elettrici
|
||||
è permessa senza condizioni, qualunque si ala licenza dello schema finale.
|
||||
Distribuendo tutto o parte della collezione di QElettroTech, con o senza
|
||||
modifiche, fuori da uno schema elettrico, bisogna rispettare le condizioni
|
||||
della licenza CC-BY:
|
||||
Questo lavoro è licenziato sotto la Licenza Creative Commons 3.0.
|
||||
Per vedere una copia di questa licenza, visitate il sito
|
||||
http://creativecommons.org/licenses/by/3.0/ o inviate una lettera a Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
|
||||
[el]
|
||||
Η συλλογή στοιχείων που παρέχεται μαζί με το QElectroTech παρέχεται ως έχει και
|
||||
χωρίς καμία εγγύηση καταλληλότητας για συγκεκριμένο σκοπό ή την εργασία σας.
|
||||
Η χρήση, η τροποποίηση και η ενσωμάτωση των στοιχείων στα ηλεκτρικά
|
||||
διαγράμματα επιτρέπεται χωρίς καμία προϋπόθεση, όποια και αν είναι η τελική άδεια
|
||||
των διαγραμμάτων.
|
||||
Εάν αναδιανείμετε το σύνολο ή ένα μέρος της συλλογής του QElectroTech, με ή
|
||||
χωρίς καμία τροποποίηση, έξω από ένα ηλεκτρικό διάγραμμα, θα πρέπει να σεβαστείτε
|
||||
τους όρους της άδειας CC-BY:
|
||||
Το έργο αυτό είναι υπό την άδεια Creative Commons Attribution 3.0 License.
|
||||
Για να δείτε ένα αντίγραφο της άδειας αυτής, επισκεφτείτε το
|
||||
http://creativecommons.org/licenses/by/3.0/ ή στείλτε μια επιστολή στο Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
|
||||
[nl]
|
||||
|
||||
De elementen collectie voorzien, samen met QElectroTech wordt geleverd als en
|
||||
zonder enige garantie van geschiktheid voor uw doel of werk.
|
||||
Het gebruik, de wijziging en de integratie van de elementen in elektrische
|
||||
diagrammen wordt toegestaan zonder enige voorwaarden, ongeacht wat de uiteindelijke
|
||||
vergunning van het diagram is.
|
||||
Als u alle of een deel van de QElectroTech collectie, met of herdistribueren
|
||||
zonder enige wijziging, van een elektrisch schema, moet u voldoen aan de
|
||||
voorwaarden van de CC-BY-licentie:
|
||||
Dit werk is gelicenseerd onder de Creative Commons Attribution 3.0-licentie.
|
||||
Om een kopie van deze licentie te bekijken, bezoek
|
||||
http://creativecommons.org/licenses/by/3.0/ of stuur een brief naar Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
|
||||
[be]
|
||||
|
||||
De elementen collectie welke samen met QElectroTech wordt geleverd zonder enige garantie
|
||||
of deze geschikt zijn voor uw doel of de werking.
|
||||
Het gebruik, wijzigen en integratie van de elementen in uw elektrische
|
||||
schema's wordt toegestaan zonder enige voorwaarden, ongeacht wat de uiteindelijke
|
||||
liventie van het schema is.
|
||||
Als u één of meerdere elementen van de QElectroTech collectie, met of zonder wijzigingen, herdistribuer in een elektrisch schema of zonder schzma , moet u de voorwaarden van de
|
||||
CC-BY-licentie volgen:
|
||||
Dit werk is gelicenseerd onder de Creative Commons Attribution 3.0-licentie.
|
||||
Om een kopie van deze licentie te bekijken, bezoek
|
||||
http://creativecommons.org/licenses/by/3.0/ of stuur een brief naar Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
|
||||
[da]
|
||||
Element samlinger leveret sammen med QElectroTech er tilvejebragt som er og
|
||||
uden nogen garanti for egnethed til dit formål eller arbejde.
|
||||
Brug, modifikation og integration af elementer til elektrisk diagrammer er
|
||||
tilladt uden nogen betingelse uanset den endelige diagram licens.
|
||||
Omfordeling af hele eller dele af QElectroTech samlingen, med eller
|
||||
uden ændring af et elektrisk diagram, skal du respektere betingelser for CC-BY-licens:
|
||||
Dette værk er licenseret under Creative Commons Attribution 3.0 License.
|
||||
For at se en kopi af denne licens, besøg
|
||||
http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
131
INSTALL
131
INSTALL
@@ -1,142 +1,19 @@
|
||||
[en]
|
||||
Requirements :
|
||||
libQt5 (see packages libqt5*)
|
||||
libQt4 (see packages libqt4*)
|
||||
cupsys-bsd for printing
|
||||
|
||||
Howto compile :
|
||||
$ qmake (qmake-qt5 for Debian-based systems)
|
||||
$ qmake (qmake-qt4 for Debian-based systems)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[fr]
|
||||
Pré-requis :
|
||||
libQt5 (paquets libqt5*)
|
||||
libQt4 (paquets libqt4*)
|
||||
cupsys-bsd pour l'impression
|
||||
|
||||
Comment compiler :
|
||||
$ qmake (qmake-qt5 pour les systèmes basés sur Debian)
|
||||
$ qmake (qmake-qt4 pour les systèmes basés sur Debian)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[ru]
|
||||
Зависимости:
|
||||
libQt5 (пакет libqt5*)
|
||||
cupsys-bsd для печати
|
||||
|
||||
Как компилировать?:
|
||||
$ qmake (qmake-qt5 для систем основанных на Debian)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[pt]
|
||||
Dependências:
|
||||
libQt5 (ver pacotes libqt5*)
|
||||
cupsys-bsd para impressão
|
||||
|
||||
Como compilar:
|
||||
$ qmake (qmake-qt5 para sistemas baseados em Debian)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[es]
|
||||
Dependencias:
|
||||
libQt5 (paquetes libqt5*)
|
||||
cupsys-bsd para imprimir
|
||||
|
||||
Cómo compilar:
|
||||
$ qmake (qmake-qt5 para los sistemas basados en Debian)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[ca]
|
||||
Dependències:
|
||||
libQt5 (paquets libqt5*)
|
||||
cupsys-bsd per imprimir
|
||||
|
||||
Com compilar:
|
||||
$ qmake (qmake-qt5 pels sistemes basats en Debian)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[cs]
|
||||
Požadavky :
|
||||
libQt5 (viz balíček libqt5*)
|
||||
cupsys-bsd kvůli tisku
|
||||
|
||||
Jak program sestavit :
|
||||
$ qmake (qmake-qt5 u systémů založených na Debianu)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[pl]
|
||||
Zależności:
|
||||
libQt5 (pakiety libqt5 *)
|
||||
cupsys-bsd do druku
|
||||
|
||||
Sposób kompilacji:
|
||||
$ qmake (qmake-qt5 dla systemów opartych na Debianie)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[it]
|
||||
Dipendenze:
|
||||
libQt5 (vedi pacchetti libqt5*)
|
||||
cupsys-bsd per la stampa
|
||||
|
||||
Come compilare:
|
||||
$ qmake (qmake-qt5 per sistemi basati su Debian)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[el]
|
||||
Απαιτήσεις:
|
||||
libQt5 (δείτε για πακέτα libqt5*)
|
||||
cupsys-bsd για εκτύπωση
|
||||
|
||||
Πως να το μεταγλωττίσετε:
|
||||
$ qmake (qmake-qt5 για συστήματα βασισμένα σε Debian)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[nl]
|
||||
vereisten:
|
||||
libqt5 (zie pakketten libqt5 *)
|
||||
cupsys-bsd om af te drukken
|
||||
|
||||
Hoe te compileren:
|
||||
$ Qmake (qmake-qt5 voor Debian-gebaseerde systemen)
|
||||
$ make
|
||||
# Umask 0022
|
||||
# Make install
|
||||
|
||||
[be]
|
||||
Vereisten:
|
||||
libQt5 (pakketten libqt5*)
|
||||
cupsys-bsd voor het afdrukken
|
||||
|
||||
Hoe te compileren :
|
||||
$ qmake (qmake-qt5 voor systemen op basis van Debian)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[da]
|
||||
Krav:
|
||||
libQt5 (se pakke libqt5*)
|
||||
cupsys-bsd til udskrivning
|
||||
|
||||
Hvordan man kompilerer:
|
||||
$ qmake (qmake-qt5 for Debian baserede systemer)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
50
README
50
README
@@ -1,47 +1,9 @@
|
||||
[en]
|
||||
QElectroTech is a Qt5 application to design electric diagrams.
|
||||
It uses XML files for elements and diagrams, and includes both a diagram editor, a element editor, and an titleblock editor.
|
||||
QElectroTech is a Qt4 application to design electric diagrams. It uses XML
|
||||
files for elements and diagrams, and includes both a diagram editor and an
|
||||
element editor.
|
||||
|
||||
[fr]
|
||||
QElectroTech est une application Qt5 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, un éditeur d'élément, ainsi qu'un editeur de cartouche.
|
||||
|
||||
[ru]
|
||||
QElectroTech - приложение написанное на Qt5 и предназначенное для разработки электрических схем.
|
||||
Оно использует XML-файлы для элементов и схем, и включает, как редактор схем, так и редактор элементов.
|
||||
|
||||
[pt]
|
||||
QElectroTech é uma aplicação baseada em Qt5 para desenhar esquemas eléctricos.
|
||||
QET utiliza ficheiros XML para os elementos e para os esquemas e inclui um editor de esquemas e um editor de elementos.
|
||||
|
||||
[es]
|
||||
QElectroTech es una aplicación Qt5 para diseñar esquemas eléctricos.
|
||||
Utiliza archivos XML para los elementos y esquemas, e incluye un editor de esquemas y un editor de elementos.
|
||||
|
||||
[cs]
|
||||
QElectroTech je aplikací Qt5 určenou pro návrh nákresů elektrických obvodů.
|
||||
Pro prvky a nákresy používá soubory XML, a zahrnuje v sobě jak editor nákresů, tak editor prvků.
|
||||
|
||||
[pl]
|
||||
QElectroTech to aplikacja napisana w Qt5, przeznaczona do tworzenia schematów elektrycznych.
|
||||
Wykorzystuje XML do zapisywania plików elementów i projektów. Posiada edytor schematów i elementów.
|
||||
|
||||
[it]
|
||||
QElectroTech è una applicazione fatta in Qt5 per disegnare schemi elettrici.
|
||||
QET usa il formato XML per i suoi elementi e schemi, includendo anche un editor per gli stessi.
|
||||
|
||||
[el]
|
||||
Το QElectroTech είναι μια εφαρμογή Qt5 για σχεδίαση ηλεκτρικών διαγραμμάτων.
|
||||
Χρησιμοποιεί αρχεία XML για στοιχεία και διαγράμματα, και περιλαμβάνει επεξεργαστή διαγραμμάτων καθώς και επεξεργαστή στοιχείων.
|
||||
|
||||
[nl]
|
||||
QElectroTech is een Qt5 applicatie om elektrische schema's te ontwerpen.
|
||||
Het maakt gebruik van XML-bestanden voor elementen en diagrammen, en omvat zowel een diagram bewerker, een element bewerker, en een bloksjabloon bewerker.
|
||||
|
||||
[be]
|
||||
QElectroTech is een Qt5 toepassing voor het maken en beheren van elektrische schema's.
|
||||
QET gebruikt XML voor de elementen en schema's en omvat een schematische editor, itemeditor, en een titel sjabloon editor.
|
||||
|
||||
[da]
|
||||
QElectroTech er et Qt5 program til at redigere elektriske diagrammer.
|
||||
Det bruger XML filer for symboler og diagrammer og inkluderer diagram, symbol og titelblok redigering.
|
||||
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
aboutqet.cpp
Normal file
138
aboutqet.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
Copyright 2006-2008 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "aboutqet.h"
|
||||
#include "qet.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param parent Le QWidget parent de la boite de dialogue
|
||||
*/
|
||||
AboutQET::AboutQET(QWidget *parent) : QDialog(parent) {
|
||||
// Titre, taille, comportement...
|
||||
setWindowTitle(tr("\300 propos de QElectrotech"));
|
||||
setMinimumWidth(680);
|
||||
setMinimumHeight(350);
|
||||
setModal(true);
|
||||
|
||||
// Trois onglets
|
||||
QTabWidget *onglets = new QTabWidget(this);
|
||||
onglets -> addTab(ongletAPropos(), tr("\300 &propos"));
|
||||
onglets -> addTab(ongletAuteurs(), tr("A&uteurs"));
|
||||
onglets -> addTab(ongletLicence(), tr("&Accord de licence"));
|
||||
|
||||
// Un bouton pour fermer la boite de dialogue
|
||||
QDialogButtonBox *boutons = new QDialogButtonBox(QDialogButtonBox::Close);
|
||||
connect(boutons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(boutons, SIGNAL(rejected()), this, SLOT(accept()));
|
||||
|
||||
// Le tout dans une disposition verticale
|
||||
QVBoxLayout *disposition = new QVBoxLayout();
|
||||
disposition -> addWidget(titre());
|
||||
disposition -> addWidget(onglets);
|
||||
disposition -> addWidget(boutons);
|
||||
setLayout(disposition);
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
AboutQET::~AboutQET() {
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le titre QElectroTech avec son icone
|
||||
*/
|
||||
QWidget *AboutQET::titre() const {
|
||||
QWidget *icone_et_titre = new QWidget();
|
||||
// icone
|
||||
QLabel *icone = new QLabel();
|
||||
icone -> setPixmap(QIcon(":/ico/qelectrotech.png").pixmap(48, 48));
|
||||
// label "QElectroTech"
|
||||
QLabel *titre = new QLabel("<span style=\"font-weight:0;font-size:16pt;\">QElectroTech v" + QET::version + "</span>");
|
||||
titre -> setTextFormat(Qt::RichText);
|
||||
// le tout dans une grille
|
||||
QGridLayout *dispo_horiz = new QGridLayout();
|
||||
dispo_horiz -> addWidget(icone, 0, 0);
|
||||
dispo_horiz -> addWidget(titre, 0, 1);
|
||||
dispo_horiz -> setColumnStretch(0, 1);
|
||||
dispo_horiz -> setColumnStretch(1, 100);
|
||||
icone_et_titre -> setLayout(dispo_horiz);
|
||||
return(icone_et_titre);
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le widget contenu par l'onglet <20> A propos <20>
|
||||
*/
|
||||
QWidget *AboutQET::ongletAPropos() const {
|
||||
QLabel *apropos = new QLabel(
|
||||
tr("QElectroTech, une application de r\351alisation de sch\351mas \351lectriques.") +
|
||||
"<br><br>" +
|
||||
tr("\251 2006-2008 Les d\351veloppeurs de QElectroTech") +
|
||||
"<br><br>"
|
||||
"<a href=\"http://qelectrotech.tuxfamily.org/\">"
|
||||
"http://qelectrotech.tuxfamily.org/</a>"
|
||||
);
|
||||
apropos -> setAlignment(Qt::AlignCenter);
|
||||
apropos -> setOpenExternalLinks(true);
|
||||
apropos -> setTextFormat(Qt::RichText);
|
||||
return(apropos);
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le widget contenu par l'onglet <20> Auteurs <20>
|
||||
*/
|
||||
QWidget *AboutQET::ongletAuteurs() const {
|
||||
QLabel *auteurs = new QLabel(
|
||||
"<span style=\"text-decoration: underline;\">" +
|
||||
tr("Id\351e originale") +
|
||||
"</span> : Beno\356t Ansieau "
|
||||
"<<a href=\"mailto:benoit.ansieau@gmail.com\">"
|
||||
"benoit.ansieau@gmail.com</a>>"
|
||||
"<br><br>"
|
||||
"<span style=\"text-decoration: underline;\">" +
|
||||
tr("Programmation") +
|
||||
"</span> : Xavier Guerrin "
|
||||
"<<a href=\"mailto:xavier.guerrin@gmail.com\">"
|
||||
"xavier.guerrin@gmail.com</a>>"
|
||||
);
|
||||
auteurs -> setAlignment(Qt::AlignCenter);
|
||||
auteurs -> setOpenExternalLinks(true);
|
||||
auteurs -> setTextFormat(Qt::RichText);
|
||||
return(auteurs);
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le widget contenu par l'onglet <20> Accord de Licence <20>
|
||||
*/
|
||||
QWidget *AboutQET::ongletLicence() const {
|
||||
QWidget *licence = new QWidget();
|
||||
// label
|
||||
QLabel *titre_licence = new QLabel(tr("Ce programme est sous licence GNU/GPL."));
|
||||
|
||||
// texte de la GNU/GPL dans une zone de texte scrollable non editable
|
||||
QTextEdit *texte_licence = new QTextEdit();
|
||||
texte_licence -> setPlainText(QET::license());
|
||||
texte_licence -> setReadOnly(true);
|
||||
|
||||
// le tout dans une disposition verticale
|
||||
QVBoxLayout *dispo_licence = new QVBoxLayout();
|
||||
dispo_licence -> addWidget(titre_licence);
|
||||
dispo_licence -> addWidget(texte_licence);
|
||||
licence -> setLayout(dispo_licence);
|
||||
return(licence);
|
||||
}
|
||||
43
aboutqet.h
Normal file
43
aboutqet.h
Normal 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
|
||||
<09> A propos de QElectroTech <20>
|
||||
*/
|
||||
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
borderinset.cpp
Normal file
231
borderinset.cpp
Normal 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
borderinset.h
Normal file
182
borderinset.h
Normal 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
conductor.cpp
Normal file
1279
conductor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
141
conductor.h
Normal file
141
conductor.h
Normal 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
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
Copyright 2006-2008 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -16,9 +16,8 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "conductorprofile.h"
|
||||
#include "qetgraphicsitem/conductor.h"
|
||||
#include "conductor.h"
|
||||
#include "conductorsegmentprofile.h"
|
||||
#include "terminal.h"
|
||||
|
||||
/// Constructeur
|
||||
ConductorProfile::ConductorProfile() {
|
||||
@@ -101,7 +100,7 @@ qreal ConductorProfile::height() const{
|
||||
@param type Type de Segments
|
||||
@return Le nombre de segments composant le conducteur.
|
||||
*/
|
||||
uint ConductorProfile::segmentsCount(QET::ConductorSegmentType type) const {
|
||||
uint ConductorProfile::nbSegments(QET::ConductorSegmentType type) const {
|
||||
if (type == QET::Both) return(segments.count());
|
||||
uint nb_seg = 0;
|
||||
foreach(ConductorSegmentProfile *csp, segments) {
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
Copyright 2006-2008 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -22,34 +22,34 @@
|
||||
class Conductor;
|
||||
class ConductorSegmentProfile;
|
||||
/**
|
||||
This class represents the profile of a conductor, i.e. its primary
|
||||
characteristics.
|
||||
Cette classe contient le profil (= les caracteristiques essentielles) d'un
|
||||
conducteur.
|
||||
*/
|
||||
class ConductorProfile {
|
||||
public:
|
||||
// constructors, destructor
|
||||
// constructeurs, destructeur
|
||||
ConductorProfile();
|
||||
ConductorProfile(Conductor *conductor);
|
||||
ConductorProfile(const ConductorProfile &);
|
||||
ConductorProfile &operator=(const ConductorProfile &);
|
||||
virtual ~ConductorProfile();
|
||||
|
||||
// attributes
|
||||
// attributs
|
||||
public:
|
||||
/// Segments composing the conductor
|
||||
/// Segment composant le profil du conducteur
|
||||
QList<ConductorSegmentProfile *> segments;
|
||||
/// Orientation of the start terminal
|
||||
Qet::Orientation beginOrientation;
|
||||
/// Orientation of the end terminal.
|
||||
Qet::Orientation endOrientation;
|
||||
/// Orientation de la borne de depart du profil
|
||||
QET::Orientation beginOrientation;
|
||||
/// Orientation de la borne d'arrivee du profil
|
||||
QET::Orientation endOrientation;
|
||||
|
||||
// methods
|
||||
// methodes
|
||||
public:
|
||||
bool isNull() const;
|
||||
void setNull();
|
||||
qreal width() const;
|
||||
qreal height() const;
|
||||
uint segmentsCount(QET::ConductorSegmentType) const;
|
||||
uint nbSegments(QET::ConductorSegmentType) const;
|
||||
QList<ConductorSegmentProfile *> horizontalSegments();
|
||||
QList<ConductorSegmentProfile *> verticalSegments();
|
||||
void fromConductor(Conductor *);
|
||||
319
conductorproperties.cpp
Normal file
319
conductorproperties.cpp
Normal 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
conductorproperties.h
Normal file
100
conductorproperties.h
Normal 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
conductorpropertieswidget.cpp
Normal file
210
conductorpropertieswidget.cpp
Normal 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
conductorpropertieswidget.h
Normal file
73
conductorpropertieswidget.h
Normal 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
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
Copyright 2006-2008 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -493,8 +493,8 @@ bool ConductorSegment::hasNextSegment() const {
|
||||
QPointF ConductorSegment::middle() const {
|
||||
return(
|
||||
QPointF(
|
||||
(point1.x()+ point2.x()) / 2.0,
|
||||
(point1.y()+ point2.y()) / 2.0
|
||||
(point1.x() + point2.x()) / 2.0,
|
||||
(point1.y() + point2.y()) / 2.0
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
Copyright 2006-2008 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -20,11 +20,11 @@
|
||||
#include <QPointF>
|
||||
#include "qet.h"
|
||||
/**
|
||||
This class represents a conductor segment.
|
||||
Cette classe represente un segment de conducteur.
|
||||
*/
|
||||
class ConductorSegment {
|
||||
|
||||
// constructors, destructor
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
ConductorSegment(const QPointF &, const QPointF &, ConductorSegment * = NULL, ConductorSegment * = NULL);
|
||||
virtual ~ConductorSegment();
|
||||
@@ -32,14 +32,14 @@ class ConductorSegment {
|
||||
private:
|
||||
ConductorSegment(const ConductorSegment &);
|
||||
|
||||
// attributes
|
||||
// attributs
|
||||
private:
|
||||
ConductorSegment *previous_segment;
|
||||
ConductorSegment *next_segment;
|
||||
QPointF point1;
|
||||
QPointF point2;
|
||||
|
||||
// methods
|
||||
// methodes
|
||||
public:
|
||||
void moveX(const qreal &);
|
||||
void moveY(const qreal &);
|
||||
61
conductorsegmentprofile.h
Normal file
61
conductorsegmentprofile.h
Normal 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
configdialog.cpp
Normal file
105
configdialog.cpp
Normal 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);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
Copyright 2006-2008 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -18,46 +18,39 @@
|
||||
#ifndef CONFIG_DIALOG_H
|
||||
#define CONFIG_DIALOG_H
|
||||
#include <QDialog>
|
||||
class ConfigPage;
|
||||
#include "configpages.h"
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
class QStackedWidget;
|
||||
class QDialogButtonBox;
|
||||
/**
|
||||
This class represents the configuration dialog for QElectroTech.
|
||||
It displays "configuration pages", each page having to provide an icon and
|
||||
a title.
|
||||
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
|
||||
// constructors, destructor
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
ConfigDialog(QWidget * = 0);
|
||||
virtual ~ConfigDialog();
|
||||
private:
|
||||
ConfigDialog(const ConfigDialog &);
|
||||
|
||||
public:
|
||||
QList<ConfigPage *> pages;
|
||||
|
||||
|
||||
// methods
|
||||
// methodes
|
||||
public slots:
|
||||
void changePage(QListWidgetItem *, QListWidgetItem *);
|
||||
void applyConf();
|
||||
void addPage(ConfigPage *);
|
||||
void setCurrentPage(const int index);
|
||||
|
||||
private:
|
||||
void buildPagesList();
|
||||
void addPageToList(ConfigPage *);
|
||||
|
||||
// attributes
|
||||
// attributs
|
||||
private:
|
||||
QListWidget *pages_list;
|
||||
QStackedWidget *pages_widget;
|
||||
QDialogButtonBox *buttons;
|
||||
|
||||
|
||||
|
||||
QList<ConfigPage *> pages;
|
||||
};
|
||||
#endif
|
||||
136
configpages.cpp
Normal file
136
configpages.cpp
Normal 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
configpages.h
Normal file
72
configpages.h
Normal 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
customelement.cpp
Normal file
566
customelement.cpp
Normal 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
customelement.h
Normal file
124
customelement.h
Normal 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
|
||||
@@ -1,6 +0,0 @@
|
||||
ChangeElementInformationCommand = 1
|
||||
LinkElementCommand = 2
|
||||
ItemResizerCommand = 3
|
||||
ChangeShapeStyleCommand = 4
|
||||
QetShapeGeometryCommand = 5
|
||||
QPropertyUndoCommand = 10 000
|
||||
@@ -1,23 +0,0 @@
|
||||
Type = UserType + ???
|
||||
###DIAGRAM EDITOR###
|
||||
Element + 1000
|
||||
Conductor + 1001
|
||||
Terminal + 1002
|
||||
ElementTextItem + 1003
|
||||
DiagramTextItem + 1004
|
||||
IndependentTextItem + 1005
|
||||
ConductorTextItem + 1006
|
||||
DiagramImageItem + 1007
|
||||
QetShapItem + 1008
|
||||
crossRefItem + 1009
|
||||
ElementPrimitiveDecorator + 2200
|
||||
|
||||
###ELEMENT EDITOR###
|
||||
part arc + 1101
|
||||
part ellipse + 1103
|
||||
part Line + 1104
|
||||
part polygon + 1105
|
||||
part terminal + 1106
|
||||
part text + 1107
|
||||
part text field + 1108
|
||||
part rectangle + 1109
|
||||
648
diagram.cpp
Normal file
648
diagram.cpp
Normal 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 <20> XMLiser <20>
|
||||
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
diagram.h
Normal file
266
diagram.h
Normal 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 <20> poseur de conducteur <20>, 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
diagramcommands.cpp
Normal file
625
diagramcommands.cpp
Normal 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
diagramcommands.h
Normal file
394
diagramcommands.h
Normal 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
diagramcontent.cpp
Normal file
130
diagramcontent.cpp
Normal 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
diagramcontent.h
Normal file
70
diagramcontent.h
Normal 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
diagramprintdialog.cpp
Normal file
302
diagramprintdialog.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "diagramprintdialog.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param dia Schema a imprimer
|
||||
@param printer Imprimante a utiliser
|
||||
@param parent Widget parent du dialogue
|
||||
*/
|
||||
DiagramPrintDialog::DiagramPrintDialog(Diagram *dia, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
diagram(dia),
|
||||
dialog(0)
|
||||
{
|
||||
// initialise l'imprimante
|
||||
printer = new QPrinter();
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
DiagramPrintDialog::~DiagramPrintDialog() {
|
||||
delete dialog;
|
||||
delete printer;
|
||||
}
|
||||
|
||||
/**
|
||||
Definit le nom du PDF si l'utilisateur choisit une sortie vers un PDF
|
||||
*/
|
||||
void DiagramPrintDialog::setPDFName(const QString &name) {
|
||||
pdf_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
@return le nom du PDF
|
||||
*/
|
||||
QString DiagramPrintDialog::PDFName() const {
|
||||
return(pdf_name);
|
||||
}
|
||||
|
||||
/**
|
||||
Execute le dialogue d'impression
|
||||
*/
|
||||
void DiagramPrintDialog::exec() {
|
||||
|
||||
// affichage du dialogue d'impression standard
|
||||
QPrintDialog print_dialog(printer);
|
||||
print_dialog.setEnabledOptions(QAbstractPrintDialog::PrintToFile);
|
||||
#ifndef Q_OS_WIN32
|
||||
if (!pdf_name.isEmpty()) printer -> setOutputFileName(pdf_name);
|
||||
#endif
|
||||
if (print_dialog.exec() == QDialog::Rejected) return;
|
||||
|
||||
/*
|
||||
Apres l'execution de ce premier dialogue, on connait le format papier a
|
||||
utiliser, son orientation et on est sur que tout cela est supporte par
|
||||
l'imprimante.
|
||||
On peut donc en deduire le nombre de pages a imprimer
|
||||
*/
|
||||
|
||||
// affichage d'un second dialogue, non standard, pour connaitre les pages a imprimer
|
||||
buildDialog();
|
||||
if (dialog -> exec() == QDialog::Rejected) return;
|
||||
|
||||
// effectue l'impression en elle-meme
|
||||
print();
|
||||
}
|
||||
|
||||
/**
|
||||
@param fullPage true pour utiliser toute la feuille dans le calcul
|
||||
@return Le nombre de pages necessaires pour imprimer le schema
|
||||
avec l'orientation et le format papier utilise dans l'imprimante en cours.
|
||||
*/
|
||||
int DiagramPrintDialog::pagesCount(bool fullpage) const {
|
||||
return(horizontalPagesCount(fullpage) * verticalPagesCount(fullpage));
|
||||
}
|
||||
|
||||
/**
|
||||
@param fullPage true pour utiliser toute la feuille dans le calcul
|
||||
@return La largeur du "poster" en nombre de pages pour imprimer le schema
|
||||
avec l'orientation et le format papier utilise dans l'imprimante en cours.
|
||||
*/
|
||||
int DiagramPrintDialog::horizontalPagesCount(bool fullpage) const {
|
||||
// note : pageRect et Paper Rect tiennent compte de l'orientation du papier
|
||||
QRect printable_area = fullpage ? printer -> paperRect() : printer -> pageRect();
|
||||
QRect diagram_rect = diagram -> border().toRect();
|
||||
|
||||
int h_pages_count = int(ceil(qreal(diagram_rect.width()) / qreal(printable_area.width())));
|
||||
return(h_pages_count);
|
||||
}
|
||||
|
||||
/**
|
||||
@param fullPage true pour utiliser toute la feuille dans le calcul
|
||||
@return La largeur du "poster" en nombre de pages pour imprimer le schema
|
||||
avec l'orientation et le format papier utilise dans l'imprimante en cours.
|
||||
*/
|
||||
int DiagramPrintDialog::verticalPagesCount(bool fullpage) const {
|
||||
// note : pageRect et Paper Rect tiennent compte de l'orientation du papier
|
||||
QRect printable_area = fullpage ? printer -> paperRect() : printer -> pageRect();
|
||||
QRect diagram_rect = diagram -> border().toRect();
|
||||
|
||||
int v_pages_count = int(ceil(qreal(diagram_rect.height()) / qreal(printable_area.height())));
|
||||
return(v_pages_count);
|
||||
}
|
||||
|
||||
/**
|
||||
Construit un dialogue non standard pour demander les pages a imprimer a l'utilisateur
|
||||
*/
|
||||
void DiagramPrintDialog::buildDialog() {
|
||||
dialog = new QDialog();
|
||||
dialog -> setWindowTitle(tr("Options d'impression"));
|
||||
options_label = new QLabel();
|
||||
use_full_page = new QCheckBox(tr("Utiliser toute la feuille"));
|
||||
fit_diagram_to_page = new QCheckBox(tr("Adapter le sch\351ma \340 la page"));
|
||||
range_from_label = new QLabel(tr("Plage de "));
|
||||
start_page = new QSpinBox();
|
||||
to_label = new QLabel(tr(" \340 "));
|
||||
end_page = new QSpinBox();
|
||||
buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
|
||||
QHBoxLayout *pages_layout = new QHBoxLayout();
|
||||
pages_layout -> addWidget(range_from_label);
|
||||
pages_layout -> addWidget(start_page);
|
||||
pages_layout -> addWidget(to_label);
|
||||
pages_layout -> addWidget(end_page);
|
||||
|
||||
QVBoxLayout *dialog_layout = new QVBoxLayout(dialog);
|
||||
dialog_layout -> addWidget(options_label);
|
||||
dialog_layout -> addWidget(use_full_page);
|
||||
dialog_layout -> addWidget(fit_diagram_to_page);
|
||||
dialog_layout -> addLayout(pages_layout);
|
||||
dialog_layout -> addStretch();
|
||||
dialog_layout -> addWidget(buttons);
|
||||
|
||||
connect(use_full_page, SIGNAL(stateChanged(int)), this, SLOT(updateDialog()));
|
||||
connect(fit_diagram_to_page, SIGNAL(stateChanged(int)), this, SLOT(updateDialog()));
|
||||
connect(start_page, SIGNAL(valueChanged(int)), this, SLOT(checkStartPage()));
|
||||
connect(end_page, SIGNAL(valueChanged(int)), this, SLOT(checkEndPage()));
|
||||
connect(buttons, SIGNAL(accepted()), dialog, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), dialog, SLOT(reject()));
|
||||
|
||||
updateDialog();
|
||||
}
|
||||
|
||||
/**
|
||||
Assure la coherence du dialogue
|
||||
*/
|
||||
void DiagramPrintDialog::updateDialog() {
|
||||
int pages_count;
|
||||
// si on adapte le schema a la page, alors il n'y a qu'une page a imprimer
|
||||
if (fit_diagram_to_page -> isChecked()) {
|
||||
pages_count = 1;
|
||||
} else {
|
||||
pages_count = pagesCount(use_full_page -> isChecked());
|
||||
}
|
||||
options_label -> setText(tr("Nombre total de pages : ") + QString("%1").arg(pages_count));
|
||||
setPagesRangeVisible(pages_count > 1);
|
||||
start_page -> setRange(1, pages_count);
|
||||
end_page -> setRange(1, pages_count);
|
||||
end_page -> setValue(pages_count);
|
||||
}
|
||||
|
||||
/**
|
||||
S'assure que la premiere page ne soit pas superieure a la derniere page
|
||||
*/
|
||||
void DiagramPrintDialog::checkStartPage() {
|
||||
if (start_page -> value() > end_page -> value()) {
|
||||
start_page -> blockSignals(true);
|
||||
start_page -> setValue(end_page -> value());
|
||||
start_page -> blockSignals(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
S'assure que la derniere page ne soit pas inferieure a la premiere page
|
||||
*/
|
||||
void DiagramPrintDialog::checkEndPage() {
|
||||
if (end_page -> value() < start_page -> value()) {
|
||||
end_page -> blockSignals(true);
|
||||
end_page -> setValue(start_page -> value());
|
||||
end_page -> blockSignals(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@param visible true pour afficher les pages, false sinon
|
||||
*/
|
||||
void DiagramPrintDialog::setPagesRangeVisible(bool visible) {
|
||||
range_from_label -> setVisible(visible);
|
||||
start_page -> setVisible(visible);
|
||||
to_label -> setVisible(visible);
|
||||
end_page -> setVisible(visible);
|
||||
}
|
||||
|
||||
/**
|
||||
Effectue l'impression elle-meme
|
||||
*/
|
||||
void DiagramPrintDialog::print() {
|
||||
// recupere les informations collectees dans le second dialogue
|
||||
bool full_page = use_full_page -> isChecked();
|
||||
bool fit_page = fit_diagram_to_page -> isChecked();
|
||||
int first_page = start_page -> value();
|
||||
int last_page = end_page -> value();
|
||||
|
||||
// parametre l'imprimante
|
||||
printer -> setFullPage(full_page);
|
||||
|
||||
// QPainter utiliser pour effectuer le rendu
|
||||
QPainter qp(printer);
|
||||
|
||||
// impression physique (!= fichier PDF)
|
||||
if (printer -> outputFileName().isEmpty()) {
|
||||
// lorsqu'on imprime en paysage sur imprimante reelle, il faut pivoter soi-meme le rendu
|
||||
if (printer -> orientation() == QPrinter::Landscape) {
|
||||
qp.rotate(90.0);
|
||||
qp.translate(0.0, -printer -> pageRect().height());
|
||||
}
|
||||
}
|
||||
|
||||
diagram -> setDisplayGrid(false);
|
||||
diagram -> setDrawTerminals(false);
|
||||
|
||||
if (fit_page) {
|
||||
// impression adaptee sur une seule page
|
||||
diagram -> render(&qp, QRectF(), diagram -> border(), Qt::KeepAspectRatio);
|
||||
} else {
|
||||
// impression sur une ou plusieurs pages
|
||||
QRect diagram_rect = diagram -> border().toRect();
|
||||
QRect printed_area = full_page ? printer -> paperRect() : printer -> pageRect();
|
||||
int used_width = printed_area.width();
|
||||
int used_height = printed_area.height();
|
||||
int h_pages_count = horizontalPagesCount(full_page);
|
||||
int v_pages_count = verticalPagesCount(full_page);
|
||||
|
||||
QVector< QVector< QRect > > pages_grid;
|
||||
// le schema est imprime sur une matrice de feuilles
|
||||
// parcourt les lignes de la matrice
|
||||
int y_offset = 0;
|
||||
for (int i = 0 ; i < v_pages_count ; ++ i) {
|
||||
pages_grid << QVector< QRect >();
|
||||
|
||||
// parcourt les feuilles de la ligne
|
||||
int x_offset = 0;
|
||||
for (int j = 0 ; j < h_pages_count ; ++ j) {
|
||||
pages_grid.last() << QRect(
|
||||
QPoint(x_offset, y_offset),
|
||||
QSize(
|
||||
qMin(used_width, diagram_rect.width() - x_offset),
|
||||
qMin(used_height, diagram_rect.height() - y_offset)
|
||||
)
|
||||
);
|
||||
x_offset += used_width;
|
||||
}
|
||||
|
||||
y_offset += used_height;
|
||||
}
|
||||
|
||||
// ne retient que les pages a imprimer
|
||||
QVector<QRect> pages_to_print;
|
||||
for (int i = 0 ; i < v_pages_count ; ++ i) {
|
||||
for (int j = 0 ; j < h_pages_count ; ++ j) {
|
||||
int page_number = (i * h_pages_count) + j + 1;
|
||||
if (page_number >= first_page && page_number <= last_page) {
|
||||
pages_to_print << pages_grid.at(i).at(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parcourt les pages pour impression
|
||||
for (int i = 0 ; i < pages_to_print.count() ; ++ i) {
|
||||
QRect current_rect(pages_to_print.at(i));
|
||||
diagram -> render(
|
||||
&qp,
|
||||
QRect(QPoint(0,0), current_rect.size()),
|
||||
current_rect.translated(diagram_rect.topLeft()),
|
||||
Qt::KeepAspectRatio
|
||||
);
|
||||
if (i != pages_to_print.count() - 1) {
|
||||
printer -> newPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
diagram -> setDrawTerminals(true);
|
||||
diagram -> setDisplayGrid(true);
|
||||
}
|
||||
71
diagramprintdialog.h
Normal file
71
diagramprintdialog.h
Normal 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
diagramtextitem.cpp
Normal file
200
diagramtextitem.cpp
Normal 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
diagramtextitem.h
Normal file
67
diagramtextitem.h
Normal 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
diagramview.cpp
Normal file
950
diagramview.cpp
Normal 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
diagramview.h
Normal file
118
diagramview.h
Normal 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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 43 KiB |
Binary file not shown.
128
editor/arceditor.cpp
Normal file
128
editor/arceditor.cpp
Normal 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
editor/arceditor.h
Normal file
56
editor/arceditor.h
Normal 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
editor/circleeditor.cpp
Normal file
99
editor/circleeditor.cpp
Normal 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
editor/circleeditor.h
Normal file
53
editor/circleeditor.h
Normal 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
editor/customelementgraphicpart.cpp
Normal file
208
editor/customelementgraphicpart.cpp
Normal 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
editor/customelementgraphicpart.h
Normal file
192
editor/customelementgraphicpart.h
Normal 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
editor/customelementpart.cpp
Normal file
35
editor/customelementpart.cpp
Normal 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
editor/customelementpart.h
Normal file
87
editor/customelementpart.h
Normal 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
editor/editorcommands.cpp
Normal file
504
editor/editorcommands.cpp
Normal 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
editor/editorcommands.h
Normal file
311
editor/editorcommands.h
Normal 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
editor/elementitemeditor.cpp
Normal file
78
editor/elementitemeditor.cpp
Normal 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
editor/elementitemeditor.h
Normal file
53
editor/elementitemeditor.h
Normal 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
editor/elementscene.cpp
Normal file
732
editor/elementscene.cpp
Normal 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
editor/elementscene.h
Normal file
238
editor/elementscene.h
Normal 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
editor/elementview.cpp
Normal file
128
editor/elementview.cpp
Normal 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
editor/elementview.h
Normal file
56
editor/elementview.h
Normal 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
editor/ellipseeditor.cpp
Normal file
108
editor/ellipseeditor.cpp
Normal 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
editor/ellipseeditor.h
Normal file
53
editor/ellipseeditor.h
Normal 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
editor/lineeditor.cpp
Normal file
115
editor/lineeditor.cpp
Normal 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
editor/lineeditor.h
Normal file
53
editor/lineeditor.h
Normal 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
editor/partarc.cpp
Normal file
263
editor/partarc.cpp
Normal 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
editor/partarc.h
Normal file
67
editor/partarc.h
Normal 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
editor/partcircle.cpp
Normal file
199
editor/partcircle.cpp
Normal 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
editor/partcircle.h
Normal file
62
editor/partcircle.h
Normal 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
editor/partellipse.cpp
Normal file
199
editor/partellipse.cpp
Normal 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
editor/partellipse.h
Normal file
61
editor/partellipse.h
Normal 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
editor/partline.cpp
Normal file
253
editor/partline.cpp
Normal 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
editor/partline.h
Normal file
66
editor/partline.h
Normal 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
editor/partpolygon.cpp
Normal file
175
editor/partpolygon.cpp
Normal 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
editor/partpolygon.h
Normal file
92
editor/partpolygon.h
Normal 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
editor/partterminal.cpp
Normal file
228
editor/partterminal.cpp
Normal 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
editor/partterminal.h
Normal file
69
editor/partterminal.h
Normal 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
editor/parttext.cpp
Normal file
233
editor/parttext.cpp
Normal 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
editor/parttext.h
Normal file
68
editor/parttext.h
Normal 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
editor/parttextfield.cpp
Normal file
258
editor/parttextfield.cpp
Normal 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
editor/parttextfield.h
Normal file
74
editor/parttextfield.h
Normal 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
editor/polygoneditor.cpp
Normal file
155
editor/polygoneditor.cpp
Normal 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
editor/polygoneditor.h
Normal file
58
editor/polygoneditor.h
Normal 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
editor/qetelementeditor.cpp
Normal file
784
editor/qetelementeditor.cpp
Normal 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
editor/qetelementeditor.h
Normal file
201
editor/qetelementeditor.h
Normal 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
editor/styleeditor.cpp
Normal file
180
editor/styleeditor.cpp
Normal 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
editor/styleeditor.h
Normal file
65
editor/styleeditor.h
Normal 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
editor/terminaleditor.cpp
Normal file
113
editor/terminaleditor.cpp
Normal 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
editor/terminaleditor.h
Normal file
54
editor/terminaleditor.h
Normal 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
editor/texteditor.cpp
Normal file
112
editor/texteditor.cpp
Normal 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
editor/texteditor.h
Normal file
55
editor/texteditor.h
Normal 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
editor/textfieldeditor.cpp
Normal file
126
editor/textfieldeditor.cpp
Normal 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
editor/textfieldeditor.h
Normal file
58
editor/textfieldeditor.h
Normal 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
element.cpp
Normal file
471
element.cpp
Normal 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
element.h
Normal file
154
element.h
Normal 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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user