mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-09 21:54:13 +02:00
0e2738b246
Closing a title block template editor crashed it. The editor deletes
itself on close; QWidget's destructor then deletes its children, and
some of them signal the editor as they go:
- the scene deselects its cells, so the view emits
selectedCellsChanged() to the editor's slot of the same name (when a
cell was selected);
- the undo stack is cleared, so it emits cleanChanged() to
updateEditorTitle() (when the template was edited).
Both slots then run on an object whose destructor has already run. A
Debug build aborts ("Called object is not of the correct type (class
destructor may have already run)"); a release build calls a member
function of a destroyed object.
Disconnect every child of the editor from it in the editor's
destructor, before the base destructors delete the children.
No file-format change, no change while the editor is open.
Tests: none automated; the editor needs the whole application.
Checked by hand (see the PR).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Beat Hangartner <beat@hangartners.ch>
1101 lines
37 KiB
C++
1101 lines
37 KiB
C++
/*
|
||
Copyright 2006-2026 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 "qettemplateeditor.h"
|
||
|
||
#include "../qetapp.h"
|
||
#include "../qeticons.h"
|
||
#include "../shortcutmanager.h"
|
||
#include "../qetmessagebox.h"
|
||
#include "../qetproject.h"
|
||
#include "templatecellwidget.h"
|
||
#include "templatecommands.h"
|
||
#include "templatelocationsaver.h"
|
||
#include "templatelogomanager.h"
|
||
#include "templateview.h"
|
||
#include "../toolbarsettings.h"
|
||
|
||
/**
|
||
@param parent parent QWidget of this window
|
||
*/
|
||
QETTitleBlockTemplateEditor::QETTitleBlockTemplateEditor(QWidget *parent) :
|
||
QETMainWindow(parent),
|
||
opened_from_file_(false),
|
||
read_only_(false),
|
||
duplicate_(false),
|
||
tb_template_(nullptr),
|
||
logo_manager_(nullptr)
|
||
{
|
||
setWindowIcon(QET::Icons::QETLogo);
|
||
setAttribute(Qt::WA_DeleteOnClose);
|
||
|
||
initWidgets();
|
||
initActions();
|
||
initMenus();
|
||
initToolbars();
|
||
ToolbarSettings::applyTo(this);
|
||
readSettings();
|
||
}
|
||
|
||
/**
|
||
Destructor
|
||
*/
|
||
QETTitleBlockTemplateEditor::~QETTitleBlockTemplateEditor()
|
||
{
|
||
// QWidget's destructor deletes the children, and some of them
|
||
// signal this editor as they go: the scene deselects its cells (the
|
||
// view emits selectedCellsChanged()), the undo stack is cleared
|
||
// (cleanChanged()). By then this editor is already destroyed, so
|
||
// stop listening to all of its children first.
|
||
const auto children = findChildren<QObject *>();
|
||
for (QObject *child : children) {
|
||
disconnect(child, nullptr, this, nullptr);
|
||
}
|
||
}
|
||
|
||
/**
|
||
@return the location of the currently edited template
|
||
*/
|
||
TitleBlockTemplateLocation QETTitleBlockTemplateEditor::location() const
|
||
{
|
||
return(location_);
|
||
}
|
||
|
||
/**
|
||
@return true if the provided filepath matches the currently edited template.
|
||
@param filepath path of a title block template on the filesystem
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::isEditing(const QString &filepath)
|
||
{
|
||
QString current_filepath;
|
||
if (opened_from_file_) {
|
||
current_filepath = filepath_;
|
||
} else {
|
||
current_filepath = QETApp::realPath(location_.toString());
|
||
}
|
||
|
||
return(
|
||
QET::compareCanonicalFilePaths(
|
||
current_filepath,
|
||
filepath
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
@brief QETTitleBlockTemplateEditor::setOpenForDuplication
|
||
@param duplicate : true for this editor to prompt the user for a
|
||
new template name as soon as the window appears in order to duplicate
|
||
the edited one.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::setOpenForDuplication(bool duplicate)
|
||
{
|
||
duplicate_ = duplicate;
|
||
}
|
||
|
||
/**
|
||
@return true if this editor will prompt the user for a new template
|
||
name as soon as the window appears in order to duplicate the edited one.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::openForDuplication() const
|
||
{
|
||
return(duplicate_);
|
||
}
|
||
|
||
/**
|
||
@return true if the currently edited template can be closed. A template can be
|
||
closed if it has not been modified. If the template has been modified, this
|
||
method asks the user what he wants to do.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::canClose()
|
||
{
|
||
if (undo_stack_ -> isClean()) return(true);
|
||
// ask the user whether he wants to save the current template
|
||
QMessageBox::StandardButton answer = QET::QetMessageBox::question(
|
||
this,
|
||
tr("Save current template?", "dialog title"),
|
||
QString(
|
||
tr(
|
||
"Do you wish to save the template %1?",
|
||
"dialog content - %1 is a title block template name"
|
||
)
|
||
).arg(location_.name()),
|
||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
|
||
QMessageBox::Cancel
|
||
);
|
||
bool result;
|
||
switch(answer) {
|
||
case QMessageBox::Cancel: result = false; break; // the user hits Cancel or closes the dialog: abort the closing
|
||
case QMessageBox::Yes: result = save(); break; // the user hits Yes: la reussite depend de l'enregistrement
|
||
default: result = true; // the user hits no: the editor can be closed
|
||
}
|
||
return(result);
|
||
}
|
||
|
||
/**
|
||
@param event Object describing the received event.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::firstActivation(QEvent *event)
|
||
{
|
||
Q_UNUSED(event)
|
||
if (duplicate_ && !opened_from_file_ && location_.parentCollection()) {
|
||
// this editor is supposed to duplicate its current location
|
||
QTimer::singleShot(250, this, &QETTitleBlockTemplateEditor::duplicateCurrentLocation);
|
||
}
|
||
}
|
||
|
||
/**
|
||
Handle the closing of the main window
|
||
@param qce The QCloseEvent event
|
||
*/
|
||
void QETTitleBlockTemplateEditor::closeEvent(QCloseEvent *qce)
|
||
{
|
||
if (canClose()) {
|
||
writeSettings();
|
||
setAttribute(Qt::WA_DeleteOnClose);
|
||
qce -> accept();
|
||
} else qce -> ignore();
|
||
}
|
||
|
||
/**
|
||
Ask the user for a new template name in order to duplicate the currently
|
||
edited template.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::duplicateCurrentLocation()
|
||
{
|
||
// this method does not work for templates edited from the filesystem
|
||
if (opened_from_file_) return;
|
||
|
||
QString proposed_name;
|
||
if (location_.name().isEmpty()) {
|
||
proposed_name = tr("new_template",
|
||
"template name suggestion when duplicating the default one");
|
||
} else {
|
||
proposed_name = QString("%1_copy").arg(location_.name());
|
||
}
|
||
|
||
bool accepted = false;
|
||
QString new_template_name = QInputDialog::getText(
|
||
this,
|
||
tr("Duplicate a title block template", "input dialog title"),
|
||
tr("In order to duplicate this template, please enter a name for its copy",
|
||
"input dialog text"),
|
||
QLineEdit::Normal,
|
||
proposed_name,
|
||
&accepted
|
||
);
|
||
if (accepted) {
|
||
TitleBlockTemplateLocation new_template_location(
|
||
new_template_name,
|
||
location_.parentCollection());
|
||
saveAs(new_template_location);
|
||
}
|
||
}
|
||
|
||
/**
|
||
@param location Location of the tile block template to be edited.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::edit(
|
||
const TitleBlockTemplateLocation &location)
|
||
{
|
||
// the template name may be empty to create a new one
|
||
const TitleBlockTemplate *tb_template_orig;
|
||
if (location.name().isEmpty()) {
|
||
// loads the default title block template provided by the application
|
||
// it will be used as a start point to design the title block
|
||
tb_template_orig = QETApp::defaultTitleBlockTemplate();
|
||
} else {
|
||
tb_template_orig = location.getTemplate();
|
||
}
|
||
if (!tb_template_orig) {
|
||
/// TODO The TBT does not exist, manage error
|
||
#if TODO_LIST
|
||
#pragma message("@TODO The TBT does not exist, manage error")
|
||
#endif
|
||
return(false);
|
||
}
|
||
|
||
opened_from_file_ = false;
|
||
location_ = location;
|
||
setReadOnly(location.isReadOnly());
|
||
editCopyOf(tb_template_orig);
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
Edit the given template.
|
||
@param project Parent project of the template to edit.
|
||
@param template_name Name of the template to edit within its parent project.
|
||
@return true if this editor was able to edit the given template, false otherwise
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::edit(
|
||
QETProject *project, const QString &template_name)
|
||
{
|
||
// we require a project we will rattach templates to
|
||
if (!project) return(false);
|
||
|
||
// the template name may be empty to create a new one
|
||
const TitleBlockTemplate *tb_template_orig;
|
||
if (template_name.isEmpty())
|
||
{
|
||
// loads the default title block template provided by the application
|
||
// it will be used as a start point to design the title block
|
||
tb_template_orig = QETApp::defaultTitleBlockTemplate();
|
||
}
|
||
else
|
||
{
|
||
tb_template_orig = project->embeddedTitleBlockTemplatesCollection()->getTemplate(template_name);
|
||
}
|
||
|
||
if (!tb_template_orig) {
|
||
/// TODO The TBT does not exist, manage error
|
||
#if TODO_LIST
|
||
#pragma message("@TODO The TBT does not exist, manage error")
|
||
#endif
|
||
return(false);
|
||
}
|
||
|
||
opened_from_file_ = false;
|
||
location_.setParentCollection(project -> embeddedTitleBlockTemplatesCollection());
|
||
location_.setName(template_name);
|
||
setReadOnly(project -> isReadOnly());
|
||
return(editCopyOf(tb_template_orig));
|
||
}
|
||
|
||
/**
|
||
@param file_path Path of the template file to edit.
|
||
@return false if a problem occurred while opening the template, true otherwise.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::edit(const QString &file_path)
|
||
{
|
||
// get title block template object from the file, edit it
|
||
TitleBlockTemplate *tbt = new TitleBlockTemplate();
|
||
bool loading = tbt -> loadFromXmlFile(file_path);
|
||
if (!loading) {
|
||
#if TODO_LIST
|
||
#pragma message("@TODO the file opening failed, warn the user?")
|
||
#endif
|
||
/// TODO the file opening failed, warn the user?
|
||
return(false);
|
||
}
|
||
|
||
bool editing = edit(tbt);
|
||
if (!editing) {
|
||
#if TODO_LIST
|
||
#pragma message("@TODO the file editing failed, warn the user?")
|
||
#endif
|
||
/// TODO the file editing failed, warn the user?
|
||
return(false);
|
||
}
|
||
|
||
QFileInfo file_path_info(file_path);
|
||
filepath_ = file_path;
|
||
opened_from_file_ = true;
|
||
setReadOnly(!file_path_info.isWritable());
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
@param tbt Title block template to be edited
|
||
@return false if a problem occurred while opening the template, true otherwise.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::editCopyOf(const TitleBlockTemplate *tbt)
|
||
{
|
||
if (!tbt) return(false);
|
||
return(edit(tbt -> clone()));
|
||
}
|
||
|
||
/**
|
||
@param tbt Title block template to be directly edited
|
||
@return false if a problem occurred while opening the template, true otherwise.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::edit(TitleBlockTemplate *tbt)
|
||
{
|
||
if (!tbt) return(false);
|
||
tb_template_ = tbt;
|
||
template_edition_area_view_ -> setTitleBlockTemplate(tb_template_);
|
||
template_cell_editor_widget_ -> updateLogosComboBox(tb_template_);
|
||
updateEditorTitle();
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
Launches the logo manager widget, which allows the user to manage the
|
||
logos embedded within the edited template.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::editLogos()
|
||
{
|
||
if (tb_template_) {
|
||
if (!logo_manager_) {
|
||
initLogoManager();
|
||
}
|
||
|
||
logo_manager_ -> layout() -> setContentsMargins(0, 0, 0, 0);
|
||
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Close);
|
||
|
||
QVBoxLayout *vlayout0 = new QVBoxLayout();
|
||
vlayout0 -> addWidget(logo_manager_);
|
||
vlayout0 -> addWidget(buttons);
|
||
|
||
QDialog d(this);
|
||
d.setWindowTitle(logo_manager_ -> windowTitle());
|
||
d.setLayout(vlayout0);
|
||
connect(buttons, &QDialogButtonBox::rejected, &d, &QDialog::reject);
|
||
d.exec();
|
||
|
||
// prevent the logo manager from being deleted along with the dialog
|
||
logo_manager_ -> setParent(this);
|
||
}
|
||
}
|
||
|
||
/**
|
||
Launch a new title block template editor.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::newTemplate()
|
||
{
|
||
QETTitleBlockTemplateEditor *qet_template_editor = new QETTitleBlockTemplateEditor();
|
||
qet_template_editor -> edit(TitleBlockTemplateLocation());
|
||
qet_template_editor -> show();
|
||
qet_template_editor -> readSettingsState(); // must run after show() in Qt6
|
||
}
|
||
|
||
/**
|
||
Initialize the various actions.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::initActions()
|
||
{
|
||
new_ = new QAction(QET::Icons::DocumentNew, tr("&New", "menu entry"), this);
|
||
open_ = new QAction(QET::Icons::DocumentOpen, tr("&Open", "menu entry"), this);
|
||
open_from_file_ = new QAction(QET::Icons::DocumentOpen, tr("Open from a file", "menu entry"), this);
|
||
save_ = new QAction(QET::Icons::DocumentSave, tr("&Save", "menu entry"), this);
|
||
save_as_ = new QAction(QET::Icons::DocumentSaveAs, tr("Save as", "menu entry"), this);
|
||
save_as_file_ = new QAction(QET::Icons::DocumentSaveAs, tr("Save to a file", "menu entry"), this);
|
||
quit_ = new QAction(QET::Icons::ApplicationExit, tr("&Quit", "menu entry"), this);
|
||
undo_ = undo_stack_ -> createUndoAction(this);
|
||
redo_ = undo_stack_ -> createRedoAction(this);
|
||
cut_ = new QAction(QET::Icons::EditCut, tr("Cu&t", "menu entry"), this);
|
||
copy_ = new QAction(QET::Icons::EditCopy, tr("&Copy", "menu entry"), this);
|
||
paste_ = new QAction(QET::Icons::EditPaste, tr("&Paste", "menu entry"), this);
|
||
edit_logos_ = new QAction(QET::Icons::InsertImage, tr("Manage logos", "menu entry"), this);
|
||
edit_info_ = new QAction(QET::Icons::UserInformations, tr("Edit extra information", "menu entry"), this);
|
||
zoom_in_ = new QAction(QET::Icons::ZoomIn, tr("Zoom In", "menu entry"), this);
|
||
zoom_out_ = new QAction(QET::Icons::ZoomOut, tr("Zoom out", "menu entry"), this);
|
||
zoom_fit_ = new QAction(QET::Icons::ZoomFitBest, tr("Fit in view", "menu entry"), this);
|
||
zoom_reset_ = new QAction(QET::Icons::ZoomOriginal, tr("Reset zoom", "menu entry"), this);
|
||
add_row_ = new QAction(QET::Icons::EditTableInsertRowAbove, tr("Add a &row", "menu entry"), this);
|
||
add_col_ = new QAction(QET::Icons::EditTableInsertColumnRight, tr("Add a &column", "menu entry"), this);
|
||
merge_cells_ = new QAction(QET::Icons::EditTableCellMerge, tr("&Merge cells", "menu entry"), this);
|
||
split_cell_ = new QAction(QET::Icons::EditTableCellSplit, tr("&Split cells", "menu entry"), this);
|
||
|
||
undo_ -> setIcon(QET::Icons::EditUndo);
|
||
redo_ -> setIcon(QET::Icons::EditRedo);
|
||
|
||
ShortcutManager::instance().registerAction(new_, "titleblockeditor.new", tr("Title block template editors"), QKeySequence::New);
|
||
ShortcutManager::instance().registerAction(open_, "titleblockeditor.open", tr("Title block template editors"), QKeySequence::Open);
|
||
ShortcutManager::instance().registerAction(open_from_file_, "titleblockeditor.open_from_file", tr("Title block template editors"), Qt::CTRL | Qt::SHIFT | Qt::Key_O);
|
||
ShortcutManager::instance().registerAction(save_, "titleblockeditor.save", tr("Title block template editors"), QKeySequence::Save);
|
||
ShortcutManager::instance().registerAction(save_as_file_, "titleblockeditor.save_as_file", tr("Title block template editors"), Qt::CTRL | Qt::SHIFT | Qt::Key_S);
|
||
ShortcutManager::instance().registerAction(quit_, "titleblockeditor.quit", tr("Title block template editors"), Qt::CTRL | Qt::Key_Q);
|
||
ShortcutManager::instance().registerAction(undo_, "titleblockeditor.undo", tr("Title block template editors"), QKeySequence::Undo);
|
||
ShortcutManager::instance().registerAction(redo_, "titleblockeditor.redo", tr("Title block template editors"), QKeySequence::Redo);
|
||
ShortcutManager::instance().registerAction(cut_, "titleblockeditor.cut", tr("Title block template editors"), QKeySequence::Cut);
|
||
ShortcutManager::instance().registerAction(copy_, "titleblockeditor.copy", tr("Title block template editors"), QKeySequence::Copy);
|
||
ShortcutManager::instance().registerAction(paste_, "titleblockeditor.paste", tr("Title block template editors"), QKeySequence::Paste);
|
||
ShortcutManager::instance().registerAction(edit_logos_, "titleblockeditor.edit_logos", tr("Title block template editors"), Qt::CTRL | Qt::Key_T);
|
||
ShortcutManager::instance().registerAction(edit_info_, "titleblockeditor.edit_info", tr("Title block template editors"), Qt::CTRL | Qt::Key_Y);
|
||
ShortcutManager::instance().registerAction(merge_cells_, "titleblockeditor.merge_cells", tr("Title block template editors"), Qt::CTRL | Qt::Key_J);
|
||
ShortcutManager::instance().registerAction(split_cell_, "titleblockeditor.split_cell", tr("Title block template editors"), Qt::CTRL | Qt::Key_K);
|
||
ShortcutManager::instance().registerAction(zoom_in_, "titleblockeditor.zoom_in", tr("Title block template editors"), QKeySequence::ZoomIn);
|
||
ShortcutManager::instance().registerAction(zoom_out_, "titleblockeditor.zoom_out", tr("Title block template editors"), QKeySequence::ZoomOut);
|
||
ShortcutManager::instance().registerAction(zoom_fit_, "titleblockeditor.zoom_fit", tr("Title block template editors"), Qt::CTRL | Qt::Key_9);
|
||
ShortcutManager::instance().registerAction(zoom_reset_, "titleblockeditor.zoom_reset", tr("Title block template editors"), Qt::CTRL | Qt::Key_0);
|
||
|
||
connect(new_, &QAction::triggered, this, &QETTitleBlockTemplateEditor::newTemplate);
|
||
connect(open_, &QAction::triggered, this, &QETTitleBlockTemplateEditor::open);
|
||
connect(open_from_file_, &QAction::triggered, this, &QETTitleBlockTemplateEditor::openFromFile);
|
||
connect(save_, &QAction::triggered, this, &QETTitleBlockTemplateEditor::save);
|
||
connect(save_as_, &QAction::triggered, this, qOverload<>(&QETTitleBlockTemplateEditor::saveAs));
|
||
connect(save_as_file_, &QAction::triggered, this, &QETTitleBlockTemplateEditor::saveAsFile);
|
||
connect(quit_, &QAction::triggered, this, &QETTitleBlockTemplateEditor::quit);
|
||
connect(cut_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::cut);
|
||
connect(copy_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::copy);
|
||
connect(paste_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::paste);
|
||
connect(zoom_in_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::zoomIn);
|
||
connect(zoom_out_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::zoomOut);
|
||
connect(zoom_fit_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::zoomFit);
|
||
connect(zoom_reset_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::zoomReset);
|
||
connect(edit_logos_, &QAction::triggered, this, &QETTitleBlockTemplateEditor::editLogos);
|
||
connect(edit_info_, &QAction::triggered, this, &QETTitleBlockTemplateEditor::editTemplateInformation);
|
||
connect(add_row_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::addRowAtEnd);
|
||
connect(add_col_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::addColumnAtEnd);
|
||
connect(merge_cells_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::mergeSelectedCells);
|
||
connect(split_cell_, &QAction::triggered, template_edition_area_view_, &TitleBlockTemplateView::splitSelectedCell);
|
||
}
|
||
|
||
/**
|
||
Initialize the various menus.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::initMenus()
|
||
{
|
||
file_menu_ = new QMenu(tr("&File", "menu title"), this);
|
||
edit_menu_ = new QMenu(tr("&Edit", "menu title"), this);
|
||
display_menu_ = new QMenu(tr("Displ&ay", "menu title"), this);
|
||
|
||
file_menu_ -> addAction(new_);
|
||
file_menu_ -> addAction(open_);
|
||
file_menu_ -> addAction(open_from_file_);
|
||
file_menu_ -> addAction(save_);
|
||
file_menu_ -> addAction(save_as_);
|
||
file_menu_ -> addAction(save_as_file_);
|
||
file_menu_ -> addSeparator();
|
||
file_menu_ -> addAction(quit_);
|
||
|
||
edit_menu_ -> addAction(undo_);
|
||
edit_menu_ -> addAction(redo_);
|
||
edit_menu_ -> addSeparator();
|
||
edit_menu_ -> addAction(cut_);
|
||
edit_menu_ -> addAction(copy_);
|
||
edit_menu_ -> addAction(paste_);
|
||
edit_menu_ -> addSeparator();
|
||
edit_menu_ -> addAction(add_row_);
|
||
edit_menu_ -> addAction(add_col_);
|
||
edit_menu_ -> addAction(merge_cells_);
|
||
edit_menu_ -> addAction(split_cell_);
|
||
edit_menu_ -> addSeparator();
|
||
edit_menu_ -> addAction(edit_logos_);
|
||
edit_menu_ -> addAction(edit_info_);
|
||
display_menu_ -> addAction(zoom_in_);
|
||
display_menu_ -> addAction(zoom_out_);
|
||
display_menu_ -> addAction(zoom_fit_);
|
||
display_menu_ -> addAction(zoom_reset_);
|
||
|
||
insertMenu(settings_menu_, file_menu_);
|
||
insertMenu(settings_menu_, edit_menu_);
|
||
insertMenu(settings_menu_, display_menu_);
|
||
}
|
||
|
||
/**
|
||
Initialize toolbars.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::initToolbars()
|
||
{
|
||
QToolBar *main_toolbar = new QToolBar(tr("Tools", "toolbar title"), this);
|
||
main_toolbar -> setObjectName("tbt_main_toolbar");
|
||
main_toolbar -> addAction(new_);
|
||
main_toolbar -> addAction(open_);
|
||
main_toolbar -> addAction(save_);
|
||
main_toolbar -> addAction(save_as_);
|
||
addToolBar(Qt::TopToolBarArea, main_toolbar);
|
||
|
||
QToolBar *edit_toolbar = new QToolBar(tr("Edit", "toolbar title"), this);
|
||
edit_toolbar -> setObjectName("tbt_edit_toolbar");
|
||
edit_toolbar -> addAction(undo_);
|
||
edit_toolbar -> addAction(redo_);
|
||
edit_toolbar -> addSeparator();
|
||
edit_toolbar -> addAction(merge_cells_);
|
||
edit_toolbar -> addAction(split_cell_);
|
||
addToolBar(Qt::TopToolBarArea, edit_toolbar);
|
||
|
||
QToolBar *display_toolbar = new QToolBar(tr("Display", "toolbar title"), this);
|
||
display_toolbar -> setObjectName("tbt_display_toolbar");
|
||
display_toolbar -> addAction(zoom_in_);
|
||
display_toolbar -> addAction(zoom_out_);
|
||
display_toolbar -> addAction(zoom_fit_);
|
||
display_toolbar -> addAction(zoom_reset_);
|
||
addToolBar(Qt::TopToolBarArea, display_toolbar);
|
||
}
|
||
|
||
/**
|
||
Initialize layouts and widgets
|
||
*/
|
||
void QETTitleBlockTemplateEditor::initWidgets()
|
||
{
|
||
QSettings settings;
|
||
|
||
// undo list on the right
|
||
undo_stack_ = new QUndoStack(this);
|
||
undo_view_ = new QUndoView(undo_stack_);
|
||
undo_view_ -> setEmptyLabel(tr("No modification", "label displayed in the undo list when empty"));
|
||
|
||
undo_dock_widget_ = new QDockWidget(tr("Undo", "dock title"));
|
||
undo_dock_widget_ -> setObjectName("tbt_undo_dock");
|
||
undo_dock_widget_ -> setFeatures(
|
||
QDockWidget::DockWidgetClosable
|
||
|QDockWidget::DockWidgetMovable
|
||
|QDockWidget::DockWidgetFloatable);
|
||
undo_dock_widget_ -> setWidget(undo_view_);
|
||
undo_dock_widget_ -> setMinimumWidth(290);
|
||
addDockWidget(Qt::RightDockWidgetArea, undo_dock_widget_);
|
||
|
||
// WYSIWYG editor as central widget
|
||
template_edition_area_scene_ = new QGraphicsScene(this);
|
||
template_edition_area_view_ = new TitleBlockTemplateView(template_edition_area_scene_);
|
||
bool conv_ok;
|
||
int conf_preview_width = settings.value("titleblocktemplateeditor/preview_width", -1).toInt(&conv_ok);
|
||
if (conv_ok && conf_preview_width != -1) {
|
||
template_edition_area_view_ -> setPreviewWidth(conf_preview_width);
|
||
}
|
||
setCentralWidget(template_edition_area_view_);
|
||
|
||
// cell edition widget at the bottom
|
||
template_cell_editor_widget_ = new TitleBlockTemplateCellWidget(tb_template_);
|
||
template_cell_editor_dock_widget_ = new QDockWidget(tr("Cell properties", "dock title"), this);
|
||
template_cell_editor_dock_widget_ -> setObjectName("tbt_celleditor_dock");
|
||
template_cell_editor_dock_widget_ -> setFeatures(
|
||
QDockWidget::DockWidgetClosable
|
||
|QDockWidget::DockWidgetMovable
|
||
|QDockWidget::DockWidgetFloatable);
|
||
template_cell_editor_dock_widget_ -> setWidget(template_cell_editor_widget_);
|
||
template_cell_editor_dock_widget_ -> setMinimumWidth(180);
|
||
template_cell_editor_dock_widget_ -> setMinimumHeight(250);
|
||
addDockWidget(Qt::BottomDockWidgetArea, template_cell_editor_dock_widget_);
|
||
template_cell_editor_widget_ -> setVisible(false);
|
||
|
||
connect(
|
||
template_edition_area_view_,
|
||
&TitleBlockTemplateView::selectedCellsChanged,
|
||
this,
|
||
&QETTitleBlockTemplateEditor::selectedCellsChanged
|
||
);
|
||
connect(
|
||
template_cell_editor_widget_,
|
||
&TitleBlockTemplateCellWidget::logoEditionRequested,
|
||
this,
|
||
&QETTitleBlockTemplateEditor::editLogos
|
||
);
|
||
connect(
|
||
template_cell_editor_widget_,
|
||
&TitleBlockTemplateCellWidget::cellModified,
|
||
this,
|
||
&QETTitleBlockTemplateEditor::pushCellUndoCommand
|
||
);
|
||
connect(
|
||
template_edition_area_view_,
|
||
&TitleBlockTemplateView::gridModificationRequested,
|
||
this,
|
||
&QETTitleBlockTemplateEditor::pushGridUndoCommand
|
||
);
|
||
connect(
|
||
template_edition_area_view_,
|
||
&TitleBlockTemplateView::previewWidthChanged,
|
||
this,
|
||
&QETTitleBlockTemplateEditor::savePreviewWidthToApplicationSettings
|
||
);
|
||
connect(undo_stack_, &QUndoStack::cleanChanged, this, &QETTitleBlockTemplateEditor::updateEditorTitle);
|
||
connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &QETTitleBlockTemplateEditor::updateActions);
|
||
}
|
||
|
||
/**
|
||
Initialize the logo manager
|
||
*/
|
||
void QETTitleBlockTemplateEditor::initLogoManager()
|
||
{
|
||
logo_manager_ = new TitleBlockTemplateLogoManager(tb_template_, this);
|
||
logo_manager_ -> setReadOnly(read_only_);
|
||
connect(
|
||
logo_manager_,
|
||
&TitleBlockTemplateLogoManager::logosChanged,
|
||
template_cell_editor_widget_,
|
||
&TitleBlockTemplateCellWidget::updateLogosComboBox
|
||
);
|
||
}
|
||
|
||
/**
|
||
@return a string describing what is being edited, along with [Changed] or
|
||
[Read only] tags. Useful to compose the window title.
|
||
*/
|
||
QString QETTitleBlockTemplateEditor::currentlyEditedTitle() const
|
||
{
|
||
QString titleblock_title;
|
||
if (opened_from_file_) {
|
||
titleblock_title = filepath_;
|
||
} else {
|
||
titleblock_title = location_.name();
|
||
}
|
||
|
||
// if a (file)name has been added, also add a "[Changed]" tag if needed
|
||
if (!titleblock_title.isEmpty()) {
|
||
QString tag;
|
||
if (!undo_stack_ -> isClean()) {
|
||
tag = tr("[Changed]", "window title tag");
|
||
}
|
||
if (read_only_) {
|
||
tag = tr("[Read only]", "window title tag");
|
||
}
|
||
titleblock_title = QString(
|
||
tr(
|
||
"%1 %2",
|
||
"part of the window title - %1 is the filepath or template name, %2 is the [Changed] or [Read only] tag"
|
||
)
|
||
).arg(titleblock_title).arg(tag);
|
||
}
|
||
|
||
return(titleblock_title);
|
||
}
|
||
|
||
/**
|
||
@brief QETTitleBlockTemplateEditor::readSettings
|
||
Read settings
|
||
*/
|
||
void QETTitleBlockTemplateEditor::readSettings()
|
||
{
|
||
QSettings settings;
|
||
|
||
// window size and position
|
||
QVariant geometry = settings.value("titleblocktemplateeditor/geometry");
|
||
if (geometry.isValid()) restoreGeometry(geometry.toByteArray());
|
||
}
|
||
|
||
/**
|
||
@brief QETTitleBlockTemplateEditor::readSettingsState
|
||
Restore the window state (docks, toolbars).
|
||
Must be called AFTER show() in Qt6 for restoreState() to work correctly
|
||
-- callers are responsible for calling this after show(), since this
|
||
window isn't shown by its own constructor.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::readSettingsState()
|
||
{
|
||
QSettings settings;
|
||
|
||
QVariant state = settings.value("titleblocktemplateeditor/state");
|
||
if (state.isValid()) {
|
||
if (!restoreState(state.toByteArray())) {
|
||
settings.remove("titleblocktemplateeditor/state");
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
@brief QETTitleBlockTemplateEditor::writeSettings
|
||
Write the settings
|
||
*/
|
||
void QETTitleBlockTemplateEditor::writeSettings()
|
||
{
|
||
QSettings settings;
|
||
settings.setValue("titleblocktemplateeditor/geometry", saveGeometry());
|
||
settings.setValue("titleblocktemplateeditor/state", saveState());
|
||
}
|
||
|
||
/**
|
||
Update various things when user changes the selected cells.
|
||
@param selected_cells List of selected cells.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::selectedCellsChanged(
|
||
const QList<TitleBlockCell *>& selected_cells)
|
||
{
|
||
if (selected_cells.count() == 1) {
|
||
template_cell_editor_widget_ -> edit(selected_cells.at(0));
|
||
template_cell_editor_widget_ -> setVisible(true);
|
||
} else {
|
||
template_cell_editor_widget_ -> setVisible(false);
|
||
}
|
||
updateActions();
|
||
}
|
||
|
||
/**
|
||
Configure an undo Command before adding it to the undo stack.
|
||
@param command to be added to the undo stack
|
||
*/
|
||
void QETTitleBlockTemplateEditor::pushCellUndoCommand(
|
||
ModifyTitleBlockCellCommand *command)
|
||
{
|
||
command -> setView(template_edition_area_view_);
|
||
pushUndoCommand(command);
|
||
}
|
||
|
||
/**
|
||
Add an undo Command to the undo stack.
|
||
@param command QUndoCommand to be added to the undo stack
|
||
*/
|
||
void QETTitleBlockTemplateEditor::pushGridUndoCommand(
|
||
TitleBlockTemplateCommand *command)
|
||
{
|
||
pushUndoCommand(command);
|
||
}
|
||
|
||
/**
|
||
Add an undo Command to the undo stack.
|
||
@param command QUndoCommand to be added to the undo stack
|
||
*/
|
||
void QETTitleBlockTemplateEditor::pushUndoCommand(QUndoCommand *command) {
|
||
undo_stack_ -> push(command);
|
||
}
|
||
|
||
/**
|
||
Set the title of this editor.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::updateEditorTitle()
|
||
{
|
||
// base title
|
||
QString min_title(
|
||
tr(
|
||
"QElectroTech - Title block template editor",
|
||
"titleblock template editor: base window title"
|
||
)
|
||
);
|
||
|
||
// get the currently edited template (file)name
|
||
QString titleblock_title = currentlyEditedTitle();
|
||
|
||
// generate the final window title
|
||
QString title;
|
||
if (titleblock_title.isEmpty()) {
|
||
title = min_title;
|
||
} else {
|
||
title = QString(
|
||
tr(
|
||
"%1 - %2",
|
||
"window title: %1 is the base window title, %2 is a template name"
|
||
)
|
||
).arg(min_title).arg(titleblock_title);
|
||
}
|
||
setWindowTitle(title);
|
||
}
|
||
|
||
/**
|
||
Ensure the user interface remains consistent by enabling or disabling
|
||
adequate actions.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::updateActions()
|
||
{
|
||
save_ -> setEnabled(!read_only_);
|
||
|
||
bool can_merge = true;
|
||
bool can_split = true;
|
||
int count = 0;
|
||
if (!read_only_) {
|
||
template_edition_area_view_ -> analyzeSelectedCells(&can_merge, &can_split, &count);
|
||
}
|
||
cut_ -> setEnabled(!read_only_ && count);
|
||
copy_ -> setEnabled(count);
|
||
paste_ -> setEnabled(!read_only_ && count && template_edition_area_view_ -> mayPaste());
|
||
add_row_ -> setEnabled(!read_only_);
|
||
add_col_ -> setEnabled(!read_only_);
|
||
merge_cells_ -> setEnabled(!read_only_ && can_merge);
|
||
split_cell_ -> setEnabled(!read_only_ && can_split);
|
||
}
|
||
|
||
/**
|
||
Save the template under the provided location.
|
||
@see QETProject::setTemplateXmlDescription()
|
||
@param location Location where the title block template should be saved.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::saveAs(const TitleBlockTemplateLocation &location) {
|
||
TitleBlockTemplatesCollection *collection = location.parentCollection();
|
||
if (!collection) return(false);
|
||
|
||
QDomDocument doc;
|
||
QDomElement elmt = doc.createElement("root");
|
||
tb_template_ -> saveToXmlElement(elmt);
|
||
elmt.setAttribute("name", location.name());
|
||
doc.appendChild(elmt);
|
||
|
||
if (!collection -> setTemplateXmlDescription(location.name(), elmt)) {
|
||
// Report the failure instead of marking the template "saved"
|
||
// regardless (bugtracker #251) -- this return value used to
|
||
// be discarded here.
|
||
QET::QetMessageBox::critical(
|
||
this,
|
||
tr("Error", "message box title"),
|
||
tr(
|
||
"Unable to save the template ‘%1’.",
|
||
"message box content - %1 is a title block template name"
|
||
).arg(location.name())
|
||
);
|
||
return(false);
|
||
}
|
||
|
||
opened_from_file_ = false;
|
||
location_ = location;
|
||
undo_stack_ -> setClean();
|
||
setReadOnly(false);
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
Save the template in the provided filepath.
|
||
@see TitleBlockTemplate::saveToXmlFile()
|
||
@param filepath location Location where the title block template should be saved.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::saveAs(const QString &filepath) {
|
||
bool saving = tb_template_ -> saveToXmlFile(filepath);
|
||
if (!saving) return(false);
|
||
|
||
opened_from_file_ = true;
|
||
filepath_ = filepath;
|
||
undo_stack_ -> setClean();
|
||
setReadOnly(false);
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
Ask the user to choose a title block template from the known collections
|
||
then open it for edition.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::open()
|
||
{
|
||
TitleBlockTemplateLocation location = getTitleBlockTemplateLocationFromUser(
|
||
tr("Open a title block template", "File > open dialog window title"),
|
||
true
|
||
);
|
||
if (location.isValid()) {
|
||
QETApp::instance() -> openTitleBlockTemplate(location);
|
||
}
|
||
}
|
||
|
||
/**
|
||
Ask the user to choose a file supposed to contain a title block template,
|
||
then open it for edition.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::openFromFile()
|
||
{
|
||
// directory to show
|
||
QString initial_dir = filepath_.isEmpty()
|
||
? QETApp::customTitleBlockTemplatesDir()
|
||
: QDir(filepath_).absolutePath();
|
||
|
||
// ask the user to choose a filepath
|
||
QString user_filepath = QFileDialog::getOpenFileName(
|
||
this,
|
||
tr("Open a file", "dialog title"),
|
||
initial_dir,
|
||
tr(
|
||
"QElectroTech title block templates "
|
||
"(*%1);;XML files (*.xml);; All files (*)",
|
||
"filetypes allowed when opening a title block template file"
|
||
" - %1 is the .titleblock extension"
|
||
).arg(QString(TITLEBLOCKS_FILE_EXTENSION))
|
||
);
|
||
|
||
|
||
if (!user_filepath.isEmpty()) QETApp::instance() -> openTitleBlockTemplate(user_filepath);
|
||
}
|
||
|
||
/**
|
||
Save the currently edited title block template back to its parent project.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::save()
|
||
{
|
||
if (opened_from_file_) {
|
||
if (!filepath_.isEmpty()) {
|
||
QFileInfo file_path_info(filepath_);
|
||
if (file_path_info.isWritable()) {
|
||
return(saveAs(filepath_));
|
||
}
|
||
}
|
||
return(saveAsFile());
|
||
} else {
|
||
if (location_.isValid()) {
|
||
if (!location_.isReadOnly()) {
|
||
return(saveAs(location_));
|
||
}
|
||
}
|
||
return(saveAs());
|
||
}
|
||
}
|
||
|
||
/**
|
||
Ask the user where he wishes to save the currently edited template.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::saveAs()
|
||
{
|
||
TitleBlockTemplateLocation location = getTitleBlockTemplateLocationFromUser(
|
||
tr("Save template as", "dialog window title"),
|
||
false
|
||
);
|
||
if (location.isValid()) {
|
||
return(saveAs(location));
|
||
}
|
||
if (!location.name().isEmpty()) {
|
||
// The name was rejected (e.g. contains a path separator or
|
||
// other filesystem-reserved character) rather than the user
|
||
// cancelling the dialog -- say so instead of silently doing
|
||
// nothing (bugtracker #251).
|
||
QET::QetMessageBox::critical(
|
||
this,
|
||
tr("Error", "message box title"),
|
||
tr(
|
||
"The name ‘%1’ is invalid: it must not contain the "
|
||
"following characters: \\ / : * ? \" < > |",
|
||
"message box content - %1 is the rejected template name"
|
||
).arg(location.name())
|
||
);
|
||
}
|
||
return(false);
|
||
}
|
||
|
||
/**
|
||
Ask the user where on the filesystem he wishes to save the currently edited template.
|
||
*/
|
||
bool QETTitleBlockTemplateEditor::saveAsFile()
|
||
{
|
||
// directory to show
|
||
QString initial_dir = filepath_.isEmpty()
|
||
? QETApp::customTitleBlockTemplatesDir()
|
||
: QDir(filepath_).absolutePath();
|
||
|
||
// ask the user to choose a target file
|
||
QString filepath = QFileDialog::getSaveFileName(
|
||
this,
|
||
tr("Save as", "dialog title"),
|
||
initial_dir,
|
||
tr(
|
||
"QElectroTech title block templates (*%1)",
|
||
"filetypes allowed when saving a title block template file - %1 is the .titleblock extension"
|
||
).arg(QString(TITLEBLOCKS_FILE_EXTENSION))
|
||
);
|
||
|
||
// if no name was entered, return false
|
||
if (filepath.isEmpty()) return(false);
|
||
|
||
// if the name does not end with ".titleblock", add it
|
||
if (!filepath.endsWith(".titleblock", Qt::CaseInsensitive)) filepath += ".titleblock";
|
||
|
||
// attempts to save the file
|
||
bool saving = saveAs(filepath);
|
||
|
||
// retourne un booleen representatif de la reussite de l'enregistrement
|
||
return(saving);
|
||
}
|
||
|
||
/**
|
||
@param read_only True to restrict this editor to visualization of the
|
||
currently edited template, false to allow full edition.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::setReadOnly(bool read_only) {
|
||
if (read_only != read_only_) {
|
||
read_only_ = read_only;
|
||
if (logo_manager_) {
|
||
logo_manager_ -> setReadOnly(read_only_);
|
||
}
|
||
template_cell_editor_widget_ -> setReadOnly(read_only_);
|
||
template_edition_area_view_ -> setReadOnly(read_only_);
|
||
}
|
||
updateActions();
|
||
updateEditorTitle();
|
||
}
|
||
|
||
/**
|
||
Ask the user for a title block template location
|
||
@param title Title displayed by the dialog window
|
||
@param existing_only True for the user to be forced to choose an existing
|
||
template, false if he may specify the template name
|
||
@return The location chosen by the user, or an empty
|
||
TitleBlockTemplateLocation if the user cancelled the dialog
|
||
*/
|
||
TitleBlockTemplateLocation QETTitleBlockTemplateEditor::getTitleBlockTemplateLocationFromUser(
|
||
const QString &title, bool existing_only)
|
||
{
|
||
TitleBlockTemplateLocationChooser *widget;
|
||
if (existing_only) {
|
||
widget = new TitleBlockTemplateLocationChooser(location());
|
||
} else {
|
||
widget = new TitleBlockTemplateLocationSaver(location());
|
||
}
|
||
QDialogButtonBox *buttons = new QDialogButtonBox(
|
||
QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||
|
||
QVBoxLayout *dialog_layout = new QVBoxLayout();
|
||
dialog_layout -> addWidget(widget);
|
||
dialog_layout -> addWidget(buttons);
|
||
|
||
QDialog dialog;
|
||
dialog.setWindowTitle(title);
|
||
dialog.setLayout(dialog_layout);
|
||
|
||
connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
|
||
connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
||
|
||
if (dialog.exec() == QDialog::Accepted) {
|
||
return(widget -> location());
|
||
}
|
||
return TitleBlockTemplateLocation();
|
||
}
|
||
|
||
/**
|
||
Close the current editor.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::quit()
|
||
{
|
||
close();
|
||
}
|
||
|
||
/**
|
||
@brief QETTitleBlockTemplateEditor::savePreviewWidthToApplicationSettings
|
||
Save the new preview width to application settings
|
||
@param former_preview_width : former_preview_width Unused, former preview width
|
||
@param new_preview_width : new_preview_width New preview width
|
||
*/
|
||
void QETTitleBlockTemplateEditor::savePreviewWidthToApplicationSettings(
|
||
int former_preview_width, int new_preview_width)
|
||
{
|
||
Q_UNUSED(former_preview_width)
|
||
QSettings settings;
|
||
settings.setValue("titleblocktemplateeditor/preview_width", new_preview_width);
|
||
}
|
||
|
||
/**
|
||
Edit extra information attached to the template.
|
||
*/
|
||
void QETTitleBlockTemplateEditor::editTemplateInformation()
|
||
{
|
||
if (!tb_template_) return;
|
||
|
||
QDialog dialog_author(this);
|
||
dialog_author.setModal(true);
|
||
#ifdef Q_OS_MACOS
|
||
dialog_author.setWindowFlags(Qt::Sheet);
|
||
#endif
|
||
dialog_author.setMinimumSize(400, 260);
|
||
dialog_author.setWindowTitle(tr("Edit extra information", "window title"));
|
||
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_author);
|
||
|
||
// explanation label
|
||
QLabel *information_label = new QLabel(tr("You can use this field to specify the authors of this template, its license, or any other information you may find useful."));
|
||
information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
||
information_label -> setWordWrap(true);
|
||
dialog_layout -> addWidget(information_label);
|
||
|
||
// add a QTextEdit to the dialog
|
||
QTextEdit *text_field = new QTextEdit();
|
||
text_field -> setAcceptRichText(false);
|
||
text_field -> setPlainText(tb_template_ -> information());
|
||
text_field -> setReadOnly(read_only_);
|
||
dialog_layout -> addWidget(text_field);
|
||
|
||
// add two buttons to the dialog
|
||
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(
|
||
read_only_
|
||
? QDialogButtonBox::Ok
|
||
: QDialogButtonBox::Ok
|
||
| QDialogButtonBox::Cancel);
|
||
dialog_layout -> addWidget(dialog_buttons);
|
||
connect(dialog_buttons, &QDialogButtonBox::accepted, &dialog_author, &QDialog::accept);
|
||
connect(dialog_buttons, &QDialogButtonBox::rejected, &dialog_author, &QDialog::reject);
|
||
|
||
// run the dialog
|
||
if (dialog_author.exec() == QDialog::Accepted && !read_only_) {
|
||
QString new_info = text_field -> toPlainText().remove(QChar(13)); // CR-less text
|
||
if (new_info != tb_template_ -> information()) {
|
||
pushUndoCommand(new ChangeTemplateInformationsCommand(
|
||
tb_template_,
|
||
tb_template_ -> information(),
|
||
new_info));
|
||
}
|
||
}
|
||
}
|