[qet] qet/qet: [5788] Use KAutoSaveFile for the backup system, instead of home made function.

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


Revision: 5788
Author:   blacksun
Date:     2019-03-16 11:50:30 +0100 (Sat, 16 Mar 2019)
Log Message:
-----------
Use KAutoSaveFile for the backup system, instead of home made function.

Modified Paths:
--------------
    trunk/qelectrotech.pro
    trunk/sources/qet.cpp
    trunk/sources/qet.h
    trunk/sources/qetapp.cpp
    trunk/sources/qetdiagrameditor.cpp
    trunk/sources/qetdiagrameditor.h
    trunk/sources/qetproject.cpp
    trunk/sources/qetproject.h

Modified: trunk/qelectrotech.pro
===================================================================
--- trunk/qelectrotech.pro	2019-03-15 18:07:57 UTC (rev 5787)
+++ trunk/qelectrotech.pro	2019-03-16 10:50:30 UTC (rev 5788)
@@ -160,7 +160,7 @@
 TRANSLATIONS += lang/qet_en.ts lang/qet_es.ts lang/qet_fr.ts lang/qet_ru.ts lang/qet_pt.ts lang/qet_cs.ts lang/qet_pl.ts lang/qet_de.ts lang/qet_ro.ts lang/qet_it.ts lang/qet_el.ts lang/qet_nl.ts lang/qet_be.ts
 
 # Modules Qt utilises par l'application
-QT += xml svg network sql widgets printsupport concurrent KWidgetsAddons
+QT += xml svg network sql widgets printsupport concurrent KWidgetsAddons KCoreAddons
 
 # UI DESIGNER FILES AND GENERATION SOURCES FILES
 FORMS += $$files(sources/richtext/*.ui) \

Modified: trunk/sources/qet.cpp
===================================================================
--- trunk/sources/qet.cpp	2019-03-15 18:07:57 UTC (rev 5787)
+++ trunk/sources/qet.cpp	2019-03-16 10:50:30 UTC (rev 5788)
@@ -21,6 +21,7 @@
 #include <limits>
 #include <QGraphicsSceneContextMenuEvent>
 #include <QAction>
+#include <QFileInfo>
 
 /**
 	Permet de convertir une chaine de caracteres ("n", "s", "e" ou "w")
@@ -645,3 +646,36 @@
 	
 	return action_group;
 }
+
+bool QET::writeToFile(QDomDocument &xml_doc, QFile *file, QString *error_message)
+{
+	bool opened_here = file->isOpen() ? false : true;
+
+	if (!file->isOpen())
+	{
+		bool open_ = file->open(QIODevice::WriteOnly);
+		if (!open_)
+		{
+			if (error_message)
+			{
+				QFileInfo info_(*file);
+				*error_message = QString(
+							QObject::tr("Impossible d'ouvrir le fichier %1 en écriture, erreur %2 rencontrée.",
+										"error message when attempting to write an XML file")
+				).arg(info_.absoluteFilePath()).arg(file->error());
+			}
+			return false;
+		}
+	}
+
+	QTextStream out(file);
+	out.seek(0);
+	out.setCodec("UTF-8");
+	out.setGenerateByteOrderMark(false);
+	out << xml_doc.toString(4);
+	if (opened_here) {
+		file->close();
+	}
+
+	return(true);
+}

Modified: trunk/sources/qet.h
===================================================================
--- trunk/sources/qet.h	2019-03-15 18:07:57 UTC (rev 5787)
+++ trunk/sources/qet.h	2019-03-16 10:50:30 UTC (rev 5788)
@@ -175,6 +175,7 @@
 	qreal correctAngle(const qreal &);
 	bool compareCanonicalFilePaths(const QString &, const QString &);
 	bool writeXmlFile(QDomDocument &xml_doc, const QString &filepath, QString * error_message= nullptr);
+	bool writeToFile (QDomDocument &xml_doc, QFile *file, QString *error_message = nullptr);
 	bool eachStrIsEqual (const QStringList &qsl);
 	QActionGroup *depthActionGroup(QObject *parent = nullptr);
 }

Modified: trunk/sources/qetapp.cpp
===================================================================
--- trunk/sources/qetapp.cpp	2019-03-15 18:07:57 UTC (rev 5787)
+++ trunk/sources/qetapp.cpp	2019-03-16 10:50:30 UTC (rev 5788)
@@ -41,6 +41,8 @@
 #include <QProcessEnvironment>
 #include "factory/elementfactory.h"
 
+#include <KAutoSaveFile>
+
 #ifdef QET_ALLOW_OVERRIDE_CED_OPTION
 QString QETApp::common_elements_dir = QString();
 #endif
@@ -128,16 +130,6 @@
 	
 	ElementFactory::dropInstance();
 	ElementPictureFactory::dropInstance();
-	
-		//Delete all backup files
-	QDir dir(configDir() + "backup");
-	if(dir.exists())
-	{
-		QStringList extension_filter("*.qet");
-		QStringList list = dir.entryList(extension_filter);
-		for(const QString& str : list)
-			dir.remove(str);
-	}
 }
 
 /**
@@ -1795,82 +1787,47 @@
  */
 void QETApp::checkBackupFiles()
 {
-		//Delete all backup files
-	QDir dir(configDir() + "backup");
-	if(dir.exists())
+	QList<KAutoSaveFile *> stale_files = KAutoSaveFile::allStaleFiles();
+	if (stale_files.isEmpty()) {
+		return;
+	}
+
+	QString text;
+	if(stale_files.size() == 1) {
+		text.append(tr("<b>Le fichier de restauration suivant a été trouvé,<br>"
+					   "Voulez-vous l'ouvrir ?</b><br>"));
+	} else {
+		text.append(tr("<b>Les fichiers de restauration suivant on été trouvé,<br>"
+					   "Voulez-vous les ouvrir ?</b><br>"));
+	}
+	for(const KAutoSaveFile *kasf : stale_files) {
+		text.append("<br>" + kasf->managedFile().path());
+	}
+
+		//Open backup file
+	if (QET::QetMessageBox::question(nullptr, tr("Fichier de restauration"), text, QMessageBox::Ok|QMessageBox::Cancel) == QMessageBox::Ok)
 	{
-		QStringList extension_filter("*.qet");
-		QStringList list = dir.entryList(extension_filter);
-		
-			//Remove from the list, the backup file of registred project
-		for(QETProject *project : registeredProjects().values())
-			if(!project->filePath().isEmpty())
-			{
-				QFileInfo info(project->filePath());
-				list.removeOne(info.fileName());
-			}
-		
-		if(list.isEmpty())
-			return;
-		
-		QString text;
-		if(list.size() == 1)
-			text.append(tr("<b>Le fichier de restauration suivant a été trouvé,<br>"
-						   "Voulez-vous l'ouvrir ?</b><br>"));
+			//If there is opened editors, we find those who are visible
+		if (diagramEditors().count())
+		{
+			diagramEditors().first()->setVisible(true);
+			diagramEditors().first()->openBackupFiles(stale_files);
+		}
 		else
-			text.append(tr("<b>Les fichiers de restauration suivant on été trouvé,<br>"
-						   "Voulez-vous les ouvrir ?</b><br>"));
-		for(const QString& name : list)
-			text.append("<br>" + name);
-		
-		if (QET::QetMessageBox::question(nullptr, tr("Fichier de restauration"), text, QMessageBox::Ok|QMessageBox::Cancel) == QMessageBox::Ok)
 		{
-			QStringList files_list;
-			for(const QString& str : list)
-				files_list << dir.path() + "/" + str;
-			
-			QList<QETDiagramEditor *> diagrams_editors = diagramEditors();
-		
-				//If there is opened editors, we find those who are visible
-			if (diagrams_editors.count())
-			{
-				QList<QETDiagramEditor *> visible_diagrams_editors;
-				for(QETDiagramEditor *de : diagrams_editors) {
-					if (de->isVisible())
-						visible_diagrams_editors << de;
-				}
-		
-					//We take the first visible, or the first one
-				QETDiagramEditor *de_open;
-				if (visible_diagrams_editors.count()) {
-					de_open = visible_diagrams_editors.first();
-				}
-				else
-				{
-					de_open = diagrams_editors.first();
-					de_open -> setVisible(true);
-				}
-		
-				for(const QString& file : files_list) {
-					de_open -> openAndAddProject(file);
-				}
-			}
-			else {
-				new QETDiagramEditor(files_list);
-			}
-			
-				//Because the file was open from backup, we remove the file path of each project opened,
-				//for avoid user to save in the backup directory
-			for(QETDiagramEditor *editor : diagramEditors())
-			{
-				for(ProjectView *pv : editor->openedProjects())
-				{
-					if(files_list.contains(pv->project()->filePath()))
-						pv->project()->setFilePath(QString());
-				}
-			}
+			QETDiagramEditor *editor = new QETDiagramEditor();
+			editor->openBackupFiles(stale_files);
 		}
 	}
+	else //Clear backup file
+	{
+			//Remove the stale files
+		for (KAutoSaveFile *stale : stale_files)
+		{
+			stale->open(QIODevice::ReadWrite);
+			delete stale;
+		}
+	}
 }
 
 /// Met a jour les booleens concernant l'etat des fenetres

Modified: trunk/sources/qetdiagrameditor.cpp
===================================================================
--- trunk/sources/qetdiagrameditor.cpp	2019-03-15 18:07:57 UTC (rev 5787)
+++ trunk/sources/qetdiagrameditor.cpp	2019-03-16 10:50:30 UTC (rev 5788)
@@ -51,6 +51,7 @@
 
 #include <QMessageBox>
 #include <QStandardPaths>
+#include <KAutoSaveFile>
 
 #include "elementscollectionmodel.h"
 
@@ -863,7 +864,7 @@
  */
 bool QETDiagramEditor::newProject() {
 	// create new project without diagram
-	QETProject *new_project = new QETProject(0);
+	QETProject *new_project = new QETProject(this);
 	
 	// Set default properties for new diagram
 	new_project -> setDefaultBorderProperties	  (BorderProperties::    defaultProperties());
@@ -1715,6 +1716,34 @@
 }
 
 /**
+ * @brief QETDiagramEditor::openBackupFiles
+ * @param backup_files
+ */
+void QETDiagramEditor::openBackupFiles(QList<KAutoSaveFile *> backup_files)
+{
+	for (KAutoSaveFile *file : backup_files)
+	{
+			//Create the project
+		DialogWaiting::instance(this);
+
+		QETProject *project = new QETProject(file, this);
+		if (project->state() != QETProject::Ok)
+		{
+			if (project -> state() != QETProject::FileOpenDiscard)
+			{
+				QET::QetMessageBox::warning(this, tr("Échec de l'ouverture du projet", "message box title"),
+											QString(tr("Une erreur est survenue lors de l'ouverture du fichier %1.",
+													   "message box content")).arg(file->managedFile().fileName()));
+			}
+			delete project;
+			DialogWaiting::dropInstance();
+		}
+		addProject(project);
+		DialogWaiting::dropInstance();
+	}
+}
+
+/**
 	met a jour le menu "Fenetres"
 */
 void QETDiagramEditor::slot_updateWindowsMenu() {

Modified: trunk/sources/qetdiagrameditor.h
===================================================================
--- trunk/sources/qetdiagrameditor.h	2019-03-15 18:07:57 UTC (rev 5787)
+++ trunk/sources/qetdiagrameditor.h	2019-03-16 10:50:30 UTC (rev 5788)
@@ -41,6 +41,7 @@
 class DiagramPropertiesEditorDockWidget;
 class ElementsCollectionWidget;
 class AutoNumberingDockWidget;
+class KAutoSaveFile;
 
 /**
 	This class represents the main window of the QElectroTech diagram editor and,
@@ -67,6 +68,7 @@
 		ProjectView *currentProjectView() const;
 		QETProject *currentProject() const;
 		bool drawGrid() const;
+		void openBackupFiles (QList<KAutoSaveFile *> backup_files);
 		
 	protected:
 		bool event(QEvent *) override;

Modified: trunk/sources/qetproject.cpp
===================================================================
--- trunk/sources/qetproject.cpp	2019-03-15 18:07:57 UTC (rev 5787)
+++ trunk/sources/qetproject.cpp	2019-03-16 10:50:30 UTC (rev 5788)
@@ -35,57 +35,21 @@
 #include <QTimer>
 #include <QStandardPaths>
 #include <utility>
+#include <KAutoSaveFile>
 
-static int BACKUP_INTERVAL = 300000; //interval in ms of backup
+static int BACKUP_INTERVAL = 120000; //interval in ms of backup = 2min
 
 /**
-	Constructeur par defaut - cree un schema contenant une collection
-	d'elements vide et un schema vide.
-	@param diagrams Nombre de nouveaux schemas a ajouter a ce nouveau projet
-	@param parent QObject parent
-*/
-QETProject::QETProject(int diagrams, QObject *parent) :
+ * @brief QETProject::QETProject
+ * Create a empty project
+ * @param parent
+ */
+QETProject::QETProject(QObject *parent) :
 	QObject              (parent),
-	project_qet_version_ (-1    ),
-	modified_            (false ),
-	read_only_           (false ),
-	titleblocks_         (this  ),
-	folioSheetsQuantity  (0     ),
-	m_auto_conductor     (true  ),
-	m_elements_collection (nullptr),
-	m_freeze_new_elements (false),
-	m_freeze_new_conductors (false)
+	m_titleblocks_collection(this)
 {
-	// 0 a n schema(s) vide(s)
-	int diagrams_count = qMax(0, diagrams);
-	for (int i = 0 ; i < diagrams_count ; ++ i) {
-		addNewDiagram();
-	}
-
 	m_elements_collection = new XmlElementCollection(this);
-
-	setupTitleBlockTemplatesCollection();
-
-	m_undo_stack = new QUndoStack();
-	connect(m_undo_stack, SIGNAL(cleanChanged(bool)), this, SLOT(undoStackChanged(bool)));
-	
-	m_save_backup_timer.setInterval(BACKUP_INTERVAL);
-	connect(&m_save_backup_timer, &QTimer::timeout, this, &QETProject::writeBackup);
-	m_save_backup_timer.start();
-	
-	QSettings settings;
-	int autosave_interval = settings.value("diagrameditor/autosave-interval", 0).toInt();
-	if(autosave_interval > 0)
-	{
-		int ms = autosave_interval*60*1000;
-		m_autosave_timer.setInterval(ms);
-		connect(&m_autosave_timer, &QTimer::timeout, [this]()
-		{
-			if(!this->m_file_path.isEmpty())
-				this->write();
-		});
-		m_autosave_timer.start();
-	}
+	init();
 }
 
 /**
@@ -96,50 +60,74 @@
  */
 QETProject::QETProject(const QString &path, QObject *parent) :
 	QObject              (parent),
-	project_qet_version_ (-1    ),
-	modified_            (false ),
-	read_only_           (false ),
-	titleblocks_         (this  ),
-	folioSheetsQuantity  (0     ),
-	m_auto_conductor     (true  ),
-	m_elements_collection (nullptr)
+	m_titleblocks_collection(this)
 {
-		//Open the file
-	QFile project_file(path);
-	if (!project_file.open(QIODevice::ReadOnly | QIODevice::Text))
-	{
-		state_ = FileOpenFailed;
+	QFile file(path);
+	m_state = openFile(&file);
+	if (m_state != ProjectState::Ok) {
 		return;
 	}
-	setFilePath(path);
-	
-		//Extract the content of the xml
-	QDomDocument xml_project;
-	if (!xml_project.setContent(&project_file))
+
+	init();
+}
+
+/**
+ * @brief QETProject::QETProject
+ * @param backup : backup file to open, QETProject take ownership of backup.
+ * @param parent : parent QObject
+ */
+QETProject::QETProject(KAutoSaveFile *backup, QObject *parent) :
+	QObject              (parent),
+	m_titleblocks_collection(this)
+{
+	m_state = openFile(backup);
+		//Failed to open from the backup, try to open the crashed
+	if (m_state != ProjectState::Ok)
 	{
-		state_ = XmlParsingFailed;
-		return;
+		QFile file(backup->managedFile().path());
+		m_state = openFile(&file);
+		if(m_state != ProjectState::Ok)
+		{
+			backup->open(QIODevice::ReadWrite);
+			delete backup;
+			return;
+		}
 	}
+		//Set the real path, instead of the path of the backup.
+	setFilePath(backup->managedFile().path());
+	delete  backup;
 
-		//Build the project from the xml
-	readProjectXml(xml_project);
-	
-	setupTitleBlockTemplatesCollection();
-	
-	// passe le projet en lecture seule si le fichier l'est
-	QFileInfo project_file_info(path);
-	if (!project_file_info.isWritable()) {
-		setReadOnly(true);
-	}
+		//Set the project to read only mode if the file it.
+	QFileInfo fi(m_file_path);
+	setReadOnly(!fi.isWritable());
 
-	m_undo_stack = new QUndoStack();
+	init();
+}
+
+/**
+ * @brief QETProject::~QETProject
+ * Destructor
+ */
+QETProject::~QETProject() {
+	qDeleteAll(m_diagrams_list);
+}
+
+/**
+ * @brief QETProject::init
+ */
+void QETProject::init()
+{
+	connect(&m_titleblocks_collection, &TitleBlockTemplatesCollection::changed, this, &QETProject::updateDiagramsTitleBlockTemplate);
+	connect(&m_titleblocks_collection, &TitleBlockTemplatesCollection::aboutToRemove, this, &QETProject::removeDiagramsTitleBlockTemplate);
+
+	m_undo_stack = new QUndoStack(this);
 	connect(m_undo_stack, SIGNAL(cleanChanged(bool)), this, SLOT(undoStackChanged(bool)));
-	
+
 	m_save_backup_timer.setInterval(BACKUP_INTERVAL);
 	connect(&m_save_backup_timer, &QTimer::timeout, this, &QETProject::writeBackup);
 	m_save_backup_timer.start();
 	writeBackup();
-	
+
 	QSettings settings;
 	int autosave_interval = settings.value("diagrameditor/autosave-interval", 0).toInt();
 	if(autosave_interval > 0)
@@ -156,25 +144,39 @@
 }
 
 /**
- * @brief QETProject::~QETProject
- * Destructor
+ * @brief QETProject::openFile
+ * @param file
+ * @return
  */
-QETProject::~QETProject()
+QETProject::ProjectState QETProject::openFile(QFile *file)
 {
-	qDeleteAll(m_diagrams_list);
-	delete m_undo_stack;
-	
-		//Project is closed without crash, we can safely remove the backup file.
-	if (!m_file_path.isEmpty())
+	bool opened_here = file->isOpen() ? false : true;
+	if (!file->isOpen() && !file->open(QIODevice::ReadOnly | QIODevice::Text)) {
+		return FileOpenFailed;
+	}
+	QFileInfo fi(*file);
+	setFilePath(fi.absoluteFilePath());
+
+		//Extract the content of the xml
+	QDomDocument xml_project;
+	if (!xml_project.setContent(file))
 	{
-		QDir dir(QETApp::configDir() + "backup");
-		if(!dir.exists())
-			return;
-		
-		QFileInfo info(m_file_path);
-		if(info.exists())
-			dir.remove(info.fileName());
+		if(opened_here) {
+			file->close();
+		}
+		return XmlParsingFailed;
 	}
+
+		//Build the project from the xml
+	readProjectXml(xml_project);
+
+	if (!fi.isWritable()) {
+		setReadOnly(true);
+	}
+	if(opened_here) {
+		file->close();
+	}
+	return ProjectState::Ok;
 }
 
 /**
@@ -183,7 +185,7 @@
 	@see ProjectState
 */
 QETProject::ProjectState QETProject::state() const {
-	return(state_);
+	return(m_state);
 }
 
 /**
@@ -191,7 +193,7 @@
 	@return folio Sheets Quantity.
 */
 int QETProject::getFolioSheetsQuantity() const {
-	return(folioSheetsQuantity);
+	return(m_folio_sheets_quantity);
 }
 
 /**
@@ -199,7 +201,7 @@
 	@param New value of quantity to be set.
 */
 void QETProject::setFolioSheetsQuantity(int quantity) {
-	folioSheetsQuantity = quantity;
+	m_folio_sheets_quantity = quantity;
 }
 
 /**
@@ -232,7 +234,7 @@
 	@return the title block templates collection enbeedded within this project
 */
 TitleBlockTemplatesProjectCollection *QETProject::embeddedTitleBlockTemplatesCollection() {
-	return(&titleblocks_);
+	return(&m_titleblocks_collection);
 }
 
 /**
@@ -243,22 +245,40 @@
 }
 
 /**
-	Change le chemin du fichier dans lequel ce projet est enregistre
-	@param filepath Nouveau chemin de fichier
-*/
-void QETProject::setFilePath(const QString &filepath) {
+ * @brief QETProject::setFilePath
+ * Set the filepath of this project file
+ * Set a file path also create a backup file according to the path.
+ * If a previous path was set, the previous backup file is deleted and a new one
+ * is created according to the path.
+ * @param filepath
+ */
+void QETProject::setFilePath(const QString &filepath)
+{
+	if (filepath == m_file_path) {
+		return;
+	}
+
+	if (m_backup_file)
+	{
+		delete m_backup_file;
+		m_backup_file = nullptr;
+	}
+	QUrl url_(filepath);
+	m_backup_file = new KAutoSaveFile(url_, this);
+	if (!m_backup_file->open(QIODevice::WriteOnly)) {
+		delete m_backup_file;
+		m_backup_file = nullptr;
+	}
 	m_file_path = filepath;
 	
-	// le chemin a change : on reevalue la necessite du mode lecture seule
-	QFileInfo file_path_info(m_file_path);
-	if (file_path_info.isWritable()) {
-		setReadOnly(false);
-	}
-	//title block variables should be updated after file save as dialog is confirmed, before file is saved.
-	project_properties_.addValue("saveddate", QDate::currentDate().toString("yyyy-MM-dd"));
-	project_properties_.addValue("savedtime", QDateTime::currentDateTime().toString("HH:mm"));
-	project_properties_.addValue("savedfilename", QFileInfo(filePath()).baseName());
-	project_properties_.addValue("savedfilepath", filePath());
+	QFileInfo fi(m_file_path);
+	setReadOnly(!fi.isWritable());
+
+		//title block variables should be updated after file save as dialog is confirmed, before file is saved.
+	m_project_properties.addValue("saveddate", QDate::currentDate().toString("yyyy-MM-dd"));
+	m_project_properties.addValue("savedtime", QDateTime::currentDateTime().toString("HH:mm"));
+	m_project_properties.addValue("savedfilename", QFileInfo(filePath()).baseName());
+	m_project_properties.addValue("savedfilepath", filePath());
 	
 	
 	
@@ -325,7 +345,7 @@
 			)
 		).arg(final_title);
 	}
-	if (modified_) {
+	if (m_modified) {
 		final_title = QString(
 			tr(
 				"%1 [modifié]",
@@ -350,7 +370,7 @@
 	depuis un fichier, cette methode retourne -1.
 */
 qreal QETProject::declaredQElectroTechVersion() {
-	return(project_qet_version_);
+	return(m_project_qet_version);
 }
 
 /**
@@ -771,7 +791,7 @@
  */
 void QETProject::autoFolioNumberingSelectedFolios(int from, int to, const QString& autonum){
 	int total_folio = m_diagrams_list.count();
-	DiagramContext project_wide_properties = project_properties_;
+	DiagramContext project_wide_properties = m_project_properties;
 	for (int i=from; i<=to; i++) {
 		QString title = m_diagrams_list[i] -> title();
 		NumerotationContext nC = folioAutoNum(autonum);
@@ -794,14 +814,14 @@
 	project_root.setAttribute("title", project_title_);
 
 	// write the present value of folioSheetsQuantity to XML.
-	project_root.setAttribute("folioSheetQuantity", QString::number(folioSheetsQuantity));
+	project_root.setAttribute("folioSheetQuantity", QString::number(m_folio_sheets_quantity));
 	xml_doc.appendChild(project_root);
 	
 	// titleblock templates, if any
-	if (titleblocks_.templates().count()) {
+	if (m_titleblocks_collection.templates().count()) {
 		QDomElement titleblocktemplates_elmt = xml_doc.createElement("titleblocktemplates");
-		foreach (QString template_name, titleblocks_.templates()) {
-			QDomElement e = titleblocks_.getTemplateXmlDescription(template_name);
+		foreach (QString template_name, m_titleblocks_collection.templates()) {
+			QDomElement e = m_titleblocks_collection.getTemplateXmlDescription(template_name);
 			titleblocktemplates_elmt.appendChild(xml_doc.importNode(e, true));
 		}
 		project_root.appendChild(titleblocktemplates_elmt);
@@ -876,10 +896,10 @@
 	if (!QET::writeXmlFile(xml_project, m_file_path, &error_message)) return(error_message);
 	
 	//title block variables should be updated after file save dialog is confirmed, before file is saved.
-	project_properties_.addValue("saveddate", QDate::currentDate().toString(Qt::SystemLocaleShortDate));
-	project_properties_.addValue("savedtime", QDateTime::currentDateTime().toString("HH:mm"));
-	project_properties_.addValue("savedfilename", QFileInfo(filePath()).baseName());
-	project_properties_.addValue("savedfilepath", filePath());
+	m_project_properties.addValue("saveddate", QDate::currentDate().toString(Qt::SystemLocaleShortDate));
+	m_project_properties.addValue("savedtime", QDateTime::currentDateTime().toString("HH:mm"));
+	m_project_properties.addValue("savedfilename", QFileInfo(filePath()).baseName());
+	m_project_properties.addValue("savedfilepath", filePath());
 	
 	
 	
@@ -895,7 +915,7 @@
 	@return true si le projet est en mode readonly, false sinon
 */
 bool QETProject::isReadOnly() const {
-	return(read_only_ && read_only_file_path_ == m_file_path);
+	return(m_read_only && read_only_file_path_ == m_file_path);
 }
 
 /**
@@ -905,11 +925,11 @@
  */
 void QETProject::setReadOnly(bool read_only)
 {
-	if (read_only_ != read_only)
+	if (m_read_only != read_only)
 	{
 			//keep the file to which this project is read-only
 		read_only_file_path_ = m_file_path;
-		read_only_ = read_only;
+		m_read_only = read_only;
 		emit(readOnlyChanged(this, read_only));
 	}
 }
@@ -1032,11 +1052,11 @@
 	@return the name of the template after integration, or an empty QString if a problem occurred.
 */
 QString QETProject::integrateTitleBlockTemplate(const TitleBlockTemplateLocation &src_tbt, MoveTitleBlockTemplatesHandler *handler) {
-	TitleBlockTemplateLocation dst_tbt(src_tbt.name(), &titleblocks_);
+	TitleBlockTemplateLocation dst_tbt(src_tbt.name(), &m_titleblocks_collection);
 	
 	// check whether a TBT having the same name already exists within this project
 	QString target_name = dst_tbt.name();
-	while (titleblocks_.templates().contains(target_name))
+	while (m_titleblocks_collection.templates().contains(target_name))
 	{
 		QET::Action action = handler -> templateAlreadyExists(src_tbt, dst_tbt);
 		if (action == QET::Retry) {
@@ -1052,7 +1072,7 @@
 		}
 	}
 	
-	if (!titleblocks_.setTemplateXmlDescription(target_name, src_tbt.getTemplateXmlDescription()))
+	if (!m_titleblocks_collection.setTemplateXmlDescription(target_name, src_tbt.getTemplateXmlDescription()))
 	{
 		handler -> errorWithATemplate(src_tbt, tr("Une erreur s'est produite durant l'intégration du modèle.", "error message"));
 		target_name = QString();
@@ -1213,33 +1233,14 @@
 	Mark this project as modified and emit the projectModified() signal.
 */
 void QETProject::setModified(bool modified) {
-	if (modified_ != modified) {
-		modified_ = modified;
-		emit(projectModified(this, modified_));
+	if (m_modified != modified) {
+		m_modified = modified;
+		emit(projectModified(this, m_modified));
 		emit(projectInformationsChanged(this));
 	}
 }
 
 /**
-	Set up signals/slots connections related to the title block templates
-	collection.
-*/
-void QETProject::setupTitleBlockTemplatesCollection() {
-	connect(
-		&titleblocks_,
-		SIGNAL(changed(TitleBlockTemplatesCollection *, const QString &)),
-		this,
-		SLOT(updateDiagramsTitleBlockTemplate(TitleBlockTemplatesCollection *, const QString &))
-	);
-	connect(
-		&titleblocks_,
-		SIGNAL(aboutToRemove(TitleBlockTemplatesCollection *, const QString &)),
-		this,
-		SLOT(removeDiagramsTitleBlockTemplate(TitleBlockTemplatesCollection *, const QString &))
-	);
-}
-
-/**
  * @brief QETProject::readProjectXml
  * Read and make the project from an xml description
  * @param xml_project : the description of the project from an xml
@@ -1247,7 +1248,7 @@
 void QETProject::readProjectXml(QDomDocument &xml_project)
 {
 	QDomElement root_elmt = xml_project.documentElement();
-	state_ = ProjectParsingRunning;
+	m_state = ProjectParsingRunning;
 	
 		//The roots of the xml document must be a "project" element
 	if (root_elmt.tagName() == "project")
@@ -1256,9 +1257,9 @@
 		if (root_elmt.hasAttribute("version"))
 		{
 			bool conv_ok;
-			project_qet_version_ = root_elmt.attribute("version").toDouble(&conv_ok);
+			m_project_qet_version = root_elmt.attribute("version").toDouble(&conv_ok);
 
-			if (conv_ok && QET::version.toDouble() < project_qet_version_)
+			if (conv_ok && QET::version.toDouble() < m_project_qet_version)
 			{
 				int ret = QET::QetMessageBox::warning(
 							  nullptr,
@@ -1276,7 +1277,7 @@
 				
 				if (ret == QMessageBox::Cancel)
 				{
-					state_ = FileOpenDiscard;
+					m_state = FileOpenDiscard;
 					return;
 				}
 			}
@@ -1285,7 +1286,7 @@
 	}
 	else
 	{
-		state_ = ProjectParsingFailed;
+		m_state = ProjectParsingFailed;
 	}
 	
 		//Load the project-wide properties
@@ -1293,7 +1294,7 @@
 		//Load the default properties for the new diagrams
 	readDefaultPropertiesXml(xml_project);
 		//load the embedded titleblock templates
-	titleblocks_.fromXml(xml_project.documentElement());
+	m_titleblocks_collection.fromXml(xml_project.documentElement());
 		//Load the embedded elements collection
 	readElementsCollectionXml(xml_project);
 		//Load the diagrams
@@ -1304,7 +1305,7 @@
 	if (root_elmt.attribute("folioSheetQuantity","0").toInt())
 		addNewDiagramFolioList();
 	
-	state_ = Ok;
+	m_state = Ok;
 }
 
 /**
@@ -1422,7 +1423,7 @@
 void QETProject::readProjectPropertiesXml(QDomDocument &xml_project)
 {
 	foreach (QDomElement e, QET::findInDomElement(xml_project.documentElement(), "properties"))
-		project_properties_.fromXml(e);
+		m_project_properties.fromXml(e);
 }
 
 /**
@@ -1523,7 +1524,7 @@
 	Export project properties under the \a xml_element XML element.
 */
 void QETProject::writeProjectPropertiesXml(QDomElement &xml_element) {
-	project_properties_.toXml(xml_element);
+	m_project_properties.toXml(xml_element);
 }
 
 /**
@@ -1675,24 +1676,14 @@
  */
 void QETProject::writeBackup()
 {
-	if(m_file_path.isEmpty())
+	if (!m_backup_file ||
+		(!m_backup_file->isOpen() && !m_backup_file->open(QIODevice::ReadWrite))) {
 		return;
-	
-	QDir dir(QETApp::configDir() + "backup");
-	if(!dir.exists())
-	{
-		dir.cdUp();
-		dir.mkdir("backup");
-		dir.cd("backup");
 	}
-	
-	QFileInfo info(m_file_path);
-	if(info.exists())
-	{
-		QDomDocument xml_project;
-		xml_project.appendChild(xml_project.importNode(toXml().documentElement(), true));
-		QET::writeXmlFile(xml_project, dir.absoluteFilePath(info.fileName()));
-	}	
+
+	QDomDocument xml_project;
+	xml_project.appendChild(xml_project.importNode(toXml().documentElement(), true));
+	QET::writeToFile(xml_project, m_backup_file);
 }
 
 /**
@@ -1702,7 +1693,7 @@
 bool QETProject::projectOptionsWereModified() {
 	// unlike similar methods, this method does not compare the content against
 	// expected values; instead, we just check whether we have been set as modified.
-	return(modified_);
+	return(m_modified);
 }
 
 /**
@@ -1709,7 +1700,7 @@
 	@return the project-wide properties made available to child diagrams.
 */
 DiagramContext QETProject::projectProperties() {
-	return(project_properties_);
+	return(m_project_properties);
 }
 
 /**
@@ -1716,7 +1707,7 @@
 	Use \a context as project-wide properties made available to child diagrams.
 */
 void QETProject::setProjectProperties(const DiagramContext &context) {
-	project_properties_ = context;
+	m_project_properties = context;
 	updateDiagramsFolioData();
 }
 
@@ -1733,7 +1724,7 @@
 
 	if ( projectOptionsWereModified()    ||
 		 !m_undo_stack -> isClean()       ||
-		 titleblocks_.templates().count() )
+		 m_titleblocks_collection.templates().count() )
 		return(true);
 	
 	else
@@ -1748,7 +1739,7 @@
 {
 	int total_folio = m_diagrams_list.count();
 	
-	DiagramContext project_wide_properties = project_properties_;
+	DiagramContext project_wide_properties = m_project_properties;
 	project_wide_properties.addValue("projecttitle", title());
 	project_wide_properties.addValue("projectpath", filePath());
 	project_wide_properties.addValue("projectfilename", QFileInfo(filePath()).baseName());

Modified: trunk/sources/qetproject.h
===================================================================
--- trunk/sources/qetproject.h	2019-03-15 18:07:57 UTC (rev 5787)
+++ trunk/sources/qetproject.h	2019-03-16 10:50:30 UTC (rev 5788)
@@ -35,6 +35,7 @@
 class QUndoStack;
 class XmlElementCollection;
 class QTimer;
+class KAutoSaveFile;
 
 /**
 	This class represents a QET project. Typically saved as a .qet file, it
@@ -45,32 +46,29 @@
 class QETProject : public QObject
 {
 		Q_OBJECT
+	public :
+		//This enum lists possible states for a particular project.
+		enum ProjectState {
+			Ok                    = 0, /// no error
+			FileOpenFailed        = 1, /// file opening failed
+			XmlParsingFailed      = 2, /// XML parsing failed
+			ProjectParsingRunning = 3, /// the XML content is currently being processed
+			ProjectParsingFailed  = 4, /// the parsing of the XML content failed
+			FileOpenDiscard       = 5  /// the user cancelled the file opening
+		};
 
 		Q_PROPERTY(bool autoConductor READ autoConductor WRITE setAutoConductor)
 	
 		// constructors, destructor
 	public:
-		QETProject (int = 1, QObject * = nullptr);
-		QETProject (const QString &, QObject * = nullptr);
+		QETProject (QObject *parent = nullptr);
+		QETProject (const QString &path, QObject * = nullptr);
+		QETProject (KAutoSaveFile *backup, QObject *parent=nullptr);
 		~QETProject() override;
-	
+
 	private:
 		QETProject(const QETProject &);
 	
-		// enums
-	public:
-	/**
-		This enum lists possible states for a particular project.
-	*/
-	enum ProjectState {
-		Ok                    = 0, /// no error
-		FileOpenFailed        = 1, /// file opening failed
-		XmlParsingFailed      = 2, /// XML parsing failed
-		ProjectParsingRunning = 3, /// the XML content is currently being processed
-		ProjectParsingFailed  = 4, /// the parsing of the XML content failed
-		FileOpenDiscard       = 5  /// the user cancelled the file opening
-	};
-	
 		// methods
 	public:
 		ProjectState state() const;
@@ -203,7 +201,6 @@
 		void undoStackChanged (bool a) {if (!a) setModified(true);}
 	
 	private:
-		void setupTitleBlockTemplatesCollection();
 		void readProjectXml(QDomDocument &xml_project);
 		void readDiagramsXml(QDomDocument &xml_project);
 		void readElementsCollectionXml(QDomDocument &xml_project);
@@ -215,6 +212,8 @@
 		void addDiagram(Diagram *);
 		NamesList namesListForIntegrationCategory();
 		void writeBackup();
+		void init();
+		ProjectState openFile(QFile *file);
 	
 	// attributes
 	private:
@@ -221,17 +220,17 @@
 			/// File path this project is saved to
 		QString m_file_path;
 			/// Current state of the project
-		ProjectState state_;
+		ProjectState m_state;
 			/// Diagrams carried by the project
 		QList<Diagram *> m_diagrams_list;
 			/// Project title
 		QString project_title_;
 			/// QElectroTech version declared in the XML document at opening time
-		qreal project_qet_version_;
+		qreal m_project_qet_version = -1;
 			/// Whether options were modified
-		bool modified_;
+		bool m_modified = false;
 			/// Whether the project is read only
-		bool read_only_;
+		bool m_read_only = false;
 			/// Filepath for which this project is considered read only
 		QString read_only_file_path_;
 			/// Default dimensions and properties for new diagrams created within the project
@@ -245,9 +244,9 @@
 			/// Default xref properties
 		QHash <QString, XRefProperties> m_default_xref_properties;
 			/// Embedded title block templates collection
-		TitleBlockTemplatesProjectCollection titleblocks_;
+		TitleBlockTemplatesProjectCollection m_titleblocks_collection;
 			/// project-wide variables that will be made available to child diagrams
-		DiagramContext project_properties_;
+		DiagramContext m_project_properties;
 			/// undo stack for this project
 		QUndoStack *m_undo_stack;
 			/// Conductor auto numerotation
@@ -259,13 +258,14 @@
 		QHash <QString, NumerotationContext> m_element_autonum; //Title and NumContext hash
 		QString m_current_element_autonum;
 			/// Folio List Sheets quantity for this project.
-		int folioSheetsQuantity;
-		bool m_auto_conductor;
-		XmlElementCollection *m_elements_collection;
-		bool m_freeze_new_elements;
-		bool m_freeze_new_conductors;
+		int m_folio_sheets_quantity = 0;
+		bool m_auto_conductor = true;
+		XmlElementCollection *m_elements_collection = nullptr;
+		bool m_freeze_new_elements = false;
+		bool m_freeze_new_conductors = false;
 		QTimer m_save_backup_timer,
 			   m_autosave_timer;
+		KAutoSaveFile *m_backup_file = nullptr;
 };
 
 Q_DECLARE_METATYPE(QETProject *)


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