/* Copyright 2006-2026 The QElectroTech Team 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 . */ #include "shownkinds.h" #include #include namespace { bool hidden[ShownKinds::KindCount] = {}; } /** @return true unless @a kind was hidden with setShown(). */ bool ShownKinds::isShown(Kind kind) { return kind < 0 || kind >= KindCount || !hidden[kind]; } /** Show or hide @a kind for the items created from now on. Items already on a scene change when apply() is called on it. */ void ShownKinds::setShown(Kind kind, bool shown) { if (kind >= 0 && kind < KindCount) { hidden[kind] = !shown; } } /** @return how many kinds are hidden, for the status bar. */ int ShownKinds::hiddenCount() { int count = 0; for (bool h : hidden) { count += h ? 1 : 0; } return count; } /** Mark @a item as being of @a kind, and hide it now if that kind is hidden. Called by the item's constructor, while the item still wants to be visible. */ void ShownKinds::tag(QGraphicsItem *item, Kind kind) { if (!item) { return; } item->setData(data_key, int(kind)); if (!isShown(kind)) { item->setVisible(false); item->setData(hidden_key, true); } } /** Show or hide @a item as its own code wants, unless its kind is hidden: then it stays hidden, and comes back when the kind is shown again. Use this instead of QGraphicsItem::setVisible() in a tagged item. */ void ShownKinds::setVisible(QGraphicsItem *item, bool visible) { if (!item) { return; } const QVariant kind = item->data(data_key); const bool vetoed = visible && kind.isValid() && !isShown(Kind(kind.toInt())); item->setVisible(visible && !vetoed); item->setData(hidden_key, vetoed ? QVariant(true) : QVariant()); } /** @return true if @a item, or an item it hangs from, is of a hidden kind. For code that walks the items itself (DXF export) and must leave out what View > Show hides. */ bool ShownKinds::isHidden(const QGraphicsItem *item) { for (; item; item = item->parentItem()) { const QVariant value = item->data(data_key); if (value.isValid() && !isShown(Kind(value.toInt()))) { return true; } } return false; } /** Bring the items of @a kind on @a scene in line with the current state: hide the ones that are visible, or show again the ones hidden for it. */ void ShownKinds::apply(QGraphicsScene *scene, Kind kind) { if (!scene) { return; } const bool shown = isShown(kind); //items() with no argument also returns the hidden items const QList items = scene->items(); for (QGraphicsItem *item : items) { const QVariant value = item->data(data_key); if (!value.isValid() || value.toInt() != kind) { continue; } if (!shown) { //Its own flag, not isVisible(): a symbol text under a //hidden group still wants to be visible if (item->isVisibleTo(item->parentItem())) { item->setVisible(false); item->setData(hidden_key, true); } } else if (item->data(hidden_key).toBool()) { item->setVisible(true); item->setData(hidden_key, QVariant()); } } }