Changed the way the application loads elements collections.

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/branches/0.3@1217 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
xavier
2011-03-15 20:06:40 +00:00
parent 2b537f1f28
commit cf6ebf8f0f
7 changed files with 177 additions and 21 deletions

View File

@@ -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 @@ ElementsPanel::ElementsPanel(QWidget *parent) :
// 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();
@@ -514,6 +539,17 @@ void ElementsPanel::startDrag(Qt::DropActions supportedActions) {
drag -> start(Qt::MoveAction | Qt::CopyAction);
}
/**
@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
@@ -638,6 +674,7 @@ QTreeWidgetItem *ElementsPanel::addCategory(QTreeWidgetItem *qtwi_parent, Elemen
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 @@ QTreeWidgetItem *ElementsPanel::addCategory(QTreeWidgetItem *qtwi_parent, Elemen
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);
}
@@ -695,19 +735,51 @@ QTreeWidgetItem *ElementsPanel::addElement(QTreeWidgetItem *qtwi_parent, Element
return(qtwi);
}
/**
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 @@ void ElementsPanel::reload(bool reload_collections) {
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 @@ void ElementsPanel::ensureHierarchyIsVisible(QList<QTreeWidgetItem *> items) {
if (parent_qtwi -> isHidden()) parent_qtwi -> setHidden(false);
}
}

View File

@@ -82,15 +82,21 @@ class ElementsPanel : public QTreeWidget {
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 @@ class ElementsPanel : public QTreeWidget {
void dragMoveEvent(QDragMoveEvent *);
void dropEvent(QDropEvent *);
void startDrag(Qt::DropActions);
bool event(QEvent *);
private:
QTreeWidgetItem *addProject (QTreeWidgetItem *, QETProject *);
@@ -134,5 +141,7 @@ class ElementsPanel : public QTreeWidget {
QHash<QTreeWidgetItem *, QETProject *> title_blocks_directories_;
QTreeWidgetItem *common_collection_item_;
QTreeWidgetItem *custom_collection_item_;
int loading_progress_;
bool first_activation_;
};
#endif

View File

@@ -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 @@ ElementsPanelWidget::ElementsPanelWidget(QWidget *parent) : QWidget(parent) {
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 @@ ElementsPanelWidget::ElementsPanelWidget(QWidget *parent) : QWidget(parent) {
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::clearFilterTextField() {
*/
void ElementsPanelWidget::reloadAndFilter() {
// recharge tous les elements
elements_panel -> reload();
elements_panel -> reload(true);
// reapplique le filtre
elements_panel -> filter(filter_textfield -> text());
@@ -530,6 +538,44 @@ void ElementsPanelWidget::copyElements() {
copyElements(dnd_item_src_, dnd_item_dst_);
}
/**
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
*/

View File

@@ -49,6 +49,7 @@ class ElementsPanelWidget : public QWidget {
QAction *erase_textfield;
QLineEdit *filter_textfield;
ElementsCollectionItem *dnd_item_src_, *dnd_item_dst_;
QProgressBar *progress_bar_;
// methodes
public:
@@ -92,6 +93,9 @@ class ElementsPanelWidget : public QWidget {
void moveElements(ElementsCollectionItem *, ElementsCollectionItem *);
void copyElements();
void copyElements(ElementsCollectionItem *, ElementsCollectionItem *);
void collectionsRead();
void collectionsReadFinished();
void updateProgressBar(int, int);
private:
void launchElementEditor(const ElementsLocation &);

View File

@@ -92,6 +92,12 @@ QETApp::QETApp(int &argc, char **argv) :
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"));

View File

@@ -740,9 +740,11 @@ bool QETDiagramEditor::closeCurrentProject() {
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 @@ bool QETDiagramEditor::openAndAddProject(const QString &filepath, bool interacti
// 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 @@ bool QETDiagramEditor::addProject(QETProject *project) {
addProjectView(project_view);
// met a jour le panel d'elements
pa -> elementsPanel().projectWasOpened(project);
if (update_panel) {
pa -> elementsPanel().projectWasOpened(project);
}
return(true);
}

View File

@@ -52,7 +52,7 @@ class QETDiagramEditor : public QMainWindow {
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 @@ class QETDiagramEditor : public QMainWindow {
virtual bool event(QEvent *);
private:
bool addProject(QETProject *);
bool addProject(QETProject *, bool = true);
ProjectView *currentProject() const;
DiagramView *currentDiagram() const;
ProjectView *findProject(DiagramView *) const;