diff --git a/cmake/qet_compilation_vars.cmake b/cmake/qet_compilation_vars.cmake index e6e189350..61b0f6a38 100644 --- a/cmake/qet_compilation_vars.cmake +++ b/cmake/qet_compilation_vars.cmake @@ -113,6 +113,8 @@ set(QET_SRC_FILES ${QET_DIR}/sources/import/edz/edzpart.h ${QET_DIR}/sources/import/edz/edzelementbuilder.cpp ${QET_DIR}/sources/import/edz/edzelementbuilder.h + ${QET_DIR}/sources/import/edz/edzimporter.cpp + ${QET_DIR}/sources/import/edz/edzimporter.h ${QET_DIR}/sources/borderproperties.cpp ${QET_DIR}/sources/borderproperties.h ${QET_DIR}/sources/bordertitleblock.cpp diff --git a/sources/ElementsCollection/elementscollectionwidget.cpp b/sources/ElementsCollection/elementscollectionwidget.cpp index e88bd8731..ffe2e3796 100644 --- a/sources/ElementsCollection/elementscollectionwidget.cpp +++ b/sources/ElementsCollection/elementscollectionwidget.cpp @@ -19,6 +19,7 @@ #include "../editor/ui/qetelementeditor.h" #include "../elementscategoryeditor.h" +#include "../import/edz/edzimporter.h" #include "../newelementwizard.h" #include "../qetapp.h" #include "../qetdiagrameditor.h" @@ -33,6 +34,7 @@ #include "xmlprojectelementcollectionitem.h" #include +#include #include #include #include @@ -158,6 +160,8 @@ void ElementsCollectionWidget::setUpAction() tr("Nouveau dossier"), this); m_new_element = new QAction(QET::Icons::ElementNew, tr("Nouvel élément"), this); + m_import_edz = new QAction(QET::Icons::ElementNew, + tr("Importer une pièce EPLAN (.edz)…"), this); m_show_this_dir = new QAction(QET::Icons::FolderOnlyThis, tr("Afficher uniquement ce dossier"), this); @@ -247,6 +251,8 @@ void ElementsCollectionWidget::setUpConnection() this, &ElementsCollectionWidget::newDirectory); connect(m_new_element, &QAction::triggered, this, &ElementsCollectionWidget::newElement); + connect(m_import_edz, &QAction::triggered, + this, &ElementsCollectionWidget::importEdz); connect(m_show_this_dir, &QAction::triggered, this, &ElementsCollectionWidget::showThisDir); connect(m_show_all_dir, &QAction::triggered, @@ -329,6 +335,7 @@ void ElementsCollectionWidget::customContextMenu(const QPoint &point) { if (!feci->isMacrosCollection()) { m_context_menu->addAction(m_new_element); + m_context_menu->addAction(m_import_edz); } m_context_menu->addAction(m_new_directory); if (!feci->isCollectionRoot()) @@ -599,6 +606,44 @@ void ElementsCollectionWidget::newElement() &ElementsCollectionWidget::locationWasSaved); } +/** + @brief ElementsCollectionWidget::importEdz + Import an EPLAN Data Portal part (.edz) as a QET element into the directory + pointed at by the context menu. +*/ +void ElementsCollectionWidget::importEdz() +{ + ElementCollectionItem *eci = elementCollectionItemForIndex( + m_index_at_context_menu); + + if (!eci || eci->type() != FileElementCollectionItem::Type) { + return; + } + FileElementCollectionItem *feci = + static_cast(eci); + if (feci->isCommonCollection() || !feci->isDir()) { + return; + } + + const QString edz_path = QFileDialog::getOpenFileName( + this, tr("Importer une pièce EPLAN"), QString(), + tr("Pièces EPLAN (*.edz)")); + if (edz_path.isEmpty()) { + return; + } + + EdzImporter importer; + if (!importer.importToDirectory(edz_path, feci->fileSystemPath())) { + QET::QetMessageBox::critical( + this, tr("Import EPLAN"), + tr("Impossible d'importer cette pièce :\n%1") + .arg(importer.errorString())); + return; + } + + reload(); +} + /** @brief ElementsCollectionWidget::showThisDir Hide all directories except the pointed dir; diff --git a/sources/ElementsCollection/elementscollectionwidget.h b/sources/ElementsCollection/elementscollectionwidget.h index a8294ec78..84c02ec68 100644 --- a/sources/ElementsCollection/elementscollectionwidget.h +++ b/sources/ElementsCollection/elementscollectionwidget.h @@ -72,6 +72,7 @@ class ElementsCollectionWidget : public QWidget void editDirectory(); void newDirectory(); void newElement(); + void importEdz(); void showThisDir(); void resetShowThisDir(); void dirProperties(); @@ -112,6 +113,7 @@ class ElementsCollectionWidget : public QWidget *m_edit_dir, *m_new_directory, *m_new_element, + *m_import_edz, *m_show_this_dir, *m_show_all_dir, *m_dir_propertie; diff --git a/sources/import/edz/edzimporter.cpp b/sources/import/edz/edzimporter.cpp new file mode 100644 index 000000000..16fb15ba7 --- /dev/null +++ b/sources/import/edz/edzimporter.cpp @@ -0,0 +1,83 @@ +/* + Copyright 2006 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "edzimporter.h" + +#include "edzarchive.h" +#include "edzpart.h" +#include "edzelementbuilder.h" + +#include +#include +#include +#include + +/** + Import the .edz at @a edz_path, writing the generated .elmt into the + filesystem folder @a dest_dir. @return true on success; writtenPath() then + holds the created file. On failure errorString() explains why. +*/ +bool EdzImporter::importToDirectory(const QString &edz_path, + const QString &dest_dir) +{ + m_written.clear(); + m_error.clear(); + + EdzArchive archive; + if (!archive.extract(edz_path)) { + m_error = archive.errorString(); + return false; + } + + EdzPart part; + if (!part.parse(archive.partXmlPath())) { + m_error = part.errorString(); + return false; + } + + const QDomDocument doc = EdzElementBuilder::build(part); + + // Name the file from the order number (fall back to part number / source). + QString base = part.orderNumber(); + if (base.isEmpty()) { + base = part.partNumber(); + } + if (base.isEmpty()) { + base = QFileInfo(edz_path).completeBaseName(); + } + base.replace(QRegularExpression(QStringLiteral("[^A-Za-z0-9._-]")), + QStringLiteral("_")); + + const QDir dir(dest_dir); + if (!dir.exists() && !dir.mkpath(QStringLiteral("."))) { + m_error = QStringLiteral("Destination folder does not exist: %1") + .arg(dest_dir); + return false; + } + const QString out_path = dir.filePath(base + QStringLiteral(".elmt")); + + QFile file(out_path); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + m_error = QStringLiteral("Cannot write %1").arg(out_path); + return false; + } + file.write(EdzElementBuilder::toElmtString(doc).toUtf8()); + file.close(); + + m_written = out_path; + return true; +} diff --git a/sources/import/edz/edzimporter.h b/sources/import/edz/edzimporter.h new file mode 100644 index 000000000..4abf8a79a --- /dev/null +++ b/sources/import/edz/edzimporter.h @@ -0,0 +1,45 @@ +/* + Copyright 2006 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef EDZIMPORTER_H +#define EDZIMPORTER_H + +#include + +/** + @brief Orchestrates importing an EPLAN .edz package as a QET element. + + Ties together EdzArchive (extract) -> EdzPart (parse) -> EdzElementBuilder + (build) and writes the resulting .elmt into a destination collection folder. + UI-decoupled so it stays unit-testable headless; the collection widget calls + importToDirectory() and then refreshes the panel. +*/ +class EdzImporter +{ + public: + bool importToDirectory(const QString &edz_path, + const QString &dest_dir); + + QString writtenPath() const { return m_written; } + QString errorString() const { return m_error; } + + private: + QString m_written; + QString m_error; +}; + +#endif // EDZIMPORTER_H