diff --git a/sources/editor/qetelementeditor.cpp b/sources/editor/qetelementeditor.cpp index a2783d13c..9a579022e 100644 --- a/sources/editor/qetelementeditor.cpp +++ b/sources/editor/qetelementeditor.cpp @@ -16,6 +16,7 @@ along with QElectroTech. If not, see . */ #include "qetelementeditor.h" +#include "qet.h" #include "qetapp.h" #include "elementscene.h" #include "elementview.h" @@ -837,6 +838,46 @@ bool QETElementEditor::toLocation(const ElementsLocation &location) { return(true); } +/** + @param location Emplacement d'un element + @return true si cet editeur est en train d'editer l'element dont + l'emplacement est location, false sinon +*/ +bool QETElementEditor::isEditing(const ElementsLocation &provided_location) { + if (opened_from_file) { + return( + QET::compareCanonicalFilePaths( + filename_, + QETApp::realPath(provided_location.toString()) + ) + ); + } else { + return(provided_location == location_); + } +} + +/** + @param provided_filepath Chemin d'un element sur un filesystem + @return true si cet editeur est en train d'editer l'element dont + le chemin est filepath, false sinon +*/ +bool QETElementEditor::isEditing(const QString &provided_filepath) { + // determine le chemin canonique de l'element actuelle edite, si applicable + QString current_filepath; + if (opened_from_file) { + current_filepath = filename_; + } else { + current_filepath = QETApp::realPath(location_.toString()); + } + + return( + QET::compareCanonicalFilePaths( + current_filepath, + provided_filepath + ) + ); +} + /** specifie si l'editeur d'element doit etre en mode lecture seule @param ro true pour activer le mode lecture seule, false pour le desactiver @@ -872,9 +913,7 @@ void QETElementEditor::slot_open() { // demande le chemin virtuel de l'element a ouvrir a l'utilisateur ElementsLocation location = ElementDialog::getOpenElementLocation(this); if (location.isNull()) return; - QETElementEditor *cee = new QETElementEditor(); - cee -> fromLocation(location); - cee -> show(); + QETApp::instance() -> openElementLocations(QList() << location); } /** @@ -908,12 +947,11 @@ void QETElementEditor::openRecentFile(const QString &filepath) { Cette methode ne controle pas si le fichier est deja ouvert @param filepath Fichier a ouvrir @see fromFile + @see QETApp::openElementFiles */ void QETElementEditor::openElement(const QString &filepath) { if (filepath.isEmpty()) return; - QETElementEditor *cee = new QETElementEditor(); - cee -> fromFile(filepath); - cee -> show(); + QETApp::instance() -> openElementFiles(QStringList() << filepath); } /** diff --git a/sources/editor/qetelementeditor.h b/sources/editor/qetelementeditor.h index 4ec140c19..d8d418caa 100644 --- a/sources/editor/qetelementeditor.h +++ b/sources/editor/qetelementeditor.h @@ -115,6 +115,8 @@ class QETElementEditor : public QMainWindow { void fromLocation(const ElementsLocation &); bool toFile(const QString &); bool toLocation(const ElementsLocation &); + bool isEditing(const ElementsLocation &); + bool isEditing(const QString &); ElementScene *elementScene() const; void readSettings(); void writeSettings(); diff --git a/sources/elementspanelwidget.cpp b/sources/elementspanelwidget.cpp index 035661b4e..43f413e99 100644 --- a/sources/elementspanelwidget.cpp +++ b/sources/elementspanelwidget.cpp @@ -255,9 +255,7 @@ void ElementsPanelWidget::importElement() { // Ouverture de l'element dans l'editeur pour pouvoir ensuite l'enregistrer dans la categorie voulue if (!fileName.isEmpty()) { - QETElementEditor *editor = new QETElementEditor(); - editor -> fromFile(fileName); - editor -> show(); + QETApp::instance() -> openElementFiles(QStringList() << fileName); } } @@ -530,9 +528,7 @@ void ElementsPanelWidget::deleteElement() { @param location Emplacement de l'element a editer */ void ElementsPanelWidget::launchElementEditor(const ElementsLocation &location) { - QETElementEditor *editor = new QETElementEditor(); - editor -> fromLocation(location); - editor -> show(); + QETApp::instance() -> openElementLocations(QList() << location); } /** diff --git a/sources/qet.cpp b/sources/qet.cpp index 3ecc49848..33602f458 100644 --- a/sources/qet.cpp +++ b/sources/qet.cpp @@ -434,3 +434,25 @@ QString QET::pointerString(void *ptr) { ) ); } + +/** + @param first Un premier chemin vers un fichier + @param second Un second chemin vers un fichier + @return true si les deux chemins existent existent et sont identiques + lorsqu'ils sont exprimes sous forme canonique +*/ +bool QET::compareCanonicalFilePaths(const QString &first, const QString &second) { + QString first_canonical_path = QFileInfo(first).canonicalFilePath(); + if (first_canonical_path.isEmpty()) return(false); + + QString second_canonical_path = QFileInfo(second).canonicalFilePath(); + if (second_canonical_path.isEmpty()) return(false); + +#ifdef Q_WS_WIN + // sous Windows, on ramene les chemins en minuscules + first_canonical_path = first_canonical_path.toLower(); + second_canonical_path = second_canonical_path.toLower(); +#endif + + return(first_canonical_path == second_canonical_path); +} diff --git a/sources/qet.h b/sources/qet.h index 8ce367a2d..0681c588e 100644 --- a/sources/qet.h +++ b/sources/qet.h @@ -121,5 +121,6 @@ namespace QET { QString diagramAreaToString(const QET::DiagramArea &); QET::DiagramArea diagramAreaFromString(const QString &); QString pointerString(void *); + bool compareCanonicalFilePaths(const QString &, const QString &); } #endif diff --git a/sources/qetapp.cpp b/sources/qetapp.cpp index dec0b8fb0..18de97c17 100644 --- a/sources/qetapp.cpp +++ b/sources/qetapp.cpp @@ -730,10 +730,68 @@ void QETApp::openProjectFiles(const QStringList &files_list) { void QETApp::openElementFiles(const QStringList &files_list) { if (files_list.isEmpty()) return; - // creation et affichage d'un ou plusieurs editeurs d'element - foreach(QString element_file, files_list) { - QETElementEditor *element_editor = new QETElementEditor(); - element_editor -> fromFile(element_file); + // evite autant que possible les doublons dans la liste fournie + QSet files_set; + foreach(QString file, files_list) { + QString canonical_filepath = QFileInfo(file).canonicalFilePath(); + if (!canonical_filepath.isEmpty()) files_set << canonical_filepath; + } + // a ce stade, tous les fichiers dans le Set existent et sont a priori differents + if (files_set.isEmpty()) return; + + // liste des editeurs d'element ouverts + QList element_editors = elementEditors(); + + // on traite les fichiers a la queue leu leu... + foreach(QString element_file, files_set) { + bool already_opened_in_existing_element_editor = false; + foreach(QETElementEditor *element_editor, element_editors) { + if (element_editor -> isEditing(element_file)) { + // ce fichier est deja ouvert dans un editeur + already_opened_in_existing_element_editor = true; + element_editor -> setVisible(true); + element_editor -> raise(); + element_editor -> activateWindow(); + break; + } + } + if (!already_opened_in_existing_element_editor) { + // ce fichier n'est ouvert dans aucun editeur + QETElementEditor *element_editor = new QETElementEditor(); + element_editor -> fromFile(element_file); + } + } +} + +/** + Ouvre les elements dont l'emplacement est passe en parametre. Si un element + est deja ouvert, la fentre qui l'edite est activee. + @param locations_list Emplacements a ouvrir +*/ +void QETApp::openElementLocations(const QList &locations_list) { + if (locations_list.isEmpty()) return; + + // liste des editeurs d'element ouverts + QList element_editors = elementEditors(); + + // on traite les emplacements a la queue leu leu... + foreach(ElementsLocation element_location, locations_list) { + bool already_opened_in_existing_element_editor = false; + foreach(QETElementEditor *element_editor, element_editors) { + if (element_editor -> isEditing(element_location)) { + // cet emplacement est deja ouvert dans un editeur + already_opened_in_existing_element_editor = true; + element_editor -> setVisible(true); + element_editor -> raise(); + element_editor -> activateWindow(); + break; + } + } + if (!already_opened_in_existing_element_editor) { + // cet emplacement n'est ouvert dans aucun editeur + QETElementEditor *element_editor = new QETElementEditor(); + element_editor -> fromLocation(element_location); + } } } diff --git a/sources/qetapp.h b/sources/qetapp.h index cf7fae04b..7e7256d38 100644 --- a/sources/qetapp.h +++ b/sources/qetapp.h @@ -159,6 +159,7 @@ class QETApp : public QETSingleApplication { void openFiles(const QETArguments &); void openProjectFiles(const QStringList &); void openElementFiles(const QStringList &); + void openElementLocations(const QList &); void configureQET(); void aboutQET(); diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index c9dffc76e..65a750733 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -1757,12 +1757,9 @@ void QETDiagramEditor::findElementInPanel(const ElementsLocation &location) { @param location Emplacement de l'element a editer */ void QETDiagramEditor::editElementInEditor(const ElementsLocation &location) { - QETElementEditor *editor = new QETElementEditor(); - editor -> fromLocation(location); - editor -> show(); + QETApp::instance() -> openElementLocations(QList() << location); } - /** @return Les proprietes par defaut pour le cartouche d'un schema */