Compare commits
1 Commits
XMLPropert
...
0.1b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5762b3943b |
7
.gitignore
vendored
@@ -1,7 +0,0 @@
|
||||
*.snap
|
||||
.flatpak-builder
|
||||
# Qt build output
|
||||
*.user
|
||||
# doxygen Doxyfile output
|
||||
doc/
|
||||
QElectroTech.tag
|
||||
121
CONTRIBUTING.md
@@ -1,121 +0,0 @@
|
||||
# How to contribute
|
||||
|
||||
I'm really glad you're reading this,
|
||||
because we need volunteer developers to help
|
||||
this project come to fruition.
|
||||
|
||||
|
||||
Here are some important resources:
|
||||
|
||||
* [Qet code style](https://qelectrotech.org/wiki_new/doc/qt_creator#on_ajoute_le_style_de_code_qet)
|
||||
* [git Documentation](https://git-scm.com/doc)
|
||||
|
||||
## Testing
|
||||
|
||||
## Submitting changes
|
||||
|
||||
Always write a clear log message for your commits.
|
||||
One-line messages are fine for small changes,
|
||||
but bigger changes should look like this:
|
||||
|
||||
$ git commit -m "A brief summary of the commit
|
||||
>
|
||||
> A paragraph describing what changed and its impact."
|
||||
|
||||
* It is always appropriate to keep the commits small.
|
||||
* For major changes it is recommended to use branches.
|
||||
|
||||
### Interactive Staging
|
||||
https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging
|
||||
|
||||
issue: you have modified a class but you want to write it in 2 commits
|
||||
|
||||
´git add -p´ or ´git add -i´
|
||||
|
||||
|
||||
/qet> git add -i
|
||||
|
||||
|
||||
staged unstaged path
|
||||
1: unchanged +1/-1 sources/diagram.cpp
|
||||
|
||||
*** Commands ***
|
||||
1: status 2: update 3: revert 4: add untracked
|
||||
5: patch 6: diff 7: quit 8: help
|
||||
|
||||
|
||||
What now> 5
|
||||
|
||||
|
||||
staged unstaged path
|
||||
1: unchanged +1/-1 sources/diagram.cpp
|
||||
Patch update>> 1
|
||||
staged unstaged path
|
||||
* 1: unchanged +1/-1 sources/diagram.cpp
|
||||
Patch update>>
|
||||
diff --git a/sources/diagram.cpp b/sources/diagram.cpp
|
||||
index bffca653f..9bd2280f7 100644
|
||||
--- a/sources/diagram.cpp
|
||||
+++ b/sources/diagram.cpp
|
||||
@@ -103,9 +103,9 @@ Diagram::Diagram(QETProject *project) :
|
||||
connect(&border_and_titleblock,
|
||||
&BorderTitleBlock::titleBlockFolioChanged,
|
||||
this, &Diagram::updateLabels);
|
||||
- connect(this, &Diagram::diagramActivated,
|
||||
+ foo(do_a);
|
||||
- adjust(diagramActivated);
|
||||
+ bar(do_c);
|
||||
adjustSceneRect();
|
||||
}
|
||||
|
||||
|
||||
(1/1) Stage this hunk [y,n,q,a,d,s,e,?]? s
|
||||
|
||||
|
||||
Split into 2 hunks.
|
||||
@@ -103,5 +103,5 @@
|
||||
connect(&border_and_titleblock,
|
||||
&BorderTitleBlock::titleBlockFolioChanged,
|
||||
this, &Diagram::updateLabels);
|
||||
- connect(this, &Diagram::diagramActivated,
|
||||
+ foo(do_a);
|
||||
|
||||
|
||||
(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? y
|
||||
|
||||
|
||||
@@ -107,5 +107,5 @@
|
||||
this, &Diagram::loadElmtFolioSeq);
|
||||
- adjust(diagramActivated);
|
||||
+ bar(do_c);
|
||||
adjustSceneRect();
|
||||
}
|
||||
|
||||
|
||||
(2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? n
|
||||
|
||||
|
||||
*** Commands ***
|
||||
1: status 2: update 3: revert 4: add untracked
|
||||
5: patch 6: diff 7: quit 8: help
|
||||
What now>What now>7
|
||||
Bye.
|
||||
|
||||
git commit -m "Mod Signal Slot to funsion"
|
||||
|
||||
## Coding conventions
|
||||
|
||||
Start reading our code and you'll get the hang of it.
|
||||
We optimize for readability:
|
||||
|
||||
* We use tabs to indent, and interpret tabs as taking up to 8 spaces.
|
||||
see https://qelectrotech.org/wiki_new/doc/qt_creator#on_ajoute_le_style_de_code_qet
|
||||
* We try to keep to at most 80 characters per line.
|
||||
* Try to make your code understandable.
|
||||
You may put comments in, but comments invariably tend to stale out when
|
||||
the code they were describing changes.
|
||||
Often splitting a function into two
|
||||
makes the intention of the code much clearer.
|
||||
|
||||
Thanks,
|
||||
QElectroTech
|
||||
244
CREDIT
@@ -1,238 +1,6 @@
|
||||
[en]
|
||||
Thanks to Qt Software for their Qt library ( http://www.qtsoftware.com/ ), licensed under GNU/GPL.
|
||||
Thanks 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.
|
||||
|
||||
[fr]
|
||||
Merci à Qt Software pour la bibliothèque Qt ( http://www.qtsoftware.com/ ), sous licence GNU/GPL.
|
||||
Merci 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.
|
||||
Спасибо проекту 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 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 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 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 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 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.
|
||||
Ευχαριστίες στο έργο 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 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 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 <20> Trolltech pour la biblioth<74>que Qt ( http://trolltech.com/ ), sous
|
||||
licence GNU/GPL.
|
||||
Merci <20> Everaldo Coelho pour le th<74>me d'ic<69>nes Crystal SVG (
|
||||
http://www.everaldo.com/crystal/ ) sous licence LGPL, ainsi qu'au projet KDE (
|
||||
http://www.kde.org/ ).
|
||||
Merci <20> Loic pour ses explications d'ordre math<74>matique.
|
||||
|
||||
547
ChangeLog
@@ -1,547 +0,0 @@
|
||||
====== ChangeLog from 0.7 to 0.8 ======
|
||||
|
||||
|
||||
* Moving the main QET repository SVN trunk to GIT.
|
||||
* Add a mirror of the main QET repository, which is synced to hosted at tuxfamily.org to Github.
|
||||
* Doxyfile update add QCH file for doxygen-generated docs using qhelpgenerator and then import them into Qt Creator.
|
||||
* Improve portability of Doxyfile (Simon).
|
||||
* Fix deprecated warnings (Simon).
|
||||
* Wrap code for better readability (Simon, Damian).
|
||||
|
||||
|
||||
|
||||
|
||||
* Elements collection :
|
||||
Improve collection 7378 elements in 1092 categories
|
||||
Thanks Sebastien, Dinozzo, Simon, Rafał, Arnaud, Bisku, Fernando, Riesermauf, Alexis, david, Plc-user, Christophe, Michele, Galexis, Jevgenijs, Gabor,
|
||||
Benoit Michel, Franck, Ludovic, Cyrille, ossau2mation, Mitzot, Edgar, Nuri, Friskolon, Baboune41, Wiktor, shateks, Dik, Shateks, Marcin
|
||||
|
||||
|
||||
* Diagram editor :
|
||||
|
||||
* The export of the nomenclature to csv file has been completely rewritten :
|
||||
It is now possible to choose which information to export as well as the order in which it should be displayed.
|
||||
An option allows filtering by type of element: all, terminal block, button / switch.
|
||||
Another option allows to display or not the column headers in the csv file.
|
||||
With these options, it is possible to create a nomenclature, an order list, but also for printing labels: list of terminals and list of buttons / switches.
|
||||
It is possible to save / load a configuration easily.
|
||||
Finally, the work being done by an SQLite database, a text field allows the user to create his own SQL query.
|
||||
|
||||
* Add Conductors numbering to csv file.
|
||||
|
||||
* Add new summary table.
|
||||
|
||||
* add BOM creation dialog :
|
||||
nomenclature is now integrated into the project (accompanied by several parameters in order to be customizable).
|
||||
Tables can have a name.
|
||||
Tables an be added to any folio.
|
||||
Font margin and alignment (right center left) separately adjustable for headers and table cells.
|
||||
Position size and number of lines is adjustable.
|
||||
Possibility of linking several tables together, especially when the entire nomenclature cannot be contained in a folio.
|
||||
Automatic adjustment of the size of the table in relation to the folio.
|
||||
Option to apply the geometry of an array to all the array linked to it, so that everything is homogeneous.
|
||||
Save / load table configuration and content to make creation faster.
|
||||
Option to automatically adjust the table to the folio.
|
||||
Option to automatically add new tables in new folios if the nomenclature cannot be contained in 1 to N folios / tables.
|
||||
|
||||
* Table content:
|
||||
Fully customizable, you display what you want or want (info to display in the desired order, filter on type of element, filter on content of the info "contains, not contains, not empty etc ..." ).
|
||||
The content being generated from a sqlite database, you can write your own request.
|
||||
|
||||
|
||||
* Loading of element collections is now faster (thanks to the pugixml parser)
|
||||
* The loading of collections of elements no longer freezes QElectroTech.
|
||||
* The appearance and disappearance of the search / replace menu is animated.
|
||||
* Fix wrong position of slave xref after open a saved project
|
||||
|
||||
* Add font color of the conductors (Simon).
|
||||
* Add section and color properties for wires.
|
||||
|
||||
* config dialog :
|
||||
* Add QScrollArea to configdialog and resize to max_screen (Simon).
|
||||
* Add gui resize depending on screen size (Simon).
|
||||
* Add Screen info user (Simon).
|
||||
* Mod ScrollArea on demand (Simon).
|
||||
|
||||
|
||||
* Element editor:
|
||||
* Polygon editing widget, when you click on a point in the list, the corresponding point changes color in order to better visualize what you are doing.
|
||||
On this same list, a right click opens a contextual menu allowing to delete the selected point or inserted a point after the selected one.
|
||||
When holding the ctrl + directional arrow key, the selected parts move by 0.1 instead of 1 point.
|
||||
* with Ctrl key you can moving by keyboard primitives selected by 0.1 point instead by 1 points, added the same feature for moving the selected aera.
|
||||
* Added 140 web standard colors In Element editor (Arnaud).
|
||||
|
||||
* Add multiedit feature (martin).
|
||||
* Add terminals uuid for next features (martin).
|
||||
|
||||
|
||||
* Windows :
|
||||
* Fix bad fonts rendering if Qt version >= 5.13.1.
|
||||
See : https://bugreports.qt.io/browse/QTBUG-83161
|
||||
* Fix backup file on windows
|
||||
For unknown reason KautoSaveFile don't write the file on Windows if file
|
||||
is open in another part of the code.
|
||||
No error is returned and use the method :
|
||||
qint64 QIODevice::write(const QByteArray &byteArray) return the good
|
||||
number of bytes written but the real file stay empty.
|
||||
Probably the problem don't come from KautoSaveFile but QFileDevice or
|
||||
QIODevice on windows.
|
||||
|
||||
The fix consist to open the file just before write on it and close it
|
||||
just after.
|
||||
|
||||
* writeToFile on a other Thread to improve this for windows performance (Simon).
|
||||
|
||||
|
||||
* macOS :
|
||||
* Add Fusion style and fix tilesets tab bar size
|
||||
* Enable mouse wheel on tilesets tab bar with command keyboard, thanks Giovanni.
|
||||
(removed by Qt upstream) https://codereview.qt-project.org/gitweb?p=qt/qtbase.git;a=commitdiff;h=ea47d152b35158ba07a55d009f57df0e4c2a048f;hp=08cc9b9991ae9ab51bed5b857b6257401401ff6f
|
||||
|
||||
|
||||
* Add Snap packages :
|
||||
* thanks Max for help.
|
||||
https://snapcraft.io/qelectrotech
|
||||
See: https://qelectrotech.org/forum/viewtopic.php?id=1426
|
||||
* Use kde-neon extension
|
||||
The kde-neon extension reduces our boilerplate in snapcraft.yaml
|
||||
and reduces the snap size considerably, as we do not need to ship
|
||||
any library that is already included in the kde-frameworks-5-core18
|
||||
snap itself.
|
||||
|
||||
This limits qelectrotech builds to the architectures supported
|
||||
by kde-frameworks-5-core18, i.e. only amd64.
|
||||
|
||||
https://git.tuxfamily.org/qet/qet.git/log/?qt=grep&q=snap
|
||||
|
||||
|
||||
|
||||
* Add Flatpak packages :
|
||||
* thanks Mathieu for help.
|
||||
See: https://github.com/qelectrotech/qelectrotech-source-mirror/pull/18
|
||||
* remove the file name extension added
|
||||
automatically to the saved files even if the user sets an unknown file
|
||||
extension for the program.
|
||||
|
||||
https://git.tuxfamily.org/qet/qet.git/log/?qt=grep&q=flatpak
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
====== ChangeLog from 0.6 to 0.7 ======
|
||||
|
||||
|
||||
* Element editor :
|
||||
* Element informations (manufacturer, reference etc...) can be created directly from the element editor. For that go to the widget "Element Property"
|
||||
* It is no longer required to have a text field, for save the edited element.
|
||||
* Improve the behavior with the arrow keys (depending to the current selection (nothing / one / several).
|
||||
* Context menu display only enabled actions.
|
||||
* Added new feature -> alignment.
|
||||
* Alignment of text field can be edited.
|
||||
* Added two new actions in context menu for insert or remove point of a selected polygon.
|
||||
* Rectangle can have rounded corner.
|
||||
* Polyline: finish the creation of polyline with the last point at the same position of the first point, close the polyline.
|
||||
|
||||
|
||||
* Diagram editor :
|
||||
* Conductors can now be drawn with two colors.
|
||||
* Improve High-DPI support on Windows and Linux plateform.
|
||||
* The code for the resize handles has been almost completely redesigned.
|
||||
* Dissociate fonts policy and size for independent text item and for summarry pages (foliolist), added a 2 button in config page for open Qfontdialog widget and choose policy for independent text item.
|
||||
* Add in config page a Qfontdialog widget for change dynamic text size, font family, orientation angle and text length, by default.
|
||||
* Basic shape add new CustomDashLine style with Dash Pattern (<< 10 << 10 );
|
||||
* It is now possible to add a text field to an element directly from the diagram.
|
||||
* Element text item with are now converted to dynamic element text item.
|
||||
* Element editor, part text can't be edited directly.
|
||||
* User can export / import the configuration of the texts and texts group of an element.
|
||||
* Context menu display only enabled actions.
|
||||
* Added new action in the context menu, multiple paste, check box for autonum the pasted element.
|
||||
* Multipaste -> improve the conductor autonum, conductors are numerated from top to bottom, and left to right.
|
||||
* Text of conductor can be placed at top/bottom/left/right of conductor, and text never overlaps the conductor.
|
||||
* Function for search conductor at the same potential.
|
||||
When the search function is searching in a terminal element, they search only for the first terminal found, no matter if the terminal element have more than two terminals.
|
||||
So the list of conductors at the same potential is missing some conductors.
|
||||
This commit fix it, now the search function search for every terminals of a terminal element.
|
||||
* When remove an element with several conductors connected to the same terminal, the electrical potential is partially or totally destroyed.
|
||||
This commit fix it : When element is removed one or several conductors are created (if needed) to conserve the electrical potential.
|
||||
|
||||
* Added new feature -> alignment.
|
||||
* Alignment of text field can be edited.
|
||||
* Added new context menu action "group the selected texts".
|
||||
* Widget used to edit text item group can edit the pos of the group.
|
||||
* Element text item group can now be framed.
|
||||
* Added two new actions in context menu for insert or remove point of a selected polygon.
|
||||
* QETshapeItem rectangle can have rounded corner.
|
||||
* Add in config the possibility to start the numbering of the columns of titleblocks at 0.
|
||||
* Add new function Search and replace widget Crtl +F
|
||||
* Diagram properties, Element properties, Independent text item can be changed (and mass changed) through the search and replace widget.
|
||||
* Added 4 tools for edit the depth (Z value) of items.
|
||||
* Element panel : elements can be searched by their name but also with by all their informations.
|
||||
* New free selection style.
|
||||
* Diagram editor : dock used to edit the shape item, can now edit several items in the same time.
|
||||
* Dynamic element text item : The font of the dynamic texts can be individually be setted.
|
||||
|
||||
* Adding or revoming diagram set project to modified
|
||||
* When user cleanning an project, set project to modified
|
||||
* Add a shortcut "Ctrl+Shift+P" to quickly open the dialog used for create the auto numbering rules.
|
||||
* Add missing StatusTip of some QAction
|
||||
|
||||
* When user add a polygon, a message in statusBar show how to finish this shape
|
||||
* Polyline: finish the creation of polyline with the last point at the same position of the first point, close the polyline.
|
||||
|
||||
|
||||
|
||||
* Plug-in : Add StatusTip instruction for install and launching DXF plugin depending on the operating system
|
||||
* when plugin qet-tb-generator"generate terminal blocks and connectors" isn't installed show an QMessageBox instruction now depending on the operating system for install it
|
||||
Add in QMessageBox url encoding/decoding for easy download packages
|
||||
|
||||
* Elementspanelwidget: adds keyboard shortcuts to quickly move up, down,or move the targeted folio to the beginning of the project
|
||||
F3 MoveUp
|
||||
F4 MoveDown
|
||||
F5 MoveUpTop
|
||||
|
||||
* Title block editor :
|
||||
Added new title block variables %projectpath, %projectfilename, %projecttitle, previous-folio-num and next-folio-num
|
||||
"%saveddate, %savedtime, %savedfilename and %savedfilepath" they variables should be updated after file save or save as dialog is confirmed,
|
||||
before file is saved.
|
||||
* NameList widget : add a combo box for easily paste texts, like the variables for title block.
|
||||
* The font of the dynamic text field can be edited.
|
||||
* The font of the static text field can be edited.
|
||||
* The color of the static text field can be edited.
|
||||
|
||||
|
||||
|
||||
* Improve for new qet_tb_generator plug-in : added the full path of the current project as
|
||||
an argument when calling the plug-in from QET if a project is open.
|
||||
If not a file dialog is showed to select the QET project.
|
||||
|
||||
|
||||
|
||||
* QET create a backup file, use to restore the project when a crash occur.
|
||||
* Use KAutoSaveFile for the backup system, instead of home made function.
|
||||
* Use of QSAveFile instead a QFile.
|
||||
* User can enable and edit autosave timer.
|
||||
* let user define the file system path of the common,custom elements collections, and custom title blocks template.
|
||||
|
||||
|
||||
* QetGraphicsItem, remove the function applyRotation and rotateBy, and use instead the native function of QGraphicsItem : setRotation
|
||||
* Conductor is an herited class of QGraphicsObject, instead of QObject and QGraphicsPathItem
|
||||
* Clean (and reduce the size) the class QETDiagramEditor, mostly by replacing the connection syntax "signal -> slot" by "signal -> lambda".
|
||||
* Replace deprecated QMatrix by QTransform.
|
||||
|
||||
|
||||
* DXF export : fix some double items in dxf file.
|
||||
* DXF export : add some colors for basic shapes inside dxf.
|
||||
|
||||
|
||||
* Bug fix :
|
||||
* Fix compilation warning (clang and gcc).
|
||||
|
||||
* Fix element text item alignment work well when text rotation != 0.
|
||||
* Fix crash when the properties of a element text item group
|
||||
* Fix crash occurred by the conductor and shape "ghost".
|
||||
* Fix element text alignment work also when font size change.
|
||||
* fix :
|
||||
1- When open a .qet by double click on it, QET ask user for open the backup file, of this .qet.
|
||||
2- On windows, if user open a project from the recent files menu, when close QET the file is deleted  user lose her work.
|
||||
clear the element texts when paste an element with the option "Do not store the labels of items in the copy paste" enabled.
|
||||
* elements can't be moved up and left, when there rotation are different than 0.
|
||||
* minor fix : slave link dialog doesn't display the good label, when the label of master element is build from formula.
|
||||
* Fix : in some condition, dynamic text are not at the same position when open a project.
|
||||
* On windows when user drag and drop an element from the common elements collection to the custom elements collection,
|
||||
the element file stay in read only mode, and so user can't save the element
|
||||
* Improvement : minimize the unwanted gap of the top right folio of the view (see https://qelectrotech.org/forum/viewtopic.php?pid=9379#p9379)
|
||||
* Fix: bug 168
|
||||
* Fix : when create multiple conductors with the free hand selection, the checking of existing potentiel don't search trought a folio report.
|
||||
* Fix: DXF export.
|
||||
* Minor fix : remove from the element information the html hexadecimal and decimal characters of line feed and carriage return.
|
||||
* fix : in the diagram editor, when we select several shapes at the same time, the properties widget only apply the change to one shape.
|
||||
* Bug fix : when user load a project which contains summary pages, project was marked modified (summary was created on the fly and moved from the end on second
|
||||
position), now the project is no longer marked as amended when user have one or multiples summary pages when loading this project.
|
||||
* Static text of element are now exported to dxf
|
||||
* Fix Static text size of element exported to dxf
|
||||
* Improvement : minimize the unwanted gap of the top right folio of the view
|
||||
* Fix : when create multiple conductors with the free hand selection, the checking of existing potentiel don't search trought a folio report.
|
||||
* Don't display gui when qet is launched with specific argument
|
||||
|
||||
|
||||
|
||||
====== ChangeLog from 0.5 to 0.6 ======
|
||||
In the official collection, there are now 4106 elements, and 539 categoris for a total of 4645 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.
|
||||
* Windows packages are now created on a Debian operating system using cross-compilation and targeted to make executable binary files for these operating systems.
|
||||
This technical evolution allows a significant time saving during the creation of the packages. And we can provide also in the same time Windows XP and Vista packages by cross-compil with Qt 5.7.1 environment
|
||||
* The Mac OS X executable binary files are created on a virtual environment, moved compiler to latest LLVM clan version, improved dmg packages with added Info.plist.
|
||||
* An annoying memory leak has been found and solved. Afters hours of use, some users noticed that the RAM consumption growed steadily, up to 10GB or more. This problem is now solved.
|
||||
|
||||
|
||||
|
||||
====== 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
|
||||
|
||||
|
||||
189
ELEMENTS.LICENSE
@@ -1,189 +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.
|
||||
|
||||
[ja]
|
||||
QElectroTech と一緒に提供される要素コレクションは現状のまま提供され、
|
||||
あなたの目的や作業に適合することを保証するものではありません。
|
||||
回路図での要素の利用、変更、統合は、回路図の最終的なライセンスに関わらず
|
||||
無条件で許可されます。
|
||||
回路図とは別に QElectroTech コレクションの全部または一部を
|
||||
変更の有無に関わらず再配布する場合は CC-BY ライセンスを尊重しなければなりません:
|
||||
この作品は Creative Commons Attribution 3.0 の下でライセンスされます。
|
||||
ライセンスのコピーを見るには http://creativecommons.org/licenses/by/3.0/ にアクセスするか、
|
||||
「Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.」に
|
||||
手紙を送ってください。
|
||||
153
INSTALL
@@ -1,153 +0,0 @@
|
||||
[en]
|
||||
Requirements :
|
||||
libQt5 (see packages libqt5*)
|
||||
cupsys-bsd for printing
|
||||
|
||||
Howto compile :
|
||||
$ qmake (qmake-qt5 for Debian-based systems)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
|
||||
[fr]
|
||||
Pré-requis :
|
||||
libQt5 (paquets libqt5*)
|
||||
cupsys-bsd pour l'impression
|
||||
|
||||
Comment compiler :
|
||||
$ qmake (qmake-qt5 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
|
||||
|
||||
[ja]
|
||||
必要条件 :
|
||||
libQt5 (パッケージ libqt5* を参照)
|
||||
cupsys-bsd 印刷用
|
||||
|
||||
コンパイルの方法 :
|
||||
$ qmake (Debian ベースのシステムでは qmake-qt5)
|
||||
$ make
|
||||
# umask 0022
|
||||
# make install
|
||||
56
README
@@ -1,56 +0,0 @@
|
||||
[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.
|
||||
|
||||
[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.
|
||||
|
||||
[de]
|
||||
QElectroTech ist eine Qt5 Software, um Schaltpläne zu erstellen.
|
||||
QET benutzt das XML Format für seine Bauteile und seine Projekte, und beinhaltet einen Schaltplaneditor, einen Bauteileditor sowie einen Zeichnungskopfeditor.
|
||||
|
||||
|
||||
[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.
|
||||
|
||||
[ja]
|
||||
QElectroTech は電気回路図を作成する Qt5 アプリケーションです。
|
||||
QET は要素と回路図に XML 形式を利用し、回路図エディタ、要素エディタ、表題欄エディタを含みます。
|
||||
178
README.md
@@ -1,178 +0,0 @@
|
||||

|
||||
|
||||
|
||||
# QElectroTech
|
||||
|
||||
### What it is
|
||||
|
||||
QElectroTech, or QET in short, is a libre and open source desktop application to create diagrams and schematics.
|
||||
The software is primarily intended to create electrical documentation but it can also be used to draw any kinds of diagrams, such as those made in pneumatics, hydraulics, process industries, electronics...
|
||||
Generally speaking, QET is a **CAD/CAE editor focusing on schematics drawing features**.
|
||||
|
||||
This means that there are no embedded simulating or calculating functionalities and it is not planned to implement them.
|
||||
|
||||
The main goal of the developers is to provide a libre, easy to use and effective software for **schematics drawing purposes**.
|
||||
|
||||
### Version
|
||||
|
||||
The current stable version is 0.70 and was released on 2019.07.13.
|
||||
Once it has been officialy released, the stable version is always frozen and is no longer developed.
|
||||
|
||||
New functionalities, bug and issue fixings are further made in the development version (currently 0.8), which can also be [downloaded](https://qelectrotech.org/download.html).
|
||||
|
||||
Users who want to test and take benefits from the last software implementations should use the development version. But... use it at your own risk, since things are sometimes broken or only partialy implemented until they are done!
|
||||
|
||||
### License
|
||||
|
||||
The software is licensed under [GNU/GPL](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
|
||||
You are free to use, copy, modify and redistribute it under the terms of the license.
|
||||
|
||||
|
||||
Like many other open source softwares, QElectroTech is provided as it is, without any warranty.
|
||||
|
||||
### Development / technical choices
|
||||
|
||||
The development follows the classical way of free and open source software: the source code, written by a community of users, is freely accessible.
|
||||
|
||||
Here are the technical choices made for the software development:
|
||||
|
||||
* Integrated development environment: [Qt Framework](https://www.qt.io/ide/)
|
||||
* Libraries: Qt 5.x
|
||||
* [KF5 Framework](https://github.com/KDE)
|
||||
[Cmake](https://cmake.org/install/)
|
||||
[kcoreaddons](https://github.com/KDE/kcoreaddons)
|
||||
[kwidgetsaddons](https://github.com/KDE/kwidgetsaddons).
|
||||
* Coding language: [C++](https://en.wikipedia.org/wiki/C%2B%2B)
|
||||
* GUI translations: [Qt Linguist](http://doc.qt.io/qt-5/qtlinguist-index.html)
|
||||
* Version control: [GIT](https://git.tuxfamily.org/qet/qet.git/)
|
||||
* File format for projects, elements and titleblocks: [XML](http://www.w3schools.com/xml/xml_whatis.asp)
|
||||
* Main development platform: [GNU/Linux](http://getgnulinux.org/en/linux/)
|
||||
* Targeted platforms: Windows, GNU/Linux, Mac OS X, BSDs
|
||||
* [Forum](https://qelectrotech.org/forum/index.php)
|
||||
* [Wiki](https://qelectrotech.org/wiki_new/)
|
||||
* [Mantis_bugtracker](https://qelectrotech.org/bugtracker/my_view_page.php)
|
||||
|
||||
If you wish to be informed of the latest developments, browse the [archive](https://listengine.tuxfamily.org/lists.tuxfamily.org/qet/) of the project mailing list where all commits (changes) are registered. This archive is publicly available, you don't need any account to access it.
|
||||
|
||||
|
||||
# Features
|
||||
|
||||
QElectroTech is a free and open source software.
|
||||
No need to worry about restrictive licensing, privacy violation or dependency on a company.
|
||||
Zero cost and no licensing fees!
|
||||
But you are welcome to make a donation to support the development
|
||||
|
||||
QElectroTech runs on the 3 most widespread operating systems for desktop computers in the world.
|
||||
Files that were created on an OS can be edited on another OS without any conversion or restriction.
|
||||
MS Windows users can even run the "ready-to-use" version of QElectroTech from an external medium with no need to install it on an access restricted computer.
|
||||
|
||||
|
||||
Take advantage of the modern GUI
|
||||
|
||||
Toolbars and panels can be enabled/disabled, moved and displayed the way you want to work.
|
||||
Panels can be stacked on each other (as tabs) or docked on the sides (as docks) or completely separated from the main window (as windows).
|
||||
The GUI can fit to small or big screens, and even to multi-display configurations.
|
||||

|
||||
|
||||
|
||||
The GUI of QElectroTech is translated in 19 languages.
|
||||
You only need to restart the application for the new selected language to take effect.
|
||||

|
||||
|
||||
Create technical documentation in professional quality
|
||||
|
||||
Size, look and informations of the folios (sheets) are fully configurable.
|
||||
You can set vertical and horizontal headers (printed rulers) individually on and off, set number of columns and rows, and set width/height of each column/row.
|
||||
|
||||
Titlebocks can be created and edited with the embedded titleblock editor to perfectly suit your needs.
|
||||
Custom variables can be defined to display the informations you wish in the titleblock.
|
||||

|
||||
|
||||
With only 2 mouse clicks you can add a full automatic generated table of content.
|
||||
Changes in the documentation are updated on the fly.
|
||||

|
||||
|
||||
Choose from more than 7.000 symbols...
|
||||
The embedded QET collection contains a rich library of electric, logic, pneumatic, hydraulic and fluid symbols.
|
||||
The library grows at every new release thanks to an active user community.
|
||||

|
||||
|
||||
...or create your own collection
|
||||
|
||||
The embedded element editor is a nice tool to create your own elements (symbols or anything else).
|
||||
Your own elements are stored in the user collection.
|
||||

|
||||
|
||||
Quickly find what you need
|
||||
|
||||
All collections can quickly be searched with the integrated search engine.
|
||||
Furthermore, the search request can be restricted to the folder of your choice.
|
||||

|
||||
|
||||
Easily draw complex schematics
|
||||
|
||||
To add an element on the drawing area, it only needs a drag & drop from the collection panel.
|
||||

|
||||
|
||||
Elements are automatically connected if they are aligned, or connected from point to point by pulling a conductor with the mouse.
|
||||

|
||||
|
||||
The path of every conductor can be modified by moving its handles with the mouse.
|
||||

|
||||
And of course, you can accurately zoom with the mouse wheel over the drawing area to catch the smallest details.
|
||||
|
||||
Link elements together to create cross references
|
||||
|
||||
Several types of element can be linked together to display a cross reference text.
|
||||
All types of cross references are automatically updated on the fly, you don't need to think about them if you make changes.
|
||||

|
||||
To speed up your work, linkable elements are easily searched and shown.
|
||||

|
||||
|
||||
|
||||
Export informations to a parts list
|
||||
Informations of all elements in the project can be exported to a .csv file that can be read and edited by any spreadsheet application.
|
||||

|
||||
|
||||
This way, you can make your own parts list or bill of material using the full power of a spreadsheet program.
|
||||

|
||||
Print to pdf and/or export your work to images
|
||||
|
||||
Your whole documentation or only selected parts of it can be printed to a real printer or to a pdf file.
|
||||
Alternatively, you can export to vector (svg) or pixel (png, jpg, bmp) format images.
|
||||
|
||||
### And much more:
|
||||
|
||||
* open and edit several projects at the same time
|
||||
* import images (.bmp, .jpg, .png, .svg) in your diagrams
|
||||
* add basic shapes (lines, rectangles, ellipses, polygons) to your drawings
|
||||
* edit the thickness, the line style and the color of conductors
|
||||
* define some autonum patterns for conductors, symbols and folios
|
||||
* take advantage of the open xml standard of elements and projects to create custom tools
|
||||
* search and replace Widget (Ctrl + F) in entire project
|
||||
* conductors num can be exported to csv file.
|
||||
* ***
|
||||
|
||||
### Story
|
||||
|
||||
The QElectroTech project was founded in 2007 by two french students, Xavier and Benoit.
|
||||
Xavier developed the base application itself and made all technical choices about the development.
|
||||
The first version of QET (0.1) was released on 09.03.2008.
|
||||
However, both Xavier and Benoit do not participate anymore in the project since 2013.
|
||||
|
||||
Following this period, new developers and contributors took over the project and kept it alive.
|
||||
The development and the many translations are actively maintained.
|
||||
New functionalities and evolutions are planned to make QET ever better.
|
||||
|
||||
Nowadays, QET is not only used by many individuals, teachers and students but also by professional electricians and companies all over the world.
|
||||
|
||||
|
||||
### Donate Money
|
||||
|
||||
If you love QElectroTech, you can help developers to buy new hardware to test
|
||||
and implement new features. Thanks in advance for your generous donations.
|
||||
|
||||
For more information, look at [Paypal](https://www.paypal.com/donate/?token=rqf80cP0Ck1F2jn4Y46G7tIPv9bq7x0crXkwt3GZ6OZYG6ihJYi8lZxmmQ8itsFwMUdd1G&country.x=GB&locale.x=GB)
|
||||
or at [leetchi.com](https://www.leetchi.com/c/qelectroteck)
|
||||
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
__3.0.18__
|
||||
----------
|
||||
|
||||
* Fallback to standard QApplication class on iOS and Android systems where
|
||||
the library is not supported.
|
||||
|
||||
* Added Build CI tests to verify the library builds successfully on Linux, Windows and MacOS across multiple Qt versions.
|
||||
|
||||
_Anton Filimonov_
|
||||
|
||||
__3.0.17__
|
||||
----------
|
||||
|
||||
* Fixed compilation warning/error caused by `geteuid()` on unix based systems.
|
||||
|
||||
_Iakov Kirilenko_
|
||||
|
||||
* Added CMake support
|
||||
|
||||
_Hennadii Chernyshchyk_
|
||||
|
||||
__3.0.16__
|
||||
----------
|
||||
|
||||
* Use geteuid and getpwuid to get username on Unix, fallback to environment variable.
|
||||
|
||||
_Jonas Kvinge_
|
||||
|
||||
__3.0.15__
|
||||
----------
|
||||
|
||||
* Bug Fix: sendMessage() might return false even though data was actually written.
|
||||
|
||||
_Jonas Kvinge_
|
||||
|
||||
__3.0.14__
|
||||
----------
|
||||
|
||||
* Fixed uninitialised variables in the `SingleApplicationPrivate` constructor.
|
||||
|
||||
__3.0.13a__
|
||||
----------
|
||||
|
||||
* Process socket events asynchronously
|
||||
* Fix undefined variable error on Windows
|
||||
|
||||
_Francis Giraldeau_
|
||||
|
||||
__3.0.12a__
|
||||
----------
|
||||
|
||||
* Removed signal handling.
|
||||
|
||||
__3.0.11a__
|
||||
----------
|
||||
|
||||
* Fixed bug where the message sent by the second process was not received
|
||||
correctly when the message is sent immediately following a connection.
|
||||
|
||||
_Francis Giraldeau_
|
||||
|
||||
* Refactored code and implemented shared memory block consistency checks
|
||||
via `qChecksum()` (CRC-16).
|
||||
* Explicit `qWarning` and `qCritical` when the library is unable to initialise
|
||||
correctly.
|
||||
|
||||
__3.0.10__
|
||||
----------
|
||||
|
||||
* Removed C style casts and eliminated all clang warnings. Fixed `instanceId`
|
||||
reading from only one byte in the message deserialization. Cleaned up
|
||||
serialization code using `QDataStream`. Changed connection type to use
|
||||
`quint8 enum` rather than `char`.
|
||||
* Renamed `SingleAppConnectionType` to `ConnectionType`. Added initialization
|
||||
values to all `ConnectionType` enum cases.
|
||||
|
||||
_Jedidiah Buck McCready_
|
||||
|
||||
__3.0.9__
|
||||
---------
|
||||
|
||||
* Added SingleApplicationPrivate::primaryPid() as a solution to allow
|
||||
bringing the primary window of an application to the foreground on
|
||||
Windows.
|
||||
|
||||
_Eelco van Dam from Peacs BV_
|
||||
|
||||
__3.0.8__
|
||||
---------
|
||||
|
||||
* Bug fix - changed QApplication::instance() to QCoreApplication::instance()
|
||||
|
||||
_Evgeniy Bazhenov_
|
||||
|
||||
__3.0.7a__
|
||||
----------
|
||||
|
||||
* Fixed compilation error with Mingw32 in MXE thanks to Vitaly Tonkacheyev.
|
||||
* Removed QMutex used for thread safe behaviour. The implementation now uses
|
||||
QCoreApplication::instance() to get an instance to SingleApplication for
|
||||
memory deallocation.
|
||||
|
||||
__3.0.6a__
|
||||
----------
|
||||
|
||||
* Reverted GetUserName API usage on Windows. Fixed bug with missing library.
|
||||
* Fixed bug in the Calculator example, preventing it's window to be raised
|
||||
on Windows.
|
||||
|
||||
Special thanks to Charles Gunawan.
|
||||
|
||||
__3.0.5a__
|
||||
----------
|
||||
|
||||
* Fixed a memory leak in the SingleApplicationPrivate destructor.
|
||||
|
||||
_Sergei Moiseev_
|
||||
|
||||
__3.0.4a__
|
||||
----------
|
||||
|
||||
* Fixed shadow and uninitialised variable warnings.
|
||||
|
||||
_Paul Walmsley_
|
||||
|
||||
__3.0.3a__
|
||||
----------
|
||||
|
||||
* Removed Microsoft Windows specific code for getting username due to
|
||||
multiple problems and compiler differences on Windows platforms. On
|
||||
Windows the shared memory block in User mode now includes the user's
|
||||
home path (which contains the user's username).
|
||||
|
||||
* Explicitly getting absolute path of the user's home directory as on Unix
|
||||
a relative path (`~`) may be returned.
|
||||
|
||||
__3.0.2a__
|
||||
----------
|
||||
|
||||
* Fixed bug on Windows when username containing wide characters causes the
|
||||
library to crash.
|
||||
|
||||
_Le Liu_
|
||||
|
||||
__3.0.1a__
|
||||
----------
|
||||
|
||||
* Allows the application path and version to be excluded from the server name
|
||||
hash. The following flags were added for this purpose:
|
||||
* `SingleApplication::Mode::ExcludeAppVersion`
|
||||
* `SingleApplication::Mode::ExcludeAppPath`
|
||||
* Allow a non elevated process to connect to a local server created by an
|
||||
elevated process run by the same user on Windows
|
||||
* Fixes a problem with upper case letters in paths on Windows
|
||||
|
||||
_Le Liu_
|
||||
|
||||
__v3.0a__
|
||||
---------
|
||||
|
||||
* Deprecated secondary instances count.
|
||||
* Added a sendMessage() method to send a message to the primary instance.
|
||||
* Added a receivedMessage() signal, emitted when a message is received from a
|
||||
secondary instance.
|
||||
* The SingleApplication constructor's third parameter is now a bool
|
||||
specifying if the current instance should be allowed to run as a secondary
|
||||
instance if there is already a primary instance.
|
||||
* The SingleApplication constructor accept a fourth parameter specifying if
|
||||
the SingleApplication block should be User-wide or System-wide.
|
||||
* SingleApplication no longer relies on `applicationName` and
|
||||
`organizationName` to be set. It instead concatenates all of the following
|
||||
data and computes a `SHA256` hash which is used as the key of the
|
||||
`QSharedMemory` block and the `QLocalServer`. Since at least
|
||||
`applicationFilePath` is always present there is no need to explicitly set
|
||||
any of the following prior to initialising `SingleApplication`.
|
||||
* `QCoreApplication::applicationName`
|
||||
* `QCoreApplication::applicationVersion`
|
||||
* `QCoreApplication::applicationFilePath`
|
||||
* `QCoreApplication::organizationName`
|
||||
* `QCoreApplication::organizationDomain`
|
||||
* User name or home directory path if in User mode
|
||||
* The primary instance is no longer notified when a secondary instance had
|
||||
been started by default. A `Mode` flag for this feature exists.
|
||||
* Added `instanceNumber()` which represents a unique identifier for each
|
||||
secondary instance started. When called from the primary instance will
|
||||
return `0`.
|
||||
|
||||
__v2.4__
|
||||
--------
|
||||
|
||||
* Stability improvements
|
||||
* Support for secondary instances.
|
||||
* The library now recovers safely after the primary process has crashed
|
||||
and the shared memory had not been deleted.
|
||||
|
||||
__v2.3__
|
||||
--------
|
||||
|
||||
* Improved pimpl design and inheritance safety.
|
||||
|
||||
_Vladislav Pyatnichenko_
|
||||
|
||||
__v2.2__
|
||||
--------
|
||||
|
||||
* The `QAPPLICATION_CLASS` macro can now be defined in the file including the
|
||||
Single Application header or with a `DEFINES+=` statement in the project file.
|
||||
|
||||
__v2.1__
|
||||
--------
|
||||
|
||||
* A race condition can no longer occur when starting two processes nearly
|
||||
simultaneously.
|
||||
|
||||
Fix issue [#3](https://github.com/itay-grudev/SingleApplication/issues/3)
|
||||
|
||||
__v2.0__
|
||||
--------
|
||||
|
||||
* SingleApplication is now being passed a reference to `argc` instead of a
|
||||
copy.
|
||||
|
||||
Fix issue [#1](https://github.com/itay-grudev/SingleApplication/issues/1)
|
||||
|
||||
* Improved documentation.
|
||||
@@ -1,43 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.1.0)
|
||||
|
||||
project(SingleApplication)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
# SingleApplication base class
|
||||
set(QAPPLICATION_CLASS QCoreApplication CACHE STRING "Inheritance class for SingleApplication")
|
||||
set_property(CACHE QAPPLICATION_CLASS PROPERTY STRINGS QApplication QGuiApplication QCoreApplication)
|
||||
|
||||
# Libary target
|
||||
add_library(${PROJECT_NAME} STATIC
|
||||
singleapplication.cpp
|
||||
singleapplication_p.cpp
|
||||
)
|
||||
|
||||
# Find dependencies
|
||||
find_package(Qt5Network)
|
||||
if(QAPPLICATION_CLASS STREQUAL QApplication)
|
||||
find_package(Qt5 COMPONENTS Widgets REQUIRED)
|
||||
elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication)
|
||||
find_package(Qt5 COMPONENTS Gui REQUIRED)
|
||||
else()
|
||||
find_package(Qt5 COMPONENTS Core REQUIRED)
|
||||
endif()
|
||||
add_compile_definitions(QAPPLICATION_CLASS=${QAPPLICATION_CLASS})
|
||||
|
||||
# Link dependencies
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Network)
|
||||
if(QAPPLICATION_CLASS STREQUAL QApplication)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets)
|
||||
elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Gui)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE advapi32)
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
@@ -1,24 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Itay Grudev 2015 - 2016
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Note: Some of the examples include code not distributed under the terms of the
|
||||
MIT License.
|
||||
@@ -1,277 +0,0 @@
|
||||
SingleApplication
|
||||
=================
|
||||
|
||||
This is a replacement of the QtSingleApplication for `Qt5`.
|
||||
|
||||
Keeps the Primary Instance of your Application and kills each subsequent
|
||||
instances. It can (if enabled) spawn secondary (non-related to the primary)
|
||||
instances and can send data to the primary instance from secondary instances.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
The `SingleApplication` class inherits from whatever `Q[Core|Gui]Application`
|
||||
class you specify via the `QAPPLICATION_CLASS` macro (`QCoreApplication` is the
|
||||
default). Further usage is similar to the use of the `Q[Core|Gui]Application`
|
||||
classes.
|
||||
|
||||
The library sets up a `QLocalServer` and a `QSharedMemory` block. The first
|
||||
instance of your Application is your Primary Instance. It would check if the
|
||||
shared memory block exists and if not it will start a `QLocalServer` and listen
|
||||
for connections. Each subsequent instance of your application would check if the
|
||||
shared memory block exists and if it does, it will connect to the QLocalServer
|
||||
to notify the primary instance that a new instance had been started, after which
|
||||
it would terminate with status code `0`. In the Primary Instance
|
||||
`SingleApplication` would emit the `instanceStarted()` signal upon detecting
|
||||
that a new instance had been started.
|
||||
|
||||
The library uses `stdlib` to terminate the program with the `exit()` function.
|
||||
|
||||
You can use the library as if you use any other `QCoreApplication` derived
|
||||
class:
|
||||
|
||||
```cpp
|
||||
#include <QApplication>
|
||||
#include <SingleApplication.h>
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
SingleApplication app( argc, argv );
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
```
|
||||
|
||||
To include the library files I would recommend that you add it as a git
|
||||
submodule to your project and include it's contents with a `.pri` file. Here is
|
||||
how:
|
||||
|
||||
```bash
|
||||
git submodule add git@github.com:itay-grudev/SingleApplication.git singleapplication
|
||||
```
|
||||
|
||||
**Qmake:**
|
||||
|
||||
Then include the `singleapplication.pri` file in your `.pro` project file.
|
||||
|
||||
```qmake
|
||||
include(singleapplication/singleapplication.pri)
|
||||
DEFINES += QAPPLICATION_CLASS=QApplication
|
||||
```
|
||||
|
||||
**CMake:**
|
||||
|
||||
Then include the subdirectory in your `CMakeLists.txt` project file.
|
||||
|
||||
```cmake
|
||||
set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication")
|
||||
add_subdirectory(src/third-party/singleapplication)
|
||||
```
|
||||
|
||||
Also don't forget to specify which `QCoreApplication` class your app is using if it
|
||||
is not `QCoreApplication` as in examples above.
|
||||
|
||||
The `Instance Started` signal
|
||||
------------------------
|
||||
|
||||
The SingleApplication class implements a `instanceStarted()` signal. You can
|
||||
bind to that signal to raise your application's window when a new instance had
|
||||
been started, for example.
|
||||
|
||||
```cpp
|
||||
// window is a QWindow instance
|
||||
QObject::connect(
|
||||
&app,
|
||||
&SingleApplication::instanceStarted,
|
||||
&window,
|
||||
&QWindow::raise
|
||||
);
|
||||
```
|
||||
|
||||
Using `SingleApplication::instance()` is a neat way to get the
|
||||
`SingleApplication` instance for binding to it's signals anywhere in your
|
||||
program.
|
||||
|
||||
__Note:__ On Windows the ability to bring the application windows to the
|
||||
foreground is restricted. See [Windows specific implementations](Windows.md)
|
||||
for a workaround and an example implementation.
|
||||
|
||||
|
||||
Secondary Instances
|
||||
-------------------
|
||||
|
||||
If you want to be able to launch additional Secondary Instances (not related to
|
||||
your Primary Instance) you have to enable that with the third parameter of the
|
||||
`SingleApplication` constructor. The default is `false` meaning no Secondary
|
||||
Instances. Here is an example of how you would start a Secondary Instance send
|
||||
a message with the command line arguments to the primary instance and then shut
|
||||
down.
|
||||
|
||||
```cpp
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SingleApplication app( argc, argv, true );
|
||||
|
||||
if( app.isSecondary() ) {
|
||||
app.sendMessage( app.arguments().join(' ')).toUtf8() );
|
||||
app.exit( 0 );
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
```
|
||||
|
||||
*__Note:__ A secondary instance won't cause the emission of the
|
||||
`instanceStarted()` signal by default. See `SingleApplication::Mode` for more
|
||||
details.*
|
||||
|
||||
You can check whether your instance is a primary or secondary with the following
|
||||
methods:
|
||||
|
||||
```cpp
|
||||
app.isPrimary();
|
||||
// or
|
||||
app.isSecondary();
|
||||
```
|
||||
|
||||
*__Note:__ If your Primary Instance is terminated a newly launched instance
|
||||
will replace the Primary one even if the Secondary flag has been set.*
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
### Members
|
||||
|
||||
```cpp
|
||||
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100 )
|
||||
```
|
||||
|
||||
Depending on whether `allowSecondary` is set, this constructor may terminate
|
||||
your app if there is already a primary instance running. Additional `Options`
|
||||
can be specified to set whether the SingleApplication block should work
|
||||
user-wide or system-wide. Additionally the `Mode::SecondaryNotification` may be
|
||||
used to notify the primary instance whenever a secondary instance had been
|
||||
started (disabled by default). `timeout` specifies the maximum time in
|
||||
milliseconds to wait for blocking operations.
|
||||
|
||||
*__Note:__ `argc` and `argv` may be changed as Qt removes arguments that it
|
||||
recognizes.*
|
||||
|
||||
*__Note:__ `Mode::SecondaryNotification` only works if set on both the primary
|
||||
and the secondary instance.*
|
||||
|
||||
*__Note:__ Operating system can restrict the shared memory blocks to the same
|
||||
user, in which case the User/System modes will have no effect and the block will
|
||||
be user wide.*
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
bool SingleApplication::sendMessage( QByteArray message, int timeout = 100 )
|
||||
```
|
||||
|
||||
Sends `message` to the Primary Instance. Uses `timeout` as a the maximum timeout
|
||||
in milliseconds for blocking functions
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
bool SingleApplication::isPrimary()
|
||||
```
|
||||
|
||||
Returns if the instance is the primary instance.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
bool SingleApplication::isSecondary()
|
||||
```
|
||||
Returns if the instance is a secondary instance.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
quint32 SingleApplication::instanceId()
|
||||
```
|
||||
|
||||
Returns a unique identifier for the current instance.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
qint64 SingleApplication::primaryPid()
|
||||
```
|
||||
|
||||
Returns the process ID (PID) of the primary instance.
|
||||
|
||||
### Signals
|
||||
|
||||
```cpp
|
||||
void SingleApplication::instanceStarted()
|
||||
```
|
||||
|
||||
Triggered whenever a new instance had been started, except for secondary
|
||||
instances if the `Mode::SecondaryNotification` flag is not specified.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void SingleApplication::receivedMessage( quint32 instanceId, QByteArray message )
|
||||
```
|
||||
|
||||
Triggered whenever there is a message received from a secondary instance.
|
||||
|
||||
---
|
||||
|
||||
### Flags
|
||||
|
||||
```cpp
|
||||
enum SingleApplication::Mode
|
||||
```
|
||||
|
||||
* `Mode::User` - The SingleApplication block should apply user wide. This adds
|
||||
user specific data to the key used for the shared memory and server name.
|
||||
This is the default functionality.
|
||||
* `Mode::System` – The SingleApplication block applies system-wide.
|
||||
* `Mode::SecondaryNotification` – Whether to trigger `instanceStarted()` even
|
||||
whenever secondary instances are started.
|
||||
* `Mode::ExcludeAppPath` – Excludes the application path from the server name
|
||||
(and memory block) hash.
|
||||
* `Mode::ExcludeAppVersion` – Excludes the application version from the server
|
||||
name (and memory block) hash.
|
||||
|
||||
*__Note:__ `Mode::SecondaryNotification` only works if set on both the primary
|
||||
and the secondary instance.*
|
||||
|
||||
*__Note:__ Operating system can restrict the shared memory blocks to the same
|
||||
user, in which case the User/System modes will have no effect and the block will
|
||||
be user wide.*
|
||||
|
||||
---
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
Each major version introduces either very significant changes or is not
|
||||
backwards compatible with the previous version. Minor versions only add
|
||||
additional features, bug fixes or performance improvements and are backwards
|
||||
compatible with the previous release. See [`CHANGELOG.md`](CHANGELOG.md) for
|
||||
more details.
|
||||
|
||||
Implementation
|
||||
--------------
|
||||
|
||||
The library is implemented with a QSharedMemory block which is thread safe and
|
||||
guarantees a race condition will not occur. It also uses a QLocalSocket to
|
||||
notify the main process that a new instance had been spawned and thus invoke the
|
||||
`instanceStarted()` signal and for messaging the primary instance.
|
||||
|
||||
Additionally the library can recover from being forcefully killed on *nix
|
||||
systems and will reset the memory block given that there are no other
|
||||
instances running.
|
||||
|
||||
License
|
||||
-------
|
||||
This library and it's supporting documentation are released under
|
||||
`The MIT License (MIT)` with the exception of the Qt calculator examples which
|
||||
is distributed under the BSD license.
|
||||
@@ -1,46 +0,0 @@
|
||||
Windows Specific Implementations
|
||||
================================
|
||||
|
||||
Setting the foreground window
|
||||
-----------------------------
|
||||
|
||||
In the `instanceStarted()` example in the `README` we demonstrated how an
|
||||
application can bring it's primary instance window whenever a second copy
|
||||
of the application is started.
|
||||
|
||||
On Windows the ability to bring the application windows to the foreground is
|
||||
restricted, see [`AllowSetForegroundWindow()`][AllowSetForegroundWindow] for more
|
||||
details.
|
||||
|
||||
The background process (the primary instance) can bring its windows to the
|
||||
foreground if it is allowed by the current foreground process (the secondary
|
||||
instance). To bypass this `SingleApplication` must be initialized with the
|
||||
`allowSecondary` parameter set to `true` and the `options` parameter must
|
||||
include `Mode::SecondaryNotification`, See `SingleApplication::Mode` for more
|
||||
details.
|
||||
|
||||
Here is an example:
|
||||
|
||||
```cpp
|
||||
if( app.isSecondary() ) {
|
||||
// This API requires LIBS += User32.lib to be added to the project
|
||||
AllowSetForegroundWindow( DWORD( app.primaryPid() ) );
|
||||
}
|
||||
|
||||
if( app.isPrimary() ) {
|
||||
QObject::connect(
|
||||
&app,
|
||||
&SingleApplication::instanceStarted,
|
||||
this,
|
||||
&App::instanceStarted
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
```cpp
|
||||
void App::instanceStarted() {
|
||||
QApplication::setActiveWindow( [window/widget to set to the foreground] );
|
||||
}
|
||||
```
|
||||
|
||||
[AllowSetForegroundWindow]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms632668.aspx
|
||||
@@ -1,5 +0,0 @@
|
||||
# Single Application implementation
|
||||
include(../../singleapplication.pri)
|
||||
DEFINES += QAPPLICATION_CLASS=QCoreApplication
|
||||
|
||||
SOURCES += main.cpp
|
||||
@@ -1,9 +0,0 @@
|
||||
#include <singleapplication.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Allow secondary instances
|
||||
SingleApplication app( argc, argv );
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "button.h"
|
||||
|
||||
//! [0]
|
||||
Button::Button(const QString &text, QWidget *parent)
|
||||
: QToolButton(parent)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
setText(text);
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
QSize Button::sizeHint() const
|
||||
//! [1] //! [2]
|
||||
{
|
||||
QSize size = QToolButton::sizeHint();
|
||||
size.rheight() += 20;
|
||||
size.rwidth() = qMax(size.width(), size.height());
|
||||
return size;
|
||||
}
|
||||
//! [2]
|
||||
@@ -1,68 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef BUTTON_H
|
||||
#define BUTTON_H
|
||||
|
||||
#include <QToolButton>
|
||||
|
||||
//! [0]
|
||||
class Button : public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Button(const QString &text, QWidget *parent = 0);
|
||||
|
||||
QSize sizeHint() const Q_DECL_OVERRIDE;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
||||
@@ -1,406 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "button.h"
|
||||
#include "calculator.h"
|
||||
|
||||
//! [0]
|
||||
Calculator::Calculator(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
sumInMemory = 0.0;
|
||||
sumSoFar = 0.0;
|
||||
factorSoFar = 0.0;
|
||||
waitingForOperand = true;
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
display = new QLineEdit("0");
|
||||
//! [1] //! [2]
|
||||
display->setReadOnly(true);
|
||||
display->setAlignment(Qt::AlignRight);
|
||||
display->setMaxLength(15);
|
||||
|
||||
QFont font = display->font();
|
||||
font.setPointSize(font.pointSize() + 8);
|
||||
display->setFont(font);
|
||||
//! [2]
|
||||
|
||||
//! [4]
|
||||
for (int i = 0; i < NumDigitButtons; ++i) {
|
||||
digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked()));
|
||||
}
|
||||
|
||||
Button *pointButton = createButton(tr("."), SLOT(pointClicked()));
|
||||
Button *changeSignButton = createButton(tr("\302\261"), SLOT(changeSignClicked()));
|
||||
|
||||
Button *backspaceButton = createButton(tr("Backspace"), SLOT(backspaceClicked()));
|
||||
Button *clearButton = createButton(tr("Clear"), SLOT(clear()));
|
||||
Button *clearAllButton = createButton(tr("Clear All"), SLOT(clearAll()));
|
||||
|
||||
Button *clearMemoryButton = createButton(tr("MC"), SLOT(clearMemory()));
|
||||
Button *readMemoryButton = createButton(tr("MR"), SLOT(readMemory()));
|
||||
Button *setMemoryButton = createButton(tr("MS"), SLOT(setMemory()));
|
||||
Button *addToMemoryButton = createButton(tr("M+"), SLOT(addToMemory()));
|
||||
|
||||
Button *divisionButton = createButton(tr("\303\267"), SLOT(multiplicativeOperatorClicked()));
|
||||
Button *timesButton = createButton(tr("\303\227"), SLOT(multiplicativeOperatorClicked()));
|
||||
Button *minusButton = createButton(tr("-"), SLOT(additiveOperatorClicked()));
|
||||
Button *plusButton = createButton(tr("+"), SLOT(additiveOperatorClicked()));
|
||||
|
||||
Button *squareRootButton = createButton(tr("Sqrt"), SLOT(unaryOperatorClicked()));
|
||||
Button *powerButton = createButton(tr("x\302\262"), SLOT(unaryOperatorClicked()));
|
||||
Button *reciprocalButton = createButton(tr("1/x"), SLOT(unaryOperatorClicked()));
|
||||
Button *equalButton = createButton(tr("="), SLOT(equalClicked()));
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
QGridLayout *mainLayout = new QGridLayout;
|
||||
//! [5] //! [6]
|
||||
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
mainLayout->addWidget(display, 0, 0, 1, 6);
|
||||
mainLayout->addWidget(backspaceButton, 1, 0, 1, 2);
|
||||
mainLayout->addWidget(clearButton, 1, 2, 1, 2);
|
||||
mainLayout->addWidget(clearAllButton, 1, 4, 1, 2);
|
||||
|
||||
mainLayout->addWidget(clearMemoryButton, 2, 0);
|
||||
mainLayout->addWidget(readMemoryButton, 3, 0);
|
||||
mainLayout->addWidget(setMemoryButton, 4, 0);
|
||||
mainLayout->addWidget(addToMemoryButton, 5, 0);
|
||||
|
||||
for (int i = 1; i < NumDigitButtons; ++i) {
|
||||
int row = ((9 - i) / 3) + 2;
|
||||
int column = ((i - 1) % 3) + 1;
|
||||
mainLayout->addWidget(digitButtons[i], row, column);
|
||||
}
|
||||
|
||||
mainLayout->addWidget(digitButtons[0], 5, 1);
|
||||
mainLayout->addWidget(pointButton, 5, 2);
|
||||
mainLayout->addWidget(changeSignButton, 5, 3);
|
||||
|
||||
mainLayout->addWidget(divisionButton, 2, 4);
|
||||
mainLayout->addWidget(timesButton, 3, 4);
|
||||
mainLayout->addWidget(minusButton, 4, 4);
|
||||
mainLayout->addWidget(plusButton, 5, 4);
|
||||
|
||||
mainLayout->addWidget(squareRootButton, 2, 5);
|
||||
mainLayout->addWidget(powerButton, 3, 5);
|
||||
mainLayout->addWidget(reciprocalButton, 4, 5);
|
||||
mainLayout->addWidget(equalButton, 5, 5);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Calculator"));
|
||||
}
|
||||
//! [6]
|
||||
|
||||
//! [7]
|
||||
void Calculator::digitClicked()
|
||||
{
|
||||
Button *clickedButton = qobject_cast<Button *>(sender());
|
||||
int digitValue = clickedButton->text().toInt();
|
||||
if (display->text() == "0" && digitValue == 0.0)
|
||||
return;
|
||||
|
||||
if (waitingForOperand) {
|
||||
display->clear();
|
||||
waitingForOperand = false;
|
||||
}
|
||||
display->setText(display->text() + QString::number(digitValue));
|
||||
}
|
||||
//! [7]
|
||||
|
||||
//! [8]
|
||||
void Calculator::unaryOperatorClicked()
|
||||
//! [8] //! [9]
|
||||
{
|
||||
Button *clickedButton = qobject_cast<Button *>(sender());
|
||||
QString clickedOperator = clickedButton->text();
|
||||
double operand = display->text().toDouble();
|
||||
double result = 0.0;
|
||||
|
||||
if (clickedOperator == tr("Sqrt")) {
|
||||
if (operand < 0.0) {
|
||||
abortOperation();
|
||||
return;
|
||||
}
|
||||
result = std::sqrt(operand);
|
||||
} else if (clickedOperator == tr("x\302\262")) {
|
||||
result = std::pow(operand, 2.0);
|
||||
} else if (clickedOperator == tr("1/x")) {
|
||||
if (operand == 0.0) {
|
||||
abortOperation();
|
||||
return;
|
||||
}
|
||||
result = 1.0 / operand;
|
||||
}
|
||||
display->setText(QString::number(result));
|
||||
waitingForOperand = true;
|
||||
}
|
||||
//! [9]
|
||||
|
||||
//! [10]
|
||||
void Calculator::additiveOperatorClicked()
|
||||
//! [10] //! [11]
|
||||
{
|
||||
Button *clickedButton = qobject_cast<Button *>(sender());
|
||||
QString clickedOperator = clickedButton->text();
|
||||
double operand = display->text().toDouble();
|
||||
|
||||
//! [11] //! [12]
|
||||
if (!pendingMultiplicativeOperator.isEmpty()) {
|
||||
//! [12] //! [13]
|
||||
if (!calculate(operand, pendingMultiplicativeOperator)) {
|
||||
abortOperation();
|
||||
return;
|
||||
}
|
||||
display->setText(QString::number(factorSoFar));
|
||||
operand = factorSoFar;
|
||||
factorSoFar = 0.0;
|
||||
pendingMultiplicativeOperator.clear();
|
||||
}
|
||||
|
||||
//! [13] //! [14]
|
||||
if (!pendingAdditiveOperator.isEmpty()) {
|
||||
//! [14] //! [15]
|
||||
if (!calculate(operand, pendingAdditiveOperator)) {
|
||||
abortOperation();
|
||||
return;
|
||||
}
|
||||
display->setText(QString::number(sumSoFar));
|
||||
} else {
|
||||
sumSoFar = operand;
|
||||
}
|
||||
|
||||
//! [15] //! [16]
|
||||
pendingAdditiveOperator = clickedOperator;
|
||||
//! [16] //! [17]
|
||||
waitingForOperand = true;
|
||||
}
|
||||
//! [17]
|
||||
|
||||
//! [18]
|
||||
void Calculator::multiplicativeOperatorClicked()
|
||||
{
|
||||
Button *clickedButton = qobject_cast<Button *>(sender());
|
||||
QString clickedOperator = clickedButton->text();
|
||||
double operand = display->text().toDouble();
|
||||
|
||||
if (!pendingMultiplicativeOperator.isEmpty()) {
|
||||
if (!calculate(operand, pendingMultiplicativeOperator)) {
|
||||
abortOperation();
|
||||
return;
|
||||
}
|
||||
display->setText(QString::number(factorSoFar));
|
||||
} else {
|
||||
factorSoFar = operand;
|
||||
}
|
||||
|
||||
pendingMultiplicativeOperator = clickedOperator;
|
||||
waitingForOperand = true;
|
||||
}
|
||||
//! [18]
|
||||
|
||||
//! [20]
|
||||
void Calculator::equalClicked()
|
||||
{
|
||||
double operand = display->text().toDouble();
|
||||
|
||||
if (!pendingMultiplicativeOperator.isEmpty()) {
|
||||
if (!calculate(operand, pendingMultiplicativeOperator)) {
|
||||
abortOperation();
|
||||
return;
|
||||
}
|
||||
operand = factorSoFar;
|
||||
factorSoFar = 0.0;
|
||||
pendingMultiplicativeOperator.clear();
|
||||
}
|
||||
if (!pendingAdditiveOperator.isEmpty()) {
|
||||
if (!calculate(operand, pendingAdditiveOperator)) {
|
||||
abortOperation();
|
||||
return;
|
||||
}
|
||||
pendingAdditiveOperator.clear();
|
||||
} else {
|
||||
sumSoFar = operand;
|
||||
}
|
||||
|
||||
display->setText(QString::number(sumSoFar));
|
||||
sumSoFar = 0.0;
|
||||
waitingForOperand = true;
|
||||
}
|
||||
//! [20]
|
||||
|
||||
//! [22]
|
||||
void Calculator::pointClicked()
|
||||
{
|
||||
if (waitingForOperand)
|
||||
display->setText("0");
|
||||
if (!display->text().contains('.'))
|
||||
display->setText(display->text() + tr("."));
|
||||
waitingForOperand = false;
|
||||
}
|
||||
//! [22]
|
||||
|
||||
//! [24]
|
||||
void Calculator::changeSignClicked()
|
||||
{
|
||||
QString text = display->text();
|
||||
double value = text.toDouble();
|
||||
|
||||
if (value > 0.0) {
|
||||
text.prepend(tr("-"));
|
||||
} else if (value < 0.0) {
|
||||
text.remove(0, 1);
|
||||
}
|
||||
display->setText(text);
|
||||
}
|
||||
//! [24]
|
||||
|
||||
//! [26]
|
||||
void Calculator::backspaceClicked()
|
||||
{
|
||||
if (waitingForOperand)
|
||||
return;
|
||||
|
||||
QString text = display->text();
|
||||
text.chop(1);
|
||||
if (text.isEmpty()) {
|
||||
text = "0";
|
||||
waitingForOperand = true;
|
||||
}
|
||||
display->setText(text);
|
||||
}
|
||||
//! [26]
|
||||
|
||||
//! [28]
|
||||
void Calculator::clear()
|
||||
{
|
||||
if (waitingForOperand)
|
||||
return;
|
||||
|
||||
display->setText("0");
|
||||
waitingForOperand = true;
|
||||
}
|
||||
//! [28]
|
||||
|
||||
//! [30]
|
||||
void Calculator::clearAll()
|
||||
{
|
||||
sumSoFar = 0.0;
|
||||
factorSoFar = 0.0;
|
||||
pendingAdditiveOperator.clear();
|
||||
pendingMultiplicativeOperator.clear();
|
||||
display->setText("0");
|
||||
waitingForOperand = true;
|
||||
}
|
||||
//! [30]
|
||||
|
||||
//! [32]
|
||||
void Calculator::clearMemory()
|
||||
{
|
||||
sumInMemory = 0.0;
|
||||
}
|
||||
|
||||
void Calculator::readMemory()
|
||||
{
|
||||
display->setText(QString::number(sumInMemory));
|
||||
waitingForOperand = true;
|
||||
}
|
||||
|
||||
void Calculator::setMemory()
|
||||
{
|
||||
equalClicked();
|
||||
sumInMemory = display->text().toDouble();
|
||||
}
|
||||
|
||||
void Calculator::addToMemory()
|
||||
{
|
||||
equalClicked();
|
||||
sumInMemory += display->text().toDouble();
|
||||
}
|
||||
//! [32]
|
||||
//! [34]
|
||||
Button *Calculator::createButton(const QString &text, const char *member)
|
||||
{
|
||||
Button *button = new Button(text);
|
||||
connect(button, SIGNAL(clicked()), this, member);
|
||||
return button;
|
||||
}
|
||||
//! [34]
|
||||
|
||||
//! [36]
|
||||
void Calculator::abortOperation()
|
||||
{
|
||||
clearAll();
|
||||
display->setText(tr("####"));
|
||||
}
|
||||
//! [36]
|
||||
|
||||
//! [38]
|
||||
bool Calculator::calculate(double rightOperand, const QString &pendingOperator)
|
||||
{
|
||||
if (pendingOperator == tr("+")) {
|
||||
sumSoFar += rightOperand;
|
||||
} else if (pendingOperator == tr("-")) {
|
||||
sumSoFar -= rightOperand;
|
||||
} else if (pendingOperator == tr("\303\227")) {
|
||||
factorSoFar *= rightOperand;
|
||||
} else if (pendingOperator == tr("\303\267")) {
|
||||
if (rightOperand == 0.0)
|
||||
return false;
|
||||
factorSoFar /= rightOperand;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//! [38]
|
||||
@@ -1,117 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CALCULATOR_H
|
||||
#define CALCULATOR_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QLineEdit;
|
||||
QT_END_NAMESPACE
|
||||
class Button;
|
||||
|
||||
//! [0]
|
||||
class Calculator : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Calculator(QWidget *parent = 0);
|
||||
|
||||
private slots:
|
||||
void digitClicked();
|
||||
void unaryOperatorClicked();
|
||||
void additiveOperatorClicked();
|
||||
void multiplicativeOperatorClicked();
|
||||
void equalClicked();
|
||||
void pointClicked();
|
||||
void changeSignClicked();
|
||||
void backspaceClicked();
|
||||
void clear();
|
||||
void clearAll();
|
||||
void clearMemory();
|
||||
void readMemory();
|
||||
void setMemory();
|
||||
void addToMemory();
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
private:
|
||||
//! [1] //! [2]
|
||||
Button *createButton(const QString &text, const char *member);
|
||||
void abortOperation();
|
||||
bool calculate(double rightOperand, const QString &pendingOperator);
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
double sumInMemory;
|
||||
//! [3] //! [4]
|
||||
double sumSoFar;
|
||||
//! [4] //! [5]
|
||||
double factorSoFar;
|
||||
//! [5] //! [6]
|
||||
QString pendingAdditiveOperator;
|
||||
//! [6] //! [7]
|
||||
QString pendingMultiplicativeOperator;
|
||||
//! [7] //! [8]
|
||||
bool waitingForOperand;
|
||||
//! [8]
|
||||
|
||||
//! [9]
|
||||
QLineEdit *display;
|
||||
//! [9] //! [10]
|
||||
|
||||
enum { NumDigitButtons = 10 };
|
||||
Button *digitButtons[NumDigitButtons];
|
||||
};
|
||||
//! [10]
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
QT += widgets
|
||||
|
||||
HEADERS = button.h \
|
||||
calculator.h
|
||||
SOURCES = button.cpp \
|
||||
calculator.cpp \
|
||||
main.cpp
|
||||
|
||||
# Single Application implementation
|
||||
include(../../singleapplication.pri)
|
||||
DEFINES += QAPPLICATION_CLASS=QApplication
|
||||
@@ -1,71 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include <singleapplication.h>
|
||||
|
||||
#include "calculator.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SingleApplication app(argc, argv);
|
||||
|
||||
Calculator calc;
|
||||
|
||||
QObject::connect( &app, &SingleApplication::instanceStarted, [ &calc ]() {
|
||||
calc.raise();
|
||||
calc.activateWindow();
|
||||
});
|
||||
|
||||
calc.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
#include <singleapplication.h>
|
||||
#include "messagereceiver.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Allow secondary instances
|
||||
SingleApplication app( argc, argv, true );
|
||||
|
||||
MessageReceiver msgReceiver;
|
||||
|
||||
// If this is a secondary instance
|
||||
if( app.isSecondary() ) {
|
||||
app.sendMessage( app.arguments().join(' ').toUtf8() );
|
||||
return 0;
|
||||
} else {
|
||||
QObject::connect(
|
||||
&app,
|
||||
&SingleApplication::receivedMessage,
|
||||
&msgReceiver,
|
||||
&MessageReceiver::receivedMessage
|
||||
);
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#include <QDebug>
|
||||
#include "messagereceiver.h"
|
||||
|
||||
MessageReceiver::MessageReceiver(QObject *parent) : QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void MessageReceiver::receivedMessage(int instanceId, QByteArray message)
|
||||
{
|
||||
qDebug() << "Received message from instance: " << instanceId;
|
||||
qDebug() << "Message Text: " << message;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef MESSAGERECEIVER_H
|
||||
#define MESSAGERECEIVER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class MessageReceiver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MessageReceiver(QObject *parent = 0);
|
||||
public slots:
|
||||
void receivedMessage( int instanceId, QByteArray message );
|
||||
};
|
||||
|
||||
#endif // MESSAGERECEIVER_H
|
||||
@@ -1,9 +0,0 @@
|
||||
# Single Application implementation
|
||||
include(../../singleapplication.pri)
|
||||
DEFINES += QAPPLICATION_CLASS=QCoreApplication
|
||||
|
||||
SOURCES += main.cpp \
|
||||
messagereceiver.cpp
|
||||
|
||||
HEADERS += \
|
||||
messagereceiver.h
|
||||
@@ -1,195 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2018
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <QtCore/QTime>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QSharedMemory>
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) // ### Qt 6: remove
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 5.10 or later")
|
||||
#endif
|
||||
#include <QRandomGenerator>
|
||||
#endif
|
||||
#include "singleapplication.h"
|
||||
#include "singleapplication_p.h"
|
||||
|
||||
/**
|
||||
@brief Constructor. Checks and fires up LocalServer or closes the program
|
||||
if another instance already exists
|
||||
@param argc
|
||||
@param argv
|
||||
@param {bool} allowSecondaryInstances
|
||||
*/
|
||||
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout )
|
||||
: app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) )
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
// On Android and iOS since the library is not supported fallback to
|
||||
// standard QApplication behaviour by simply returning at this point.
|
||||
qWarning() << "SingleApplication is not supported on Android and iOS systems.";
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Store the current mode of the program
|
||||
d->options = options;
|
||||
|
||||
// Generating an application ID used for identifying the shared memory
|
||||
// block and QLocalServer
|
||||
d->genBlockServerName();
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
// By explicitly attaching it and then deleting it we make sure that the
|
||||
// memory is deleted even after the process has crashed on Unix.
|
||||
d->memory = new QSharedMemory( d->blockServerName );
|
||||
d->memory->attach();
|
||||
delete d->memory;
|
||||
#endif
|
||||
// Guarantee thread safe behaviour with a shared memory block.
|
||||
d->memory = new QSharedMemory( d->blockServerName );
|
||||
|
||||
// Create a shared memory block
|
||||
if( d->memory->create( sizeof( InstancesInfo ) ) ) {
|
||||
// Initialize the shared memory block
|
||||
d->memory->lock();
|
||||
d->initializeMemoryBlock();
|
||||
d->memory->unlock();
|
||||
} else {
|
||||
// Attempt to attach to the memory segment
|
||||
if( ! d->memory->attach() ) {
|
||||
qCritical() << "SingleApplication: Unable to attach to shared memory block.";
|
||||
qCritical() << d->memory->errorString();
|
||||
delete d;
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>( d->memory->data() );
|
||||
QElapsedTimer time;
|
||||
time.start();
|
||||
|
||||
// Make sure the shared memory block is initialised and in consistent state
|
||||
while( true ) {
|
||||
d->memory->lock();
|
||||
|
||||
if( d->blockChecksum() == inst->checksum ) break;
|
||||
|
||||
if( time.elapsed() > 5000 ) {
|
||||
qWarning() << "SingleApplication: Shared memory block has been in an inconsistent state from more than 5s. Assuming primary instance failure.";
|
||||
d->initializeMemoryBlock();
|
||||
}
|
||||
|
||||
d->memory->unlock();
|
||||
|
||||
// Random sleep here limits the probability of a collision between two racing apps
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) // ### Qt 6: remove
|
||||
qsrand( QDateTime::currentMSecsSinceEpoch() % std::numeric_limits<uint>::max() );
|
||||
QThread::sleep( 8 + static_cast <unsigned long>( static_cast <float>( qrand() ) / RAND_MAX * 10 ) );
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 5.10 or later")
|
||||
#endif
|
||||
quint32 value = QRandomGenerator::global()->generate();
|
||||
QThread::sleep( 8 + static_cast <unsigned long>( static_cast <float>( value ) / RAND_MAX * 10 ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
if( inst->primary == false) {
|
||||
d->startPrimary();
|
||||
d->memory->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if another instance can be started
|
||||
if( allowSecondary ) {
|
||||
inst->secondary += 1;
|
||||
inst->checksum = d->blockChecksum();
|
||||
d->instanceNumber = inst->secondary;
|
||||
d->startSecondary();
|
||||
if( d->options & Mode::SecondaryNotification ) {
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance );
|
||||
}
|
||||
d->memory->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
d->memory->unlock();
|
||||
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance );
|
||||
|
||||
delete d;
|
||||
|
||||
::exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Destructor
|
||||
*/
|
||||
SingleApplication::~SingleApplication()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool SingleApplication::isPrimary()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->server != nullptr;
|
||||
}
|
||||
|
||||
bool SingleApplication::isSecondary()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->server == nullptr;
|
||||
}
|
||||
|
||||
quint32 SingleApplication::instanceId()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->instanceNumber;
|
||||
}
|
||||
|
||||
qint64 SingleApplication::primaryPid()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->primaryPid();
|
||||
}
|
||||
|
||||
bool SingleApplication::sendMessage( QByteArray message, int timeout )
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
|
||||
// Nobody to connect to
|
||||
if( isPrimary() ) return false;
|
||||
|
||||
// Make sure the socket is connected
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect );
|
||||
|
||||
d->socket->write( message );
|
||||
bool dataWritten = d->socket->waitForBytesWritten( timeout );
|
||||
d->socket->flush();
|
||||
return dataWritten;
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2018
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef SINGLE_APPLICATION_H
|
||||
#define SINGLE_APPLICATION_H
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#ifndef QAPPLICATION_CLASS
|
||||
#define QAPPLICATION_CLASS QCoreApplication
|
||||
#endif
|
||||
|
||||
#include QT_STRINGIFY(QAPPLICATION_CLASS)
|
||||
|
||||
class SingleApplicationPrivate;
|
||||
|
||||
/**
|
||||
@brief The SingleApplication class handles multiple instances of the same
|
||||
Application
|
||||
@see QCoreApplication
|
||||
*/
|
||||
class SingleApplication : public QAPPLICATION_CLASS
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
typedef QAPPLICATION_CLASS app_t;
|
||||
|
||||
public:
|
||||
/**
|
||||
@brief Mode of operation of SingleApplication.
|
||||
Whether the block should be user-wide or system-wide and whether the
|
||||
primary instance should be notified when a secondary instance had been
|
||||
started.
|
||||
@note Operating system can restrict the shared memory blocks to the same
|
||||
user, in which case the User/System modes will have no effect and the
|
||||
block will be user wide.
|
||||
@enum
|
||||
*/
|
||||
enum Mode {
|
||||
User = 1 << 0,
|
||||
System = 1 << 1,
|
||||
SecondaryNotification = 1 << 2,
|
||||
ExcludeAppVersion = 1 << 3,
|
||||
ExcludeAppPath = 1 << 4
|
||||
};
|
||||
Q_DECLARE_FLAGS(Options, Mode)
|
||||
|
||||
/**
|
||||
@brief Intitializes a SingleApplication instance with argc command line
|
||||
arguments in argv
|
||||
@arg {int &} argc - Number of arguments in argv
|
||||
@arg {const char *[]} argv - Supplied command line arguments
|
||||
@arg {bool} allowSecondary - Whether to start the instance as secondary
|
||||
if there is already a primary instance.
|
||||
@arg {Mode} mode - Whether for the SingleApplication block to be applied
|
||||
User wide or System wide.
|
||||
@arg {int} timeout - Timeout to wait in milliseconds.
|
||||
@note argc and argv may be changed as Qt removes arguments that it
|
||||
recognizes
|
||||
@note Mode::SecondaryNotification only works if set on both the primary
|
||||
instance and the secondary instance.
|
||||
@note The timeout is just a hint for the maximum time of blocking
|
||||
operations. It does not guarantee that the SingleApplication
|
||||
initialisation will be completed in given time, though is a good hint.
|
||||
Usually 4*timeout would be the worst case (fail) scenario.
|
||||
@see See the corresponding QAPPLICATION_CLASS constructor for reference
|
||||
*/
|
||||
explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000 );
|
||||
~SingleApplication();
|
||||
|
||||
/**
|
||||
@brief Returns if the instance is the primary instance
|
||||
@returns {bool}
|
||||
*/
|
||||
bool isPrimary();
|
||||
|
||||
/**
|
||||
@brief Returns if the instance is a secondary instance
|
||||
@returns {bool}
|
||||
*/
|
||||
bool isSecondary();
|
||||
|
||||
/**
|
||||
@brief Returns a unique identifier for the current instance
|
||||
@returns {qint32}
|
||||
*/
|
||||
quint32 instanceId();
|
||||
|
||||
/**
|
||||
@brief Returns the process ID (PID) of the primary instance
|
||||
@returns {qint64}
|
||||
*/
|
||||
qint64 primaryPid();
|
||||
|
||||
/**
|
||||
@brief Sends a message to the primary instance. Returns true on success.
|
||||
@param {int} timeout - Timeout for connecting
|
||||
@returns {bool}
|
||||
@note sendMessage() will return false if invoked from the primary
|
||||
instance.
|
||||
*/
|
||||
bool sendMessage( QByteArray message, int timeout = 100 );
|
||||
|
||||
Q_SIGNALS:
|
||||
void instanceStarted();
|
||||
void receivedMessage( quint32 instanceId, QByteArray message );
|
||||
|
||||
private:
|
||||
SingleApplicationPrivate *d_ptr;
|
||||
Q_DECLARE_PRIVATE(SingleApplication)
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options)
|
||||
|
||||
#endif // SINGLE_APPLICATION_H
|
||||
@@ -1,19 +0,0 @@
|
||||
QT += core network
|
||||
CONFIG += c++17
|
||||
|
||||
HEADERS += $$PWD/singleapplication.h \
|
||||
$$PWD/singleapplication_p.h
|
||||
SOURCES += $$PWD/singleapplication.cpp \
|
||||
$$PWD/singleapplication_p.cpp
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
win32 {
|
||||
msvc:LIBS += Advapi32.lib
|
||||
gcc:LIBS += -ladvapi32
|
||||
}
|
||||
|
||||
DISTFILES += \
|
||||
$$PWD/README.md \
|
||||
$$PWD/CHANGELOG.md \
|
||||
$$PWD/Windows.md
|
||||
@@ -1,444 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2018
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
//
|
||||
// W A R N I N G !!!
|
||||
// -----------------
|
||||
//
|
||||
// This file is not part of the SingleApplication API. It is used purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or may even be removed.
|
||||
//
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtCore/QCryptographicHash>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
|
||||
#include "singleapplication.h"
|
||||
#include "singleapplication_p.h"
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
#include <lmcons.h>
|
||||
#endif
|
||||
|
||||
SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr )
|
||||
: q_ptr( q_ptr )
|
||||
{
|
||||
server = nullptr;
|
||||
socket = nullptr;
|
||||
memory = nullptr;
|
||||
instanceNumber = -1;
|
||||
}
|
||||
|
||||
SingleApplicationPrivate::~SingleApplicationPrivate()
|
||||
{
|
||||
if( socket != nullptr ) {
|
||||
socket->close();
|
||||
delete socket;
|
||||
}
|
||||
|
||||
memory->lock();
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
||||
if( server != nullptr ) {
|
||||
server->close();
|
||||
delete server;
|
||||
inst->primary = false;
|
||||
inst->primaryPid = -1;
|
||||
inst->checksum = blockChecksum();
|
||||
}
|
||||
memory->unlock();
|
||||
|
||||
delete memory;
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::genBlockServerName()
|
||||
{
|
||||
QCryptographicHash appData( QCryptographicHash::Sha256 );
|
||||
appData.addData( "SingleApplication", 17 );
|
||||
appData.addData( SingleApplication::app_t::applicationName().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::organizationName().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() );
|
||||
|
||||
if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ) {
|
||||
appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() );
|
||||
}
|
||||
|
||||
if( ! (options & SingleApplication::Mode::ExcludeAppPath) ) {
|
||||
#ifdef Q_OS_WIN
|
||||
appData.addData( SingleApplication::app_t::applicationFilePath().toLower().toUtf8() );
|
||||
#else
|
||||
appData.addData( SingleApplication::app_t::applicationFilePath().toUtf8() );
|
||||
#endif
|
||||
}
|
||||
|
||||
// User level block requires a user specific data in the hash
|
||||
if( options & SingleApplication::Mode::User ) {
|
||||
#ifdef Q_OS_WIN
|
||||
wchar_t username [ UNLEN + 1 ];
|
||||
// Specifies size of the buffer on input
|
||||
DWORD usernameLength = UNLEN + 1;
|
||||
if( GetUserNameW( username, &usernameLength ) ) {
|
||||
appData.addData( QString::fromWCharArray(username).toUtf8() );
|
||||
} else {
|
||||
appData.addData( qgetenv("USERNAME") );
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_UNIX
|
||||
QByteArray username;
|
||||
uid_t uid = geteuid();
|
||||
struct passwd *pw = getpwuid(uid);
|
||||
if( pw ) {
|
||||
username = pw->pw_name;
|
||||
}
|
||||
if( username.isEmpty() ) {
|
||||
username = qgetenv("USER");
|
||||
}
|
||||
appData.addData(username);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
|
||||
// server naming requirements.
|
||||
blockServerName = appData.result().toBase64().replace("/", "_");
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::initializeMemoryBlock()
|
||||
{
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
inst->primary = false;
|
||||
inst->secondary = 0;
|
||||
inst->primaryPid = -1;
|
||||
inst->checksum = blockChecksum();
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::startPrimary()
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
|
||||
// Successful creation means that no main process exists
|
||||
// So we start a QLocalServer to listen for connections
|
||||
QLocalServer::removeServer( blockServerName );
|
||||
server = new QLocalServer();
|
||||
|
||||
// Restrict access to the socket according to the
|
||||
// SingleApplication::Mode::User flag on User level or no restrictions
|
||||
if( options & SingleApplication::Mode::User ) {
|
||||
server->setSocketOptions( QLocalServer::UserAccessOption );
|
||||
} else {
|
||||
server->setSocketOptions( QLocalServer::WorldAccessOption );
|
||||
}
|
||||
|
||||
server->listen( blockServerName );
|
||||
QObject::connect(
|
||||
server,
|
||||
&QLocalServer::newConnection,
|
||||
this,
|
||||
&SingleApplicationPrivate::slotConnectionEstablished
|
||||
);
|
||||
|
||||
// Reset the number of connections
|
||||
InstancesInfo* inst = static_cast <InstancesInfo*>( memory->data() );
|
||||
|
||||
inst->primary = true;
|
||||
inst->primaryPid = q->applicationPid();
|
||||
inst->checksum = blockChecksum();
|
||||
|
||||
instanceNumber = 0;
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::startSecondary()
|
||||
{
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType )
|
||||
{
|
||||
// Connect to the Local Server of the Primary Instance if not already
|
||||
// connected.
|
||||
if( socket == nullptr ) {
|
||||
socket = new QLocalSocket();
|
||||
}
|
||||
|
||||
// If already connected - we are done;
|
||||
if( socket->state() == QLocalSocket::ConnectedState )
|
||||
return;
|
||||
|
||||
// If not connect
|
||||
if( socket->state() == QLocalSocket::UnconnectedState ||
|
||||
socket->state() == QLocalSocket::ClosingState ) {
|
||||
socket->connectToServer( blockServerName );
|
||||
}
|
||||
|
||||
// Wait for being connected
|
||||
if( socket->state() == QLocalSocket::ConnectingState ) {
|
||||
socket->waitForConnected( msecs );
|
||||
}
|
||||
|
||||
// Initialisation message according to the SingleApplication protocol
|
||||
if( socket->state() == QLocalSocket::ConnectedState ) {
|
||||
// Notify the parent that a new instance had been started;
|
||||
QByteArray initMsg;
|
||||
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
writeStream.setVersion(QDataStream::Qt_5_6);
|
||||
#endif
|
||||
|
||||
writeStream << blockServerName.toLatin1();
|
||||
writeStream << static_cast<quint8>(connectionType);
|
||||
writeStream << instanceNumber;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
|
||||
quint16 checksum =
|
||||
qChecksum(
|
||||
initMsg.constData(),
|
||||
static_cast<quint32>(initMsg.length()));
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 6 or later")
|
||||
#endif
|
||||
quint16 checksum =
|
||||
qChecksum(
|
||||
QByteArrayView(
|
||||
initMsg.constData(),
|
||||
static_cast<quint32>(initMsg.length())));
|
||||
#endif
|
||||
writeStream << checksum;
|
||||
|
||||
// The header indicates the message length that follows
|
||||
QByteArray header;
|
||||
QDataStream headerStream(&header, QIODevice::WriteOnly);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
headerStream.setVersion(QDataStream::Qt_5_6);
|
||||
#endif
|
||||
headerStream << static_cast <quint64>( initMsg.length() );
|
||||
|
||||
socket->write( header );
|
||||
socket->write( initMsg );
|
||||
socket->flush();
|
||||
socket->waitForBytesWritten( msecs );
|
||||
}
|
||||
}
|
||||
|
||||
quint16 SingleApplicationPrivate::blockChecksum()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
|
||||
return qChecksum(
|
||||
static_cast <const char *>( memory->data() ),
|
||||
offsetof( InstancesInfo, checksum )
|
||||
);
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 6 or later")
|
||||
#endif
|
||||
return qChecksum(
|
||||
QByteArrayView(
|
||||
static_cast <const char *>( memory->data() ),
|
||||
offsetof( InstancesInfo, checksum )));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
qint64 SingleApplicationPrivate::primaryPid()
|
||||
{
|
||||
qint64 pid;
|
||||
|
||||
memory->lock();
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
pid = inst->primaryPid;
|
||||
memory->unlock();
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Executed when a connection has been made to the LocalServer
|
||||
*/
|
||||
void SingleApplicationPrivate::slotConnectionEstablished()
|
||||
{
|
||||
QLocalSocket *nextConnSocket = server->nextPendingConnection();
|
||||
connectionMap.insert(nextConnSocket, ConnectionInfo());
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose,
|
||||
[nextConnSocket, this]() {
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
Q_EMIT this->slotClientConnectionClosed( nextConnSocket, info.instanceId );
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::disconnected,
|
||||
[nextConnSocket, this](){
|
||||
connectionMap.remove(nextConnSocket);
|
||||
nextConnSocket->deleteLater();
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::readyRead,
|
||||
[nextConnSocket, this]() {
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
switch(info.stage) {
|
||||
case StageHeader:
|
||||
readInitMessageHeader(nextConnSocket);
|
||||
break;
|
||||
case StageBody:
|
||||
readInitMessageBody(nextConnSocket);
|
||||
break;
|
||||
case StageConnected:
|
||||
Q_EMIT this->slotDataAvailable( nextConnSocket, info.instanceId );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::readInitMessageHeader( QLocalSocket *sock )
|
||||
{
|
||||
if (!connectionMap.contains( sock )) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( sock->bytesAvailable() < ( qint64 )sizeof( quint64 ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
QDataStream headerStream( sock );
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
headerStream.setVersion( QDataStream::Qt_5_6 );
|
||||
#endif
|
||||
|
||||
// Read the header to know the message length
|
||||
quint64 msgLen = 0;
|
||||
headerStream >> msgLen;
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
info.stage = StageBody;
|
||||
info.msgLen = msgLen;
|
||||
|
||||
if ( sock->bytesAvailable() >= (qint64) msgLen ) {
|
||||
readInitMessageBody( sock );
|
||||
}
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock )
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
|
||||
if (!connectionMap.contains( sock )) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
if( sock->bytesAvailable() < ( qint64 )info.msgLen ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the message body
|
||||
QByteArray msgBytes = sock->read(info.msgLen);
|
||||
QDataStream readStream(msgBytes);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
readStream.setVersion( QDataStream::Qt_5_6 );
|
||||
#endif
|
||||
|
||||
// server name
|
||||
QByteArray latin1Name;
|
||||
readStream >> latin1Name;
|
||||
|
||||
// connection type
|
||||
ConnectionType connectionType = InvalidConnection;
|
||||
quint8 connTypeVal = InvalidConnection;
|
||||
readStream >> connTypeVal;
|
||||
connectionType = static_cast <ConnectionType>( connTypeVal );
|
||||
|
||||
// instance id
|
||||
quint32 instanceId = 0;
|
||||
readStream >> instanceId;
|
||||
|
||||
// checksum
|
||||
quint16 msgChecksum = 0;
|
||||
readStream >> msgChecksum;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
|
||||
const quint16 actualChecksum =
|
||||
qChecksum(
|
||||
msgBytes.constData(),
|
||||
static_cast<quint32>( msgBytes.length() - sizeof( quint16 ) ) );
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 6 or later")
|
||||
#endif
|
||||
const quint16 actualChecksum =
|
||||
qChecksum(
|
||||
QByteArrayView(
|
||||
msgBytes.constData(),
|
||||
static_cast<quint32>(msgBytes.length() - sizeof(quint16))));
|
||||
#endif
|
||||
bool isValid = readStream.status() == QDataStream::Ok &&
|
||||
QLatin1String(latin1Name) == blockServerName &&
|
||||
msgChecksum == actualChecksum;
|
||||
|
||||
if( !isValid ) {
|
||||
sock->close();
|
||||
return;
|
||||
}
|
||||
|
||||
info.instanceId = instanceId;
|
||||
info.stage = StageConnected;
|
||||
|
||||
if( connectionType == NewInstance ||
|
||||
( connectionType == SecondaryInstance &&
|
||||
options & SingleApplication::Mode::SecondaryNotification ) )
|
||||
{
|
||||
Q_EMIT q->instanceStarted();
|
||||
}
|
||||
|
||||
if (sock->bytesAvailable() > 0) {
|
||||
Q_EMIT this->slotDataAvailable( sock, instanceId );
|
||||
}
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotDataAvailable( QLocalSocket *dataSocket, quint32 instanceId )
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
Q_EMIT q->receivedMessage( instanceId, dataSocket->readAll() );
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedSocket, quint32 instanceId )
|
||||
{
|
||||
if( closedSocket->bytesAvailable() > 0 )
|
||||
Q_EMIT slotDataAvailable( closedSocket, instanceId );
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2016
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
//
|
||||
// W A R N I N G !!!
|
||||
// -----------------
|
||||
//
|
||||
// This file is not part of the SingleApplication API. It is used purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or may even be removed.
|
||||
//
|
||||
|
||||
#ifndef SINGLEAPPLICATION_P_H
|
||||
#define SINGLEAPPLICATION_P_H
|
||||
|
||||
#include <QtCore/QSharedMemory>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include "singleapplication.h"
|
||||
|
||||
struct InstancesInfo {
|
||||
bool primary;
|
||||
quint32 secondary;
|
||||
qint64 primaryPid;
|
||||
quint16 checksum;
|
||||
};
|
||||
|
||||
struct ConnectionInfo {
|
||||
explicit ConnectionInfo() :
|
||||
msgLen(0), instanceId(0), stage(0) {}
|
||||
qint64 msgLen;
|
||||
quint32 instanceId;
|
||||
quint8 stage;
|
||||
};
|
||||
|
||||
class SingleApplicationPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ConnectionType : quint8 {
|
||||
InvalidConnection = 0,
|
||||
NewInstance = 1,
|
||||
SecondaryInstance = 2,
|
||||
Reconnect = 3
|
||||
};
|
||||
enum ConnectionStage : quint8 {
|
||||
StageHeader = 0,
|
||||
StageBody = 1,
|
||||
StageConnected = 2,
|
||||
};
|
||||
Q_DECLARE_PUBLIC(SingleApplication)
|
||||
|
||||
SingleApplicationPrivate( SingleApplication *q_ptr );
|
||||
~SingleApplicationPrivate();
|
||||
|
||||
void genBlockServerName();
|
||||
void initializeMemoryBlock();
|
||||
void startPrimary();
|
||||
void startSecondary();
|
||||
void connectToPrimary(int msecs, ConnectionType connectionType );
|
||||
quint16 blockChecksum();
|
||||
qint64 primaryPid();
|
||||
void readInitMessageHeader(QLocalSocket *socket);
|
||||
void readInitMessageBody(QLocalSocket *socket);
|
||||
|
||||
SingleApplication *q_ptr;
|
||||
QSharedMemory *memory;
|
||||
QLocalSocket *socket;
|
||||
QLocalServer *server;
|
||||
quint32 instanceNumber;
|
||||
QString blockServerName;
|
||||
SingleApplication::Options options;
|
||||
QMap<QLocalSocket*, ConnectionInfo> connectionMap;
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotConnectionEstablished();
|
||||
void slotDataAvailable( QLocalSocket*, quint32 );
|
||||
void slotClientConnectionClosed( QLocalSocket*, quint32 );
|
||||
};
|
||||
|
||||
#endif // SINGLEAPPLICATION_P_H
|
||||
138
aboutqet.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
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 "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-2007 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
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
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 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
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
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 "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
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
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 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
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"id": "org.qelectrotech.QElectroTech",
|
||||
"runtime": "org.kde.Platform",
|
||||
"runtime-version": "5.14",
|
||||
"sdk": "org.kde.Sdk",
|
||||
"command": "qelectrotech",
|
||||
"rename-desktop-file": "qelectrotech.desktop",
|
||||
"rename-appdata-file": "qelectrotech.appdata.xml",
|
||||
"rename-icon": "qelectrotech",
|
||||
"copy-icon": true,
|
||||
"finish-args": [
|
||||
"--socket=wayland",
|
||||
"--socket=x11",
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--filesystem=host"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "qelectrotech",
|
||||
"buildsystem": "qmake",
|
||||
"post-install": [
|
||||
"mv /app/share/mime/packages/qelectrotech.xml /app/share/mime/packages/org.qelectrotech.QElectroTech.xml"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "dir",
|
||||
"path": "../.."
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "patches/0001-build-Fix-the-installation-paths.patch"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
From 2a390b5188fe070295090b1bd37273d12963b371 Mon Sep 17 00:00:00 2001
|
||||
From: Laurent Trinques <scorpio@qelectrotech.org>
|
||||
Date: Sat, 26 Sep 2020 22:52:52 +0200
|
||||
Subject: [PATCH] build: Fix the installation paths
|
||||
|
||||
---
|
||||
qelectrotech.pro | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/qelectrotech.pro b/qelectrotech.pro
|
||||
index 2901a30d5..1019a9870 100644
|
||||
--- a/qelectrotech.pro
|
||||
+++ b/qelectrotech.pro
|
||||
@@ -5,20 +5,20 @@
|
||||
# Chemins utilises pour la compilation et l'installation de QET
|
||||
unix {
|
||||
# Chemins UNIX
|
||||
- COMPIL_PREFIX = '/usr/local/'
|
||||
- INSTALL_PREFIX = '/usr/local/'
|
||||
+ COMPIL_PREFIX = '/app/'
|
||||
+ INSTALL_PREFIX = '/app/'
|
||||
QET_BINARY_PATH = 'bin/'
|
||||
QET_COMMON_COLLECTION_PATH = 'share/qelectrotech/elements/'
|
||||
QET_COMMON_TBT_PATH = 'share/qelectrotech/titleblocks/'
|
||||
QET_LANG_PATH = 'share/qelectrotech/lang/'
|
||||
QET_EXAMPLES_PATH = 'share/qelectrotech/examples/'
|
||||
- QET_LICENSE_PATH = 'doc/qelectrotech/'
|
||||
- QET_MIME_XML_PATH = '../share/mime/application/'
|
||||
- QET_MIME_DESKTOP_PATH = '../share/mimelnk/application/'
|
||||
- QET_MIME_PACKAGE_PATH = '../share/mime/packages/'
|
||||
+ QET_LICENSE_PATH = 'share/doc/qelectrotech/'
|
||||
+ QET_MIME_XML_PATH = 'share/mime/application/'
|
||||
+ QET_MIME_DESKTOP_PATH = 'share/mimelnk/application/'
|
||||
+ QET_MIME_PACKAGE_PATH = 'share/mime/packages/'
|
||||
QET_DESKTOP_PATH = 'share/applications/'
|
||||
QET_ICONS_PATH = 'share/icons/hicolor/'
|
||||
- QET_MAN_PATH = 'man/'
|
||||
+ QET_MAN_PATH = 'share/man/'
|
||||
QET_APPDATA_PATH = 'share/appdata'
|
||||
}
|
||||
win32 {
|
||||
--
|
||||
2.28.0
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
[fr]
|
||||
Collection d'éléments pour QElectroTech.
|
||||
|
||||
[en]
|
||||
Elements collection for QElectroTech.
|
||||
|
||||
[de]
|
||||
Bauteilsammlung für QElectroTech.
|
||||
|
||||
[es]
|
||||
Collección de elementos para QElectroTech.
|
||||
|
||||
[pt]
|
||||
Colecção de elementos para QElectroTech.
|
||||
|
||||
[ru]
|
||||
Коллекция элементов для QElectroTech.
|
||||
|
||||
[cs]
|
||||
Sbírka prvků pro QElectroTech.
|
||||
|
||||
[pl]
|
||||
Kolekcja elementów QElectroTech.
|
||||
|
||||
[el]
|
||||
Συλλογή στοιχείων του QElectroTech.
|
||||
|
||||
[it]
|
||||
Collezione di elementi per QElectroTech.
|
||||
|
||||
[nl]
|
||||
Elementen collectie voor QElectroTech.
|
||||
|
||||
[be]
|
||||
Elementen collectie voor QElectroTech.
|
||||
|
||||
[da]
|
||||
Symbol samling for QElectroTech.
|
||||
|
||||
[ja]
|
||||
QElectroTech の要素コレクション。
|
||||
@@ -1 +0,0 @@
|
||||
http://pkgs.fedoraproject.org/gitweb/?p=qelectrotech.git
|
||||
@@ -1,3 +0,0 @@
|
||||
the gentoo ebuild is hosted on this CVS
|
||||
|
||||
http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/sci-electronics/qelectrotech/
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# a KDE session forces the KDE Plasma platformtheme which is incompatible with QET
|
||||
# unset the ENV vars in that case to prevent loading of the theme
|
||||
if [ ! -z "$KDE_FULL_SESSION" ]; then
|
||||
unset KDE_FULL_SESSION
|
||||
fi
|
||||
|
||||
if echo "$XDG_CURRENT_DESKTOP" | grep -q KDE; then
|
||||
unset XDG_CURRENT_DESKTOP
|
||||
fi
|
||||
|
||||
# migrate .qet directory from SNAP_USER_DATA to SNAP_USER_COMMON
|
||||
from="$SNAP_USER_DATA/.qet"
|
||||
to="$SNAP_USER_COMMON/.qet"
|
||||
if [ ! -d "$to" ] && [ -d "$from" ]; then
|
||||
echo "Migrating user data from $from to $to"
|
||||
mkdir "$to"
|
||||
cp -av "$from/." "$to"
|
||||
fi
|
||||
|
||||
# link DXFtoQET so that QET finds it
|
||||
mkdir -p "$HOME/.qet"
|
||||
ln -snf "$SNAP/bin/DXFtoQET" "$HOME/.qet/DXFtoQET"
|
||||
|
||||
# start desktop portal. Open & save dialogs might fail if it is not running
|
||||
dbus-send --print-reply \
|
||||
--dest=org.freedesktop.DBus \
|
||||
/org/freedesktop/DBus \
|
||||
org.freedesktop.DBus.StartServiceByName \
|
||||
string:org.freedesktop.portal.Desktop \
|
||||
uint32:0
|
||||
|
||||
exec "${@}"
|
||||
@@ -1,124 +0,0 @@
|
||||
name: qelectrotech
|
||||
title: QElectroTech
|
||||
base: core18
|
||||
adopt-info: qelectrotech
|
||||
license: GPL-2.0
|
||||
summary: Electrical diagram editor
|
||||
description: |
|
||||
QElectroTech, or QET in short, is a libre and open source desktop application
|
||||
to create diagrams and schematics.
|
||||
|
||||
grade: stable
|
||||
confinement: strict
|
||||
|
||||
architectures:
|
||||
- build-on: amd64
|
||||
run-on: amd64
|
||||
|
||||
layout:
|
||||
/usr/local/share/qelectrotech:
|
||||
symlink: $SNAP/usr/local/share/qelectrotech
|
||||
/usr/share/libdrm/amdgpu.ids:
|
||||
symlink: $SNAP/kf5/usr/share/libdrm/amdgpu.ids
|
||||
|
||||
apps:
|
||||
qelectrotech:
|
||||
command: usr/local/bin/qelectrotech
|
||||
command-chain:
|
||||
- bin/qelectrotech-launch
|
||||
desktop: usr/local/share/applications/qelectrotech.desktop
|
||||
extensions: [kde-neon]
|
||||
plugs: &plugs [opengl, unity7, home, removable-media, gsettings, network, cups-control]
|
||||
environment: &env
|
||||
__EGL_VENDOR_LIBRARY_DIRS: $SNAP/kf5/usr/share/glvnd/egl_vendor.d:$SNAP/usr/share/glvnd/egl_vendor.d
|
||||
TCL_LIBRARY: $SNAP/usr/share/tcltk/tcl8.6
|
||||
QT_QPA_PLATFORMTHEME: gtk3
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: 1
|
||||
HOME: $SNAP_USER_COMMON
|
||||
PYTHONPATH: $SNAP:$SNAP/lib/python3.6/site-packages:$SNAP/usr/lib/python3.6:$SNAP/usr/lib/python3.6/lib-dynload
|
||||
|
||||
qet-tb-generator:
|
||||
command: bin/qelectrotech-launch $SNAP/bin/qet_tb_generator
|
||||
extensions: [kde-neon]
|
||||
plugs: *plugs
|
||||
environment: *env
|
||||
|
||||
dxf-to-qet:
|
||||
command: bin/DXFtoQET
|
||||
extensions: [kde-neon]
|
||||
plugs: *plugs
|
||||
environment: *env
|
||||
|
||||
parts:
|
||||
launchers:
|
||||
plugin: dump
|
||||
source: build-aux/snap/local/launchers
|
||||
organize:
|
||||
'*': bin/
|
||||
|
||||
qet-tb-generator:
|
||||
plugin: python
|
||||
python-version: python3
|
||||
source: https://github.com/qelectrotech/qet_tb_generator.git
|
||||
stage-packages:
|
||||
- python3-lxml
|
||||
- python3-tk
|
||||
- libtk8.6
|
||||
|
||||
kde-sdk-setup:
|
||||
plugin: nil
|
||||
build-snaps:
|
||||
- kde-frameworks-5-core18-sdk
|
||||
build-packages:
|
||||
- g++
|
||||
- mesa-common-dev
|
||||
- libglvnd-dev
|
||||
- rsync
|
||||
override-build: |
|
||||
rsync -a --ignore-existing /snap/kde-frameworks-5-core18-sdk/current/ /
|
||||
|
||||
dxf-to-qet:
|
||||
after: [kde-sdk-setup]
|
||||
plugin: nil
|
||||
source: https://github.com/qelectrotech/DXFtoQET-2020.git
|
||||
override-build: |
|
||||
qmake "$SNAPCRAFT_PART_SRC/DXFtoQET.pro"
|
||||
make -j$(nproc)
|
||||
mkdir -p "$SNAPCRAFT_PART_INSTALL/bin"
|
||||
cp DXFtoQET "$SNAPCRAFT_PART_INSTALL/bin/"
|
||||
|
||||
qelectrotech:
|
||||
after: [kde-sdk-setup]
|
||||
plugin: nil
|
||||
source: .
|
||||
stage-packages: [ git, sqlite3 ]
|
||||
build-packages:
|
||||
- git
|
||||
- libsqlite3-dev
|
||||
override-pull: |
|
||||
snapcraftctl pull
|
||||
snap_version=$(git describe --dirty)
|
||||
modified_displayed_version=$snap_version".snap"
|
||||
sed -i -E "s|const QString displayedVersion =.*|const QString displayedVersion =\"$modified_displayed_version\";|" sources/qet.h
|
||||
snapcraftctl set-version "$snap_version"
|
||||
override-build: |
|
||||
qmake "$SNAPCRAFT_PART_SRC/qelectrotech.pro"
|
||||
make -j$(nproc)
|
||||
make install INSTALL_ROOT="$SNAPCRAFT_PART_INSTALL"
|
||||
override-stage: |
|
||||
snapcraftctl stage
|
||||
# patch desktop file with correct icon path
|
||||
SED_CMD="sed -i -E s|^Icon=(.*)|Icon=\${SNAP}/usr/local/share/icons/hicolor/128x128/apps/\1.png|g"
|
||||
$SED_CMD usr/local/share/applications/qelectrotech.desktop
|
||||
|
||||
cleanup:
|
||||
after: [qelectrotech, dxf-to-qet, qet-tb-generator]
|
||||
plugin: nil
|
||||
build-snaps: [core18, kde-frameworks-5-core18]
|
||||
override-prime: |
|
||||
# Remove all files from snap that are already included in the base snap or in
|
||||
# any connected content snaps
|
||||
set -eux
|
||||
for snap in "core18" "kde-frameworks-5-core18"; do # List all content-snaps and base snaps you're using here
|
||||
cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" \;
|
||||
done
|
||||
@@ -1,191 +0,0 @@
|
||||
# Header, don't edit
|
||||
NLF v6
|
||||
# Start editing here
|
||||
# Language ID
|
||||
2067
|
||||
# Font and size - dash (-) means default
|
||||
-
|
||||
-
|
||||
# Codepage - dash (-) means ANSI code page
|
||||
1252
|
||||
# RTL - anything else than RTL means LTR
|
||||
-
|
||||
# Translation by Ronny Desmedt (any credits should go here)
|
||||
# ^Branding
|
||||
Nullsoft Install System %s
|
||||
# ^SetupCaption
|
||||
$(^Name) Installatie
|
||||
# ^UninstallCaption
|
||||
$(^Name) Deïnstallatie
|
||||
# ^LicenseSubCaption
|
||||
: Licentie overeenkomst
|
||||
# ^ComponentsSubCaption
|
||||
: Installatie Opties
|
||||
# ^DirSubCaption
|
||||
: Installatie Map
|
||||
# ^InstallingSubCaption
|
||||
: Installeren
|
||||
# ^CompletedSubCaption
|
||||
: Voltooid
|
||||
# ^UnComponentsSubCaption
|
||||
: Deïnstallatie Opties
|
||||
# ^UnDirSubCaption
|
||||
: Deïnstallatie Map
|
||||
# ^ConfirmSubCaption
|
||||
: Bevestigen
|
||||
# ^UninstallingSubCaption
|
||||
: Deïnstalleren
|
||||
# ^UnCompletedSubCaption
|
||||
: Voltooid
|
||||
# ^BackBtn
|
||||
< &Terug
|
||||
# ^NextBtn
|
||||
&Volgende >
|
||||
# ^AgreeBtn
|
||||
Ik ben &Akkoord
|
||||
# ^AcceptBtn
|
||||
Ik &Accepteer de licentie overeenkomst
|
||||
# ^DontAcceptBtn
|
||||
Ik &Accepteer de licentie overeenkomst niet
|
||||
# ^InstallBtn
|
||||
&Installeer
|
||||
# ^UninstallBtn
|
||||
&Deïnstalleer
|
||||
# ^CancelBtn
|
||||
Afbreken
|
||||
# ^CloseBtn
|
||||
&Sluiten
|
||||
# ^BrowseBtn
|
||||
B&laderen...
|
||||
# ^ShowDetailsBtn
|
||||
Toon &details
|
||||
# ^ClickNext
|
||||
Klik op volgende om verder te gaan.
|
||||
# ^ClickInstall
|
||||
Klik op installeren om de installatie te starten.
|
||||
# ^ClickUninstall
|
||||
Klik op deïnstalleren om de installatie te verwijderen.
|
||||
# ^Name
|
||||
Naam
|
||||
# ^Completed
|
||||
Voltooid
|
||||
# ^LicenseText
|
||||
Gelieve de licentie overeenkomst te lezen alvorens $(^NameDA) te installeren. Als u akkord bent met de licentie overeenkomst, klik op akkoord.
|
||||
# ^LicenseTextCB
|
||||
Gelieve de licentie overeenkomst te lezen alvorens $(^NameDA) te installeren. Als u akkord bent met de licentie overeenkomst, klik op onderstaande selectievakje. $_CLICK
|
||||
# ^LicenseTextRB
|
||||
Gelieve de licentie overeenkomst te lezen alvorens $(^NameDA) te installeren. Als u akkord bent met de licentie overeenkomst, selecteer de eerste onderstaande optie. $_CLICK
|
||||
# ^UnLicenseText
|
||||
Gelieve de licentie overeenkomst te lezen alvorens $(^NameDA) te deïnstalleren. Als u akkord bent met de licentie overeenkomst, klik op akkoord.
|
||||
# ^UnLicenseTextCB
|
||||
Gelieve de licentie overeenkomst te lezen alvorens $(^NameDA) te deïnstalleren. Als u akkord bent met de licentie overeenkomst, klik op onderstaande selectievakje. $_CLICK
|
||||
# ^UnLicenseTextRB
|
||||
Gelieve de licentie overeenkomst te lezen alvorens $(^NameDA) te deïnstalleren. Als u akkord bent met de licentie overeenkomst, selecteer de eerste onderstaande optie. $_CLICK
|
||||
# ^Custom
|
||||
Aangepast
|
||||
# ^ComponentsText
|
||||
Selecteer de onderdelen die u wilt installeren en deselecteer de onderdelen die u niet wilt installeren. $_CLICK
|
||||
# ^ComponentsSubText1
|
||||
Selecteer een installatie type:
|
||||
# ^ComponentsSubText2_NoInstTypes
|
||||
Selecteer de onderdelen om te installeren:
|
||||
# ^ComponentsSubText2
|
||||
Of, selecteer optionelen onderdelen die u wilt installeren:
|
||||
# ^UnComponentsText
|
||||
Selecteer de onderdelen die u wilt deïnstalleren en deselecteer de onderdelen die u niet wilt deïinstalleren. $_CLICK
|
||||
# ^UnComponentsSubText1
|
||||
Selecteer een deïnstallatie type:
|
||||
# ^UnComponentsSubText2_NoInstTypes
|
||||
Selecteer de onderdelen om te deïnstalleren:
|
||||
# ^UnComponentsSubText2
|
||||
Of, selecteer optionelen onderdelen die u wilt deïnstalleren:
|
||||
# ^DirText
|
||||
De installatie van $(^NameDA) wordt in volgende map uitgevoerd. Om in een andere map te installeren, klik op bladeren om een andere map te selecteren. $_CLICK
|
||||
# ^DirSubText
|
||||
Installatie map
|
||||
# ^DirBrowseText
|
||||
Selecteerd de map om $(^NameDA) in te installeren:
|
||||
# ^UnDirText
|
||||
De deïnstallatie van $(^NameDA) in de volgende map. Om een andere map te deïnstalleren, klik op bladren om een andere map te selecteren. $_CLICK
|
||||
# ^UnDirSubText
|
||||
""
|
||||
# ^UnDirBrowseText
|
||||
Selecteer en map om $(^NameDA) van te deînstalleren:
|
||||
# ^SpaceAvailable
|
||||
"Beschikbare ruimte: "
|
||||
# ^SpaceRequired
|
||||
"Benodigde ruimte: "
|
||||
# ^UninstallingText
|
||||
$(^NameDA) wordt gedeïnstalleerd uit volgende map. $_CLICK
|
||||
# ^UninstallingSubText
|
||||
Deïnstalleren van:
|
||||
# ^FileError
|
||||
Fout bij openen van bestand om te schrijven: \r\n\r\n$0\r\n\r\nKlik op afbreken om de installatie te stoppen,\r\nOpnieuw om te proberen, of\r\nNegeren om dit bestand over te slaan.
|
||||
# ^FileError_NoIgnore
|
||||
Fout bij openen van bestand om te schrijven: \r\n\r\n$0\r\n\r\nOpnieuw om te proberen, of\r\nAfbreken om de installatie te stoppen.
|
||||
# ^CantWrite
|
||||
"Kan niet schrijven: "
|
||||
# ^CopyFailed
|
||||
Kopieren mislukt
|
||||
# ^CopyTo
|
||||
"Copier naar "
|
||||
# ^Registering
|
||||
"Registreren: "
|
||||
# ^Unregistering
|
||||
"Deregistreren: "
|
||||
# ^SymbolNotFound
|
||||
"Kan symbool niet vinden: "
|
||||
# ^CouldNotLoad
|
||||
"Kan niet laden: "
|
||||
# ^CreateFolder
|
||||
"Map maken: "
|
||||
# ^CreateShortcut
|
||||
"Snelkoppeling maken: "
|
||||
# ^CreatedUninstaller
|
||||
"Doe deïnstallatie: "
|
||||
# ^Delete
|
||||
"Verwijder bestanden: "
|
||||
# ^DeleteOnReboot
|
||||
Verwijder bij herstarten: "
|
||||
# ^ErrorCreatingShortcut
|
||||
"Fout bij maken snelkoppeling: "
|
||||
# ^ErrorCreating
|
||||
"Fout bij maken: "
|
||||
# ^ErrorDecompressing
|
||||
Fout bij uitpakken gegevens! Beschadigd bestand?
|
||||
# ^ErrorRegistering
|
||||
Fout bij registreren DLL
|
||||
# ^ExecShell
|
||||
"ExecShell: "
|
||||
# ^Exec
|
||||
"Uitvoeren: "
|
||||
# ^Extract
|
||||
"Extract: "
|
||||
# ^ErrorWriting
|
||||
Fout: fout bij schrijven naar bestand "
|
||||
# ^InvalidOpcode
|
||||
Installie beschadigd: niet toegestane opcode
|
||||
# ^NoOLE
|
||||
"Geen OLE voor: "
|
||||
# ^OutputFolder
|
||||
"Bestemmings map: "
|
||||
# ^RemoveFolder
|
||||
"Verwijder mapr: "
|
||||
# ^RenameOnReboot
|
||||
"Hernoem bij opstarten: "
|
||||
# ^Rename
|
||||
"Hernoem: "
|
||||
# ^Skipped
|
||||
Overgeslagen: "
|
||||
# ^CopyDetails
|
||||
Copier details naar klembord
|
||||
# ^LogInstall
|
||||
Log instaltie proces
|
||||
# ^Byte
|
||||
B
|
||||
# ^Kilo
|
||||
K
|
||||
# ^Mega
|
||||
M
|
||||
# ^Giga
|
||||
G
|
||||
@@ -1,128 +0,0 @@
|
||||
;Language:Dutch_Belgium (2067)
|
||||
;By Ronny Desmedt
|
||||
|
||||
!insertmacro LANGFILE "Dutch_Belgium" "Dutch_Belgium"
|
||||
|
||||
!ifdef MUI_WELCOMEPAGE
|
||||
${LangFileString} MUI_TEXT_WELCOME_INFO_TITLE "Welkom bij $(^NameDA) installatie Wizard"
|
||||
${LangFileString} MUI_TEXT_WELCOME_INFO_TEXT "Deze wizard zal u begeleiden bij de installatie van $(^NameDA).$\r$\n$\r$\nHet is aanbevol dat u alle andere programmas afsluit voordat u deze installatie uitvoerd. Dit geeft de mogelijkheid om relevante systeem bestanden bij te werken zonder dat uw systeem terug moet opstarten.$\r$\n$\r$\n$_CLICK"
|
||||
!endif
|
||||
|
||||
!ifdef MUI_UNWELCOMEPAGE
|
||||
${LangFileString} MUI_UNTEXT_WELCOME_INFO_TITLE "Welkom bij de $(^NameDA) deïnstallatie wizard"
|
||||
${LangFileString} MUI_UNTEXT_WELCOME_INFO_TEXT "Deze wizard zal u begeleiden bij de deïnstallatie van $(^NameDA).$\r$\n$\r$\nControleer of $(^NameDA) is afgesloten alvorens de deïnstallatie te starten.$\r$\n$\r$\n$_CLICK"
|
||||
!endif
|
||||
|
||||
!ifdef MUI_LICENSEPAGE
|
||||
${LangFileString} MUI_TEXT_LICENSE_TITLE "Licentie overeenkomst"
|
||||
${LangFileString} MUI_TEXT_LICENSE_SUBTITLE "Gelieve de licentie te lezen alvorens U $(^NameDA) installeert."
|
||||
${LangFileString} MUI_INNERTEXT_LICENSE_BOTTOM "Klik op akkoord om de overeenkomst te aanvaarden. U moet de overeenkomst aanvaarden om $(^NameDA) te installeren."
|
||||
${LangFileString} MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX "Als u de voorwaarden van de overeenkomst aanvaard, Klik op onderstaande selectievakje. U moet de overeenkomst aanvaarden om $(^NameDA) te installeren. $_CLICK"
|
||||
${LangFileString} MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS "Als u de voorwaarden van de overeenkomst aanvaard, selecteer de eerste onderstaande optie. U moet de overeenkomst aanvaarden om $(^NameDA) te installeren. $_CLICK"
|
||||
!endif
|
||||
|
||||
!ifdef MUI_UNLICENSEPAGE
|
||||
${LangFileString} MUI_UNTEXT_LICENSE_TITLE "Licentie overeenkomst"
|
||||
${LangFileString} MUI_UNTEXT_LICENSE_SUBTITLE "Gelieve de licentie overeenkomst te herlezen alvorens met de deïnstallatie van $(^NameDA) verder te doen."
|
||||
${LangFileString} MUI_UNINNERTEXT_LICENSE_BOTTOM "Klik op akkoord om de overeenkomst te aanvaarden. U moet de overeenkomst aanvaarden om $(^NameDA) te deïnstalleren."
|
||||
${LangFileString} MUI_UNINNERTEXT_LICENSE_BOTTOM_CHECKBOX "Als u de voorwaarden van de overeenkomst aanvaard, Klik op onderstaande selectievakje. U moet de overeenkomst aanvaarden om $(^NameDA) te deïnstalleren. $_CLICK"
|
||||
${LangFileString} MUI_UNINNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS "Als u de voorwaarden van de overeenkomst aanvaard, selecteer de eerste onderstaande optie. U moet de overeenkomst aanvaarden om $(^NameDA) te deïnstalleren. $_CLICK"
|
||||
!endif
|
||||
|
||||
!ifdef MUI_LICENSEPAGE | MUI_UNLICENSEPAGE
|
||||
${LangFileString} MUI_INNERTEXT_LICENSE_TOP "Gebruik pagina neer om de rest van de overeenkomst te lezen."
|
||||
!endif
|
||||
|
||||
!ifdef MUI_COMPONENTSPAGE
|
||||
${LangFileString} MUI_TEXT_COMPONENTS_TITLE "Kies onderdelen"
|
||||
${LangFileString} MUI_TEXT_COMPONENTS_SUBTITLE "Kies de onderdelen van $(^NameDA) die u wilt installeren."
|
||||
!endif
|
||||
|
||||
!ifdef MUI_UNCOMPONENTSPAGE
|
||||
${LangFileString} MUI_UNTEXT_COMPONENTS_TITLE "Kies onderdelen"
|
||||
${LangFileString} MUI_UNTEXT_COMPONENTS_SUBTITLE "Kies de onderdelen van $(^NameDA) die u wilt deïnstalleren."
|
||||
!endif
|
||||
|
||||
!ifdef MUI_COMPONENTSPAGE | MUI_UNCOMPONENTSPAGE
|
||||
${LangFileString} MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE "Beschrijving"
|
||||
!ifndef NSIS_CONFIG_COMPONENTPAGE_ALTERNATIVE
|
||||
${LangFileString} MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO "Beweeg de muisaanwijzer over de onderdelen om de beschrijving te zien."
|
||||
!else
|
||||
${LangFileString} MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO "Beweeg de muisaanwijzer over de onderdelen om de beschrijving te zien."
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!ifdef MUI_DIRECTORYPAGE
|
||||
${LangFileString} MUI_TEXT_DIRECTORY_TITLE "Kies een installatie locatie"
|
||||
${LangFileString} MUI_TEXT_DIRECTORY_SUBTITLE "Kies een map waar U $(^NameDA) wilt installeren."
|
||||
!endif
|
||||
|
||||
!ifdef MUI_UNDIRECTORYPAGE
|
||||
${LangFileString} MUI_UNTEXT_DIRECTORY_TITLE "Kies een deïnstallatie locatie"
|
||||
${LangFileString} MUI_UNTEXT_DIRECTORY_SUBTITLE "Kies een map waar U $(^NameDA) wilt deïnstalleren."
|
||||
!endif
|
||||
|
||||
!ifdef MUI_INSTFILESPAGE
|
||||
${LangFileString} MUI_TEXT_INSTALLING_TITLE "Installeren"
|
||||
${LangFileString} MUI_TEXT_INSTALLING_SUBTITLE "Even gedult terwijl $(^NameDA) wordt geinstalleerd."
|
||||
${LangFileString} MUI_TEXT_FINISH_TITLE "Installatie voltooid"
|
||||
${LangFileString} MUI_TEXT_FINISH_SUBTITLE "De installatie is succesvol afgerond."
|
||||
${LangFileString} MUI_TEXT_ABORT_TITLE "Installatie is afgebroken"
|
||||
${LangFileString} MUI_TEXT_ABORT_SUBTITLE "De installatie is niet voltooid."
|
||||
!endif
|
||||
|
||||
!ifdef MUI_UNINSTFILESPAGE
|
||||
${LangFileString} MUI_UNTEXT_UNINSTALLING_TITLE "DeïnEven geduld terwijl $(^NameDA) wordt gedeïnstalleerd."
|
||||
${LangFileString} MUI_UNTEXT_FINISH_TITLE "Deïnstallatie voltooid"
|
||||
${LangFileString} MUI_UNTEXT_FINISH_SUBTITLE "Deïnstallatie succesvol afgerond."
|
||||
${LangFileString} MUI_UNTEXT_ABORT_TITLE "Deïnstallatie onderbroken"
|
||||
${LangFileString} MUI_UNTEXT_ABORT_SUBTITLE "Deïnstallatie is niet voltooid."
|
||||
!endif
|
||||
|
||||
!ifdef MUI_FINISHPAGE
|
||||
${LangFileString} MUI_TEXT_FINISH_INFO_TITLE "Voltooien van de $(^NameDA) installatie Wizard"
|
||||
${LangFileString} MUI_TEXT_FINISH_INFO_TEXT "$(^NameDA) is geinstalleerd op uw computer.$\r$\n$\r$\nKlik op einde om de installatie wizard af te sluiten."
|
||||
${LangFileString} MUI_TEXT_FINISH_INFO_REBOOT "Uw computer moet herstarten op de installatie van $(^NameDA) te voltooien. Wilt u nu opnieuw opstarten?"
|
||||
!endif
|
||||
|
||||
!ifdef MUI_UNFINISHPAGE
|
||||
${LangFileString} MUI_UNTEXT_FINISH_INFO_TITLE "Voltooien van de $(^NameDA) deïnstallatie wizard"
|
||||
${LangFileString} MUI_UNTEXT_FINISH_INFO_TEXT "$(^NameDA) is gedeïnstalleerd op uw computer.$\r$\n$\r$\nKlik op einde om de installatie wizard af te sluiten."
|
||||
${LangFileString} MUI_UNTEXT_FINISH_INFO_REBOOT "Uw computer moet herstarten op de deïnstallatie van $(^NameDA)te voltooien. Wilt u nu opnieuw opstarten?"
|
||||
!endif
|
||||
|
||||
!ifdef MUI_FINISHPAGE | MUI_UNFINISHPAGE
|
||||
${LangFileString} MUI_TEXT_FINISH_REBOOTNOW "Nu herstarten"
|
||||
${LangFileString} MUI_TEXT_FINISH_REBOOTLATER "Ik wil later herstarten"
|
||||
${LangFileString} MUI_TEXT_FINISH_RUN "&Starten $(^NameDA)"
|
||||
${LangFileString} MUI_TEXT_FINISH_SHOWREADME "&Toon leesmij"
|
||||
${LangFileString} MUI_BUTTONTEXT_FINISH "&Einde"
|
||||
!endif
|
||||
|
||||
!ifdef MUI_STARTMENUPAGE
|
||||
${LangFileString} MUI_TEXT_STARTMENU_TITLE "Kies start menu map"
|
||||
${LangFileString} MUI_TEXT_STARTMENU_SUBTITLE "Kies een map in start menu voor de snelkoppeling van $(^NameDA)."
|
||||
${LangFileString} MUI_INNERTEXT_STARTMENU_TOP "Kies een map in start menu waar u de programma snelkoppelingen wilt aanmaken. U kan ook de naam van een nieuwe map opgeven."
|
||||
${LangFileString} MUI_INNERTEXT_STARTMENU_CHECKBOX "Maak geen snelkoppelingen"
|
||||
!endif
|
||||
|
||||
!ifdef MUI_UNCONFIRMPAGE
|
||||
${LangFileString} MUI_UNTEXT_CONFIRM_TITLE "Deïnstalleer$(^NameDA)"
|
||||
${LangFileString} MUI_UNTEXT_CONFIRM_SUBTITLE "Verwijder $(^NameDA) van uw computer."
|
||||
!endif
|
||||
|
||||
!ifdef MUI_ABORTWARNING
|
||||
${LangFileString} MUI_TEXT_ABORTWARNING "Weet u zeker dat U installatie van $(^Name) wilt afbreken?"
|
||||
!endif
|
||||
|
||||
!ifdef MUI_UNABORTWARNING
|
||||
${LangFileString} MUI_UNTEXT_ABORTWARNING "Weet u zeker dat U de deïnstallatie van $(^Name)wilt afbreken?"
|
||||
!endif
|
||||
|
||||
!ifdef MULTIUSER_INSTALLMODEPAGE
|
||||
${LangFileString} MULTIUSER_TEXT_INSTALLMODE_TITLE "Kies gebruikers"
|
||||
${LangFileString} MULTIUSER_TEXT_INSTALLMODE_SUBTITLE "Kies voor welke gebruikers U $(^NameDA) wilt installeren."
|
||||
${LangFileString} MULTIUSER_INNERTEXT_INSTALLMODE_TOP "Kies of U $(^NameDA) alleen voor u zelf of voor alle gebruikers op deze computer wilt installeren. $(^ClickNext)"
|
||||
${LangFileString} MULTIUSER_INNERTEXT_INSTALLMODE_ALLUSERS "Installeer voor iedereen die deze computer gebruikt"
|
||||
${LangFileString} MULTIUSER_INNERTEXT_INSTALLMODE_CURRENTUSER "Installeer alleen voor mij"
|
||||
!endif
|
||||
@@ -1,11 +0,0 @@
|
||||
@echo off
|
||||
|
||||
rem Se rend dans le dossier qui convient
|
||||
set current_dir=%~dp0
|
||||
cd /d %current_dir%
|
||||
|
||||
rem lance QElectroTech
|
||||
rem Sans option --config-dir, la configuration de QElectroTech ainsi que la
|
||||
rem collection d'elements perso seront dans "%APPDATA%\qet"
|
||||
set command=bin\qelectrotech.exe --common-elements-dir=elements/ --common-tbt-dir=titleblocks/ --lang-dir=lang/ -style windowsvista %*
|
||||
@start %command%
|
||||
@@ -1,391 +0,0 @@
|
||||
; this file is part of installer for QElectroTech
|
||||
; Copyright (C)2015 QElectroTech Team <scorpio@qelectrotech.org>
|
||||
;
|
||||
; This program is free software; you can redistribute it and/or
|
||||
; modify it under the terms of the GNU General Public License
|
||||
; as published by the Free Software Foundation; either
|
||||
; version 2 of the License, or (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program; if not, write to the Free Software
|
||||
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
; WebSite : http://qelectrotech.org/
|
||||
|
||||
;--------------------------------
|
||||
;Include Modern UI
|
||||
|
||||
!include "MUI2.nsh"
|
||||
!include "FileFunc.nsh"
|
||||
!insertmacro Locate
|
||||
!include FileFunc.nsh
|
||||
!insertmacro GetParameters
|
||||
!insertmacro GetOptions
|
||||
|
||||
|
||||
|
||||
; MUI Settings
|
||||
;--------------------------------
|
||||
;General
|
||||
; General Product Description Definitions
|
||||
!define SOFT_NAME "QElectroTech"
|
||||
!define SOFT_VERSION "0.5-dev+4113"
|
||||
!define SOFT_WEB_SITE "http://qelectrotech.org/"
|
||||
!define SOFT_BUILD "1"
|
||||
|
||||
SetCompressor /final /solid lzma
|
||||
CRCCheck force
|
||||
XPStyle on
|
||||
BrandingText "${SOFT_NAME}-${SOFT_VERSION}-${SOFT_BUILD}" ; Shows in the Bottom Left of the installer
|
||||
|
||||
;Name and file
|
||||
Name "${SOFT_NAME} ${SOFT_VERSION}"
|
||||
OutFile "Installer_${SOFT_NAME}-${SOFT_VERSION}-${SOFT_BUILD}.exe"
|
||||
|
||||
;Default installation folder
|
||||
InstallDir "$PROGRAMFILES\${SOFT_NAME}"
|
||||
|
||||
;Get installation folder from registry if available
|
||||
InstallDirRegKey HKCU "Software\${SOFT_NAME}" ""
|
||||
|
||||
;Request application privileges for Windows Vista
|
||||
; we request for admin because we write stuff into the registry
|
||||
RequestExecutionLevel admin
|
||||
|
||||
;--------------------------------
|
||||
;Interface Settings
|
||||
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\XPUI-install.ico"
|
||||
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\XPUI-uninstall.ico"
|
||||
|
||||
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP ".\images\wizard.bmp"
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH
|
||||
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_BITMAP ".\images\header.bmp" ; optional
|
||||
|
||||
;--------------------------------
|
||||
;Language Selection Dialog Settings
|
||||
|
||||
;Remember the installer language
|
||||
!define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
|
||||
!define MUI_LANGDLL_REGISTRY_KEY "Software\${SOFT_NAME}"
|
||||
!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
|
||||
|
||||
;--------------------------------
|
||||
;Pages
|
||||
|
||||
!define MUI_COMPONENTSPAGE_SMALLDESC
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_LICENSE "files\LICENSE"
|
||||
!insertmacro MUI_PAGE_COMPONENTS
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
; Finish page and checkbox to run QElectroTech
|
||||
!define MUI_FINISHPAGE_RUN "$INSTDIR\Lancer QET.bat"
|
||||
!define MUI_FINISHPAGE_RUN_NOTCHECKED
|
||||
!define MUI_FINISHPAGE_RUN_TEXT "$(Check)"
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
;--------------------------------
|
||||
;Languages
|
||||
;Since NSIS 2.26, the language selection dialog of Modern UI hides languages unsupported by the user's selected codepage by default.
|
||||
;To revert to the old behavior and display all languages, no matter what the user will see when they're selected, use MUI_LANGDLL_ALLLANGUAGES.
|
||||
!define MUI_LANGDLL_ALLLANGUAGES
|
||||
|
||||
; For consistency, we limit the installer to languages supported by QElectroTech itself
|
||||
!insertmacro MUI_LANGUAGE "English" ;first language is the default language
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
!insertmacro MUI_LANGUAGE "Spanish"
|
||||
!insertmacro MUI_LANGUAGE "Russian"
|
||||
!insertmacro MUI_LANGUAGE "Portuguese"
|
||||
!insertmacro MUI_LANGUAGE "Czech"
|
||||
!insertmacro MUI_LANGUAGE "Polish"
|
||||
!insertmacro MUI_LANGUAGE "Greek"
|
||||
!insertmacro MUI_LANGUAGE "Arabic"
|
||||
!insertmacro MUI_LANGUAGE "German"
|
||||
!insertmacro MUI_LANGUAGE "Italian"
|
||||
!insertmacro MUI_LANGUAGE "Romanian"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Croatian"
|
||||
!insertmacro MUI_LANGUAGE "Dutch"
|
||||
!insertmacro MUI_LANGUAGE "Dutch_Belgium"
|
||||
!insertmacro MUI_LANGUAGE "Danish"
|
||||
|
||||
!insertmacro MUI_RESERVEFILE_LANGDLL
|
||||
!include lang_extra.nsh
|
||||
!include lang_extra_fr.nsh
|
||||
|
||||
|
||||
|
||||
SetOverwrite on
|
||||
Section "Main Program"
|
||||
SectionIn RO ; Read only, always installed
|
||||
|
||||
Setoutpath "$INSTDIR\bin\"
|
||||
File "./files/bin/${SOFT_NAME}.exe"
|
||||
|
||||
Setoutpath "$INSTDIR"
|
||||
File "./files/ChangeLog"
|
||||
File "./files/CREDIT"
|
||||
File "./files/ELEMENTS.LICENSE"
|
||||
File "./files/LICENSE"
|
||||
File "./files/qet_uninstall_file_associations.reg"
|
||||
File "./files/README"
|
||||
File "./files/register_filetypes.bat"
|
||||
File "Lancer QET.bat"
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
File /r "./files/ico"
|
||||
|
||||
SectionEnd
|
||||
|
||||
;---------------------------
|
||||
SetOverwrite on
|
||||
SubSection "$(Elements)" SEC01
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Electric)"
|
||||
SetOutPath "$INSTDIR\elements"
|
||||
File /r "./files/elements/10_electric"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Logic)"
|
||||
SetOutPath "$INSTDIR\elements"
|
||||
File /r "./files/elements/20_logic"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Hydraulic)"
|
||||
SetOutPath "$INSTDIR\elements"
|
||||
File /r "./files/elements/30_hydraulic"
|
||||
SectionEnd
|
||||
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Pneumatic)"
|
||||
SetOutPath "$INSTDIR\elements"
|
||||
File /r "./files/elements/50_pneumatic"
|
||||
SectionEnd
|
||||
|
||||
|
||||
;---------------------------------
|
||||
SubSection "$(Energy)"
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(water)"
|
||||
SetOutPath "$INSTDIR\elements\60_energy"
|
||||
File /r "./files/elements/60_energy/11_water"
|
||||
File /r "./files/elements/60_energy/"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Refrigeration)"
|
||||
SetOutPath "$INSTDIR\elements\60_energy"
|
||||
File /r "./files/elements/60_energy/21_refrigeration"
|
||||
File /r "./files/elements/60_energy/"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Solar_thermal)"
|
||||
SetOutPath "$INSTDIR\elements\60_energy"
|
||||
File /r "./files/elements/60_energy/31_solar_thermal"
|
||||
File /r "./files/elements/60_energy/"
|
||||
SectionEnd
|
||||
|
||||
SubSectionEnd
|
||||
SubSectionEnd
|
||||
;-------------------------------
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Lang)" SEC02
|
||||
SetOutPath "$INSTDIR\lang"
|
||||
File "./files/lang/*.qm"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Titleblocks)" SEC03
|
||||
SetOutPath "$INSTDIR"
|
||||
File /r "./files/titleblocks"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Examples)" SEC04
|
||||
SetOutPath "$INSTDIR"
|
||||
File /r "./files/examples"
|
||||
SectionEnd
|
||||
|
||||
;--------------------------------
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC01} $(var1)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC02} $(var2)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC03} $(var3)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC04} $(var4)
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
;--------------------------------
|
||||
|
||||
;Installer Sections
|
||||
|
||||
Section ""
|
||||
SetOutPath "$INSTDIR"
|
||||
;Store installation folder
|
||||
WriteRegStr HKCU "Software\${SOFT_NAME}" "" $INSTDIR
|
||||
; write uninstall strings
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SOFT_NAME}" "DisplayName" "${SOFT_NAME} (remove only)"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SOFT_NAME}" "UninstallString" '"$INSTDIR\Uninstall.exe"'
|
||||
;Create uninstaller
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
||||
; get the final path for the icons and the launch script
|
||||
Var /GLOBAL final_qet_exe
|
||||
Var /GLOBAL final_project_ico
|
||||
Var /GLOBAL final_element_ico
|
||||
Var /GLOBAL final_titleblock_ico
|
||||
|
||||
StrCpy $final_qet_exe "$INSTDIR\Lancer QET.bat"
|
||||
StrCpy $final_project_ico "$INSTDIR\\ico\application-x-qet-project.ico"
|
||||
StrCpy $final_element_ico "$INSTDIR\\ico\application-x-qet-element.ico"
|
||||
StrCpy $final_titleblock_ico "$INSTDIR\\ico\application-x-qet-titleblock.ico"
|
||||
|
||||
; write file associations registry keys
|
||||
WriteRegStr HKEY_CLASSES_ROOT "Applications\qelectrotech.exe\shell\open\command" "" "$\"$final_qet_exe$\" $\"%1$\""
|
||||
WriteRegStr HKEY_CLASSES_ROOT ".qet" "" "qet_diagram_file"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_diagram_file" "" "Sch<EFBFBD>ma QET"
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_diagram_file" "EditFlags" 0x00000000
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_diagram_file" "BrowserFlags" 0x00000008
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_diagram_file\DefaultIcon" "" "$final_project_ico"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_diagram_file\shell\open\command" "" "$\"$final_qet_exe$\" $\"%1$\""
|
||||
WriteRegStr HKEY_CLASSES_ROOT ".elmt" "" "qet_element_file"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_element_file" "" "<EFBFBD>l<EFBFBD>ment QET"
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_element_file" "EditFlags" 0x00000000
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_element_file" "BrowserFlags" 0x00000008
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_element_file\DefaultIcon" "" "$final_element_ico"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_element_file\shell\open\command" "" "$\"$final_qet_exe$\" $\"%1$\""
|
||||
WriteRegStr HKEY_CLASSES_ROOT ".titleblock" "" "qet_titleblock_file"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_titleblock_file" "" "Titleblock QET"
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_titleblock_file" "EditFlags" 0x00000000
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_titleblock_file" "BrowserFlags" 0x00000008
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_titleblock_file\DefaultIcon" "" "$final_titleblock_ico"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_titleblock_file\shell\open\command" "" "$\"$final_qet_exe$\" $\"%1$\""
|
||||
|
||||
SetShellVarContext all ; all users
|
||||
; shortcuts in the start menu
|
||||
CreateDirectory "$SMPROGRAMS\${SOFT_NAME}"
|
||||
CreateDirectory "$SMPROGRAMS\${SOFT_NAME}\Manual"
|
||||
CreateDirectory "$SMPROGRAMS\${SOFT_NAME}\Upgrade"
|
||||
CreateShortCut "$SMPROGRAMS\${SOFT_NAME}\QElectroTech.lnk" "$INSTDIR\Lancer QET.bat" 0 "$INSTDIR\\ico\qelectrotech.ico"
|
||||
CreateShortCut "$SMPROGRAMS\${SOFT_NAME}\Uninstall QElectroTech.lnk" "$INSTDIR\Uninstall.exe"
|
||||
|
||||
; shortcut on the desktop
|
||||
CreateShortCut "$DESKTOP\QElectroTech.lnk" "$INSTDIR\Lancer QET.bat" 0 "$INSTDIR\ico\qelectrotech.ico"
|
||||
WriteINIStr "$SMPROGRAMS\${SOFT_NAME}\Manual\Manual_English.url" "InternetShortcut" "URL" "https://download.tuxfamily.org/qet/manual_0.7/build/index.html"
|
||||
WriteINIStr "$SMPROGRAMS\${SOFT_NAME}\Manual\Manual_Russian.url" "InternetShortcut" "URL" "https://download.tuxfamily.org/qet/joshua/html/QET_ru.html"
|
||||
WriteINIStr "$SMPROGRAMS\${SOFT_NAME}\Upgrade\Download.url" "InternetShortcut" "URL" "https://download.tuxfamily.org/qet/builds/nightly/"
|
||||
WriteINIStr "$SMPROGRAMS\${SOFT_NAME}\Donate.url" "InternetShortcut" "URL" "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZZHC9D7C3MDPC"
|
||||
|
||||
;changing $INSTDIR\elements\ *.elmt to read-only attribute
|
||||
${Locate} "$INSTDIR\elements\" "/L=FD /M=*.elmt" "LocateCallback"
|
||||
IfErrors 0 +2
|
||||
;MessageBox MB_OK "Error"
|
||||
SectionEnd
|
||||
|
||||
Function LocateCallback
|
||||
SetFileAttributes $R9 FILE_ATTRIBUTE_READONLY
|
||||
Push $0
|
||||
FunctionEnd
|
||||
;--------------------------------
|
||||
;Installer Functions
|
||||
|
||||
Function .onInit
|
||||
|
||||
!insertmacro MUI_LANGDLL_DISPLAY
|
||||
|
||||
;Auto-uninstall old before installing new
|
||||
ReadRegStr $R0 HKLM \
|
||||
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${SOFT_NAME}" \
|
||||
"UninstallString"
|
||||
StrCmp $R0 "" done
|
||||
|
||||
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
|
||||
"$(installed)" \
|
||||
IDOK uninst
|
||||
Abort
|
||||
|
||||
|
||||
;Run the uninstaller
|
||||
uninst:
|
||||
ClearErrors
|
||||
ExecWait '$R0 _?=$INSTDIR' ;Do not copy the uninstaller to a temp file
|
||||
|
||||
IfErrors no_remove_uninstaller done
|
||||
;You can either use Delete /REBOOTOK in the uninstaller or add some code
|
||||
;here to remove the uninstaller. Use a registry key to check
|
||||
;whether the user has chosen to uninstall. If you are using an uninstaller
|
||||
;components page, make sure all sections are uninstalled.
|
||||
no_remove_uninstaller:
|
||||
|
||||
done:
|
||||
|
||||
FunctionEnd
|
||||
|
||||
;--------------------------------
|
||||
;Descriptions
|
||||
|
||||
;USE A LANGUAGE STRING IF YOU WANT YOUR DESCRIPTIONS TO BE LANGAUGE SPECIFIC
|
||||
|
||||
;Assign descriptions to sections
|
||||
;!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
;!insertmacro MUI_DESCRIPTION_TEXT ${CopyFiles} "CopyFiles"
|
||||
;!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
|
||||
;--------------------------------
|
||||
;Uninstaller Section
|
||||
|
||||
Section "Uninstall"
|
||||
SetShellVarContext all ; all users
|
||||
; remove start menu shortcuts
|
||||
RMDir /r "$SMPROGRAMS\${SOFT_NAME}"
|
||||
; remove shortcut on the desktop
|
||||
Delete "$DESKTOP\QElectroTech.lnk"
|
||||
|
||||
; remove the application files
|
||||
Delete "$INSTDIR\*.*"
|
||||
RMDir /r "$INSTDIR"
|
||||
|
||||
;remove installation registry keys
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SOFT_NAME}"
|
||||
DeleteRegKey /ifempty HKCU "Software\${SOFT_NAME}"
|
||||
|
||||
; remove file associations registry keys
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "Applications\qelectrotech.exe"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT ".qet"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "qet_diagram_file"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT ".elmt"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "qet_element_file"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT ".titleblock"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "qet_titleblock_file"
|
||||
|
||||
IfFileExists "$INSTDIR" 0 NoErrorMsg
|
||||
;MessageBox MB_OK "Note: $INSTDIR could not be removed!" IDOK 0 ; skipped if file doesn't exist
|
||||
NoErrorMsg:
|
||||
SectionEnd
|
||||
|
||||
;--------------------------------
|
||||
;Uninstaller Functions
|
||||
|
||||
Function un.onInit
|
||||
|
||||
!insertmacro MUI_UNGETLANGUAGE
|
||||
|
||||
FunctionEnd
|
||||
@@ -1,406 +0,0 @@
|
||||
; this file is part of installer for QElectroTech
|
||||
; Copyright (C)2015 QElectroTech Team <scorpio@qelectrotech.org>
|
||||
;
|
||||
; This program is free software; you can redistribute it and/or
|
||||
; modify it under the terms of the GNU General Public License
|
||||
; as published by the Free Software Foundation; either
|
||||
; version 2 of the License, or (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program; if not, write to the Free Software
|
||||
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
; WebSite : http://qelectrotech.org/
|
||||
|
||||
;--------------------------------
|
||||
;Include Modern UI
|
||||
!include x64.nsh
|
||||
!include "MUI2.nsh"
|
||||
!include "FileFunc.nsh"
|
||||
!insertmacro Locate
|
||||
!include FileFunc.nsh
|
||||
!insertmacro GetParameters
|
||||
!insertmacro GetOptions
|
||||
|
||||
|
||||
!ifndef PROC
|
||||
!define PROC 32 ;
|
||||
!endif
|
||||
|
||||
|
||||
|
||||
; MUI Settings
|
||||
;--------------------------------
|
||||
;General
|
||||
; General Product Description Definitions
|
||||
!define SOFT_NAME "QElectroTech"
|
||||
!define SOFT_VERSION "0.5-dev_x86_64-win64+4094"
|
||||
!define SOFT_WEB_SITE "http://qelectrotech.org/"
|
||||
!define SOFT_BUILD "1"
|
||||
|
||||
|
||||
SetCompressor /final /solid lzma
|
||||
CRCCheck force
|
||||
XPStyle on
|
||||
BrandingText "${SOFT_NAME}-${SOFT_VERSION}-${SOFT_BUILD}" ; Shows in the Bottom Left of the installer
|
||||
|
||||
|
||||
;Name and file
|
||||
Name "${SOFT_NAME} ${SOFT_VERSION}"
|
||||
OutFile "Installer_${SOFT_NAME}-${SOFT_VERSION}-${SOFT_BUILD}.exe"
|
||||
|
||||
;Default installation folder
|
||||
InstallDir "$PROGRAMFILES64\${SOFT_NAME}"
|
||||
|
||||
;Get installation folder from registry if available
|
||||
InstallDirRegKey HKCU "Software\${SOFT_NAME}" ""
|
||||
|
||||
;Request application privileges for Windows Vista
|
||||
; we request for admin because we write stuff into the registry
|
||||
RequestExecutionLevel admin
|
||||
|
||||
;--------------------------------
|
||||
;Interface Settings
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\XPUI-install.ico"
|
||||
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\XPUI-uninstall.ico"
|
||||
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP ".\images\wizard.bmp"
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH
|
||||
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_BITMAP ".\images\header.bmp" ; optional
|
||||
;--------------------------------
|
||||
;Language Selection Dialog Settings
|
||||
|
||||
;Remember the installer language
|
||||
!define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
|
||||
!define MUI_LANGDLL_REGISTRY_KEY "Software\${SOFT_NAME}"
|
||||
!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
|
||||
|
||||
;--------------------------------
|
||||
;Pages
|
||||
|
||||
!define MUI_COMPONENTSPAGE_SMALLDESC
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_LICENSE "files\LICENSE"
|
||||
!insertmacro MUI_PAGE_COMPONENTS
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
; Finish page and checkbox to run QElectroTech
|
||||
!define MUI_FINISHPAGE_RUN "$INSTDIR\Lancer QET.bat"
|
||||
!define MUI_FINISHPAGE_RUN_NOTCHECKED
|
||||
!define MUI_FINISHPAGE_RUN_TEXT "$(Check)"
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
;--------------------------------
|
||||
;Languages
|
||||
;Since NSIS 2.26, the language selection dialog of Modern UI hides languages unsupported by the user's selected codepage by default.
|
||||
;To revert to the old behavior and display all languages, no matter what the user will see when they're selected, use MUI_LANGDLL_ALLLANGUAGES.
|
||||
!define MUI_LANGDLL_ALLLANGUAGES
|
||||
|
||||
; For consistency, we limit the installer to languages supported by QElectroTech itself
|
||||
!insertmacro MUI_LANGUAGE "English" ;first language is the default language
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
!insertmacro MUI_LANGUAGE "Spanish"
|
||||
!insertmacro MUI_LANGUAGE "Russian"
|
||||
!insertmacro MUI_LANGUAGE "Portuguese"
|
||||
!insertmacro MUI_LANGUAGE "Czech"
|
||||
!insertmacro MUI_LANGUAGE "Polish"
|
||||
!insertmacro MUI_LANGUAGE "Greek"
|
||||
!insertmacro MUI_LANGUAGE "Arabic"
|
||||
!insertmacro MUI_LANGUAGE "German"
|
||||
!insertmacro MUI_LANGUAGE "Italian"
|
||||
!insertmacro MUI_LANGUAGE "Romanian"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Croatian"
|
||||
!insertmacro MUI_LANGUAGE "Dutch"
|
||||
!insertmacro MUI_LANGUAGE "Dutch_Belgium"
|
||||
!insertmacro MUI_LANGUAGE "Danish"
|
||||
!insertmacro MUI_RESERVEFILE_LANGDLL
|
||||
|
||||
!include lang_extra.nsh
|
||||
!include lang_extra_fr.nsh
|
||||
|
||||
|
||||
|
||||
SetOverwrite on
|
||||
Section "Main Program"
|
||||
SectionIn RO ; Read only, always installed
|
||||
|
||||
Setoutpath "$INSTDIR\bin\"
|
||||
File "./files/bin/${SOFT_NAME}.exe"
|
||||
|
||||
Setoutpath "$INSTDIR"
|
||||
File "./files/ChangeLog"
|
||||
File "./files/CREDIT"
|
||||
File "./files/ELEMENTS.LICENSE"
|
||||
File "./files/LICENSE"
|
||||
File "./files/qet_uninstall_file_associations.reg"
|
||||
File "./files/README"
|
||||
File "./files/register_filetypes.bat"
|
||||
File "Lancer QET.bat"
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
File /r "./files/ico"
|
||||
|
||||
SectionEnd
|
||||
|
||||
;---------------------------
|
||||
SetOverwrite on
|
||||
SubSection "$(Elements)" SEC01
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Electric)"
|
||||
SetOutPath "$INSTDIR\elements"
|
||||
File /r "./files/elements/10_electric"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Logic)"
|
||||
SetOutPath "$INSTDIR\elements"
|
||||
File /r "./files/elements/20_logic"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Hydraulic)"
|
||||
SetOutPath "$INSTDIR\elements"
|
||||
File /r "./files/elements/30_hydraulic"
|
||||
SectionEnd
|
||||
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Pneumatic)"
|
||||
SetOutPath "$INSTDIR\elements"
|
||||
File /r "./files/elements/50_pneumatic"
|
||||
SectionEnd
|
||||
|
||||
|
||||
;---------------------------------
|
||||
SubSection "$(Energy)"
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(water)"
|
||||
SetOutPath "$INSTDIR\elements\60_energy"
|
||||
File /r "./files/elements/60_energy/11_water"
|
||||
File /r "./files/elements/60_energy/"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Refrigeration)"
|
||||
SetOutPath "$INSTDIR\elements\60_energy"
|
||||
File /r "./files/elements/60_energy/21_refrigeration"
|
||||
File /r "./files/elements/60_energy/"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Solar_thermal)"
|
||||
SetOutPath "$INSTDIR\elements\60_energy"
|
||||
File /r "./files/elements/60_energy/31_solar_thermal"
|
||||
File /r "./files/elements/60_energy/"
|
||||
SectionEnd
|
||||
|
||||
SubSectionEnd
|
||||
SubSectionEnd
|
||||
;-------------------------------
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Lang)" SEC02
|
||||
SetOutPath "$INSTDIR\lang"
|
||||
File "./files/lang/*.qm"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Titleblocks)" SEC03
|
||||
SetOutPath "$INSTDIR"
|
||||
File /r "./files/titleblocks"
|
||||
SectionEnd
|
||||
|
||||
SetOverwrite on
|
||||
Section "$(Examples)" SEC04
|
||||
SetOutPath "$INSTDIR"
|
||||
File /r "./files/examples"
|
||||
SectionEnd
|
||||
|
||||
;--------------------------------
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC01} $(var1)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC02} $(var2)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC03} $(var3)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC04} $(var4)
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
;--------------------------------
|
||||
|
||||
;Installer Sections
|
||||
|
||||
Section ""
|
||||
SetOutPath "$INSTDIR"
|
||||
;Store installation folder
|
||||
WriteRegStr HKCU "Software\${SOFT_NAME}" "" $INSTDIR
|
||||
; write uninstall strings
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SOFT_NAME}" "DisplayName" "${SOFT_NAME} (remove only)"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SOFT_NAME}" "UninstallString" '"$INSTDIR\Uninstall.exe"'
|
||||
;Create uninstaller
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
SetRegView 64
|
||||
|
||||
; get the final path for the icons and the launch script
|
||||
Var /GLOBAL final_qet_exe
|
||||
Var /GLOBAL final_project_ico
|
||||
Var /GLOBAL final_element_ico
|
||||
Var /GLOBAL final_titleblock_ico
|
||||
|
||||
StrCpy $final_qet_exe "$INSTDIR\Lancer QET.bat"
|
||||
StrCpy $final_project_ico "$INSTDIR\ico\application-x-qet-project.ico"
|
||||
StrCpy $final_element_ico "$INSTDIR\ico\application-x-qet-element.ico"
|
||||
StrCpy $final_titleblock_ico "$INSTDIR\ico\application-x-qet-titleblock.ico"
|
||||
|
||||
; write file associations registry keys
|
||||
WriteRegStr HKEY_CLASSES_ROOT "Applications\qelectrotech.exe\shell\open\command" "" "$\"$final_qet_exe$\" $\"%1$\""
|
||||
WriteRegStr HKEY_CLASSES_ROOT ".qet" "" "qet_diagram_file"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_diagram_file" "" "Sch<EFBFBD>ma QET"
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_diagram_file" "EditFlags" 0x00000000
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_diagram_file" "BrowserFlags" 0x00000008
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_diagram_file\DefaultIcon" "" "$final_project_ico"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_diagram_file\shell\open\command" "" "$\"$final_qet_exe$\" $\"%1$\""
|
||||
WriteRegStr HKEY_CLASSES_ROOT ".elmt" "" "qet_element_file"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_element_file" "" "<EFBFBD>l<EFBFBD>ment QET"
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_element_file" "EditFlags" 0x00000000
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_element_file" "BrowserFlags" 0x00000008
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_element_file\DefaultIcon" "" "$final_element_ico"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_element_file\shell\open\command" "" "$\"$final_qet_exe$\" $\"%1$\""
|
||||
WriteRegStr HKEY_CLASSES_ROOT ".titleblock" "" "qet_titleblock_file"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_titleblock_file" "" "Titleblock QET"
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_titleblock_file" "EditFlags" 0x00000000
|
||||
WriteRegDWORD HKEY_CLASSES_ROOT "qet_titleblock_file" "BrowserFlags" 0x00000008
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_titleblock_file\DefaultIcon" "" "$final_titleblock_ico"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "qet_titleblock_file\shell\open\command" "" "$\"$final_qet_exe$\" $\"%1$\""
|
||||
|
||||
SetShellVarContext all ; all users
|
||||
; shortcuts in the start menu
|
||||
CreateDirectory "$SMPROGRAMS\${SOFT_NAME}"
|
||||
CreateDirectory "$SMPROGRAMS\${SOFT_NAME}\Manual"
|
||||
CreateDirectory "$SMPROGRAMS\${SOFT_NAME}\Upgrade"
|
||||
CreateShortCut "$SMPROGRAMS\${SOFT_NAME}\QElectroTech.lnk" "$INSTDIR\Lancer QET.bat" 0 "$INSTDIR\ico\qelectrotech.ico"
|
||||
CreateShortCut "$SMPROGRAMS\${SOFT_NAME}\Uninstall QElectroTech.lnk" "$INSTDIR\Uninstall.exe"
|
||||
; TODO : add the QuickStart Guide (or any other documentation) when available
|
||||
|
||||
; shortcut on the desktop
|
||||
CreateShortCut "$DESKTOP\QElectroTech.lnk" "$INSTDIR\Lancer QET.bat" 0 "$INSTDIR\ico\qelectrotech.ico"
|
||||
WriteINIStr "$SMPROGRAMS\${SOFT_NAME}\Manual\Manual_English.url" "InternetShortcut" "URL" "https://download.tuxfamily.org/qet/manual_0.7/build/index.html"
|
||||
WriteINIStr "$SMPROGRAMS\${SOFT_NAME}\Manual\Manual_Russian.url" "InternetShortcut" "URL" "https://download.tuxfamily.org/qet/joshua/html/QET_ru.html"
|
||||
WriteINIStr "$SMPROGRAMS\${SOFT_NAME}\Upgrade\Download.url" "InternetShortcut" "URL" "https://download.tuxfamily.org/qet/builds/nightly/"
|
||||
WriteINIStr "$SMPROGRAMS\${SOFT_NAME}\Donate.url" "InternetShortcut" "URL" "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZZHC9D7C3MDPC"
|
||||
|
||||
;changing $INSTDIR\elements\ *.elmt to read-only attribute
|
||||
|
||||
${Locate} "$INSTDIR\elements\" "/L=FD /M=*.elmt" "LocateCallback"
|
||||
IfErrors 0 +2
|
||||
;MessageBox MB_OK "Error"
|
||||
SectionEnd
|
||||
|
||||
Function LocateCallback
|
||||
SetFileAttributes $R9 FILE_ATTRIBUTE_READONLY
|
||||
Push $0
|
||||
FunctionEnd
|
||||
|
||||
;--------------------------------
|
||||
;Installer Functions
|
||||
|
||||
Function .onInit
|
||||
!insertmacro MUI_LANGDLL_DISPLAY
|
||||
|
||||
${If} ${RunningX64}
|
||||
${Else}
|
||||
|
||||
MessageBox MB_OK|MB_ICONSTOP $(wrongArch)
|
||||
Abort $(wrongArch)
|
||||
${EndIf}
|
||||
|
||||
;Auto-uninstall old before installing new
|
||||
ReadRegStr $R0 HKLM \
|
||||
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${SOFT_NAME}" \
|
||||
"UninstallString"
|
||||
StrCmp $R0 "" done
|
||||
|
||||
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
|
||||
"$(installed)" \
|
||||
IDOK uninst
|
||||
Abort
|
||||
|
||||
;Run the uninstaller
|
||||
uninst:
|
||||
ClearErrors
|
||||
ExecWait '$R0 _?=$INSTDIR' ;Do not copy the uninstaller to a temp file
|
||||
|
||||
IfErrors no_remove_uninstaller done
|
||||
;You can either use Delete /REBOOTOK in the uninstaller or add some code
|
||||
;here to remove the uninstaller. Use a registry key to check
|
||||
;whether the user has chosen to uninstall. If you are using an uninstaller
|
||||
;components page, make sure all sections are uninstalled.
|
||||
no_remove_uninstaller:
|
||||
|
||||
done:
|
||||
|
||||
FunctionEnd
|
||||
|
||||
;--------------------------------
|
||||
;Descriptions
|
||||
|
||||
;USE A LANGUAGE STRING IF YOU WANT YOUR DESCRIPTIONS TO BE LANGAUGE SPECIFIC
|
||||
|
||||
;Assign descriptions to sections
|
||||
;!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
; !insertmacro MUI_DESCRIPTION_TEXT ${CopyFiles} "CopyFiles"
|
||||
;!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
|
||||
;--------------------------------
|
||||
;Uninstaller Section
|
||||
|
||||
Section "Uninstall"
|
||||
SetShellVarContext all ; all users
|
||||
; remove start menu shortcuts
|
||||
RMDir /r "$SMPROGRAMS\${SOFT_NAME}"
|
||||
; remove shortcut on the desktop
|
||||
Delete "$DESKTOP\QElectroTech.lnk"
|
||||
|
||||
; remove the application files
|
||||
Delete "$INSTDIR\*.*"
|
||||
RMDir /r "$INSTDIR"
|
||||
|
||||
;remove installation registry keys
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SOFT_NAME}"
|
||||
DeleteRegKey /ifempty HKCU "Software\${SOFT_NAME}"
|
||||
|
||||
; remove file associations registry keys
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "Applications\qelectrotech.exe"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT ".qet"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "qet_diagram_file"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT ".elmt"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "qet_element_file"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT ".titleblock"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "qet_titleblock_file"
|
||||
|
||||
IfFileExists "$INSTDIR" 0 NoErrorMsg
|
||||
;MessageBox MB_OK "Note: $INSTDIR could not be removed!" IDOK 0 ; skipped if file doesn't exist
|
||||
NoErrorMsg:
|
||||
SectionEnd
|
||||
|
||||
;--------------------------------
|
||||
;Uninstaller Functions
|
||||
|
||||
Function un.onInit
|
||||
|
||||
!insertmacro MUI_UNGETLANGUAGE
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
Place all files of "*win32-readytouse.zip" in the "files/" directory
|
||||
and run "QET.nsi"
|
||||
|
||||
enjoy
|
||||
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 151 KiB |
@@ -1,336 +0,0 @@
|
||||
LangString installed ${LANG_ENGLISH} "${SOFT_NAME} is already installed. $\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
LangString wrongArch ${LANG_ENGLISH} "This distribution is for 64 bits computers only."
|
||||
LangString Elements ${LANG_ENGLISH} "Elements"
|
||||
LangString Electric ${LANG_ENGLISH} "Electric"
|
||||
LangString Logic ${LANG_ENGLISH} "Logic"
|
||||
LangString Hydraulic ${LANG_ENGLISH} "Hydraulic"
|
||||
LangString Pneumatic ${LANG_ENGLISH} "Pneumatic"
|
||||
LangString Energy ${LANG_ENGLISH} "Energy"
|
||||
LangString water ${LANG_ENGLISH} "Water"
|
||||
LangString Refrigeration ${LANG_ENGLISH} "Refrigeration"
|
||||
LangString Solar_thermal ${LANG_ENGLISH} "Solar_thermal"
|
||||
LangString Lang ${LANG_ENGLISH} "Lang"
|
||||
LangString Titleblocks ${LANG_ENGLISH} "Titleblocks"
|
||||
LangString Examples ${LANG_ENGLISH} "Examples"
|
||||
LangString Check ${LANG_ENGLISH} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_ENGLISH} "Elements of the official collection"
|
||||
LangString var2 ${LANG_ENGLISH} "languagues files"
|
||||
LangString var3 ${LANG_ENGLISH} "Examples of cartridges"
|
||||
LangString var4 ${LANG_ENGLISH} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_POLISH} "${SOFT_NAME} jest już zainstalowany. $\n$\nKliknij `OK` aby odinstalować poprzednią wersję lub `Anuluj` aby przerwać aktualizację."
|
||||
LangString wrongArch ${LANG_POLISH} "To oprogramowanie jest przeznaczone wyłącznie dla komputerów 64 bitowych."
|
||||
LangString Elements ${LANG_POLISH} "Elementy"
|
||||
LangString Electric ${LANG_POLISH} "Elektryka"
|
||||
LangString Logic ${LANG_POLISH} "Automatyka"
|
||||
LangString Hydraulic ${LANG_POLISH} "Hydraullika"
|
||||
LangString Pneumatic ${LANG_POLISH} "Pneumatyka"
|
||||
LangString Energy ${LANG_POLISH} "Energia"
|
||||
LangString water ${LANG_POLISH} "Woda"
|
||||
LangString Refrigeration ${LANG_POLISH} "Chłodnictwo"
|
||||
LangString Solar_thermal ${LANG_POLISH} "Energia słoneczna"
|
||||
LangString Lang ${LANG_POLISH} "Język"
|
||||
LangString Titleblocks ${LANG_POLISH} "Tabliczki rysunkowe"
|
||||
LangString Examples ${LANG_POLISH} "Przykłady"
|
||||
LangString Check ${LANG_POLISH} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_POLISH} "Elements of the official collection"
|
||||
LangString var2 ${LANG_POLISH} "languagues files"
|
||||
LangString var3 ${LANG_POLISH} "Examples of cartridges"
|
||||
LangString var4 ${LANG_POLISH} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_GREEK} "${SOFT_NAME} είναι ήδη εγκατεστημένο. $\n$\nΠάτησε `OK` για αφαίρεση της προηγούμενης έκδοσης ή `Cancel` για ακύρωση της αναβάθμισης."
|
||||
LangString wrongArch ${LANG_GREEK} "Αυτή η διανομή είναι μόνο για 64μπιτους υπολογιστές."
|
||||
LangString Elements ${LANG_GREEK} "Στοιχεία"
|
||||
LangString Electric ${LANG_GREEK} "Ηλεκτρικά"
|
||||
LangString Logic ${LANG_GREEK} "Λογικά"
|
||||
LangString Hydraulic ${LANG_GREEK} "Υδραυλικά"
|
||||
LangString Pneumatic ${LANG_GREEK} "Πνευματικά"
|
||||
LangString Energy ${LANG_GREEK} "Ενέργεια"
|
||||
LangString water ${LANG_GREEK} "Νερό"
|
||||
LangString Refrigeration ${LANG_GREEK} "Ψύξη"
|
||||
LangString Solar_thermal ${LANG_GREEK} "Ηλιοθερμία"
|
||||
LangString Lang ${LANG_GREEK} "Γλώσσα"
|
||||
LangString Titleblocks ${LANG_GREEK} "Πινακίδες"
|
||||
LangString Examples ${LANG_GREEK} "Παραδείγματα"
|
||||
LangString Check ${LANG_GREEK} "Επιλέξτε για εκκίνηση ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_GREEK} "Στοιχεία της επίσημης συλλογής"
|
||||
LangString var2 ${LANG_GREEK} "Αρχεία γλωσσών"
|
||||
LangString var3 ${LANG_GREEK} "Examples of cartridges"
|
||||
LangString var4 ${LANG_GREEK} "Παραδείγματα διαγραμμάτων"
|
||||
|
||||
|
||||
LangString installed ${LANG_CZECH} "${SOFT_NAME} is already installed. $\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
LangString wrongArch ${LANG_CZECH} "This distribution is for 64 bits computers only."
|
||||
LangString Elements ${LANG_CZECH} "Elements"
|
||||
LangString Electric ${LANG_CZECH} "Electric"
|
||||
LangString Logic ${LANG_CZECH} "Logic"
|
||||
LangString Hydraulic ${LANG_CZECH} "Hydraulic"
|
||||
LangString Pneumatic ${LANG_CZECH} "Pneumatic"
|
||||
LangString Energy ${LANG_CZECH} "Energy"
|
||||
LangString water ${LANG_CZECH} "Water"
|
||||
LangString Refrigeration ${LANG_CZECH} "Refrigeration"
|
||||
LangString Solar_thermal ${LANG_CZECH} "Solar_thermal"
|
||||
LangString Lang ${LANG_CZECH} "Lang"
|
||||
LangString Titleblocks ${LANG_CZECH} "Titleblocks"
|
||||
LangString Examples ${LANG_CZECH} "Examples"
|
||||
LangString Check ${LANG_CZECH} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_CZECH} "Elements of the official collection"
|
||||
LangString var2 ${LANG_CZECH} "languagues files"
|
||||
LangString var3 ${LANG_CZECH} "Examples of cartridges"
|
||||
LangString var4 ${LANG_CZECH} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_SPANISH} "${SOFT_NAME} is already installed. $\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
LangString wrongArch ${LANG_SPANISH} "This distribution is for 64 bits computers only."
|
||||
LangString Elements ${LANG_SPANISH} "Elements"
|
||||
LangString Electric ${LANG_SPANISH} "Electric"
|
||||
LangString Logic ${LANG_SPANISH} "Logic"
|
||||
LangString Hydraulic ${LANG_SPANISH} "Hydraulic"
|
||||
LangString Pneumatic ${LANG_SPANISH} "Pneumatic"
|
||||
LangString Energy ${LANG_SPANISH} "Energy"
|
||||
LangString water ${LANG_SPANISH} "Water"
|
||||
LangString Refrigeration ${LANG_SPANISH} "Refrigeration"
|
||||
LangString Solar_thermal ${LANG_SPANISH} "Solar_thermal"
|
||||
LangString Lang ${LANG_SPANISH} "Lang"
|
||||
LangString Titleblocks ${LANG_SPANISH} "Titleblocks"
|
||||
LangString Examples ${LANG_SPANISH} "Examples"
|
||||
LangString Check ${LANG_SPANISH} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_SPANISH} "Elements of the official collection"
|
||||
LangString var2 ${LANG_SPANISH} "languagues files"
|
||||
LangString var3 ${LANG_SPANISH} "Examples of cartridges"
|
||||
LangString var4 ${LANG_SPANISH} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_GERMAN} "${SOFT_NAME} ist bereits installiert. $\n$\nKlicken Sie auf `OK`, um die alte Version zu deinstallieren, oder auf `Abbrechen`, um das Upgrade abzubrechen."
|
||||
LangString wrongArch ${LANG_GERMAN} "Dieses Programm läuft ausschließlich unter Windows 64 Bits."
|
||||
LangString Elements ${LANG_GERMAN} "Bauteile"
|
||||
LangString Electric ${LANG_GERMAN} "Elektrik"
|
||||
LangString Logic ${LANG_GERMAN} "Logik"
|
||||
LangString Hydraulic ${LANG_GERMAN} "Hydraulik"
|
||||
LangString Pneumatic ${LANG_GERMAN} "Pneumatik"
|
||||
LangString Energy ${LANG_GERMAN} "Energietechnik"
|
||||
LangString water ${LANG_GERMAN} "Wasser"
|
||||
LangString Refrigeration ${LANG_GERMAN} "Kältetechnik"
|
||||
LangString Solar_thermal ${LANG_GERMAN} "Solar-Wärmetechnik"
|
||||
LangString Lang ${LANG_GERMAN} "Sprachen"
|
||||
LangString Titleblocks ${LANG_GERMAN} "Zeichnungsköpfe"
|
||||
LangString Examples ${LANG_GERMAN} "Beispiele"
|
||||
LangString Check ${LANG_GERMAN} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_GERMAN} "Elements of the official collection"
|
||||
LangString var2 ${LANG_GERMAN} "languagues files"
|
||||
LangString var3 ${LANG_GERMAN} "Examples of cartridges"
|
||||
LangString var4 ${LANG_GERMAN} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_RUSSIAN} "${SOFT_NAME} уже установлен. $\n$\nДля удаления предыдущей версии нажмите `OK` или `Cancel` для отмены обновления."
|
||||
LangString wrongArch ${LANG_RUSSIAN} "Эта версия только для 64 битных компьютеров."
|
||||
LangString Elements ${LANG_RUSSIAN} "Элементы"
|
||||
LangString Electric ${LANG_RUSSIAN} "Электротехника"
|
||||
LangString Logic ${LANG_RUSSIAN} "Логика"
|
||||
LangString Hydraulic ${LANG_RUSSIAN} "Гидравлика"
|
||||
LangString Pneumatic ${LANG_RUSSIAN} "Пневматика"
|
||||
LangString Energy ${LANG_RUSSIAN} "Энергетика"
|
||||
LangString water ${LANG_RUSSIAN} "Водоснабжение"
|
||||
LangString Refrigeration ${LANG_RUSSIAN} "Холодильная техника"
|
||||
LangString Solar_thermal ${LANG_RUSSIAN} "Солнечная-тепловая"
|
||||
LangString Lang ${LANG_RUSSIAN} "Язык"
|
||||
LangString Titleblocks ${LANG_RUSSIAN} "Штампы"
|
||||
LangString Examples ${LANG_RUSSIAN} "Примеры"
|
||||
LangString Check ${LANG_RUSSIAN} "Нажмите для запуска ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_RUSSIAN} "Элементы официальной коллекции"
|
||||
LangString var2 ${LANG_RUSSIAN} "языковые файлы"
|
||||
LangString var3 ${LANG_RUSSIAN} "Примеры штампов"
|
||||
LangString var4 ${LANG_RUSSIAN} "Примеры схем"
|
||||
|
||||
|
||||
LangString installed ${LANG_ARABIC} "${SOFT_NAME} is already installed. $\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
LangString wrongArch ${LANG_ARABIC} "This distribution is for 64 bits computers only."
|
||||
LangString Elements ${LANG_ARABIC} "Elements"
|
||||
LangString Electric ${LANG_ARABIC} "Electric"
|
||||
LangString Logic ${LANG_ARABIC} "Logic"
|
||||
LangString Hydraulic ${LANG_ARABIC} "Hydraulic"
|
||||
LangString Pneumatic ${LANG_ARABIC} "Pneumatic"
|
||||
LangString Energy ${LANG_ARABIC} "Energy"
|
||||
LangString water ${LANG_ARABIC} "Water"
|
||||
LangString Refrigeration ${LANG_ARABIC} "Refrigeration"
|
||||
LangString Solar_thermal ${LANG_ARABIC} "Solar_thermal"
|
||||
LangString Lang ${LANG_ARABIC} "Lang"
|
||||
LangString Titleblocks ${LANG_ARABIC} "Titleblocks"
|
||||
LangString Examples ${LANG_ARABIC} "Examples"
|
||||
LangString Check ${LANG_ARABIC} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_ARABIC} "Elements of the official collection"
|
||||
LangString var2 ${LANG_ARABIC} "languagues files"
|
||||
LangString var3 ${LANG_ARABIC} "Examples of cartridges"
|
||||
LangString var4 ${LANG_ARABIC} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_CATALAN} "${SOFT_NAME} is already installed. $\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
LangString wrongArch ${LANG_CATALAN} "This distribution is for 64 bits computers only."
|
||||
LangString Elements ${LANG_CATALAN} "Elements"
|
||||
LangString Electric ${LANG_CATALAN} "Electric"
|
||||
LangString Logic ${LANG_CATALAN} "Logic"
|
||||
LangString Hydraulic ${LANG_CATALAN} "Hydraulic"
|
||||
LangString Pneumatic ${LANG_CATALAN} "Pneumatic"
|
||||
LangString Energy ${LANG_CATALAN} "Energy"
|
||||
LangString water ${LANG_CATALAN} "Water"
|
||||
LangString Refrigeration ${LANG_CATALAN} "Refrigeration"
|
||||
LangString Solar_thermal ${LANG_CATALAN} "Solar_thermal"
|
||||
LangString Lang ${LANG_CATALAN} "Lang"
|
||||
LangString Titleblocks ${LANG_CATALAN} "Titleblocks"
|
||||
LangString Examples ${LANG_CATALAN} "Examples"
|
||||
LangString Check ${LANG_CATALAN} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_CATALAN} "Elements of the official collection"
|
||||
LangString var2 ${LANG_CATALAN} "languagues files"
|
||||
LangString var3 ${LANG_CATALAN} "Examples of cartridges"
|
||||
LangString var4 ${LANG_CATALAN} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_ITALIAN} "${SOFT_NAME} è già installato. $\n$\nFare click su `OK` per rimuovere la versione precedente o su `Annulla` per annullare questo aggiornamento."
|
||||
LangString wrongArch ${LANG_ITALIAN} "Questa distribuzione è riservata ai sistemi a 64 bit."
|
||||
LangString Elements ${LANG_ITALIAN} "Elementi"
|
||||
LangString Electric ${LANG_ITALIAN} "Electricità"
|
||||
LangString Logic ${LANG_ITALIAN} "Logica"
|
||||
LangString Hydraulic ${LANG_ITALIAN} "Idraulica"
|
||||
LangString Pneumatic ${LANG_ITALIAN} "Pneumatica"
|
||||
LangString Energy ${LANG_ITALIAN} "Energia"
|
||||
LangString water ${LANG_ITALIAN} "Acqua"
|
||||
LangString Refrigeration ${LANG_ITALIAN} "Refrigerazione"
|
||||
LangString Solar_thermal ${LANG_ITALIAN} "Solare_termico"
|
||||
LangString Lang ${LANG_ITALIAN} "Lingua"
|
||||
LangString Titleblocks ${LANG_ITALIAN} "Cartigli"
|
||||
LangString Examples ${LANG_ITALIAN} "Esempi"
|
||||
LangString Check ${LANG_ITALIAN} "Avvia ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_ITALIAN} "Elementi della collezione ufficiale"
|
||||
LangString var2 ${LANG_ITALIAN} "File della lingua"
|
||||
LangString var3 ${LANG_ITALIAN} "Cartigli di esempio"
|
||||
LangString var4 ${LANG_ITALIAN} "Schemi di esempio"
|
||||
|
||||
|
||||
LangString installed ${LANG_PORTUGUESE} "${SOFT_NAME} is already installed. $\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
LangString wrongArch ${LANG_PORTUGUESE} "This distribution is for 64 bits computers only."
|
||||
LangString Elements ${LANG_PORTUGUESE} "Elements"
|
||||
LangString Electric ${LANG_PORTUGUESE} "Electric"
|
||||
LangString Logic ${LANG_PORTUGUESE} "Logic"
|
||||
LangString Hydraulic ${LANG_PORTUGUESE} "Hydraulic"
|
||||
LangString Pneumatic ${LANG_PORTUGUESE} "Pneumatic"
|
||||
LangString Energy ${LANG_PORTUGUESE} "Energy"
|
||||
LangString water ${LANG_PORTUGUESE} "Water"
|
||||
LangString Refrigeration ${LANG_PORTUGUESE} "Refrigeration"
|
||||
LangString Solar_thermal ${LANG_PORTUGUESE} "Solar_thermal"
|
||||
LangString Lang ${LANG_PORTUGUESE} "Lang"
|
||||
LangString Titleblocks ${LANG_PORTUGUESE} "Titleblocks"
|
||||
LangString Examples ${LANG_PORTUGUESE} "Examples"
|
||||
LangString Check ${LANG_PORTUGUESE} "Avviare ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_PORTUGUESE} "Elements of the official collection"
|
||||
LangString var2 ${LANG_PORTUGUESE} "languagues files"
|
||||
LangString var3 ${LANG_PORTUGUESE} "Examples of cartridges"
|
||||
LangString var4 ${LANG_PORTUGUESE} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_ROMANIAN} "${SOFT_NAME} is already installed. $\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
LangString wrongArch ${LANG_ROMANIAN} "This distribution is for 64 bits computers only."
|
||||
LangString Elements ${LANG_ROMANIAN} "Elements"
|
||||
LangString Electric ${LANG_ROMANIAN} "Electric"
|
||||
LangString Logic ${LANG_ROMANIAN} "Logic"
|
||||
LangString Hydraulic ${LANG_ROMANIAN} "Hydraulic"
|
||||
LangString Pneumatic ${LANG_ROMANIAN} "Pneumatic"
|
||||
LangString Energy ${LANG_ROMANIAN} "Energy"
|
||||
LangString water ${LANG_ROMANIAN} "Water"
|
||||
LangString Refrigeration ${LANG_ROMANIAN} "Refrigeration"
|
||||
LangString Solar_thermal ${LANG_ROMANIAN} "Solar_thermal"
|
||||
LangString Lang ${LANG_ROMANIAN} "Lang"
|
||||
LangString Titleblocks ${LANG_ROMANIAN} "Titleblocks"
|
||||
LangString Examples ${LANG_ROMANIAN} "Examples"
|
||||
LangString Check ${LANG_ROMANIAN} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_ROMANIAN} "Elements of the official collection"
|
||||
LangString var2 ${LANG_ROMANIAN} "languagues files"
|
||||
LangString var3 ${LANG_ROMANIAN} "Examples of cartridges"
|
||||
LangString var4 ${LANG_ROMANIAN} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_CROATIAN} "${SOFT_NAME} is already installed. $\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
LangString wrongArch ${LANG_CROATIAN} "This distribution is for 64 bits computers only."
|
||||
LangString Elements ${LANG_CROATIAN} "Elements"
|
||||
LangString Electric ${LANG_CROATIAN} "Electric"
|
||||
LangString Logic ${LANG_CROATIAN} "Logic"
|
||||
LangString Hydraulic ${LANG_CROATIAN} "Hydraulic"
|
||||
LangString Pneumatic ${LANG_CROATIAN} "Pneumatic"
|
||||
LangString Energy ${LANG_CROATIAN} "Energy"
|
||||
LangString water ${LANG_CROATIAN} "Water"
|
||||
LangString Refrigeration ${LANG_CROATIAN} "Refrigeration"
|
||||
LangString Solar_thermal ${LANG_CROATIAN} "Solar_thermal"
|
||||
LangString Lang ${LANG_CROATIAN} "Lang"
|
||||
LangString Titleblocks ${LANG_CROATIAN} "Titleblocks"
|
||||
LangString Examples ${LANG_CROATIAN} "Examples"
|
||||
LangString Check ${LANG_CROATIAN} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_CROATIAN} "Elements of the official collection"
|
||||
LangString var2 ${LANG_CROATIAN} "languagues files"
|
||||
LangString var3 ${LANG_CROATIAN} "Examples of cartridges"
|
||||
LangString var4 ${LANG_CROATIAN} "Examples of diagrams"
|
||||
|
||||
|
||||
LangString installed ${LANG_DUTCH} "${SOFT_NAME} is al geinstalleerd. $\n$\nklik `OK` om vorige versie te verwijderen of `annuleer` om deze upgrade te annuleren."
|
||||
LangString wrongArch ${LANG_DUTCH} "Deze distributie is alleen voor 64 bits computers."
|
||||
LangString Elements ${LANG_DUTCH} "Elementen"
|
||||
LangString Electric ${LANG_DUTCH} "Electriciteit"
|
||||
LangString Logic ${LANG_DUTCH} "Logica"
|
||||
LangString Hydraulic ${LANG_DUTCH} "Hydraulisch"
|
||||
LangString Pneumatic ${LANG_DUTCH} "Pneumatisch"
|
||||
LangString Energy ${LANG_DUTCH} "Energie"
|
||||
LangString water ${LANG_DUTCH} "Water"
|
||||
LangString Refrigeration ${LANG_DUTCH} "Koelinstallaties"
|
||||
LangString Solar_thermal ${LANG_DUTCH} "Zonne_warmte"
|
||||
LangString Lang ${LANG_DUTCH} "Taal"
|
||||
LangString Titleblocks ${LANG_DUTCH} "Titelblok"
|
||||
LangString Examples ${LANG_DUTCH} "Voorbeelden"
|
||||
LangString Check ${LANG_DUTCH} "Check to start ${SOFT_NAME}"
|
||||
LangString Check ${LANG_DUTCH} "Check to start ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_DUTCH} "Elements of the official collection"
|
||||
LangString var2 ${LANG_DUTCH} "languagues files"
|
||||
LangString var3 ${LANG_DUTCH} "Examples of cartridges"
|
||||
LangString var4 ${LANG_DUTCH} "Examples of diagrams"
|
||||
|
||||
LangString installed ${LANG_DUTCH_BELGIUM} "${SOFT_NAME} is reeds geinstallerd. $\n$\nKlik`OK` om vorige versie te verwijderen of `Afbreken` om de upgrade niet uit te voeren."
|
||||
LangString wrongArch ${LANG_DUTCH_BELGIUM} "Deze distributie werkt enkel op 64 bits computers."
|
||||
LangString Elements ${LANG_DUTCH_BELGIUM} "Elementen"
|
||||
LangString Electric ${LANG_DUTCH_BELGIUM} "Electrisch"
|
||||
LangString Logic ${LANG_DUTCH_BELGIUM} "Logica"
|
||||
LangString Hydraulic ${LANG_DUTCH_BELGIUM} "Hydraulisch"
|
||||
LangString Pneumatic ${LANG_DUTCH_BELGIUM} "Pneumatisch"
|
||||
LangString Energy ${LANG_DUTCH_BELGIUM} "Energie"
|
||||
LangString water ${LANG_DUTCH_BELGIUM} "Water"
|
||||
LangString Refrigeration ${LANG_DUTCH_BELGIUM} "Klimatisatie"
|
||||
LangString Solar_thermal ${LANG_DUTCH_BELGIUM} "Termisch & zonlicht"
|
||||
LangString Lang ${LANG_DUTCH_BELGIUM} "Taal"
|
||||
LangString Titleblocks ${LANG_DUTCH_BELGIUM} "Titelhoek"
|
||||
LangString Examples ${LANG_DUTCH_BELGIUM} "Voorbeelden"
|
||||
LangString Check ${LANG_DUTCH_BELGIUM} "Controleer om te beginnen ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_DUTCH_BELGIUM} "Symbolen van de officielen verzameling"
|
||||
LangString var2 ${LANG_DUTCH_BELGIUM} "taal bestanden"
|
||||
LangString var3 ${LANG_DUTCH_BELGIUM} "Voorbeel titelhoeken"
|
||||
LangString var4 ${LANG_DUTCH_BELGIUM} "Voorbeeld schema's"
|
||||
|
||||
|
||||
LangString installed ${LANG_DANISH} "${SOFT_NAME} er allerede installeret. $\n$\nKlik `Ok` for at fjerne foregående version eller `Annuller` for at annullere opgraderingen."
|
||||
LangString wrongArch ${LANG_DANISH} "Dette program er kun for 64 bit systemer."
|
||||
LangString Elements ${LANG_DANISH} "Symboler"
|
||||
LangString Electric ${LANG_DANISH} "Elektrisk"
|
||||
LangString Logic ${LANG_DANISH} "Logik"
|
||||
LangString Hydraulic ${LANG_DANISH} "Hydraulik"
|
||||
LangString Pneumatic ${LANG_DANISH} "Pneumatik"
|
||||
LangString Energy ${LANG_DANISH} "Energi teknik"
|
||||
LangString water ${LANG_DANISH} "VVS teknik"
|
||||
LangString Refrigeration ${LANG_DANISH} "Køle teknik"
|
||||
LangString Solar_thermal ${LANG_DANISH} "Sol & varme teknik"
|
||||
LangString Lang ${LANG_DANISH} "Sprog"
|
||||
LangString Titleblocks ${LANG_DANISH} "Titel blokke"
|
||||
LangString Examples ${LANG_DANISH} "Eksempler"
|
||||
LangString Check ${LANG_DANISH} "Vælg for at starte ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_DANISH} "Symboler fra officiel samling"
|
||||
LangString var2 ${LANG_DANISH} "Sprog filer"
|
||||
LangString var3 ${LANG_DANISH} "Titel blokke eksempler"
|
||||
LangString var4 ${LANG_DANISH} "Diagram eksempler"
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
LangString wrongArch ${LANG_FRENCH} "Ce programme est pour Windows 64 bits seulement."
|
||||
LangString installed ${LANG_FRENCH} "${SOFT_NAME} est d<>ja install<6C>. $\n$\nCliquer sur `OK` pour d<>sinstaller l'ancienne version `Annuler` pour annuler cet upgrade."
|
||||
LangString Elements ${LANG_FRENCH} "El<EFBFBD>ments"
|
||||
LangString Electric ${LANG_FRENCH} "Electrique"
|
||||
LangString Logic ${LANG_FRENCH} "Logique"
|
||||
LangString Hydraulic ${LANG_FRENCH} "Hydraulique"
|
||||
LangString Pneumatic ${LANG_FRENCH} "Pneumatique"
|
||||
LangString Energy ${LANG_FRENCH} "Energie"
|
||||
LangString water ${LANG_FRENCH} "Eaux"
|
||||
LangString Refrigeration ${LANG_FRENCH} "Climatisation"
|
||||
LangString Solar_thermal ${LANG_FRENCH} "Thermique & solaire"
|
||||
LangString Lang ${LANG_FRENCH} "Langues"
|
||||
LangString Titleblocks ${LANG_FRENCH} "Cartouches"
|
||||
LangString Examples ${LANG_FRENCH} "Exemples"
|
||||
LangString Check ${LANG_FRENCH} "Cocher pour lancer ${SOFT_NAME}"
|
||||
LangString var1 ${LANG_FRENCH} "El<EFBFBD>ments de la collection officielle"
|
||||
LangString var2 ${LANG_FRENCH} "Fichiers de langues"
|
||||
LangString var3 ${LANG_FRENCH} "Exemples de cartouches"
|
||||
LangString var4 ${LANG_FRENCH} "Exemples de sch<63>mas"
|
||||
1277
conductor.cpp
Normal file
141
conductor.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
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 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-2020 The QElectroTech Team
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -16,13 +16,11 @@
|
||||
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()
|
||||
{
|
||||
ConductorProfile::ConductorProfile() {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,27 +63,23 @@ ConductorProfile &ConductorProfile::operator=(const ConductorProfile &c) {
|
||||
}
|
||||
|
||||
/// destructeur
|
||||
ConductorProfile::~ConductorProfile()
|
||||
{
|
||||
ConductorProfile::~ConductorProfile() {
|
||||
setNull();
|
||||
}
|
||||
|
||||
/// @return true si le profil est nul
|
||||
bool ConductorProfile::isNull() const
|
||||
{
|
||||
bool ConductorProfile::isNull() const {
|
||||
return(segments.isEmpty());
|
||||
}
|
||||
|
||||
/// supprime les segments du profil de conducteur
|
||||
void ConductorProfile::setNull()
|
||||
{
|
||||
void ConductorProfile::setNull() {
|
||||
foreach(ConductorSegmentProfile *csp, segments) delete csp;
|
||||
segments.clear();
|
||||
}
|
||||
|
||||
/// @return la largeur occupee par le conducteur
|
||||
qreal ConductorProfile::width() const
|
||||
{
|
||||
qreal ConductorProfile::width() const {
|
||||
qreal width = 0.0;
|
||||
foreach(ConductorSegmentProfile *csp, segments) {
|
||||
if (csp -> isHorizontal) width += csp -> length;
|
||||
@@ -106,8 +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) {
|
||||
@@ -118,8 +111,7 @@ uint ConductorProfile::segmentsCount(QET::ConductorSegmentType type) const
|
||||
}
|
||||
|
||||
/// @return les segments horizontaux de ce profil
|
||||
QList<ConductorSegmentProfile *> ConductorProfile::horizontalSegments()
|
||||
{
|
||||
QList<ConductorSegmentProfile *> ConductorProfile::horizontalSegments() {
|
||||
QList<ConductorSegmentProfile *> segments_list;
|
||||
foreach(ConductorSegmentProfile *csp, segments) {
|
||||
if (csp -> isHorizontal) segments_list << csp;
|
||||
@@ -128,8 +120,7 @@ QList<ConductorSegmentProfile *> ConductorProfile::horizontalSegments()
|
||||
}
|
||||
|
||||
/// @return les segments verticaux de ce profil
|
||||
QList<ConductorSegmentProfile *> ConductorProfile::verticalSegments()
|
||||
{
|
||||
QList<ConductorSegmentProfile *> ConductorProfile::verticalSegments() {
|
||||
QList<ConductorSegmentProfile *> segments_list;
|
||||
foreach(ConductorSegmentProfile *csp, segments) {
|
||||
if (!csp -> isHorizontal) segments_list << csp;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2020 The QElectroTech Team
|
||||
Copyright 2006-2007 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
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
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 "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
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
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 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
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
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 "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
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
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 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-2020 The QElectroTech Team
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -41,8 +41,7 @@ ConductorSegment::ConductorSegment(
|
||||
/**
|
||||
Destructeur - Relie le segment precedent au suivant
|
||||
*/
|
||||
ConductorSegment::~ConductorSegment()
|
||||
{
|
||||
ConductorSegment::~ConductorSegment() {
|
||||
if (hasPreviousSegment()) previousSegment() -> setNextSegment(nextSegment());
|
||||
if (hasNextSegment()) nextSegment() -> setPreviousSegment(previousSegment());
|
||||
}
|
||||
@@ -55,8 +54,7 @@ ConductorSegment::~ConductorSegment()
|
||||
@param possible_dx La valeur du mouvement possible (au maximum)
|
||||
@return true si le mouvement est possible ; false s'il doit etre limite
|
||||
*/
|
||||
bool ConductorSegment::canMove1stPointX(const qreal &asked_dx, qreal &possible_dx) const
|
||||
{
|
||||
bool ConductorSegment::canMove1stPointX(const qreal &asked_dx, qreal &possible_dx) const {
|
||||
|
||||
Q_ASSERT_X(isVertical(), "ConductorSegment::canMove1stPointX", "segment non vertical");
|
||||
|
||||
@@ -115,8 +113,7 @@ bool ConductorSegment::canMove1stPointX(const qreal &asked_dx, qreal &possible_d
|
||||
@param possible_dx La valeur du mouvement possible (au maximum)
|
||||
@return true si le mouvement est possible ; false s'il doit etre limite
|
||||
*/
|
||||
bool ConductorSegment::canMove2ndPointX(const qreal &asked_dx, qreal &possible_dx) const
|
||||
{
|
||||
bool ConductorSegment::canMove2ndPointX(const qreal &asked_dx, qreal &possible_dx) const {
|
||||
|
||||
Q_ASSERT_X(isVertical(), "ConductorSegment::canMove2ndPointX", "segment non vertical");
|
||||
|
||||
@@ -175,8 +172,7 @@ bool ConductorSegment::canMove2ndPointX(const qreal &asked_dx, qreal &possible_d
|
||||
@param possible_dy La valeur du mouvement possible (au maximum)
|
||||
@return true si le mouvement est possible ; false s'il doit etre limite
|
||||
*/
|
||||
bool ConductorSegment::canMove1stPointY(const qreal &asked_dy, qreal &possible_dy) const
|
||||
{
|
||||
bool ConductorSegment::canMove1stPointY(const qreal &asked_dy, qreal &possible_dy) const {
|
||||
|
||||
Q_ASSERT_X(isHorizontal(), "ConductorSegment::canMove1stPointY", "segment non horizontal");
|
||||
|
||||
@@ -235,8 +231,7 @@ bool ConductorSegment::canMove1stPointY(const qreal &asked_dy, qreal &possible_d
|
||||
@param possible_dy La valeur du mouvement possible (au maximum)
|
||||
@return true si le mouvement est possible ; false s'il doit etre limite
|
||||
*/
|
||||
bool ConductorSegment::canMove2ndPointY(const qreal &asked_dy, qreal &possible_dy) const
|
||||
{
|
||||
bool ConductorSegment::canMove2ndPointY(const qreal &asked_dy, qreal &possible_dy) const {
|
||||
|
||||
Q_ASSERT_X(isHorizontal(), "ConductorSegment::canMove2ndPointY", "segment non horizontal");
|
||||
|
||||
@@ -406,68 +401,59 @@ void ConductorSegment::setNextSegment(ConductorSegment *ns) {
|
||||
}
|
||||
|
||||
/// @return true si ce segment est un segment statique, cad un segment relie a une borne
|
||||
bool ConductorSegment::isStatic() const
|
||||
{
|
||||
bool ConductorSegment::isStatic() const {
|
||||
return(isFirstSegment() || isLastSegment());
|
||||
}
|
||||
|
||||
/// @return true si ce segment est le premier du conducteur
|
||||
bool ConductorSegment::isFirstSegment() const
|
||||
{
|
||||
bool ConductorSegment::isFirstSegment() const {
|
||||
return(!hasPreviousSegment());
|
||||
}
|
||||
|
||||
/// @return true si ce segment est le dernier du conducteur
|
||||
bool ConductorSegment::isLastSegment() const
|
||||
{
|
||||
bool ConductorSegment::isLastSegment() const {
|
||||
return(!hasNextSegment());
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le segment precedent
|
||||
*/
|
||||
ConductorSegment *ConductorSegment::previousSegment() const
|
||||
{
|
||||
ConductorSegment *ConductorSegment::previousSegment() const {
|
||||
return(previous_segment);
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le segment suivant
|
||||
*/
|
||||
ConductorSegment *ConductorSegment::nextSegment() const
|
||||
{
|
||||
ConductorSegment *ConductorSegment::nextSegment() const {
|
||||
return(next_segment);
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le segment est vertical, false sinon
|
||||
*/
|
||||
bool ConductorSegment::isVertical() const
|
||||
{
|
||||
bool ConductorSegment::isVertical() const {
|
||||
return(point1.x() == point2.x());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le segment est horizontal, false sinon
|
||||
*/
|
||||
bool ConductorSegment::isHorizontal() const
|
||||
{
|
||||
bool ConductorSegment::isHorizontal() const {
|
||||
return(point1.y() == point2.y());
|
||||
}
|
||||
|
||||
/**
|
||||
@return le premier point du segment
|
||||
*/
|
||||
QPointF ConductorSegment::firstPoint() const
|
||||
{
|
||||
QPointF ConductorSegment::firstPoint() const {
|
||||
return(point1);
|
||||
}
|
||||
|
||||
/**
|
||||
@return le second point du segment
|
||||
*/
|
||||
QPointF ConductorSegment::secondPoint() const
|
||||
{
|
||||
QPointF ConductorSegment::secondPoint() const {
|
||||
return(point2);
|
||||
}
|
||||
|
||||
@@ -490,24 +476,21 @@ void ConductorSegment::setSecondPoint(const QPointF &p) {
|
||||
/**
|
||||
@return true si le segment a un segment precedent, false sinon
|
||||
*/
|
||||
bool ConductorSegment::hasPreviousSegment() const
|
||||
{
|
||||
return(previous_segment != nullptr);
|
||||
bool ConductorSegment::hasPreviousSegment() const {
|
||||
return(previous_segment != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le segment a un segment suivant, false sinon
|
||||
*/
|
||||
bool ConductorSegment::hasNextSegment() const
|
||||
{
|
||||
return(next_segment != nullptr);
|
||||
bool ConductorSegment::hasNextSegment() const {
|
||||
return(next_segment != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le centre du rectangle delimitant le conducteur
|
||||
*/
|
||||
QPointF ConductorSegment::middle() const
|
||||
{
|
||||
QPointF ConductorSegment::middle() const {
|
||||
return(
|
||||
QPointF(
|
||||
(point1.x() + point2.x()) / 2.0,
|
||||
@@ -519,8 +502,7 @@ QPointF ConductorSegment::middle() const
|
||||
/**
|
||||
@return La longueur du conducteur
|
||||
*/
|
||||
qreal ConductorSegment::length() const
|
||||
{
|
||||
qreal ConductorSegment::length() const {
|
||||
if (isHorizontal()) {
|
||||
return(secondPoint().x() - firstPoint().x());
|
||||
} else {
|
||||
@@ -529,13 +511,11 @@ qreal ConductorSegment::length() const
|
||||
}
|
||||
|
||||
/// @return QET::Horizontal si le segment est horizontal, QET::Vertical sinon
|
||||
QET::ConductorSegmentType ConductorSegment::type() const
|
||||
{
|
||||
QET::ConductorSegmentType ConductorSegment::type() const {
|
||||
return(isHorizontal() ? QET::Horizontal : QET::Vertical);
|
||||
}
|
||||
|
||||
/// @return true si les deux points constituant le segment sont egaux
|
||||
bool ConductorSegment::isPoint() const
|
||||
{
|
||||
bool ConductorSegment::isPoint() const {
|
||||
return(point1 == point2);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006-2020 The QElectroTech Team
|
||||
Copyright 2006-2007 Xavier Guerrin
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
@@ -20,26 +20,26 @@
|
||||
#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 * = nullptr, ConductorSegment * = nullptr);
|
||||
ConductorSegment(const QPointF &, const QPointF &, ConductorSegment * = NULL, ConductorSegment * = NULL);
|
||||
virtual ~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
@@ -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 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
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
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 "configdialog.h"
|
||||
#include "qetapp.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param parent QWidget parent
|
||||
*/
|
||||
ConfigDialog::ConfigDialog(QWidget *parent) : QDialog(parent) {
|
||||
|
||||
setWindowTitle(tr("Configurer QElectroTech"));
|
||||
|
||||
// liste des pages
|
||||
pages_list = new QListWidget();
|
||||
pages_list -> setViewMode(QListView::IconMode);
|
||||
pages_list -> setIconSize(QSize(48, 48));
|
||||
pages_list -> setMovement(QListView::Static);
|
||||
pages_list -> setMinimumWidth(135);
|
||||
pages_list -> setMaximumWidth(135);
|
||||
pages_list -> setSpacing(4);
|
||||
|
||||
// pages
|
||||
pages_widget = new QStackedWidget();
|
||||
addPage(new NewDiagramPage());
|
||||
buildPagesList();
|
||||
|
||||
// boutons
|
||||
buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
|
||||
|
||||
// layouts
|
||||
QHBoxLayout *hlayout1 = new QHBoxLayout();
|
||||
hlayout1 -> addWidget(pages_list);
|
||||
hlayout1 -> addWidget(pages_widget);
|
||||
|
||||
QVBoxLayout *vlayout1 = new QVBoxLayout();
|
||||
vlayout1 -> addLayout(hlayout1);
|
||||
vlayout1 -> addWidget(buttons);
|
||||
setLayout(vlayout1);
|
||||
|
||||
// connexion signaux / slots
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(applyConf()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(pages_list, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(changePage(QListWidgetItem *, QListWidgetItem*)));
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
ConfigDialog::~ConfigDialog() {
|
||||
}
|
||||
|
||||
/**
|
||||
Gere les changements de page dans le dialogue de configuration
|
||||
*/
|
||||
void ConfigDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) {
|
||||
if (!current) current = previous;
|
||||
pages_widget -> setCurrentIndex(pages_list -> row(current));
|
||||
}
|
||||
|
||||
/**
|
||||
Construit la liste des pages sur la gauche
|
||||
*/
|
||||
void ConfigDialog::buildPagesList() {
|
||||
pages_list -> clear();
|
||||
foreach(ConfigPage *page, pages) {
|
||||
QListWidgetItem *new_button = new QListWidgetItem(pages_list);
|
||||
new_button -> setIcon(page -> icon());
|
||||
new_button -> setText(page -> title());
|
||||
new_button -> setTextAlignment(Qt::AlignHCenter);
|
||||
new_button -> setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Applique la configuration de toutes les pages
|
||||
*/
|
||||
void ConfigDialog::applyConf() {
|
||||
foreach(ConfigPage *page, pages) {
|
||||
page -> applyConf();
|
||||
}
|
||||
accept();
|
||||
}
|
||||
|
||||
/**
|
||||
Ajoute une page au dialogue de configuration
|
||||
*/
|
||||
void ConfigDialog::addPage(ConfigPage *page) {
|
||||
if (!page || pages.contains(page)) return;
|
||||
pages << page;
|
||||
pages_widget -> addWidget(page);
|
||||
}
|
||||
56
configdialog.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 CONFIG_DIALOG_H
|
||||
#define CONFIG_DIALOG_H
|
||||
#include <QDialog>
|
||||
#include "configpages.h"
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
class QStackedWidget;
|
||||
class QDialogButtonBox;
|
||||
/**
|
||||
Cette classe represente le dialogue de configuration de QElectroTech.
|
||||
Il s'agit d'un dialogue affichant des "pages de configuration".
|
||||
Chaque page de configuration doit fournir une icone et un titre.
|
||||
*/
|
||||
class ConfigDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
ConfigDialog(QWidget * = 0);
|
||||
virtual ~ConfigDialog();
|
||||
private:
|
||||
ConfigDialog(const ConfigDialog &);
|
||||
|
||||
// methodes
|
||||
public slots:
|
||||
void changePage(QListWidgetItem *, QListWidgetItem *);
|
||||
void applyConf();
|
||||
void addPage(ConfigPage *);
|
||||
|
||||
private:
|
||||
void buildPagesList();
|
||||
|
||||
// attributs
|
||||
private:
|
||||
QListWidget *pages_list;
|
||||
QStackedWidget *pages_widget;
|
||||
QDialogButtonBox *buttons;
|
||||
QList<ConfigPage *> pages;
|
||||
};
|
||||
#endif
|
||||
136
configpages.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
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 "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
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
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 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
|
||||
565
customelement.cpp
Normal file
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
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 "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::MiterJoin);
|
||||
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);
|
||||
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::MiterJoin);
|
||||
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
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
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 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,7 +0,0 @@
|
||||
ChangeElementInformationCommand = 1
|
||||
LinkElementCommand = 2
|
||||
ItemResizerCommand = 3
|
||||
ChangeShapeStyleCommand = 4
|
||||
QetShapeGeometryCommand = 5
|
||||
AlignmentTextsGroupCommand = 6
|
||||
QPropertyUndoCommand = 10 000
|
||||
@@ -1,32 +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
|
||||
DynamiqueElementTextItem + 1010
|
||||
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
|
||||
part dynamic text field + 1110
|
||||
|
||||
###QetGraphicsHandlerItem###
|
||||
QetGraphicsHandlerItem + 1200
|
||||
|
||||
###VIEW ITEMS###
|
||||
QetGraphicsTableItem + 1300
|
||||
QetGraphicsHeaderItem + 1301
|
||||
648
diagram.cpp
Normal file
@@ -0,0 +1,648 @@
|
||||
/*
|
||||
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 <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
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
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 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
@@ -0,0 +1,625 @@
|
||||
/*
|
||||
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 "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
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
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_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
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
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 "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
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
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_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
|
||||
200
diagramtextitem.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
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 "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
@@ -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 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
|
||||
960
diagramview.cpp
Normal file
@@ -0,0 +1,960 @@
|
||||
/*
|
||||
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 "diagramview.h"
|
||||
#include "diagram.h"
|
||||
#include "customelement.h"
|
||||
#include "exportdialog.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() {
|
||||
// initialise l'acces a l'imprimante
|
||||
QPrinter qprin;
|
||||
#ifndef Q_OS_WIN32
|
||||
qprin.setOutputFormat(QPrinter::PdfFormat);
|
||||
#endif
|
||||
qprin.setOrientation(QPrinter::Landscape);
|
||||
qprin.setPageSize(QPrinter::A4);
|
||||
QPrintDialog qpd(&qprin, this);
|
||||
|
||||
if (qpd.exec() == QDialog::Accepted) {
|
||||
QPainter qp(&qprin);
|
||||
// impression physique (!= fichier PDF)
|
||||
if (qprin.outputFileName().isEmpty()) {
|
||||
// lorsqu'on imprime en paysage sur imprimante reelle, il faut pivoter soi-meme le rendu
|
||||
if (qprin.orientation() == QPrinter::Landscape) {
|
||||
qp.rotate(90.0);
|
||||
qp.translate(0.0, -qprin.pageRect().height());
|
||||
}
|
||||
}
|
||||
scene -> setDisplayGrid(false);
|
||||
scene -> setDrawTerminals(false);
|
||||
scene -> render(&qp, QRectF(), scene -> border(), Qt::KeepAspectRatio);
|
||||
scene -> setDrawTerminals(true);
|
||||
scene -> setDisplayGrid(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
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
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
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 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
|
||||
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 43 KiB |
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||