diff --git a/sources/elementspanel.cpp b/sources/elementspanel.cpp index 079f17f1d..2ce21f83e 100644 --- a/sources/elementspanel.cpp +++ b/sources/elementspanel.cpp @@ -67,7 +67,10 @@ ElementsPanel::ElementsPanel(QWidget *parent) : connect(this, &ElementsPanel::itemDoubleClicked, this, &ElementsPanel::slot_doubleClick); connect(this, &GenericPanel::firstActivated, [this]() {QTimer::singleShot(250, this, SLOT(reload()));}); 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 setContextMenuPolicy(Qt::CustomContextMenu); } @@ -139,15 +142,26 @@ QTreeWidgetItem *ElementsPanel::addProject(QETProject *project, Q_UNUSED(options) 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); - // 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( indexOfTopLevelItem(common_tbt_collection_item_), 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 (QTreeWidgetItem *tbt_collection_qtwi = itemForTemplatesCollection(tbt_collection)) { @@ -258,21 +272,28 @@ void ElementsPanel::reload() } /** - Gere le double-clic sur un element. - Si un double-clic sur un projet est effectue, le signal requestForProject - est emis. - Si un double-clic sur un schema est effectue, le signal requestForDiagram - est emis. + @brief ElementsPanel::slot_clicked + handle click on qtwi + @param qtwi item that was clickerd on +*/ +void ElementsPanel::slot_clicked(QTreeWidgetItem *clickedItem, int) { + + requestForItem(clickedItem); +} + +/** + @brief ElementsPanel::slot_doubleClick + handle double click on qtwi @param qtwi */ void ElementsPanel::slot_doubleClick(QTreeWidgetItem *qtwi, int) { int qtwi_type = qtwi -> type(); if (qtwi_type == QET::Project) { - QETProject *project = valueForItem(qtwi); - emit(requestForProject(project)); + // open project properties + emit(requestForProjectPropertiesEdition()); } else if (qtwi_type == QET::Diagram) { - Diagram *diagram = valueForItem(qtwi); - diagram->showMe(); + // open diagram properties + emit(requestForDiagramPropertiesEdition()); } else if (qtwi_type == QET::TitleBlockTemplate) { TitleBlockTemplateLocation tbt = valueForItem(qtwi); emit(requestForTitleBlockTemplate(tbt)); @@ -444,3 +465,64 @@ void ElementsPanel::ensureHierarchyIsVisible(const QList &ite 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(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); + } +} diff --git a/sources/elementspanel.h b/sources/elementspanel.h index a82daa160..7aa1143e5 100644 --- a/sources/elementspanel.h +++ b/sources/elementspanel.h @@ -53,8 +53,13 @@ class ElementsPanel : public GenericPanel { signals: void requestForProject(QETProject *); void requestForTitleBlockTemplate(const TitleBlockTemplateLocation &); - + // Signal to open the project properties + void requestForProjectPropertiesEdition(); + // Signal to open the diagram properties + void requestForDiagramPropertiesEdition(); + public slots: + void slot_clicked(QTreeWidgetItem *, int); void slot_doubleClick(QTreeWidgetItem *, int); void reload(); void filter(const QString &, QET::Filtering = QET::RegularFilter); @@ -63,7 +68,9 @@ class ElementsPanel : public GenericPanel { void buildFilterList(); void applyCurrentFilter(const QList &); void ensureHierarchyIsVisible(const QList &); - + void requestForItem(QTreeWidgetItem *); + void keyPressEvent(QKeyEvent *event)override; + protected: void startDrag(Qt::DropActions) override; void startTitleBlockTemplateDrag(const TitleBlockTemplateLocation &); diff --git a/sources/elementspanelwidget.cpp b/sources/elementspanelwidget.cpp index 43b4b6958..89e6b521b 100644 --- a/sources/elementspanelwidget.cpp +++ b/sources/elementspanelwidget.cpp @@ -120,6 +120,12 @@ ElementsPanelWidget::ElementsPanelWidget(QWidget *parent) : QWidget(parent) { 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 QVBoxLayout *vlayout = new QVBoxLayout(this); vlayout -> setContentsMargins(0,0,0,0); @@ -236,6 +242,7 @@ void ElementsPanelWidget::deleteDiagram() { if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { emit(requestForDiagramDeletion(selected_diagram)); + elements_panel->reload(); } } diff --git a/sources/genericpanel.cpp b/sources/genericpanel.cpp index e895d02bd..76c866d34 100644 --- a/sources/genericpanel.cpp +++ b/sources/genericpanel.cpp @@ -766,7 +766,6 @@ void GenericPanel::projectDiagramsOrderChanged(QETProject *project, if (!moved_qtwi_diagram) return; // 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 -> insertChild (to, moved_qtwi_diagram); @@ -781,8 +780,8 @@ void GenericPanel::projectDiagramsOrderChanged(QETProject *project, updateDiagramItem(qtwi_diagram, diagram); } - if (was_selected) - setCurrentItem(moved_qtwi_diagram); + // select the moved diagram + setCurrentItem(qtwi_project -> child(from)); emit(panelContentChanged()); } diff --git a/sources/projectview.cpp b/sources/projectview.cpp index 085d86196..9535dcdf5 100644 --- a/sources/projectview.cpp +++ b/sources/projectview.cpp @@ -721,6 +721,14 @@ void ProjectView::initActions() 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());}); + + // 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); #endif 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(); 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; - add_new_diagram_button -> setDefaultAction(m_add_new_diagram); - add_new_diagram_button -> setAutoRaise(true); - TopRightCorner_Layout->addWidget(add_new_diagram_button); + QHBoxLayout *TopLeftCorner_Layout = new QHBoxLayout(); + TopLeftCorner_Layout->setContentsMargins(0,0,0,0); + + // 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; m_end_view_button->setDefaultAction(m_end_view); m_end_view_button->setAutoRaise(true); TopRightCorner_Layout->addWidget(m_end_view_button); - QWidget *tabwidget=new QWidget(this); - tabwidget->setLayout(TopRightCorner_Layout); - m_tab -> setCornerWidget(tabwidget, Qt::TopRightCorner); + QToolButton *add_new_diagram_button = new QToolButton; + add_new_diagram_button -> setDefaultAction(m_add_new_diagram); + 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); m_tab -> setVisible(false); diff --git a/sources/projectview.h b/sources/projectview.h index 0456a0bd7..7537d2867 100644 --- a/sources/projectview.h +++ b/sources/projectview.h @@ -168,8 +168,10 @@ class ProjectView : public QWidget // attributes private: QAction *m_add_new_diagram, - *m_first_view, - *m_end_view; + *m_first_view, + *m_end_view, + *m_next_view_left, + *m_next_view_right; QETProject *m_project; QVBoxLayout *layout_; QWidget *fallback_widget_; diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 8724fdf25..7785411f1 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -1180,18 +1180,6 @@ bool QETDiagramEditor::addProject(QETProject *project, bool update_panel) // cree un ProjectView pour visualiser le projet 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); undo_group.addStack(project -> undoStack()); @@ -1853,6 +1841,31 @@ void QETDiagramEditor::addProjectView(ProjectView *project_view) connect(project_view, SIGNAL(errorEncountered(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 QWidget *current_window = m_workspace.activeSubWindow(); bool maximise = ((!current_window) @@ -2361,6 +2374,7 @@ void QETDiagramEditor::subWindowActivated(QMdiSubWindow *subWindows) slot_updateActions(); slot_updateWindowsMenu(); + emit syncElementsPanel(); } /** diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h index a0090285a..9fe010dd7 100644 --- a/sources/qetdiagrameditor.h +++ b/sources/qetdiagrameditor.h @@ -98,6 +98,9 @@ class QETDiagramEditor : public QETMainWindow ProjectView *findProject(const QString &) const; QMdiSubWindow *subWindowForWidget(QWidget *) const; + signals: + void syncElementsPanel(); + public slots: void save(); void saveAs();