Element dialog : Remove ElementsCategoriesList and use QTreeView with ElementsCollectionModel instead

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4456 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun
2016-04-19 09:29:40 +00:00
parent c0a8b60dbb
commit 1d9735d0e3
6 changed files with 343 additions and 391 deletions

View File

@@ -16,362 +16,283 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "elementdialog.h"
#include <QtWidgets>
#include "qetapp.h"
#include "elementscategorieslist.h"
#include "elementscollectionitem.h"
#include "qfilenameedit.h"
#include "elementcollectionitem.h"
#include "elementscollectionmodel.h"
#include "qetmessagebox.h"
/**
Constructeur par defaut.
Construit un dialogue permettant d'ouvrir un element
@param mode Mode du dialogue
@see ElementDialog::Mode
@param parentWidget QWidget parent
@param parent QObject parent
*/
ElementDialog::ElementDialog(uint mode, QWidget *parentWidget, QObject *parent) :
QObject(parent),
mode_(mode),
buttons_(0),
list_(0),
textfield_(0)
* @brief ElementDialog::ElementDialog
* @param mode
* @param parent
*/
ElementDialog::ElementDialog(uint mode, QWidget *parent) :
QDialog(parent),
m_mode(mode)
{
dialog_ = new QDialog(parentWidget);
dialog_ -> setWindowModality(Qt::WindowModal);
setUpWidget();
setUpConnection();
}
/**
* @brief ElementDialog::setUpWidget
* Build and setup the widgets of this dialog
*/
void ElementDialog::setUpWidget()
{
setWindowModality(Qt::WindowModal);
#ifdef Q_OS_MAC
dialog_ -> setWindowFlags(Qt::Sheet);
setWindowFlags(Qt::Sheet);
#endif
buttons_ = new QDialogButtonBox();
// types selectionnables dans la liste
bool display_elements = (mode_ == OpenElement || mode_ == SaveElement);
int selectables = 0;
switch(mode_) {
case OpenElement: selectables = QET::Element; break;
case SaveElement: selectables = QET::ElementsCollectionItem; break;
case OpenCategory: selectables = QET::ElementsContainer; break;
case SaveCategory: selectables = QET::ElementsContainer; break;
QVBoxLayout *layout = new QVBoxLayout(this);
QString title_, label_;
switch (m_mode)
{
case OpenElement:
title_ = tr("Ouvrir un élément", "dialog title");
label_ = tr("Choisissez l'élément que vous souhaitez ouvrir.", "dialog content");
break;
case SaveElement:
title_ = tr("Enregistrer un élément", "dialog title");
label_ = tr("Choisissez l'élément dans lequel vous souhaitez enregistrer votre définition.", "dialog content");
break;
case OpenCategory:
title_ = tr("Ouvrir une catégorie", "dialog title");
label_ = tr("Choisissez une catégorie.", "dialog content");
break;
case SaveCategory:
title_ = tr("Enregistrer une catégorie", "dialog title");
label_ = tr("Choisissez une catégorie.", "dialog content");
break;
default:
title_ = tr("Titre");
label_ = tr("Label");
break;
}
list_ = new ElementsCategoriesList(display_elements, selectables);
connect(list_, SIGNAL(locationChanged(const ElementsLocation &)), this, SLOT(locationChanged(const ElementsLocation &)));
// titre et label
if (!mode) {
title_ = tr("Ouvrir un élément", "dialog title");
label_ = tr("Choisissez l'élément que vous souhaitez ouvrir.", "dialog content");
} else if (mode == 1) {
title_ = tr("Enregistrer un élément", "dialog title");
label_ = tr("Choisissez l'élément dans lequel vous souhaitez enregistrer votre définition.", "dialog content");
} else if (mode == 2) {
title_ = tr("Ouvrir une catégorie", "dialog title");
label_ = tr("Choisissez une catégorie.", "dialog content");
} else {
title_ = tr("Enregistrer une catégorie", "dialog title");
label_ = tr("Choisissez une catégorie.", "dialog content");
setWindowTitle(title_);
layout->addWidget(new QLabel(label_));
m_tree_view = new QTreeView(this);
ElementsCollectionModel *model = new ElementsCollectionModel(m_tree_view);
if (m_mode == OpenElement) {model->addCommonCollection();}
model->addCustomCollection();
foreach (QETProject *project, QETApp::registeredProjects()) {
model->addProject(project);
}
// mode ouverture / enregistrement
if (mode_ == SaveCategory || mode_ == SaveElement) {
buttons_ -> setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
textfield_ = new QFileNameEdit();
connect(textfield_, SIGNAL(textChanged(const QString &)), this, SLOT(textFieldChanged(const QString &)));
} else {
buttons_ -> setStandardButtons(QDialogButtonBox::Open | QDialogButtonBox::Cancel);
m_tree_view->setModel(model);
m_tree_view->setHeaderHidden(true);
layout->addWidget(m_tree_view);
m_buttons_box = new QDialogButtonBox(this);
if (m_mode == SaveCategory || m_mode == SaveElement)
{
m_buttons_box->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(true);
m_text_field = new QFileNameEdit();
m_text_field->setDisabled(true);
m_text_field->setPlaceholderText(m_mode == SaveCategory? tr("Nom du nouveau dossier") : tr("Nom du nouvel élément"));
layout->addWidget(m_text_field);
}
// connexions boutons -> dialogue
connect(buttons_, SIGNAL(accepted()), this, SLOT(checkDialog()));
connect(buttons_, SIGNAL(rejected()), dialog_, SLOT(reject()));
// connexions dialogue -> classe
connect(dialog_, SIGNAL(accepted()), this, SLOT(dialogAccepted()));
connect(dialog_, SIGNAL(rejected()), this, SLOT(dialogRejected()));
makeInterface();
else
{
m_buttons_box->setStandardButtons(QDialogButtonBox::Open | QDialogButtonBox::Cancel);
m_buttons_box->button(QDialogButtonBox::Open)->setDisabled(true);
}
layout->addWidget(m_buttons_box);
}
/**
Destructeur
*/
ElementDialog::~ElementDialog() {
dialog_ -> setParent(0);
delete dialog_;
* @brief ElementDialog::setUpConnection
* Setup connection of this dialog
*/
void ElementDialog::setUpConnection()
{
connect(m_tree_view, &QTreeView::clicked, this, &ElementDialog::indexClicked);
connect(m_buttons_box, &QDialogButtonBox::accepted, this, &ElementDialog::checkAccept);
connect(m_buttons_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
if (m_text_field) { connect(m_text_field, &QFileNameEdit::textChanged, this, &ElementDialog::checkCurrentLocation); }
}
/**
Affiche un dialogue permettant a l'utilisateur de selectionner une categorie existant deja
@param parentWidget QWidget parent
@return le chemin virtuel de cette categorie
*/
ElementsLocation ElementDialog::getExistingCategoryLocation(QWidget *parentWidget) {
return(ElementDialog::execConfiguredDialog(ElementDialog::OpenCategory, parentWidget));
* @brief ElementDialog::indexClicked
* @param index
*/
void ElementDialog::indexClicked(const QModelIndex &index)
{
ElementCollectionItem *eci = static_cast<ElementCollectionItem*> (index.internalPointer());
m_location = ElementsLocation(eci->collectionPath());
checkCurrentLocation();
}
/**
Affiche un dialogue permettant a l'utilisateur de selectionner une nouvelle categorie
@param parentWidget QWidget parent
@return le chemin virtuel de cette categorie
*/
ElementsLocation ElementDialog::getNewCategoryLocation(QWidget *parentWidget) {
return(ElementDialog::execConfiguredDialog(ElementDialog::SaveCategory, parentWidget));
* @brief ElementDialog::checkCurrentLocation
* Update this dialog according to the current selected location and the current mode
*/
void ElementDialog::checkCurrentLocation()
{
if (m_mode == OpenElement) {
m_buttons_box->button(QDialogButtonBox::Open)->setEnabled(m_location.isElement() && m_location.exist());
}
else if (m_mode == SaveElement)
{
m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(true);
//Location doesn't exist
if (!m_location.exist()) { return; }
if (m_location.isElement())
{
m_text_field->setDisabled(true);
m_buttons_box->button(QDialogButtonBox::Save)->setEnabled(true);
}
else if (m_location.isDirectory())
{
m_text_field->setEnabled(true);
if (m_text_field->text().isEmpty()) { return; }
//Only enable save button if the location at path :
//m_location.collectionPath + m_text_filed.text doesn't exist.
QString new_path = m_text_field->text();
if (!new_path.endsWith(".elmt")) new_path += ".elmt";
ElementsLocation loc = m_location;
loc.addToPath(new_path);
m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(loc.exist() ? true : false);
}
}
}
void ElementDialog::checkAccept()
{
ElementsLocation loc = location();
if (m_mode == OpenElement)
{
if (loc.isElement() && loc.exist()) {accept();}
if (!loc.exist())
{
QET::QetMessageBox::critical(this,
tr("Sélection inexistante", "message box title"),
tr("La sélection n'existe pas.", "message box content"));
return;
}
else if (!loc.isElement())
{
QET::QetMessageBox::critical(this,
tr("Sélection incorrecte", "message box title"),
tr("La sélection n'est pas un élément.", "message box content"));
return;
}
}
else if (m_mode == SaveElement)
{
if (loc.isElement())
{
if (loc.exist())
{
QMessageBox::StandardButton answer = QET::QetMessageBox::question(this,
tr("Écraser l'élément ?", "message box title"),
tr("L'élément existe déjà. Voulez-vous l'écraser ?", "message box content"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No);
if (answer == QMessageBox::Yes) {accept();}
else {return;}
}
else {accept();}
}
else
{
QET::QetMessageBox::critical(this,
tr("Sélection incorrecte", "message box title"),
tr("Vous devez sélectionner un élément ou une catégorie avec un nom pour l'élément.", "message box content"));
return;
}
}
}
/**
Affiche un dialogue permettant a l'utilisateur de selectionner un element a ouvrir
@param parentWidget QWidget parent
@return le chemin virtuel de cet element
*/
* @brief ElementDialog::location
* @return The selected location or a null location if user has selected nothing
* or selection isn't compatible with the curent mode
*/
ElementsLocation ElementDialog::location() const
{
if (m_mode == OpenElement)
{
if (m_location.isElement()) { return m_location; }
else {return ElementsLocation(); }
}
else if (m_mode == SaveElement)
{
//Current selected location is element, we return this location
if (m_location.isElement()) { return m_location; }
//Current selected location is directory, we return a location at path :
//m_location->collectionPath + m_text_field->text
else if (m_location.isDirectory())
{
QString new_path = m_text_field->text();
if (new_path.isEmpty()) { return ElementsLocation(); }
if (!new_path.endsWith(".elmt")) { new_path += ".elmt"; }
ElementsLocation loc = m_location;
loc.addToPath(new_path);
return loc;
}
}
return ElementsLocation();
}
/**
* @brief ElementDialog::getOpenElementLocation
* Display a dialog for open an element through her location
* @param parentWidget
* @return The location of the selected element
*/
ElementsLocation ElementDialog::getOpenElementLocation(QWidget *parentWidget) {
return(ElementDialog::execConfiguredDialog(ElementDialog::OpenElement, parentWidget));
}
/**
Affiche un dialogue permettant a l'utilisateur de selectionner un element (existant ou non)
qu'il souhaite enregistrer
@param parentWidget QWidget parent
@return le chemin virtuel de cet element
*/
* @brief ElementDialog::getSaveElementLocation
* Display a dialog that allow to user to select an element (existing or not) who he want to save
* @param parentWidget
* @return The location where the element must be save
*/
ElementsLocation ElementDialog::getSaveElementLocation(QWidget *parentWidget) {
return(ElementDialog::execConfiguredDialog(ElementDialog::SaveElement, parentWidget));
}
/**
Lance un dialogue selon la configuration mode
@param mode Mode du dialogue
@param parentWidget QWidget parent
*/
ElementsLocation ElementDialog::execConfiguredDialog(int mode, QWidget *parentWidget) {
ElementDialog element_dialog(mode, parentWidget);
element_dialog.exec();
return(element_dialog.location());
}
/**
Assemble les widgets pour obtenir le dialogue final
*/
void ElementDialog::makeInterface() {
dialog_ -> setWindowTitle(title_);
// disposition verticale
QVBoxLayout *layout = new QVBoxLayout(dialog_);
layout -> addWidget(new QLabel(label_));
layout -> addWidget(list_);
if (textfield_) {
QHBoxLayout *filename_layout = new QHBoxLayout();
filename_layout -> addWidget(new QLabel(tr("Nom :")));
filename_layout -> addWidget(textfield_);
layout -> addLayout(filename_layout);
}
layout -> addWidget(buttons_);
}
/**
Execute le dialogue
@return QDialog::Accepted si le dialogue a ete accepte, false sinon
@see DialogCode
*/
int ElementDialog::exec() {
return(dialog_ -> exec());
}
/**
@return le chemin virtuel choisi via le dialogue
Si l'utilisateur n'a pas pu faire son choix, une chaine vide est retournee.
*/
ElementsLocation ElementDialog::location() const {
return(location_);
}
/**
gere le changement de chemin virtuel par l'utilisateur
@param new_loc le nouveau chemin virtuel choisi par l'utilisateur
*/
void ElementDialog::locationChanged(const ElementsLocation &new_loc) {
ElementsCollectionItem *item = QETApp::collectionItem(new_loc);
if (!item) return;
if (mode_ == OpenElement) {
buttons_ -> button(QDialogButtonBox::Open) -> setEnabled(item -> isElement());
} else if (mode_ == SaveElement) {
// si l'utilisateur choisit un element existant, on desactive le champ
textfield_ -> setEnabled(!item -> isElement());
// il faut soit un element selectionne soit une categorie et un nom
buttons_ -> button(QDialogButtonBox::Save) -> setEnabled(
((item -> isCategory() || item -> isCollection()) && !textfield_ -> text().isEmpty()) ||\
item -> isElement()
);
} else if (mode_ == OpenCategory) {
/// @todo
} else if (mode_ == SaveCategory) {
/// @todo
}
location_ = new_loc;
}
/**
Gere le changement de contenu dans le champ de texte
@param text Contenu du champ de texte
*/
void ElementDialog::textFieldChanged(const QString &text) {
ElementsCollectionItem *item = QETApp::collectionItem(list_ -> selectedLocation());
if (!item) return;
if (mode_ == SaveElement) {
// il faut soit un element selectionne soit une categorie et un nom
buttons_ -> button(QDialogButtonBox::Save) -> setEnabled(
((item -> isCategory() || item -> isCollection()) && !text.isEmpty()) ||\
item -> isElement()
);
} else if (mode_ == SaveCategory) {
// il faut forcement un nom pour la nouvelle categorie
buttons_ -> button(QDialogButtonBox::Save) -> setEnabled(!text.isEmpty());
}
}
/**
Verifie l'etat du dialogue au moment ou l'utilisateur le valide.
*/
void ElementDialog::checkDialog() {
// verifie si ce qui a ete selectionne par l'utilisateur correspond au mode du widget
if (mode_ == OpenElement) {
// l'utilisateur doit avoir choisi un element existant
// on verifie d'abord que l'utilisateur a choisi quelque chose
ElementsLocation location = list_ -> selectedLocation();
if (location.isNull()) {
QET::QetMessageBox::critical(
dialog_,
tr("Pas de sélection", "message box title"),
tr("Vous devez sélectionner un élément.", "message box content")
);
return;
}
// on verifie donc que la selection existe
ElementsCollectionItem *item = QETApp::collectionItem(location);
if (!item) {
QET::QetMessageBox::critical(
dialog_,
tr("Sélection inexistante", "message box title"),
tr("La sélection n'existe pas.", "message box content")
);
return;
}
// puis on verifie qu'il s'agit bien d'un element
if (!item -> isElement()) {
QET::QetMessageBox::critical(
dialog_,
tr("Sélection incorrecte", "message box title"),
tr("La sélection n'est pas un élément.", "message box content")
);
return;
}
location_ = location;
} else if (mode_ == SaveElement) {
/*
l'utilisateur doit avoir choisi soit :
-une categorie et un nom d'element
-un element existant
*/
ElementsLocation location = list_ -> selectedLocation();
if (location.isNull()) {
QET::QetMessageBox::critical(
dialog_,
tr("Pas de sélection", "message box title"),
tr("Vous devez sélectionner une catégorie ou un élément.", "message box content")
);
return;
}
// on verifie donc que la selection existe
ElementsCollectionItem *item = QETApp::collectionItem(location);
if (!item) {
QET::QetMessageBox::critical(
dialog_,
tr("Sélection inexistante", "message box title"),
tr("La sélection n'existe pas.", "message box content")
);
return;
}
ElementsLocation final_location(location);
if (!item -> isElement()) {
QString element_name(textfield_ -> text());
// si on a une categorie (ou une collection), il nous faut un nom d'element
if (element_name.isEmpty()) {
QET::QetMessageBox::critical(
dialog_,
tr("Nom manquant", "message box title"),
tr("Vous devez entrer un nom pour l'élément", "message box content")
);
return;
}
// ce nom d'element doit etre valide
if (QET::containsForbiddenCharacters(element_name)) {
QET::QetMessageBox::critical(
dialog_,
tr("Nom invalide", "message box title"),
QString(
tr(
"Vous ne pouvez pas utiliser les caractères "
"suivants dans le nom de l'élément : %1"
)
).arg(QET::forbiddenCharactersString(true))
);
return;
}
// ajoute .elmt a la fin du nom si necessaire
if (!element_name.endsWith(".elmt", Qt::CaseInsensitive)) {
element_name += ".elmt";
}
final_location.addToPath(element_name);
}
// determine si l'element n'existe pas deja
bool element_already_exists = (
item -> isElement() ||\
QETApp::collectionItem(final_location)
);
// si l'element existe, on demande confirmation pour son ecrasement
if (element_already_exists) {
QMessageBox::StandardButton answer = QET::QetMessageBox::question(
dialog_,
tr("Écraser l'élément ?", "message box title"),
tr("L'élément existe déjà. Voulez-vous l'écraser ?", "message box content"),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
QMessageBox::No
);
if (answer != QMessageBox::Yes) return;
}
location_ = final_location;
} else if (mode_ == OpenCategory) {
// l'utilisateur doit avoir choisi une categorie ou une collection existante
/// @todo effectuer les verifications necessaires
} else if (mode_ == SaveCategory) {
// l'utilisateur doit avoir choisi une categorie inexistante
/// @todo effectuer les verifications necessaires
}
// le dialogue est verifie, il peut etre accepte
dialog_ -> accept();
}
/**
Slot execute apres la validation du dialogue par l'utilisateur
*/
void ElementDialog::dialogAccepted() {
}
/**
Gere le rejet du dialogue par l'utilisateur.
*/
void ElementDialog::dialogRejected() {
location_ = ElementsLocation();
* @brief ElementDialog::execConfiguredDialog
* launch a dialog with the chosen mode
* @param mode : mode of the dialog
* @param parentWidget : parent widget of the dialog
* @return the chosen location
*/
ElementsLocation ElementDialog::execConfiguredDialog(int mode, QWidget *parentWidget)
{
ElementDialog *element_dialog = new ElementDialog(mode, parentWidget);
element_dialog->exec();
ElementsLocation location = element_dialog->location();
delete element_dialog;
return(location);
}