[qet] qet/qet: [5658] Search and replace : We can now replace a properties text (diagram, element, conductor, diagram text) with regular expression

[ Thread Index | Date Index | More lists.tuxfamily.org/qet Archives ]


Revision: 5658
Author:   blacksun
Date:     2018-12-21 19:08:58 +0100 (Fri, 21 Dec 2018)
Log Message:
-----------
Search and replace : We can now replace a properties text (diagram, element, conductor, diagram text) with regular expression 

Modified Paths:
--------------
    trunk/sources/SearchAndReplace/searchandreplaceworker.cpp
    trunk/sources/SearchAndReplace/searchandreplaceworker.h
    trunk/sources/SearchAndReplace/ui/replaceconductordialog.h
    trunk/sources/SearchAndReplace/ui/replaceelementdialog.cpp
    trunk/sources/SearchAndReplace/ui/replaceelementdialog.ui
    trunk/sources/SearchAndReplace/ui/searchandreplacewidget.cpp
    trunk/sources/SearchAndReplace/ui/searchandreplacewidget.h
    trunk/sources/SearchAndReplace/ui/searchandreplacewidget.ui
    trunk/sources/qetapp.cpp
    trunk/sources/qetapp.h

Added Paths:
-----------
    trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.cpp
    trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.h
    trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.ui

Modified: trunk/sources/SearchAndReplace/searchandreplaceworker.cpp
===================================================================
--- trunk/sources/SearchAndReplace/searchandreplaceworker.cpp	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/SearchAndReplace/searchandreplaceworker.cpp	2018-12-21 18:08:58 UTC (rev 5658)
@@ -232,6 +232,122 @@
 }
 
 /**
+ * @brief SearchAndReplaceWorker::replaceAdvanced
+ * Apply the change of text according to the current advancedStruct
+ * All items in the 4 list must belong to the same QETProject,
+ * if not this function do nothing
+ * @param d
+ * @param e
+ * @param t
+ * @param c
+ */
+void SearchAndReplaceWorker::replaceAdvanced(QList<Diagram *> diagrams, QList<Element *> elements, QList<IndependentTextItem *> texts, QList<Conductor *> conductors)
+{
+	QETProject *project_ = nullptr;
+	
+		//Some test to check if a least one list have one item
+		//and if all items belong to the same project
+	if (!diagrams.isEmpty()) {
+		project_ = diagrams.first()->project();
+	} else if (!elements.isEmpty() && elements.first()->diagram()) {
+		project_ = elements.first()->diagram()->project();
+	} else if (!texts.isEmpty() && texts.first()->diagram()) {
+		project_ = texts.first()->diagram()->project();
+	} else if (!conductors.isEmpty() && conductors.first()->diagram()) {
+		project_ = conductors.first()->diagram()->project();
+	} else {
+		return;
+	}
+	
+	for (Diagram *dd : diagrams) {
+		if (dd->project() != project_) {
+			return;
+		}
+	}
+	for (Element *elmt : elements) {
+		if (!elmt->diagram() || elmt->diagram()->project() != project_) {
+			return;
+		}
+	}
+	for (IndependentTextItem *text : texts) {
+		if (!text->diagram() || text->diagram()->project() != project_) {
+			return;
+		}
+	}
+	for (Conductor *cc : conductors) {
+		if (!cc->diagram() || cc->diagram()->project() != project_) {
+			return;
+		}
+	}
+		//The end of the test
+	
+	int who = m_advanced_struct.who;
+	if (who == -1) {
+		return;
+	}
+	
+	project_->undoStack()->beginMacro(QObject::tr("Rechercher / remplacer avancé"));
+	if (who == 0)
+	{
+		for (Diagram *diagram : diagrams)
+		{
+			TitleBlockProperties old_properties = diagram->border_and_titleblock.exportTitleBlock();
+			TitleBlockProperties new_properties = replaceAdvanced(diagram);
+			if (old_properties != new_properties) {
+				project_->undoStack()->push(new ChangeTitleBlockCommand(diagram, old_properties, new_properties));
+			}
+		}
+	}
+	else if (who == 1)
+	{
+		for (Element *element : elements)
+		{
+			DiagramContext old_context = element->elementInformations();
+			DiagramContext new_context = replaceAdvanced(element);
+			if (old_context != new_context) {
+				project_->undoStack()->push(new ChangeElementInformationCommand(element, old_context, new_context));
+			}
+		}
+	}
+	else if (who == 2)
+	{
+		for (Conductor *conductor : conductors)
+		{
+			ConductorProperties old_properties = conductor->properties();
+			ConductorProperties new_properties = replaceAdvanced(conductor);
+			if (old_properties != new_properties)
+			{
+				QSet <Conductor *> potential_conductors = conductor->relatedPotentialConductors(true);
+				potential_conductors << conductor;
+				
+				for (Conductor *c : potential_conductors)
+				{
+					QVariant old_value, new_value;
+					old_value.setValue(c->properties());
+					new_value.setValue(new_properties);
+					project_->undoStack()->push(new QPropertyUndoCommand(c, "properties", old_value, new_value));
+				}
+			}
+		}
+	}
+	else if (who == 3)
+	{
+		for (IndependentTextItem *text : texts)
+		{
+			QRegularExpression rx(m_advanced_struct.search);
+			QString replace = m_advanced_struct.replace;
+			QString after = text->toPlainText();
+			after = after.replace(rx, replace);
+			
+			if (after != text->toPlainText()) {
+				project_->undoStack()->push(new ChangeDiagramTextCommand(text, text->toPlainText(), after));
+			}
+		}
+	}
+	project_->undoStack()->endMacro();
+}
+
+/**
  * @brief SearchAndReplaceWorker::setupLineEdit
  * With search and replace, when the variable to edit is a text,
  * the editor is always the same no matter if it is for a folio, element or conductor.
@@ -313,3 +429,79 @@
 	else if (change == eraseText()) {return QString();}
 	else                            {return change;}
 }
+
+/**
+ * @brief SearchAndReplaceWorker::replaceAdvanced
+ * @param diagram
+ * @return the titleblock properties with the change applied,
+ * according to the state of @m_advanced_struct
+ */
+TitleBlockProperties SearchAndReplaceWorker::replaceAdvanced(Diagram *diagram)
+{
+	TitleBlockProperties p = diagram->border_and_titleblock.exportTitleBlock();
+	
+	if (m_advanced_struct.who == 0)
+	{
+		QRegularExpression rx(m_advanced_struct.search);
+		QString replace = m_advanced_struct.replace;
+		QString what = m_advanced_struct.what;
+		if (what == "title") {p.title = p.title.replace(rx, replace);}
+		else if (what == "author") {p.author = p.author.replace(rx, replace);}
+		else if (what == "filename") {p.filename = p.filename.replace(rx, replace);}
+		else if (what == "folio") {p.folio = p.folio.replace(rx, replace);}
+		else if (what == "plant") {p.plant = p.plant.replace(rx, replace);}
+		else if (what == "locmach") {p.locmach = p.locmach.replace(rx, replace);}
+		else if (what == "indexrev") {p.indexrev = p.indexrev.replace(rx, replace);}
+	}
+	return p;
+}
+
+/**
+ * @brief SearchAndReplaceWorker::replaceAdvanced
+ * @param element
+ * @return The diagram context with the change applied,
+ * according to the state of @m_advanced_struct
+ */
+DiagramContext SearchAndReplaceWorker::replaceAdvanced(Element *element)
+{
+	DiagramContext context = element->elementInformations();
+	
+	if (m_advanced_struct.who == 1)
+	{
+		QString what = m_advanced_struct.what;
+		if (context.contains(what))
+		{
+			QRegularExpression rx(m_advanced_struct.search);
+			QString replace = m_advanced_struct.replace;
+			QString value = context[what].toString();
+			context.addValue(what, value.replace(rx, replace));
+		}
+	}
+	
+	return context;
+}
+
+/**
+ * @brief SearchAndReplaceWorker::replaceAdvanced
+ * @param conductor
+ * @return the conductor properties with the change applied,
+ * according to the state of @m_advanced_struct
+ */
+ConductorProperties SearchAndReplaceWorker::replaceAdvanced(Conductor *conductor)
+{
+	ConductorProperties properties = conductor->properties();
+	
+	if (m_advanced_struct.who == 2)
+	{
+		QRegularExpression rx(m_advanced_struct.search);
+		QString what = m_advanced_struct.what;
+		QString replace = m_advanced_struct.replace;
+		
+		if (what == "formula")               {properties.m_formula.replace(rx, replace);}
+		else if (what == "text")             {properties.text.replace(rx, replace);}
+		else if (what == "function")         {properties.m_function.replace(rx, replace);}
+		else if (what == "tension/protocol") {properties.m_tension_protocol.replace(rx, replace);}
+	}
+	
+	return properties;
+}

Modified: trunk/sources/SearchAndReplace/searchandreplaceworker.h
===================================================================
--- trunk/sources/SearchAndReplace/searchandreplaceworker.h	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/SearchAndReplace/searchandreplaceworker.h	2018-12-21 18:08:58 UTC (rev 5658)
@@ -30,6 +30,19 @@
 class QLineEdit;
 class QCheckBox;
 
+struct advancedReplaceStruct
+{
+		//Who :
+		// 0 == diagram
+		// 1 == element
+		// 2 == conductor
+		// 3 == independant text
+	int who = -1;
+	QString what;
+	QString search;
+	QString replace;
+};
+
 /**
  * @brief The SearchAndReplaceWorker class
  * This class is the worker use to change properties when use the search and replace function of QET
@@ -47,6 +60,8 @@
 		void replaceIndiText(IndependentTextItem *text);
 		void replaceConductor(QList <Conductor *> list);
 		void replaceConductor(Conductor *conductor);
+		void replaceAdvanced (QList<Diagram *> diagrams = QList<Diagram *>(), QList<Element *> elements = QList<Element *>(),\
+							  QList<IndependentTextItem *> texts = QList<IndependentTextItem *>(), QList<Conductor *> conductors = QList<Conductor *>());
 		
 		static QString eraseText() {return QString("XXXXXXXXXXXXXXXXXXX");}
 		static QDate eraseDate() {return QDate(1900, 1, 1);}
@@ -57,10 +72,15 @@
 		static QString applyChange(const QString &original, const QString &change);
 		
 	private:
+		TitleBlockProperties replaceAdvanced (Diagram *diagram);
+		DiagramContext       replaceAdvanced (Element *element);
+		ConductorProperties  replaceAdvanced (Conductor *conductor);
+		
 		TitleBlockProperties m_titleblock_properties;
 		DiagramContext m_element_context;
 		QString m_indi_text;
 		ConductorProperties m_conductor_properties;
+		advancedReplaceStruct m_advanced_struct;
 		
 		friend class SearchAndReplaceWidget;
 };

Added: trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.cpp
===================================================================
--- trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.cpp	                        (rev 0)
+++ trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.cpp	2018-12-21 18:08:58 UTC (rev 5658)
@@ -0,0 +1,118 @@
+/*
+	Copyright 2006-2018 The QElectroTech Team
+	This file is part of QElectroTech.
+
+	QElectroTech is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 2 of the License, or
+	(at your option) any later version.
+
+	QElectroTech is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "replaceadvanceddialog.h"
+#include "ui_replaceadvanceddialog.h"
+#include "qetapp.h"
+
+#include <QAbstractButton>
+
+/**
+ * @brief replaceAdvancedDialog::replaceAdvancedDialog
+ * @param advanced
+ * @param parent
+ */
+replaceAdvancedDialog::replaceAdvancedDialog(advancedReplaceStruct advanced, QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::replaceAdvancedDialog)
+{
+	ui->setupUi(this);
+	
+	connect(ui->m_button_box, &QDialogButtonBox::clicked, [this](QAbstractButton *button_) {
+		this->done(ui->m_button_box->buttonRole(button_));
+	});
+	
+	fillWhatComboBox(ui->m_who_cb->currentIndex());
+	ui->m_search_le->setFocus();
+	setAdvancedStruct(advanced);
+}
+
+replaceAdvancedDialog::~replaceAdvancedDialog()
+{
+	delete ui;
+}
+
+/**
+ * @brief replaceAdvancedDialog::setAdvancedStruct
+ * Set the edited advanced struct
+ * @param advanced
+ */
+void replaceAdvancedDialog::setAdvancedStruct(advancedReplaceStruct advanced)
+{
+	int index = advanced.who;
+	if (index == -1) {
+		return;
+	}
+	ui->m_who_cb->setCurrentIndex(index);
+
+	for (int i=0 ; i < ui->m_what_cb->count() ; i++)
+	{
+		if (ui->m_what_cb->itemData(i).toString() == advanced.what)
+		{
+			ui->m_what_cb->setCurrentIndex(i);
+			continue;
+		}
+	}
+	
+	ui->m_search_le->setText(advanced.search);
+	ui->m_replace_le->setText(advanced.replace);
+}
+
+/**
+ * @brief replaceAdvancedDialog::advancedStruct
+ * @return the edited advanced struct
+ */
+advancedReplaceStruct replaceAdvancedDialog::advancedStruct() const
+{
+	advancedReplaceStruct a;
+	a.who     = ui->m_who_cb->currentIndex();
+	a.what    = ui->m_what_cb->currentData().toString();
+	a.search  = ui->m_search_le->text();
+	a.replace = ui->m_replace_le->text();
+	
+	return a;
+}
+
+void replaceAdvancedDialog::fillWhatComboBox(int index)
+{
+	ui->m_what_cb->clear();
+	
+	if (index == 0)
+	{
+		for (QString str : QETApp::diagramInfoKeys()) {
+			ui->m_what_cb->addItem(QETApp::diagramTranslatedInfoKey(str), str);
+		}
+	}
+	else if (index == 1) {
+		for (QString str : QETApp::elementInfoKeys()) {
+			ui->m_what_cb->addItem(QETApp::elementTranslatedInfoKey(str), str);
+		}
+	}
+	else if (index == 2) {
+		for (QString str : QETApp::conductorInfoKeys()) {
+			ui->m_what_cb->addItem(QETApp::conductorTranslatedInfoKey(str), str);
+		}
+	}
+}
+
+/**
+ * @brief replaceAdvancedDialog::on_m_who_cb_currentIndexChanged
+ * @param index
+ */
+void replaceAdvancedDialog::on_m_who_cb_currentIndexChanged(int index) {
+	fillWhatComboBox(index);
+}

Added: trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.h
===================================================================
--- trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.h	                        (rev 0)
+++ trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.h	2018-12-21 18:08:58 UTC (rev 5658)
@@ -0,0 +1,50 @@
+/*
+	Copyright 2006-2018 The QElectroTech Team
+	This file is part of QElectroTech.
+
+	QElectroTech is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 2 of the License, or
+	(at your option) any later version.
+
+	QElectroTech is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef REPLACEADVANCEDDIALOG_H
+#define REPLACEADVANCEDDIALOG_H
+
+#include "searchandreplaceworker.h"
+
+#include <QDialog>
+
+namespace Ui {
+	class replaceAdvancedDialog;
+}
+
+class replaceAdvancedDialog : public QDialog
+{
+	Q_OBJECT
+	
+	public:
+		explicit replaceAdvancedDialog(advancedReplaceStruct advanced, QWidget *parent = nullptr);
+		~replaceAdvancedDialog();
+	
+		void setAdvancedStruct(advancedReplaceStruct advanced);
+		advancedReplaceStruct advancedStruct() const;
+	
+	private:
+		void fillWhatComboBox(int index);
+	
+	private slots:
+		void on_m_who_cb_currentIndexChanged(int index);
+		
+	private:
+		Ui::replaceAdvancedDialog *ui;
+};
+
+#endif // REPLACEADVANCEDDIALOG_H

Added: trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.ui
===================================================================
--- trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.ui	                        (rev 0)
+++ trunk/sources/SearchAndReplace/ui/replaceadvanceddialog.ui	2018-12-21 18:08:58 UTC (rev 5658)
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>replaceAdvancedDialog</class>
+ <widget class="QDialog" name="replaceAdvancedDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>508</width>
+    <height>178</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Rechercher/Remplacer avancé</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0">
+   <item row="1" column="3">
+    <widget class="QLineEdit" name="m_replace_le">
+     <property name="clearButtonEnabled">
+      <bool>false</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="2">
+    <widget class="QLabel" name="label_4">
+     <property name="text">
+      <string>par :</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>Remplacer :</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0" colspan="4">
+    <widget class="QDialogButtonBox" name="m_button_box">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Qui :</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLineEdit" name="m_search_le">
+     <property name="placeholderText">
+      <string>Texte ou expression régulière</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="3">
+    <widget class="QComboBox" name="m_what_cb"/>
+   </item>
+   <item row="0" column="1">
+    <widget class="QComboBox" name="m_who_cb">
+     <item>
+      <property name="text">
+       <string>Folio</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Élément</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Conducteur</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Texte indépendant</string>
+      </property>
+     </item>
+    </widget>
+   </item>
+   <item row="0" column="2">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>Quoi :</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

Modified: trunk/sources/SearchAndReplace/ui/replaceconductordialog.h
===================================================================
--- trunk/sources/SearchAndReplace/ui/replaceconductordialog.h	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/SearchAndReplace/ui/replaceconductordialog.h	2018-12-21 18:08:58 UTC (rev 5658)
@@ -57,7 +57,7 @@
 		void on_m_color_pb_clicked();
 		void on_m_color_2_pb_clicked();
 		
-		private:
+	private:
 		Ui::ReplaceConductorDialog *ui;
 		ConductorProperties m_properties;
 };

Modified: trunk/sources/SearchAndReplace/ui/replaceelementdialog.cpp
===================================================================
--- trunk/sources/SearchAndReplace/ui/replaceelementdialog.cpp	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/SearchAndReplace/ui/replaceelementdialog.cpp	2018-12-21 18:08:58 UTC (rev 5658)
@@ -68,9 +68,7 @@
 
 void ReplaceElementDialog::buildWidget()
 {
-	ui->m_button_box->disconnect();
-	connect(ui->m_button_box, &QDialogButtonBox::clicked, [this](QAbstractButton *button_)
-	{
+	connect(ui->m_button_box, &QDialogButtonBox::clicked, [this](QAbstractButton *button_) {
 		this->done(ui->m_button_box->buttonRole(button_));
 	});
 	

Modified: trunk/sources/SearchAndReplace/ui/replaceelementdialog.ui
===================================================================
--- trunk/sources/SearchAndReplace/ui/replaceelementdialog.ui	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/SearchAndReplace/ui/replaceelementdialog.ui	2018-12-21 18:08:58 UTC (rev 5658)
@@ -27,8 +27,8 @@
        <rect>
         <x>0</x>
         <y>0</y>
-        <width>280</width>
-        <height>351</height>
+        <width>284</width>
+        <height>346</height>
        </rect>
       </property>
       <layout class="QVBoxLayout" name="m_scroll_layout"/>
@@ -48,38 +48,5 @@
   </layout>
  </widget>
  <resources/>
- <connections>
-  <connection>
-   <sender>m_button_box</sender>
-   <signal>accepted()</signal>
-   <receiver>ReplaceElementDialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>157</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>m_button_box</sender>
-   <signal>rejected()</signal>
-   <receiver>ReplaceElementDialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>286</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
+ <connections/>
 </ui>

Modified: trunk/sources/SearchAndReplace/ui/searchandreplacewidget.cpp
===================================================================
--- trunk/sources/SearchAndReplace/ui/searchandreplacewidget.cpp	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/SearchAndReplace/ui/searchandreplacewidget.cpp	2018-12-21 18:08:58 UTC (rev 5658)
@@ -28,6 +28,7 @@
 #include "replaceelementdialog.h"
 #include "qetapp.h"
 #include "replaceconductordialog.h"
+#include "replaceadvanceddialog.h"
 
 #include <QSettings>
 
@@ -214,6 +215,7 @@
 	ui->m_replace_all_pb   ->setHidden(hide);
 	ui->m_mode_cb          ->setHidden(hide);
 	ui->m_case_sensitive_cb->setHidden(hide);
+	ui->m_advanced_replace_pb->setHidden(hide);
 }
 
 /**
@@ -631,6 +633,94 @@
 }
 
 /**
+ * @brief SearchAndReplaceWidget::selectedDiagram
+ * @return The list of visible and selected diagram in the tree widget
+ */
+QList<Diagram *> SearchAndReplaceWidget::selectedDiagram() const
+{
+	QList <Diagram *> diagram_list;
+	
+	for (QTreeWidgetItem *qtwi : m_diagram_hash.keys())
+	{
+		if (!qtwi->isHidden() && qtwi->checkState(0) == Qt::Checked)
+		{
+			QPointer <Diagram> p = m_diagram_hash.value(qtwi);
+			if (p) {
+				diagram_list.append(p.data());
+			}
+		}
+	}
+	
+	return diagram_list;
+}
+
+/**
+ * @brief SearchAndReplaceWidget::selectedElement
+ * @return The list of visible and selected element in the tree widget
+ */
+QList<Element *> SearchAndReplaceWidget::selectedElement() const
+{
+	QList <Element *> element_list;
+	
+	for (QTreeWidgetItem *qtwi : m_element_hash.keys())
+	{
+		if (!qtwi->isHidden() && qtwi->checkState(0) == Qt::Checked)
+		{
+			QPointer <Element> p = m_element_hash.value(qtwi);
+			if (p) {
+				element_list.append(p.data());
+			}
+		}
+	}
+	
+	return element_list;
+}
+
+/**
+ * @brief SearchAndReplaceWidget::selectedConductor
+ * @return The list of visible and selected conductor in the tree widget
+ */
+QList<Conductor *> SearchAndReplaceWidget::selectedConductor() const
+{
+	QList <Conductor *> conductor_list;
+	
+	for (QTreeWidgetItem *qtwi : m_conductor_hash.keys())
+	{
+		if (!qtwi->isHidden() && qtwi->checkState(0) == Qt::Checked)
+		{
+			QPointer <Conductor> c = m_conductor_hash.value(qtwi);
+			if (c) {
+				conductor_list.append(c.data());
+			}
+		}
+	}
+	
+	return conductor_list;
+}
+
+/**
+ * @brief SearchAndReplaceWidget::selectedText
+ * @return The list of visible and selected independant text in the tree widget
+ */
+QList<IndependentTextItem *> SearchAndReplaceWidget::selectedText() const
+{
+	QList <IndependentTextItem *> text_list;
+	
+	for(QTreeWidgetItem *qtwi : m_text_hash.keys())
+	{
+		if (!qtwi->isHidden() && qtwi->checkState(0) == Qt::Checked)
+		{
+			QPointer<IndependentTextItem> t = m_text_hash.value(qtwi);
+			if (t) {
+				text_list.append(t.data());
+			}
+		}
+	}
+	
+	return text_list;
+}
+
+/**
  * @brief SearchAndReplaceWidget::searchTerms
  * @param diagram
  * @return All QStrings use as terms for search.
@@ -919,84 +1009,76 @@
 				m_worker.replaceConductor(c.data());
 			}
 		}
-	}
-	activateNextChecked();
-	ui->m_replace_pb->setEnabled(ui->m_next_pb->isEnabled());
-}
-
-/**
- * @brief SearchAndReplaceWidget::on_m_replace_all_pb_clicked
- * Replace all checked item
- */
-void SearchAndReplaceWidget::on_m_replace_all_pb_clicked()
-{
-		//Replace folio
-	if (ui->m_folio_pb->text().endsWith(tr(" [édité]")))
-	{
-		QList <Diagram *> diagram_list;
-		for (QTreeWidgetItem *qtwi : m_diagram_hash.keys())
+		
+			//Replace advanced
+		if (ui->m_advanced_replace_pb->text().endsWith(tr(" [édité]")))
 		{
-			if (!qtwi->isHidden() && qtwi->checkState(0) == Qt::Checked)
+			QList <Diagram *>dl;
+			QList <Element *>el;
+			QList <IndependentTextItem *>tl;
+			QList <Conductor *>cl;
+			
+			if (m_diagram_hash.keys().contains(qtwi))
 			{
-				QPointer <Diagram> p = m_diagram_hash.value(qtwi);
-				if (p) {
-					diagram_list.append(p.data());
+				QPointer<Diagram> d = m_diagram_hash.value(qtwi);
+				if (d) {
+					dl.append(d.data());
 				}
 			}
-		}
-		m_worker.replaceDiagram(diagram_list);
-	}
-		//Replace text
-	if (ui->m_element_pb->text().endsWith(tr(" [édité]")))
-	{
-		QList <Element *> element_list;
-		for (QTreeWidgetItem *qtwi : m_element_hash.keys())
-		{
-			if (!qtwi->isHidden() && qtwi->checkState(0) == Qt::Checked)
+			else if (m_element_hash.keys().contains(qtwi))
 			{
-				QPointer <Element> p = m_element_hash.value(qtwi);
-				if (p) {
-					element_list.append(p.data());
+				QPointer<Element> e = m_element_hash.value(qtwi);
+				if (e) {
+					el.append(e.data());
 				}
 			}
-		}
-		m_worker.replaceElement(element_list);
-	}
-		//Replace indi text
-	if (!ui->m_replace_le->text().isEmpty())
-	{
-		QList <IndependentTextItem*> text_list;
-		for(QTreeWidgetItem *qtwi : m_text_hash.keys())
-		{
-			if (!qtwi->isHidden() && qtwi->checkState(0) == Qt::Checked)
+			else if (m_text_hash.keys().contains(qtwi))
 			{
 				QPointer<IndependentTextItem> t = m_text_hash.value(qtwi);
 				if (t) {
-					text_list.append(t.data());
+					tl.append(t.data());
 				}
 			}
-		}
-		m_worker.m_indi_text = ui->m_replace_le->text();
-		m_worker.replaceIndiText(text_list );
-	}
-	
-		//Replace conductor
-	if (ui->m_conductor_pb->text().endsWith(tr(" [édité]")))
-	{
-		QList <Conductor *> conductor_list;
-		for (QTreeWidgetItem *qtwi : m_conductor_hash.keys())
-		{
-			if (!qtwi->isHidden() && qtwi->checkState(0) == Qt::Checked)
+			else if (m_conductor_hash.keys().contains(qtwi))
 			{
-				QPointer <Conductor> c = m_conductor_hash.value(qtwi);
+				QPointer<Conductor> c = m_conductor_hash.value(qtwi);
 				if (c) {
-					conductor_list.append(c.data());
+					cl.append(c.data());
 				}
 			}
+			
+			m_worker.replaceAdvanced(dl, el, tl, cl);
 		}
-		m_worker.replaceConductor(conductor_list);
 	}
 	
+	activateNextChecked();
+	ui->m_replace_pb->setEnabled(ui->m_next_pb->isEnabled());
+}
+
+/**
+ * @brief SearchAndReplaceWidget::on_m_replace_all_pb_clicked
+ * Replace all checked item
+ */
+void SearchAndReplaceWidget::on_m_replace_all_pb_clicked()
+{
+	if (ui->m_folio_pb->text().endsWith(tr(" [édité]"))) {
+		m_worker.replaceDiagram(selectedDiagram());
+	}
+	if (ui->m_element_pb->text().endsWith(tr(" [édité]"))) {
+		m_worker.replaceElement(selectedElement());
+	}
+	if (!ui->m_replace_le->text().isEmpty()) {
+		m_worker.m_indi_text = ui->m_replace_le->text();
+		m_worker.replaceIndiText(selectedText() );
+	}
+	if (ui->m_conductor_pb->text().endsWith(tr(" [édité]"))) {
+		m_worker.replaceConductor(selectedConductor());
+	}
+	if (ui->m_advanced_replace_pb->text().endsWith(tr(" [édité]"))) {
+
+		m_worker.replaceAdvanced(selectedDiagram(), selectedElement(), selectedText(), selectedConductor());
+	}	
+	
 		//Change was made, we reload the panel
 		//and search again to keep up to date the tree widget
 		//and the match item of search
@@ -1081,3 +1163,32 @@
 		m_worker.m_conductor_properties = m_worker.invalidConductorProperties();
 	}
 }
+
+/**
+ * @brief SearchAndReplaceWidget::on_m_advanced_replace_pb_clicked
+ * Open the advanced editor.
+ */
+void SearchAndReplaceWidget::on_m_advanced_replace_pb_clicked()
+{
+	replaceAdvancedDialog *dialog = new replaceAdvancedDialog(m_worker.m_advanced_struct, this);
+	int result = dialog->exec();
+	
+	if (result == QDialogButtonBox::AcceptRole)
+	{
+		QString text = ui->m_advanced_replace_pb->text();
+		if (!text.endsWith(tr(" [édité]"))) {
+			text.append(tr(" [édité]"));
+		}
+		ui->m_advanced_replace_pb->setText(text);
+		m_worker.m_advanced_struct = dialog->advancedStruct();
+	}
+	else if (result == QDialogButtonBox::ResetRole)
+	{
+		QString text = ui->m_advanced_replace_pb->text();
+		if (text.endsWith(tr(" [édité]"))) {
+			text.remove(tr(" [édité]"));
+		}
+		ui->m_advanced_replace_pb->setText(text);
+		m_worker.m_advanced_struct = advancedReplaceStruct();
+	}
+}

Modified: trunk/sources/SearchAndReplace/ui/searchandreplacewidget.h
===================================================================
--- trunk/sources/SearchAndReplace/ui/searchandreplacewidget.h	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/SearchAndReplace/ui/searchandreplacewidget.h	2018-12-21 18:08:58 UTC (rev 5658)
@@ -60,6 +60,11 @@
 		void setChildCheckState(QTreeWidgetItem *item, Qt::CheckState check, bool deep = true);
 		void updateParentCheckState(QTreeWidgetItem *item, bool all_parents = true);
 		void activateNextChecked();
+		QList<Diagram *> selectedDiagram() const;
+		QList<Element *> selectedElement() const;
+		QList<Conductor *> selectedConductor() const;
+		QList<IndependentTextItem *> selectedText() const;
+		
 		static QStringList searchTerms(Diagram *diagram);
 		static QStringList searchTerms(Element *element);
 		static QStringList searchTerms(Conductor *conductor);
@@ -80,8 +85,9 @@
 		void on_m_mode_cb_currentIndexChanged(int index);
 		void on_m_case_sensitive_cb_stateChanged(int arg1);
 		void on_m_conductor_pb_clicked();
+		void on_m_advanced_replace_pb_clicked();
 		
-		private:
+	private:
 		Ui::SearchAndReplaceWidget *ui;
 		QETDiagramEditor *m_editor;
 		QTreeWidgetItem *m_root_qtwi          = nullptr,

Modified: trunk/sources/SearchAndReplace/ui/searchandreplacewidget.ui
===================================================================
--- trunk/sources/SearchAndReplace/ui/searchandreplacewidget.ui	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/SearchAndReplace/ui/searchandreplacewidget.ui	2018-12-21 18:08:58 UTC (rev 5658)
@@ -13,7 +13,14 @@
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,1" columnstretch="0,0,1,0,0,0,0,0,0,0,0,0">
+  <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,1" columnstretch="0,0,1,0,0,0,0,0,0,0,0,0,0">
+   <item row="0" column="1">
+    <widget class="QLabel" name="m_search">
+     <property name="text">
+      <string>Chercher :</string>
+     </property>
+    </widget>
+   </item>
    <item row="0" column="0">
     <widget class="QPushButton" name="m_quit_button">
      <property name="toolTip">
@@ -31,14 +38,7 @@
      </property>
     </widget>
    </item>
-   <item row="0" column="1">
-    <widget class="QLabel" name="m_search">
-     <property name="text">
-      <string>Chercher :</string>
-     </property>
-    </widget>
-   </item>
-   <item row="0" column="6">
+   <item row="0" column="7">
     <widget class="QComboBox" name="m_mode_cb">
      <property name="toolTip">
       <string>Mode</string>
@@ -58,7 +58,7 @@
      </item>
     </widget>
    </item>
-   <item row="0" column="7">
+   <item row="0" column="8">
     <widget class="QCheckBox" name="m_case_sensitive_cb">
      <property name="text">
       <string>Sensible à la casse</string>
@@ -65,7 +65,14 @@
      </property>
     </widget>
    </item>
-   <item row="0" column="8">
+   <item row="1" column="1">
+    <widget class="QLabel" name="m_replace">
+     <property name="text">
+      <string>Remplacer :</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="9">
     <widget class="QPushButton" name="m_next_pb">
      <property name="toolTip">
       <string>Aller à la correspondance suivante</string>
@@ -82,7 +89,7 @@
      </property>
     </widget>
    </item>
-   <item row="0" column="9">
+   <item row="0" column="10">
     <widget class="QPushButton" name="m_previous_pb">
      <property name="toolTip">
       <string>Aller à la correspondance précédente</string>
@@ -99,10 +106,10 @@
      </property>
     </widget>
    </item>
-   <item row="0" column="10">
-    <widget class="QPushButton" name="m_reload_pb">
+   <item row="0" column="12">
+    <widget class="QPushButton" name="m_advanced_pb">
      <property name="toolTip">
-      <string>Actualiser</string>
+      <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Afficher les options avancées&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
      </property>
      <property name="text">
       <string/>
@@ -109,8 +116,14 @@
      </property>
      <property name="icon">
       <iconset resource="../../../qelectrotech.qrc">
-       <normaloff>:/ico/16x16/view-refresh.png</normaloff>:/ico/16x16/view-refresh.png</iconset>
+       <normaloff>:/ico/16x16/configure-toolbars.png</normaloff>:/ico/16x16/configure-toolbars.png</iconset>
      </property>
+     <property name="checkable">
+      <bool>true</bool>
+     </property>
+     <property name="checked">
+      <bool>false</bool>
+     </property>
      <property name="flat">
       <bool>true</bool>
      </property>
@@ -117,9 +130,9 @@
     </widget>
    </item>
    <item row="0" column="11">
-    <widget class="QPushButton" name="m_advanced_pb">
+    <widget class="QPushButton" name="m_reload_pb">
      <property name="toolTip">
-      <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Afficher les options avancées&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+      <string>Actualiser</string>
      </property>
      <property name="text">
       <string/>
@@ -126,26 +139,13 @@
      </property>
      <property name="icon">
       <iconset resource="../../../qelectrotech.qrc">
-       <normaloff>:/ico/16x16/configure-toolbars.png</normaloff>:/ico/16x16/configure-toolbars.png</iconset>
+       <normaloff>:/ico/16x16/view-refresh.png</normaloff>:/ico/16x16/view-refresh.png</iconset>
      </property>
-     <property name="checkable">
-      <bool>true</bool>
-     </property>
-     <property name="checked">
-      <bool>false</bool>
-     </property>
      <property name="flat">
       <bool>true</bool>
      </property>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="QLabel" name="m_replace">
-     <property name="text">
-      <string>Remplacer :</string>
-     </property>
-    </widget>
-   </item>
    <item row="1" column="2">
     <widget class="QLineEdit" name="m_replace_le">
      <property name="placeholderText">
@@ -189,7 +189,7 @@
      </property>
     </widget>
    </item>
-   <item row="1" column="8" colspan="2">
+   <item row="1" column="9" colspan="2">
     <widget class="QPushButton" name="m_replace_pb">
      <property name="enabled">
       <bool>false</bool>
@@ -202,7 +202,7 @@
      </property>
     </widget>
    </item>
-   <item row="1" column="10" colspan="2">
+   <item row="1" column="11" colspan="2">
     <widget class="QPushButton" name="m_replace_all_pb">
      <property name="enabled">
       <bool>false</bool>
@@ -215,14 +215,7 @@
      </property>
     </widget>
    </item>
-   <item row="0" column="2" colspan="4">
-    <widget class="QLineEdit" name="m_search_le">
-     <property name="clearButtonEnabled">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item row="2" column="0" colspan="12">
+   <item row="2" column="0" colspan="13">
     <widget class="QTreeWidget" name="m_tree_widget">
      <property name="uniformRowHeights">
       <bool>true</bool>
@@ -243,6 +236,20 @@
      </column>
     </widget>
    </item>
+   <item row="1" column="6">
+    <widget class="QPushButton" name="m_advanced_replace_pb">
+     <property name="text">
+      <string>avancé</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="2" colspan="5">
+    <widget class="QLineEdit" name="m_search_le">
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <resources>

Modified: trunk/sources/qetapp.cpp
===================================================================
--- trunk/sources/qetapp.cpp	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/qetapp.cpp	2018-12-21 18:08:58 UTC (rev 5658)
@@ -379,6 +379,72 @@
 }
 
 /**
+ * @brief QETApp::conductorInfoKeys
+ * @return the conductor information keys
+ */
+QStringList QETApp::conductorInfoKeys()
+{
+	QStringList keys;
+	keys.append("formula");
+	keys.append("text");
+	keys.append("function");
+	keys.append("tension/protocol");
+	
+	return keys;
+}
+
+/**
+ * @brief QETApp::conductorTranslatedInfoKey
+ * @param key
+ * @return the translated information key given by @key
+ * If @key don't match, return an empty string
+ */
+QString QETApp::conductorTranslatedInfoKey(const QString &key)
+{
+	if      (key == "formula")           return tr("Formule du texte");
+	else if (key == "text")              return tr("Texte");
+	else if (key == "function")          return tr("Fonction");
+	else if (key ==  "tension/protocol") return tr("Tension / Protocole");
+	return QString();
+}
+
+/**
+ * @brief QETApp::diagramInfoKeys
+ * @return the diagram default information keys
+ */
+QStringList QETApp::diagramInfoKeys()
+{
+	QStringList list;
+	list.append("title");
+	list.append("author");
+	list.append("filename");
+	list.append("folio");
+	list.append("plant");
+	list.append("locmach");
+	list.append("indexrev");
+	
+	return list;
+}
+
+/**
+ * @brief QETApp::diagramTranslatedInfoKey
+ * @param key
+ * @return the translated information key given by @key
+ * If @key don't match, return an empty string
+ */
+QString QETApp::diagramTranslatedInfoKey(const QString &key)
+{
+	if      (key == "title")    return tr("Titre");
+	else if (key == "author")   return tr("Auteur");
+	else if (key == "filename") return tr("Fichier");
+	else if (key == "folio")    return tr("Folio");
+	else if (key == "plant")    return tr("Installation");
+	else if (key == "locmach")  return tr("Localisation");
+	else if (key == "indexrev") return tr("Indice Rev");
+	else return QString();
+}
+
+/**
 	@return the common title block templates collection, i.e. the one provided
 	by QElecrotTech
 */

Modified: trunk/sources/qetapp.h
===================================================================
--- trunk/sources/qetapp.h	2018-12-20 23:17:17 UTC (rev 5657)
+++ trunk/sources/qetapp.h	2018-12-21 18:08:58 UTC (rev 5658)
@@ -76,6 +76,12 @@
 		static QString elementTranslatedInfoKey(const QString &);
 		static QString elementInfoToVar(const QString &info);
 		
+		static QStringList conductorInfoKeys();
+		static QString conductorTranslatedInfoKey(const QString &key);
+		
+		static QStringList diagramInfoKeys();
+		static QString diagramTranslatedInfoKey(const QString &key);
+		
 		static TitleBlockTemplatesFilesCollection *commonTitleBlockTemplatesCollection();
 		static TitleBlockTemplatesFilesCollection *customTitleBlockTemplatesCollection();
 		static QList<TitleBlockTemplatesCollection *> availableTitleBlockTemplatesCollections();


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/