[qet] [1697] Elements panels now display and highlight elements newly-integrated into projects .

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


Revision: 1697
Author:   xavier
Date:     2012-04-28 18:45:16 +0200 (Sat, 28 Apr 2012)
Log Message:
-----------
Elements panels now display and highlight elements newly-integrated into projects.

Modified Paths:
--------------
    branches/0.3/sources/elementslocation.cpp
    branches/0.3/sources/elementslocation.h
    branches/0.3/sources/elementspanel.cpp
    branches/0.3/sources/elementspanel.h
    branches/0.3/sources/genericpanel.cpp
    branches/0.3/sources/genericpanel.h
    branches/0.3/sources/qetproject.cpp
    branches/0.3/sources/qetproject.h

Added Paths:
-----------
    branches/0.3/sources/treecoloranimation.cpp
    branches/0.3/sources/treecoloranimation.h

Modified: branches/0.3/sources/elementslocation.cpp
===================================================================
--- branches/0.3/sources/elementslocation.cpp	2012-04-28 16:45:13 UTC (rev 1696)
+++ branches/0.3/sources/elementslocation.cpp	2012-04-28 16:45:16 UTC (rev 1697)
@@ -136,6 +136,22 @@
 }
 
 /**
+	@return the location of the parent category, or a copy of this location
+	when it represents a root category.
+*/
+ElementsLocation ElementsLocation::parent() const {
+	ElementsLocation copy(*this);
+	QRegExp re1("^([a-z]+://)(.*)/*$");
+	if (re1.exactMatch(path_)) {
+		QString path_proto = re1.capturedTexts().at(1);
+		QString path_path = re1.capturedTexts().at(2);
+		QString parent_path = path_path.remove(QRegExp("/*[^/]+$"));
+		copy.setPath(path_proto + parent_path);
+	}
+	return(copy);
+}
+
+/**
 	@return le projet de cet emplacement ou 0 si celui-ci n'est pas lie a
 	un projet.
 */

Modified: branches/0.3/sources/elementslocation.h
===================================================================
--- branches/0.3/sources/elementslocation.h	2012-04-28 16:45:13 UTC (rev 1696)
+++ branches/0.3/sources/elementslocation.h	2012-04-28 16:45:16 UTC (rev 1697)
@@ -42,6 +42,7 @@
 	QString path() const;
 	void setPath(const QString &);
 	bool addToPath(const QString &);
+	ElementsLocation parent() const;
 	QETProject *project() const;
 	void setProject(QETProject *);
 	bool isNull() const;

Modified: branches/0.3/sources/elementspanel.cpp
===================================================================
--- branches/0.3/sources/elementspanel.cpp	2012-04-28 16:45:13 UTC (rev 1696)
+++ branches/0.3/sources/elementspanel.cpp	2012-04-28 16:45:16 UTC (rev 1697)
@@ -26,6 +26,7 @@
 #include "fileelementdefinition.h"
 #include "qeticons.h"
 #include "templatescollection.h"
+#include "treecoloranimation.h"
 
 /**
 	This class implements a thread reloading the following elements
@@ -382,6 +383,32 @@
 }
 
 /**
+	Inform this panel the project \a project has integrated the element at \a location
+*/
+QList<ElementsLocation> ElementsPanel::elementIntegrated(QETProject *project, const ElementsLocation &location) {
+	// the base implementation simply refreshes the adequate category and returns the list of added locations
+	QList<ElementsLocation> added_locations = GenericPanel::elementIntegrated(project, location);
+	if (!added_locations.count()) return(added_locations);
+	
+	// the additional job of this method consists in displaying the integrated elements...
+	if (QTreeWidgetItem *integrated_element_qtwi = itemForElementsLocation(location)) {
+		ensureHierarchyIsVisible(QList<QTreeWidgetItem *>() << integrated_element_qtwi);
+		scrollToItem(integrated_element_qtwi, QAbstractItemView::PositionAtCenter);
+	}
+	
+	// and make them "flash" (not too obviously though) so the user notices they have been integrated.
+	QList<QTreeWidgetItem *> items;
+	foreach (ElementsLocation loc, added_locations) {
+		if (QTreeWidgetItem *added_item = itemForElementsLocation(loc)) {
+			items << added_item;
+		}
+	}
+	highlightItems(items, this, SLOT(scrollToSelectedItem()));
+	
+	return(added_locations);
+}
+
+/**
 	Methode permettant d'ajouter un projet au panel d'elements.
 	@param qtwi_parent QTreeWidgetItem parent sous lequel sera insere le projet
 	@param project Projet a inserer dans le panel d'elements
@@ -774,3 +801,40 @@
 		if (parent_qtwi -> isHidden()) parent_qtwi -> setHidden(false);
 	}
 }
+
+/**
+	Scroll to the currently selected item.
+*/
+void ElementsPanel::scrollToSelectedItem() {
+	QList<QTreeWidgetItem *> selected_items = selectedItems();
+	if (selected_items.count()) {
+		scrollToItem(selected_items.first(), QAbstractItemView::PositionAtCenter);
+	}
+}
+
+/**
+	Scroll to and highlight \a items. Once the animation is finished, the slot
+	\a method is called on the object \a receiver.
+*/
+void ElementsPanel::highlightItems(const QList<QTreeWidgetItem *> &items, const QObject *receiver, const char *method) {
+	TreeColorAnimation *animation1 = new TreeColorAnimation(items);
+	animation1 -> setStartValue(QColor(Qt::white));
+	animation1 -> setEndValue(QColor(Qt::yellow));
+	animation1 -> setDuration(400);
+	animation1 -> setEasingCurve(QEasingCurve::InQuad);
+	
+	TreeColorAnimation *animation2 = new TreeColorAnimation(items);
+	animation2 -> setStartValue(QColor(Qt::yellow));
+	animation2 -> setEndValue(QColor(Qt::white));
+	animation2 -> setDuration(500);
+	animation2 -> setEasingCurve(QEasingCurve::OutInQuint);
+	
+	QSequentialAnimationGroup *animation = new QSequentialAnimationGroup(this);
+	animation -> addAnimation(animation1);
+	animation -> addAnimation(new QPauseAnimation(700));
+	animation -> addAnimation(animation2);
+	if (receiver) {
+		connect(animation, SIGNAL(finished()), receiver, method);
+	}
+	animation -> start(QAbstractAnimation::DeleteWhenStopped);
+}

Modified: branches/0.3/sources/elementspanel.h
===================================================================
--- branches/0.3/sources/elementspanel.h	2012-04-28 16:45:13 UTC (rev 1696)
+++ branches/0.3/sources/elementspanel.h	2012-04-28 16:45:16 UTC (rev 1697)
@@ -80,6 +80,8 @@
 	bool scrollToElement(const ElementsLocation &);
 	void applyCurrentFilter(const QList<QTreeWidgetItem *> &);
 	void ensureHierarchyIsVisible(const QList<QTreeWidgetItem *> &);
+	void scrollToSelectedItem();
+	void highlightItems(const QList<QTreeWidgetItem *> &, const QObject * = 0, const char * = 0);
 	
 	protected:
 	void dragEnterEvent(QDragEnterEvent *);
@@ -93,6 +95,7 @@
 	protected slots:
 	void firstActivation();
 	void panelContentChange();
+	virtual QList<ElementsLocation> elementIntegrated(QETProject *, const ElementsLocation &);
 	
 	private:
 	QTreeWidgetItem *addProject   (QETProject *);

Modified: branches/0.3/sources/genericpanel.cpp
===================================================================
--- branches/0.3/sources/genericpanel.cpp	2012-04-28 16:45:13 UTC (rev 1696)
+++ branches/0.3/sources/genericpanel.cpp	2012-04-28 16:45:16 UTC (rev 1697)
@@ -10,6 +10,7 @@
 #include "elementslocation.h"
 #include "qeticons.h"
 #include "elementscollectioncache.h"
+#include "qetapp.h"
 
 /**
 	Constructor
@@ -248,6 +249,10 @@
 				project, SIGNAL(projectDiagramsOrderChanged(QETProject *, int, int)),
 				this,    SLOT  (projectDiagramsOrderChanged(QETProject *, int, int))
 			);
+			connect(
+				project, SIGNAL(elementIntegrated(QETProject *, const ElementsLocation &)),
+				this,    SLOT(elementIntegrated(QETProject *, const ElementsLocation &))
+			);
 		} else {
 			// remove diagrams unknown to the project (presumably removed)
 			removeObsoleteItems(project -> diagrams(), project_qtwi, QET::Diagram, false);
@@ -729,6 +734,8 @@
 	
 	int index = 0;
 	
+	category_qtwi -> setData(0, GenericPanel::PanelFlags, (int)options);
+	
 	if (options & AddChildElementsCategories) {
 		if (!freshly_created) {
 			QList<ElementsLocation> sub_categories;
@@ -762,6 +769,23 @@
 }
 
 /**
+	Refresh elements category at \a location.
+	@return the refreshed tree item
+*/
+QTreeWidgetItem *GenericPanel::refreshElementsCategory(const ElementsLocation &location) {
+	QTreeWidgetItem *item = itemForElementsLocation(location);
+	if (!item) return(0);
+	if (item -> type() != QET::ElementsCategory && item -> type() != QET::ElementsCollection) return(0);
+	QTreeWidgetItem *result = fillElementsCategoryItem(
+		item,
+		QETApp::collectionItem(location) -> toCategory(),
+		PanelOptions(QFlag(item -> data(0, GenericPanel::PanelFlags).toInt())),
+		false
+	);
+	return(result);
+}
+
+/**
 	
 */
 QTreeWidgetItem *GenericPanel::addElement(ElementDefinition *element, QTreeWidgetItem *parent_item, PanelOptions options) {
@@ -941,6 +965,27 @@
 }
 
 /**
+	Inform this panel the project \a project has integrated the element at \a location
+*/
+QList<ElementsLocation> GenericPanel::elementIntegrated(QETProject *project, const ElementsLocation &location) {
+	Q_UNUSED(project)
+	QList<ElementsLocation> added_locations;
+	
+	int i = 0;
+	ElementsLocation loc = location;
+	// starting from the provided location, goes up into the tree until a displayed location is reached
+	while (i < 100 && !(itemForElementsLocation(loc))) {
+		added_locations << loc;
+		loc = loc.parent();
+		++ i;
+	}
+	if (added_locations.count()) {
+		refreshElementsCategory(loc);
+	}
+	return(added_locations);
+}
+
+/**
 	Inform this panel the diagram \a diagram has changed its title to \a title.
 */
 void GenericPanel::diagramTitleChanged(Diagram *diagram, const QString &title) {

Modified: branches/0.3/sources/genericpanel.h
===================================================================
--- branches/0.3/sources/genericpanel.h	2012-04-28 16:45:13 UTC (rev 1696)
+++ branches/0.3/sources/genericpanel.h	2012-04-28 16:45:16 UTC (rev 1697)
@@ -59,7 +59,8 @@
 	enum MetaData {
 		Item = Qt::UserRole + 1,
 		AliasItem,
-		Parent
+		Parent,
+		PanelFlags
 	};
 	
 	// Constructors, destructor
@@ -143,6 +144,7 @@
 	virtual QTreeWidgetItem *getItemForElementsCategory(ElementsCategory *, bool * = 0);
 	virtual QTreeWidgetItem *updateElementsCategoryItem(QTreeWidgetItem *, ElementsCategory *, PanelOptions = AddAllChild, bool = false);
 	virtual QTreeWidgetItem *fillElementsCategoryItem  (QTreeWidgetItem *, ElementsCategory *, PanelOptions = AddAllChild, bool = false);
+	virtual QTreeWidgetItem *refreshElementsCategory(const ElementsLocation &);
 	
 	// elements methods
 	public:
@@ -164,6 +166,7 @@
 	virtual void diagramAdded(QETProject *, Diagram *);
 	virtual void diagramRemoved(QETProject *, Diagram *);
 	virtual void projectDiagramsOrderChanged(QETProject *, int, int);
+	virtual QList<ElementsLocation> elementIntegrated(QETProject *, const ElementsLocation &);
 	virtual void diagramTitleChanged(Diagram *, const QString &);
 	virtual void templatesCollectionChanged(TitleBlockTemplatesCollection*, const QString &);
 	virtual void diagramUsedTemplate(TitleBlockTemplatesCollection *, const QString &);

Modified: branches/0.3/sources/qetproject.cpp
===================================================================
--- branches/0.3/sources/qetproject.cpp	2012-04-28 16:45:13 UTC (rev 1696)
+++ branches/0.3/sources/qetproject.cpp	2012-04-28 16:45:16 UTC (rev 1697)
@@ -629,6 +629,7 @@
 	}
 	
 	// recopie l'element
+	ElementsLocation result;
 	if (ElementDefinition *existing_elmt = target_cat -> element(integ_item -> pathName())) {
 		
 		// l'element existe deja - on demande au handler ce que l'on doit faire
@@ -636,31 +637,31 @@
 		
 		if (action == QET::Ignore) {
 			// il faut conserver et utiliser l'element deja integre
-			return(existing_elmt -> location().toString());
+			result = existing_elmt -> location();
 		} else if (action == QET::Erase) {
 			// il faut ecraser l'element deja integre
 			BasicMoveElementsHandler *erase_handler = new BasicMoveElementsHandler();
-			ElementsLocation result_loc = copyElementWithHandler(integ_elmt, target_cat, erase_handler, error_message);
+			ElementsLocation result = copyElementWithHandler(integ_elmt, target_cat, erase_handler, error_message);
 			delete erase_handler;
-			return(result_loc.toString());
 		} else if (action == QET::Rename) {
 			// il faut faire cohabiter les deux elements en renommant le nouveau 
 			QString integ_element_name = handler -> nameForRenamingOperation();
 			BasicMoveElementsHandler *rename_handler = new BasicMoveElementsHandler();
 			rename_handler -> setActionIfItemAlreadyExists(QET::Rename);
 			rename_handler -> setNameForRenamingOperation(integ_element_name);
-			ElementsLocation result_loc = copyElementWithHandler(integ_elmt, target_cat, rename_handler, error_message);
+			result = copyElementWithHandler(integ_elmt, target_cat, rename_handler, error_message);
 			delete rename_handler;
-			return(result_loc.toString());
 		} else {
 			// il faut annuler la pose de l'element
-			return(QString());
+			result = ElementsLocation();
 		}
 	} else {
 		// integre l'element normalement
-		ElementsLocation result_loc = copyElementWithHandler(integ_elmt, target_cat, handler, error_message);
-		return(result_loc.toString());
+		result = copyElementWithHandler(integ_elmt, target_cat, handler, error_message);
 	}
+	
+	if (!result.isNull()) emit(elementIntegrated(this, result));
+	return(result.toString());
 }
 
 /**

Modified: branches/0.3/sources/qetproject.h
===================================================================
--- branches/0.3/sources/qetproject.h	2012-04-28 16:45:13 UTC (rev 1696)
+++ branches/0.3/sources/qetproject.h	2012-04-28 16:45:16 UTC (rev 1697)
@@ -129,6 +129,7 @@
 	void diagramAdded(QETProject *, Diagram *);
 	void diagramRemoved(QETProject *, Diagram *);
 	void projectDiagramsOrderChanged(QETProject *, int, int);
+	void elementIntegrated(QETProject *, const ElementsLocation &);
 	void diagramUsedTemplate(TitleBlockTemplatesCollection *, const QString &);
 	void readOnlyChanged(QETProject *, bool);
 	

Added: branches/0.3/sources/treecoloranimation.cpp
===================================================================
--- branches/0.3/sources/treecoloranimation.cpp	                        (rev 0)
+++ branches/0.3/sources/treecoloranimation.cpp	2012-04-28 16:45:16 UTC (rev 1697)
@@ -0,0 +1,35 @@
+#include "treecoloranimation.h"
+
+/**
+	Constructor
+	@param items List of items whose background color will be animated.
+	@param parent Parent QObject
+*/
+TreeColorAnimation::TreeColorAnimation(const QList<QTreeWidgetItem *> &items, QObject *parent) : 
+	QVariantAnimation(parent),
+	items_(items)
+{
+}
+
+/**
+	Destructor
+*/
+TreeColorAnimation::~TreeColorAnimation() {
+}
+
+/**
+	@return the list of items whose background color will be animated.
+*/
+QList<QTreeWidgetItem *> TreeColorAnimation::items() const {
+	return(items_);
+}
+
+/**
+	Apply the provided color to animated items.
+	@param color Color to be applied on animated items.
+*/
+void TreeColorAnimation::updateCurrentValue(const QVariant &color) {
+	foreach (QTreeWidgetItem *item, items_) {
+		item -> setBackgroundColor(0, color.value<QColor>());
+	}
+}

Added: branches/0.3/sources/treecoloranimation.h
===================================================================
--- branches/0.3/sources/treecoloranimation.h	                        (rev 0)
+++ branches/0.3/sources/treecoloranimation.h	2012-04-28 16:45:16 UTC (rev 1697)
@@ -0,0 +1,43 @@
+/*
+	Copyright 2006-2012 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 TREE_COLOR_ANIMATION_H
+#define TREE_COLOR_ANIMATION_H
+#include <QtGui>
+
+/**
+	This class allows animating a background color change for a
+	set of QTreeWidgetItem.
+*/
+class TreeColorAnimation : public QVariantAnimation {
+	// Constructors, destructor
+	public:
+	TreeColorAnimation(const QList<QTreeWidgetItem *> &items, QObject * = 0);
+	virtual ~TreeColorAnimation();
+	
+	// methods
+	public:
+	QList<QTreeWidgetItem *> items() const;
+	
+	protected:
+	void updateCurrentValue(const QVariant &);
+	
+	// attributes
+	private:
+	QList<QTreeWidgetItem *> items_; ///< Items this object will animate
+};
+#endif


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