NameList widget : add a combo box for easily paste texts, like the variables for title block.

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5687 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun
2019-01-02 16:56:46 +00:00
parent 2d76065b98
commit 04e890ab7d
20 changed files with 724 additions and 321 deletions

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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>