mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-05-21 20:59:59 +02:00
Merge pull request #451 from Kellermorph/makro
Draft: Feature - Introduce User Templates Collection and Dedicated UI Tab
This commit is contained in:
@@ -254,6 +254,8 @@ set(QET_SRC_FILES
|
|||||||
${QET_DIR}/sources/diagramevent/diagrameventaddtext.h
|
${QET_DIR}/sources/diagramevent/diagrameventaddtext.h
|
||||||
${QET_DIR}/sources/diagramevent/diagrameventinterface.cpp
|
${QET_DIR}/sources/diagramevent/diagrameventinterface.cpp
|
||||||
${QET_DIR}/sources/diagramevent/diagrameventinterface.h
|
${QET_DIR}/sources/diagramevent/diagrameventinterface.h
|
||||||
|
${QET_DIR}/sources/diagramevent/diagrameventaddmacro.cpp
|
||||||
|
${QET_DIR}/sources/diagramevent/diagrameventaddmacro.h
|
||||||
|
|
||||||
${QET_DIR}/sources/dvevent/dveventinterface.cpp
|
${QET_DIR}/sources/dvevent/dveventinterface.cpp
|
||||||
${QET_DIR}/sources/dvevent/dveventinterface.h
|
${QET_DIR}/sources/dvevent/dveventinterface.h
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ int ElementCollectionItem::rowForInsertItem(const QString &name)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
QList <ElementCollectionItem *> child;
|
QList <ElementCollectionItem *> child;
|
||||||
//The item to insert is an element we search from element child
|
//The item to insert is an element/template we search from element child
|
||||||
if (name.endsWith(".elmt"))
|
if (name.endsWith(".elmt") || name.endsWith(".qetmak"))
|
||||||
{
|
{
|
||||||
child = elementsDirectChild();
|
child = elementsDirectChild();
|
||||||
//There isn't element, we insert at last position
|
//There isn't element, we insert at last position
|
||||||
|
|||||||
@@ -268,6 +268,8 @@ void ElementsCollectionModel::loadCollections(bool common_collection,
|
|||||||
bool custom_collection,
|
bool custom_collection,
|
||||||
QList<QETProject *> projects)
|
QList<QETProject *> projects)
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
m_items_list_to_setUp.clear();
|
m_items_list_to_setUp.clear();
|
||||||
|
|
||||||
if (common_collection)
|
if (common_collection)
|
||||||
@@ -280,12 +282,12 @@ void ElementsCollectionModel::loadCollections(bool common_collection,
|
|||||||
if (common_collection || company_collection || custom_collection)
|
if (common_collection || company_collection || custom_collection)
|
||||||
m_items_list_to_setUp.append(items());
|
m_items_list_to_setUp.append(items());
|
||||||
|
|
||||||
|
|
||||||
for (QETProject *project : projects)
|
for (QETProject *project : projects)
|
||||||
{
|
{
|
||||||
addProject(project, false);
|
addProject(project, false);
|
||||||
m_items_list_to_setUp.append(projectItems(project));
|
m_items_list_to_setUp.append(projectItems(project));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *watcher = new QFutureWatcher<void>();
|
auto *watcher = new QFutureWatcher<void>();
|
||||||
connect(watcher, &QFutureWatcher<void>::progressValueChanged,
|
connect(watcher, &QFutureWatcher<void>::progressValueChanged,
|
||||||
this, &ElementsCollectionModel::loadingProgressValueChanged);
|
this, &ElementsCollectionModel::loadingProgressValueChanged);
|
||||||
@@ -293,23 +295,51 @@ void ElementsCollectionModel::loadCollections(bool common_collection,
|
|||||||
this, &ElementsCollectionModel::loadingProgressRangeChanged);
|
this, &ElementsCollectionModel::loadingProgressRangeChanged);
|
||||||
connect(watcher, &QFutureWatcher<void>::finished,
|
connect(watcher, &QFutureWatcher<void>::finished,
|
||||||
this, &ElementsCollectionModel::loadingFinished);
|
this, &ElementsCollectionModel::loadingFinished);
|
||||||
connect(
|
connect(watcher, &QFutureWatcher<void>::finished, watcher, &QFutureWatcher<void>::deleteLater);
|
||||||
watcher,
|
|
||||||
&QFutureWatcher<void>::finished,
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
watcher,
|
|
||||||
&QFutureWatcher<void>::deleteLater);
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
|
|
||||||
m_future = QtConcurrent::map(m_items_list_to_setUp, setUpData);
|
m_future = QtConcurrent::map(m_items_list_to_setUp, setUpData);
|
||||||
#else
|
#else
|
||||||
# if TODO_LIST
|
qDebug() << "Help code for QT 6 or later";
|
||||||
# pragma message("@TODO remove code for QT 6 or later")
|
#endif
|
||||||
# endif
|
|
||||||
qDebug() << "Help code for QT 6 or later"
|
|
||||||
<< "QtConcurrent::run its backwards now...function, object, args";
|
|
||||||
#endif
|
|
||||||
watcher->setFuture(m_future);
|
watcher->setFuture(m_future);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ElementsCollectionModel::loadMacrosCollection
|
||||||
|
* Load the macros collection synchronously to avoid thread-collisions.
|
||||||
|
*/
|
||||||
|
void ElementsCollectionModel::loadMacrosCollection()
|
||||||
|
{
|
||||||
|
m_items_list_to_setUp.clear();
|
||||||
|
addMacrosCollection(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ElementsCollectionModel::addMacrosCollection
|
||||||
|
* Add the user macros collection to this model
|
||||||
|
* @param set_data
|
||||||
|
*/
|
||||||
|
void ElementsCollectionModel::addMacrosCollection(bool set_data)
|
||||||
|
{
|
||||||
|
QString macrosPath = QETApp::userMacrosDir();
|
||||||
|
qDebug() << "=== MAKRO PFAD CHECK ===" << macrosPath;
|
||||||
|
if (macrosPath.endsWith("/")) {
|
||||||
|
macrosPath.remove(macrosPath.length() - 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileElementCollectionItem *feci = new FileElementCollectionItem();
|
||||||
|
if (feci->setRootPath(macrosPath,
|
||||||
|
set_data,
|
||||||
|
m_hide_element)) {
|
||||||
|
invisibleRootItem()->appendRow(feci);
|
||||||
|
if (set_data)
|
||||||
|
feci->setUpData();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
delete feci;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief ElementsCollectionModel::addCommonCollection
|
@brief ElementsCollectionModel::addCommonCollection
|
||||||
Add the common elements collection to this model
|
Add the common elements collection to this model
|
||||||
@@ -368,11 +398,11 @@ void ElementsCollectionModel::addCustomCollection(bool set_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief ElementsCollectionModel::addLocation
|
* @brief ElementsCollectionModel::addLocation
|
||||||
Add the element or directory to this model.
|
* Add the element or directory to this model.
|
||||||
If the location is already managed by this model, do nothing.
|
* If the location is already managed by this model, do nothing.
|
||||||
@param location
|
* @param location
|
||||||
*/
|
*/
|
||||||
void ElementsCollectionModel::addLocation(const ElementsLocation& location)
|
void ElementsCollectionModel::addLocation(const ElementsLocation& location)
|
||||||
{
|
{
|
||||||
QModelIndex index = indexFromLocation(location);
|
QModelIndex index = indexFromLocation(location);
|
||||||
@@ -394,7 +424,8 @@ void ElementsCollectionModel::addLocation(const ElementsLocation& location)
|
|||||||
collection_name);
|
collection_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (location.isCustomCollection()) {
|
// ANPASSUNG: Makros und Custom Collection werden hier behandelt!
|
||||||
|
else if (location.isCustomCollection() || location.isMacrosCollection()) {
|
||||||
QList <ElementCollectionItem *> child_list;
|
QList <ElementCollectionItem *> child_list;
|
||||||
|
|
||||||
for (int i=0 ; i<rowCount() ; i++)
|
for (int i=0 ; i<rowCount() ; i++)
|
||||||
@@ -406,7 +437,10 @@ void ElementsCollectionModel::addLocation(const ElementsLocation& location)
|
|||||||
FileElementCollectionItem *feci =
|
FileElementCollectionItem *feci =
|
||||||
static_cast<FileElementCollectionItem *>(eci);
|
static_cast<FileElementCollectionItem *>(eci);
|
||||||
|
|
||||||
if (feci->isCustomCollection()) {
|
// Wir prüfen explizit, ob es Custom ODER Macros ist, und weisen es richtig zu.
|
||||||
|
if ((location.isCustomCollection() && feci->isCustomCollection()) ||
|
||||||
|
(location.isMacrosCollection() && feci->isMacrosCollection())) {
|
||||||
|
|
||||||
last_item = feci->lastItemForPath(
|
last_item = feci->lastItemForPath(
|
||||||
location.collectionPath(false),
|
location.collectionPath(false),
|
||||||
collection_name);
|
collection_name);
|
||||||
@@ -574,12 +608,12 @@ void ElementsCollectionModel::hideElement()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief ElementsCollectionModel::indexFromLocation
|
* @brief ElementsCollectionModel::indexFromLocation
|
||||||
Return the index who represent location.
|
* Return the index who represent location.
|
||||||
Index can be non valid
|
* Index can be non valid
|
||||||
@param location
|
* @param location
|
||||||
@return
|
* @return
|
||||||
*/
|
*/
|
||||||
QModelIndex ElementsCollectionModel::indexFromLocation(
|
QModelIndex ElementsCollectionModel::indexFromLocation(
|
||||||
const ElementsLocation &location)
|
const ElementsLocation &location)
|
||||||
{
|
{
|
||||||
@@ -595,9 +629,13 @@ QModelIndex ElementsCollectionModel::indexFromLocation(
|
|||||||
|
|
||||||
if (eci->type() == FileElementCollectionItem::Type) {
|
if (eci->type() == FileElementCollectionItem::Type) {
|
||||||
if (FileElementCollectionItem *feci = static_cast<FileElementCollectionItem *>(eci)) {
|
if (FileElementCollectionItem *feci = static_cast<FileElementCollectionItem *>(eci)) {
|
||||||
|
|
||||||
|
// ANPASSUNG: Makro-Prüfung hinzugefügt, damit das Modell den Pfad im Baum findet!
|
||||||
if ( (location.isCommonCollection() && feci->isCommonCollection()) ||
|
if ( (location.isCommonCollection() && feci->isCommonCollection()) ||
|
||||||
(location.isCompanyCollection() && feci->isCompanyCollection()) ||
|
(location.isCompanyCollection() && feci->isCompanyCollection()) ||
|
||||||
(location.isCustomCollection() && !feci->isCommonCollection()) ) {
|
(location.isMacrosCollection() && feci->isMacrosCollection()) ||
|
||||||
|
(location.isCustomCollection() && feci->isCustomCollection()) ) {
|
||||||
|
|
||||||
match_eci = feci->itemAtPath(location.collectionPath(false));
|
match_eci = feci->itemAtPath(location.collectionPath(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ class ElementsCollectionModel : public QStandardItemModel
|
|||||||
void addCommonCollection(bool set_data = true);
|
void addCommonCollection(bool set_data = true);
|
||||||
void addCompanyCollection(bool set_data = true);
|
void addCompanyCollection(bool set_data = true);
|
||||||
void addCustomCollection(bool set_data = true);
|
void addCustomCollection(bool set_data = true);
|
||||||
|
void addMacrosCollection(bool set_data = true);
|
||||||
|
void loadMacrosCollection();
|
||||||
void addLocation(const ElementsLocation& location);
|
void addLocation(const ElementsLocation& location);
|
||||||
|
|
||||||
void addProject(QETProject *project, bool set_data = true);
|
void addProject(QETProject *project, bool set_data = true);
|
||||||
|
|||||||
@@ -93,10 +93,7 @@ void ElementsCollectionWidget::addProject(QETProject *project)
|
|||||||
{
|
{
|
||||||
if (m_model)
|
if (m_model)
|
||||||
{
|
{
|
||||||
m_progress_bar->show();
|
m_model->addProject(project, true);
|
||||||
m_tree_view->setDisabled(true);
|
|
||||||
QList <QETProject *> prj; prj.append(project);
|
|
||||||
m_model->loadCollections(false, false, false, prj);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_waiting_project.append(project);
|
m_waiting_project.append(project);
|
||||||
@@ -176,16 +173,14 @@ void ElementsCollectionWidget::setUpAction()
|
|||||||
*/
|
*/
|
||||||
void ElementsCollectionWidget::setUpWidget()
|
void ElementsCollectionWidget::setUpWidget()
|
||||||
{
|
{
|
||||||
//Setup the main layout
|
|
||||||
m_main_vlayout = new QVBoxLayout(this);
|
m_main_vlayout = new QVBoxLayout(this);
|
||||||
this->setLayout(m_main_vlayout);
|
m_main_vlayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
m_main_vlayout->setSpacing(2);
|
||||||
|
|
||||||
m_search_field = new QLineEdit(this);
|
m_search_field = new QLineEdit(this);
|
||||||
m_search_field->setPlaceholderText(tr("Rechercher"));
|
m_search_field->setPlaceholderText(tr("Rechercher..."));
|
||||||
m_search_field->setClearButtonEnabled(true);
|
m_search_field->setClearButtonEnabled(true);
|
||||||
m_main_vlayout->addWidget(m_search_field);
|
|
||||||
|
|
||||||
//Setup the tree view
|
|
||||||
m_tree_view = new ElementsTreeView(this);
|
m_tree_view = new ElementsTreeView(this);
|
||||||
m_tree_view->setHeaderHidden(true);
|
m_tree_view->setHeaderHidden(true);
|
||||||
m_tree_view->setIconSize(QSize(50, 50));
|
m_tree_view->setIconSize(QSize(50, 50));
|
||||||
@@ -195,12 +190,29 @@ void ElementsCollectionWidget::setUpWidget()
|
|||||||
m_tree_view->setAnimated(true);
|
m_tree_view->setAnimated(true);
|
||||||
m_tree_view->setMouseTracking(true);
|
m_tree_view->setMouseTracking(true);
|
||||||
m_tree_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
m_tree_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
m_main_vlayout->addWidget(m_tree_view);
|
|
||||||
|
|
||||||
//Setup the progress bar
|
//Setup the macros tree view
|
||||||
|
m_macros_tree_view = new ElementsTreeView(this);
|
||||||
|
m_macros_tree_view->setHeaderHidden(true);
|
||||||
|
m_macros_tree_view->setIconSize(QSize(50, 50));
|
||||||
|
m_macros_tree_view->setDragDropMode(QAbstractItemView::DragDrop);
|
||||||
|
m_macros_tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
m_macros_tree_view->setAutoExpandDelay(500);
|
||||||
|
m_macros_tree_view->setAnimated(true);
|
||||||
|
m_macros_tree_view->setMouseTracking(true);
|
||||||
|
m_macros_tree_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
|
|
||||||
|
m_tab_widget = new QTabWidget(this);
|
||||||
|
m_tab_widget->setDocumentMode(true);
|
||||||
|
m_tab_widget->setTabPosition(QTabWidget::North);
|
||||||
|
m_tab_widget->addTab(m_tree_view, tr("Collections"));
|
||||||
|
m_tab_widget->addTab(m_macros_tree_view, tr("Modèles"));
|
||||||
|
|
||||||
|
m_main_vlayout->addWidget(m_search_field);
|
||||||
|
m_main_vlayout->addWidget(m_tab_widget);
|
||||||
|
|
||||||
m_progress_bar = new QProgressBar(this);
|
m_progress_bar = new QProgressBar(this);
|
||||||
m_progress_bar->setFormat(QObject::tr("chargement %p% (%v sur %m)"));
|
m_progress_bar->setFormat(QObject::tr("chargement %p% (%v sur %m)"));
|
||||||
|
|
||||||
m_main_vlayout->addWidget(m_progress_bar);
|
m_main_vlayout->addWidget(m_progress_bar);
|
||||||
m_progress_bar->hide();
|
m_progress_bar->hide();
|
||||||
|
|
||||||
@@ -246,6 +258,10 @@ void ElementsCollectionWidget::setUpConnection()
|
|||||||
[this](const QModelIndex &index)
|
[this](const QModelIndex &index)
|
||||||
{
|
{
|
||||||
this->m_index_at_context_menu = index ;
|
this->m_index_at_context_menu = index ;
|
||||||
|
ElementCollectionItem *eci = elementCollectionItemForIndex(index);
|
||||||
|
if (eci && eci->collectionPath().endsWith(".qetmak")) {
|
||||||
|
return; // Do nothing on double click for macros
|
||||||
|
}
|
||||||
this->editElement();
|
this->editElement();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -256,16 +272,41 @@ void ElementsCollectionWidget::setUpConnection()
|
|||||||
if (qde && eci)
|
if (qde && eci)
|
||||||
qde->statusBar()->showMessage(eci->localName());
|
qde->statusBar()->showMessage(eci->localName());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(m_macros_tree_view, &QTreeView::customContextMenuRequested,
|
||||||
|
this, &ElementsCollectionWidget::customContextMenu);
|
||||||
|
|
||||||
|
connect(m_macros_tree_view, &QTreeView::doubleClicked,
|
||||||
|
[this](const QModelIndex &index)
|
||||||
|
{
|
||||||
|
this->m_index_at_context_menu = index ;
|
||||||
|
ElementCollectionItem *eci = elementCollectionItemForIndex(index);
|
||||||
|
if (eci && eci->collectionPath().endsWith(".qetmak")) {
|
||||||
|
return; // Do nothing on double click for macros
|
||||||
|
}
|
||||||
|
this->editElement();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_macros_tree_view, &QTreeView::entered,
|
||||||
|
[this] (const QModelIndex &index) {
|
||||||
|
QETDiagramEditor *qde = QETApp::diagramEditorAncestorOf(this);
|
||||||
|
ElementCollectionItem *eci = elementCollectionItemForIndex(index);
|
||||||
|
if (qde && eci)
|
||||||
|
qde->statusBar()->showMessage(eci->localName());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief ElementsCollectionWidget::customContextMenu
|
* @brief ElementsCollectionWidget::customContextMenu
|
||||||
Display the context menu of this widget at point
|
* Display the context menu of this widget at point
|
||||||
@param point
|
* @param point
|
||||||
*/
|
*/
|
||||||
void ElementsCollectionWidget::customContextMenu(const QPoint &point)
|
void ElementsCollectionWidget::customContextMenu(const QPoint &point)
|
||||||
{
|
{
|
||||||
m_index_at_context_menu = m_tree_view->indexAt(point);
|
QTreeView *clicked_tree = qobject_cast<QTreeView *>(sender());
|
||||||
|
if (!clicked_tree) clicked_tree = m_tree_view; // Fallback
|
||||||
|
|
||||||
|
m_index_at_context_menu = clicked_tree->indexAt(point);
|
||||||
if (!m_index_at_context_menu.isValid()) return;
|
if (!m_index_at_context_menu.isValid()) return;
|
||||||
|
|
||||||
m_context_menu->clear();
|
m_context_menu->clear();
|
||||||
@@ -274,7 +315,7 @@ void ElementsCollectionWidget::customContextMenu(const QPoint &point)
|
|||||||
m_index_at_context_menu);
|
m_index_at_context_menu);
|
||||||
bool add_open_dir = false;
|
bool add_open_dir = false;
|
||||||
|
|
||||||
if (eci->isElement())
|
if (eci->isElement() && !eci->collectionPath().endsWith(".qetmak"))
|
||||||
m_context_menu->addAction(m_edit_element);
|
m_context_menu->addAction(m_edit_element);
|
||||||
|
|
||||||
if (eci->type() == FileElementCollectionItem::Type)
|
if (eci->type() == FileElementCollectionItem::Type)
|
||||||
@@ -286,7 +327,9 @@ void ElementsCollectionWidget::customContextMenu(const QPoint &point)
|
|||||||
{
|
{
|
||||||
if (feci->isDir())
|
if (feci->isDir())
|
||||||
{
|
{
|
||||||
|
if (!feci->isMacrosCollection()) {
|
||||||
m_context_menu->addAction(m_new_element);
|
m_context_menu->addAction(m_new_element);
|
||||||
|
}
|
||||||
m_context_menu->addAction(m_new_directory);
|
m_context_menu->addAction(m_new_directory);
|
||||||
if (!feci->isCollectionRoot())
|
if (!feci->isCollectionRoot())
|
||||||
{
|
{
|
||||||
@@ -320,7 +363,7 @@ void ElementsCollectionWidget::customContextMenu(const QPoint &point)
|
|||||||
m_context_menu->addAction(m_open_dir);
|
m_context_menu->addAction(m_open_dir);
|
||||||
m_context_menu->addAction(m_reload);
|
m_context_menu->addAction(m_reload);
|
||||||
|
|
||||||
m_context_menu->popup(mapToGlobal(m_tree_view->mapToParent(point)));
|
m_context_menu->popup(mapToGlobal(clicked_tree->mapToParent(point)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -360,6 +403,9 @@ void ElementsCollectionWidget::editElement()
|
|||||||
|
|
||||||
if ( !(eci && eci->isElement()) ) return;
|
if ( !(eci && eci->isElement()) ) return;
|
||||||
|
|
||||||
|
// Prevent the element editor from opening for macros
|
||||||
|
if (eci->collectionPath().endsWith(".qetmak")) return;
|
||||||
|
|
||||||
ElementsLocation location(eci->collectionPath());
|
ElementsLocation location(eci->collectionPath());
|
||||||
|
|
||||||
QETApp *app = QETApp::instance();
|
QETApp *app = QETApp::instance();
|
||||||
@@ -384,11 +430,15 @@ void ElementsCollectionWidget::deleteElement()
|
|||||||
if (!eci) return;
|
if (!eci) return;
|
||||||
|
|
||||||
ElementsLocation loc(eci->collectionPath());
|
ElementsLocation loc(eci->collectionPath());
|
||||||
if (! (loc.isElement()
|
|
||||||
|
bool isDeletableFile = loc.isElement() || eci->collectionPath().endsWith(".qetmak");
|
||||||
|
|
||||||
|
if (! (isDeletableFile
|
||||||
&& loc.exist()
|
&& loc.exist()
|
||||||
&& loc.isFileSystem()
|
&& loc.isFileSystem()
|
||||||
&& (loc.collectionPath().startsWith("company://")
|
&& (loc.collectionPath().startsWith("company://")
|
||||||
|| loc.collectionPath().startsWith("custom://"))) ) return;
|
|| loc.collectionPath().startsWith("custom://")
|
||||||
|
|| loc.collectionPath().startsWith("macros://"))) ) return;
|
||||||
|
|
||||||
if (QET::QetMessageBox::question(
|
if (QET::QetMessageBox::question(
|
||||||
this,
|
this,
|
||||||
@@ -400,9 +450,10 @@ void ElementsCollectionWidget::deleteElement()
|
|||||||
QFile file(loc.fileSystemPath());
|
QFile file(loc.fileSystemPath());
|
||||||
if (file.remove())
|
if (file.remove())
|
||||||
{
|
{
|
||||||
m_model->removeRows(m_index_at_context_menu.row(),
|
QAbstractItemModel *clicked_model = const_cast<QAbstractItemModel*>(m_index_at_context_menu.model());
|
||||||
1,
|
if (clicked_model) {
|
||||||
m_index_at_context_menu.parent());
|
clicked_model->removeRows(m_index_at_context_menu.row(), 1, m_index_at_context_menu.parent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -432,7 +483,8 @@ void ElementsCollectionWidget::deleteDirectory()
|
|||||||
&& loc.exist()
|
&& loc.exist()
|
||||||
&& loc.isFileSystem()
|
&& loc.isFileSystem()
|
||||||
&& (loc.collectionPath().startsWith("company://")
|
&& (loc.collectionPath().startsWith("company://")
|
||||||
|| loc.collectionPath().startsWith("custom://"))) ) return;
|
|| loc.collectionPath().startsWith("custom://")
|
||||||
|
|| loc.collectionPath().startsWith("macros://"))) ) return;
|
||||||
|
|
||||||
if (QET::QetMessageBox::question(
|
if (QET::QetMessageBox::question(
|
||||||
this,
|
this,
|
||||||
@@ -445,9 +497,10 @@ void ElementsCollectionWidget::deleteDirectory()
|
|||||||
QDir dir (loc.fileSystemPath());
|
QDir dir (loc.fileSystemPath());
|
||||||
if (dir.removeRecursively())
|
if (dir.removeRecursively())
|
||||||
{
|
{
|
||||||
m_model->removeRows(m_index_at_context_menu.row(),
|
QAbstractItemModel *clicked_model = const_cast<QAbstractItemModel*>(m_index_at_context_menu.model());
|
||||||
1,
|
if (clicked_model) {
|
||||||
m_index_at_context_menu.parent());
|
clicked_model->removeRows(m_index_at_context_menu.row(), 1, m_index_at_context_menu.parent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -489,19 +542,29 @@ void ElementsCollectionWidget::editDirectory()
|
|||||||
*/
|
*/
|
||||||
void ElementsCollectionWidget::newDirectory()
|
void ElementsCollectionWidget::newDirectory()
|
||||||
{
|
{
|
||||||
ElementCollectionItem *eci = elementCollectionItemForIndex(
|
ElementCollectionItem *eci = elementCollectionItemForIndex(m_index_at_context_menu);
|
||||||
m_index_at_context_menu);
|
|
||||||
|
|
||||||
if (eci->type() != FileElementCollectionItem::Type) return;
|
if (!eci || eci->type() != FileElementCollectionItem::Type) return;
|
||||||
|
|
||||||
FileElementCollectionItem *feci =
|
FileElementCollectionItem *feci = static_cast<FileElementCollectionItem*>(eci);
|
||||||
static_cast<FileElementCollectionItem*>(eci);
|
|
||||||
if(feci->isCommonCollection()) return;
|
if(feci->isCommonCollection()) return;
|
||||||
|
|
||||||
ElementsLocation location(feci->collectionPath());
|
ElementsLocation location(feci->collectionPath());
|
||||||
ElementsCategoryEditor new_dir_editor(location, false, this);
|
ElementsCategoryEditor new_dir_editor(location, false, this);
|
||||||
if (new_dir_editor.exec() == QDialog::Accepted)
|
|
||||||
m_model->addLocation(new_dir_editor.createdLocation());
|
if (new_dir_editor.exec() == QDialog::Accepted) {
|
||||||
|
ElementsLocation new_loc = new_dir_editor.createdLocation();
|
||||||
|
|
||||||
|
if (new_loc.isMacrosCollection()) {
|
||||||
|
if (m_macros_model) {
|
||||||
|
m_macros_model->addLocation(new_loc);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m_model) {
|
||||||
|
m_model->addLocation(new_loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -662,12 +725,19 @@ void ElementsCollectionWidget::reload()
|
|||||||
&ElementsCollectionWidget::loadingFinished);
|
&ElementsCollectionWidget::loadingFinished);
|
||||||
|
|
||||||
m_new_model->loadCollections(true, true, true, project_list);
|
m_new_model->loadCollections(true, true, true, project_list);
|
||||||
|
|
||||||
|
if (m_macros_model) {
|
||||||
|
m_macros_model->deleteLater();
|
||||||
|
}
|
||||||
|
m_macros_model = new ElementsCollectionModel(m_macros_tree_view);
|
||||||
|
m_macros_tree_view->setModel(m_macros_model);
|
||||||
|
m_macros_model->loadMacrosCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief ElementsCollectionWidget::loadingFinished
|
* @brief ElementsCollectionWidget::loadingFinished
|
||||||
Process when collection finished to be loaded
|
* Process when collection finished to be loaded
|
||||||
*/
|
*/
|
||||||
void ElementsCollectionWidget::loadingFinished()
|
void ElementsCollectionWidget::loadingFinished()
|
||||||
{
|
{
|
||||||
if (m_new_model)
|
if (m_new_model)
|
||||||
@@ -842,15 +912,21 @@ void ElementsCollectionWidget::showAndExpandItem(const QModelIndex &index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief ElementsCollectionWidget::elementCollectionItemForIndex
|
* @brief ElementsCollectionWidget::elementCollectionItemForIndex
|
||||||
@param index
|
* @param index
|
||||||
@return The internal pointer of index casted to ElementCollectionItem;
|
* @return The internal pointer of index casted to ElementCollectionItem;
|
||||||
*/
|
*/
|
||||||
ElementCollectionItem *ElementsCollectionWidget::elementCollectionItemForIndex(
|
ElementCollectionItem *ElementsCollectionWidget::elementCollectionItemForIndex(const QModelIndex &index)
|
||||||
const QModelIndex &index) {
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid()) return nullptr;
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return static_cast<ElementCollectionItem*>(
|
if (m_macros_model && index.model() == m_macros_model) {
|
||||||
m_model->itemFromIndex(index));
|
return static_cast<ElementCollectionItem *>(m_macros_model->itemFromIndex(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_model && index.model() == m_model) {
|
||||||
|
return static_cast<ElementCollectionItem *>(m_model->itemFromIndex(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
|
#include <QTabWidget>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
class ElementsCollectionModel;
|
class ElementsCollectionModel;
|
||||||
class QVBoxLayout;
|
class QVBoxLayout;
|
||||||
@@ -90,9 +92,12 @@ class ElementsCollectionWidget : public QWidget
|
|||||||
private:
|
private:
|
||||||
ElementsCollectionModel *m_model = nullptr;
|
ElementsCollectionModel *m_model = nullptr;
|
||||||
ElementsCollectionModel *m_new_model = nullptr;
|
ElementsCollectionModel *m_new_model = nullptr;
|
||||||
|
ElementsCollectionModel *m_macros_model = nullptr;
|
||||||
QLineEdit *m_search_field;
|
QLineEdit *m_search_field;
|
||||||
QTimer m_search_timer;
|
QTimer m_search_timer;
|
||||||
ElementsTreeView *m_tree_view;
|
ElementsTreeView *m_tree_view;
|
||||||
|
ElementsTreeView *m_macros_tree_view = nullptr;
|
||||||
|
QTabWidget *m_tab_widget = nullptr;
|
||||||
QVBoxLayout *m_main_vlayout;
|
QVBoxLayout *m_main_vlayout;
|
||||||
QMenu *m_context_menu;
|
QMenu *m_context_menu;
|
||||||
QModelIndex m_index_at_context_menu;
|
QModelIndex m_index_at_context_menu;
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ QString ElementsLocation::collectionPath(bool protocol) const
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString path = m_collection_path;
|
QString path = m_collection_path;
|
||||||
return path.remove(QRegularExpression("common://|company://|custom://|embed://"));
|
return path.remove(QRegularExpression("common://|company://|custom://|macros://|embed://"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,54 +232,34 @@ QString ElementsLocation::path() const
|
|||||||
(start by common://, company://, custom:// or embed://) or not.
|
(start by common://, company://, custom:// or embed://) or not.
|
||||||
@param path
|
@param path
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ElementsLocation::setPath(const QString &path)
|
void ElementsLocation::setPath(const QString &path)
|
||||||
{
|
{
|
||||||
QString tmp_path = path;
|
QString tmp_path = path;
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
//On windows, we convert backslash to slash
|
|
||||||
tmp_path = QDir::fromNativeSeparators(path);
|
tmp_path = QDir::fromNativeSeparators(path);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
QString macrosPath = QETApp::userMacrosDir();
|
||||||
|
if (macrosPath.endsWith("/")) macrosPath.remove(macrosPath.length() - 1, 1);
|
||||||
|
|
||||||
//There is a project, the path is for an embedded coolection.
|
|
||||||
if (m_project)
|
if (m_project)
|
||||||
{
|
{
|
||||||
m_collection_path = path;
|
m_collection_path = path;
|
||||||
//Add the protocol to the collection path
|
|
||||||
if (!path.startsWith("embed://"))
|
if (!path.startsWith("embed://"))
|
||||||
m_collection_path.prepend("embed://");
|
m_collection_path.prepend("embed://");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//The path start with project, we get the project and the path from the string
|
|
||||||
else if (tmp_path.startsWith("project"))
|
else if (tmp_path.startsWith("project"))
|
||||||
{
|
{
|
||||||
QRegularExpression re
|
QRegularExpression re ("^project(?<project_id>[0-9])\\+(?<collection_path>embed://*.*)$");
|
||||||
("^project(?<project_id>[0-9])\\+(?<collection_path>embed://*.*)$");
|
if (!re.isValid()) return;
|
||||||
if (!re.isValid())
|
|
||||||
{
|
|
||||||
qWarning() <<QObject::tr("this is an error in the code")
|
|
||||||
<< re.errorString()
|
|
||||||
<< re.patternErrorOffset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QRegularExpressionMatch match = re.match(tmp_path);
|
QRegularExpressionMatch match = re.match(tmp_path);
|
||||||
if (!match.hasMatch())
|
if (!match.hasMatch()) return;
|
||||||
{
|
|
||||||
qDebug()<<"no Match => return"
|
|
||||||
<<tmp_path;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool conv_ok;
|
bool conv_ok;
|
||||||
uint project_id = match.captured("project_id").toUInt(&conv_ok);
|
uint project_id = match.captured("project_id").toUInt(&conv_ok);
|
||||||
if (!conv_ok)
|
if (!conv_ok) return;
|
||||||
{
|
|
||||||
qWarning()<<"toUint failed"
|
|
||||||
<<match.captured("project_id")
|
|
||||||
<<re
|
|
||||||
<<tmp_path;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QETProject *project = QETApp::project(project_id);
|
QETProject *project = QETApp::project(project_id);
|
||||||
if (project)
|
if (project)
|
||||||
{
|
{
|
||||||
@@ -287,10 +267,7 @@ void ElementsLocation::setPath(const QString &path)
|
|||||||
m_project = project;
|
m_project = project;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (path.startsWith("common://") || path.startsWith("company://") || path.startsWith("custom://") || path.startsWith("macros://"))
|
||||||
// The path is in file system,
|
|
||||||
// the given path is relative to common or custom collection
|
|
||||||
else if (path.startsWith("common://") || path.startsWith("company://") || path.startsWith("custom://"))
|
|
||||||
{
|
{
|
||||||
QString p;
|
QString p;
|
||||||
if (path.startsWith("common://"))
|
if (path.startsWith("common://"))
|
||||||
@@ -303,6 +280,11 @@ void ElementsLocation::setPath(const QString &path)
|
|||||||
tmp_path.remove("company://");
|
tmp_path.remove("company://");
|
||||||
p = QETApp::companyElementsDirN() % "/" % tmp_path;
|
p = QETApp::companyElementsDirN() % "/" % tmp_path;
|
||||||
}
|
}
|
||||||
|
else if (path.startsWith("macros://"))
|
||||||
|
{
|
||||||
|
tmp_path.remove("macros://");
|
||||||
|
p = macrosPath % "/" % tmp_path;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmp_path.remove("custom://");
|
tmp_path.remove("custom://");
|
||||||
@@ -312,11 +294,10 @@ void ElementsLocation::setPath(const QString &path)
|
|||||||
m_file_system_path = p;
|
m_file_system_path = p;
|
||||||
m_collection_path = path;
|
m_collection_path = path;
|
||||||
}
|
}
|
||||||
//In this case, the path is supposed to be relative to the file system.
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString path_ = path;
|
QString path_ = path;
|
||||||
if(path_.endsWith(".elmt"))
|
if(path_.endsWith(".elmt") || path_.endsWith(".qetmak"))
|
||||||
{
|
{
|
||||||
m_file_system_path = path_;
|
m_file_system_path = path_;
|
||||||
if (path_.startsWith(QETApp::commonElementsDirN()))
|
if (path_.startsWith(QETApp::commonElementsDirN()))
|
||||||
@@ -331,6 +312,13 @@ void ElementsLocation::setPath(const QString &path)
|
|||||||
path_.prepend("company://");
|
path_.prepend("company://");
|
||||||
m_collection_path = path_;
|
m_collection_path = path_;
|
||||||
}
|
}
|
||||||
|
else if (path_.startsWith(macrosPath))
|
||||||
|
{
|
||||||
|
QString matchPath = macrosPath + "/";
|
||||||
|
path_.remove(matchPath);
|
||||||
|
path_.prepend("macros://");
|
||||||
|
m_collection_path = path_;
|
||||||
|
}
|
||||||
else if (path_.startsWith(QETApp::customElementsDirN()))
|
else if (path_.startsWith(QETApp::customElementsDirN()))
|
||||||
{
|
{
|
||||||
path_.remove(QETApp::customElementsDirN()+="/");
|
path_.remove(QETApp::customElementsDirN()+="/");
|
||||||
@@ -353,6 +341,13 @@ void ElementsLocation::setPath(const QString &path)
|
|||||||
path_.prepend("company://");
|
path_.prepend("company://");
|
||||||
m_collection_path = path_;
|
m_collection_path = path_;
|
||||||
}
|
}
|
||||||
|
else if (path_.startsWith(macrosPath))
|
||||||
|
{
|
||||||
|
QString matchPath = macrosPath + "/";
|
||||||
|
path_.remove(matchPath);
|
||||||
|
path_.prepend("macros://");
|
||||||
|
m_collection_path = path_;
|
||||||
|
}
|
||||||
else if (path_.startsWith(QETApp::customElementsDirN()))
|
else if (path_.startsWith(QETApp::customElementsDirN()))
|
||||||
{
|
{
|
||||||
path_.remove(QETApp::customElementsDirN()+="/");
|
path_.remove(QETApp::customElementsDirN()+="/");
|
||||||
@@ -371,10 +366,11 @@ void ElementsLocation::setPath(const QString &path)
|
|||||||
*/
|
*/
|
||||||
bool ElementsLocation::addToPath(const QString &string)
|
bool ElementsLocation::addToPath(const QString &string)
|
||||||
{
|
{
|
||||||
if (m_collection_path.endsWith(".elmt", Qt::CaseInsensitive))
|
if (m_collection_path.endsWith(".elmt", Qt::CaseInsensitive) ||
|
||||||
|
m_collection_path.endsWith(".qetmak", Qt::CaseInsensitive))
|
||||||
{
|
{
|
||||||
qDebug() << "ElementsLocation::addToPath :"
|
qDebug() << "ElementsLocation::addToPath :"
|
||||||
" Can't add string to the path of an element";
|
" Can't add string to the path of an element or template";
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,7 +473,7 @@ QString ElementsLocation::toString() const
|
|||||||
*/
|
*/
|
||||||
bool ElementsLocation::isElement() const
|
bool ElementsLocation::isElement() const
|
||||||
{
|
{
|
||||||
return m_collection_path.endsWith(".elmt");
|
return m_collection_path.endsWith(".elmt") || m_collection_path.endsWith(".qetmak");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -942,3 +938,14 @@ QDebug operator<< (QDebug debug, const ElementsLocation &location)
|
|||||||
|
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ElementsLocation::isMacrosCollection
|
||||||
|
* @return True if this location represent an item from the macros collection
|
||||||
|
*/
|
||||||
|
bool ElementsLocation::isMacrosCollection() const
|
||||||
|
{
|
||||||
|
QString macrosPath = QETApp::userMacrosDir();
|
||||||
|
if (macrosPath.endsWith("/")) macrosPath.remove(macrosPath.length() - 1, 1);
|
||||||
|
return fileSystemPath().startsWith(macrosPath);
|
||||||
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class ElementsLocation
|
|||||||
bool isCommonCollection() const;
|
bool isCommonCollection() const;
|
||||||
bool isCompanyCollection() const;
|
bool isCompanyCollection() const;
|
||||||
bool isCustomCollection() const;
|
bool isCustomCollection() const;
|
||||||
|
bool isMacrosCollection() const;
|
||||||
bool isProject() const;
|
bool isProject() const;
|
||||||
bool exist() const;
|
bool exist() const;
|
||||||
bool isWritable() const;
|
bool isWritable() const;
|
||||||
|
|||||||
@@ -22,7 +22,12 @@
|
|||||||
#include "../qeticons.h"
|
#include "../qeticons.h"
|
||||||
#include "elementcollectionitem.h"
|
#include "elementcollectionitem.h"
|
||||||
#include "elementslocation.h"
|
#include "elementslocation.h"
|
||||||
|
#include "../qetproject.h"
|
||||||
|
#include "../diagram.h"
|
||||||
|
#include "xmlelementcollection.h"
|
||||||
|
#include "../NameList/nameslist.h"
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QScopedPointer>
|
||||||
#include <QDrag>
|
#include <QDrag>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
@@ -98,6 +103,104 @@ void ElementsTreeView::startElementDrag(const ElementsLocation &location)
|
|||||||
location_str.toLatin1());
|
location_str.toLatin1());
|
||||||
drag->setPixmap(QET::Icons::Folder.pixmap(22, 22));
|
drag->setPixmap(QET::Icons::Folder.pixmap(22, 22));
|
||||||
}
|
}
|
||||||
|
else if (location.fileName().endsWith(".qetmak"))
|
||||||
|
{
|
||||||
|
mime_data->setData("application/x-qet-element-uri", location_str.toLatin1());
|
||||||
|
|
||||||
|
QPixmap macro_pixmap;
|
||||||
|
|
||||||
|
// --- MINI-RENDERER FÜR DAS MAKRO-VORSCHAUBILD ---
|
||||||
|
QFile file(location.fileSystemPath());
|
||||||
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
QDomDocument macro_doc;
|
||||||
|
if (macro_doc.setContent(&file)) {
|
||||||
|
QDomElement root = macro_doc.documentElement();
|
||||||
|
if (root.tagName() == "qet_macro") {
|
||||||
|
|
||||||
|
// 1. Unsichtbares Dummy-Projekt erstellen
|
||||||
|
QScopedPointer<QETProject> dummy_project(new QETProject());
|
||||||
|
|
||||||
|
// 2. Bauteile in das Dummy-Projekt laden (wie beim echten Drop)
|
||||||
|
QDomElement collection_node = root.firstChildElement("collection");
|
||||||
|
if (!collection_node.isNull()) {
|
||||||
|
QDomNodeList elements = collection_node.elementsByTagName("element");
|
||||||
|
for (int i = 0; i < elements.count(); ++i) {
|
||||||
|
QDomElement elmt_node = elements.at(i).toElement();
|
||||||
|
QString path = elmt_node.attribute("path");
|
||||||
|
QDomElement definition = elmt_node.firstChildElement("definition");
|
||||||
|
if (!path.isEmpty() && !definition.isNull()) {
|
||||||
|
int last_slash = path.lastIndexOf('/');
|
||||||
|
QString dir_path = (last_slash != -1) ? path.left(last_slash) : "";
|
||||||
|
QString file_name = (last_slash != -1) ? path.mid(last_slash + 1) : path;
|
||||||
|
|
||||||
|
if (!dir_path.isEmpty()) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||||
|
QStringList parts = dir_path.split('/', QString::SkipEmptyParts);
|
||||||
|
#else
|
||||||
|
QStringList parts = dir_path.split('/', Qt::SkipEmptyParts);
|
||||||
|
#endif
|
||||||
|
QString current_path = "";
|
||||||
|
for (const QString &part : parts) {
|
||||||
|
QString parent_path = current_path;
|
||||||
|
if (!current_path.isEmpty()) current_path += "/";
|
||||||
|
current_path += part;
|
||||||
|
if (current_path == "import") continue;
|
||||||
|
NamesList empty_names;
|
||||||
|
dummy_project->embeddedElementCollection()->createDir(parent_path, part, empty_names);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dummy_project->embeddedElementCollection()->addElementDefinition(dir_path, file_name, definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Diagram *dummy_diagram = dummy_project->addNewDiagram();
|
||||||
|
|
||||||
|
// 4. Makro auf dem unsichtbaren Blatt zeichnen
|
||||||
|
QDomElement diagram_content_node = root.firstChildElement("diagram_content");
|
||||||
|
QDomElement diagram_node = diagram_content_node.firstChildElement("diagram");
|
||||||
|
if (!diagram_node.isNull()) {
|
||||||
|
QDomNodeList instances = diagram_node.elementsByTagName("element");
|
||||||
|
for (int i = 0; i < instances.count(); ++i) {
|
||||||
|
QDomElement inst = instances.at(i).toElement();
|
||||||
|
QString type = inst.attribute("type");
|
||||||
|
if (type.startsWith("macro://")) {
|
||||||
|
inst.setAttribute("type", type.replace("macro://", "embed://"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dummy_diagram->fromXml(diagram_node, QPointF(0, 0), false, nullptr);
|
||||||
|
dummy_diagram->clearSelection();
|
||||||
|
|
||||||
|
// 5. "Screenshot" (Pixmap) von den gezeichneten Elementen machen
|
||||||
|
QRectF scene_rect = dummy_diagram->itemsBoundingRect();
|
||||||
|
if (!scene_rect.isEmpty()) {
|
||||||
|
scene_rect.adjust(-5, -5, 5, 5); // Kleiner Rand
|
||||||
|
macro_pixmap = QPixmap(scene_rect.size().toSize());
|
||||||
|
macro_pixmap.fill(Qt::transparent); // Transparenter Hintergrund
|
||||||
|
|
||||||
|
QPainter painter(¯o_pixmap);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
dummy_diagram->render(&painter, macro_pixmap.rect(), scene_rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (macro_pixmap.isNull()) {
|
||||||
|
macro_pixmap = QET::Icons::Project.pixmap(32, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bild verkleinern, falls das Makro gigantisch groß ist
|
||||||
|
if (macro_pixmap.width() > MAX_DND_PIXMAP_WIDTH || macro_pixmap.height() > MAX_DND_PIXMAP_HEIGHT) {
|
||||||
|
macro_pixmap = macro_pixmap.scaled(MAX_DND_PIXMAP_WIDTH, MAX_DND_PIXMAP_HEIGHT, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
drag->setPixmap(macro_pixmap);
|
||||||
|
// Bild zentriert an die Maus hängen
|
||||||
|
drag->setHotSpot(QPoint(macro_pixmap.width() / 2, macro_pixmap.height() / 2));
|
||||||
|
}
|
||||||
else if (location.isElement())
|
else if (location.isElement())
|
||||||
{
|
{
|
||||||
mime_data->setData("application/x-qet-element-uri",
|
mime_data->setData("application/x-qet-element-uri",
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ QString FileElementCollectionItem::dirPath() const
|
|||||||
*/
|
*/
|
||||||
bool FileElementCollectionItem::isDir() const
|
bool FileElementCollectionItem::isDir() const
|
||||||
{
|
{
|
||||||
if (m_path.endsWith(".elmt"))
|
if (m_path.endsWith(".elmt") || m_path.endsWith(".qetmak"))
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
@@ -110,9 +110,9 @@ bool FileElementCollectionItem::isElement() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief FileElementCollectionItem::localName
|
* @brief FileElementCollectionItem::localName
|
||||||
@return the located name of this item
|
* @return the located name of this item
|
||||||
*/
|
*/
|
||||||
QString FileElementCollectionItem::localName()
|
QString FileElementCollectionItem::localName()
|
||||||
{
|
{
|
||||||
if (!text().isNull())
|
if (!text().isNull())
|
||||||
@@ -120,12 +120,17 @@ QString FileElementCollectionItem::localName()
|
|||||||
|
|
||||||
else if (isDir()) {
|
else if (isDir()) {
|
||||||
if (isCollectionRoot()) {
|
if (isCollectionRoot()) {
|
||||||
|
QString macrosPath = QETApp::userMacrosDir();
|
||||||
|
if (macrosPath.endsWith("/")) macrosPath.remove(macrosPath.length() - 1, 1);
|
||||||
|
|
||||||
if (m_path == QETApp::commonElementsDirN())
|
if (m_path == QETApp::commonElementsDirN())
|
||||||
setText(QObject::tr("Collection QET"));
|
setText(QObject::tr("Collection QET"));
|
||||||
else if (m_path == QETApp::companyElementsDirN())
|
else if (m_path == QETApp::companyElementsDirN())
|
||||||
setText(QObject::tr("Collection Company"));
|
setText(QObject::tr("Collection Company"));
|
||||||
else if (m_path == QETApp::customElementsDirN())
|
else if (m_path == QETApp::customElementsDirN())
|
||||||
setText(QObject::tr("Collection utilisateur"));
|
setText(QObject::tr("Collection utilisateur"));
|
||||||
|
else if (m_path == macrosPath)
|
||||||
|
setText(QObject::tr("Makros"));
|
||||||
else
|
else
|
||||||
setText(QObject::tr("Collection inconnue"));
|
setText(QObject::tr("Collection inconnue"));
|
||||||
}
|
}
|
||||||
@@ -147,7 +152,11 @@ QString FileElementCollectionItem::localName()
|
|||||||
}
|
}
|
||||||
else if (isElement()) {
|
else if (isElement()) {
|
||||||
ElementsLocation loc(collectionPath());
|
ElementsLocation loc(collectionPath());
|
||||||
setText(loc.name());
|
QString display_name = loc.name();
|
||||||
|
if (display_name.endsWith(".qetmak")) {
|
||||||
|
display_name.remove(".qetmak");
|
||||||
|
}
|
||||||
|
setText(display_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return text();
|
return text();
|
||||||
@@ -169,7 +178,12 @@ QString FileElementCollectionItem::localName(const ElementsLocation &location)
|
|||||||
localName();
|
localName();
|
||||||
}
|
}
|
||||||
else if (isElement()) {
|
else if (isElement()) {
|
||||||
setText(location.name());
|
QString display_name = location.name();
|
||||||
|
// Schneide die Endung .qetmak für die Anzeige ab
|
||||||
|
if (display_name.endsWith(".qetmak")) {
|
||||||
|
display_name.remove(".qetmak");
|
||||||
|
}
|
||||||
|
setText(display_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return text();
|
return text();
|
||||||
@@ -194,10 +208,15 @@ QString FileElementCollectionItem::name() const
|
|||||||
QString FileElementCollectionItem::collectionPath() const
|
QString FileElementCollectionItem::collectionPath() const
|
||||||
{
|
{
|
||||||
if (isCollectionRoot()) {
|
if (isCollectionRoot()) {
|
||||||
|
QString macrosPath = QETApp::userMacrosDir();
|
||||||
|
if (macrosPath.endsWith("/")) macrosPath.remove(macrosPath.length() - 1, 1);
|
||||||
|
|
||||||
if (m_path == QETApp::commonElementsDirN())
|
if (m_path == QETApp::commonElementsDirN())
|
||||||
return "common://";
|
return "common://";
|
||||||
else if (m_path == QETApp::companyElementsDirN())
|
else if (m_path == QETApp::companyElementsDirN())
|
||||||
return "company://";
|
return "company://";
|
||||||
|
else if (m_path == macrosPath)
|
||||||
|
return "macros://"; // <-- NEU: Protokoll für Makros zuweisen
|
||||||
else
|
else
|
||||||
return "custom://";
|
return "custom://";
|
||||||
}
|
}
|
||||||
@@ -220,9 +239,13 @@ QString FileElementCollectionItem::collectionPath() const
|
|||||||
*/
|
*/
|
||||||
bool FileElementCollectionItem::isCollectionRoot() const
|
bool FileElementCollectionItem::isCollectionRoot() const
|
||||||
{
|
{
|
||||||
|
QString macrosPath = QETApp::userMacrosDir();
|
||||||
|
if (macrosPath.endsWith("/")) macrosPath.remove(macrosPath.length() - 1, 1);
|
||||||
|
|
||||||
if (m_path == QETApp::commonElementsDirN()
|
if (m_path == QETApp::commonElementsDirN()
|
||||||
|| m_path == QETApp::companyElementsDirN()
|
|| m_path == QETApp::companyElementsDirN()
|
||||||
|| m_path == QETApp::customElementsDirN())
|
|| m_path == QETApp::customElementsDirN()
|
||||||
|
|| m_path == macrosPath)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
@@ -318,10 +341,15 @@ void FileElementCollectionItem::setUpIcon()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (isCollectionRoot()) {
|
if (isCollectionRoot()) {
|
||||||
|
QString macrosPath = QETApp::userMacrosDir();
|
||||||
|
if (macrosPath.endsWith("/")) macrosPath.remove(macrosPath.length() - 1, 1);
|
||||||
|
|
||||||
if (m_path == QETApp::commonElementsDirN())
|
if (m_path == QETApp::commonElementsDirN())
|
||||||
setIcon(QIcon(":/ico/16x16/qet.png"));
|
setIcon(QIcon(":/ico/16x16/qet.png"));
|
||||||
else if (m_path == QETApp::companyElementsDirN())
|
else if (m_path == QETApp::companyElementsDirN())
|
||||||
setIcon(QIcon(":/ico/16x16/go-company.png"));
|
setIcon(QIcon(":/ico/16x16/go-company.png"));
|
||||||
|
else if (m_path == macrosPath)
|
||||||
|
setIcon(QIcon(":/ico/16x16/go-home.png")); // <-- NEU: Icon für Makros (z.B. go-home)
|
||||||
else
|
else
|
||||||
setIcon(QIcon(":/ico/16x16/go-home.png"));
|
setIcon(QIcon(":/ico/16x16/go-home.png"));
|
||||||
}
|
}
|
||||||
@@ -352,8 +380,8 @@ void FileElementCollectionItem::setPathName(const QString& path_name,
|
|||||||
{
|
{
|
||||||
m_path = path_name;
|
m_path = path_name;
|
||||||
|
|
||||||
//This isn't an element, we create the childs
|
//This isn't an element or template, we create the childs
|
||||||
if (!path_name.endsWith(".elmt"))
|
if (!path_name.endsWith(".elmt") && !path_name.endsWith(".qetmak"))
|
||||||
populate(set_data, hide_element);
|
populate(set_data, hide_element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +410,7 @@ void FileElementCollectionItem::populate(bool set_data, bool hide_element)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//Get all elmt file in this directory
|
//Get all elmt file in this directory
|
||||||
dir.setNameFilters(QStringList() << "*.elmt");
|
dir.setNameFilters(QStringList() << "*.elmt" << "*.qetmak");
|
||||||
for (auto& str :
|
for (auto& str :
|
||||||
dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name))
|
dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name))
|
||||||
{
|
{
|
||||||
@@ -393,3 +421,15 @@ void FileElementCollectionItem::populate(bool set_data, bool hide_element)
|
|||||||
feci->setUpData();
|
feci->setUpData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FileElementCollectionItem::isMacrosCollection
|
||||||
|
* @return True if this item represent the macros collection
|
||||||
|
*/
|
||||||
|
bool FileElementCollectionItem::isMacrosCollection() const
|
||||||
|
{
|
||||||
|
QString macrosPath = QETApp::userMacrosDir();
|
||||||
|
if (macrosPath.endsWith("/")) macrosPath.remove(macrosPath.length() - 1, 1);
|
||||||
|
|
||||||
|
return fileSystemPath().startsWith(macrosPath);
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class FileElementCollectionItem : public ElementCollectionItem
|
|||||||
bool isCommonCollection() const;
|
bool isCommonCollection() const;
|
||||||
bool isCompanyCollection() const;
|
bool isCompanyCollection() const;
|
||||||
bool isCustomCollection() const;
|
bool isCustomCollection() const;
|
||||||
|
bool isMacrosCollection() const;
|
||||||
void addChildAtPath(const QString &collection_name) override;
|
void addChildAtPath(const QString &collection_name) override;
|
||||||
|
|
||||||
void setUpData() override;
|
void setUpData() override;
|
||||||
|
|||||||
260
sources/diagramevent/diagrameventaddmacro.cpp
Normal file
260
sources/diagramevent/diagrameventaddmacro.cpp
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2026 The QElectroTech Team
|
||||||
|
* This file is part of QElectroTech.
|
||||||
|
*/
|
||||||
|
#include "diagrameventaddmacro.h"
|
||||||
|
|
||||||
|
#include "../diagram.h"
|
||||||
|
#include "../qetapp.h"
|
||||||
|
#include "../qetdiagrameditor.h"
|
||||||
|
#include "../qetproject.h"
|
||||||
|
#include "../ElementsCollection/xmlelementcollection.h"
|
||||||
|
#include "../NameList/nameslist.h"
|
||||||
|
#include "../diagramcommands.h"
|
||||||
|
#include "../diagramcontent.h"
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
#include <QStatusBar>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
DiagramEventAddMacro::DiagramEventAddMacro(const ElementsLocation &location, Diagram *diagram, QPointF pos) :
|
||||||
|
DiagramEventInterface(diagram),
|
||||||
|
m_location(location),
|
||||||
|
m_preview_item(nullptr)
|
||||||
|
{
|
||||||
|
if (loadMacro()) {
|
||||||
|
init();
|
||||||
|
|
||||||
|
QScopedPointer<QETProject> dummy_project(new QETProject());
|
||||||
|
QDomElement root = m_macro_doc.documentElement();
|
||||||
|
|
||||||
|
QDomElement collection_node = root.firstChildElement("collection");
|
||||||
|
if (!collection_node.isNull()) {
|
||||||
|
QDomNodeList elements = collection_node.elementsByTagName("element");
|
||||||
|
for (int i = 0; i < elements.count(); ++i) {
|
||||||
|
QDomElement elmt_node = elements.at(i).toElement();
|
||||||
|
QString path = elmt_node.attribute("path");
|
||||||
|
QDomElement definition = elmt_node.firstChildElement("definition");
|
||||||
|
|
||||||
|
if (!path.isEmpty() && !definition.isNull()) {
|
||||||
|
int last_slash = path.lastIndexOf('/');
|
||||||
|
QString dir_path = (last_slash != -1) ? path.left(last_slash) : "";
|
||||||
|
QString file_name = (last_slash != -1) ? path.mid(last_slash + 1) : path;
|
||||||
|
|
||||||
|
if (!dir_path.isEmpty()) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||||
|
QStringList parts = dir_path.split('/', QString::SkipEmptyParts);
|
||||||
|
#else
|
||||||
|
QStringList parts = dir_path.split('/', Qt::SkipEmptyParts);
|
||||||
|
#endif
|
||||||
|
QString current_path = "";
|
||||||
|
for (const QString &part : parts) {
|
||||||
|
QString parent_path = current_path;
|
||||||
|
if (!current_path.isEmpty()) current_path += "/";
|
||||||
|
current_path += part;
|
||||||
|
if (current_path == "import") continue;
|
||||||
|
NamesList empty_names;
|
||||||
|
dummy_project->embeddedElementCollection()->createDir(parent_path, part, empty_names);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dummy_project->embeddedElementCollection()->addElementDefinition(dir_path, file_name, definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Diagram *dummy_diagram = dummy_project->addNewDiagram();
|
||||||
|
QDomElement diagram_node = root.firstChildElement("diagram_content").firstChildElement("diagram");
|
||||||
|
|
||||||
|
if (!diagram_node.isNull()) {
|
||||||
|
dummy_diagram->fromXml(diagram_node, QPointF(0, 0), false, nullptr);
|
||||||
|
|
||||||
|
QRectF scene_rect = dummy_diagram->itemsBoundingRect();
|
||||||
|
if (!scene_rect.isEmpty()) {
|
||||||
|
QPixmap pixmap(scene_rect.toAlignedRect().size());
|
||||||
|
pixmap.fill(Qt::transparent);
|
||||||
|
QPainter painter(&pixmap);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
dummy_diagram->render(&painter, QRectF(QPointF(0,0), scene_rect.size()), scene_rect);
|
||||||
|
|
||||||
|
m_preview_item = new QGraphicsPixmapItem(pixmap);
|
||||||
|
m_preview_item->setOffset(scene_rect.topLeft());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_preview_item) {
|
||||||
|
m_preview_item->setPos(Diagram::snapToGrid(pos));
|
||||||
|
m_preview_item->setOpacity(0.6);
|
||||||
|
m_diagram->addItem(m_preview_item);
|
||||||
|
m_running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!diagram->views().isEmpty()) {
|
||||||
|
const auto qde = QETApp::diagramEditorAncestorOf(diagram->views().at(0));
|
||||||
|
if (qde) {
|
||||||
|
m_status_bar = qde->statusBar();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_status_bar.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DiagramEventAddMacro::~DiagramEventAddMacro()
|
||||||
|
{
|
||||||
|
if (m_preview_item) {
|
||||||
|
m_diagram->removeItem(m_preview_item);
|
||||||
|
delete m_preview_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_status_bar) {
|
||||||
|
m_status_bar->clearMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto view : m_diagram->views())
|
||||||
|
view->setContextMenuPolicy(Qt::DefaultContextMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiagramEventAddMacro::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (m_preview_item) {
|
||||||
|
const auto pos_{Diagram::snapToGrid(event->scenePos())};
|
||||||
|
m_preview_item->setPos(pos_);
|
||||||
|
|
||||||
|
if (m_status_bar) {
|
||||||
|
m_status_bar->showMessage(QString("x %1 : y %2 (Makro-Anker)").arg(QString::number(pos_.x()), QString::number(pos_.y())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event->setAccepted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiagramEventAddMacro::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
event->setAccepted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiagramEventAddMacro::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (m_preview_item) {
|
||||||
|
if (event->button() == Qt::RightButton) {
|
||||||
|
m_diagram->removeItem(m_preview_item);
|
||||||
|
delete m_preview_item;
|
||||||
|
m_preview_item = nullptr;
|
||||||
|
m_running = false;
|
||||||
|
emit finish();
|
||||||
|
}
|
||||||
|
else if (event->button() == Qt::LeftButton) {
|
||||||
|
addMacro(Diagram::snapToGrid(event->scenePos()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event->setAccepted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiagramEventAddMacro::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (m_preview_item && (event->button() == Qt::LeftButton)) {
|
||||||
|
m_diagram->removeItem(m_preview_item);
|
||||||
|
delete m_preview_item;
|
||||||
|
m_preview_item = nullptr;
|
||||||
|
m_running = false;
|
||||||
|
emit finish();
|
||||||
|
}
|
||||||
|
event->setAccepted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiagramEventAddMacro::keyPressEvent(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
DiagramEventInterface::keyPressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiagramEventAddMacro::init()
|
||||||
|
{
|
||||||
|
foreach(QGraphicsView *view, m_diagram->views())
|
||||||
|
view->setContextMenuPolicy(Qt::NoContextMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DiagramEventAddMacro::loadMacro()
|
||||||
|
{
|
||||||
|
QFile file(m_location.fileSystemPath());
|
||||||
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
qDebug() << "Error: Macro file could not be read:" << m_location.fileSystemPath();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_macro_doc.setContent(&file)) {
|
||||||
|
qDebug() << "Error: Invalid XML in macro.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDomElement root = m_macro_doc.documentElement();
|
||||||
|
if (root.tagName() != "qet_macro") return false;
|
||||||
|
|
||||||
|
QDomElement collection_node = root.firstChildElement("collection");
|
||||||
|
if (!collection_node.isNull()) {
|
||||||
|
QDomNodeList elements = collection_node.elementsByTagName("element");
|
||||||
|
for (int i = 0; i < elements.count(); ++i) {
|
||||||
|
QDomElement elmt_node = elements.at(i).toElement();
|
||||||
|
QString path = elmt_node.attribute("path");
|
||||||
|
QDomElement definition = elmt_node.firstChildElement("definition");
|
||||||
|
|
||||||
|
if (!path.isEmpty() && !definition.isNull()) {
|
||||||
|
int last_slash = path.lastIndexOf('/');
|
||||||
|
QString dir_path = (last_slash != -1) ? path.left(last_slash) : "";
|
||||||
|
QString file_name = (last_slash != -1) ? path.mid(last_slash + 1) : path;
|
||||||
|
|
||||||
|
if (!dir_path.isEmpty()) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||||
|
QStringList parts = dir_path.split('/', QString::SkipEmptyParts);
|
||||||
|
#else
|
||||||
|
QStringList parts = dir_path.split('/', Qt::SkipEmptyParts);
|
||||||
|
#endif
|
||||||
|
QString current_path = "";
|
||||||
|
for (const QString &part : parts) {
|
||||||
|
QString parent_path = current_path;
|
||||||
|
if (!current_path.isEmpty()) current_path += "/";
|
||||||
|
current_path += part;
|
||||||
|
if (current_path == "import") continue;
|
||||||
|
NamesList empty_names;
|
||||||
|
m_diagram->project()->embeddedElementCollection()->createDir(parent_path, part, empty_names);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_diagram->project()->embeddedElementCollection()->addElementDefinition(dir_path, file_name, definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QDomElement diagram_node = root.firstChildElement("diagram_content").firstChildElement("diagram");
|
||||||
|
if (!diagram_node.isNull()) {
|
||||||
|
QDomNodeList instances = diagram_node.elementsByTagName("element");
|
||||||
|
for (int i = 0; i < instances.count(); ++i) {
|
||||||
|
QDomElement inst = instances.at(i).toElement();
|
||||||
|
QString type = inst.attribute("type");
|
||||||
|
if (type.startsWith("macro://")) {
|
||||||
|
inst.setAttribute("type", type.replace("macro://", "embed://"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiagramEventAddMacro::addMacro(QPointF final_pos)
|
||||||
|
{
|
||||||
|
QDomElement root = m_macro_doc.documentElement();
|
||||||
|
QDomElement diagram_node = root.firstChildElement("diagram_content").firstChildElement("diagram");
|
||||||
|
|
||||||
|
if (!diagram_node.isNull()) {
|
||||||
|
QDomElement cloned_node = diagram_node.cloneNode(true).toElement();
|
||||||
|
|
||||||
|
QPointF target_pos = final_pos;
|
||||||
|
if (m_preview_item) {
|
||||||
|
target_pos += m_preview_item->offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
DiagramContent pasted_content;
|
||||||
|
|
||||||
|
m_diagram->fromXml(cloned_node, target_pos, false, &pasted_content);
|
||||||
|
m_diagram->refreshContents();
|
||||||
|
|
||||||
|
m_diagram->undoStack().push(new PasteDiagramCommand(m_diagram, pasted_content));
|
||||||
|
}
|
||||||
|
}
|
||||||
45
sources/diagramevent/diagrameventaddmacro.h
Normal file
45
sources/diagramevent/diagrameventaddmacro.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
C opyright 2006-2026 The QEle*ctroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
*/
|
||||||
|
#ifndef DIAGRAMEVENTADDMACRO_H
|
||||||
|
#define DIAGRAMEVENTADDMACRO_H
|
||||||
|
|
||||||
|
#include "../ElementsCollection/elementslocation.h"
|
||||||
|
#include "diagrameventinterface.h"
|
||||||
|
|
||||||
|
#include <QDomDocument>
|
||||||
|
#include <QGraphicsPixmapItem>
|
||||||
|
|
||||||
|
class QStatusBar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The DiagramEventAddMacro class
|
||||||
|
*/
|
||||||
|
class DiagramEventAddMacro : public DiagramEventInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DiagramEventAddMacro(const ElementsLocation &location, Diagram *diagram, QPointF pos = QPointF(0,0));
|
||||||
|
~DiagramEventAddMacro() override;
|
||||||
|
|
||||||
|
void mouseMoveEvent (QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mousePressEvent (QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mouseReleaseEvent (QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void keyPressEvent (QKeyEvent *event) override;
|
||||||
|
void init() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool loadMacro();
|
||||||
|
void addMacro(QPointF final_pos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ElementsLocation m_location;
|
||||||
|
QDomDocument m_macro_doc;
|
||||||
|
QGraphicsPixmapItem *m_preview_item;
|
||||||
|
QPointer<QStatusBar> m_status_bar;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DIAGRAMEVENTADDMACRO_H
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "QPropertyUndoCommand/qpropertyundocommand.h"
|
#include "QPropertyUndoCommand/qpropertyundocommand.h"
|
||||||
#include "diagramcommands.h"
|
#include "diagramcommands.h"
|
||||||
#include "diagramevent/diagrameventaddelement.h"
|
#include "diagramevent/diagrameventaddelement.h"
|
||||||
|
#include "diagramevent/diagrameventaddmacro.h"
|
||||||
#include "dvevent/dveventinterface.h"
|
#include "dvevent/dveventinterface.h"
|
||||||
#include "projectview.h"
|
#include "projectview.h"
|
||||||
#include "qetdiagrameditor.h"
|
#include "qetdiagrameditor.h"
|
||||||
@@ -34,7 +35,9 @@
|
|||||||
#include "utils/conductorcreator.h"
|
#include "utils/conductorcreator.h"
|
||||||
#include "undocommand/addgraphicsobjectcommand.h"
|
#include "undocommand/addgraphicsobjectcommand.h"
|
||||||
#include "diagram.h"
|
#include "diagram.h"
|
||||||
|
#include "ElementsCollection/xmlelementcollection.h"
|
||||||
|
#include "NameList/nameslist.h"
|
||||||
|
#include "elementdialog.h"
|
||||||
#include <QDropEvent>
|
#include <QDropEvent>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,6 +87,10 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
|
|||||||
d.exec();
|
d.exec();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Setup the action to create a template
|
||||||
|
m_create_template = new QAction(tr("Créer un template", "context menu action"), this);
|
||||||
|
connect(m_create_template, SIGNAL(triggered()), this, SLOT(createTemplateFromSelection()));
|
||||||
|
|
||||||
//setup three separators, to be use in context menu
|
//setup three separators, to be use in context menu
|
||||||
for(int i=0 ; i<3 ; ++i)
|
for(int i=0 ; i<3 ; ++i)
|
||||||
{
|
{
|
||||||
@@ -188,10 +195,10 @@ void DiagramView::dropEvent(QDropEvent *e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief DiagramView::handleElementDrop
|
* @brief DiagramView::handleElementDrop
|
||||||
Handle the drop of an element.
|
* Handle the drop of an element.
|
||||||
@param event the QDropEvent describing the current drag'n drop
|
* @param event the QDropEvent describing the current drag'n drop
|
||||||
*/
|
*/
|
||||||
void DiagramView::handleElementDrop(QDropEvent *event)
|
void DiagramView::handleElementDrop(QDropEvent *event)
|
||||||
{
|
{
|
||||||
//Build an element from the text of the mime data
|
//Build an element from the text of the mime data
|
||||||
@@ -203,18 +210,18 @@ void DiagramView::handleElementDrop(QDropEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
|
QPointF drop_pos;
|
||||||
diagram()->setEventInterface(
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
|
||||||
new DiagramEventAddElement(
|
drop_pos = mapToScene(event->pos());
|
||||||
location, diagram(), mapToScene(event->pos())));
|
#else
|
||||||
#else
|
drop_pos = event->position();
|
||||||
#if TODO_LIST
|
#endif
|
||||||
#pragma message("@TODO remove code for QT 6 or later")
|
|
||||||
#endif
|
if (location.path().endsWith(".qetmak")) {
|
||||||
diagram()->setEventInterface(
|
diagram()->setEventInterface(new DiagramEventAddMacro(location, diagram(), drop_pos));
|
||||||
new DiagramEventAddElement(
|
} else {
|
||||||
location, diagram(), event->position()));
|
diagram()->setEventInterface(new DiagramEventAddElement(location, diagram(), drop_pos));
|
||||||
#endif
|
}
|
||||||
|
|
||||||
//Set focus to the view to get event
|
//Set focus to the view to get event
|
||||||
this->setFocus();
|
this->setFocus();
|
||||||
@@ -1202,6 +1209,7 @@ QList<QAction *> DiagramView::contextMenuActions() const
|
|||||||
list << qde->m_copy;
|
list << qde->m_copy;
|
||||||
list << m_multi_paste;
|
list << m_multi_paste;
|
||||||
list << m_separators.at(0);
|
list << m_separators.at(0);
|
||||||
|
list << m_create_template; // Add the create template action
|
||||||
list << qde->m_conductor_reset;
|
list << qde->m_conductor_reset;
|
||||||
list << m_separators.at(1);
|
list << m_separators.at(1);
|
||||||
list << qde->m_selection_actions_group.actions();
|
list << qde->m_selection_actions_group.actions();
|
||||||
@@ -1265,6 +1273,101 @@ void DiagramView::contextMenuEvent(QContextMenuEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DiagramView::createTemplateFromSelection
|
||||||
|
* Triggered from the context menu to create a new template (macro) from the current selection.
|
||||||
|
*/
|
||||||
|
void DiagramView::createTemplateFromSelection()
|
||||||
|
{
|
||||||
|
QList<QGraphicsItem *> selected_elements = m_diagram->selectedItems();
|
||||||
|
|
||||||
|
if (selected_elements.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Ready to create a template from" << selected_elements.size() << "elements!";
|
||||||
|
|
||||||
|
// Open the dialog to let the user select where to save the .qetmak file
|
||||||
|
ElementsLocation template_location = ElementDialog::getSaveTemplateLocation(this);
|
||||||
|
|
||||||
|
// Check if the user clicked 'Cancel' or closed the window
|
||||||
|
if (template_location.isNull()) {
|
||||||
|
qDebug() << "User canceled template creation.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Will save template to:" << template_location.path();
|
||||||
|
|
||||||
|
QDomDocument content_xml = m_diagram->toXml(false, true);
|
||||||
|
|
||||||
|
QDomDocument macro_doc;
|
||||||
|
QDomElement root = macro_doc.createElement("qet_macro");
|
||||||
|
macro_doc.appendChild(root);
|
||||||
|
|
||||||
|
QDomElement collection_node = macro_doc.createElement("collection");
|
||||||
|
root.appendChild(collection_node);
|
||||||
|
|
||||||
|
QSet<QString> processed_types;
|
||||||
|
|
||||||
|
QDomNodeList element_nodes = content_xml.elementsByTagName("element");
|
||||||
|
for (int i = 0; i < element_nodes.count(); ++i) {
|
||||||
|
QDomElement elmt_node = element_nodes.at(i).toElement();
|
||||||
|
QString old_type = elmt_node.attribute("type");
|
||||||
|
|
||||||
|
if (old_type.isEmpty()) continue;
|
||||||
|
|
||||||
|
ElementsLocation loc(old_type, m_diagram->project());
|
||||||
|
|
||||||
|
QString clean_path = loc.collectionPath(false);
|
||||||
|
|
||||||
|
QString new_type = "macro://" + clean_path;
|
||||||
|
elmt_node.setAttribute("type", new_type);
|
||||||
|
|
||||||
|
if (!processed_types.contains(clean_path)) {
|
||||||
|
processed_types.insert(clean_path);
|
||||||
|
|
||||||
|
QDomElement definition_node = loc.xml();
|
||||||
|
|
||||||
|
if (!definition_node.isNull()) {
|
||||||
|
QDomElement collection_elmt = macro_doc.createElement("element");
|
||||||
|
collection_elmt.setAttribute("path", clean_path);
|
||||||
|
|
||||||
|
QDomNode imported_def = macro_doc.importNode(definition_node, true);
|
||||||
|
collection_elmt.appendChild(imported_def);
|
||||||
|
|
||||||
|
collection_node.appendChild(collection_elmt);
|
||||||
|
} else {
|
||||||
|
qDebug() << "Warnung: Konnte XML-Definition für" << old_type << "nicht laden.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QDomElement content_container = macro_doc.createElement("diagram_content");
|
||||||
|
root.appendChild(content_container);
|
||||||
|
|
||||||
|
QDomNode imported_node = macro_doc.importNode(content_xml.documentElement(), true);
|
||||||
|
content_container.appendChild(imported_node);
|
||||||
|
|
||||||
|
QString full_path = template_location.fileSystemPath();
|
||||||
|
|
||||||
|
QDir().mkpath(QFileInfo(full_path).absolutePath());
|
||||||
|
|
||||||
|
QFile file(full_path);
|
||||||
|
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
QTextStream out(&file);
|
||||||
|
out.setCodec("UTF-8");
|
||||||
|
out << macro_doc.toString(4);
|
||||||
|
file.close();
|
||||||
|
qDebug() << "Template successfully saved to:" << full_path;
|
||||||
|
|
||||||
|
QMessageBox::information(this, tr("Modèle enregistré"),
|
||||||
|
tr("Le modèle a été enregistré avec succès sous :\n%1").arg(full_path));
|
||||||
|
} else {
|
||||||
|
qDebug() << "Error: Could not open file for writing:" << full_path;
|
||||||
|
QMessageBox::critical(this, tr("Erreur"), tr("Le fichier n'a pas pu être écrit."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@return l'editeur de schemas parent ou 0
|
@return l'editeur de schemas parent ou 0
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#ifndef DIAGRAMVIEW_H
|
#ifndef DIAGRAMVIEW_H
|
||||||
#define DIAGRAMVIEW_H
|
#define DIAGRAMVIEW_H
|
||||||
|
|
||||||
#include "ElementsCollection/elementslocation.h"
|
#include "../ElementsCollection/elementslocation.h"
|
||||||
#include "titleblock/templatelocation.h"
|
#include "titleblock/templatelocation.h"
|
||||||
|
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
@@ -53,6 +53,7 @@ class DiagramView : public QGraphicsView
|
|||||||
DVEventInterface *m_event_interface = nullptr;
|
DVEventInterface *m_event_interface = nullptr;
|
||||||
QAction *m_paste_here = nullptr;
|
QAction *m_paste_here = nullptr;
|
||||||
QAction *m_multi_paste = nullptr;
|
QAction *m_multi_paste = nullptr;
|
||||||
|
QAction *m_create_template = nullptr;
|
||||||
QPoint m_paste_here_pos;
|
QPoint m_paste_here_pos;
|
||||||
QPointF m_drag_last_pos;
|
QPointF m_drag_last_pos;
|
||||||
bool m_fresh_focus_in,
|
bool m_fresh_focus_in,
|
||||||
@@ -133,5 +134,6 @@ class DiagramView : public QGraphicsView
|
|||||||
private slots:
|
private slots:
|
||||||
void adjustGridToZoom();
|
void adjustGridToZoom();
|
||||||
void applyReadOnly();
|
void applyReadOnly();
|
||||||
|
void createTemplateFromSelection();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ void ElementDialog::setUpWidget()
|
|||||||
title_ = tr("Enregistrer une catégorie", "dialog title");
|
title_ = tr("Enregistrer une catégorie", "dialog title");
|
||||||
label_ = tr("Choisissez une catégorie.", "dialog content");
|
label_ = tr("Choisissez une catégorie.", "dialog content");
|
||||||
break;
|
break;
|
||||||
|
case SaveTemplate:
|
||||||
|
title_ = tr("Enregistrer un template", "dialog title");
|
||||||
|
label_ = tr("Choisissez l'emplacement dans lequel vous souhaitez enregistrer votre template.", "dialog content");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
title_ = tr("Titre");
|
title_ = tr("Titre");
|
||||||
label_ = tr("Label");
|
label_ = tr("Label");
|
||||||
@@ -92,10 +96,14 @@ void ElementDialog::setUpWidget()
|
|||||||
foreach(QETProject *prj, QETApp::registeredProjects())
|
foreach(QETProject *prj, QETApp::registeredProjects())
|
||||||
prjs.append(prj);
|
prjs.append(prj);
|
||||||
|
|
||||||
if (m_mode == OpenElement)
|
if (m_mode == OpenElement) {
|
||||||
m_model->loadCollections(true, true, true, prjs);
|
m_model->loadCollections(true, true, true, prjs);
|
||||||
else
|
} else if (m_mode == SaveTemplate) {
|
||||||
|
// Load only the templates/macros collection for the template save dialog
|
||||||
|
m_model->loadMacrosCollection();
|
||||||
|
} else {
|
||||||
m_model->loadCollections(false, true, true, prjs);
|
m_model->loadCollections(false, true, true, prjs);
|
||||||
|
}
|
||||||
|
|
||||||
m_tree_view->setModel(m_model);
|
m_tree_view->setModel(m_model);
|
||||||
m_tree_view->setHeaderHidden(true);
|
m_tree_view->setHeaderHidden(true);
|
||||||
@@ -103,14 +111,21 @@ void ElementDialog::setUpWidget()
|
|||||||
|
|
||||||
m_buttons_box = new QDialogButtonBox(this);
|
m_buttons_box = new QDialogButtonBox(this);
|
||||||
|
|
||||||
if (m_mode == SaveCategory || m_mode == SaveElement)
|
if (m_mode == SaveCategory || m_mode == SaveElement || m_mode == SaveTemplate)
|
||||||
{
|
{
|
||||||
m_buttons_box->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
|
m_buttons_box->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
|
||||||
m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(true);
|
m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(true);
|
||||||
|
|
||||||
m_text_field = new QFileNameEdit();
|
m_text_field = new QFileNameEdit();
|
||||||
m_text_field->setDisabled(true);
|
m_text_field->setDisabled(true);
|
||||||
m_text_field->setPlaceholderText(m_mode == SaveCategory? tr("Nom du nouveau dossier") : tr("Nom du nouvel élément"));
|
|
||||||
|
if (m_mode == SaveCategory) {
|
||||||
|
m_text_field->setPlaceholderText(tr("Nom du nouveau dossier"));
|
||||||
|
} else if (m_mode == SaveTemplate) {
|
||||||
|
m_text_field->setPlaceholderText(tr("Nom du nouveau template"));
|
||||||
|
} else {
|
||||||
|
m_text_field->setPlaceholderText(tr("Nom du nouvel élément"));
|
||||||
|
}
|
||||||
|
|
||||||
layout->addWidget(m_text_field);
|
layout->addWidget(m_text_field);
|
||||||
}
|
}
|
||||||
@@ -156,14 +171,17 @@ void ElementDialog::checkCurrentLocation()
|
|||||||
if (m_mode == OpenElement) {
|
if (m_mode == OpenElement) {
|
||||||
m_buttons_box->button(QDialogButtonBox::Open)->setEnabled(m_location.isElement() && m_location.exist());
|
m_buttons_box->button(QDialogButtonBox::Open)->setEnabled(m_location.isElement() && m_location.exist());
|
||||||
}
|
}
|
||||||
else if (m_mode == SaveElement)
|
else if (m_mode == SaveElement || m_mode == SaveTemplate)
|
||||||
{
|
{
|
||||||
m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(true);
|
m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(true);
|
||||||
|
|
||||||
//Location doesn't exist
|
//Location doesn't exist
|
||||||
if (!m_location.exist()) { return; }
|
if (!m_location.exist()) { return; }
|
||||||
|
|
||||||
if (m_location.isElement())
|
// Accept .elmt for elements, and .qetmak for templates
|
||||||
|
bool is_valid_file = m_location.isElement() || (m_mode == SaveTemplate && m_location.path().endsWith(".qetmak"));
|
||||||
|
|
||||||
|
if (is_valid_file)
|
||||||
{
|
{
|
||||||
m_text_field->setDisabled(true);
|
m_text_field->setDisabled(true);
|
||||||
m_buttons_box->button(QDialogButtonBox::Save)->setEnabled(true);
|
m_buttons_box->button(QDialogButtonBox::Save)->setEnabled(true);
|
||||||
@@ -174,10 +192,10 @@ void ElementDialog::checkCurrentLocation()
|
|||||||
|
|
||||||
if (m_text_field->text().isEmpty()) { return; }
|
if (m_text_field->text().isEmpty()) { return; }
|
||||||
|
|
||||||
//Only enable save button if the location at path :
|
//Only enable save button if the location at path doesn't exist.
|
||||||
//m_location.collectionPath + m_text_filed.text doesn't exist.
|
|
||||||
QString new_path = m_text_field->text();
|
QString new_path = m_text_field->text();
|
||||||
if (!new_path.endsWith(".elmt")) new_path += ".elmt";
|
QString extension = (m_mode == SaveTemplate) ? ".qetmak" : ".elmt";
|
||||||
|
if (!new_path.endsWith(extension)) new_path += extension;
|
||||||
|
|
||||||
ElementsLocation loc = m_location;
|
ElementsLocation loc = m_location;
|
||||||
loc.addToPath(new_path);
|
loc.addToPath(new_path);
|
||||||
@@ -209,15 +227,19 @@ void ElementDialog::checkAccept()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_mode == SaveElement)
|
else if (m_mode == SaveElement || m_mode == SaveTemplate)
|
||||||
{
|
{
|
||||||
if (loc.isElement())
|
bool is_valid_file = loc.isElement() || (m_mode == SaveTemplate && loc.path().endsWith(".qetmak"));
|
||||||
|
|
||||||
|
if (is_valid_file)
|
||||||
{
|
{
|
||||||
if (loc.exist())
|
if (loc.exist())
|
||||||
{
|
{
|
||||||
|
QString msgTitle = (m_mode == SaveTemplate) ? tr("Écraser le template ?", "message box title") : tr("Écraser l'élément ?", "message box title");
|
||||||
|
QString msgContent = (m_mode == SaveTemplate) ? tr("Le template existe déjà. Voulez-vous l'écraser ?", "message box content") : tr("L'élément existe déjà. Voulez-vous l'écraser ?", "message box content");
|
||||||
QMessageBox::StandardButton answer = QET::QetMessageBox::question(this,
|
QMessageBox::StandardButton answer = QET::QetMessageBox::question(this,
|
||||||
tr("Écraser l'élément ?", "message box title"),
|
msgTitle,
|
||||||
tr("L'élément existe déjà. Voulez-vous l'écraser ?", "message box content"),
|
msgContent,
|
||||||
QMessageBox::Yes | QMessageBox::No,
|
QMessageBox::Yes | QMessageBox::No,
|
||||||
QMessageBox::No);
|
QMessageBox::No);
|
||||||
if (answer == QMessageBox::Yes) {accept();}
|
if (answer == QMessageBox::Yes) {accept();}
|
||||||
@@ -248,10 +270,11 @@ ElementsLocation ElementDialog::location() const
|
|||||||
else {return ElementsLocation(); }
|
else {return ElementsLocation(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (m_mode == SaveElement)
|
else if (m_mode == SaveElement || m_mode == SaveTemplate)
|
||||||
{
|
{
|
||||||
//Current selected location is element, we return this location
|
//Current selected location is element or template, we return this location
|
||||||
if (m_location.isElement()) { return m_location; }
|
bool is_valid_file = m_location.isElement() || (m_mode == SaveTemplate && m_location.path().endsWith(".qetmak"));
|
||||||
|
if (is_valid_file) { return m_location; }
|
||||||
|
|
||||||
//Current selected location is directory, we return a location at path :
|
//Current selected location is directory, we return a location at path :
|
||||||
//m_location->collectionPath + m_text_field->text
|
//m_location->collectionPath + m_text_field->text
|
||||||
@@ -260,7 +283,8 @@ ElementsLocation ElementDialog::location() const
|
|||||||
QString new_path = m_text_field->text();
|
QString new_path = m_text_field->text();
|
||||||
if (new_path.isEmpty()) { return ElementsLocation(); }
|
if (new_path.isEmpty()) { return ElementsLocation(); }
|
||||||
|
|
||||||
if (!new_path.endsWith(".elmt")) { new_path += ".elmt"; }
|
QString extension = (m_mode == SaveTemplate) ? ".qetmak" : ".elmt";
|
||||||
|
if (!new_path.endsWith(extension)) { new_path += extension; }
|
||||||
|
|
||||||
ElementsLocation loc = m_location;
|
ElementsLocation loc = m_location;
|
||||||
loc.addToPath(new_path);
|
loc.addToPath(new_path);
|
||||||
@@ -291,6 +315,16 @@ ElementsLocation ElementDialog::getSaveElementLocation(QWidget *parentWidget) {
|
|||||||
return(ElementDialog::execConfiguredDialog(ElementDialog::SaveElement, parentWidget));
|
return(ElementDialog::execConfiguredDialog(ElementDialog::SaveElement, parentWidget));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ElementDialog::getSaveTemplateLocation
|
||||||
|
* Display a dialog that allow to user to select a location for saving a template
|
||||||
|
* @param parentWidget
|
||||||
|
* @return The location where the template must be save
|
||||||
|
*/
|
||||||
|
ElementsLocation ElementDialog::getSaveTemplateLocation(QWidget *parentWidget) {
|
||||||
|
return(ElementDialog::execConfiguredDialog(ElementDialog::SaveTemplate, parentWidget));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief ElementDialog::execConfiguredDialog
|
@brief ElementDialog::execConfiguredDialog
|
||||||
launch a dialog with the chosen mode
|
launch a dialog with the chosen mode
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ class ElementDialog : public QDialog
|
|||||||
OpenElement = 0, ///< The dialog should open an element
|
OpenElement = 0, ///< The dialog should open an element
|
||||||
SaveElement = 1, ///< The dialog should select an element for saving
|
SaveElement = 1, ///< The dialog should select an element for saving
|
||||||
OpenCategory = 2, ///< The dialog should open a category
|
OpenCategory = 2, ///< The dialog should open a category
|
||||||
SaveCategory = 3 ///< The dialog should select a category for saving
|
SaveCategory = 3, ///< The dialog should select a category for saving
|
||||||
|
SaveTemplate = 4 ///< The dialog should select a template for saving
|
||||||
};
|
};
|
||||||
|
|
||||||
// constructors, destructor
|
// constructors, destructor
|
||||||
@@ -74,6 +75,7 @@ class ElementDialog : public QDialog
|
|||||||
public:
|
public:
|
||||||
static ElementsLocation getOpenElementLocation(QWidget *parent = nullptr);
|
static ElementsLocation getOpenElementLocation(QWidget *parent = nullptr);
|
||||||
static ElementsLocation getSaveElementLocation(QWidget *parent = nullptr);
|
static ElementsLocation getSaveElementLocation(QWidget *parent = nullptr);
|
||||||
|
static ElementsLocation getSaveTemplateLocation(QWidget *parent = nullptr);
|
||||||
private:
|
private:
|
||||||
static ElementsLocation execConfiguredDialog(int, QWidget *parent = nullptr);
|
static ElementsLocation execConfiguredDialog(int, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "qeticons.h"
|
#include "qeticons.h"
|
||||||
#include "qetproject.h"
|
#include "qetproject.h"
|
||||||
#include "titleblock/templatedeleter.h"
|
#include "titleblock/templatedeleter.h"
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When the ENABLE_PANEL_WIDGET_DND_CHECKS flag is set, the panel
|
When the ENABLE_PANEL_WIDGET_DND_CHECKS flag is set, the panel
|
||||||
@@ -152,6 +153,11 @@ void ElementsPanelWidget::openDirectoryForSelectedItem()
|
|||||||
if (QTreeWidgetItem *qtwi = elements_panel -> currentItem()) {
|
if (QTreeWidgetItem *qtwi = elements_panel -> currentItem()) {
|
||||||
QString dir_path = elements_panel -> dirPathForItem(qtwi);
|
QString dir_path = elements_panel -> dirPathForItem(qtwi);
|
||||||
if (!dir_path.isEmpty()) {
|
if (!dir_path.isEmpty()) {
|
||||||
|
QFileInfo fileInfo(dir_path);
|
||||||
|
// Wenn der Pfad auf eine Datei (z.B. Makro) zeigt, isoliere den Ordnerpfad
|
||||||
|
if (fileInfo.isFile()) {
|
||||||
|
dir_path = fileInfo.absolutePath();
|
||||||
|
}
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(dir_path));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(dir_path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ QString QETApp::m_user_company_tbt_dir = QString();
|
|||||||
|
|
||||||
QString QETApp::m_user_custom_tbt_dir = QString();
|
QString QETApp::m_user_custom_tbt_dir = QString();
|
||||||
|
|
||||||
|
QString QETApp::m_user_macros_dir = QString();
|
||||||
|
|
||||||
QETApp *QETApp::m_qetapp = nullptr;
|
QETApp *QETApp::m_qetapp = nullptr;
|
||||||
|
|
||||||
bool lang_is_set = false;
|
bool lang_is_set = false;
|
||||||
@@ -724,6 +726,8 @@ void QETApp::resetCollectionsPath()
|
|||||||
m_user_company_tbt_dir.clear();
|
m_user_company_tbt_dir.clear();
|
||||||
|
|
||||||
m_user_custom_tbt_dir.clear();
|
m_user_custom_tbt_dir.clear();
|
||||||
|
|
||||||
|
m_user_macros_dir.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -822,6 +826,38 @@ QString QETApp::customTitleBlockTemplatesDir()
|
|||||||
return(dataDir() + "/titleblocks/");
|
return(dataDir() + "/titleblocks/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QETApp::userMacrosDir
|
||||||
|
* @return the path of the directory containing the user macros collection.
|
||||||
|
*/
|
||||||
|
QString QETApp::userMacrosDir()
|
||||||
|
{
|
||||||
|
if (m_user_macros_dir.isEmpty())
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
QString path = settings.value(
|
||||||
|
"elements-collections/macros-path",
|
||||||
|
"default").toString();
|
||||||
|
if (path != "default" && !path.isEmpty())
|
||||||
|
{
|
||||||
|
QDir dir(path);
|
||||||
|
if (dir.exists())
|
||||||
|
{
|
||||||
|
m_user_macros_dir = path;
|
||||||
|
return m_user_macros_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_user_macros_dir = "default";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_user_macros_dir != "default") {
|
||||||
|
return m_user_macros_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(dataDir() + "/macros/");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief QETApp::configDir
|
@brief QETApp::configDir
|
||||||
Return the QET configuration folder, i.e. the path to the folder in
|
Return the QET configuration folder, i.e. the path to the folder in
|
||||||
@@ -938,6 +974,8 @@ QString QETApp::realPath(const QString &sym_path) {
|
|||||||
directory = commonElementsDir();
|
directory = commonElementsDir();
|
||||||
} else if (sym_path.startsWith("company://")) {
|
} else if (sym_path.startsWith("company://")) {
|
||||||
directory = companyElementsDir();
|
directory = companyElementsDir();
|
||||||
|
} else if (sym_path.startsWith("macros://")) {
|
||||||
|
directory = userMacrosDir();
|
||||||
} else if (sym_path.startsWith("company://")) {
|
} else if (sym_path.startsWith("company://")) {
|
||||||
directory = companyElementsDir();
|
directory = companyElementsDir();
|
||||||
} else if (sym_path.startsWith("custom://")) {
|
} else if (sym_path.startsWith("custom://")) {
|
||||||
@@ -976,6 +1014,7 @@ QString QETApp::symbolicPath(const QString &real_path) {
|
|||||||
QString commond = commonElementsDir();
|
QString commond = commonElementsDir();
|
||||||
QString companyd = companyElementsDir();
|
QString companyd = companyElementsDir();
|
||||||
QString customd = customElementsDir();
|
QString customd = customElementsDir();
|
||||||
|
QString macrosd = userMacrosDir();
|
||||||
QString chemin;
|
QString chemin;
|
||||||
// analyzes the file path passed in parameter
|
// analyzes the file path passed in parameter
|
||||||
// analyse le chemin de fichier passe en parametre
|
// analyse le chemin de fichier passe en parametre
|
||||||
@@ -987,6 +1026,10 @@ QString QETApp::symbolicPath(const QString &real_path) {
|
|||||||
chemin = "company://"
|
chemin = "company://"
|
||||||
+ real_path.right(
|
+ real_path.right(
|
||||||
real_path.length() - companyd.length());
|
real_path.length() - companyd.length());
|
||||||
|
} else if (real_path.startsWith(macrosd)) {
|
||||||
|
chemin = "macros://"
|
||||||
|
+ real_path.right(
|
||||||
|
real_path.length() - macrosd.length());
|
||||||
} else if (real_path.startsWith(customd)) {
|
} else if (real_path.startsWith(customd)) {
|
||||||
chemin = "custom://"
|
chemin = "custom://"
|
||||||
+ real_path.right(
|
+ real_path.right(
|
||||||
@@ -2212,6 +2255,10 @@ void QETApp::initConfiguration()
|
|||||||
if (!custom_tbt_dir.exists())
|
if (!custom_tbt_dir.exists())
|
||||||
custom_tbt_dir.mkpath(QETApp::customTitleBlockTemplatesDir());
|
custom_tbt_dir.mkpath(QETApp::customTitleBlockTemplatesDir());
|
||||||
|
|
||||||
|
QDir macros_dir(QETApp::userMacrosDir());
|
||||||
|
if (!macros_dir.exists())
|
||||||
|
macros_dir.mkpath(QETApp::userMacrosDir());
|
||||||
|
|
||||||
/* recent files
|
/* recent files
|
||||||
* note:
|
* note:
|
||||||
* icons must be initialized before these instructions
|
* icons must be initialized before these instructions
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ class QETApp : public QObject
|
|||||||
static QString commonTitleBlockTemplatesDir();
|
static QString commonTitleBlockTemplatesDir();
|
||||||
static QString companyTitleBlockTemplatesDir();
|
static QString companyTitleBlockTemplatesDir();
|
||||||
static QString customTitleBlockTemplatesDir();
|
static QString customTitleBlockTemplatesDir();
|
||||||
|
static QString userMacrosDir();
|
||||||
static bool registerProject(QETProject *);
|
static bool registerProject(QETProject *);
|
||||||
static bool unregisterProject(QETProject *);
|
static bool unregisterProject(QETProject *);
|
||||||
static QMap<uint, QETProject *> registeredProjects();
|
static QMap<uint, QETProject *> registeredProjects();
|
||||||
@@ -242,7 +243,7 @@ class QETApp : public QObject
|
|||||||
|
|
||||||
static QString m_user_company_tbt_dir;
|
static QString m_user_company_tbt_dir;
|
||||||
static QString m_user_custom_tbt_dir;
|
static QString m_user_custom_tbt_dir;
|
||||||
|
static QString m_user_macros_dir;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void systray(QSystemTrayIcon::ActivationReason);
|
void systray(QSystemTrayIcon::ActivationReason);
|
||||||
|
|||||||
@@ -177,6 +177,15 @@ GeneralConfigurationPage::GeneralConfigurationPage(QWidget *parent) :
|
|||||||
ui->m_custom_tbt_path_cb->blockSignals(false);
|
ui->m_custom_tbt_path_cb->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path = settings.value("elements-collections/macros-path", "default").toString();
|
||||||
|
if (path != "default")
|
||||||
|
{
|
||||||
|
ui->m_user_macros_path_cb->blockSignals(true);
|
||||||
|
ui->m_user_macros_path_cb->setCurrentIndex(1);
|
||||||
|
ui->m_user_macros_path_cb->setItemData(1, path, Qt::DisplayRole);
|
||||||
|
ui->m_user_macros_path_cb->blockSignals(false);
|
||||||
|
}
|
||||||
|
|
||||||
fillLang();
|
fillLang();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,6 +330,21 @@ void GeneralConfigurationPage::applyConf()
|
|||||||
if (path != settings.value("elements-collections/custom-tbt-path").toString()) {
|
if (path != settings.value("elements-collections/custom-tbt-path").toString()) {
|
||||||
QETApp::resetCollectionsPath();
|
QETApp::resetCollectionsPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path = settings.value("elements-collections/macros-path").toString();
|
||||||
|
if (ui->m_user_macros_path_cb->currentIndex() == 1)
|
||||||
|
{
|
||||||
|
QString path = ui->m_user_macros_path_cb->currentText();
|
||||||
|
QDir dir(path);
|
||||||
|
settings.setValue("elements-collections/macros-path",
|
||||||
|
dir.exists() ? path : "default");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
settings.setValue("elements-collections/macros-path", "default");
|
||||||
|
}
|
||||||
|
if (path != settings.value("elements-collections/macros-path").toString()) {
|
||||||
|
QETApp::resetCollectionsPath();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -512,6 +536,19 @@ void GeneralConfigurationPage::on_m_custom_tbt_path_cb_currentIndexChanged(int i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeneralConfigurationPage::on_m_user_macros_path_cb_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (index == 1)
|
||||||
|
{
|
||||||
|
QString path = QFileDialog::getExistingDirectory(this, tr("Chemin des macros utilisateur"), QETApp::documentDir());
|
||||||
|
if (!path.isEmpty()) {
|
||||||
|
ui->m_user_macros_path_cb->setItemData(1, path, Qt::DisplayRole);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui->m_user_macros_path_cb->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GeneralConfigurationPage::on_m_indi_text_font_pb_clicked()
|
void GeneralConfigurationPage::on_m_indi_text_font_pb_clicked()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ class GeneralConfigurationPage : public ConfigPage
|
|||||||
void on_m_custom_elmt_path_cb_currentIndexChanged(int index);
|
void on_m_custom_elmt_path_cb_currentIndexChanged(int index);
|
||||||
void on_m_company_tbt_path_cb_currentIndexChanged(int index);
|
void on_m_company_tbt_path_cb_currentIndexChanged(int index);
|
||||||
void on_m_custom_tbt_path_cb_currentIndexChanged(int index);
|
void on_m_custom_tbt_path_cb_currentIndexChanged(int index);
|
||||||
|
void on_m_user_macros_path_cb_currentIndexChanged(int index);
|
||||||
void on_m_indi_text_font_pb_clicked();
|
void on_m_indi_text_font_pb_clicked();
|
||||||
void on_MaxPartsElementEditorList_sb_valueChanged(int value);
|
void on_MaxPartsElementEditorList_sb_valueChanged(int value);
|
||||||
void on_DiagramEditor_Grid_PointSize_min_sb_valueChanged(int value);
|
void on_DiagramEditor_Grid_PointSize_min_sb_valueChanged(int value);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab_3">
|
<widget class="QWidget" name="tab_3">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@@ -349,6 +349,27 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="text">
|
||||||
|
<string>Répertoire des Macros utilisateur</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QComboBox" name="m_user_macros_path_cb">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Par defaut</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Parcourir...</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user