[qet] [1133] Added context menu entries and a basic, non-WYSIWYG template editor to add, modify and delete title block templates embedded within a project.

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


Revision: 1133
Author:   xavier
Date:     2010-12-24 22:00:11 +0100 (Fri, 24 Dec 2010)
Log Message:
-----------
Added context menu entries and a basic, non-WYSIWYG template editor to add, modify and delete title block templates embedded within a project.

Modified Paths:
--------------
    branches/0.3/qelectrotech.qrc
    branches/0.3/sources/bordertitleblock.cpp
    branches/0.3/sources/bordertitleblock.h
    branches/0.3/sources/diagram.cpp
    branches/0.3/sources/diagram.h
    branches/0.3/sources/elementspanel.cpp
    branches/0.3/sources/elementspanel.h
    branches/0.3/sources/elementspanelwidget.cpp
    branches/0.3/sources/elementspanelwidget.h
    branches/0.3/sources/qetapp.cpp
    branches/0.3/sources/qetapp.h
    branches/0.3/sources/qeticons.cpp
    branches/0.3/sources/qeticons.h
    branches/0.3/sources/qetproject.cpp
    branches/0.3/sources/qetproject.h
    branches/0.3/sources/titleblocktemplate.cpp
    branches/0.3/sources/titleblocktemplaterenderer.h

Added Paths:
-----------
    branches/0.3/ico/titleblock.png
    branches/0.3/sources/templateeditor.cpp
    branches/0.3/sources/templateeditor.h

Added: branches/0.3/ico/titleblock.png
===================================================================
(Binary files differ)


Property changes on: branches/0.3/ico/titleblock.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Modified: branches/0.3/qelectrotech.qrc
===================================================================
--- branches/0.3/qelectrotech.qrc	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/qelectrotech.qrc	2010-12-24 21:00:11 UTC (rev 1133)
@@ -180,6 +180,7 @@
 	<file>ico/oxygen-icons/48x48/apps/qelectrotech.png</file>
 	<file>ico/oxygen-icons/64x64/apps/qelectrotech.png</file>
 	<file>ico/splash.png</file>
+	<file>ico/titleblock.png</file>
 	<file>titleblocks/default.titleblock</file>
 	<file>LICENSE</file>
 </qresource>

Modified: branches/0.3/sources/bordertitleblock.cpp
===================================================================
--- branches/0.3/sources/bordertitleblock.cpp	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/bordertitleblock.cpp	2010-12-24 21:00:11 UTC (rev 1133)
@@ -162,6 +162,35 @@
 }
 
 /**
+	This slot may be used to inform this class that the given title block
+	template has changed. The title block-dedicated rendering cache will thus be
+	flushed.
+	@param template_name Name of the title block template that has changed
+*/
+void BorderTitleBlock::titleBlockTemplateChanged(const QString &template_name) {
+	Q_UNUSED(template_name); // this class does not store the name of its template
+	titleblock_template_renderer -> invalidateRenderedTemplate();
+}
+
+/**
+	This slot has to be used to inform this class that the given title block
+	template is about to be removed and is no longer accessible. This class
+	will either use the provided optional TitleBlockTemplate or the default
+	title block provided by QETApp::defaultTitleBlockTemplate()
+	@param template_name Name of the title block template that has changed
+	@param new_template (Optional) title block template to use instead
+*/
+void BorderTitleBlock::titleBlockTemplateRemoved(const QString &removed_template_name, const TitleBlockTemplate *new_template) {
+	Q_UNUSED(removed_template_name); // this class does not store the name of its template
+	
+	if (new_template) {
+		setTitleBlockTemplate(new_template);
+	} else {
+		setTitleBlockTemplate(QETApp::defaultTitleBlockTemplate());
+	}
+}
+
+/**
 	@param di true pour afficher le cartouche, false sinon
 */
 void BorderTitleBlock::displayTitleBlock(bool di) {

Modified: branches/0.3/sources/bordertitleblock.h
===================================================================
--- branches/0.3/sources/bordertitleblock.h	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/bordertitleblock.h	2010-12-24 21:00:11 UTC (rev 1133)
@@ -153,6 +153,10 @@
 	const TitleBlockTemplate *titleBlockTemplate();
 	void setTitleBlockTemplate(const TitleBlockTemplate *);
 	
+	public slots:
+	void titleBlockTemplateChanged(const QString &);
+	void titleBlockTemplateRemoved(const QString &, const TitleBlockTemplate * = 0);
+	
 	// methodes d'acces en ecriture aux options
 	void displayTitleBlock(bool);
 	void displayColumns(bool);

Modified: branches/0.3/sources/diagram.cpp
===================================================================
--- branches/0.3/sources/diagram.cpp	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/diagram.cpp	2010-12-24 21:00:11 UTC (rev 1133)
@@ -766,6 +766,36 @@
 }
 
 /**
+	This slot may be used to inform the diagram object that the given title
+	block template has changed. The diagram will thus flush its title
+	block-dedicated rendering cache.
+	@param template_name Name of the title block template that has changed
+*/
+void Diagram::titleBlockTemplateChanged(const QString &template_name) {
+	if (titleblock_template_name_ == template_name) {
+		border_and_titleblock.titleBlockTemplateChanged(template_name);
+	}
+	update();
+}
+
+/**
+	This slot has to be be used to inform this class that the given title block
+	template is about to be removed and is no longer accessible. This class
+	will either use the provided  optional TitleBlockTemplate or the default
+	title block provided by QETApp::defaultTitleBlockTemplate()
+	@param template_name Name of the title block template that has changed
+	@param new_template (Optional) Name of the title block template to use instead
+*/
+void Diagram::titleBlockTemplateRemoved(const QString &template_name, const QString &new_template) {
+	if (titleblock_template_name_ == template_name) {
+		const TitleBlockTemplate *final_template = project_ -> getTemplateByName(new_template);
+		titleblock_template_name_ = final_template ? new_template : QString();
+		border_and_titleblock.titleBlockTemplateRemoved(template_name, final_template);
+		update();
+	}
+}
+
+/**
 	Selectionne tous les objets du schema
 */
 void Diagram::selectAll() {

Modified: branches/0.3/sources/diagram.h
===================================================================
--- branches/0.3/sources/diagram.h	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/diagram.h	2010-12-24 21:00:11 UTC (rev 1133)
@@ -169,6 +169,8 @@
 	
 	public slots:
 	void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
+	void titleBlockTemplateChanged(const QString &);
+	void titleBlockTemplateRemoved(const QString &, const QString & = QString());
 	
 	// fonctions relative a la selection sur le schema
 	void selectAll();

Modified: branches/0.3/sources/elementspanel.cpp
===================================================================
--- branches/0.3/sources/elementspanel.cpp	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/elementspanel.cpp	2010-12-24 21:00:11 UTC (rev 1133)
@@ -171,6 +171,24 @@
 }
 
 /**
+	@param qtwi A QTreeWidgetItem 
+	@return true if the given QTreeWidgetItem represents a block templates directory
+*/
+bool ElementsPanel::itemIsATitleBlockTemplatesDirectory(QTreeWidgetItem *qtwi) const {
+	return(title_blocks_directories_.contains(qtwi));
+}
+
+/**
+	@param qtwi A QTreeWidgetItem 
+	@return true if the given QTreeWidgetItem represents a block template
+*/
+bool ElementsPanel::itemIsATitleBlockTemplate(QTreeWidgetItem *qtwi) const {
+	// does this QTreeWidgetItem have a parent?
+	if (!qtwi -> parent()) return(false);
+	return(itemIsATitleBlockTemplatesDirectory(qtwi -> parent()));
+}
+
+/**
 	@param qtwi Un QTreeWidgetItem
 	@return L'ElementsCollectionItem represente par qtwi, ou 0 si qtwi ne
 	represente pas un ElementsCollectionItem
@@ -280,6 +298,23 @@
 }
 
 /**
+	@return true if the currently selected item represents a title block
+	templates directory
+*/
+bool ElementsPanel::selectedItemIsATitleBlockTemplatesDirectory() const {
+	return(itemIsATitleBlockTemplatesDirectory(currentItem()));
+}
+
+/**
+	@return true if the currently selected item represents a title block
+	template
+*/
+bool ElementsPanel::selectedItemIsATitleBlockTemplate() const {
+	if (!currentItem()) return(false);
+	return(itemIsATitleBlockTemplate(currentItem()));
+}
+
+/**
 	@return la collection, la categorie ou l'element selectionne(e)
 */
 ElementsCollectionItem *ElementsPanel::selectedItem() const {
@@ -507,6 +542,13 @@
 		addDiagram(qtwi_project, diagram);
 	}
 	
+	// add the title blocks templates embedded within the project
+	updateProjectTemplates(project);
+	connect(
+		project, SIGNAL(projectTemplatesChanged(QETProject *)),
+		this,    SLOT  (projectTemplatesChanged(QETProject *))
+	);
+	
 	// ajoute la collection du projet
 	addCollection(qtwi_project, project -> embeddedCollection(), tr("Collection projet"));
 	
@@ -673,6 +715,7 @@
 	locations_.clear();
 	projects_.clear();
 	diagrams_.clear();
+	title_blocks_directories_.clear();
 	common_collection_item_ = 0;
 	custom_collection_item_ = 0;
 	
@@ -769,6 +812,8 @@
 		diagrams_.remove(removed_item);
 	} else if (projects_.contains(removed_item)) {
 		projects_.remove(removed_item);
+	} else if (title_blocks_directories_.contains(removed_item)) {
+		title_blocks_directories_.remove(removed_item);
 	}
 	delete removed_item;
 }
@@ -790,6 +835,41 @@
 }
 
 /**
+	@param qtwi A QTreeWidgetItem, supposed to represent a templates directory
+	@return the project that embeds the given templates directory, if
+	applicable, 0 otherwise
+*/
+QETProject *ElementsPanel::projectForTitleBlockTemplatesDirectory(QTreeWidgetItem *qtwi) {
+	if (title_blocks_directories_.contains(qtwi)) {
+		return(title_blocks_directories_[qtwi]);
+	}
+	return(0);
+}
+
+/**
+	@param qtwi A QTreeWidgetItem, supposed to represent a title block template
+	@return the project that embeds the given template, if applicable, 0
+	otherwise
+*/
+QETProject *ElementsPanel::projectForTitleBlockTemplate(QTreeWidgetItem *qtwi) {
+	if (qtwi->parent()) {
+		return(projectForTitleBlockTemplatesDirectory(qtwi->parent()));
+	}
+	return(0);
+}
+
+/**
+	@param qtwi A QTreeWidgetItem, supposed to represent a title block template
+	@return the name of the given template, if applicable, 0 otherwise
+*/
+QString ElementsPanel::nameOfTitleBlockTemplate(QTreeWidgetItem *qtwi) {
+	if (itemIsATitleBlockTemplate(qtwi)) {
+		return(qtwi -> data(0, 42).toString());
+	}
+	return(QString());
+}
+
+/**
 	Cette methode permet d'acceder a la categorie correspondant a un item donne.
 	Si cet item represente une collection, c'est sa categorie racine qui est renvoyee.
 	Si cet item represente une categorie, c'est cette categorie qui est renvoyee.
@@ -861,6 +941,14 @@
 }
 
 /**
+	Handles the fact that the title block templates of a project changed.
+	@param project the modified project
+*/
+void ElementsPanel::projectTemplatesChanged(QETProject *project) {
+	updateProjectTemplates(project);
+}
+
+/**
 	Gere l'ajout d'un schema dans un projet
 	@param project Projet auquel a ete ajouter le schema
 	@param diagram Schema ajoute
@@ -966,6 +1054,39 @@
 }
 
 /**
+	(Re)generates the templates list of a given project.
+	@param project the project we want to update the templates
+*/
+void ElementsPanel::updateProjectTemplates(QETProject *project) {
+	// determine the QTWI for the templates directory of the given project
+	QTreeWidgetItem *qtwi_project = projects_.key(project);
+	if (!qtwi_project) return;
+	
+	// determine the templates directory for the given project, if any
+	QTreeWidgetItem *titleblock_templates_qtwi = title_blocks_directories_.key(project);
+	if (!titleblock_templates_qtwi) {
+		// the poor thing does not exist... let's create it.
+		titleblock_templates_qtwi = new QTreeWidgetItem(qtwi_project, QStringList() << tr("Mod\350les de cartouche"));
+		titleblock_templates_qtwi -> setIcon(0, QET::Icons::Folder);
+		titleblock_templates_qtwi -> setExpanded(true);
+		title_blocks_directories_.insert(titleblock_templates_qtwi, project);
+	} else {
+		// oh, what a shiny templates directory... let's clear it.
+		foreach(QTreeWidgetItem *titleblock_template_qtwi, titleblock_templates_qtwi -> takeChildren()) {
+			deleteItem(titleblock_template_qtwi);
+		}
+	}
+	
+	// we can now populate the templates directory
+	foreach (QString titleblock_name, project -> embeddedTitleBlockTemplates()) {
+		QString final_name = QString(tr("Mod\350le \"%1\"")).arg(titleblock_name);
+		QTreeWidgetItem *titleblock_template_qtwi = new QTreeWidgetItem(titleblock_templates_qtwi, QStringList() << final_name);
+		titleblock_template_qtwi -> setIcon(0, QET::Icons::TitleBlock);
+		titleblock_template_qtwi -> setData(0, 42, titleblock_name); // we store the original title block template name here, since the displayed one could be modified
+	}
+}
+
+/**
 	@param diagram Schema dont on souhaite affiche le titre
 	@return Un titre affichable, tenant compte du fait que le titre du schema
 	peut etre vide.

Modified: branches/0.3/sources/elementspanel.h
===================================================================
--- branches/0.3/sources/elementspanel.h	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/elementspanel.h	2010-12-24 21:00:11 UTC (rev 1133)
@@ -51,6 +51,8 @@
 	bool itemIsADiagram(QTreeWidgetItem *) const;
 	bool itemHasLocation(QTreeWidgetItem *) const;
 	bool itemIsWritable(QTreeWidgetItem *) const;
+	bool itemIsATitleBlockTemplatesDirectory(QTreeWidgetItem *) const;
+	bool itemIsATitleBlockTemplate(QTreeWidgetItem *) const;
 	
 	// methodes pour obtenir ce que represente un item donne
 	ElementsCollectionItem *collectionItemForItem(QTreeWidgetItem *) const;
@@ -59,6 +61,9 @@
 	ElementsLocation locationForItem(QTreeWidgetItem *) const;
 	ElementsCategory *categoryForItem(QTreeWidgetItem *);
 	ElementsCategory *categoryForPos(const QPoint &);
+	QETProject *projectForTitleBlockTemplatesDirectory(QTreeWidgetItem *);
+	QETProject *projectForTitleBlockTemplate(QTreeWidgetItem *);
+	QString nameOfTitleBlockTemplate(QTreeWidgetItem *);
 	
 	// methodes pour determiner ce que represente l'item selectionne
 	bool selectedItemIsACollection() const;
@@ -68,6 +73,8 @@
 	bool selectedItemIsADiagram() const;
 	bool selectedItemHasLocation() const;
 	bool selectedItemIsWritable() const;
+	bool selectedItemIsATitleBlockTemplatesDirectory() const;
+	bool selectedItemIsATitleBlockTemplate() const;
 	
 	// methodes pour obtenir ce que represente l'item selectionne
 	ElementsCollectionItem *selectedItem() const;
@@ -88,6 +95,7 @@
 	void projectWasOpened(QETProject *);
 	void projectWasClosed(QETProject *);
 	void projectInformationsChanged(QETProject *);
+	void projectTemplatesChanged(QETProject *);
 	void diagramWasAdded(QETProject *, Diagram *);
 	void diagramWasRemoved(QETProject *, Diagram *);
 	void diagramTitleChanged(QETProject *, Diagram *);
@@ -111,6 +119,7 @@
 	QTreeWidgetItem *findLocation(const QString &) const;
 	void deleteItem(QTreeWidgetItem *);
 	void updateProjectItemInformations(QETProject *);
+	void updateProjectTemplates(QETProject *);
 	QString diagramTitleToDisplay(Diagram *) const;
 	void ensureHierarchyIsVisible(QList<QTreeWidgetItem *>);
 	
@@ -122,6 +131,7 @@
 	QSet<QETProject *> projects_to_display_;
 	QHash<QTreeWidgetItem *, QETProject *> projects_;
 	QHash<QTreeWidgetItem *, Diagram *> diagrams_;
+	QHash<QTreeWidgetItem *, QETProject *> title_blocks_directories_;
 	QTreeWidgetItem *common_collection_item_;
 	QTreeWidgetItem *custom_collection_item_;
 };

Modified: branches/0.3/sources/elementspanelwidget.cpp
===================================================================
--- branches/0.3/sources/elementspanelwidget.cpp	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/elementspanelwidget.cpp	2010-12-24 21:00:11 UTC (rev 1133)
@@ -64,6 +64,9 @@
 	prj_del_diagram       = new QAction(QET::Icons::DiagramDelete,             tr("Supprimer ce sch\351ma"),              this);
 	prj_move_diagram_up   = new QAction(QET::Icons::GoUp,                      tr("Remonter ce sch\351ma"),               this);
 	prj_move_diagram_down = new QAction(QET::Icons::GoDown,                    tr("Abaisser ce sch\351ma"),               this);
+	tbt_add               = new QAction(QET::Icons::TitleBlock,                tr("Importer un nouveau mod\350le"),       this);
+	tbt_edit              = new QAction(QET::Icons::TitleBlock,                tr("\311diter ce mod\350le"),              this);
+	tbt_remove            = new QAction(QET::Icons::TitleBlock,                tr("Supprimer ce mod\350le"),              this);
 	move_elements_        = new QAction(QET::Icons::MoveFile,                  tr("D\351placer dans cette cat\351gorie"), this);
 	copy_elements_        = new QAction(QET::Icons::CopyFile,                  tr("Copier dans cette cat\351gorie"),      this);
 	cancel_elements_      = new QAction(QET::Icons::Cancel,                    tr("Annuler"),                             this);
@@ -102,6 +105,9 @@
 	connect(prj_del_diagram,       SIGNAL(triggered()), this,           SLOT(deleteDiagram()));
 	connect(prj_move_diagram_up,   SIGNAL(triggered()), this,           SLOT(moveDiagramUp()));
 	connect(prj_move_diagram_down, SIGNAL(triggered()), this,           SLOT(moveDiagramDown()));
+	connect(tbt_add,               SIGNAL(triggered()), this,           SLOT(addTitleBlockTemplate()));
+	connect(tbt_edit,              SIGNAL(triggered()), this,           SLOT(editTitleBlockTemplate()));
+	connect(tbt_remove,            SIGNAL(triggered()), this,           SLOT(removeTitleBlockTemplate()));
 	connect(move_elements_,        SIGNAL(triggered()), this,           SLOT(moveElements()));
 	connect(copy_elements_,        SIGNAL(triggered()), this,           SLOT(copyElements()));
 	
@@ -235,6 +241,49 @@
 }
 
 /**
+	Opens a template editor to create a new title block template.
+*/
+void ElementsPanelWidget::addTitleBlockTemplate() {
+	QTreeWidgetItem *current_item = elements_panel -> currentItem();
+	if (!current_item) return;
+	
+	QETProject *parent_project = 0;
+	if (elements_panel -> itemIsATitleBlockTemplate(current_item)) {
+		parent_project = elements_panel -> projectForTitleBlockTemplate(current_item);
+	} else if (elements_panel -> itemIsATitleBlockTemplatesDirectory(current_item)) {
+		parent_project = elements_panel -> projectForTitleBlockTemplatesDirectory(current_item);
+	}
+	
+	if (parent_project) {
+		QETApp::instance() -> openTitleBlockTemplate(parent_project);
+	}
+}
+
+/**
+	Opens an editor to edit the currently selected title block template, if any.
+*/
+void ElementsPanelWidget::editTitleBlockTemplate() {
+	QTreeWidgetItem *current_item = elements_panel -> currentItem();
+	if (current_item && elements_panel -> itemIsATitleBlockTemplate(current_item)) {
+		QETProject *parent_project = elements_panel -> projectForTitleBlockTemplate(current_item);
+		QString template_name = elements_panel -> nameOfTitleBlockTemplate(current_item);
+		QETApp::instance() -> openTitleBlockTemplate(parent_project, template_name);
+	}
+}
+
+/**
+	Delete the currently selected title block template, if any.
+*/
+void ElementsPanelWidget::removeTitleBlockTemplate() {
+	QTreeWidgetItem *current_item = elements_panel -> currentItem();
+	if (current_item && elements_panel -> itemIsATitleBlockTemplate(current_item)) {
+		QETProject *parent_project = elements_panel -> projectForTitleBlockTemplate(current_item);
+		QString template_name = elements_panel -> nameOfTitleBlockTemplate(current_item);
+		parent_project -> removeTemplateByName(template_name);
+	}
+}
+
+/**
 	Appelle l'assistant de creation de nouvel element
 */
 void ElementsPanelWidget::newElement() {
@@ -311,6 +360,14 @@
 		prj_del_diagram       -> setEnabled(is_writable);
 		prj_move_diagram_up   -> setEnabled(is_writable && diagram_position > 0);
 		prj_move_diagram_down -> setEnabled(is_writable && diagram_position < project_diagrams_count - 1);
+	} else if (elements_panel -> selectedItemIsATitleBlockTemplatesDirectory()) {
+		bool is_writable = !(elements_panel -> projectForTitleBlockTemplatesDirectory(elements_panel -> currentItem()) -> isReadOnly());
+		tbt_add -> setEnabled(is_writable);
+	} else if (elements_panel -> selectedItemIsATitleBlockTemplate()) {
+		bool is_writable = !(elements_panel -> projectForTitleBlockTemplate(elements_panel -> currentItem()) -> isReadOnly());
+		tbt_add -> setEnabled(is_writable);
+		tbt_edit -> setEnabled(is_writable);
+		tbt_remove -> setEnabled(is_writable);
 	}
 }
 
@@ -381,6 +438,12 @@
 			context_menu -> addAction(prj_del_diagram);
 			context_menu -> addAction(prj_move_diagram_up);
 			context_menu -> addAction(prj_move_diagram_down);
+		} else if (elements_panel -> itemIsATitleBlockTemplatesDirectory(item)) {
+			context_menu -> addAction(tbt_add);
+		} else if (elements_panel -> itemIsATitleBlockTemplate(item)) {
+			context_menu -> addAction(tbt_add);
+			context_menu -> addAction(tbt_edit);
+			context_menu -> addAction(tbt_remove);
 		}
 	}
 	

Modified: branches/0.3/sources/elementspanelwidget.h
===================================================================
--- branches/0.3/sources/elementspanelwidget.h	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/elementspanelwidget.h	2010-12-24 21:00:11 UTC (rev 1133)
@@ -43,6 +43,7 @@
 	QAction *delete_collection;
 	QAction *new_element, *import_element,  *edit_element,  *delete_element;
 	QAction *prj_close, *prj_edit_prop, *prj_prop_diagram, *prj_add_diagram, *prj_del_diagram, *prj_move_diagram_up, *prj_move_diagram_down;
+	QAction *tbt_add, *tbt_edit, *tbt_remove;
 	QAction *copy_elements_, *move_elements_, *cancel_elements_;
 	QMenu *context_menu;
 	QAction *erase_textfield;
@@ -72,6 +73,9 @@
 	void deleteDiagram();
 	void moveDiagramUp();
 	void moveDiagramDown();
+	void addTitleBlockTemplate();
+	void editTitleBlockTemplate();
+	void removeTitleBlockTemplate();
 	void newCategory();
 	void newElement();
 	void importElement();

Modified: branches/0.3/sources/qetapp.cpp
===================================================================
--- branches/0.3/sources/qetapp.cpp	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/qetapp.cpp	2010-12-24 21:00:11 UTC (rev 1133)
@@ -23,6 +23,7 @@
 #include "elementscollectionitem.h"
 #include "fileelementscollection.h"
 #include "titleblocktemplate.h"
+#include "templateeditor.h"
 #include "qetproject.h"
 #include "qtextorientationspinboxwidget.h"
 #include "recentfiles.h"
@@ -836,6 +837,23 @@
 }
 
 /**
+	Launch a new title block template editor to edit the given template
+	@param project Parent project of the template to edit
+	@param template_name Name of the template to edit within its parent project
+	If no template name is supplied, the method assumes the editor has to be
+	launched for a template creation.
+*/
+void QETApp::openTitleBlockTemplate(QETProject *project, const QString &template_name) {
+	TemplateEditor *editor = new TemplateEditor();
+	bool can_edit = editor -> edit(project, template_name);
+	if (can_edit) {
+		editor -> showNormal();
+	} else {
+		QMessageBox::warning(0, tr("Erreur"), tr("Impossible d'\351diter le template demand\351"));
+	}
+}
+
+/**
 	Permet a l'utilisateur de configurer QET en lancant un dialogue approprie.
 	@see ConfigDialog
 */

Modified: branches/0.3/sources/qetapp.h
===================================================================
--- branches/0.3/sources/qetapp.h	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/qetapp.h	2010-12-24 21:00:11 UTC (rev 1133)
@@ -165,6 +165,7 @@
 	void openProjectFiles(const QStringList &);
 	void openElementFiles(const QStringList &);
 	void openElementLocations(const QList<ElementsLocation> &);
+	void openTitleBlockTemplate(QETProject *, const QString & = QString());
 	void configureQET();
 	void aboutQET();
 	

Modified: branches/0.3/sources/qeticons.cpp
===================================================================
--- branches/0.3/sources/qeticons.cpp	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/qeticons.cpp	2010-12-24 21:00:11 UTC (rev 1133)
@@ -128,6 +128,7 @@
 		QIcon South;
 		QIcon Start;
 		QIcon Terminal;
+		QIcon TitleBlock;
 		QIcon UserInformations;
 		QIcon ViewFitWidth;
 		QIcon ViewFitWindow;
@@ -304,6 +305,7 @@
 	South               .addFile(":/ico/16x16/south.png");
 	Start               .addFile(":/ico/22x22/start.png");
 	Terminal            .addFile(":/ico/22x22/terminal.png");
+	TitleBlock          .addFile(":/ico/titleblock.png");
 	UserInformations    .addFile(":/ico/16x16/preferences-desktop-user.png");
 	UserInformations    .addFile(":/ico/22x22/preferences-desktop-user.png");
 	ViewFitWidth        .addFile(":/ico/22x22/view_fit_width.png");

Modified: branches/0.3/sources/qeticons.h
===================================================================
--- branches/0.3/sources/qeticons.h	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/qeticons.h	2010-12-24 21:00:11 UTC (rev 1133)
@@ -138,6 +138,7 @@
 		extern QIcon South;
 		extern QIcon Start;
 		extern QIcon Terminal;
+		extern QIcon TitleBlock;
 		extern QIcon UserInformations;
 		extern QIcon ViewFitWidth;
 		extern QIcon ViewFitWindow;

Modified: branches/0.3/sources/qetproject.cpp
===================================================================
--- branches/0.3/sources/qetproject.cpp	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/qetproject.cpp	2010-12-24 21:00:11 UTC (rev 1133)
@@ -313,6 +313,70 @@
 }
 
 /**
+	This methods allows adding or modifying a template embedded within the
+	project. This method emits the signal projectTemplatesChanged() if
+	necessary.
+	@param template_name Name / Identifier of the template - will be used to
+	determine whether the given description will be added or will replace an
+	existing one.
+	@param xml_elmt An \<titleblocktemplate\> XML element describing the
+	template. Its "name" attribute must equal to template_name.
+	@return false if a problem occured, true otherwise
+*/
+bool QETProject::setTemplateXmlDescription(const QString &template_name, const QDomElement &xml_elmt) {
+	// checks basic stuff
+	if (xml_elmt.tagName() != "titleblocktemplate" || xml_elmt.attribute("name") != template_name) {
+		return(false);
+	}
+	
+	// we import the provided XML element in the project document
+	QDomElement import = document_root_.importNode(xml_elmt, true).toElement();
+	
+	// we either replace the previous description
+	if (titleblock_templates_xml_.contains(template_name)) {
+		QDomElement old_description = titleblock_templates_xml_[template_name];
+		if (!old_description.parentNode().isNull()) {
+			old_description.parentNode().replaceChild(import, old_description);
+			titleblock_templates_xml_[template_name] = import;
+		}
+	} else {
+		// or simply insert the new one
+		titleblock_templates_xml_.insert(template_name, import);
+	}
+	
+	if (titleblock_templates_.contains(template_name)) {
+		titleblock_templates_[template_name] -> loadFromXmlElement(titleblock_templates_xml_[template_name]);
+		foreach (Diagram *diagram, diagrams_) {
+			diagram -> titleBlockTemplateChanged(template_name);
+		}
+	}
+	emit(projectTemplatesChanged(this));
+	
+	return(true);
+}
+
+/**
+	This methods allows removing a template embedded within the project. This
+	method emits the signal projectTemplatesChanged() if necessary.
+	@param template_name Name of the template to be removed
+*/
+void QETProject::removeTemplateByName(const QString &template_name) {
+	if (titleblock_templates_.contains(template_name)) {
+		// warn diagrams that the given template is about to be removed
+		foreach (Diagram *diagram, diagrams_) {
+			diagram -> titleBlockTemplateRemoved(template_name); /// TODO specify the default template of the project as a fallback
+		}
+	}
+	
+	// remove the template itself
+	titleblock_templates_xml_.remove(template_name);
+	titleblock_templates_.remove(template_name);
+	
+	// warn the rest of the world that the list of templates embedded within this project has changed
+	emit(projectTemplatesChanged(this));
+}
+
+/**
 	@return les dimensions par defaut utilisees lors de la creation d'un
 	nouveau schema dans ce projet.
 */

Modified: branches/0.3/sources/qetproject.h
===================================================================
--- branches/0.3/sources/qetproject.h	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/qetproject.h	2010-12-24 21:00:11 UTC (rev 1133)
@@ -83,6 +83,8 @@
 	QList<QString> embeddedTitleBlockTemplates() const;
 	const TitleBlockTemplate *getTemplateByName(const QString &template_name);
 	QDomElement getTemplateXmlDescriptionByName(const QString &);
+	bool setTemplateXmlDescription(const QString &, const QDomElement &);
+	void removeTemplateByName(const QString &);
 	BorderProperties defaultBorderProperties() const;
 	void setDefaultBorderProperties(const BorderProperties &);
 	TitleBlockProperties defaultTitleBlockProperties() const;
@@ -119,6 +121,7 @@
 	void diagramAdded(QETProject *, Diagram *);
 	void diagramRemoved(QETProject *, Diagram *);
 	void readOnlyChanged(QETProject *, bool);
+	void projectTemplatesChanged(QETProject *);
 	
 	private slots:
 	void updateDiagramsFolioData();

Added: branches/0.3/sources/templateeditor.cpp
===================================================================
--- branches/0.3/sources/templateeditor.cpp	                        (rev 0)
+++ branches/0.3/sources/templateeditor.cpp	2010-12-24 21:00:11 UTC (rev 1133)
@@ -0,0 +1,170 @@
+#include "templateeditor.h"
+#include <QtXml>
+#include "qetproject.h"
+#include "qetapp.h"
+
+/**
+	Constructor
+	@param parent parent QWidget for this editor
+	@param f Windows flags for this editor
+	@see QWidget()
+*/
+TemplateEditor::TemplateEditor(QWidget *parent, Qt::WindowFlags f) :
+	QWidget(parent, f),
+	parent_project_(0)
+{
+	build();
+}
+
+/**
+	Destructor
+*/
+TemplateEditor::~TemplateEditor() {
+}
+
+/**
+	Edit the given template.
+	@param project Parent project of the template to edit.
+	@param template_name Name of the template to edit within its parent project.
+*/
+bool TemplateEditor::edit(QETProject *project, const QString &template_name) {
+	// we require a project we will rattach templates to
+	if (!project) return(false);
+	parent_project_ = project;
+	updateProjectLabel();
+	
+	// the template name may be empty to create a new element
+	if (template_name.isEmpty()) {
+		template_name_edit_ -> setText(tr("Nouveau-modele"));
+		template_name_edit_ -> setReadOnly(false);
+		return(true);
+	}
+	
+	QDomElement xml_tb_template = project -> getTemplateXmlDescriptionByName(template_name);
+	if (!xml_tb_template.isNull()) {
+		QDomDocument xml_doc;
+		xml_doc.appendChild(xml_doc.importNode(xml_tb_template, true));
+		template_name_edit_ -> setText(template_name);
+		template_name_edit_ -> setReadOnly(true);
+		template_xml_edit_ -> setPlainText(xml_doc.toString(4));
+		
+		// stores the parent project and template name, in order to write/save the template later
+		template_name_ = template_name;
+		return(true);
+	}
+	return(false);
+}
+
+/**
+	Validates the content of the current text area. It has to be a valid XML
+	description of a title block template for this method not to display a
+	message to the user.
+	@todo implement it.
+*/
+void TemplateEditor::validate() {
+	QMessageBox::information(
+		this,
+		tr("Not implemented yet"),
+		tr("Sorry, Not implemented yet")
+	);
+}
+
+/**
+	Saves the content of the current text area to a template within the project.
+*/
+void TemplateEditor::save() {
+	if (!parent_project_) return;
+	
+	// are we creating a new template?
+	if (!template_name_edit_ -> isReadOnly()) {
+		// Yes, so we must ensure the new name will not clatch with an existing ine
+		if (parent_project_ -> embeddedTitleBlockTemplates().contains(template_name_edit_ -> text())) {
+			QMessageBox::critical(
+				this,
+				tr("Un mod\350le de ce nom existe d\351j\340"),
+				tr("Un mod\350le de ce nom existe d\351j\340 au sein du projet - veuillez choisir un autre nom.")
+			);
+			/// TODO propose to overwrite the existing template?
+			return;
+		}
+		
+	}
+	
+	QDomDocument xml_doc;
+	bool parsing = xml_doc.setContent(template_xml_edit_ -> toPlainText());
+	if (!parsing) {
+		QMessageBox::critical(
+			this,
+			tr("Code XML non valide"),
+			tr("Le code XML du mod\350le ne semble pas \320tre valide. Impossible d'enregistrer le mod\350le.")
+		);
+		return;
+	}
+	
+	if (!template_name_edit_ -> isReadOnly()) {
+		template_name_edit_ -> setReadOnly(true);
+		template_name_ = template_name_edit_ -> text();
+	}
+	parent_project_ -> setTemplateXmlDescription(template_name_, xml_doc.documentElement());
+}
+
+/**
+	Exits this editor.
+*/
+void TemplateEditor::quit() {
+	/// TODO save if needed
+	close();
+}
+
+/**
+	Builds the user interface.
+*/
+void TemplateEditor::build() {
+	parent_project_label_ = new QLabel();
+	updateProjectLabel();
+	template_name_edit_ = new QLineEdit();
+	template_xml_edit_ = new QTextEdit();
+	template_xml_edit_ -> setAcceptRichText(false);
+	template_xml_edit_ -> setFontFamily("monospace");
+	template_xml_edit_ -> setWordWrapMode(QTextOption::NoWrap);
+	
+	validate_button_ = new QPushButton(tr("V\351rifier le mod\350le"));
+	save_button_ = new QPushButton(tr("Enregistrer et appliquer"));
+	quit_button_ = new QPushButton(tr("Quitter"));
+	
+	connect(validate_button_, SIGNAL(released()), this, SLOT(validate()));
+	connect(save_button_,     SIGNAL(released()), this, SLOT(save()));
+	connect(quit_button_,     SIGNAL(released()), this, SLOT(quit()));
+	
+	QHBoxLayout *h_layout0 = new QHBoxLayout();
+	h_layout0 -> addWidget(validate_button_);
+	h_layout0 -> addWidget(save_button_);
+	h_layout0 -> addWidget(quit_button_);
+	
+	QVBoxLayout *v_layout0 = new QVBoxLayout();
+	v_layout0 -> addWidget(parent_project_label_);
+	v_layout0 -> addWidget(template_name_edit_);
+	v_layout0 -> addWidget(template_xml_edit_);
+	v_layout0 -> addLayout(h_layout0);
+	
+	setLayout(v_layout0);
+	
+	setWindowTitle(tr("QElectroTech - \311diteur de mod\350le de cartouche"));
+	resize(700, 500);
+}
+
+/**
+	Updates the "Parent project:" label.
+*/
+void TemplateEditor::updateProjectLabel() {
+	QString parent_project_title;
+	if (parent_project_) {
+		parent_project_title = parent_project_ -> pathNameTitle();
+	} else {
+		parent_project_title = tr("Non d\351fini");
+	}
+	
+	parent_project_label_ -> setText(
+		QString(tr("Projet parent : %1")).arg(parent_project_title)
+	);
+}

Added: branches/0.3/sources/templateeditor.h
===================================================================
--- branches/0.3/sources/templateeditor.h	                        (rev 0)
+++ branches/0.3/sources/templateeditor.h	2010-12-24 21:00:11 UTC (rev 1133)
@@ -0,0 +1,60 @@
+/*
+	Copyright 2006-2010 Xavier Guerrin
+	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 TEMPLATE_EDITOR_H
+#define TEMPLATE_EDITOR_H
+#include <QtGui>
+class QETProject;
+/**
+	This class allows the user to edit a title block template.
+	For the moment, it simply provides a text editor.
+*/
+class TemplateEditor : public QWidget {
+	Q_OBJECT
+	
+	// constructors, destructor
+	public:
+	TemplateEditor(QWidget * = 0, Qt::WindowFlags = 0);
+	virtual ~TemplateEditor();
+	private:
+	TemplateEditor(const TemplateEditor &);
+	
+	// method\s
+	public:
+	bool edit(QETProject *, const QString &);
+	
+	private slots:
+	void validate();
+	void save();
+	void quit();
+	
+	private:
+	void build();
+	void updateProjectLabel();
+	
+	// attributes
+	private:
+	QLabel *parent_project_label_;
+	QLineEdit *template_name_edit_;
+	QTextEdit *template_xml_edit_;
+	QPushButton *validate_button_;
+	QPushButton *save_button_;
+	QPushButton *quit_button_;
+	QETProject *parent_project_;
+	QString template_name_;
+};
+#endif

Modified: branches/0.3/sources/titleblocktemplate.cpp
===================================================================
--- branches/0.3/sources/titleblocktemplate.cpp	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/titleblocktemplate.cpp	2010-12-24 21:00:11 UTC (rev 1133)
@@ -486,7 +486,7 @@
 	// run through each inidividual cell
 	for (int j = 0 ; j < rows_heights_.count() ; ++ j) {
 		for (int i = 0 ; i < columns_width_.count() ; ++ i) {
-			if (cells_[i][j].spanner_cell) continue;
+			if (cells_[i][j].spanner_cell || cells_[i][j].is_null) continue;
 			
 			// calculate the border rect of the current cell
 			int x = lengthRange(0, cells_[i][j].num_col, widths); 

Modified: branches/0.3/sources/titleblocktemplaterenderer.h
===================================================================
--- branches/0.3/sources/titleblocktemplaterenderer.h	2010-12-20 02:45:36 UTC (rev 1132)
+++ branches/0.3/sources/titleblocktemplaterenderer.h	2010-12-24 21:00:11 UTC (rev 1133)
@@ -31,10 +31,10 @@
 	void setContext(const DiagramContext &context);
 	int height() const;
 	void render(QPainter *, int);
+	void invalidateRenderedTemplate();
 	
 	private:
 	void renderToQPicture(int);
-	void invalidateRenderedTemplate();
 	
 	private:
 	const TitleBlockTemplate *titleblock_template_;


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