1 /*
2 	Copyright 2006-2019 The QElectroTech Team
3 	This file is part of QElectroTech.
4 
5 	QElectroTech is free software: you can redistribute it and/or modify
6 	it under the terms of the GNU General Public License as published by
7 	the Free Software Foundation, either version 2 of the License, or
8 	(at your option) any later version.
9 
10 	QElectroTech is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU General Public License for more details.
14 
15 	You should have received a copy of the GNU General Public License
16 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "nameslist.h"
19 #include "qetapp.h"
20 
21 // make this class usable with QVariant
22 int NamesList::MetaTypeId = qRegisterMetaType<NamesList>("NamesList");
23 
24 /**
25 	Constructeur
26 */
NamesList()27 NamesList::NamesList() {
28 }
29 
30 /**
31 	Constructeur de copie
32 	@param other La NamesList a copier
33 */
NamesList(const NamesList & other)34 NamesList::NamesList(const NamesList &other) : hash_names(other.hash_names) {
35 }
36 
37 /**
38 	Destructeur
39 */
~NamesList()40 NamesList::~NamesList() {
41 }
42 
43 /**
44 	Ajoute un nom a la liste
45 	@param lang Sigle de deux lettres representant une langue. Si cela n'est
46 	pas respecte, l'insertion n'est pas effectuee.
47 	@param name Nom lui-meme. Ce ne doit pas etre une chaine de caractere vide.
48 	Si cela n'est pas respecte, l'insertion n'est pas effectuee.
49 */
addName(const QString & lang,const QString & name)50 void NamesList::addName(const QString &lang, const QString &name) {
51 	if (lang.length() != 2) return;
52 	hash_names.insert(lang, name);
53 }
54 
55 /**
56 	Enleve le nom dont une langue donnee
57 	@param lang la langue pour laquelle il faut supprimer le nom
58 */
removeName(const QString & lang)59 void NamesList::removeName(const QString &lang) {
60 	hash_names.remove(lang);
61 }
62 
63 /**
64 	Supprime tous les noms
65 */
clearNames()66 void NamesList::clearNames() {
67 	hash_names.clear();
68 }
69 
70 /**
71 	@return La liste de toutes les langues disponibles
72 */
langs() const73 QList<QString> NamesList::langs() const {
74 	return(hash_names.keys());
75 }
76 
77 /**
78 	@return true si la liste de noms est vide, false sinon
79 */
isEmpty() const80 bool NamesList::isEmpty() const {
81 	return(hash_names.isEmpty());
82 }
83 
84 /**
85 	@return Le nombre de noms dans la liste
86 */
count() const87 int NamesList::count() const {
88 	return(hash_names.count());
89 }
90 
91 /**
92 	@param lang une langue
93 	@return Le nom dans la langue donnee ou QString() si ce nom n'est pas
94 	defini
95 */
operator [](const QString & lang)96 QString &NamesList::operator[](const QString &lang) {
97 	return(hash_names[lang]);
98 }
99 
100 /**
101 	@param lang une langue
102 	@return Le nom dans la langue donnee ou QString() si ce nom n'est pas
103 	defini
104 */
operator [](const QString & lang) const105 const QString NamesList::operator[](const QString &lang) const {
106 	return(hash_names.value(lang));
107 }
108 
109 
110 
111 /**
112 	Charge la liste de noms depuis un element XML. Cet element est sense etre
113 	le parent d'un element "names", qui contient lui meme les "name".
114 	Les noms precedemment contenus dans la liste ne sont pas effaces mais
115 	peuvent etre ecrases.
116 	@param xml_element L'element XML a analyser
117 	@param xml_options A set of options related to XML parsing.
118 	@see getXmlOptions()
119 */
fromXml(const QDomElement & xml_element,const QHash<QString,QString> & xml_options)120 void NamesList::fromXml(const QDomElement &xml_element, const QHash<QString, QString> &xml_options) {
121 	QHash<QString, QString> xml_opt = getXmlOptions(xml_options);
122 	// parcourt les enfants "names" de l'element XML
123 	for (QDomNode node = xml_element.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
124 		QDomElement names = node.toElement();
125 		if (names.isNull() || names.tagName() != xml_opt["ParentTagName"]) continue;
126 		// parcourt les petits-enfants "name"
127 		for (QDomNode n = names.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
128 			QDomElement name = n.toElement();
129 			if (name.isNull() || name.tagName() != xml_opt["TagName"]) continue;
130 			addName(name.attribute(xml_opt["LanguageAttribute"]), name.text());
131 		}
132 	}
133 }
134 
135 /**
136 	Exporte la liste des noms vers un element XML. Veillez a verifier que la
137 	liste de noms n'est pas vide avant de l'exporter.
138 	@param xml_document Le document XML dans lequel l'element XML sera insere
139 	@param xml_options A set of options related to XML parsing.
140 	@return L'element XML correspondant a la section "names"
141 	@see count()
142 */
toXml(QDomDocument & xml_document,const QHash<QString,QString> & xml_options) const143 QDomElement NamesList::toXml(QDomDocument &xml_document, const QHash<QString, QString> &xml_options) const {
144 	QHash<QString, QString> xml_opt = getXmlOptions(xml_options);
145 	QDomElement names_elmt = xml_document.createElement(xml_opt["ParentTagName"]);
146 	QHashIterator<QString, QString> names_iterator(hash_names);
147 	while (names_iterator.hasNext()) {
148 		names_iterator.next();
149 		QDomElement name_elmt = xml_document.createElement(xml_opt["TagName"]);
150 		name_elmt.setAttribute(xml_opt["LanguageAttribute"], names_iterator.key());
151 		name_elmt.appendChild(xml_document.createTextNode(names_iterator.value()));
152 		names_elmt.appendChild(name_elmt);
153 	}
154 	return(names_elmt);
155 }
156 
157 /**
158 	@param xml_options A set of options related to XML parsing. Available keys:
159 		* ParentTagName (falls back to "names")
160 		* TagName (falls back to "name")
161 		* LanguageAttribute (falls back to "lang")
162 	@return the same set, with at least all the known options
163 */
getXmlOptions(const QHash<QString,QString> & xml_options) const164 QHash<QString, QString> NamesList::getXmlOptions(const QHash<QString, QString> &xml_options) const {
165 	QHash<QString, QString> new_xml_options = xml_options;
166 	if (!xml_options.contains("ParentTagName")) {
167 		new_xml_options.insert("ParentTagName", "names");
168 	}
169 	if (!xml_options.contains("TagName")) {
170 		new_xml_options.insert("TagName", "name");
171 	}
172 	if (!xml_options.contains("LanguageAttribute")) {
173 		new_xml_options.insert("LanguageAttribute", "lang");
174 	}
175 	return new_xml_options;
176 }
177 
178 /**
179 	@param nl une autre liste de noms
180 	@return true si les listes de noms sont differentes, false sinon
181 */
operator !=(const NamesList & nl) const182 bool NamesList::operator!=(const NamesList &nl) const {
183 	return(hash_names != nl.hash_names);
184 }
185 
186 /**
187 	@param nl une autre liste de noms
188 	@return true si les listes de noms sont identiques, false sinon
189 */
operator ==(const NamesList & nl) const190 bool NamesList::operator==(const NamesList &nl) const {
191 	return(hash_names == nl.hash_names);
192 }
193 
194 /**
195 	Return the adequate name regarding the current system locale.
196 	By order of preference, this function chooses:
197 		- the name in the system language
198 		- the English name
199 		- the provided fallback name if non-empty
200 		- the first language encountered in the list
201 		- an empty string
202 	@param fallback_name name to be returned when no adequate name has been found
203 	@return The adequate name regarding the current system locale.
204 */
name(const QString & fallback_name) const205 QString NamesList::name(const QString &fallback_name) const {
206 	QString system_language = QETApp::langFromSetting();
207 	QString returned_name;
208 	if (!hash_names[system_language].isEmpty()) {
209 		returned_name = hash_names[system_language];
210 	} else if (!hash_names["en"].isEmpty()) {
211 		returned_name = hash_names["en"];
212 	} else if (!fallback_name.isEmpty()) {
213 		returned_name = fallback_name;
214 	} else if (hash_names.count()) {
215 		returned_name = hash_names.value(hash_names.keys().first());
216 	}
217 	return(returned_name);
218 }
219