From 438ce78c4fe8021345c2e75fff33c7b3085424c2 Mon Sep 17 00:00:00 2001 From: blacksun Date: Thu, 30 Jun 2016 09:12:25 +0000 Subject: [PATCH] element collection widget : highlight unused element in a project. the feature "clean project" does not clean unused elements yet git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4561 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- .../elementscollectionmodel.cpp | 26 ++++ .../elementscollectionmodel.h | 13 +- .../elementscollectionwidget.cpp | 15 ++- .../elementscollectionwidget.h | 1 + .../xmlelementcollection.cpp | 98 ++++++++++++-- .../ElementsCollection/xmlelementcollection.h | 24 ++-- sources/projectview.cpp | 120 +++++++++--------- sources/projectview.h | 10 +- sources/qetdiagrameditor.cpp | 2 + sources/qetproject.cpp | 21 ++- sources/qetproject.h | 3 +- 11 files changed, 240 insertions(+), 93 deletions(-) diff --git a/sources/ElementsCollection/elementscollectionmodel.cpp b/sources/ElementsCollection/elementscollectionmodel.cpp index 5b0be8806..10f0b421c 100644 --- a/sources/ElementsCollection/elementscollectionmodel.cpp +++ b/sources/ElementsCollection/elementscollectionmodel.cpp @@ -341,6 +341,32 @@ QList ElementsCollectionModel::project() const return m_project_list; } +/** + * @brief ElementsCollectionModel::highlightUnusedElement + * Highlight every unused element of managed project. + * @See QETProject::unusedElements() + */ +void ElementsCollectionModel::highlightUnusedElement() +{ + QList unused; + + foreach (QETProject *project, m_project_list) + unused.append(project->unusedElements()); + + QBrush brush; + brush.setStyle(Qt::Dense4Pattern); + brush.setColor(Qt::red); + + foreach (ElementsLocation location, unused) { + QModelIndex index = indexFromLocation(location); + if (index.isValid()) { + QStandardItem *qsi = itemFromIndex(index); + if (qsi) + qsi->setBackground(brush); + } + } +} + /** * @brief ElementsCollectionModel::items * @return every ElementCollectionItem owned by this model diff --git a/sources/ElementsCollection/elementscollectionmodel.h b/sources/ElementsCollection/elementscollectionmodel.h index 0f01b1708..e64449cb8 100644 --- a/sources/ElementsCollection/elementscollectionmodel.h +++ b/sources/ElementsCollection/elementscollectionmodel.h @@ -21,14 +21,13 @@ #include #include "elementslocation.h" -template<> -class QList; class XmlProjectElementCollectionItem; -template<> -class QHash; class ElementCollectionItem; -template<> -class QList; +template<> class QList; +template<> class QHash; +template<> class QList; + + class ElementsCollectionModel : public QStandardItemModel { @@ -50,6 +49,8 @@ class ElementsCollectionModel : public QStandardItemModel void addProject(QETProject *project, bool set_data = true); void removeProject(QETProject *project); QList project() const; + void highlightUnusedElement(); + QList items() const; void hideElement(); diff --git a/sources/ElementsCollection/elementscollectionwidget.cpp b/sources/ElementsCollection/elementscollectionwidget.cpp index 7971c54e5..3eda83db1 100644 --- a/sources/ElementsCollection/elementscollectionwidget.cpp +++ b/sources/ElementsCollection/elementscollectionwidget.cpp @@ -76,8 +76,10 @@ void ElementsCollectionWidget::expandFirstItems() * @param project */ void ElementsCollectionWidget::addProject(QETProject *project) { - if (m_model) + if (m_model) { m_model->addProject(project); + m_model->highlightUnusedElement(); + } else m_waiting_project.append(project); } @@ -87,6 +89,16 @@ void ElementsCollectionWidget::removeProject(QETProject *project) { m_model->removeProject(project); } +/** + * @brief ElementsCollectionWidget::highlightUnusedElement + * highlight the unused element + * @See ElementsCollectionModel::highlightUnusedElement() + */ +void ElementsCollectionWidget::highlightUnusedElement() +{ + m_model->highlightUnusedElement(); +} + bool ElementsCollectionWidget::event(QEvent *event) { if (m_first_show && event->type() == QEvent::WindowActivate) { @@ -471,6 +483,7 @@ void ElementsCollectionWidget::reload() m_progress_bar->setValue(futur.progressValue()); } + new_model->highlightUnusedElement(); m_tree_view->setModel(new_model); m_index_at_context_menu = QModelIndex(); m_showed_index = QModelIndex(); diff --git a/sources/ElementsCollection/elementscollectionwidget.h b/sources/ElementsCollection/elementscollectionwidget.h index 3bd79cde2..ad12b5935 100644 --- a/sources/ElementsCollection/elementscollectionwidget.h +++ b/sources/ElementsCollection/elementscollectionwidget.h @@ -50,6 +50,7 @@ class ElementsCollectionWidget : public QWidget void addProject (QETProject *project); void removeProject (QETProject *project); + void highlightUnusedElement(); protected: virtual bool event(QEvent *event); diff --git a/sources/ElementsCollection/xmlelementcollection.cpp b/sources/ElementsCollection/xmlelementcollection.cpp index 90bcd0765..3d2282df7 100644 --- a/sources/ElementsCollection/xmlelementcollection.cpp +++ b/sources/ElementsCollection/xmlelementcollection.cpp @@ -19,6 +19,7 @@ #include "nameslist.h" #include "qetxml.h" #include "elementslocation.h" +#include "qetproject.h" /** * @brief XmlElementCollection::XmlElementCollection @@ -29,10 +30,11 @@ * * * All elements and category are stored as child of XmlElementCollection::directories(const QDomElement &parent_element) +QList XmlElementCollection::directories(const QDomElement &parent_element) const { QList directory_list; QDomNodeList node_list = childs(parent_element); @@ -190,7 +193,7 @@ QList XmlElementCollection::directories(const QDomElement &parent_e * @param parent_element * @return a list of names for every child directories of @parent_element */ -QStringList XmlElementCollection::directoriesNames(const QDomElement &parent_element) +QStringList XmlElementCollection::directoriesNames(const QDomElement &parent_element) const { QList childs = directories(parent_element); QStringList names; @@ -210,7 +213,7 @@ QStringList XmlElementCollection::directoriesNames(const QDomElement &parent_ele * @param parent_element * @return A list of element stored in @parent_element */ -QList XmlElementCollection::elements(const QDomElement &parent_element) +QList XmlElementCollection::elements(const QDomElement &parent_element) const { QList element_list; QDomNodeList node_list = childs(parent_element); @@ -231,7 +234,7 @@ QList XmlElementCollection::elements(const QDomElement &parent_elem * @param parent_element * @return A list of names fr every childs element of @parent_element */ -QStringList XmlElementCollection::elementsNames(const QDomElement &parent_element) +QStringList XmlElementCollection::elementsNames(const QDomElement &parent_element) const { QList childs = elements(parent_element); QStringList names; @@ -252,7 +255,7 @@ QStringList XmlElementCollection::elementsNames(const QDomElement &parent_elemen * @return the QDomElement that represent the element at path @path * or a null QDomElement if not found or doesn't represent an element */ -QDomElement XmlElementCollection::element(const QString &path) +QDomElement XmlElementCollection::element(const QString &path) const { if (!path.endsWith(".elmt")) return QDomElement(); @@ -270,7 +273,7 @@ QDomElement XmlElementCollection::element(const QString &path) * @return the QDomElement that represent the directory at path @path * or a null QDomElement if not found. */ -QDomElement XmlElementCollection::directory(const QString &path) +QDomElement XmlElementCollection::directory(const QString &path) const { QDomElement directory = child(path); @@ -457,7 +460,7 @@ ElementsLocation XmlElementCollection::copy(ElementsLocation &source, ElementsLo * @param path * @return */ -bool XmlElementCollection::exist(const QString &path) +bool XmlElementCollection::exist(const QString &path) const { if (child(path).isNull()) return false; @@ -499,6 +502,75 @@ bool XmlElementCollection::createDir(QString path, QString name, const NamesList return true; } +/** + * @brief XmlElementCollection::elementsLocation + * Return all locations stored in dom_element (element and directory). + * If dom_element is null, return all location owned by this collection + * dom_element must be a child of this collection. + * @param dom_element : dom_element where we must to search location. + * @param childs = if true return all childs location of dom_element, if false, only return the direct childs location of dom_element. + * @return + */ +QList XmlElementCollection::elementsLocation(QDomElement dom_element, bool childs) const +{ + QList location_list; + + if (dom_element.isNull()) + dom_element = m_dom_document.documentElement(); + + if (dom_element.ownerDocument() != m_dom_document) + return location_list; + + //get element childs + QList element_list = elements(dom_element); + + foreach (QDomElement elmt, element_list) { + ElementsLocation location = domToLocation(elmt); + if (location.exist()) + location_list << location; + } + + //get directory childs + QList directory_list = directories(dom_element); + + foreach (QDomElement dir, directory_list) { + ElementsLocation location = domToLocation(dir); + if (location.exist()) + location_list << location; + + if (childs) + location_list.append(elementsLocation(dir, childs)); + } + + return location_list; +} + +/** + * @brief XmlElementCollection::domToLocation + * Return the element location who represent the xml element : dom_element + * dom_element must be owned by this collection + * @param dom_element : the dom_element of this collection that represent an element. + * The tag name of dom_element must be "element" + * @return the element location, location can be null if fail. + */ +ElementsLocation XmlElementCollection::domToLocation(QDomElement dom_element) const +{ + if (dom_element.ownerDocument() == m_dom_document) { + QString path = dom_element.attribute("name"); + + while (!dom_element.parentNode().isNull() && dom_element.parentNode().isElement()) { + dom_element = dom_element.parentNode().toElement(); + + if (dom_element.tagName() == "category") + path.prepend(dom_element.attribute("name") + "/"); + } + + return ElementsLocation(path, m_project); + } + else + return ElementsLocation(); +} + /** * @brief XmlElementCollection::copyDirectory * Copy the directory represented by source to destination. diff --git a/sources/ElementsCollection/xmlelementcollection.h b/sources/ElementsCollection/xmlelementcollection.h index 1c83b1222..1e5494a22 100644 --- a/sources/ElementsCollection/xmlelementcollection.h +++ b/sources/ElementsCollection/xmlelementcollection.h @@ -24,6 +24,7 @@ class QDomElement; class QFile; +class QETProject; /** * @brief The XmlElementCollection class @@ -32,26 +33,30 @@ class QFile; class XmlElementCollection : public QObject { Q_OBJECT + public: - XmlElementCollection (QObject *parent = nullptr); - XmlElementCollection (const QDomElement &dom_element, QObject *parent = nullptr); + XmlElementCollection (QETProject *project); + XmlElementCollection (const QDomElement &dom_element, QETProject *project); QDomElement root() const; QDomElement importCategory() const; QDomNodeList childs(const QDomElement &parent_element) const; QDomElement child(const QDomElement &parent_element, const QString &child_name) const; QDomElement child(const QString &path) const; - QList directories(const QDomElement &parent_element); - QStringList directoriesNames(const QDomElement &parent_element); - QList elements(const QDomElement &parent_element); - QStringList elementsNames(const QDomElement &parent_element); - QDomElement element(const QString &path); - QDomElement directory(const QString &path); + QList directories(const QDomElement &parent_element) const; + QStringList directoriesNames(const QDomElement &parent_element) const; + QList elements(const QDomElement &parent_element) const; + QStringList elementsNames(const QDomElement &parent_element) const; + QDomElement element(const QString &path) const; + QDomElement directory(const QString &path) const; QString addElement (ElementsLocation &location); bool addElementDefinition (const QString &dir_path, const QString &elmt_name, const QDomElement &xml_definition); ElementsLocation copy (ElementsLocation &source, ElementsLocation &destination, QString rename = QString(), bool deep_copy = true); - bool exist (const QString &path); + bool exist (const QString &path) const; bool createDir (QString path, QString name, const NamesList &name_list); + QList elementsLocation (QDomElement dom_element = QDomElement(), bool childs = true) const; + ElementsLocation domToLocation(QDomElement dom_element) const; + private: ElementsLocation copyDirectory(ElementsLocation &source, ElementsLocation &destination, QString rename = QString(), bool deep_copy = true); ElementsLocation copyElement(ElementsLocation &source, ElementsLocation &destination, QString rename = QString()); @@ -78,6 +83,7 @@ class XmlElementCollection : public QObject private: QDomDocument m_dom_document; + QETProject *m_project = nullptr; }; #endif // XMLELEMENTCOLLECTION_H diff --git a/sources/projectview.cpp b/sources/projectview.cpp index b1aecb774..d43932f36 100644 --- a/sources/projectview.cpp +++ b/sources/projectview.cpp @@ -31,7 +31,6 @@ #include "qettemplateeditor.h" #include "diagramfoliolist.h" #include "projectpropertiesdialog.h" -#include /** Constructeur @@ -40,7 +39,7 @@ */ ProjectView::ProjectView(QETProject *project, QWidget *parent) : QWidget(parent), - project_(0) + m_project(0) { initActions(); initWidgets(); @@ -65,7 +64,7 @@ ProjectView::~ProjectView() { @return le projet actuellement visualise par le ProjectView */ QETProject *ProjectView::project() { - return(project_); + return(m_project); } /** @@ -74,12 +73,12 @@ QETProject *ProjectView::project() { @param project projet a visualiser */ void ProjectView::setProject(QETProject *project) { - if (!project_) { - project_ = project; - connect(project_, SIGNAL(projectTitleChanged(QETProject *, const QString &)), this, SLOT(updateWindowTitle())); - connect(project_, SIGNAL(projectModified (QETProject *, bool)), this, SLOT(updateWindowTitle())); - connect(project_, SIGNAL(readOnlyChanged (QETProject *, bool)), this, SLOT(adjustReadOnlyState())); - connect(project_, SIGNAL(addAutoNumDiagram()), this, SLOT(addNewDiagram())); + if (!m_project) { + m_project = project; + connect(m_project, SIGNAL(projectTitleChanged(QETProject *, const QString &)), this, SLOT(updateWindowTitle())); + connect(m_project, SIGNAL(projectModified (QETProject *, bool)), this, SLOT(updateWindowTitle())); + connect(m_project, SIGNAL(readOnlyChanged (QETProject *, bool)), this, SLOT(adjustReadOnlyState())); + connect(m_project, SIGNAL(addAutoNumDiagram()), this, SLOT(addNewDiagram())); adjustReadOnlyState(); loadDiagrams(); } @@ -98,7 +97,7 @@ QList ProjectView::diagrams() const { QList ProjectView::getDiagrams(ProjectSaveOptions options) { QList selection; if ((options & AllDiagrams) == AllDiagrams) { - selection << project_ -> diagrams(); + selection << m_project -> diagrams(); } else { Diagram *current = 0; if (DiagramView *view = currentDiagram()) { @@ -107,7 +106,7 @@ QList ProjectView::getDiagrams(ProjectSaveOptions options) { if (options & CurrentDiagram) { if (current) selection << current; } else if (options & AllDiagramsButCurrent) { - selection = project_ -> diagrams(); + selection = m_project -> diagrams(); selection.removeOne(current); } } @@ -223,7 +222,7 @@ DiagramView *ProjectView::firstDiagram(){ @see tryClosingDiagrams() */ bool ProjectView::tryClosing() { - if (!project_) return(true); + if (!m_project) return(true); // First step: require external editors closing -- users may either cancel // the whole closing process or save (and therefore add) content into this @@ -233,7 +232,7 @@ bool ProjectView::tryClosing() { } // Check how different the current situation is from a brand new, untouched project - if (project_ -> filePath().isEmpty() && !project_ -> projectWasModified()) { + if (m_project -> filePath().isEmpty() && !m_project -> projectWasModified()) { return(true); } @@ -251,15 +250,15 @@ bool ProjectView::tryClosing() { } // Check how different the current situation is from a brand new, untouched project (yes , again) - if (project_ -> filePath().isEmpty() && !project_ -> projectWasModified()) { + if (m_project -> filePath().isEmpty() && !m_project -> projectWasModified()) { return(true); } - if (project_ -> filePath().isEmpty()) { + if (m_project -> filePath().isEmpty()) { QString filepath = askUserForFilePath(); if (filepath.isEmpty()) return(false); // users may cancel the closing } - QETResult result = project_ -> write(); + QETResult result = m_project -> write(); updateWindowTitle(); if (!result.isOk()) emit(errorEncountered(result.errorMessage())); return(result.isOk()); @@ -272,17 +271,17 @@ bool ProjectView::tryClosing() { @return true si tous les editeurs d'element ont pu etre fermes, false sinon */ bool ProjectView::tryClosingElementEditors() { - if (!project_) return(true); + if (!m_project) return(true); /* La QETApp permet d'acceder rapidement aux editeurs d'element editant un element du projet. */ - QList editors = QETApp::elementEditors(project_); + QList editors = QETApp::elementEditors(m_project); foreach(QETElementEditor *editor, editors) { if (!editor -> close()) return(false); } - QList template_editors = QETApp::titleBlockTemplateEditors(project_); + QList template_editors = QETApp::titleBlockTemplateEditors(m_project); foreach(QETTitleBlockTemplateEditor *template_editor, template_editors) { if (!template_editor -> close()) return(false); } @@ -296,7 +295,7 @@ bool ProjectView::tryClosingElementEditors() { * @return the answer of dialog or discard if no change. */ int ProjectView::tryClosingDiagrams() { - if (!project_) return(QMessageBox::Discard); + if (!m_project) return(QMessageBox::Discard); if (!project()->projectOptionsWereModified() && project()->undoStack()->isClean() && @@ -335,7 +334,7 @@ QString ProjectView::askUserForFilePath(bool assign) { QString filepath = QFileDialog::getSaveFileName( this, tr("Enregistrer sous", "dialog title"), - project_ -> currentDir(), + m_project -> currentDir(), tr("Projet QElectroTech (*.qet)", "filetypes allowed when saving a project file") ); @@ -347,7 +346,7 @@ QString ProjectView::askUserForFilePath(bool assign) { if (assign) { // assign the provided filepath to the currently edited project - project_ -> setFilePath(filepath); + m_project -> setFilePath(filepath); } return(filepath); @@ -367,13 +366,13 @@ QETResult ProjectView::noProjectResult() const { * Add new diagram to project view */ void ProjectView::addNewDiagram() { - if (project_ -> isReadOnly()) return; + if (m_project -> isReadOnly()) return; - Diagram *new_diagram = project_ -> addNewDiagram(); + Diagram *new_diagram = m_project -> addNewDiagram(); DiagramView *new_diagram_view = new DiagramView(new_diagram); addDiagram(new_diagram_view); - if (project_ -> diagrams().size() % 58 == 1 && project_ -> getFolioSheetsQuantity() != 0) + if (m_project -> diagrams().size() % 58 == 1 && m_project -> getFolioSheetsQuantity() != 0) addNewDiagramFolioList(); showDiagram(new_diagram_view); } @@ -383,10 +382,10 @@ void ProjectView::addNewDiagram() { * Add new diagram folio list to project */ void ProjectView::addNewDiagramFolioList() { - if (project_ -> isReadOnly()) return; + if (m_project -> isReadOnly()) return; int i = 1; //< Each new diagram is added to the end of the project. //< We use @i to move the folio list at second position in the project - foreach (Diagram *d, project_ -> addNewDiagramFolioList()) { + foreach (Diagram *d, m_project -> addNewDiagramFolioList()) { DiagramView *new_diagram_view = new DiagramView(d); addDiagram(new_diagram_view); showDiagram(new_diagram_view); @@ -435,7 +434,7 @@ void ProjectView::addDiagram(DiagramView *diagram) { */ void ProjectView::removeDiagram(DiagramView *diagram_view) { if (!diagram_view) return; - if (project_ -> isReadOnly()) return; + if (m_project -> isReadOnly()) return; // verifie que le schema est bien present dans le projet if (!diagram_ids_.values().contains(diagram_view)) return; @@ -460,14 +459,14 @@ void ProjectView::removeDiagram(DiagramView *diagram_view) { rebuildDiagramsMap(); // supprime le DiagramView, puis le Diagram - project_ -> removeDiagram(diagram_view -> diagram()); + m_project -> removeDiagram(diagram_view -> diagram()); delete diagram_view; // signale le retrait du schema emit(diagramRemoved(diagram_view)); // rend definitif le retrait du schema - project_ -> write(); + m_project -> write(); } /** @@ -507,8 +506,8 @@ void ProjectView::showDiagram(Diagram *diagram) { configuration dialog. */ void ProjectView::editProjectProperties() { - if (!project_) return; - ProjectPropertiesDialog dialog(project_, parentWidget()); + if (!m_project) return; + ProjectPropertiesDialog dialog(m_project, parentWidget()); dialog.exec(); } @@ -647,14 +646,14 @@ void ProjectView::moveDiagramDownx10(Diagram *diagram) { lancer l'impression de toute ou partie du projet. */ void ProjectView::printProject() { - if (!project_) return; + if (!m_project) return; // transforme le titre du projet en nom utilisable pour le document QString doc_name; - if (!(project_ -> title().isEmpty())) { - doc_name = project_ -> title(); - } else if (!project_ -> filePath().isEmpty()) { - doc_name = QFileInfo(project_ -> filePath()).baseName(); + if (!(m_project -> title().isEmpty())) { + doc_name = m_project -> title(); + } else if (!m_project -> filePath().isEmpty()) { + doc_name = QFileInfo(m_project -> filePath()).baseName(); } doc_name = QET::stringToFileName(doc_name); if (doc_name.isEmpty()) { @@ -662,12 +661,12 @@ void ProjectView::printProject() { } // recupere le dossier contenant le fichier courant - QString dir_path = project_ -> currentDir(); + QString dir_path = m_project -> currentDir(); // determine un chemin pour le pdf / ps QString file_name = QDir::toNativeSeparators(QDir::cleanPath(dir_path + "/" + doc_name)); - DiagramPrintDialog print_dialog(project_, this); + DiagramPrintDialog print_dialog(m_project, this); print_dialog.setDocName(doc_name); print_dialog.setFileName(file_name); print_dialog.exec(); @@ -677,9 +676,9 @@ void ProjectView::printProject() { Exporte le schema. */ void ProjectView::exportProject() { - if (!project_) return; + if (!m_project) return; - ExportDialog ed(project_, parentWidget()); + ExportDialog ed(m_project, parentWidget()); #ifdef Q_OS_MAC ed.setWindowFlags(Qt::Sheet); #endif @@ -704,7 +703,7 @@ QETResult ProjectView::save() { QETResult object is returned if the operation was cancelled. */ QETResult ProjectView::saveAs(ProjectSaveOptions options) { - if (!project_) return(noProjectResult()); + if (!m_project) return(noProjectResult()); QString filepath = askUserForFilePath(); if (filepath.isEmpty()) return(QETResult()); @@ -720,9 +719,9 @@ QETResult ProjectView::saveAs(ProjectSaveOptions options) { QETResult object is returned if the operation was cancelled. */ QETResult ProjectView::doSave(ProjectSaveOptions options) { - if (!project_) return(noProjectResult()); + if (!m_project) return(noProjectResult()); - if (project_ -> filePath().isEmpty()) { + if (m_project -> filePath().isEmpty()) { // The project has not been saved to a file yet, // so save() actually means saveAs(). return(saveAs(options)); @@ -732,7 +731,7 @@ QETResult ProjectView::doSave(ProjectSaveOptions options) { saveDiagrams(getDiagrams(options)); // write to file - QETResult result = project_ -> write(); + QETResult result = m_project -> write(); updateWindowTitle(); if (options == AllDiagrams) project()->undoStack()->clear(); return(result); @@ -763,10 +762,10 @@ void ProjectView::saveDiagrams(const QList &diagrams) { cleaned. */ int ProjectView::cleanProject() { - if (!project_) return(0); + if (!m_project) return(0); // s'assure que le schema n'est pas en lecture seule - if (project_ -> isReadOnly()) { + if (m_project -> isReadOnly()) { QET::QetMessageBox::critical( this, tr("Projet en lecture seule", "message box title"), @@ -805,9 +804,10 @@ int ProjectView::cleanProject() { if (clean_dialog.exec() == QDialog::Accepted) { if (clean_tbt -> isChecked()) { - project_->embeddedTitleBlockTemplatesCollection()->deleteUnusedTitleBlocKTemplates(); + m_project->embeddedTitleBlockTemplatesCollection()->deleteUnusedTitleBlocKTemplates(); } } + return(clean_count); } @@ -879,18 +879,18 @@ void ProjectView::initLayout() { * and add it to the project view. */ void ProjectView::loadDiagrams() { - if (!project_) return; + if (!m_project) return; - setDisplayFallbackWidget(project_ -> diagrams().isEmpty()); + setDisplayFallbackWidget(m_project -> diagrams().isEmpty()); - foreach(Diagram *diagram, project_ -> diagrams()) { + foreach(Diagram *diagram, m_project -> diagrams()) { DiagramView *sv = new DiagramView(diagram); addDiagram(sv); } // If project have the folios list, move it at the beginning of the project - if (project_ -> getFolioSheetsQuantity()) { - for (int i = 0; i < project_->getFolioSheetsQuantity(); i++) + if (m_project -> getFolioSheetsQuantity()) { + for (int i = 0; i < m_project->getFolioSheetsQuantity(); i++) m_tab -> tabBar() -> moveTab(diagrams().size()-1, + 1); } } @@ -901,8 +901,8 @@ void ProjectView::loadDiagrams() { */ void ProjectView::updateWindowTitle() { QString title; - if (project_) { - title = project_ -> pathNameTitle(); + if (m_project) { + title = m_project -> pathNameTitle(); } else { title = tr("Projet", "window title for a project-less ProjectView"); } @@ -914,7 +914,7 @@ void ProjectView::updateWindowTitle() { du mode lecture seule. */ void ProjectView::adjustReadOnlyState() { - bool editable = !(project_ -> isReadOnly()); + bool editable = !(m_project -> isReadOnly()); // prevent users from moving existing diagrams m_tab -> setMovable(editable); @@ -942,10 +942,10 @@ void ProjectView::updateTabTitle(DiagramView *diagram, const QString &diagram_ti @param to Index de l'onglet apres le deplacement */ void ProjectView::tabMoved(int from, int to) { - if (!project_) return; + if (!m_project) return; // signale au QETProject le changement d'ordre des schemas - project_ -> diagramOrderChanged(from, to); + m_project -> diagramOrderChanged(from, to); // reconstruit la liste associant les index des onglets aux schemas rebuildDiagramsMap(); @@ -961,10 +961,10 @@ void ProjectView::tabMoved(int from, int to) { in order to duplicate the \a template_name template */ void ProjectView::editTitleBlockTemplateRequired(const QString &template_name, bool duplicate) { - if (!project_) return; + if (!m_project) return; emit( editTitleBlockTemplate( - project_ -> embeddedTitleBlockTemplatesCollection() -> location(template_name), + m_project -> embeddedTitleBlockTemplatesCollection() -> location(template_name), duplicate ) ); diff --git a/sources/projectview.h b/sources/projectview.h index 3f7a0182c..7bbb4ef17 100644 --- a/sources/projectview.h +++ b/sources/projectview.h @@ -17,14 +17,20 @@ */ #ifndef PROJECT_VIEW_H #define PROJECT_VIEW_H -#include + +#include + #include "templatelocation.h" #include "qetresult.h" + class QETProject; class DiagramView; class Diagram; class ElementsLocation; class QTabWidget; +class QLabel; +class QVBoxLayout; + /** This class provides a widget displaying the diagrams of a particular project using tabs. @@ -133,7 +139,7 @@ class ProjectView : public QWidget { // attributes private: QAction *add_new_diagram_; - QETProject *project_; + QETProject *m_project; QVBoxLayout *layout_; QWidget *fallback_widget_; QLabel *fallback_label_; diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index b72daefc9..01b3da294 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -691,6 +691,7 @@ void QETDiagramEditor::save() { if (title.isEmpty()) title = "QElectroTech "; QString filePath = (project_view -> project() -> filePath ()); statusBar()-> showMessage(tr("Projet %1 enregistré dans le repertoire: %2.").arg(title).arg (filePath), 2000); + m_element_collection_widget->highlightUnusedElement(); } else { showError(saved); @@ -712,6 +713,7 @@ void QETDiagramEditor::saveAs() { if (title.isEmpty()) title = "QElectroTech "; QString filePath = (project_view -> project() -> filePath ()); statusBar()->showMessage(tr("Projet %1 enregistré dans le repertoire: %2.").arg(title).arg (filePath), 2000); + m_element_collection_widget->highlightUnusedElement(); } else { showError(save_file); diff --git a/sources/qetproject.cpp b/sources/qetproject.cpp index aafe7518a..0a799ee94 100644 --- a/sources/qetproject.cpp +++ b/sources/qetproject.cpp @@ -815,7 +815,8 @@ QString QETProject::integrateTitleBlockTemplate(const TitleBlockTemplateLocation @return true si l'element location est utilise sur au moins un des schemas de ce projet, false sinon */ -bool QETProject::usesElement(const ElementsLocation &location) { +bool QETProject::usesElement(const ElementsLocation &location) const +{ foreach(Diagram *diagram, diagrams()) { if (diagram -> usesElement(location)) { return(true); @@ -824,6 +825,24 @@ bool QETProject::usesElement(const ElementsLocation &location) { return(false); } +/** + * @brief QETProject::unusedElements + * @return the list of unused element (exactly her location) + * An unused element, is an element present in the embedded collection but not present in a diagram of this project. + * Be aware that an element can be not present in a diagram, + * but managed by an undo command (delete an element), so an unused element can be used after an undo. + */ +QList QETProject::unusedElements() const +{ + QList unused_list; + + foreach(ElementsLocation location, m_elements_collection->elementsLocation()) + if (location.isElement() && !usesElement(location)) + unused_list << location; + + return unused_list; +} + /** @param location Location of a title block template @return true if the provided template is used by at least one diagram diff --git a/sources/qetproject.h b/sources/qetproject.h index 9c1ebb5f0..fe38fc4a8 100644 --- a/sources/qetproject.h +++ b/sources/qetproject.h @@ -130,7 +130,8 @@ class QETProject : public QObject bool isEmpty() const; ElementsLocation importElement(ElementsLocation &location); QString integrateTitleBlockTemplate(const TitleBlockTemplateLocation &, MoveTitleBlockTemplatesHandler *handler); - bool usesElement(const ElementsLocation &); + bool usesElement(const ElementsLocation &) const; + QList unusedElements() const; bool usesTitleBlockTemplate(const TitleBlockTemplateLocation &); bool projectWasModified(); bool projectOptionsWereModified();