/* Copyright 2006-2025 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 . */ #include "templatelogomanager.h" #include "../qetapp.h" #include "../qeticons.h" #include "../titleblocktemplate.h" /** Constructor @param managed_template Title block template this widget manages logos for. @param parent Parent QWidget. */ TitleBlockTemplateLogoManager::TitleBlockTemplateLogoManager(TitleBlockTemplate *managed_template, QWidget *parent) : QWidget(parent), managed_template_(managed_template) { initWidgets(); fillView(); } /** Destructor */ TitleBlockTemplateLogoManager::~TitleBlockTemplateLogoManager() { } /** @return the name of the currently selected logo, or a null QString if none is selected. */ QString TitleBlockTemplateLogoManager::currentLogo() const { if (!managed_template_) return QString(); QListWidgetItem *current_item = logos_view_ -> currentItem(); if (!current_item) return QString(); return(current_item -> text()); } /** @return Whether this logo manager should allow logo edition (renaming, addition, deletion). */ bool TitleBlockTemplateLogoManager::isReadOnly() const { return(read_only_); } /** Emit the logosChanged() signal. */ void TitleBlockTemplateLogoManager::emitLogosChangedSignal() { emit(logosChanged(const_cast(managed_template_))); } /** Initialize widgets composing the Logo manager */ void TitleBlockTemplateLogoManager::initWidgets() { open_dialog_dir_.setPath(QETApp::documentDir()); setWindowTitle(tr("Gestionnaire de logos")); setWindowIcon(QET::Icons::InsertImage); setWindowFlags(Qt::Dialog); logos_label_ = new QLabel(tr("Logos embarqués dans ce modèle :")); logos_view_ = new QListWidget(); logos_view_ -> setViewMode(QListView::IconMode); logos_view_ -> setGridSize(iconsize() * 1.4); logos_view_ -> setMinimumSize(iconsize() * 2.9); logos_view_ -> setIconSize(iconsize()); logos_view_ -> setWrapping(true); logos_view_ -> setMovement(QListView::Static); logos_view_ -> setResizeMode(QListView::Adjust); add_button_ = new QPushButton(QET::Icons::Add, tr("Ajouter un logo")); export_button_ = new QPushButton(QET::Icons::DocumentExport, tr("Exporter ce logo")); delete_button_ = new QPushButton(QET::Icons::Remove, tr("Supprimer ce logo")); logo_box_ = new QGroupBox(tr("Propriétés")); logo_name_label_ = new QLabel(tr("Nom :")); logo_name_ = new QLineEdit(); rename_button_ = new QPushButton(QET::Icons::EditRename, tr("Renommer")); logo_type_ = new QLabel(tr("Type :")); buttons_ = new QDialogButtonBox(QDialogButtonBox::Ok); hlayout1_ = new QHBoxLayout(); hlayout1_ -> addWidget(logo_name_label_); hlayout1_ -> addWidget(logo_name_); hlayout1_ -> addWidget(rename_button_); hlayout0_ = new QHBoxLayout(); hlayout0_ -> addWidget(export_button_); hlayout0_ -> addWidget(delete_button_); vlayout1_ = new QVBoxLayout(); vlayout1_ -> addLayout(hlayout1_); vlayout1_ -> addWidget(logo_type_); logo_box_ -> setLayout(vlayout1_); vlayout0_ = new QVBoxLayout(); vlayout0_ -> addWidget(logos_label_); vlayout0_ -> addWidget(logos_view_); vlayout0_ -> addWidget(add_button_); vlayout0_ -> addLayout(hlayout0_); vlayout0_ -> addWidget(logo_box_); setLayout(vlayout0_); connect( logos_view_, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(updateLogoInformations(QListWidgetItem *, QListWidgetItem *)) ); connect(add_button_, SIGNAL(released()), this, SLOT(addLogo())); connect(export_button_, SIGNAL(released()), this, SLOT(exportLogo())); connect(delete_button_, SIGNAL(released()), this, SLOT(removeLogo())); connect(rename_button_, SIGNAL(released()), this, SLOT(renameLogo())); } /** Update the logos display. */ void TitleBlockTemplateLogoManager::fillView() { if (!managed_template_) return; logos_view_ -> clear(); foreach (QString logo_name, managed_template_ -> logos()) { QIcon current_icon; QPixmap current_logo = managed_template_ -> bitmapLogo(logo_name); if (!current_logo.isNull()) { current_icon = QIcon(current_logo); } else { QSvgRenderer *svg_logo = managed_template_ -> vectorLogo(logo_name); if (svg_logo) { QPixmap *svg_pixmap = new QPixmap(iconsize()); svg_pixmap -> fill(); QPainter p; p.begin(svg_pixmap); svg_logo -> render(&p); p.end(); current_icon = QIcon(*svg_pixmap); } } QListWidgetItem *qlwi = new QListWidgetItem(current_icon, logo_name); qlwi -> setTextAlignment(Qt::AlignBottom | Qt::AlignHCenter); logos_view_ -> insertItem(0, qlwi); } QListWidgetItem *current_item = logos_view_ -> currentItem(); updateLogoInformations(current_item, nullptr); } /** @return the icon size to display the logos embedded within the managed template. */ QSize TitleBlockTemplateLogoManager::iconsize() const { return(QSize(80, 80)); } /** When adding a logo, it may occur its name is already used by another pre-existing logo. This method asks users whether they want to erase the existing logo, change the initial name or simply cancel the operation. @param initial_name Initial name of the logo to be added @return Either a null QString if the user cancelled the operation, or the name to be used when adding the logo. */ QString TitleBlockTemplateLogoManager::confirmLogoName(const QString &initial_name) { QString name = initial_name; QDialog *rename_dialog = nullptr; QLabel *rd_label = nullptr; QLineEdit *rd_input = nullptr; while (managed_template_ -> logos().contains(name)) { if (!rename_dialog) { rename_dialog = new QDialog(this); rename_dialog -> setWindowTitle(tr("Logo déjà existant")); rd_label = new QLabel(); rd_label -> setWordWrap(true); rd_input = new QLineEdit(); QDialogButtonBox *rd_buttons = new QDialogButtonBox(); QPushButton *replace_button = rd_buttons -> addButton(tr("Remplacer"), QDialogButtonBox::YesRole); QPushButton *rename_button = rd_buttons -> addButton(tr("Renommer"), QDialogButtonBox::NoRole); QPushButton *cancel_button = rd_buttons -> addButton(QDialogButtonBox::Cancel); QVBoxLayout *rd_vlayout0 = new QVBoxLayout(); rd_vlayout0 -> addWidget(rd_label); rd_vlayout0 -> addWidget(rd_input); rd_vlayout0 -> addWidget(rd_buttons); rename_dialog -> setLayout(rd_vlayout0); QSignalMapper *signal_mapper = new QSignalMapper(rename_dialog); signal_mapper -> setMapping(replace_button, QDialogButtonBox::YesRole); signal_mapper -> setMapping(rename_button, QDialogButtonBox::NoRole); signal_mapper -> setMapping(cancel_button, QDialogButtonBox::RejectRole); connect(replace_button, SIGNAL(clicked()), signal_mapper, SLOT(map())); connect(rename_button, SIGNAL(clicked()), signal_mapper, SLOT(map())); connect(cancel_button, SIGNAL(clicked()), signal_mapper, SLOT(map())); connect(signal_mapper, SIGNAL(mapped(int)), rename_dialog, SLOT(done(int))); } rd_label -> setText( QString(tr( "Il existe déjà un logo portant le nom \"%1\" au sein de " "ce modèle de cartouche. Voulez-vous le remplacer ou " "préférez-vous spécifier un autre nom pour ce nouveau " "logo ?" )).arg(name) ); rd_input -> setText(name); int answer = rename_dialog -> exec(); if (answer == QDialogButtonBox::YesRole) { // we can use the initial name break; } else if (answer == QDialogButtonBox::NoRole) { // the user provided another name name = rd_input -> text(); #if TODO_LIST #pragma message("@TODO prevent the user from entering an empty name") #endif /// TODO prevent the user from entering an empty name } else { // the user cancelled the operation return(QString()); } }; return(name); } /** Update the displayed informations relative to the currently selected logo. @param current Newly selected logo item @param previous Previously selected logo item */ void TitleBlockTemplateLogoManager::updateLogoInformations(QListWidgetItem *current, QListWidgetItem *previous) { Q_UNUSED(previous); if (current) { QString logo_name = current -> text(); logo_name_ -> setText(logo_name); if (managed_template_) { QString logo_type = managed_template_ -> logoType(logo_name); logo_type_ -> setText(tr("Type : %1").arg(logo_type)); } } else { logo_name_ -> setText(QString()); logo_type_ -> setText(tr("Type :")); } } /** Ask the user for a filepath, and add it as a new logo in the managed template. */ void TitleBlockTemplateLogoManager::addLogo() { if (!managed_template_) return; QString filepath = QFileDialog::getOpenFileName( this, tr("Choisir une image / un logo"), open_dialog_dir_.absolutePath(), tr("Images vectorielles (*.svg);;Images bitmap (*.png *.jpg *.jpeg *.gif *.bmp *.xpm);;Tous les fichiers (*)") ); if (filepath.isEmpty()) return; // that filepath needs to point to a valid, readable file QFileInfo filepath_info(filepath); if (!filepath_info.exists() || !filepath_info.isReadable()) { QMessageBox::critical(this, tr("Erreur"), tr("Impossible d'ouvrir le fichier spécifié")); return; } // ensure we can use the file name to add the logo QString logo_name = confirmLogoName(filepath_info.fileName()); if (logo_name.isNull()) return; open_dialog_dir_ = QDir(filepath); if (managed_template_ -> addLogoFromFile(filepath, logo_name)) { fillView(); emitLogosChangedSignal(); } } /** Export the currently selected logo */ void TitleBlockTemplateLogoManager::exportLogo() { QString current_logo = currentLogo(); if (current_logo.isNull()) return; QString filepath = QFileDialog::getSaveFileName( this, tr("Choisir un fichier pour exporter ce logo"), open_dialog_dir_.absolutePath() % "/" % current_logo, tr("Tous les fichiers (*);;Images vectorielles (*.svg);;Images bitmap (*.png *.jpg *.jpeg *.gif *.bmp *.xpm)") ); if (filepath.isEmpty()) return; bool save_logo = managed_template_ -> saveLogoToFile(current_logo, filepath); if (!save_logo) { QMessageBox::critical(this, tr("Erreur"), QString(tr("Impossible d'exporter vers le fichier spécifié"))); } else { open_dialog_dir_ = QDir(filepath); } } /** Delete the currently selected logo. */ void TitleBlockTemplateLogoManager::removeLogo() { QString current_logo = currentLogo(); if (current_logo.isNull()) return; if (managed_template_ -> removeLogo(current_logo)) { fillView(); emitLogosChangedSignal(); } } /** Rename currently selected logo. */ void TitleBlockTemplateLogoManager::renameLogo() { QString current_logo = currentLogo(); if (current_logo.isNull()) return; QString entered_name = logo_name_ -> text(); QString warning_title = tr("Renommer un logo"); if (entered_name == current_logo) { QMessageBox::warning( this, warning_title, tr("Vous devez saisir un nouveau nom.") ); return; } if (entered_name.trimmed().isEmpty()) { QMessageBox::warning( this, warning_title, tr("Le nouveau nom ne peut pas être vide.") ); return; } if (managed_template_ -> logos().contains(entered_name)) { QMessageBox::warning( this, warning_title, tr("Le nom saisi est déjà utilisé par un autre logo.") ); return; } if (managed_template_ -> renameLogo(current_logo, entered_name)) { fillView(); emitLogosChangedSignal(); } } /** @param read_only Whether this logo manager should allow logo edition (renaming, addition, deletion) */ void TitleBlockTemplateLogoManager::setReadOnly(bool read_only) { if (read_only_ == read_only) return; read_only_ = read_only; add_button_ -> setEnabled(!read_only_); delete_button_ -> setEnabled(!read_only_); rename_button_ -> setEnabled(!read_only_); logo_name_ -> setReadOnly(read_only_); }