[qet] [1217] Changed the way the application loads elements collections.

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


Revision: 1217
Author:   xavier
Date:     2011-03-15 21:06:40 +0100 (Tue, 15 Mar 2011)
Log Message:
-----------
Changed the way the application loads elements collections.

Modified Paths:
--------------
    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/qetdiagrameditor.cpp
    branches/0.3/sources/qetdiagrameditor.h

Modified: branches/0.3/sources/elementspanel.cpp
===================================================================
--- branches/0.3/sources/elementspanel.cpp	2011-03-15 18:32:52 UTC (rev 1216)
+++ branches/0.3/sources/elementspanel.cpp	2011-03-15 20:06:40 UTC (rev 1217)
@@ -25,6 +25,37 @@
 #include "fileelementdefinition.h"
 #include "qeticons.h"
 
+/**
+	This class implements a thread reloading the following elements
+	collections:
+	  * the common collection
+	  * the custom collection
+	  * the embedded collection of each project listed in the projects_
+	attribute.
+*/
+class ReloadCollectionThread : public QThread {
+	public:
+	void run();
+	/// list of projects whose embedded collection should be reloaded.
+	QList<QETProject *> projects_;
+};
+
+/**
+	Reloads collections.
+*/
+void ReloadCollectionThread::run() {
+	QETApp::commonElementsCollection() -> reload();
+	QETApp::customElementsCollection() -> reload();
+	
+	// reloads collection of every project displayed in this panel
+	foreach(QETProject *project, projects_) {
+		if (ElementsCollection *project_collection = project -> embeddedCollection()) {
+			project_collection -> reload();
+		}
+	}
+	exit();
+}
+
 /*
 	Lorsque le flag ENABLE_PANEL_DND_CHECKS est defini, le panel d'elements
 	effectue des verifications lors des drag'n drop d'elements et categories.
@@ -54,7 +85,8 @@
 ElementsPanel::ElementsPanel(QWidget *parent) :
 	QTreeWidget(parent),
 	common_collection_item_(0),
-	custom_collection_item_(0)
+	custom_collection_item_(0),
+	first_activation_(true)
 {
 	
 	// selection unique
@@ -72,13 +104,6 @@
 	// taille des elements
 	setIconSize(QSize(50, 50));
 	
-	// charge les collections
-	reload();
-	
-	// la premiere fois, etend le premier niveau des collections
-	if (common_collection_item_) common_collection_item_ -> setExpanded(true);
-	if (custom_collection_item_) custom_collection_item_ -> setExpanded(true);
-	
 	// force du noir sur une alternance de blanc (comme le schema) et de gris
 	// clair, avec du blanc sur bleu pas trop fonce pour la selection
 	QPalette qp = palette();
@@ -515,6 +540,17 @@
 }
 
 /**
+	@param event Object describing the received event 
+*/
+bool ElementsPanel::event(QEvent *event) {
+	if (first_activation_ && event -> type() == QEvent::WindowActivate) {
+		reload(false);
+		first_activation_ = false;
+	}
+	return(QTreeWidget::event(event));
+}
+
+/**
 	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
@@ -638,6 +674,7 @@
 	t.setColorAt(1, QColor("#ffffff"));
 	qtwi_category -> setBackground(0, QBrush(t));
 	locations_.insert(qtwi_category, category -> location());
+	emit(loadingProgressed(++ loading_progress_, -1));
 	
 	// reduit le dossier si besoin
 	qtwi_category -> setExpanded(expanded_directories.contains(category -> location().toString()));
@@ -646,7 +683,10 @@
 	foreach(ElementsCategory *sub_cat, category -> categories()) addCategory(qtwi_category, sub_cat);
 	
 	// ajout des elements
-	foreach(ElementDefinition *elmt, category -> elements()) addElement(qtwi_category, elmt);
+	foreach(ElementDefinition *elmt, category -> elements()) {
+		addElement(qtwi_category, elmt);
+		emit(loadingProgressed(++ loading_progress_, -1));
+	}
 	
 	return(qtwi_category);
 }
@@ -696,18 +736,50 @@
 }
 
 /**
+	Reloads the following collections:
+	  * common collection
+	  * custom collection
+	  * collection of every project displayed in this panel
+*/
+void ElementsPanel::reloadCollections() {
+	ReloadCollectionThread thread;
+	thread.projects_ = projects_to_display_.values();
+	thread.start();
+	while(!thread.wait(100)) {
+		QApplication::processEvents();
+	}
+}
+
+/**
+	@return the count of categories and elements within the following collections:
+	  * common collection
+	  * custom collection
+	  * collection of every project displayed in this panel
+*/
+int ElementsPanel::elementsCollectionItemsCount() {
+	int items_count = 0;
+	items_count += QETApp::commonElementsCollection() -> count();
+	items_count += QETApp::customElementsCollection() -> count();
+	foreach(QETProject *project, projects_to_display_.values()) {
+		if (ElementsCollection *project_collection = project -> embeddedCollection()) {
+			items_count += project_collection -> count();
+		}
+	}
+	return(items_count);
+}
+
+/**
 	Recharge l'arbre des elements
 	@param reload_collections true pour relire les collections depuis leurs sources (fichiers, projets...)
 */
 void ElementsPanel::reload(bool reload_collections) {
-	
 	// sauvegarde la liste des repertoires reduits
 	saveExpandedCategories();
 	
 	if (reload_collections) {
-		foreach(ElementsCollection *collection, QETApp::availableCollections()) {
-			collection -> reload();
-		}
+		emit(readingAboutToBegin());
+		reloadCollections();
+		emit(readingFinished());
 	}
 	
 	// vide l'arbre et le hash
@@ -719,12 +791,22 @@
 	common_collection_item_ = 0;
 	custom_collection_item_ = 0;
 	
+	// estimates the number of categories and elements to load
+	int items_count = elementsCollectionItemsCount();
+	emit(loadingProgressed(loading_progress_ = 0, items_count));
+	
 	// chargement des elements de la collection QET
 	common_collection_item_ = addCollection(invisibleRootItem(), QETApp::commonElementsCollection(), tr("Collection QET"),         QIcon(":/ico/16x16/qet.png"));
 	
 	// chargement des elements de la collection utilisateur
 	custom_collection_item_ = addCollection(invisibleRootItem(), QETApp::customElementsCollection(), tr("Collection utilisateur"), QIcon(":/ico/16x16/go-home.png"));
 	
+	// the first time, expand the first level of collections
+	if (first_activation_) {
+		common_collection_item_ -> setExpanded(true);
+		custom_collection_item_ -> setExpanded(true);
+	}
+	
 	// chargement des projets
 	foreach(QETProject *project, projects_to_display_.values()) {
 		addProject(invisibleRootItem(), project);
@@ -1118,3 +1200,4 @@
 		if (parent_qtwi -> isHidden()) parent_qtwi -> setHidden(false);
 	}
 }
+

Modified: branches/0.3/sources/elementspanel.h
===================================================================
--- branches/0.3/sources/elementspanel.h	2011-03-15 18:32:52 UTC (rev 1216)
+++ branches/0.3/sources/elementspanel.h	2011-03-15 20:06:40 UTC (rev 1217)
@@ -82,15 +82,21 @@
 	Diagram *selectedDiagram() const;
 	ElementsLocation selectedLocation() const;
 	
+	void reloadCollections();
+	int elementsCollectionItemsCount();
+	
 	signals:
 	void requestForProject(QETProject *);
 	void requestForDiagram(Diagram *);
 	void requestForCollectionItem(ElementsCollectionItem *);
 	void requestForMoveElements(ElementsCollectionItem *, ElementsCollectionItem *, QPoint);
+	void readingAboutToBegin();
+	void readingFinished();
+	void loadingProgressed(int, int);
 	
 	public slots:
 	void slot_doubleClick(QTreeWidgetItem *, int);
-	void reload(bool = true);
+	void reload(bool = false);
 	void filter(const QString &);
 	void projectWasOpened(QETProject *);
 	void projectWasClosed(QETProject *);
@@ -107,6 +113,7 @@
 	void dragMoveEvent(QDragMoveEvent *);
 	void dropEvent(QDropEvent *);
 	void startDrag(Qt::DropActions);
+	bool event(QEvent *);
 	
 	private:
 	QTreeWidgetItem *addProject   (QTreeWidgetItem *, QETProject         *);
@@ -134,5 +141,7 @@
 	QHash<QTreeWidgetItem *, QETProject *> title_blocks_directories_;
 	QTreeWidgetItem *common_collection_item_;
 	QTreeWidgetItem *custom_collection_item_;
+	int loading_progress_;
+	bool first_activation_;
 };
 #endif

Modified: branches/0.3/sources/elementspanelwidget.cpp
===================================================================
--- branches/0.3/sources/elementspanelwidget.cpp	2011-03-15 18:32:52 UTC (rev 1216)
+++ branches/0.3/sources/elementspanelwidget.cpp	2011-03-15 20:06:40 UTC (rev 1217)
@@ -44,6 +44,10 @@
 	@param parent Le QWidget parent de ce widget
 */
 ElementsPanelWidget::ElementsPanelWidget(QWidget *parent) : QWidget(parent) {
+	// initialize the progress bar (hidden by default)
+	progress_bar_ = new QProgressBar(this);
+	progress_bar_ -> setVisible(false);
+	progress_bar_ -> setTextVisible(true);
 	// initalise le panel d'elements
 	elements_panel = new ElementsPanel(this);
 	
@@ -124,6 +128,9 @@
 		SLOT(handleMoveElementsRequest(ElementsCollectionItem *, ElementsCollectionItem *, const QPoint &)),
 		Qt::QueuedConnection
 	);
+	connect(elements_panel, SIGNAL(loadingProgressed(int, int)),  this, SLOT(updateProgressBar(int, int)));
+	connect(elements_panel, SIGNAL(readingAboutToBegin()),        this, SLOT(collectionsRead()));
+	connect(elements_panel, SIGNAL(readingFinished()),            this, SLOT(collectionsReadFinished()));
 	
 	// initialise la barre d'outils
 	toolbar = new QToolBar(this);
@@ -146,6 +153,7 @@
 	vlayout -> addWidget(toolbar);
 	vlayout -> addWidget(filter_toolbar);
 	vlayout -> addWidget(elements_panel);
+	vlayout -> addWidget(progress_bar_);
 	vlayout -> setStretchFactor(elements_panel, 75000);
 	setLayout(vlayout);
 }
@@ -171,7 +179,7 @@
 */
 void ElementsPanelWidget::reloadAndFilter() {
 	// recharge tous les elements
-	elements_panel -> reload();
+	elements_panel -> reload(true);
 	
 	// reapplique le filtre
 	elements_panel -> filter(filter_textfield -> text());
@@ -531,6 +539,44 @@
 }
 
 /**
+	Reflects the fact that collections are being read (i.e from filesystem) in
+	the progress bar.
+*/
+void ElementsPanelWidget::collectionsRead() {
+	progress_bar_ -> setMinimum(0);
+	progress_bar_ -> setMaximum(1);
+	progress_bar_ -> setValue(0);
+	progress_bar_ -> setFormat(tr("Lecture...", "Reading of elements/categories files"));
+	progress_bar_ -> setVisible(true);
+}
+
+/**
+	Reflects the fact that collections being read (i.e from filesystem) in the
+	progress bar.
+*/
+void ElementsPanelWidget::collectionsReadFinished() {
+	progress_bar_ -> setFormat(tr("Chargement : %p%", "Visual rendering of elements/categories files - %p is the progress percentage"));
+}
+
+/**
+	Updates the progress bar
+	@param current value that should be displayed
+	@param maximum maximum expected value; -1 means "use the previously known one"
+*/
+void ElementsPanelWidget::updateProgressBar(int current, int maximum) {
+	int provided_maximum = maximum == -1 ? progress_bar_ -> maximum() : maximum;
+	if (provided_maximum != progress_bar_ -> maximum()) {
+		progress_bar_ -> setMaximum(maximum);
+	}
+	if (!current) {
+		progress_bar_ -> setVisible(true);
+	} else if (current == provided_maximum) {
+		QTimer::singleShot(500, progress_bar_, SLOT(hide()));
+	}
+	progress_bar_ -> setValue(current);
+}
+
+/**
 	Copie l'item src dans l'item dst
 */
 void ElementsPanelWidget::copyElements(ElementsCollectionItem *src, ElementsCollectionItem *dst) {

Modified: branches/0.3/sources/elementspanelwidget.h
===================================================================
--- branches/0.3/sources/elementspanelwidget.h	2011-03-15 18:32:52 UTC (rev 1216)
+++ branches/0.3/sources/elementspanelwidget.h	2011-03-15 20:06:40 UTC (rev 1217)
@@ -49,6 +49,7 @@
 	QAction *erase_textfield;
 	QLineEdit *filter_textfield;
 	ElementsCollectionItem *dnd_item_src_, *dnd_item_dst_;
+	QProgressBar *progress_bar_;
 	
 	// methodes
 	public:
@@ -92,6 +93,9 @@
 	void moveElements(ElementsCollectionItem *, ElementsCollectionItem *);
 	void copyElements();
 	void copyElements(ElementsCollectionItem *, ElementsCollectionItem *);
+	void collectionsRead();
+	void collectionsReadFinished();
+	void updateProgressBar(int, int);
 	
 	private:
 	void launchElementEditor(const ElementsLocation &);

Modified: branches/0.3/sources/qetapp.cpp
===================================================================
--- branches/0.3/sources/qetapp.cpp	2011-03-15 18:32:52 UTC (rev 1216)
+++ branches/0.3/sources/qetapp.cpp	2011-03-15 20:06:40 UTC (rev 1217)
@@ -92,6 +92,12 @@
 	setQuitOnLastWindowClosed(false);
 	connect(this, SIGNAL(lastWindowClosed()), this, SLOT(checkRemainingWindows()));
 	
+	// loads known collections into memory (this does not include items rendering made in elements panels)
+	setSplashScreenStep(tr("Chargement... Lecture des collections d'\351l\351ments", "splash screen caption"));
+	foreach(ElementsCollection *collection, availableCollections()) {
+		collection -> reload();
+	}
+	
 	// on ouvre soit les fichiers passes en parametre soit un nouvel editeur de projet
 	if (qet_arguments_.files().isEmpty()) {
 		setSplashScreenStep(tr("Chargement... \311diteur de sch\351mas", "splash screen caption"));

Modified: branches/0.3/sources/qetdiagrameditor.cpp
===================================================================
--- branches/0.3/sources/qetdiagrameditor.cpp	2011-03-15 18:32:52 UTC (rev 1216)
+++ branches/0.3/sources/qetdiagrameditor.cpp	2011-03-15 20:06:40 UTC (rev 1217)
@@ -740,9 +740,11 @@
 	Ouvre un projet depuis un fichier et l'ajoute a cet editeur
 	@param filepath Chemin du projet a ouvrir
 	@param interactive true pour afficher des messages a l'utilisateur, false sinon
+	@param update_panel Whether the elements panel should be warned this
+	project has been added. Defaults to true.
 	@return true si l'ouverture a reussi, false sinon
 */
-bool QETDiagramEditor::openAndAddProject(const QString &filepath, bool interactive) {
+bool QETDiagramEditor::openAndAddProject(const QString &filepath, bool interactive, bool update_panel) {
 	if (filepath.isEmpty()) return(false);
 	
 	QFileInfo filepath_info(filepath);
@@ -812,14 +814,18 @@
 	// on l'ajoute a la liste des fichiers recents
 	QETApp::projectsRecentFiles() -> fileWasOpened(filepath);
 	// ... et on l'ajoute dans l'application
-	return(addProject(project));
+	// Note: we require the panel not to be updated when the project is added
+	// because it will update itself as soon as it becomes visible
+	return(addProject(project), update_panel);
 }
 
 /**
 	Ajoute un projet
 	@param project projet a ajouter
+	@param update_panel Whether the elements panel should be warned this
+	project has been added. Defaults to true.
 */
-bool QETDiagramEditor::addProject(QETProject *project) {
+bool QETDiagramEditor::addProject(QETProject *project, bool update_panel) {
 	// enregistre le projet
 	QETApp::registerProject(project);
 	
@@ -828,7 +834,9 @@
 	addProjectView(project_view);
 	
 	// met a jour le panel d'elements
-	pa -> elementsPanel().projectWasOpened(project);
+	if (update_panel) {
+		pa -> elementsPanel().projectWasOpened(project);
+	}
 	
 	return(true);
 }

Modified: branches/0.3/sources/qetdiagrameditor.h
===================================================================
--- branches/0.3/sources/qetdiagrameditor.h	2011-03-15 18:32:52 UTC (rev 1216)
+++ branches/0.3/sources/qetdiagrameditor.h	2011-03-15 20:06:40 UTC (rev 1217)
@@ -52,7 +52,7 @@
 	void closeEvent(QCloseEvent *);
 	QList<ProjectView *> openedProjects() const;
 	void addProjectView(ProjectView *);
-	bool openAndAddProject(const QString &, bool interactive = true);
+	bool openAndAddProject(const QString &, bool = true, bool = true);
 	QList<DiagramView *> projectViews() const;
 	QList<QString> editedFiles() const;
 	ProjectView *viewForFile(const QString &) const;
@@ -67,7 +67,7 @@
 	virtual bool event(QEvent *);
 	
 	private:
-	bool addProject(QETProject *);
+	bool addProject(QETProject *, bool = true);
 	ProjectView *currentProject() const;
 	DiagramView *currentDiagram() const;
 	ProjectView *findProject(DiagramView *) const;


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