diff --git a/sources/editor/editorcommands.cpp b/sources/editor/editorcommands.cpp index ab573df5b..1304908c1 100644 --- a/sources/editor/editorcommands.cpp +++ b/sources/editor/editorcommands.cpp @@ -291,7 +291,7 @@ void AddPartCommand::redo() { if (!part -> zValue()) { // the added part has no specific zValue already defined, we put it // above existing items (but still under terminals) - QList existing_items = editor_scene_ -> zItems(); + QList existing_items = editor_scene_ -> zItems(ElementScene::SortByZValue | ElementScene::SelectedOrNot); qreal z = existing_items.count() ? existing_items.last() -> zValue() + 1 : 1; part -> setZValue(z); } @@ -522,8 +522,8 @@ ChangeZValueCommand::ChangeZValueCommand( ElementEditionCommand(elmt, 0, parent), option(o) { - // recupere les parties de l'elements, sauf les bornes - QList items_list = editor_scene_ -> zItems(); + // retrieve all primitives but terminals + QList items_list = editor_scene_ -> zItems(ElementScene::SortByZValue | ElementScene::SelectedOrNot); // prend un snapshot des zValues foreach(QGraphicsItem *qgi, items_list) undo_hash.insert(qgi, qgi -> zValue()); diff --git a/sources/editor/elementscene.cpp b/sources/editor/elementscene.cpp index a596d5215..a1898563b 100644 --- a/sources/editor/elementscene.cpp +++ b/sources/editor/elementscene.cpp @@ -487,7 +487,7 @@ const QDomDocument ElementScene::toXml(bool all_parts) const { QDomElement description = xml_document.createElement("description"); // description de l'element - foreach(QGraphicsItem *qgi, zItems(true)) { + foreach(QGraphicsItem *qgi, zItems()) { // si l'export ne concerne que la selection, on ignore les parties non selectionnees if (!all_parts && !qgi -> isSelected()) continue; if (CustomElementPart *ce = dynamic_cast(qgi)) { @@ -961,30 +961,56 @@ QList ElementScene::primitives() const { @param include_terminals true pour inclure les bornes, false sinon @return les parties de l'element ordonnes par zValue croissante */ -QList ElementScene::zItems(bool include_terminals) const { - // recupere les elements - QList all_items_list(items()); +QList ElementScene::zItems(ItemOptions options) const { + // handle dummy request, i.e. when neither Selected nor NonSelected are set + if (!(options & ElementScene::Selected) && !(options & ElementScene::NonSelected)) { + return(QList()); + } + + // retrieve all items + QList all_items_list(items()); + QMutableListIterator i(all_items_list); + + // remove unrequired items + if ((options & ElementScene::SelectedOrNot) != ElementScene::SelectedOrNot) { + bool keep_selected = options & ElementScene::Selected; + while (i.hasNext()) { + if (i.next() -> isSelected() != keep_selected) { + i.remove(); + } + } + } - // enleve les bornes QList terminals; - foreach(QGraphicsItem *qgi, all_items_list) { + QList helpers; + for (i.toFront(); i.hasNext(); ) { + i.next(); + QGraphicsItem *qgi = i.value(); if ( qgi -> type() == ElementPrimitiveDecorator::Type || qgi -> type() == QGraphicsRectItem::Type ) { - all_items_list.removeAt(all_items_list.indexOf(qgi)); + i.remove(); + helpers << qgi; } else if (qgraphicsitem_cast(qgi)) { - all_items_list.removeAt(all_items_list.indexOf(qgi)); + i.remove(); terminals << qgi; } } // ordonne les parties par leur zValue - qSort(all_items_list.begin(), all_items_list.end(), ElementScene::zValueLessThan); + if (options & SortByZValue) { + qSort(all_items_list.begin(), all_items_list.end(), ElementScene::zValueLessThan); + } // rajoute eventuellement les bornes - if (include_terminals) all_items_list += terminals; + if (options & ElementScene::IncludeTerminals) { + all_items_list += terminals; + } + if (options & ElementScene::IncludeHelperItems) { + all_items_list += helpers; + } return(all_items_list); } @@ -993,7 +1019,7 @@ QList ElementScene::zItems(bool include_terminals) const { */ ElementContent ElementScene::selectedContent() const { ElementContent content; - foreach(QGraphicsItem *qgi, zItems(true)) { + foreach(QGraphicsItem *qgi, zItems()) { if (qgi -> isSelected()) content << qgi; } return(content); @@ -1260,6 +1286,7 @@ bool ElementScene::zValueLessThan(QGraphicsItem *item1, QGraphicsItem *item2) { represents the current selection. */ void ElementScene::managePrimitivesGroups() { + // this function is not supposed to be reentrant if (!decorator_lock_ -> tryLock()) return; if (!decorator_) { @@ -1269,18 +1296,8 @@ void ElementScene::managePrimitivesGroups() { decorator_ -> hide(); } - QList selected_items; - foreach (QGraphicsItem *item, items()) { - if (item -> type() == ElementPrimitiveDecorator::Type) continue; - if (item -> type() == QGraphicsRectItem::Type) continue; - if (item -> isSelected()) { - selected_items << item; - } - } - /// TODO export the above code to a proper method - - // should we hide the decorator? + QList selected_items = zItems(ElementScene::Selected | ElementScene::IncludeTerminals); if (!selected_items.count()) { decorator_ -> hide(); } else { diff --git a/sources/editor/elementscene.h b/sources/editor/elementscene.h index d12ca0c90..5670e13bb 100644 --- a/sources/editor/elementscene.h +++ b/sources/editor/elementscene.h @@ -42,7 +42,17 @@ class ElementScene : public QGraphicsScene { Q_OBJECT // enum + public: enum Behavior { Normal, Line, Rectangle, Circle, Ellipse, Polygon, Text, Terminal, Arc, TextField, PasteArea }; + enum ItemOption { + SortByZValue = 1, + IncludeTerminals = 2, + IncludeHelperItems = 4, + Selected = 8, + NonSelected = 16, + SelectedOrNot = 24 + }; + Q_DECLARE_FLAGS(ItemOptions, ItemOption); // constructors, destructor public: @@ -130,7 +140,7 @@ class ElementScene : public QGraphicsScene { virtual void fromXml(const QDomDocument &, const QPointF & = QPointF(), bool = true, ElementContent * = 0); virtual void reset(); virtual QList primitives() const; - virtual QList zItems(bool = false) const; + virtual QList zItems(ItemOptions options = ItemOptions(SortByZValue | IncludeTerminals | SelectedOrNot)) const; virtual ElementContent selectedContent() const; virtual void getPasteArea(const QRectF &); QRectF borderRect() const; @@ -209,6 +219,8 @@ class ElementScene : public QGraphicsScene { void pasteAreaDefined(const QRectF &); }; +Q_DECLARE_OPERATORS_FOR_FLAGS(ElementScene::ItemOptions) + /** @param wid the new width for the currently edited element */ diff --git a/sources/editor/qetelementeditor.cpp b/sources/editor/qetelementeditor.cpp index 266ad7543..297f62c92 100644 --- a/sources/editor/qetelementeditor.cpp +++ b/sources/editor/qetelementeditor.cpp @@ -1145,7 +1145,7 @@ void QETElementEditor::firstActivation(QEvent *event) { void QETElementEditor::slot_createPartsList() { parts_list -> blockSignals(true); parts_list -> clear(); - QList qgis = ce_scene -> zItems(true); + QList qgis = ce_scene -> zItems(); // on ne construit plus la liste a partir de 200 primitives // c'est ingerable : la maj de la liste prend trop de temps et le resultat @@ -1179,7 +1179,7 @@ void QETElementEditor::slot_updatePartsList() { } else if (items_count <= QET_MAX_PARTS_IN_ELEMENT_EDITOR_LIST) { parts_list -> blockSignals(true); int i = 0; - QList items = ce_scene -> zItems(true); + QList items = ce_scene -> zItems(); for (int j = items.count() - 1 ; j >= 0 ; -- j) { QGraphicsItem *qgi = items[j]; QListWidgetItem *qlwi = parts_list -> item(i);