Merge pull request #448 from ChuckNr11/master

Supplement to pull request #444 by Kellermorph
This commit is contained in:
Laurent Trinques
2026-04-06 05:50:03 +02:00
committed by GitHub
8 changed files with 203 additions and 50 deletions

View File

@@ -67,7 +67,10 @@ ElementsPanel::ElementsPanel(QWidget *parent) :
connect(this, &ElementsPanel::itemDoubleClicked, this, &ElementsPanel::slot_doubleClick); connect(this, &ElementsPanel::itemDoubleClicked, this, &ElementsPanel::slot_doubleClick);
connect(this, &GenericPanel::firstActivated, [this]() {QTimer::singleShot(250, this, SLOT(reload()));}); connect(this, &GenericPanel::firstActivated, [this]() {QTimer::singleShot(250, this, SLOT(reload()));});
connect(this, &ElementsPanel::panelContentChanged, this, &ElementsPanel::panelContentChange); connect(this, &ElementsPanel::panelContentChanged, this, &ElementsPanel::panelContentChange);
// manage signal itemClicked
connect(this, &ElementsPanel::itemClicked, this, &ElementsPanel::slot_clicked);
//Emit a signal instead au manage is own context menu //Emit a signal instead au manage is own context menu
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);
} }
@@ -139,15 +142,26 @@ QTreeWidgetItem *ElementsPanel::addProject(QETProject *project,
Q_UNUSED(options) Q_UNUSED(options)
bool first_add = (first_reload_ || !projects_to_display_.contains(project)); bool first_add = (first_reload_ || !projects_to_display_.contains(project));
clearSelection();
// create the QTreeWidgetItem representing the project // create the QTreeWidgetItem representing the project
QTreeWidgetItem *qtwi_project = GenericPanel::addProject(project, nullptr, GenericPanel::All); QTreeWidgetItem *qtwi_project = GenericPanel::addProject(project, nullptr, GenericPanel::All);
// the project will be inserted right before the common tb templates collection // the project will be inserted right before the common tb templates collection
invisibleRootItem() -> insertChild( invisibleRootItem() -> insertChild(
indexOfTopLevelItem(common_tbt_collection_item_), indexOfTopLevelItem(common_tbt_collection_item_),
qtwi_project qtwi_project
); );
if (first_add) qtwi_project -> setExpanded(true); if (first_add){
qtwi_project -> setExpanded(true);
// on adding an project select first diagram
setCurrentItem(qtwi_project -> child(0));
qtwi_project -> child(0)->setSelected(true);
}
else {
// on adding an diagram to project select the last diagram
setCurrentItem(qtwi_project->child(qtwi_project->childCount()-2));
qtwi_project->child(qtwi_project->childCount()-2)->setSelected(true);
}
if (TitleBlockTemplatesCollection *tbt_collection = project -> embeddedTitleBlockTemplatesCollection()) { if (TitleBlockTemplatesCollection *tbt_collection = project -> embeddedTitleBlockTemplatesCollection()) {
if (QTreeWidgetItem *tbt_collection_qtwi = itemForTemplatesCollection(tbt_collection)) { if (QTreeWidgetItem *tbt_collection_qtwi = itemForTemplatesCollection(tbt_collection)) {
@@ -258,21 +272,28 @@ void ElementsPanel::reload()
} }
/** /**
Gere le double-clic sur un element. @brief ElementsPanel::slot_clicked
Si un double-clic sur un projet est effectue, le signal requestForProject handle click on qtwi
est emis. @param qtwi item that was clickerd on
Si un double-clic sur un schema est effectue, le signal requestForDiagram */
est emis. void ElementsPanel::slot_clicked(QTreeWidgetItem *clickedItem, int) {
requestForItem(clickedItem);
}
/**
@brief ElementsPanel::slot_doubleClick
handle double click on qtwi
@param qtwi @param qtwi
*/ */
void ElementsPanel::slot_doubleClick(QTreeWidgetItem *qtwi, int) { void ElementsPanel::slot_doubleClick(QTreeWidgetItem *qtwi, int) {
int qtwi_type = qtwi -> type(); int qtwi_type = qtwi -> type();
if (qtwi_type == QET::Project) { if (qtwi_type == QET::Project) {
QETProject *project = valueForItem<QETProject *>(qtwi); // open project properties
emit(requestForProject(project)); emit(requestForProjectPropertiesEdition());
} else if (qtwi_type == QET::Diagram) { } else if (qtwi_type == QET::Diagram) {
Diagram *diagram = valueForItem<Diagram *>(qtwi); // open diagram properties
diagram->showMe(); emit(requestForDiagramPropertiesEdition());
} else if (qtwi_type == QET::TitleBlockTemplate) { } else if (qtwi_type == QET::TitleBlockTemplate) {
TitleBlockTemplateLocation tbt = valueForItem<TitleBlockTemplateLocation>(qtwi); TitleBlockTemplateLocation tbt = valueForItem<TitleBlockTemplateLocation>(qtwi);
emit(requestForTitleBlockTemplate(tbt)); emit(requestForTitleBlockTemplate(tbt));
@@ -444,3 +465,64 @@ void ElementsPanel::ensureHierarchyIsVisible(const QList<QTreeWidgetItem *> &ite
if (parent_qtwi -> isHidden()) parent_qtwi -> setHidden(false); if (parent_qtwi -> isHidden()) parent_qtwi -> setHidden(false);
} }
} }
/**
* @brief ElementsPanel::syncTabBars
* set the project- or diagram Tab corresponding to
* the selection in the treeView
*/
void ElementsPanel::requestForItem(QTreeWidgetItem *clickedItem)
{
// activate diagram
if(clickedItem->type() == QET::Diagram){
Diagram *diagram = valueForItem<Diagram *>(clickedItem);
// if we click on diagramItem in annother project we need the other project
emit(requestForProject(projectForItem(clickedItem->parent())));
// required for keyPressEvent
// after emit the focus is on the diagram editor, we put it back to elementsPanel
this->setFocus();
// activate diagram
diagram->showMe();
}
// activate project
else if(clickedItem->type() == QET::Project) {
QETProject *project = projectForItem(clickedItem);
emit(requestForProject(project));
this->setFocus();
}
}
/**
* @brief ElementsPanel::keyPressEvent
* @param event
*/
void ElementsPanel::keyPressEvent(QKeyEvent *event)
{
switch (event->key())
{
case Qt::Key_Up:{
// check if there is another item abbove
if(!itemAbove(currentItem()))
break;
setCurrentItem(itemAbove(currentItem()));
if (currentItem()->type()==QET::Diagram || currentItem()->type()==QET::Project){
requestForItem(currentItem());
}
break;
}
case Qt::Key_Down:{
// check if there is another item below
if(!itemBelow(currentItem()))
break;
setCurrentItem(itemBelow(currentItem()));
if (currentItem()->type()==QET::Diagram || currentItem()->type()==QET::Project){
requestForItem(currentItem());
}
break;
}
default:
QTreeView::keyPressEvent(event);
}
}

View File

@@ -53,8 +53,13 @@ class ElementsPanel : public GenericPanel {
signals: signals:
void requestForProject(QETProject *); void requestForProject(QETProject *);
void requestForTitleBlockTemplate(const TitleBlockTemplateLocation &); void requestForTitleBlockTemplate(const TitleBlockTemplateLocation &);
// Signal to open the project properties
void requestForProjectPropertiesEdition();
// Signal to open the diagram properties
void requestForDiagramPropertiesEdition();
public slots: public slots:
void slot_clicked(QTreeWidgetItem *, int);
void slot_doubleClick(QTreeWidgetItem *, int); void slot_doubleClick(QTreeWidgetItem *, int);
void reload(); void reload();
void filter(const QString &, QET::Filtering = QET::RegularFilter); void filter(const QString &, QET::Filtering = QET::RegularFilter);
@@ -63,7 +68,9 @@ class ElementsPanel : public GenericPanel {
void buildFilterList(); void buildFilterList();
void applyCurrentFilter(const QList<QTreeWidgetItem *> &); void applyCurrentFilter(const QList<QTreeWidgetItem *> &);
void ensureHierarchyIsVisible(const QList<QTreeWidgetItem *> &); void ensureHierarchyIsVisible(const QList<QTreeWidgetItem *> &);
void requestForItem(QTreeWidgetItem *);
void keyPressEvent(QKeyEvent *event)override;
protected: protected:
void startDrag(Qt::DropActions) override; void startDrag(Qt::DropActions) override;
void startTitleBlockTemplateDrag(const TitleBlockTemplateLocation &); void startTitleBlockTemplateDrag(const TitleBlockTemplateLocation &);

View File

@@ -120,6 +120,12 @@ ElementsPanelWidget::ElementsPanelWidget(QWidget *parent) : QWidget(parent) {
SLOT(openTitleBlockTemplate(const TitleBlockTemplateLocation &)) SLOT(openTitleBlockTemplate(const TitleBlockTemplateLocation &))
); );
// manage double click on TreeWidgetItem
connect(elements_panel, SIGNAL(requestForProjectPropertiesEdition()), this, SLOT(editProjectProperties()) );
connect(elements_panel, SIGNAL(requestForDiagramPropertiesEdition()), this, SLOT(editDiagramProperties()) );
// manage project activation
connect(elements_panel, SIGNAL(requestForProject(QETProject*)), this, SIGNAL(requestForProject(QETProject*)));
// disposition verticale // disposition verticale
QVBoxLayout *vlayout = new QVBoxLayout(this); QVBoxLayout *vlayout = new QVBoxLayout(this);
vlayout -> setContentsMargins(0,0,0,0); vlayout -> setContentsMargins(0,0,0,0);
@@ -236,6 +242,7 @@ void ElementsPanelWidget::deleteDiagram()
{ {
if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
emit(requestForDiagramDeletion(selected_diagram)); emit(requestForDiagramDeletion(selected_diagram));
elements_panel->reload();
} }
} }

View File

@@ -766,7 +766,6 @@ void GenericPanel::projectDiagramsOrderChanged(QETProject *project,
if (!moved_qtwi_diagram) return; if (!moved_qtwi_diagram) return;
// remove the QTWI then insert it back at the adequate location // remove the QTWI then insert it back at the adequate location
bool was_selected = moved_qtwi_diagram -> isSelected();
qtwi_project -> removeChild (moved_qtwi_diagram); qtwi_project -> removeChild (moved_qtwi_diagram);
qtwi_project -> insertChild (to, moved_qtwi_diagram); qtwi_project -> insertChild (to, moved_qtwi_diagram);
@@ -781,8 +780,8 @@ void GenericPanel::projectDiagramsOrderChanged(QETProject *project,
updateDiagramItem(qtwi_diagram, diagram); updateDiagramItem(qtwi_diagram, diagram);
} }
if (was_selected) // select the moved diagram
setCurrentItem(moved_qtwi_diagram); setCurrentItem(qtwi_project -> child(from));
emit(panelContentChanged()); emit(panelContentChanged());
} }

View File

@@ -721,6 +721,14 @@ void ProjectView::initActions()
m_end_view = new QAction(QET::Icons::ArrowRightDouble, tr("Aller à la fin du projet"),this); m_end_view = new QAction(QET::Icons::ArrowRightDouble, tr("Aller à la fin du projet"),this);
connect(m_end_view, &QAction::triggered, [this](){this->m_tab->setCurrentWidget(lastDiagram());}); connect(m_end_view, &QAction::triggered, [this](){this->m_tab->setCurrentWidget(lastDiagram());});
// button to scroll one page left
m_next_view_left = new QAction(QET::Icons::ArrowLeft, tr("go one page left"),this);
connect(m_next_view_left, &QAction::triggered, [this](){this->m_tab->setCurrentWidget(previousDiagram());});
// button to scroll one page right
m_next_view_right = new QAction(QET::Icons::ArrowRight, tr("go one page right"),this);
connect(m_next_view_right, &QAction::triggered, [this](){this->m_tab->setCurrentWidget(nextDiagram());});
} }
/** /**
@@ -748,34 +756,65 @@ void ProjectView::initWidgets()
m_tab = new QTabWidget(this); m_tab = new QTabWidget(this);
#endif #endif
m_tab -> setMovable(true); m_tab -> setMovable(true);
// setting UsesScrollButton ensures that when the tab bar is full, the tabs are scrolled.
m_tab -> setUsesScrollButtons(true);
// disable the internal scroll buttons of the TabWidget, we will use our own buttons.
m_tab->setStyleSheet("QTabBar QToolButton {border-image: ;border-width: 0px}");
m_tab->setStyleSheet("QTabBar::scroller {width: 0px;}");
// add layouts
QHBoxLayout *TopRightCorner_Layout = new QHBoxLayout(); QHBoxLayout *TopRightCorner_Layout = new QHBoxLayout();
TopRightCorner_Layout->setContentsMargins(0,0,0,0); TopRightCorner_Layout->setContentsMargins(0,0,0,0);
// some place left to the 'next_right_view_button' button
TopRightCorner_Layout->insertSpacing(1,10);
QToolButton *add_new_diagram_button = new QToolButton; QHBoxLayout *TopLeftCorner_Layout = new QHBoxLayout();
add_new_diagram_button -> setDefaultAction(m_add_new_diagram); TopLeftCorner_Layout->setContentsMargins(0,0,0,0);
add_new_diagram_button -> setAutoRaise(true);
TopRightCorner_Layout->addWidget(add_new_diagram_button); // add buttons
QToolButton *m_next_right_view_button =new QToolButton;
m_next_right_view_button->setDefaultAction(m_next_view_right);
m_next_right_view_button->setAutoRaise(true);
TopRightCorner_Layout->addWidget(m_next_right_view_button);
connect(m_tab, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
connect(m_tab, SIGNAL(tabBarDoubleClicked(int)), this, SLOT(tabDoubleClicked(int)));
connect(m_tab->tabBar(), SIGNAL(tabMoved(int, int)), this, SLOT(tabMoved(int, int)), Qt::QueuedConnection);
//arrows button to return on first view
QToolButton *m_first_view_button =new QToolButton;
m_first_view_button->setDefaultAction(m_first_view);
m_first_view_button->setAutoRaise(true);
m_tab->setCornerWidget(m_first_view_button, Qt::TopLeftCorner);
//arrows button to go on last view
QToolButton *m_end_view_button =new QToolButton; QToolButton *m_end_view_button =new QToolButton;
m_end_view_button->setDefaultAction(m_end_view); m_end_view_button->setDefaultAction(m_end_view);
m_end_view_button->setAutoRaise(true); m_end_view_button->setAutoRaise(true);
TopRightCorner_Layout->addWidget(m_end_view_button); TopRightCorner_Layout->addWidget(m_end_view_button);
QWidget *tabwidget=new QWidget(this); QToolButton *add_new_diagram_button = new QToolButton;
tabwidget->setLayout(TopRightCorner_Layout); add_new_diagram_button -> setDefaultAction(m_add_new_diagram);
m_tab -> setCornerWidget(tabwidget, Qt::TopRightCorner); add_new_diagram_button -> setAutoRaise(true);
TopRightCorner_Layout->addWidget(add_new_diagram_button);
// some place right to the 'add_new_diagram_button' button
TopRightCorner_Layout->addSpacing(5);
QToolButton *m_first_view_button =new QToolButton;
m_first_view_button->setDefaultAction(m_first_view);
m_first_view_button->setAutoRaise(true);
TopLeftCorner_Layout->addWidget(m_first_view_button);
QToolButton *m_next_left_view_button =new QToolButton;
m_next_left_view_button->setDefaultAction(m_next_view_left);
m_next_left_view_button->setAutoRaise(true);
TopLeftCorner_Layout->addWidget(m_next_left_view_button);
// some place right to the 'first_view_button' button
TopLeftCorner_Layout->addSpacing(10);
// add widgets to tabbar
QWidget *tabwidgetRight=new QWidget(this);
tabwidgetRight->setLayout(TopRightCorner_Layout);
m_tab -> setCornerWidget(tabwidgetRight, Qt::TopRightCorner);
QWidget *tabwidgetLeft=new QWidget(this);
tabwidgetLeft->setLayout(TopLeftCorner_Layout);
m_tab -> setCornerWidget(tabwidgetLeft, Qt::TopLeftCorner);
// manage signals
connect(m_tab, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
connect(m_tab, SIGNAL(tabBarDoubleClicked(int)), this, SLOT(tabDoubleClicked(int)));
connect(m_tab->tabBar(), SIGNAL(tabMoved(int,int)), this, SLOT(tabMoved(int,int)), Qt::QueuedConnection);
fallback_widget_ -> setVisible(false); fallback_widget_ -> setVisible(false);
m_tab -> setVisible(false); m_tab -> setVisible(false);

View File

@@ -168,8 +168,10 @@ class ProjectView : public QWidget
// attributes // attributes
private: private:
QAction *m_add_new_diagram, QAction *m_add_new_diagram,
*m_first_view, *m_first_view,
*m_end_view; *m_end_view,
*m_next_view_left,
*m_next_view_right;
QETProject *m_project; QETProject *m_project;
QVBoxLayout *layout_; QVBoxLayout *layout_;
QWidget *fallback_widget_; QWidget *fallback_widget_;

View File

@@ -1180,18 +1180,6 @@ bool QETDiagramEditor::addProject(QETProject *project, bool update_panel)
// cree un ProjectView pour visualiser le projet // cree un ProjectView pour visualiser le projet
ProjectView *project_view = new ProjectView(project); ProjectView *project_view = new ProjectView(project);
//Highlight the current page
connect(project_view, &ProjectView::diagramActivated, this, [this](DiagramView *dv) {
if (dv && dv->diagram() && pa) {
// 1. Find the item in the tree that corresponds to this diagram
QTreeWidgetItem *item = pa->elementsPanel().getItemForDiagram(dv->diagram());
// 2. If you find it, select it
if (item) {
pa->elementsPanel().setCurrentItem(item);
}
}
});
addProjectView(project_view); addProjectView(project_view);
undo_group.addStack(project -> undoStack()); undo_group.addStack(project -> undoStack());
@@ -1853,6 +1841,31 @@ void QETDiagramEditor::addProjectView(ProjectView *project_view)
connect(project_view, SIGNAL(errorEncountered(QString)), connect(project_view, SIGNAL(errorEncountered(QString)),
this, SLOT(showError(const QString &))); this, SLOT(showError(const QString &)));
//Highlight the current page
connect(project_view, &ProjectView::diagramActivated, this, [this](DiagramView *dv) {
if (dv && dv->diagram() && pa) {
// 1. Find the item in the tree that corresponds to this diagram
QTreeWidgetItem *item = pa->elementsPanel().getItemForDiagram(dv->diagram());
// 2. If you find it, select it
if (item) {
pa->elementsPanel().setCurrentItem(item);
}
}
});
//Highlight the current page in projectView on project activation
connect(this, &QETDiagramEditor::syncElementsPanel, this, [this]() {
if (pa && currentDiagramView()) {
// In the tree, find the element that corresponds to the diagram of the selected project.
QTreeWidgetItem *item = pa->elementsPanel().getItemForDiagram(currentDiagramView()->diagram());
if (item) {
// select the diagram
pa->elementsPanel().setCurrentItem(item);
}
}
});
//We maximise the new window if the current window is inexistent or maximized //We maximise the new window if the current window is inexistent or maximized
QWidget *current_window = m_workspace.activeSubWindow(); QWidget *current_window = m_workspace.activeSubWindow();
bool maximise = ((!current_window) bool maximise = ((!current_window)
@@ -2361,6 +2374,7 @@ void QETDiagramEditor::subWindowActivated(QMdiSubWindow *subWindows)
slot_updateActions(); slot_updateActions();
slot_updateWindowsMenu(); slot_updateWindowsMenu();
emit syncElementsPanel();
} }
/** /**

View File

@@ -98,6 +98,9 @@ class QETDiagramEditor : public QETMainWindow
ProjectView *findProject(const QString &) const; ProjectView *findProject(const QString &) const;
QMdiSubWindow *subWindowForWidget(QWidget *) const; QMdiSubWindow *subWindowForWidget(QWidget *) const;
signals:
void syncElementsPanel();
public slots: public slots:
void save(); void save();
void saveAs(); void saveAs();