qelectrotech-source-mirror/sources/ui/masterpropertieswidget.cpp

478 lines
13 KiB
C++
Raw Normal View History

/*
2023-01-01 17:05:57 +01:00
Copyright 2006-2023 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 "masterpropertieswidget.h"
2020-12-09 15:28:43 +01:00
#include "../diagram.h"
#include "../diagramposition.h"
#include "../elementprovider.h"
2020-12-10 21:19:45 +01:00
#include "../qetgraphicsitem/element.h"
#include "../undocommand/linkelementcommand.h"
#include "ui_masterpropertieswidget.h"
2020-12-09 15:28:43 +01:00
#include <QListWidgetItem>
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::MasterPropertiesWidget
Default constructor
@param elmt
@param parent
*/
MasterPropertiesWidget::MasterPropertiesWidget(Element *elmt, QWidget *parent) :
AbstractElementPropertiesEditorWidget(parent),
ui(new Ui::MasterPropertiesWidget),
m_project(nullptr)
{
ui->setupUi(this);
ui->m_free_tree_widget->setContextMenuPolicy(Qt::CustomContextMenu);
ui->m_link_tree_widget->setContextMenuPolicy(Qt::CustomContextMenu);
QStringList list;
QSettings settings;
if (settings.value("genericpanel/folio", false).toBool()) {
2020-07-19 13:58:34 +02:00
list << tr("Vignette")
<< tr("Label de folio")
<< tr("Titre de folio")
<< tr("Position");
}
else {
2020-07-19 13:58:34 +02:00
list << tr("Vignette")
<< tr("N° de folio")
<< tr("Titre de folio")
<< tr("Position");
}
ui->m_free_tree_widget->setHeaderLabels(list);
ui->m_link_tree_widget->setHeaderLabels(list);
m_context_menu = new QMenu(this);
m_link_action = new QAction(tr("Lier l'élément"), this);
m_unlink_action = new QAction(tr("Délier l'élément"), this);
m_show_qtwi = new QAction(tr("Montrer l'élément"), this);
m_show_element = new QAction(tr("Montrer l'élément maître"), this);
m_save_header_state = new QAction(tr("Enregistrer la disposition"), this);
2020-07-19 13:58:34 +02:00
connect(ui->m_free_tree_widget, &QTreeWidget::itemDoubleClicked,
this, &MasterPropertiesWidget::showElementFromTWI);
connect(ui->m_link_tree_widget, &QTreeWidget::itemDoubleClicked,
this, &MasterPropertiesWidget::showElementFromTWI);
2020-07-19 13:58:34 +02:00
connect(ui->m_free_tree_widget, &QTreeWidget::customContextMenuRequested,
[this](QPoint point) {this->customContextMenu(point, 1);});
connect(ui->m_link_tree_widget, &QTreeWidget::customContextMenuRequested,
[this](QPoint point) {this->customContextMenu(point, 2);});
2020-07-19 13:58:34 +02:00
connect(m_link_action, &QAction::triggered,
this, &MasterPropertiesWidget::on_link_button_clicked);
connect(m_unlink_action, &QAction::triggered,
this, &MasterPropertiesWidget::on_unlink_button_clicked);
connect(m_show_qtwi, &QAction::triggered,
[this]() {this->showElementFromTWI(this->m_qtwi_at_context_menu,0);});
connect(m_show_element, &QAction::triggered, [this]()
{
this->m_element->diagram()->showMe();
this->m_element->setHighlighted(true);
if(this->m_showed_element)
m_showed_element->setHighlighted(false);
});
QHeaderView *qhv = ui->m_free_tree_widget->header();
qhv->setContextMenuPolicy(Qt::CustomContextMenu);
2020-07-19 13:58:34 +02:00
connect(qhv, &QHeaderView::customContextMenuRequested,
this, &MasterPropertiesWidget::headerCustomContextMenuRequested);
connect(m_save_header_state, &QAction::triggered, [qhv]()
{
QByteArray qba = qhv->saveState();
QSettings settings;
settings.setValue("link-element-widget/master-state", qba);
});
setElement(elmt);
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::~MasterPropertiesWidget
Destructor
*/
MasterPropertiesWidget::~MasterPropertiesWidget()
{
if (m_showed_element)
m_showed_element->setHighlighted(false);
if(m_element)
m_element->setHighlighted(false);
delete ui;
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::setElement
Set the element to be edited
@param element
*/
void MasterPropertiesWidget::setElement(Element *element)
{
if (m_element == element)
return;
if (m_showed_element)
{
m_showed_element->setHighlighted(false);
m_showed_element = nullptr;
}
if (m_element)
m_element->setHighlighted(false);
if (m_project)
2020-07-19 13:58:34 +02:00
disconnect(m_project, SIGNAL(diagramRemoved(QETProject*,Diagram*)),
this, SLOT(diagramWasdeletedFromProject()));
if(Q_LIKELY(element->diagram() && element->diagram()->project()))
{
m_project = element->diagram()->project();
2020-07-19 13:58:34 +02:00
connect(m_project, SIGNAL(diagramRemoved(QETProject*,Diagram*)),
this, SLOT(diagramWasdeletedFromProject()));
}
else
m_project = nullptr;
2020-07-19 13:58:08 +02:00
//Keep up to date this widget when the linked elements of m_element change
if (m_element)
2020-07-19 13:58:34 +02:00
disconnect(m_element.data(), &Element::linkedElementChanged,
this, &MasterPropertiesWidget::updateUi);
m_element = element;
2020-07-19 13:58:34 +02:00
connect(m_element.data(), &Element::linkedElementChanged,
this, &MasterPropertiesWidget::updateUi);
updateUi();
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::apply
If link between edited element and other change,
2020-07-19 13:58:08 +02:00
apply the change with a QUndoCommand (got with method associatedUndo)
pushed to the stack of element project.
Return true if link change, else false
@note is void no Return ???
2020-08-16 11:19:36 +02:00
*/
2020-09-07 22:03:40 +02:00
void MasterPropertiesWidget::apply()
{
if (QUndoCommand *undo = associatedUndo())
m_element -> diagram() -> undoStack().push(undo);
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::reset
Reset current widget, clear eveything and rebuild widget.
2020-07-19 13:58:08 +02:00
*/
void MasterPropertiesWidget::reset()
{
foreach (QTreeWidgetItem *qtwi, m_qtwi_hash.keys())
delete qtwi;
m_qtwi_hash.clear();
updateUi();
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::associatedUndo
If link between the edited element and other change,
return a QUndoCommand with this change.
If no change return nullptr.
@return
*/
QUndoCommand* MasterPropertiesWidget::associatedUndo() const
{
QList <Element *> to_link;
QList <Element *> linked_ = m_element->linkedElements();
for (int i=0; i<ui->m_link_tree_widget->topLevelItemCount(); i++)
to_link << m_qtwi_hash[ui->m_link_tree_widget->topLevelItem(i)];
//The two list contain the same element, there is no change
if (to_link.size() == linked_.size())
{
bool equal = true;
foreach(Element *elmt, to_link)
if (!linked_.contains(elmt))
equal = false;
if(equal)
return nullptr;
}
LinkElementCommand *undo = new LinkElementCommand(m_element);
if (to_link.isEmpty())
undo->unlinkAll();
else
undo->setLink(to_link);
return undo;
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::setLiveEdit
@param live_edit = true : live edit is enable
else false : live edit is disable.
@return always true because live edit is handled by this editor widget
*/
bool MasterPropertiesWidget::setLiveEdit(bool live_edit)
{
m_live_edit = live_edit;
return true;
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::updateUi
Build the interface of the widget
*/
void MasterPropertiesWidget::updateUi()
{
ui->m_free_tree_widget->clear();
ui->m_link_tree_widget->clear();
m_qtwi_hash.clear();
if (Q_UNLIKELY(!m_project))
return;
ElementProvider elmt_prov(m_project);
QSettings settings;
//Build the list of free available element
QList <QTreeWidgetItem *> items_list;
2022-06-13 20:46:22 +02:00
for(const auto &elmt : elmt_prov.freeElement(ElementData::Slave))
{
QTreeWidgetItem *qtwi = new QTreeWidgetItem(ui->m_free_tree_widget);
qtwi->setIcon(0, elmt->pixmap());
if(settings.value("genericpanel/folio", false).toBool())
{
autonum::sequentialNumbers seq;
2020-07-19 13:58:34 +02:00
QString F =autonum::AssignVariables::formulaToLabel(
elmt->diagram()->border_and_titleblock.folio(),
seq,
elmt->diagram(),
elmt);
qtwi->setText(1, F);
}
else
{
2020-07-19 13:58:34 +02:00
qtwi->setText(1, QString::number(
elmt->diagram()->folioIndex()
+ 1));
}
qtwi->setText(2, elmt->diagram()->title());
2020-07-19 13:58:34 +02:00
qtwi->setText(4, elmt->diagram()->convertPosition(
elmt->scenePos()).toString());
items_list.append(qtwi);
m_qtwi_hash.insert(qtwi, elmt);
}
ui->m_free_tree_widget->addTopLevelItems(items_list);
items_list.clear();
//Build the list of already linked element
const QList<Element *> link_list = m_element->linkedElements();
for(Element *elmt : link_list)
{
QTreeWidgetItem *qtwi = new QTreeWidgetItem(ui->m_link_tree_widget);
qtwi->setIcon(0, elmt->pixmap());
if(settings.value("genericpanel/folio", false).toBool())
{
autonum::sequentialNumbers seq;
2020-07-19 13:58:34 +02:00
QString F =autonum::AssignVariables::formulaToLabel(
elmt->diagram()->border_and_titleblock.folio(),
seq,
elmt->diagram(),
elmt);
qtwi->setText(1, F);
}
else
{
2020-07-19 13:58:34 +02:00
qtwi->setText(1, QString::number(
elmt->diagram()->folioIndex()
+ 1));
}
qtwi->setText(2, elmt->diagram()->title());
2020-07-19 13:58:34 +02:00
qtwi->setText(3, elmt->diagram()->convertPosition(
elmt->scenePos()).toString());
items_list.append(qtwi);
m_qtwi_hash.insert(qtwi, elmt);
}
if(items_list.count())
ui->m_link_tree_widget->addTopLevelItems(items_list);
QVariant v = settings.value("link-element-widget/master-state");
if(!v.isNull())
{
ui->m_free_tree_widget->header()->restoreState(v.toByteArray());
ui->m_link_tree_widget->header()->restoreState(v.toByteArray());
}
}
2020-07-19 13:58:08 +02:00
/**
@brief MasterPropertiesWidget::headerCustomContextMenuRequested
@param pos
*/
void MasterPropertiesWidget::headerCustomContextMenuRequested(const QPoint &pos)
{
m_context_menu->clear();
m_context_menu->addAction(m_save_header_state);
m_context_menu->popup(ui->m_free_tree_widget->header()->mapToGlobal(pos));
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::on_link_button_clicked
move current item in the free_list to linked_list
2020-07-19 13:58:08 +02:00
*/
void MasterPropertiesWidget::on_link_button_clicked()
{
//take the current item from free_list and push it to linked_list
QTreeWidgetItem *qtwi = ui->m_free_tree_widget->currentItem();
if (qtwi)
{
2020-07-19 13:58:34 +02:00
ui->m_free_tree_widget->takeTopLevelItem(
ui->m_free_tree_widget->indexOfTopLevelItem(qtwi));
ui->m_link_tree_widget->insertTopLevelItem(0, qtwi);
if(m_live_edit)
apply();
}
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::on_unlink_button_clicked
move current item in linked_list to free_list
2020-07-19 13:58:08 +02:00
*/
void MasterPropertiesWidget::on_unlink_button_clicked()
{
//take the current item from linked_list and push it to free_list
QTreeWidgetItem *qtwi = ui->m_link_tree_widget->currentItem();
if(qtwi)
{
2020-07-19 13:58:34 +02:00
ui->m_link_tree_widget->takeTopLevelItem(
ui->m_link_tree_widget->indexOfTopLevelItem(qtwi));
ui->m_free_tree_widget->insertTopLevelItem(0, qtwi);
if(m_live_edit)
apply();
}
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::showElementFromTWI
Show the element corresponding to the given QTreeWidgetItem
@param qtwi
@param column
*/
void MasterPropertiesWidget::showElementFromTWI(QTreeWidgetItem *qtwi, int column)
{
Q_UNUSED(column);
if (m_showed_element)
{
2020-07-19 13:58:34 +02:00
disconnect(m_showed_element, SIGNAL(destroyed()),
this, SLOT(showedElementWasDeleted()));
m_showed_element -> setHighlighted(false);
}
if (m_element)
m_element->setHighlighted(false);
m_showed_element = m_qtwi_hash[qtwi];
m_showed_element->diagram()->showMe();
m_showed_element->setHighlighted(true);
2020-07-19 13:58:34 +02:00
connect(m_showed_element, SIGNAL(destroyed()),
this, SLOT(showedElementWasDeleted()));
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::showedElementWasDeleted
Set to nullptr the current showed element when he was deleted
*/
2020-09-07 22:03:40 +02:00
void MasterPropertiesWidget::showedElementWasDeleted()
{
m_showed_element = nullptr;
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::diagramWasdeletedFromProject
This slot is called when a diagram is removed from the parent project
of edited element to update the content of this widget
*/
void MasterPropertiesWidget::diagramWasdeletedFromProject()
{
2020-07-19 13:58:08 +02:00
// We use a timer because if the removed diagram
// contains slave element linked to the edited element
// we must wait for this elements be unlinked,
// or else the linked list provides deleted elements.
QTimer::singleShot(10, this, SLOT(updateUi()));
}
/**
2020-07-19 13:58:08 +02:00
@brief MasterPropertiesWidget::customContextMenu
Display a context menu
@param pos
@param i : the tree widget where the context menu was requested.
*/
void MasterPropertiesWidget::customContextMenu(const QPoint &pos, int i)
{
2020-07-19 13:58:08 +02:00
// add the size of the header to display the topleft of the QMenu
// at the position of the mouse.
// See doc about QWidget::customContextMenuRequested
// section related to QAbstractScrollArea
QPoint point = pos;
point.ry()+=ui->m_free_tree_widget->header()->height();
m_context_menu->clear();
if (i == 1)
{
point = ui->m_free_tree_widget->mapToGlobal(point);
//Context at for free tree widget
if (ui->m_free_tree_widget->currentItem())
{
m_qtwi_at_context_menu = ui->m_free_tree_widget->currentItem();
m_context_menu->addAction(m_link_action);
m_context_menu->addAction(m_show_qtwi);
}
}
else
{
point = ui->m_link_tree_widget->mapToGlobal(point);
//context at for link tre widget
if (ui->m_link_tree_widget->currentItem())
{
m_qtwi_at_context_menu = ui->m_link_tree_widget->currentItem();
m_context_menu->addAction(m_unlink_action);
m_context_menu->addAction(m_show_qtwi);
}
}
m_context_menu->addAction(m_show_element);
m_context_menu->popup(point);
}