mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-20 07:14:13 +02:00
Compare commits
5 Commits
fd38f55724
...
265aa44320
| Author | SHA1 | Date | |
|---|---|---|---|
| 265aa44320 | |||
| 395c6f6602 | |||
| 6ed26358e8 | |||
| 3c1c29f6c3 | |||
| cafc5bcf6d |
+55
-15
@@ -1252,30 +1252,70 @@ QList<QAction *> DiagramView::contextMenuActions() const
|
||||
*/
|
||||
void DiagramView::contextMenuEvent(QContextMenuEvent *e)
|
||||
{
|
||||
QGraphicsView::contextMenuEvent(e);
|
||||
if(e->isAccepted())
|
||||
return;
|
||||
QPoint menu_pos = e->pos();
|
||||
QPoint menu_global_pos = e->globalPos();
|
||||
|
||||
//A context menu raised from the keyboard (the Menu key, or
|
||||
//Shift+F10) carries no useful position: Qt does not aim it at the
|
||||
//selection. Two things then went wrong. QGraphicsView handed the
|
||||
//event to whichever item held focus, which answered with its own
|
||||
//generic Undo/Cut/Copy menu and accepted it, so the folio's real
|
||||
//menu was never built; and had it got past that, itemAt() below
|
||||
//would have looked up an unrelated point.
|
||||
//
|
||||
//So a keyboard-raised menu is built here directly rather than being
|
||||
//offered to the items first, and aimed at the selection when there
|
||||
//is one. The keyboard then gets the folio's menu, which is what a
|
||||
//right-click gets.
|
||||
const bool from_keyboard = e->reason() == QContextMenuEvent::Keyboard;
|
||||
|
||||
if (auto qgi = m_diagram->itemAt(mapToScene(e->pos()), transform()))
|
||||
if (from_keyboard)
|
||||
{
|
||||
if (!qgi->isSelected()) {
|
||||
m_diagram->clearSelection();
|
||||
//Aim at the selection when there is one, so the menu appears
|
||||
//beside what it acts on. With nothing selected there is nothing
|
||||
//to aim at, so use the middle of the view -- the folio's own
|
||||
//menu is still the right menu to show.
|
||||
const auto selection = m_diagram->selectedItems();
|
||||
if (!selection.isEmpty())
|
||||
{
|
||||
QRectF selection_rect;
|
||||
for (auto *item : selection) {
|
||||
selection_rect |= item->sceneBoundingRect();
|
||||
}
|
||||
menu_pos = mapFromScene(selection_rect.center());
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_pos = viewport()->rect().center();
|
||||
}
|
||||
menu_global_pos = viewport()->mapToGlobal(menu_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
QGraphicsView::contextMenuEvent(e);
|
||||
if(e->isAccepted())
|
||||
return;
|
||||
|
||||
// At this step qgi can be deleted for example if qgi is a QetGraphicsHandlerItem.
|
||||
// When we call clearSelection the parent item of the handler
|
||||
// is deselected and so delete all handlers, in this case,
|
||||
// qgi become a dangling pointer.
|
||||
// we need to call again itemAt.
|
||||
if (auto item_ = m_diagram->itemAt(mapToScene(e->pos()), transform())) {
|
||||
item_->setSelected(true);
|
||||
if (auto qgi = m_diagram->itemAt(mapToScene(menu_pos), transform()))
|
||||
{
|
||||
if (!qgi->isSelected()) {
|
||||
m_diagram->clearSelection();
|
||||
}
|
||||
|
||||
// At this step qgi can be deleted for example if qgi is a QetGraphicsHandlerItem.
|
||||
// When we call clearSelection the parent item of the handler
|
||||
// is deselected and so delete all handlers, in this case,
|
||||
// qgi become a dangling pointer.
|
||||
// we need to call again itemAt.
|
||||
if (auto item_ = m_diagram->itemAt(mapToScene(menu_pos), transform())) {
|
||||
item_->setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_diagram->selectedItems().isEmpty())
|
||||
{
|
||||
m_paste_here_pos = e->pos();
|
||||
m_paste_here_pos = menu_pos;
|
||||
m_paste_here->setEnabled(Diagram::clipboardMayContainDiagram());
|
||||
}
|
||||
|
||||
@@ -1284,7 +1324,7 @@ void DiagramView::contextMenuEvent(QContextMenuEvent *e)
|
||||
{
|
||||
QMenu *context_menu = new QMenu(this);
|
||||
context_menu->addActions(list);
|
||||
context_menu->popup(e->globalPos());
|
||||
context_menu->popup(menu_global_pos);
|
||||
e->accept();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QCheckBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QGridLayout>
|
||||
@@ -36,6 +37,7 @@
|
||||
#include <QAction>
|
||||
#include <QFont>
|
||||
#include <QTimer>
|
||||
#include <QSettings>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QGridLayout>
|
||||
@@ -56,12 +58,16 @@ PlcLinkWidget::PlcLinkWidget(Element *elmt, QWidget *parent)
|
||||
main_layout->addWidget(m_unlink_pb, 0, 1);
|
||||
main_layout->addWidget(m_show_this_pb, 0, 2);
|
||||
|
||||
// Row 1: Search field
|
||||
// Row 1: Hide linked elements checkbox
|
||||
m_hide_linked_cb = new QCheckBox(tr("Masquer les éléments connectés"), this);
|
||||
main_layout->addWidget(m_hide_linked_cb, 1, 0, 1, 3);
|
||||
|
||||
// Row 2: Search field
|
||||
m_search_field = new QLineEdit(this);
|
||||
m_search_field->setPlaceholderText(tr("Recherche"));
|
||||
main_layout->addWidget(m_search_field, 1, 0, 1, 3);
|
||||
main_layout->addWidget(m_search_field, 2, 0, 1, 3);
|
||||
|
||||
// Row 2: Tree widget
|
||||
// Row 3: Tree widget
|
||||
m_tree_widget = new QTreeWidget(this);
|
||||
m_tree_widget->setHeaderLabels({
|
||||
tr("Label"), tr("Type"), tr("Adresse"),
|
||||
@@ -78,9 +84,9 @@ PlcLinkWidget::PlcLinkWidget(Element *elmt, QWidget *parent)
|
||||
m_tree_widget->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||
m_tree_widget->header()->setSectionResizeMode(4, QHeaderView::ResizeToContents);
|
||||
m_tree_widget->header()->setSectionResizeMode(5, QHeaderView::ResizeToContents);
|
||||
main_layout->addWidget(m_tree_widget, 2, 0, 1, 3);
|
||||
main_layout->addWidget(m_tree_widget, 3, 0, 1, 3);
|
||||
|
||||
// Row 3: Hidden masters note
|
||||
// Row 4: Hidden masters note
|
||||
m_hidden_masters_label = new QLabel(
|
||||
tr("Remarque : les éléments maîtres ayant atteint leur nombre maximal "
|
||||
"d'esclaves sont masqués."), this);
|
||||
@@ -89,9 +95,9 @@ PlcLinkWidget::PlcLinkWidget(Element *elmt, QWidget *parent)
|
||||
italic_font.setItalic(true);
|
||||
m_hidden_masters_label->setFont(italic_font);
|
||||
m_hidden_masters_label->hide();
|
||||
main_layout->addWidget(m_hidden_masters_label, 3, 0, 1, 3);
|
||||
main_layout->addWidget(m_hidden_masters_label, 4, 0, 1, 3);
|
||||
|
||||
main_layout->setRowStretch(2, 1);
|
||||
main_layout->setRowStretch(3, 1);
|
||||
|
||||
setMinimumWidth(500);
|
||||
|
||||
@@ -104,6 +110,12 @@ PlcLinkWidget::PlcLinkWidget(Element *elmt, QWidget *parent)
|
||||
this, &PlcLinkWidget::on_m_search_field_textEdited);
|
||||
connect(m_tree_widget, &QTreeWidget::customContextMenuRequested,
|
||||
this, &PlcLinkWidget::on_m_tree_widget_customContextMenuRequested);
|
||||
connect(m_hide_linked_cb, &QCheckBox::toggled,
|
||||
this, &PlcLinkWidget::on_m_hide_linked_cb_toggled);
|
||||
|
||||
QSettings settings;
|
||||
m_hide_linked_cb->setChecked(
|
||||
settings.value(QStringLiteral("plclinkwidget/hideLinked"), false).toBool());
|
||||
|
||||
if (elmt)
|
||||
setElement(elmt);
|
||||
@@ -163,6 +175,7 @@ void PlcLinkWidget::buildPlcTree()
|
||||
{
|
||||
m_tree_widget->clear();
|
||||
m_io_entry_hash.clear();
|
||||
m_linked_children.clear();
|
||||
|
||||
if (!m_element || !m_element->diagram() || !m_element->diagram()->project())
|
||||
return;
|
||||
@@ -216,6 +229,7 @@ void PlcLinkWidget::buildPlcTree()
|
||||
parent_item->setExpanded(false);
|
||||
|
||||
// Add child items for each IO entry
|
||||
bool all_children_hidden = true;
|
||||
for (int i = 0; i < plc_data.ios.size(); ++i) {
|
||||
const auto &io = plc_data.ios.at(i);
|
||||
auto *child_item = new QTreeWidgetItem(parent_item);
|
||||
@@ -233,36 +247,54 @@ void PlcLinkWidget::buildPlcTree()
|
||||
entry.ioIndex = i;
|
||||
m_io_entry_hash.insert(child_item, entry);
|
||||
|
||||
// If this IO is already linked to a slave, grey it out and strike through
|
||||
// If this IO is already linked to a slave
|
||||
if (used_io_indices.contains(i)) {
|
||||
QFont strike_font = child_item->font(0);
|
||||
strike_font.setStrikeOut(true);
|
||||
child_item->setFont(0, strike_font);
|
||||
child_item->setFont(1, strike_font);
|
||||
child_item->setFont(2, strike_font);
|
||||
child_item->setFont(3, strike_font);
|
||||
child_item->setFont(4, strike_font);
|
||||
child_item->setFont(5, strike_font);
|
||||
m_linked_children.insert(child_item);
|
||||
if (m_hide_linked_cb->isChecked()) {
|
||||
child_item->setHidden(true);
|
||||
} else {
|
||||
all_children_hidden = false;
|
||||
QFont strike_font = child_item->font(0);
|
||||
strike_font.setStrikeOut(true);
|
||||
child_item->setFont(0, strike_font);
|
||||
child_item->setFont(1, strike_font);
|
||||
child_item->setFont(2, strike_font);
|
||||
child_item->setFont(3, strike_font);
|
||||
child_item->setFont(4, strike_font);
|
||||
child_item->setFont(5, strike_font);
|
||||
|
||||
QBrush grey_brush(Qt::gray);
|
||||
for (int col = 0; col < 6; ++col)
|
||||
child_item->setForeground(col, grey_brush);
|
||||
QBrush grey_brush(Qt::gray);
|
||||
for (int col = 0; col < 6; ++col)
|
||||
child_item->setForeground(col, grey_brush);
|
||||
|
||||
// Show which slave is linked
|
||||
for (Element *linked : elmt->linkedElements()) {
|
||||
if (elmt->groupIndexForElement(linked) == i) {
|
||||
child_item->setToolTip(0,
|
||||
tr("Lié à: %1").arg(linked->actualLabel()));
|
||||
break;
|
||||
// Show which slave is linked
|
||||
for (Element *linked : elmt->linkedElements()) {
|
||||
if (elmt->groupIndexForElement(linked) == i) {
|
||||
child_item->setToolTip(0,
|
||||
tr("Lié à: %1").arg(linked->actualLabel()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
child_item->setFlags(child_item->flags() & ~Qt::ItemIsSelectable);
|
||||
child_item->setFlags(child_item->flags() & ~Qt::ItemIsSelectable);
|
||||
}
|
||||
} else {
|
||||
all_children_hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If checkbox is on and every child is linked (hidden), hide the master too
|
||||
if (m_hide_linked_cb->isChecked() && all_children_hidden) {
|
||||
parent_item->setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PlcLinkWidget::isChildLinked(QTreeWidgetItem *child) const
|
||||
{
|
||||
return m_linked_children.contains(child);
|
||||
}
|
||||
|
||||
void PlcLinkWidget::hideButtons()
|
||||
{
|
||||
m_label->hide();
|
||||
@@ -296,15 +328,21 @@ void PlcLinkWidget::on_m_search_field_textEdited(const QString &text)
|
||||
}
|
||||
}
|
||||
}
|
||||
child->setHidden(!match);
|
||||
if (match) any_child_visible = true;
|
||||
bool hidden = m_hide_linked_cb->isChecked() && isChildLinked(child);
|
||||
child->setHidden(!match || hidden);
|
||||
if (match && !hidden) any_child_visible = true;
|
||||
}
|
||||
|
||||
// Also check if parent label matches
|
||||
if (!text.isEmpty() && parent->text(0).contains(text, Qt::CaseInsensitive)) {
|
||||
any_child_visible = true;
|
||||
for (int j = 0; j < parent->childCount(); ++j)
|
||||
parent->child(j)->setHidden(false);
|
||||
for (int j = 0; j < parent->childCount(); ++j) {
|
||||
QTreeWidgetItem *child = parent->child(j);
|
||||
bool hidden = m_hide_linked_cb->isChecked() && isChildLinked(child);
|
||||
if (!hidden) {
|
||||
any_child_visible = true;
|
||||
child->setHidden(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent->setHidden(!any_child_visible);
|
||||
@@ -369,3 +407,10 @@ void PlcLinkWidget::on_m_show_this_pb_clicked()
|
||||
m_element->diagram()->showMe();
|
||||
m_element->setHighlighted(true);
|
||||
}
|
||||
|
||||
void PlcLinkWidget::on_m_hide_linked_cb_toggled(bool checked)
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue(QStringLiteral("plclinkwidget/hideLinked"), checked);
|
||||
buildPlcTree();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ class QTreeWidget;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class QLabel;
|
||||
class QCheckBox;
|
||||
class Element;
|
||||
|
||||
/**
|
||||
@@ -58,17 +59,20 @@ class PlcLinkWidget : public AbstractElementPropertiesEditorWidget
|
||||
void buildPlcTree();
|
||||
void hideButtons();
|
||||
void showButtons();
|
||||
bool isChildLinked(QTreeWidgetItem *child) const;
|
||||
|
||||
private slots:
|
||||
void on_m_search_field_textEdited(const QString &text);
|
||||
void on_m_tree_widget_customContextMenuRequested(const QPoint &pos);
|
||||
void on_m_unlink_pb_clicked();
|
||||
void on_m_show_this_pb_clicked();
|
||||
void on_m_hide_linked_cb_toggled(bool checked);
|
||||
|
||||
private:
|
||||
QLabel *m_label{nullptr};
|
||||
QPushButton *m_unlink_pb{nullptr};
|
||||
QPushButton *m_show_this_pb{nullptr};
|
||||
QCheckBox *m_hide_linked_cb{nullptr};
|
||||
QLineEdit *m_search_field{nullptr};
|
||||
QTreeWidget *m_tree_widget{nullptr};
|
||||
QLabel *m_hidden_masters_label{nullptr};
|
||||
@@ -79,6 +83,7 @@ class PlcLinkWidget : public AbstractElementPropertiesEditorWidget
|
||||
int ioIndex = -1;
|
||||
};
|
||||
QHash<QTreeWidgetItem*, PlcIoEntry> m_io_entry_hash;
|
||||
QSet<QTreeWidgetItem*> m_linked_children;
|
||||
|
||||
Element *m_element_to_link = nullptr;
|
||||
int m_pending_io_index = -1;
|
||||
|
||||
Reference in New Issue
Block a user