[qet] qet/qet: [5687] NameList widget : add a combo box for easily paste texts, like the variables for title block.

[ Thread Index | Date Index | More lists.tuxfamily.org/qet Archives ]


Revision: 5687
Author:   blacksun
Date:     2019-01-02 17:56:46 +0100 (Wed, 02 Jan 2019)
Log Message:
-----------
NameList widget : add a combo box for easily paste texts, like the variables for title block.

Modified Paths:
--------------
    trunk/qelectrotech.pro
    trunk/sources/editor/elementscene.cpp
    trunk/sources/editor/elementscene.h
    trunk/sources/elementscategoryeditor.cpp
    trunk/sources/elementscategoryeditor.h
    trunk/sources/newelementwizard.cpp
    trunk/sources/newelementwizard.h
    trunk/sources/titleblock/templatecellwidget.cpp

Added Paths:
-----------
    trunk/sources/NameList/
    trunk/sources/NameList/nameslist.cpp
    trunk/sources/NameList/nameslist.h
    trunk/sources/NameList/ui/
    trunk/sources/NameList/ui/namelistdialog.cpp
    trunk/sources/NameList/ui/namelistdialog.h
    trunk/sources/NameList/ui/namelistdialog.ui
    trunk/sources/NameList/ui/namelistwidget.cpp
    trunk/sources/NameList/ui/namelistwidget.h
    trunk/sources/NameList/ui/namelistwidget.ui
    trunk/sources/qetinformation.cpp
    trunk/sources/qetinformation.h

Removed Paths:
-------------
    trunk/sources/nameslist.cpp
    trunk/sources/nameslist.h
    trunk/sources/nameslistwidget.cpp
    trunk/sources/nameslistwidget.h

Modified: trunk/qelectrotech.pro
===================================================================
--- trunk/qelectrotech.pro	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/qelectrotech.pro	2019-01-02 16:56:46 UTC (rev 5687)
@@ -94,7 +94,9 @@
                sources/autoNum/ui \
                sources/ui/configpage \
 			   sources/SearchAndReplace \
-			   sources/SearchAndReplace/ui
+			   sources/SearchAndReplace/ui \
+			   sources/NameList \
+			   sources/NameList/ui
 
 
 # Fichiers sources
@@ -117,7 +119,9 @@
            $$files(sources/autoNum/ui/*.h) \
            $$files(sources/ui/configpage/*.h) \
            $$files(sources/SearchAndReplace/*.h) \
-		   $$files(sources/SearchAndReplace/ui/*.h)
+		   $$files(sources/SearchAndReplace/ui/*.h) \
+		   $$files(sources/NameList/*.h) \
+		   $$files(sources/NameList/ui/*.h)
 
 SOURCES += $$files(sources/*.cpp) \
            $$files(sources/editor/*.cpp) \
@@ -139,7 +143,9 @@
            $$files(sources/autoNum/ui/*.cpp) \
            $$files(sources/ui/configpage/*.cpp) \
 		   $$files(sources/SearchAndReplace/*.cpp) \
-		   $$files(sources/SearchAndReplace/ui/*.cpp)
+		   $$files(sources/SearchAndReplace/ui/*.cpp) \
+		   $$files(sources/NameList/*.cpp) \
+		   $$files(sources/NameList/ui/*.cpp)
 
 # Liste des fichiers qui seront incorpores au binaire en tant que ressources Qt
 RESOURCES += qelectrotech.qrc
@@ -160,7 +166,8 @@
          $$files(sources/ElementsCollection/ui/*.ui) \
          $$files(sources/autoNum/ui/*.ui) \
          $$files(sources/ui/configpage/*.ui) \
-		 $$files(sources/SearchAndReplace/ui/*.ui)
+		 $$files(sources/SearchAndReplace/ui/*.ui) \
+         $$files(sources/NameList/ui/*.ui)
 
 UI_SOURCES_DIR = sources/ui/
 UI_HEADERS_DIR = sources/ui/

Added: trunk/sources/NameList/nameslist.cpp
===================================================================
--- trunk/sources/NameList/nameslist.cpp	                        (rev 0)
+++ trunk/sources/NameList/nameslist.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,218 @@
+/*
+	Copyright 2006-2017 The QElectroTech Team
+	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 "nameslist.h"
+#include "qetapp.h"
+
+// make this class usable with QVariant
+int NamesList::MetaTypeId = qRegisterMetaType<NamesList>("NamesList");
+
+/**
+	Constructeur
+*/
+NamesList::NamesList() {
+}
+
+/**
+	Constructeur de copie
+	@param other La NamesList a copier
+*/
+NamesList::NamesList(const NamesList &other) : hash_names(other.hash_names) {	
+}
+
+/**
+	Destructeur
+*/
+NamesList::~NamesList() {
+}
+
+/**
+	Ajoute un nom a la liste
+	@param lang Sigle de deux lettres representant une langue. Si cela n'est
+	pas respecte, l'insertion n'est pas effectuee.
+	@param name Nom lui-meme. Ce ne doit pas etre une chaine de caractere vide.
+	Si cela n'est pas respecte, l'insertion n'est pas effectuee.
+*/
+void NamesList::addName(const QString &lang, const QString &name) {
+	if (lang.length() != 2) return;
+	hash_names.insert(lang, name);
+}
+
+/**
+	Enleve le nom dont une langue donnee
+	@param lang la langue pour laquelle il faut supprimer le nom
+*/
+void NamesList::removeName(const QString &lang) {
+	hash_names.remove(lang);
+}
+
+/**
+	Supprime tous les noms
+*/
+void NamesList::clearNames() {
+	hash_names.clear();
+}
+
+/**
+	@return La liste de toutes les langues disponibles
+*/
+QList<QString> NamesList::langs() const {
+	return(hash_names.keys());
+}
+
+/**
+	@return true si la liste de noms est vide, false sinon
+*/
+bool NamesList::isEmpty() const {
+	return(hash_names.isEmpty());
+}
+
+/**
+	@return Le nombre de noms dans la liste
+*/
+int NamesList::count() const {
+	return(hash_names.count());
+}
+
+/**
+	@param lang une langue
+	@return Le nom dans la langue donnee ou QString() si ce nom n'est pas
+	defini
+*/
+QString &NamesList::operator[](const QString &lang) {
+	return(hash_names[lang]);
+}
+
+/**
+	@param lang une langue
+	@return Le nom dans la langue donnee ou QString() si ce nom n'est pas
+	defini
+*/
+const QString NamesList::operator[](const QString &lang) const {
+	return(hash_names.value(lang));
+}
+
+
+
+/**
+	Charge la liste de noms depuis un element XML. Cet element est sense etre
+	le parent d'un element "names", qui contient lui meme les "name".
+	Les noms precedemment contenus dans la liste ne sont pas effaces mais
+	peuvent etre ecrases.
+	@param xml_element L'element XML a analyser
+	@param xml_options A set of options related to XML parsing.
+	@see getXmlOptions()
+*/
+void NamesList::fromXml(const QDomElement &xml_element, const QHash<QString, QString> &xml_options) {
+	QHash<QString, QString> xml_opt = getXmlOptions(xml_options);
+	// parcourt les enfants "names" de l'element XML
+	for (QDomNode node = xml_element.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
+		QDomElement names = node.toElement();
+		if (names.isNull() || names.tagName() != xml_opt["ParentTagName"]) continue;
+		// parcourt les petits-enfants "name"
+		for (QDomNode n = names.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
+			QDomElement name = n.toElement();
+			if (name.isNull() || name.tagName() != xml_opt["TagName"]) continue;
+			addName(name.attribute(xml_opt["LanguageAttribute"]), name.text());
+		}
+	}
+}
+
+/**
+	Exporte la liste des noms vers un element XML. Veillez a verifier que la
+	liste de noms n'est pas vide avant de l'exporter.
+	@param xml_document Le document XML dans lequel l'element XML sera insere
+	@param xml_options A set of options related to XML parsing.
+	@return L'element XML correspondant a la section "names"
+	@see count()
+*/
+QDomElement NamesList::toXml(QDomDocument &xml_document, const QHash<QString, QString> &xml_options) const {
+	QHash<QString, QString> xml_opt = getXmlOptions(xml_options);
+	QDomElement names_elmt = xml_document.createElement(xml_opt["ParentTagName"]);
+	QHashIterator<QString, QString> names_iterator(hash_names);
+	while (names_iterator.hasNext()) {
+		names_iterator.next();
+		QDomElement name_elmt = xml_document.createElement(xml_opt["TagName"]);
+		name_elmt.setAttribute(xml_opt["LanguageAttribute"], names_iterator.key());
+		name_elmt.appendChild(xml_document.createTextNode(names_iterator.value()));
+		names_elmt.appendChild(name_elmt);
+	}
+	return(names_elmt);
+}
+
+/**
+	@param xml_options A set of options related to XML parsing. Available keys:
+		* ParentTagName (falls back to "names")
+		* TagName (falls back to "name")
+		* LanguageAttribute (falls back to "lang")
+	@return the same set, with at least all the known options
+*/
+QHash<QString, QString> NamesList::getXmlOptions(const QHash<QString, QString> &xml_options) const {
+	QHash<QString, QString> new_xml_options = xml_options;
+	if (!xml_options.contains("ParentTagName")) {
+		new_xml_options.insert("ParentTagName", "names");
+	}
+	if (!xml_options.contains("TagName")) {
+		new_xml_options.insert("TagName", "name");
+	}
+	if (!xml_options.contains("LanguageAttribute")) {
+		new_xml_options.insert("LanguageAttribute", "lang");
+	}
+	return new_xml_options;
+}
+
+/**
+	@param nl une autre liste de noms
+	@return true si les listes de noms sont differentes, false sinon
+*/
+bool NamesList::operator!=(const NamesList &nl) const {
+	return(hash_names != nl.hash_names);
+}
+
+/**
+	@param nl une autre liste de noms
+	@return true si les listes de noms sont identiques, false sinon
+*/
+bool NamesList::operator==(const NamesList &nl) const {
+	return(hash_names == nl.hash_names);
+}
+
+/**
+	Return the adequate name regarding the current system locale.
+	By order of preference, this function chooses:
+		- the name in the system language
+		- the English name
+		- the provided fallback name if non-empty
+		- the first language encountered in the list
+		- an empty string
+	@param fallback_name name to be returned when no adequate name has been found
+	@return The adequate name regarding the current system locale.
+*/
+QString NamesList::name(const QString &fallback_name) const {
+	QString system_language = QETApp::langFromSetting();
+	QString returned_name;
+	if (!hash_names[system_language].isEmpty()) {
+		returned_name = hash_names[system_language];
+	} else if (!hash_names["en"].isEmpty()) {
+		returned_name = hash_names["en"];
+	} else if (!fallback_name.isEmpty()) {
+		returned_name = fallback_name;
+	} else if (hash_names.count()) {
+		returned_name = hash_names.value(hash_names.keys().first());
+	}
+	return(returned_name);
+}

Added: trunk/sources/NameList/nameslist.h
===================================================================
--- trunk/sources/NameList/nameslist.h	                        (rev 0)
+++ trunk/sources/NameList/nameslist.h	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,66 @@
+/*
+	Copyright 2006-2017 The QElectroTech Team
+	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 NAMES_LIST_H
+#define NAMES_LIST_H
+#include <QtXml>
+/**
+	Cette classe represente une liste de noms, utilisee
+	par les elements et categories pour embarquer un meme nom en plusieurs
+	langues.
+	Les langues sont representees par deux lettres (typiquement : les deux
+	premieres de la locale du systeme) ; exemples : en pour l'anglais, fr
+	pour le francais.
+*/
+class NamesList {
+	// constructors, destructor
+	public:
+	NamesList();
+	NamesList(const NamesList &);
+	virtual ~NamesList();
+	
+	// attributes
+	private:
+	QHash<QString, QString> hash_names;
+	
+	public:
+	static int MetaTypeId;
+	
+	// methods
+	public:
+	// methods relatives a la gestion de la liste
+	void addName(const QString &, const QString &);
+	void removeName(const QString &);
+	void clearNames();
+	QList<QString> langs() const;
+	bool isEmpty() const;
+	int count() const;
+	QString &operator[](const QString &);
+	const QString operator[](const QString &) const;
+	bool operator!=(const NamesList &) const;
+	bool operator==(const NamesList &) const;
+	QString name(const QString & = QString()) const;
+	
+	// methods relatives a XML
+	void fromXml(const QDomElement &, const QHash<QString, QString> & = QHash<QString, QString>());
+	QDomElement toXml(QDomDocument &, const QHash<QString, QString> & = QHash<QString, QString>()) const;
+	
+	protected:
+	QHash<QString, QString> getXmlOptions(const QHash<QString, QString> & = QHash<QString, QString>()) const;
+};
+Q_DECLARE_METATYPE(NamesList);
+#endif

Added: trunk/sources/NameList/ui/namelistdialog.cpp
===================================================================
--- trunk/sources/NameList/ui/namelistdialog.cpp	                        (rev 0)
+++ trunk/sources/NameList/ui/namelistdialog.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,67 @@
+/*
+	Copyright 2006-2018 The QElectroTech Team
+	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 "namelistdialog.h"
+#include "ui_namelistdialog.h"
+#include "namelistwidget.h"
+
+#include <QPushButton>
+#include <QMessageBox>
+
+NameListDialog::NameListDialog(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::NameListDialog)
+{
+	ui->setupUi(this);
+
+	m_namelist_widget = new NameListWidget(this);
+	ui->m_main_layout->insertWidget(1, m_namelist_widget);
+#ifdef Q_OS_MAC
+	this->setWindowFlags(Qt::Sheet);
+#endif
+}
+
+NameListDialog::~NameListDialog() {
+	delete ui;
+}
+
+void NameListDialog::setInformationText(const QString &text) {
+	ui->m_top_label->setText(text);
+}
+
+/**
+ * @brief NameListDialog::namelistWidget
+ * @return the name list widget used by this dialog.
+ * The ownership of the namelistwidget stay to this dialog
+ */
+NameListWidget *NameListDialog::namelistWidget() const {
+	return m_namelist_widget;
+}
+
+void NameListDialog::setHelpText(const QString &text)
+{
+	m_help_text = text;
+	if (!m_help_text.isEmpty())
+	{
+		QPushButton *button = ui->m_button_box->addButton(QDialogButtonBox::Help);
+		connect(button, &QPushButton::clicked, this, &NameListDialog::showHelpDialog);
+	}
+}
+
+void NameListDialog::showHelpDialog() {
+	QMessageBox::information(this, tr("Variables de cartouche"), m_help_text);
+}

Added: trunk/sources/NameList/ui/namelistdialog.h
===================================================================
--- trunk/sources/NameList/ui/namelistdialog.h	                        (rev 0)
+++ trunk/sources/NameList/ui/namelistdialog.h	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,52 @@
+/*
+	Copyright 2006-2018 The QElectroTech Team
+	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 NAMELISTDIALOG_H
+#define NAMELISTDIALOG_H
+
+#include <QDialog>
+
+class NameListWidget;
+
+namespace Ui {
+	class NameListDialog;
+}
+
+/**
+ * @brief The NameListDialog class
+ * Provide a dialog for let user define localized string;
+ */
+class NameListDialog : public QDialog
+{
+	Q_OBJECT
+	
+	public:
+		explicit NameListDialog(QWidget *parent = nullptr);
+		~NameListDialog();
+	
+		void setInformationText(const QString &text);
+		NameListWidget *namelistWidget() const;
+		void setHelpText(const QString &text);
+		void showHelpDialog();
+	
+	private:
+		Ui::NameListDialog *ui;
+		NameListWidget *m_namelist_widget = nullptr;
+		QString m_help_text;
+};
+
+#endif // NAMELISTDIALOG_H

Added: trunk/sources/NameList/ui/namelistdialog.ui
===================================================================
--- trunk/sources/NameList/ui/namelistdialog.ui	                        (rev 0)
+++ trunk/sources/NameList/ui/namelistdialog.ui	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NameListDialog</class>
+ <widget class="QDialog" name="NameListDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>507</width>
+    <height>370</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="m_main_layout">
+   <item>
+    <widget class="QLabel" name="m_top_label">
+     <property name="text">
+      <string/>
+     </property>
+     <property name="textFormat">
+      <enum>Qt::RichText</enum>
+     </property>
+     <property name="wordWrap">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="m_button_box">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>m_button_box</sender>
+   <signal>accepted()</signal>
+   <receiver>NameListDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>m_button_box</sender>
+   <signal>rejected()</signal>
+   <receiver>NameListDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

Added: trunk/sources/NameList/ui/namelistwidget.cpp
===================================================================
--- trunk/sources/NameList/ui/namelistwidget.cpp	                        (rev 0)
+++ trunk/sources/NameList/ui/namelistwidget.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,168 @@
+/*
+	Copyright 2006-2018 The QElectroTech Team
+	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 "namelistwidget.h"
+#include "ui_namelistwidget.h"
+
+#include <QPushButton>
+#include <QClipboard>
+
+NameListWidget::NameListWidget(QWidget *parent) :
+	QWidget(parent),
+	ui(new Ui::NameListWidget)
+{
+	ui->setupUi(this);
+	ui->m_clipboard_cb->setHidden(true);
+	connect(ui->m_add_line_pb, &QPushButton::clicked, this, &NameListWidget::addLine);
+}
+
+NameListWidget::~NameListWidget()
+{
+	delete ui;
+}
+
+/**
+ * @brief NameListWidget::addLine
+ * Add a new line to the name list widget
+ */
+void NameListWidget::addLine()
+{
+	clean();
+	if (m_read_only) {
+		return;
+	}
+	QTreeWidgetItem *qtwi = new QTreeWidgetItem();
+	qtwi->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+	ui->m_tree->addTopLevelItem(qtwi);
+ 	ui->m_tree->setCurrentItem(qtwi);
+	ui->m_tree->editItem(qtwi);
+}
+
+/**
+ * @brief NameListWidget::setNames
+ * Set the current names of this dialog from @name_list
+ * @param name_list
+ */
+void NameListWidget::setNames(const NamesList &name_list)
+{
+	for (QString lang : name_list.langs())
+	{
+		QString value = name_list[lang];
+		QStringList values;
+		values << lang << value;
+		QTreeWidgetItem *qtwi = new QTreeWidgetItem(values);
+		if (!m_read_only) {
+			qtwi->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+		}
+		ui->m_tree->addTopLevelItem(qtwi);
+		ui->m_tree->sortItems(0, Qt::AscendingOrder);
+	}
+}
+
+/**
+ * @brief NameListWidget::names
+ * @return the current name list edited by this dialog
+ */
+NamesList NameListWidget::names() const
+{
+	NamesList nl_;
+	
+	int names_count = ui->m_tree->topLevelItemCount();
+	for (int i = 0 ; i < names_count ; ++ i)
+	{
+		QString lang  = ui->m_tree->topLevelItem(i)->text(0);
+		QString value = ui->m_tree->topLevelItem(i)->text(1);
+		if (lang != "" && value != "") {
+			nl_.addName(lang, value);
+		}
+	}
+	
+	return nl_;
+}
+
+/**
+ * @brief NameListWidget::setReadOnly
+ * Set this dialog to read only or not.
+ * @param ro
+ */
+void NameListWidget::setReadOnly(bool ro)
+{
+	m_read_only = ro;
+	
+	int names_count = ui->m_tree->topLevelItemCount() - 1;
+	for (int i = names_count ; i >= 0 ; -- i)
+	{
+		Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+		if (!m_read_only) {
+			flags |= Qt::ItemIsEditable;
+		}
+		ui->m_tree->topLevelItem(i)->setFlags(flags);
+	}
+	ui->m_add_line_pb->setEnabled(!ro);
+}
+
+/**
+ * @brief NameListWidget::isEmpty
+ * @return true if empty.
+ * An empty dialog, is a dialog without any edited lang. 
+ */
+bool NameListWidget::isEmpty() const {
+	return names().isEmpty();
+}
+
+void NameListWidget::setClipboardValue(QHash<QString, QString> value)
+{
+	if (value.isEmpty()) {
+		ui->m_clipboard_cb->setHidden(true);
+	}
+	else
+	{
+		ui->m_clipboard_cb->setVisible(true);
+		
+		QStringList list = value.keys();
+		list.sort();
+		for (QString key : list) {
+			ui->m_clipboard_cb->addItem(key, value.value(key));
+		}
+	}
+}
+
+/**
+ * @brief NameListWidget::clean
+ * Clean the lists of names by removing the emtpy lines
+ */
+void NameListWidget::clean()
+{
+	int names_count = ui->m_tree->topLevelItemCount() - 1;
+	for (int i = names_count ; i >= 0 ; -- i)
+	{
+		if (ui->m_tree->topLevelItem(i)->text(0).isEmpty() &&
+			ui->m_tree->topLevelItem(i)->text(1).isEmpty())
+		{
+			ui->m_tree->takeTopLevelItem(i);
+		}
+	}
+}
+
+void NameListWidget::on_m_clipboard_cb_activated(int index)
+{
+	Q_UNUSED(index);
+	
+	QClipboard *clipboard = QApplication::clipboard();
+	clipboard->setText(ui->m_clipboard_cb->currentData().toString());
+	ui->m_clipboard_cb->setCurrentIndex(0);
+}

Added: trunk/sources/NameList/ui/namelistwidget.h
===================================================================
--- trunk/sources/NameList/ui/namelistwidget.h	                        (rev 0)
+++ trunk/sources/NameList/ui/namelistwidget.h	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,58 @@
+/*
+	Copyright 2006-2018 The QElectroTech Team
+	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 NAMELISTWIDGET_H
+#define NAMELISTWIDGET_H
+
+#include "nameslist.h"
+#include <QWidget>
+
+namespace Ui {
+	class NameListWidget;
+}
+
+/**
+ * @brief The NameListWidget class
+ * Provide a widget for let user define localized string;
+ */
+class NameListWidget : public QWidget
+{
+	Q_OBJECT
+	
+	public:
+		explicit NameListWidget(QWidget *parent = nullptr);
+		~NameListWidget();
+		
+		void addLine();
+		void setNames (const NamesList &name_list);
+		NamesList names() const;
+		void setReadOnly(bool ro);
+		bool isEmpty() const;
+		void setClipboardValue (QHash <QString, QString> value);
+	
+	private slots:
+		void on_m_clipboard_cb_activated(int index);
+		
+	private:
+		void clean();
+	
+	private:
+		Ui::NameListWidget *ui;
+		bool m_read_only = false;	
+};
+
+#endif // NAMELISTWIDGET_H

Added: trunk/sources/NameList/ui/namelistwidget.ui
===================================================================
--- trunk/sources/NameList/ui/namelistwidget.ui	                        (rev 0)
+++ trunk/sources/NameList/ui/namelistwidget.ui	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NameListWidget</class>
+ <widget class="QWidget" name="NameListWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTreeWidget" name="m_tree">
+     <column>
+      <property name="text">
+       <string>Langue</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Texte</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QPushButton" name="m_add_line_pb">
+       <property name="text">
+        <string>Ajouter une ligne</string>
+       </property>
+       <property name="icon">
+        <iconset resource="../../../qelectrotech.qrc">
+         <normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QComboBox" name="m_clipboard_cb">
+       <item>
+        <property name="text">
+         <string>Copier dans le presse papier</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../../../qelectrotech.qrc">
+          <normaloff>:/ico/16x16/edit-paste.png</normaloff>:/ico/16x16/edit-paste.png</iconset>
+        </property>
+       </item>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../../../qelectrotech.qrc"/>
+ </resources>
+ <connections/>
+</ui>

Modified: trunk/sources/editor/elementscene.cpp
===================================================================
--- trunk/sources/editor/elementscene.cpp	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/editor/elementscene.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -1,5 +1,5 @@
 /*
-	Copyright 2006-2017 The QElectroTech Team
+	Copyright 2006-2018 The QElectroTech Team
 	This file is part of QElectroTech.
 	
 	QElectroTech is free software: you can redistribute it and/or modify
@@ -28,12 +28,13 @@
 #include "partarc.h"
 #include "editorcommands.h"
 #include "elementcontent.h"
-#include "nameslist.h"
 #include "ui/elementpropertieseditorwidget.h"
 #include "eseventinterface.h"
 #include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
 #include "partdynamictextfield.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "namelistdialog.h"
+#include "namelistwidget.h"
 
 #include <algorithm>
 #include <QKeyEvent>
@@ -725,44 +726,31 @@
 }
 
 /**
-	Lance un dialogue pour editer les noms de cet element
-*/
-void ElementScene::slot_editNames() {
+ * @brief ElementScene::slot_editNames
+ * Launch a dialog for edit the names of the edited element
+ */
+void ElementScene::slot_editNames()
+{
 	bool is_read_only = m_element_editor && m_element_editor -> isReadOnly();
 	
-	// cree un dialogue
-	QDialog dialog(m_element_editor);
-#ifdef Q_OS_MAC
-	dialog.setWindowFlags(Qt::Sheet);
-#endif
-	dialog.setModal(true);
-	dialog.setMinimumSize(400, 330);
-	dialog.setWindowTitle(tr("Éditer les noms", "window title"));
-	QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog);
+	NameListDialog dialog_(m_element_editor);
 	
-	// ajoute un champ explicatif au dialogue
-	QLabel *information_label = new QLabel(tr("Vous pouvez spécifier le nom de l'élément dans plusieurs langues."));
-	information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
-	information_label -> setWordWrap(true);
-	dialog_layout -> addWidget(information_label);
+	dialog_.setModal(true);
+	dialog_.setMinimumSize(400, 330);
+	dialog_.setWindowTitle(tr("Éditer les noms", "window title"));
 	
-	// ajoute un NamesListWidget au dialogue
-	NamesListWidget *names_widget = new NamesListWidget();
-	names_widget -> setNames(m_names_list);
-	names_widget -> setReadOnly(is_read_only);
-	dialog_layout -> addWidget(names_widget);
+	dialog_.setInformationText(tr("Vous pouvez spécifier le nom de l'élément dans plusieurs langues."));
 	
-	// ajoute deux boutons au dialogue
-	QDialogButtonBox *dialog_buttons = new QDialogButtonBox(is_read_only ? QDialogButtonBox::Ok : QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
-	dialog_layout -> addWidget(dialog_buttons);
-	connect(dialog_buttons, SIGNAL(accepted()),     names_widget, SLOT(check()));
-	connect(names_widget,   SIGNAL(inputChecked()), &dialog,      SLOT(accept()));
-	connect(dialog_buttons, SIGNAL(rejected()),     &dialog,      SLOT(reject()));
+	NameListWidget *nlw_ = dialog_.namelistWidget();
+	nlw_->setNames(m_names_list);
+	nlw_->setReadOnly(is_read_only);
 	
-	// lance le dialogue
-	if (dialog.exec() == QDialog::Accepted && !is_read_only) {
-		NamesList new_names(names_widget -> names());
-		if (new_names != m_names_list) undoStack().push(new ChangeNamesCommand(this, m_names_list, new_names));
+	if (dialog_.exec() == QDialog::Accepted && !is_read_only && !nlw_->isEmpty())
+	{
+		NamesList new_names = nlw_->names();
+		if (new_names != m_names_list) {
+			undoStack().push(new ChangeNamesCommand(this, m_names_list, new_names));
+		}
 	}
 }
 

Modified: trunk/sources/editor/elementscene.h
===================================================================
--- trunk/sources/editor/elementscene.h	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/editor/elementscene.h	2019-01-02 16:56:46 UTC (rev 5687)
@@ -19,10 +19,10 @@
 #define ELEMENT_SCENE_H
 #include <QtWidgets>
 #include <QtXml>
-#include "nameslistwidget.h"
 #include "qgimanager.h"
 #include "elementcontent.h"
 #include "diagramcontext.h"
+#include "nameslist.h"
 
 class CustomElementPart;
 class ElementEditionCommand;

Modified: trunk/sources/elementscategoryeditor.cpp
===================================================================
--- trunk/sources/elementscategoryeditor.cpp	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/elementscategoryeditor.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -16,12 +16,17 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "elementscategoryeditor.h"
-#include "nameslistwidget.h"
 #include "qet.h"
 #include "qfilenameedit.h"
 #include "qetmessagebox.h"
 #include "elementcollectionhandler.h"
+#include "namelistwidget.h"
 
+#include <QDialogButtonBox>
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QHBoxLayout>
+
 /**
  * @brief ElementsCategoryEditor::ElementsCategoryEditor
  * Constructor
@@ -102,7 +107,7 @@
 	QVBoxLayout *editor_layout = new QVBoxLayout();
 	setLayout(editor_layout);
 	
-	m_names_list = new NamesListWidget();
+	m_names_list = new NameListWidget(this);
 	m_file_name = new QLabel(tr("Nom interne : "));
 	m_file_line_edit = new QFileNameEdit();
 	
@@ -130,7 +135,7 @@
 	}
 	
 		//there must be at least one name
-	if (!m_names_list -> checkOneName()) {
+	if (m_names_list->isEmpty()) {
 		return;
 	}
 	
@@ -181,7 +186,7 @@
 	}
 	
 		//There must be at least one name
-	if (!m_names_list -> checkOneName()) {
+	if (m_names_list->isEmpty()) {
 		return;
 	}
 	

Modified: trunk/sources/elementscategoryeditor.h
===================================================================
--- trunk/sources/elementscategoryeditor.h	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/elementscategoryeditor.h	2019-01-02 16:56:46 UTC (rev 5687)
@@ -21,7 +21,7 @@
 #include <QDialog>
 #include "elementslocation.h"
 
-class NamesListWidget;
+class NameListWidget;
 class QFileNameEdit;
 class QDialogButtonBox;
 class QLabel;
@@ -45,7 +45,7 @@
 	
 	private:
 		QDialogButtonBox *m_buttons;
-		NamesListWidget *m_names_list;
+		NameListWidget *m_names_list;
 		QLabel *m_file_name;
 		QFileNameEdit *m_file_line_edit;
 		bool m_edit_mode;

Deleted: trunk/sources/nameslist.cpp
===================================================================
--- trunk/sources/nameslist.cpp	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/nameslist.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -1,218 +0,0 @@
-/*
-	Copyright 2006-2017 The QElectroTech Team
-	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 "nameslist.h"
-#include "qetapp.h"
-
-// make this class usable with QVariant
-int NamesList::MetaTypeId = qRegisterMetaType<NamesList>("NamesList");
-
-/**
-	Constructeur
-*/
-NamesList::NamesList() {
-}
-
-/**
-	Constructeur de copie
-	@param other La NamesList a copier
-*/
-NamesList::NamesList(const NamesList &other) : hash_names(other.hash_names) {	
-}
-
-/**
-	Destructeur
-*/
-NamesList::~NamesList() {
-}
-
-/**
-	Ajoute un nom a la liste
-	@param lang Sigle de deux lettres representant une langue. Si cela n'est
-	pas respecte, l'insertion n'est pas effectuee.
-	@param name Nom lui-meme. Ce ne doit pas etre une chaine de caractere vide.
-	Si cela n'est pas respecte, l'insertion n'est pas effectuee.
-*/
-void NamesList::addName(const QString &lang, const QString &name) {
-	if (lang.length() != 2) return;
-	hash_names.insert(lang, name);
-}
-
-/**
-	Enleve le nom dont une langue donnee
-	@param lang la langue pour laquelle il faut supprimer le nom
-*/
-void NamesList::removeName(const QString &lang) {
-	hash_names.remove(lang);
-}
-
-/**
-	Supprime tous les noms
-*/
-void NamesList::clearNames() {
-	hash_names.clear();
-}
-
-/**
-	@return La liste de toutes les langues disponibles
-*/
-QList<QString> NamesList::langs() const {
-	return(hash_names.keys());
-}
-
-/**
-	@return true si la liste de noms est vide, false sinon
-*/
-bool NamesList::isEmpty() const {
-	return(hash_names.isEmpty());
-}
-
-/**
-	@return Le nombre de noms dans la liste
-*/
-int NamesList::count() const {
-	return(hash_names.count());
-}
-
-/**
-	@param lang une langue
-	@return Le nom dans la langue donnee ou QString() si ce nom n'est pas
-	defini
-*/
-QString &NamesList::operator[](const QString &lang) {
-	return(hash_names[lang]);
-}
-
-/**
-	@param lang une langue
-	@return Le nom dans la langue donnee ou QString() si ce nom n'est pas
-	defini
-*/
-const QString NamesList::operator[](const QString &lang) const {
-	return(hash_names.value(lang));
-}
-
-
-
-/**
-	Charge la liste de noms depuis un element XML. Cet element est sense etre
-	le parent d'un element "names", qui contient lui meme les "name".
-	Les noms precedemment contenus dans la liste ne sont pas effaces mais
-	peuvent etre ecrases.
-	@param xml_element L'element XML a analyser
-	@param xml_options A set of options related to XML parsing.
-	@see getXmlOptions()
-*/
-void NamesList::fromXml(const QDomElement &xml_element, const QHash<QString, QString> &xml_options) {
-	QHash<QString, QString> xml_opt = getXmlOptions(xml_options);
-	// parcourt les enfants "names" de l'element XML
-	for (QDomNode node = xml_element.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
-		QDomElement names = node.toElement();
-		if (names.isNull() || names.tagName() != xml_opt["ParentTagName"]) continue;
-		// parcourt les petits-enfants "name"
-		for (QDomNode n = names.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
-			QDomElement name = n.toElement();
-			if (name.isNull() || name.tagName() != xml_opt["TagName"]) continue;
-			addName(name.attribute(xml_opt["LanguageAttribute"]), name.text());
-		}
-	}
-}
-
-/**
-	Exporte la liste des noms vers un element XML. Veillez a verifier que la
-	liste de noms n'est pas vide avant de l'exporter.
-	@param xml_document Le document XML dans lequel l'element XML sera insere
-	@param xml_options A set of options related to XML parsing.
-	@return L'element XML correspondant a la section "names"
-	@see count()
-*/
-QDomElement NamesList::toXml(QDomDocument &xml_document, const QHash<QString, QString> &xml_options) const {
-	QHash<QString, QString> xml_opt = getXmlOptions(xml_options);
-	QDomElement names_elmt = xml_document.createElement(xml_opt["ParentTagName"]);
-	QHashIterator<QString, QString> names_iterator(hash_names);
-	while (names_iterator.hasNext()) {
-		names_iterator.next();
-		QDomElement name_elmt = xml_document.createElement(xml_opt["TagName"]);
-		name_elmt.setAttribute(xml_opt["LanguageAttribute"], names_iterator.key());
-		name_elmt.appendChild(xml_document.createTextNode(names_iterator.value()));
-		names_elmt.appendChild(name_elmt);
-	}
-	return(names_elmt);
-}
-
-/**
-	@param xml_options A set of options related to XML parsing. Available keys:
-		* ParentTagName (falls back to "names")
-		* TagName (falls back to "name")
-		* LanguageAttribute (falls back to "lang")
-	@return the same set, with at least all the known options
-*/
-QHash<QString, QString> NamesList::getXmlOptions(const QHash<QString, QString> &xml_options) const {
-	QHash<QString, QString> new_xml_options = xml_options;
-	if (!xml_options.contains("ParentTagName")) {
-		new_xml_options.insert("ParentTagName", "names");
-	}
-	if (!xml_options.contains("TagName")) {
-		new_xml_options.insert("TagName", "name");
-	}
-	if (!xml_options.contains("LanguageAttribute")) {
-		new_xml_options.insert("LanguageAttribute", "lang");
-	}
-	return new_xml_options;
-}
-
-/**
-	@param nl une autre liste de noms
-	@return true si les listes de noms sont differentes, false sinon
-*/
-bool NamesList::operator!=(const NamesList &nl) const {
-	return(hash_names != nl.hash_names);
-}
-
-/**
-	@param nl une autre liste de noms
-	@return true si les listes de noms sont identiques, false sinon
-*/
-bool NamesList::operator==(const NamesList &nl) const {
-	return(hash_names == nl.hash_names);
-}
-
-/**
-	Return the adequate name regarding the current system locale.
-	By order of preference, this function chooses:
-		- the name in the system language
-		- the English name
-		- the provided fallback name if non-empty
-		- the first language encountered in the list
-		- an empty string
-	@param fallback_name name to be returned when no adequate name has been found
-	@return The adequate name regarding the current system locale.
-*/
-QString NamesList::name(const QString &fallback_name) const {
-	QString system_language = QETApp::langFromSetting();
-	QString returned_name;
-	if (!hash_names[system_language].isEmpty()) {
-		returned_name = hash_names[system_language];
-	} else if (!hash_names["en"].isEmpty()) {
-		returned_name = hash_names["en"];
-	} else if (!fallback_name.isEmpty()) {
-		returned_name = fallback_name;
-	} else if (hash_names.count()) {
-		returned_name = hash_names.value(hash_names.keys().first());
-	}
-	return(returned_name);
-}

Deleted: trunk/sources/nameslist.h
===================================================================
--- trunk/sources/nameslist.h	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/nameslist.h	2019-01-02 16:56:46 UTC (rev 5687)
@@ -1,66 +0,0 @@
-/*
-	Copyright 2006-2017 The QElectroTech Team
-	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 NAMES_LIST_H
-#define NAMES_LIST_H
-#include <QtXml>
-/**
-	Cette classe represente une liste de noms, utilisee
-	par les elements et categories pour embarquer un meme nom en plusieurs
-	langues.
-	Les langues sont representees par deux lettres (typiquement : les deux
-	premieres de la locale du systeme) ; exemples : en pour l'anglais, fr
-	pour le francais.
-*/
-class NamesList {
-	// constructors, destructor
-	public:
-	NamesList();
-	NamesList(const NamesList &);
-	virtual ~NamesList();
-	
-	// attributes
-	private:
-	QHash<QString, QString> hash_names;
-	
-	public:
-	static int MetaTypeId;
-	
-	// methods
-	public:
-	// methods relatives a la gestion de la liste
-	void addName(const QString &, const QString &);
-	void removeName(const QString &);
-	void clearNames();
-	QList<QString> langs() const;
-	bool isEmpty() const;
-	int count() const;
-	QString &operator[](const QString &);
-	const QString operator[](const QString &) const;
-	bool operator!=(const NamesList &) const;
-	bool operator==(const NamesList &) const;
-	QString name(const QString & = QString()) const;
-	
-	// methods relatives a XML
-	void fromXml(const QDomElement &, const QHash<QString, QString> & = QHash<QString, QString>());
-	QDomElement toXml(QDomDocument &, const QHash<QString, QString> & = QHash<QString, QString>()) const;
-	
-	protected:
-	QHash<QString, QString> getXmlOptions(const QHash<QString, QString> & = QHash<QString, QString>()) const;
-};
-Q_DECLARE_METATYPE(NamesList);
-#endif

Deleted: trunk/sources/nameslistwidget.cpp
===================================================================
--- trunk/sources/nameslistwidget.cpp	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/nameslistwidget.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -1,173 +0,0 @@
-/*
-	Copyright 2006-2017 The QElectroTech Team
-	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 "nameslistwidget.h"
-#include "qetmessagebox.h"
-#include "qeticons.h"
-
-/**
-	Constructeur
-	@param parent QWidget parent de la liste de noms
-*/
-NamesListWidget::NamesListWidget(QWidget *parent) : QWidget(parent), read_only(false) {
-	QVBoxLayout *names_list_layout = new QVBoxLayout();
-	setLayout(names_list_layout);
-	
-	tree_names = new QTreeWidget();
-	tree_names -> setRootIsDecorated(false);
-	tree_names -> setColumnCount(2);
-	QStringList headers;
-	headers << tr("Langue") << tr("Texte");
-	tree_names -> setHeaderLabels(headers);
-	tree_names -> setWhatsThis(
-		tr(
-			"Cette liste vous permet de saisir un court texte de façon à ce"
-			" qu'il soit traduisible dans d'autres langues. Pour ce faire, elle"
-			" associe des codes ISO 639-1 de langues (ex. : \"fr\" pour"
-			" français) aux traductions du texte en question dans ces"
-			" mêmes langues.",
-			"\"What's this\" tip"
-		)
-	);
-	
-	button_add_line = new QPushButton(QET::Icons::Add, tr("Ajouter une ligne"));
-	button_add_line -> setWhatsThis(
-		tr(
-			"Ce bouton permet d'ajouter une association langue / traduction "
-			"dans la liste ci-dessus.",
-			"\"What's this\" tip"
-		)
-	);
-	connect(button_add_line, SIGNAL(released()), this, SLOT(addLine()));
-	
-	names_list_layout -> addWidget(tree_names);
-	names_list_layout -> addWidget(button_add_line);
-}
-
-/**
-	Destructeur
-*/
-NamesListWidget::~NamesListWidget() {
-}
-
-/**
-	Ajoute une ligne a l'editeur
-*/
-void NamesListWidget::addLine() {
-	clean();
-	if (read_only) return;
-	QTreeWidgetItem *qtwi = new QTreeWidgetItem();
-	qtwi -> setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
-	tree_names -> addTopLevelItem(qtwi);
- 	tree_names -> setCurrentItem(qtwi);
-    	tree_names -> editItem(qtwi);
-}
-
-/**
-	Verifie qu'il y a au moins un nom
-*/
-bool NamesListWidget::checkOneName() {
-	updateHash();
-	if (!hash_names.count()) {
-		QET::QetMessageBox::critical(
-			this,
-			tr("Il doit y avoir au moins un nom.", "message box title"),
-			tr("Vous devez entrer au moins un nom.", "message box content")
-		);
-		return(false);
-	}
-	return(true);
-}
-
-/**
-	Lit les noms valides dans hash_names
-*/
-void NamesListWidget::updateHash() {
-	hash_names.clearNames();
-	int names_count = tree_names -> topLevelItemCount();
-	for (int i = 0 ; i < names_count ; ++ i) {
-		QString lang  = tree_names -> topLevelItem(i) -> text(0);
-		QString value = tree_names -> topLevelItem(i) -> text(1);
-		if (lang != "" && value != "") hash_names.addName(lang, value);
-	}
-}
-
-/**
-	Nettoie la liste des noms en enlevant les lignes vides
-*/
-void NamesListWidget::clean() {
-	int names_count = tree_names -> topLevelItemCount() - 1;
-	for (int i = names_count ; i >= 0 ; -- i) {
-		if (
-			tree_names -> topLevelItem(i) -> text(0).isEmpty() &&\
-			tree_names -> topLevelItem(i) -> text(1).isEmpty()
-		) {
-			tree_names -> takeTopLevelItem(i);
-		}
-	}
-}
-
-/**
-	@return Les noms entres dans la Names List
-*/
-NamesList NamesListWidget::names() {
-	updateHash();
-	return(hash_names);
-}
-
-/**
-	Definit les noms que le widget doit afficher
-*/
-void NamesListWidget::setNames(const NamesList &provided_names) {
-	foreach(QString lang, provided_names.langs()) {
-		QString value = provided_names[lang];
-		QStringList values;
-		values << lang << value;
-		QTreeWidgetItem *qtwi = new QTreeWidgetItem(values);
-		if (!read_only) qtwi -> setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
-		tree_names -> addTopLevelItem(qtwi);
-		tree_names -> sortItems(0, Qt::AscendingOrder);
-	}
-}
-
-/**
-	Verifie qu'il y a au moins un nom de saisi - si c'est le cas, le signal
-	imputChecked() est emis.
-*/
-void NamesListWidget::check() {
-	if (checkOneName()) emit(inputChecked());
-}
-
-/**
-	Definit le mode d'edition du widget
-	@param ro true pour que la liste de noms soit en lecture seule, false sinon
-*/
-void NamesListWidget::setReadOnly(bool ro) {
-	read_only = ro;
-	int names_count = tree_names -> topLevelItemCount() - 1;
-	for (int i = names_count ; i >= 0 ; -- i) {
-		Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
-		if (!read_only) flags |= Qt::ItemIsEditable;
-		tree_names -> topLevelItem(i) -> setFlags(flags);
-	}
-	button_add_line -> setEnabled(!read_only);
-}
-
-/// @return true si la liste de noms est en lecture seule, false sinon
-bool NamesListWidget::isReadOnly() const {
-	return(read_only);
-}

Deleted: trunk/sources/nameslistwidget.h
===================================================================
--- trunk/sources/nameslistwidget.h	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/nameslistwidget.h	2019-01-02 16:56:46 UTC (rev 5687)
@@ -1,67 +0,0 @@
-/*
-	Copyright 2006-2017 The QElectroTech Team
-	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 NAMES_LIST_WIDGET_H
-#define NAMES_LIST_WIDGET_H
-#include <QtWidgets>
-#include "nameslist.h"
-/**
-	This class provides a widget enabling users to enter localized names for
-	categories and elements.
-*/
-class NamesListWidget : public QWidget {
-	Q_OBJECT
-	
-	// constructors, destructor
-	public:
-	NamesListWidget(QWidget * = nullptr);
-	~NamesListWidget() override;
-	
-	private:
-	NamesListWidget(const NamesListWidget &);
-	
-	// attributes
-	private:
-	QTreeWidget *tree_names;
-	QPushButton *button_add_line;
-	NamesList hash_names;
-	bool read_only;
-	
-	// methods
-	public:
-	bool checkOneName();
-	NamesList names();
-	void setNames(const NamesList &);
-	void setReadOnly(bool);
-	bool isReadOnly() const;
-	
-	private:
-	void clean();
-	void updateHash();
-	
-	public slots:
-	void addLine();
-	void check();
-	
-	signals:
-	/**
-		Signal emitted after the widget successfully checked there was at least one
-		name entered
-	*/
-	void inputChecked();
-};
-#endif

Modified: trunk/sources/newelementwizard.cpp
===================================================================
--- trunk/sources/newelementwizard.cpp	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/newelementwizard.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -16,7 +16,7 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "newelementwizard.h"
-#include "nameslistwidget.h"
+#include "namelistwidget.h"
 #include "qetelementeditor.h"
 #include "qfilenameedit.h"
 #include "qetmessagebox.h"
@@ -130,7 +130,7 @@
 	page -> setSubTitle(tr("Indiquez le ou les noms de l'élément.", "wizard page subtitle"));
 	QVBoxLayout *layout = new QVBoxLayout();
 	
-	m_names_list = new NamesListWidget();
+	m_names_list = new NameListWidget(this);
 	NamesList hash_name;
 	hash_name.addName(QLocale::system().name().left(2), tr("Nom du nouvel élément", "default name when creating a new element"));
 	m_names_list -> setNames(hash_name);
@@ -144,14 +144,22 @@
  * @brief NewElementWizard::validateCurrentPage
  * @return true if the current step is valid
  */
-bool NewElementWizard::validateCurrentPage() {
+bool NewElementWizard::validateCurrentPage()
+{
 	WizardState wizard_state = static_cast<WizardState>(currentPage() -> property("WizardState").toInt());
-	if      (wizard_state == Category) return(validStep1());
-	else if (wizard_state == Filename) return(validStep2());
-	else if (wizard_state == Names) {
-		// must have one name minimum
-		if (m_names_list -> checkOneName())
+	
+	if (wizard_state == Category) {
+		return(validStep1());
+	}
+	else if (wizard_state == Filename) {
+		return(validStep2());
+	}
+	else if (wizard_state == Names)
+	{
+			// must have one name minimum
+		if (!m_names_list->isEmpty()) {
 			createNewElement();
+		}
 		return true;
 	}
 	else return(true);

Modified: trunk/sources/newelementwizard.h
===================================================================
--- trunk/sources/newelementwizard.h	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/newelementwizard.h	2019-01-02 16:56:46 UTC (rev 5687)
@@ -21,7 +21,7 @@
 #include <QWizard>
 #include "elementslocation.h"
 
-class NamesListWidget;
+class NameListWidget;
 class QFileNameEdit;
 class QTreeView;
 class ElementsCollectionModel;
@@ -53,7 +53,7 @@
 	private:
 		enum WizardState { Category, Filename, Names };
 		QFileNameEdit *m_qle_filename;
-		NamesListWidget *m_names_list;
+		NameListWidget *m_names_list;
 		QString m_chosen_file;
 		QTreeView *m_tree_view = nullptr;
 		ElementsLocation m_chosen_location;

Added: trunk/sources/qetinformation.cpp
===================================================================
--- trunk/sources/qetinformation.cpp	                        (rev 0)
+++ trunk/sources/qetinformation.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,128 @@
+/*
+	Copyright 2006-2018 The QElectroTech Team
+	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 "qetinformation.h"
+
+#include <QObject>
+#include <QHash>
+
+/**
+ * @brief QETInformation::titleblockInfoKeys
+ * @return all available key for use with a titleblock
+ */
+QStringList QETInformation::titleblockInfoKeys()
+{
+	QStringList info_list;
+	info_list << "author";
+	info_list << "date";
+	info_list << "title";
+	info_list << "filename";
+	info_list << "plant";
+	info_list << "locmach";
+	info_list << "indexrev";
+	info_list << "version";
+	info_list << "folio";
+	info_list << "folio-id";
+	info_list << "folio-total";
+	info_list << "previous-folio-num";
+	info_list << "next-folio-num";
+	info_list << "projecttitle";
+	info_list << "projectpath";
+	info_list << "projectfilename";
+	info_list << "saveddate";
+	info_list << "savedtime";
+	info_list << "savedfilename";
+	info_list << "savedfilepath";
+	
+	return info_list;
+}
+
+/**
+ * @brief QETInformation::titleblockTranslatedInfoKey
+ * @param info : info key to be translated
+ * @return the translated information given by @info
+ * If  @info don't match, return an empty string
+ */
+QString QETInformation::titleblockTranslatedInfoKey(const QString &info)
+{
+	if      (info == "author")             return QObject::tr("Auteur");
+	else if (info == "date")               return QObject::tr("Date");
+	else if (info == "title")              return QObject::tr("Titre");
+	else if (info == "filename")           return QObject::tr("Fichier");
+	else if (info == "plant")              return QObject::tr("Installation (=)");
+	else if (info == "locmach")            return QObject::tr("Localisation (+)");
+	else if (info == "indexrev")           return QObject::tr("Indice de révision");
+	else if (info == "version")            return QObject::tr("Version de QElectroTech");
+	else if (info == "folio")              return QObject::tr("Numéro de folio");
+	else if (info == "folio-id")           return QObject::tr("Position du folio");
+	else if (info == "folio-total")        return QObject::tr("Nombre de folio");
+	else if (info == "previous-folio-num") return QObject::tr("Numéro du folio précédent");
+	else if (info == "next-folio-num")     return QObject::tr("Numéro du folio suivant");
+	else if (info == "projecttitle")       return QObject::tr("Titre du projet");
+	else if (info == "projectpath")        return QObject::tr("Chemin du fichier du projet");
+	else if (info == "projectfilename")    return QObject::tr("Nom du fichier");
+	else if (info == "saveddate")          return QObject::tr("Date d'enregistrement du fichier");
+	else if (info == "savedtime")          return QObject::tr("Heure d'enregistrement du fichier");
+	else if (info == "savedfilename")      return QObject::tr("Nom du fichier enregistré");
+	else if (info == "savedfilepath")      return QObject::tr("Chemin du fichier enregistré");
+	else return QString();
+}
+
+/**
+ * @brief QETInformation::titleblockInfoKeysToVar
+ * @param info
+ * @return var in form %{my-var} corresponding to the info.
+ * if there is not available var for the given info, the returned var is %{void}
+ */
+QString QETInformation::titleblockInfoKeysToVar(const QString &info)
+{
+	if      (info == "author")             return QString("%{author}");
+	else if (info == "date")               return QString("%{date}");
+	else if (info == "title")              return QString("%{title}");
+	else if (info == "filename")           return QString("%{filename}");
+	else if (info == "plant")              return QString("%{plant}");
+	else if (info == "locmach")            return QString("%{locmach}");
+	else if (info == "indexrev")           return QString("%{indexrev}");
+	else if (info == "version")            return QString("%{version}");
+	else if (info == "folio")              return QString("%{folio}");
+	else if (info == "folio-id")           return QString("%{folio-id}");
+	else if (info == "folio-total")        return QString("%{folio-total}");
+	else if (info == "previous-folio-num") return QString("%{previous-folio-num}");
+	else if (info == "next-folio-num")     return QString("%{next-folio-num}");
+	else if (info == "projecttitle")       return QString("%{projecttitle}");
+	else if (info == "projectpath")        return QString("%{projectpath}");
+	else if (info == "projectfilename")    return QString("%{projectfilename}");
+	else if (info == "saveddate")          return QString("%{saveddate}");
+	else if (info == "savedtime")          return QString("%{savedtime}");
+	else if (info == "savedfilename")      return QString("%{savedfilename}");
+	else if (info == "savedfilepath")      return QString("%{savedfilepath}");
+	else return QString("%{void");
+}
+
+/**
+ * @brief QETInformation::titleblockTranslatedKeyHashVar
+ * @return a QHash with for key, the translated information key of title block,
+ * and for value the corresponding var.
+ */
+QHash<QString, QString> QETInformation::titleblockTranslatedKeyHashVar()
+{
+	QHash <QString, QString> hash_;
+	for (QString str : titleblockInfoKeys()) {
+		hash_.insert(titleblockTranslatedInfoKey(str), titleblockInfoKeysToVar(str));
+	}
+	return hash_;
+}

Added: trunk/sources/qetinformation.h
===================================================================
--- trunk/sources/qetinformation.h	                        (rev 0)
+++ trunk/sources/qetinformation.h	2019-01-02 16:56:46 UTC (rev 5687)
@@ -0,0 +1,31 @@
+/*
+	Copyright 2006-2018 The QElectroTech Team
+	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 QETINFORMATION_H
+#define QETINFORMATION_H
+
+#include <QStringList>
+
+namespace QETInformation
+{
+	QStringList titleblockInfoKeys();
+	QString titleblockTranslatedInfoKey(const QString &info);
+	QString titleblockInfoKeysToVar(const QString &info);
+	QHash <QString, QString> titleblockTranslatedKeyHashVar();
+}
+
+#endif // QETINFORMATION_H

Modified: trunk/sources/titleblock/templatecellwidget.cpp
===================================================================
--- trunk/sources/titleblock/templatecellwidget.cpp	2019-01-02 00:20:17 UTC (rev 5686)
+++ trunk/sources/titleblock/templatecellwidget.cpp	2019-01-02 16:56:46 UTC (rev 5687)
@@ -18,10 +18,12 @@
 #include "templatecellwidget.h"
 #include "titleblockcell.h"
 #include "nameslist.h"
-#include "nameslistwidget.h"
 #include "titleblocktemplate.h"
 #include "templatecommands.h"
 #include "qeticons.h"
+#include "namelistdialog.h"
+#include "namelistwidget.h"
+#include "qetinformation.h"
 
 /**
 	Constructor
@@ -374,33 +376,20 @@
 	@param attribute Name of the edited cell attribute
 	@param title Title of the dialog window
 */
-void TitleBlockTemplateCellWidget::editTranslatableValue(NamesList &names, const QString &attribute, const QString &title) const {
-	NamesListWidget *names_widget = new NamesListWidget();
-	names_widget -> setNames(names);
-	QDialogButtonBox * buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+void TitleBlockTemplateCellWidget::editTranslatableValue(NamesList &names, const QString &attribute, const QString &title) const
+{	
+	NameListDialog dialog_;
+
+	dialog_.setWindowTitle(title);
+	dialog_.setInformationText(labelValueInformationString());
+	dialog_.setHelpText(defaultVariablesString());
 	
-	QLabel *information = new QLabel(labelValueInformationString());
-	information -> setTextFormat(Qt::RichText);
-	information -> setWordWrap(true);
+	NameListWidget *nlw_ = dialog_.namelistWidget();
+	nlw_->setNames(names);
+	nlw_->setClipboardValue(QETInformation::titleblockTranslatedKeyHashVar());
 	
-	QLabel *def_var_label = new QLabel(defaultVariablesString());
-	def_var_label -> setTextFormat(Qt::RichText);
-	def_var_label -> setTextInteractionFlags(Qt::TextSelectableByMouse);
-	
-	QVBoxLayout *editor_layout = new QVBoxLayout();
-	editor_layout -> addWidget(information);
-	editor_layout -> addWidget(names_widget);
-	editor_layout -> addWidget(def_var_label);
-	editor_layout -> addWidget(buttons);
-	
-	QDialog edit_dialog;
-	edit_dialog.setWindowTitle(title);
-	connect(buttons, SIGNAL(rejected()), &edit_dialog, SLOT(reject()));
-	connect(buttons, SIGNAL(accepted()), &edit_dialog, SLOT(accept()));
-	edit_dialog.setLayout(editor_layout);
-	if (edit_dialog.exec() == QDialog::Accepted) {
-		emitModification(attribute, qVariantFromValue(names_widget -> names()));
-		
+	if(dialog_.exec() == QDialog::Accepted) {
+		emitModification(attribute, qVariantFromValue(nlw_->names()));
 	}
 }
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/