Simon De Backer c958d54d01 Fix Qt 6 deprecated QDockWidget::AllDockWidgetFeatures
(Deprecated) The dock widget can be closed, moved, and floated.
Since new features might be added in future releases,
the look and behavior of dock widgets might change if you use this flag.
Please specify individual flags instead.
2020-09-21 21:16:05 +02:00

1033 lines
34 KiB
C++

/*
Copyright 2006-2020 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 "qetmessagebox.h"
#include "qeticons.h"
#include "qetapp.h"
#include "qetproject.h"
#include "templatecellwidget.h"
#include "templatecommands.h"
#include "templateview.h"
#include "templatelocationsaver.h"
#include "templatelogomanager.h"
#include "templatecellwidget.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();
readSettings();
}
/**
Destructor
*/
QETTitleBlockTemplateEditor::~QETTitleBlockTemplateEditor()
{}
/**
@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("Enregistrer le modèle en cours ?", "dialog title"),
QString(
tr(
"Voulez-vous enregistrer le modèle %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, SLOT(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("nouveau_modele",
"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("Dupliquer un modèle de cartouche", "input dialog title"),
tr("Pour dupliquer ce modèle, entrez le nom voulu pour sa copie",
"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
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
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) {
/// TODO the file opening failed, warn the user?
return(false);
}
bool editing = edit(tbt);
if (!editing) {
/// 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, SIGNAL(rejected()), &d, SLOT(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();
}
/**
Initialize the various actions.
*/
void QETTitleBlockTemplateEditor::initActions()
{
new_ = new QAction(QET::Icons::DocumentNew, tr("&Nouveau", "menu entry"), this);
open_ = new QAction(QET::Icons::DocumentOpen, tr("&Ouvrir", "menu entry"), this);
open_from_file_ = new QAction(QET::Icons::DocumentOpen, tr("Ouvrir depuis un fichier", "menu entry"), this);
save_ = new QAction(QET::Icons::DocumentSave, tr("&Enregistrer", "menu entry"), this);
save_as_ = new QAction(QET::Icons::DocumentSaveAs, tr("Enregistrer sous", "menu entry"), this);
save_as_file_ = new QAction(QET::Icons::DocumentSaveAs, tr("Enregistrer vers un fichier", "menu entry"), this);
quit_ = new QAction(QET::Icons::ApplicationExit, tr("&Quitter", "menu entry"), this);
undo_ = undo_stack_ -> createUndoAction(this);
redo_ = undo_stack_ -> createRedoAction(this);
cut_ = new QAction(QET::Icons::EditCut, tr("Co&uper", "menu entry"), this);
copy_ = new QAction(QET::Icons::EditCopy, tr("Cop&ier", "menu entry"), this);
paste_ = new QAction(QET::Icons::EditPaste, tr("C&oller", "menu entry"), this);
edit_logos_ = new QAction(QET::Icons::InsertImage, tr("Gérer les logos", "menu entry"), this);
edit_info_ = new QAction(QET::Icons::UserInformations, tr("Éditer les informations complémentaires", "menu entry"), this);
zoom_in_ = new QAction(QET::Icons::ZoomIn, tr("Zoom avant", "menu entry"), this);
zoom_out_ = new QAction(QET::Icons::ZoomOut, tr("Zoom arrière", "menu entry"), this);
zoom_fit_ = new QAction(QET::Icons::ZoomFitBest, tr("Zoom adapté", "menu entry"), this);
zoom_reset_ = new QAction(QET::Icons::ZoomOriginal, tr("Pas de zoom", "menu entry"), this);
add_row_ = new QAction(QET::Icons::EditTableInsertRowAbove, tr("Ajouter une &ligne", "menu entry"), this);
add_col_ = new QAction(QET::Icons::EditTableInsertColumnRight, tr("Ajouter une &colonne", "menu entry"), this);
merge_cells_ = new QAction(QET::Icons::EditTableCellMerge, tr("&Fusionner les cellules", "menu entry"), this);
split_cell_ = new QAction(QET::Icons::EditTableCellSplit, tr("&Séparer les cellules", "menu entry"), this);
undo_ -> setIcon(QET::Icons::EditUndo);
redo_ -> setIcon(QET::Icons::EditRedo);
new_ -> setShortcut(QKeySequence::New);
open_ -> setShortcut(QKeySequence::Open);
open_from_file_ -> setShortcut(tr("Ctrl+Shift+O", "shortcut to open a template from a file"));
save_ -> setShortcut(QKeySequence::Save);
save_as_file_ -> setShortcut(tr("Ctrl+Shift+S", "shortcut to save a template to a file"));
quit_ -> setShortcut(QKeySequence(tr("Ctrl+Q", "shortcut to quit")));
undo_ -> setShortcut(QKeySequence::Undo);
redo_ -> setShortcut(QKeySequence::Redo);
cut_ -> setShortcut(QKeySequence::Cut);
copy_ -> setShortcut(QKeySequence::Copy);
paste_ -> setShortcut(QKeySequence::Paste);
edit_logos_ -> setShortcut(QKeySequence(tr("Ctrl+T", "shortcut to manage embedded logos")));
edit_info_ -> setShortcut(QKeySequence(tr("Ctrl+Y", "shortcut to edit extra information")));
merge_cells_ -> setShortcut(QKeySequence(tr("Ctrl+J", "shortcut to merge cells")));
split_cell_ -> setShortcut(QKeySequence(tr("Ctrl+K", "shortcut to split merged cell")));
zoom_in_ -> setShortcut(QKeySequence::ZoomIn);
zoom_out_ -> setShortcut(QKeySequence::ZoomOut);
zoom_fit_ -> setShortcut(QKeySequence(tr("Ctrl+9", "shortcut to enable fit zoom")));
zoom_reset_ -> setShortcut(QKeySequence(tr("Ctrl+0", "shortcut to reset zoom")));
connect(new_, SIGNAL(triggered()), this, SLOT(newTemplate()));
connect(open_, SIGNAL(triggered()), this, SLOT(open()));
connect(open_from_file_, SIGNAL(triggered()), this, SLOT(openFromFile()));
connect(save_, SIGNAL(triggered()), this, SLOT(save()));
connect(save_as_, SIGNAL(triggered()), this, SLOT(saveAs()));
connect(save_as_file_, SIGNAL(triggered()), this, SLOT(saveAsFile()));
connect(quit_, SIGNAL(triggered()), this, SLOT(quit()));
connect(cut_, SIGNAL(triggered()), template_edition_area_view_, SLOT(cut()));
connect(copy_, SIGNAL(triggered()), template_edition_area_view_, SLOT(copy()));
connect(paste_, SIGNAL(triggered()), template_edition_area_view_, SLOT(paste()));
connect(zoom_in_, SIGNAL(triggered()), template_edition_area_view_, SLOT(zoomIn()));
connect(zoom_out_, SIGNAL(triggered()), template_edition_area_view_, SLOT(zoomOut()));
connect(zoom_fit_, SIGNAL(triggered()), template_edition_area_view_, SLOT(zoomFit()));
connect(zoom_reset_, SIGNAL(triggered()), template_edition_area_view_, SLOT(zoomReset()));
connect(edit_logos_, SIGNAL(triggered()), this, SLOT(editLogos()));
connect(edit_info_, SIGNAL(triggered()), this, SLOT(editTemplateInformation()));
connect(add_row_, SIGNAL(triggered()), template_edition_area_view_, SLOT(addRowAtEnd()));
connect(add_col_, SIGNAL(triggered()), template_edition_area_view_, SLOT(addColumnAtEnd()));
connect(merge_cells_, SIGNAL(triggered()), template_edition_area_view_, SLOT(mergeSelectedCells()));
connect(split_cell_, SIGNAL(triggered()), template_edition_area_view_, SLOT(splitSelectedCell()));
}
/**
Initialize the various menus.
*/
void QETTitleBlockTemplateEditor::initMenus()
{
file_menu_ = new QMenu(tr("&Fichier", "menu title"), this);
edit_menu_ = new QMenu(tr("&Édition", "menu title"), this);
display_menu_ = new QMenu(tr("Afficha&ge", "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_);
}
/**
Initalize toolbars.
*/
void QETTitleBlockTemplateEditor::initToolbars()
{
QToolBar *main_toolbar = new QToolBar(tr("Outils", "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("Édition", "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("Affichage", "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("Aucune modification", "label displayed in the undo list when empty"));
undo_dock_widget_ = new QDockWidget(tr("Annulations", "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("Propriétés de la cellule", "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_,
SIGNAL(selectedCellsChanged(QList<TitleBlockCell *>)),
this,
SLOT(selectedCellsChanged(QList<TitleBlockCell *>))
);
connect(template_cell_editor_widget_, SIGNAL(logoEditionRequested()),
this, SLOT(editLogos()));
connect(
template_cell_editor_widget_,
SIGNAL(cellModified(ModifyTitleBlockCellCommand *)),
this,
SLOT(pushCellUndoCommand(ModifyTitleBlockCellCommand *))
);
connect(
template_edition_area_view_,
SIGNAL(gridModificationRequested(TitleBlockTemplateCommand *)),
this,
SLOT(pushGridUndoCommand(TitleBlockTemplateCommand *))
);
connect(
template_edition_area_view_,
SIGNAL(previewWidthChanged(int,int)),
this,
SLOT(savePreviewWidthToApplicationSettings(int, int))
);
connect(undo_stack_, SIGNAL(cleanChanged(bool)),
this, SLOT(updateEditorTitle()));
connect(QApplication::clipboard(), SIGNAL(dataChanged()),
this, SLOT(updateActions()));
}
/**
Initialize the logo manager
*/
void QETTitleBlockTemplateEditor::initLogoManager()
{
logo_manager_ = new TitleBlockTemplateLogoManager(tb_template_, this);
logo_manager_ -> setReadOnly(read_only_);
connect(
logo_manager_,
SIGNAL(logosChanged(const TitleBlockTemplate *)),
template_cell_editor_widget_,
SLOT(updateLogosComboBox(const TitleBlockTemplate *))
);
}
/**
@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("[Modifié]", "window title tag");
}
if (read_only_) {
tag = tr("[Lecture seule]", "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());
// window state (toolbars, docks...)
QVariant state = settings.value("titleblocktemplateeditor/state");
if (state.isValid()) restoreState(state.toByteArray());
}
/**
@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 - Éditeur de modèle de cartouche",
"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);
collection -> setTemplateXmlDescription(location.name(), elmt);
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("Ouvrir un modèle", "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("Ouvrir un fichier", "dialog title"),
initial_dir,
tr(
"Modèles de cartouches QElectroTech (*%1);;"
"Fichiers XML (*.xml);;"
"Tous les fichiers (*)",
"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("Enregistrer le modèle sous", "dialog window title"),
false
);
if (location.isValid()) {
return(saveAs(location));
}
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("Enregistrer sous", "dialog title"),
initial_dir,
tr(
"Modèles de cartouches QElectroTech (*%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, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(buttons, SIGNAL(rejected()), &dialog, SLOT(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("Éditer les informations complémentaires", "window title"));
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_author);
// explanation label
QLabel *information_label = new QLabel(tr("Vous pouvez utiliser ce champ libre pour mentionner les auteurs du cartouche, sa licence, ou tout autre renseignement que vous jugerez utile."));
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, SIGNAL(accepted()),
&dialog_author, SLOT(accept()));
connect(dialog_buttons, SIGNAL(rejected()),
&dialog_author, SLOT(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));
}
}
}