mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-05 18:54:14 +02:00
Merge pull request #1268 from ispyisail/feat/301-show-by-kind
Add View > Show to hide texts, shapes and pictures (bugtracker #301)
This commit is contained in:
@@ -242,6 +242,8 @@ set(QET_SRC_FILES
|
||||
${QET_DIR}/sources/genericpanel.h
|
||||
${QET_DIR}/sources/itemgroups.cpp
|
||||
${QET_DIR}/sources/itemgroups.h
|
||||
${QET_DIR}/sources/shownkinds.cpp
|
||||
${QET_DIR}/sources/shownkinds.h
|
||||
${QET_DIR}/sources/lastusedstyle.cpp
|
||||
${QET_DIR}/sources/lastusedstyle.h
|
||||
${QET_DIR}/sources/machine_info.cpp
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "dxfexport.h"
|
||||
#include "shownkinds.h"
|
||||
|
||||
#include "conductorsegment.h"
|
||||
#include "createdxf.h"
|
||||
@@ -135,6 +136,10 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
}
|
||||
}
|
||||
for (QGraphicsItem *qgi : std::as_const(stacked_items)) {
|
||||
//Left out like on screen and in print (View > Show, #301)
|
||||
if (ShownKinds::isHidden(qgi)) {
|
||||
continue;
|
||||
}
|
||||
if (Element *elmt = qgraphicsitem_cast<Element *>(qgi)) {
|
||||
list_elements << elmt;
|
||||
} else if (Conductor *f = qgraphicsitem_cast<Conductor *>(qgi)) {
|
||||
@@ -147,7 +152,8 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
list_shapes << dii;
|
||||
} else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(qgi)) {
|
||||
list_texts << deti;
|
||||
if (QGraphicsTextItem *xref = deti->slaveXrefItem()) {
|
||||
QGraphicsTextItem *xref = deti->slaveXrefItem();
|
||||
if (xref && !ShownKinds::isHidden(xref)) {
|
||||
list_xref_texts << xref;
|
||||
}
|
||||
} else if (QetGraphicsTableItem *gti = qgraphicsitem_cast<QetGraphicsTableItem *>(qgi)) {
|
||||
@@ -290,7 +296,7 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
Createdxf::layer = Layer::WireNumbers;
|
||||
ConductorTextItem *textItem = cond -> textItem();
|
||||
|
||||
if (textItem) {
|
||||
if (textItem && !ShownKinds::isHidden(textItem)) {
|
||||
qreal fontSize = textItem -> font().pointSizeF();
|
||||
if (fontSize < 0)
|
||||
fontSize = textItem -> font().pixelSize();
|
||||
|
||||
@@ -264,6 +264,8 @@ class QETApp : public QObject
|
||||
signals:
|
||||
/// The text grid setting changed, see TextGrid.
|
||||
void textGridChanged();
|
||||
/// A kind of item was shown or hidden, see ShownKinds.
|
||||
void shownKindsChanged();
|
||||
|
||||
public slots:
|
||||
void systray(QSystemTrayIcon::ActivationReason);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qetdiagrameditor.h"
|
||||
#include "shownkinds.h"
|
||||
#ifdef QET_HAS_SCRIPTING
|
||||
#include "scripting/qetscripting.h"
|
||||
#include "scripting/scriptlibrary.h"
|
||||
@@ -607,6 +608,36 @@ void QETDiagramEditor::setUpActions()
|
||||
dv->setCellLinesShown(checked);
|
||||
});
|
||||
|
||||
//Show or hide whole kinds of items on every folio (bugtracker #301)
|
||||
m_shown_kinds_menu = new QMenu(tr("Afficher"), this);
|
||||
const QList<QPair<ShownKinds::Kind, QString>> kinds {
|
||||
{ShownKinds::SymbolTexts, tr("Textes des éléments")},
|
||||
{ShownKinds::WireNumbers, tr("Textes des conducteurs")},
|
||||
{ShownKinds::FreeTexts, tr("Champs de texte")},
|
||||
{ShownKinds::Shapes, tr("Formes")},
|
||||
{ShownKinds::Pictures, tr("Images")},
|
||||
{ShownKinds::Tables, tr("Tableaux")},
|
||||
{ShownKinds::CrossReferences, tr("Références croisées")}};
|
||||
for (const auto &kind : kinds)
|
||||
{
|
||||
QAction *action = m_shown_kinds_menu->addAction(kind.second);
|
||||
action->setCheckable(true);
|
||||
action->setData(int(kind.first));
|
||||
connect(action, &QAction::triggered, this, [kind](bool checked) {
|
||||
ShownKinds::setShown(kind.first, checked);
|
||||
for (QETProject *project : QETApp::registeredProjects())
|
||||
for (Diagram *diagram : project->diagrams())
|
||||
ShownKinds::apply(diagram, kind.first);
|
||||
emit QETApp::instance()->shownKindsChanged();
|
||||
});
|
||||
}
|
||||
m_hidden_kinds_label = new QLabel(this);
|
||||
m_hidden_kinds_label->setToolTip(tr("Voir Affichage > Afficher"));
|
||||
statusBar()->addPermanentWidget(m_hidden_kinds_label);
|
||||
connect(QETApp::instance(), &QETApp::shownKindsChanged,
|
||||
this, &QETDiagramEditor::updateShownKinds);
|
||||
updateShownKinds();
|
||||
|
||||
//Edit current diagram properties
|
||||
m_edit_diagram_properties = new QAction(QET::Icons::DialogInformation, tr("Propriétés du folio"), this);
|
||||
ShortcutManager::instance().registerAction(m_edit_diagram_properties, "diagrameditor.edit_diagram_properties", tr("Éditeur de schémas"), Qt::CTRL | Qt::Key_L);
|
||||
@@ -1458,6 +1489,7 @@ void QETDiagramEditor::setUpMenu()
|
||||
menu_affichage -> addAction(m_draw_guides);
|
||||
menu_affichage -> addAction(m_cell_rulers);
|
||||
menu_affichage -> addAction(m_cell_lines);
|
||||
menu_affichage -> addMenu(m_shown_kinds_menu);
|
||||
menu_affichage -> addMenu(m_background_color_button->menu());
|
||||
menu_affichage -> addSeparator();
|
||||
menu_affichage -> addActions(m_zoom_actions_group.actions());
|
||||
@@ -4140,6 +4172,21 @@ void QETDiagramEditor::updateScriptActions()
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@brief QETDiagramEditor::updateShownKinds
|
||||
Tick the kinds shown in View > Show, and say in the status bar how many
|
||||
are hidden, so that a hidden kind is never forgotten.
|
||||
*/
|
||||
void QETDiagramEditor::updateShownKinds()
|
||||
{
|
||||
for (QAction *action : m_shown_kinds_menu->actions())
|
||||
action->setChecked(ShownKinds::isShown(ShownKinds::Kind(action->data().toInt())));
|
||||
|
||||
const int hidden = ShownKinds::hiddenCount();
|
||||
m_hidden_kinds_label->setText(tr("%n type(s) d'objets masqué(s)", "", hidden));
|
||||
m_hidden_kinds_label->setVisible(hidden > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETDiagramEditor::updateTextGridButton
|
||||
Show the current text grid on its toolbar button and check it in its menu.
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <QUndoGroup>
|
||||
|
||||
class QToolButton;
|
||||
class QLabel;
|
||||
|
||||
class QMdiSubWindow;
|
||||
class QETProject;
|
||||
@@ -187,6 +188,7 @@ class QETDiagramEditor : public QETMainWindow
|
||||
|
||||
private slots:
|
||||
void updateTextGridButton();
|
||||
void updateShownKinds();
|
||||
void selectionChanged();
|
||||
|
||||
public:
|
||||
@@ -284,6 +286,8 @@ class QETDiagramEditor : public QETMainWindow
|
||||
DiagramBgColorToolButton *m_background_color_button = nullptr;
|
||||
QMenu *m_text_grid_menu = nullptr; ///< Snap step used when dragging texts
|
||||
QToolButton *m_text_grid_button = nullptr;
|
||||
QMenu *m_shown_kinds_menu = nullptr; ///< View > Show, kinds of items (#301)
|
||||
QLabel *m_hidden_kinds_label = nullptr; ///< Status bar: how many kinds are hidden
|
||||
|
||||
QList <QAction *> m_zoom_action_toolBar; ///Only zoom action must displayed in the toolbar
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qetgraphicstableitem.h"
|
||||
#include "../../shownkinds.h"
|
||||
#include "../../qetproject.h"
|
||||
#include "../../QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
#include "../../createdxf.h"
|
||||
@@ -133,6 +134,7 @@ void QetGraphicsTableItem::checkInsufficientRowsCount(
|
||||
QetGraphicsTableItem::QetGraphicsTableItem(QGraphicsItem *parent) :
|
||||
QetGraphicsItem(parent)
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::Tables);
|
||||
setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "../qetgraphicsitem/conductor.h"
|
||||
#include "../shownkinds.h"
|
||||
#include "../lastusedstyle.h"
|
||||
#include "../qetproject.h"
|
||||
#include "../QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
@@ -1521,6 +1522,20 @@ QPointF Conductor::posForText(Qt::Orientations &flag)
|
||||
return p1;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Conductor::updateTextVisibility
|
||||
Show the text of this conductor if its properties ask for it and wire
|
||||
numbers are not hidden (View > Show). With "one text per potential",
|
||||
call calculateTextItemPosition() afterwards: it hides all texts of the
|
||||
potential but the longest conductor's.
|
||||
*/
|
||||
void Conductor::updateTextVisibility()
|
||||
{
|
||||
ShownKinds::setVisible(m_text_item,
|
||||
m_properties.type == ConductorProperties::Multi
|
||||
&& m_properties.m_show_text);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Conductor::calculateTextItemPosition
|
||||
Move the text at middle of conductor (if is vertical or horizontal)
|
||||
@@ -1548,10 +1563,11 @@ void Conductor::calculateTextItemPosition()
|
||||
|
||||
//At this point this conductor is the longest conductor we hide all text of conductor_list
|
||||
foreach (Conductor *c, relatedPotentialConductors(false)) {
|
||||
c -> textItem() -> setVisible(false);
|
||||
ShownKinds::setVisible(c -> textItem(), false);
|
||||
}
|
||||
//Make sure text item is visible
|
||||
m_text_item -> setVisible(true);
|
||||
//Make sure text item is visible, unless wire numbers are hidden
|
||||
//(View > Show)
|
||||
ShownKinds::setVisible(m_text_item, true);
|
||||
}
|
||||
|
||||
//position
|
||||
@@ -1806,11 +1822,7 @@ void Conductor::setProperties(const ConductorProperties &property)
|
||||
m_text_item->setFont(font);
|
||||
m_text_item->setColor(m_properties.text_color);
|
||||
|
||||
if (m_properties.type != ConductorProperties::Multi)
|
||||
m_text_item->setVisible(false);
|
||||
else
|
||||
m_text_item->setVisible(m_properties.m_show_text);
|
||||
|
||||
updateTextVisibility();
|
||||
calculateTextItemPosition();
|
||||
update();
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ class Conductor : public QGraphicsObject
|
||||
void setProfiles(const ConductorProfilesGroup &);
|
||||
ConductorProfilesGroup profiles() const;
|
||||
void calculateTextItemPosition();
|
||||
void updateTextVisibility();
|
||||
virtual Highlight highlight() const;
|
||||
virtual void setHighlighted(Highlight);
|
||||
QSet<Conductor *> relatedPotentialConductors(
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "conductortextitem.h"
|
||||
#include "../shownkinds.h"
|
||||
|
||||
#include "../diagram.h"
|
||||
#include "../diagramcommands.h"
|
||||
@@ -31,6 +32,7 @@ ConductorTextItem::ConductorTextItem(Conductor *parent_conductor) :
|
||||
moved_by_user_(false),
|
||||
rotate_by_user_(false)
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::WireNumbers);
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
|
||||
@@ -45,7 +47,9 @@ ConductorTextItem::ConductorTextItem(
|
||||
parent_conductor_(parent_conductor),
|
||||
moved_by_user_(false),
|
||||
rotate_by_user_(false)
|
||||
{}
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::WireNumbers);
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "crossrefitem.h"
|
||||
#include "../shownkinds.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include "../qetproject.h"
|
||||
@@ -81,6 +82,7 @@ CrossRefItem::~CrossRefItem()
|
||||
*/
|
||||
void CrossRefItem::init()
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::CrossReferences);
|
||||
if(!m_element->diagram())
|
||||
{
|
||||
qDebug() << "CrossRefItem constructor" << "element is not in a diagram";
|
||||
@@ -238,11 +240,13 @@ void CrossRefItem::updateProperties()
|
||||
if (m_properties != xrp)
|
||||
{
|
||||
m_properties = xrp;
|
||||
hide();
|
||||
//Through ShownKinds: stays hidden while View > Show hides
|
||||
//cross-references
|
||||
ShownKinds::setVisible(this, false);
|
||||
if(m_properties.snapTo() == XRefProperties::Label && (m_text || m_group)) //Snap to label and parent is text or group
|
||||
show();
|
||||
ShownKinds::setVisible(this, true);
|
||||
else if((m_properties.snapTo() == XRefProperties::Bottom && !m_text && !m_group)) //Snap to bottom of element is the parent
|
||||
show();
|
||||
ShownKinds::setVisible(this, true);
|
||||
|
||||
setUpConnection();
|
||||
updateLabel();
|
||||
@@ -528,7 +532,9 @@ void CrossRefItem::linkedChanged()
|
||||
|
||||
m_slave_connection.clear();
|
||||
|
||||
if(!isVisible())
|
||||
//Hidden only by View > Show: keep following the slaves, so the
|
||||
//label is right when it is shown again
|
||||
if(!isVisible() && !ShownKinds::isHidden(this))
|
||||
return;
|
||||
|
||||
for(Element *elmt : m_element->linkedElements())
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "diagramimageitem.h"
|
||||
#include "../shownkinds.h"
|
||||
|
||||
#include "../PropertiesEditor/propertieseditordialog.h"
|
||||
#include "../QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
@@ -50,6 +51,7 @@
|
||||
DiagramImageItem::DiagramImageItem(QetGraphicsItem *parent_item):
|
||||
QetGraphicsItem(parent_item)
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::Pictures);
|
||||
setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemSendsGeometryChanges);
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
@@ -66,6 +68,7 @@ DiagramImageItem::DiagramImageItem(const QPixmap &pixmap, QetGraphicsItem *paren
|
||||
m_base_pixmap(pixmap),
|
||||
m_crop_rect(pixmap.rect())
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::Pictures);
|
||||
// m_transform.toMatrix(), not QGraphicsItem::setRotation()/setScale():
|
||||
// those are a single uniform scale() float, which is exactly why an
|
||||
// image could never break its own aspect ratio before this class
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include "../shownkinds.h"
|
||||
#include "../qetproject.h"
|
||||
#include "../QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
#include "../diagram.h"
|
||||
@@ -44,6 +45,7 @@ DynamicElementTextItem::DynamicElementTextItem(Element *parent_element) :
|
||||
m_parent_element(parent_element),
|
||||
m_uuid(QUuid::createUuid())
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::SymbolTexts);
|
||||
setFont(QETApp::dynamicTextsItemFont());
|
||||
setText(tr("Texte"));
|
||||
setParentItem(parent_element);
|
||||
@@ -1662,6 +1664,7 @@ void DynamicElementTextItem::updateXref()
|
||||
if(!m_slave_Xref_item)
|
||||
{
|
||||
m_slave_Xref_item = new QGraphicsTextItem(xref_label, this);
|
||||
ShownKinds::tag(m_slave_Xref_item, ShownKinds::CrossReferences);
|
||||
m_slave_Xref_item->setFont(QETApp::diagramTextsFont(5));
|
||||
// Match the parent text's user-configurable color instead of
|
||||
// hardcoding black, which renders invisible under dark themes
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "elementtextitemgroup.h"
|
||||
#include "../shownkinds.h"
|
||||
#include "../qetproject.h"
|
||||
#include "../QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
#include "../diagram.h"
|
||||
@@ -53,6 +54,7 @@ ElementTextItemGroup::ElementTextItemGroup(const QString &name,
|
||||
m_name(name),
|
||||
m_parent_element(parent)
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::SymbolTexts);
|
||||
setFlags(QGraphicsItem::ItemIsSelectable
|
||||
| QGraphicsItem::ItemIsMovable);
|
||||
connect(parent,
|
||||
@@ -882,6 +884,7 @@ void ElementTextItemGroup::updateXref()
|
||||
if(!m_slave_Xref_item)
|
||||
{
|
||||
m_slave_Xref_item = new QGraphicsTextItem(xref_label, this);
|
||||
ShownKinds::tag(m_slave_Xref_item, ShownKinds::CrossReferences);
|
||||
m_slave_Xref_item->setFont(QETApp::diagramTextsFont(5));
|
||||
|
||||
m_update_slave_Xref_connection << connect(master_elmt, &Element::xChanged, this, &ElementTextItemGroup::updateXref);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "independenttextitem.h"
|
||||
#include "../shownkinds.h"
|
||||
|
||||
#include "../diagram.h"
|
||||
#include "../diagramcommands.h"
|
||||
@@ -34,6 +35,7 @@
|
||||
IndependentTextItem::IndependentTextItem() :
|
||||
DiagramTextItem(nullptr)
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::FreeTexts);
|
||||
//Start from the font last applied to a text item this session,
|
||||
//falling back to the app-wide Preferences default otherwise.
|
||||
setFont(LastUsedStyle::hasTextFont() ? LastUsedStyle::textFont()
|
||||
@@ -49,7 +51,9 @@ IndependentTextItem::IndependentTextItem() :
|
||||
*/
|
||||
IndependentTextItem::IndependentTextItem(const QString &text) :
|
||||
DiagramTextItem(text, nullptr)
|
||||
{}
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::FreeTexts);
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
IndependentTextItem::~IndependentTextItem()
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qetshapeitem.h"
|
||||
#include "../shownkinds.h"
|
||||
|
||||
#include "../PropertiesEditor/propertieseditordialog.h"
|
||||
#include "../QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
@@ -57,6 +58,7 @@ QetShapeItem::QetShapeItem(QPointF p1, QPointF p2, ShapeType type, QGraphicsItem
|
||||
m_P2 (p2),
|
||||
m_hovered(false)
|
||||
{
|
||||
ShownKinds::tag(this, ShownKinds::Shapes);
|
||||
if (type == Polygon) m_polygon << m_P1 << m_P2;
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
@@ -4098,10 +4098,7 @@ bool QetScriptApi::setConductorDefault(int folioIndex, const QString &property,
|
||||
{
|
||||
const QList<Conductor *> conductor_list = diagram->conductors();
|
||||
for (Conductor *c : conductor_list)
|
||||
{
|
||||
const ConductorProperties cp = c->properties();
|
||||
c->textItem()->setVisible(cp.type == ConductorProperties::Multi && cp.m_show_text);
|
||||
}
|
||||
c->updateTextVisibility();
|
||||
for (Conductor *c : conductor_list)
|
||||
c->calculateTextItemPosition();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "shownkinds.h"
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include <QGraphicsScene>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool hidden[ShownKinds::KindCount] = {};
|
||||
}
|
||||
|
||||
/**
|
||||
@return true unless @a kind was hidden with setShown().
|
||||
*/
|
||||
bool ShownKinds::isShown(Kind kind)
|
||||
{
|
||||
return 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 < 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@return true if @a item is visible, or would be but for its kind being
|
||||
hidden. For code that asks isVisible() to learn what an item's own code
|
||||
decided (which wire carries the text of a potential).
|
||||
*/
|
||||
bool ShownKinds::wantsVisible(const QGraphicsItem *item)
|
||||
{
|
||||
return item && (item->isVisible() || item->data(hidden_key).toBool());
|
||||
}
|
||||
|
||||
/**
|
||||
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<QGraphicsItem *> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SHOWNKINDS_H
|
||||
#define SHOWNKINDS_H
|
||||
|
||||
class QGraphicsItem;
|
||||
class QGraphicsScene;
|
||||
|
||||
/**
|
||||
Show or hide whole kinds of folio items, View > Show (bugtracker #301):
|
||||
symbol texts, wire numbers, free texts and so on.
|
||||
|
||||
Each item says which kind it is with a tag set by its constructor, so an
|
||||
item created while its kind is hidden starts hidden, whichever way it was
|
||||
created (load, paste, a text added to a symbol, a new cross-reference).
|
||||
A tag and not type(): the cross-reference under a contact's label is a
|
||||
plain QGraphicsTextItem.
|
||||
|
||||
Some items also hide themselves (a wire number switched off, one text
|
||||
per potential, a cross-reference snapped elsewhere). They call
|
||||
setVisible() here instead of QGraphicsItem::setVisible(), and the kind
|
||||
state can only veto what they ask for: showing a kind again brings back
|
||||
only what was hidden for it, never what an item hid itself.
|
||||
|
||||
The state is for the whole application and is not saved: it is a way of
|
||||
looking at the folios, like the grid. Hidden items are left out of
|
||||
printing and exports, and Qt does not select them, so nothing hidden is
|
||||
copied, moved or deleted by accident.
|
||||
|
||||
This part knows nothing of Diagram, so it can be tested on a plain scene.
|
||||
*/
|
||||
namespace ShownKinds
|
||||
{
|
||||
enum Kind {
|
||||
SymbolTexts,
|
||||
WireNumbers,
|
||||
FreeTexts,
|
||||
Shapes,
|
||||
Pictures,
|
||||
Tables,
|
||||
CrossReferences,
|
||||
KindCount
|
||||
};
|
||||
|
||||
/// QGraphicsItem::data() key holding an item's kind.
|
||||
inline constexpr int data_key = 0x4b4e44; // "KND"
|
||||
/// QGraphicsItem::data() key set while an item that wants to be
|
||||
/// visible is hidden only because its kind is hidden.
|
||||
inline constexpr int hidden_key = 0x4b4e48; // "KNH"
|
||||
|
||||
bool isShown(Kind kind);
|
||||
void setShown(Kind kind, bool shown);
|
||||
int hiddenCount();
|
||||
|
||||
void tag(QGraphicsItem *item, Kind kind);
|
||||
void setVisible(QGraphicsItem *item, bool visible);
|
||||
bool isHidden(const QGraphicsItem *item);
|
||||
bool wantsVisible(const QGraphicsItem *item);
|
||||
void apply(QGraphicsScene *scene, Kind kind);
|
||||
}
|
||||
|
||||
#endif // SHOWNKINDS_H
|
||||
@@ -124,10 +124,7 @@ DiagramPropertiesDialog::DiagramPropertiesDialog(Diagram *diagram, QWidget *pare
|
||||
{
|
||||
const QList<Conductor *> conductor_list = diagram -> conductors();
|
||||
for (Conductor *c : conductor_list)
|
||||
{
|
||||
const ConductorProperties cp = c -> properties();
|
||||
c -> textItem() -> setVisible(cp.type == ConductorProperties::Multi && cp.m_show_text);
|
||||
}
|
||||
c -> updateTextVisibility();
|
||||
for (Conductor *c : conductor_list)
|
||||
c -> calculateTextItemPosition();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "../qetgraphicsitem/dynamicelementtextitem.h"
|
||||
#include "../qetgraphicsitem/element.h"
|
||||
#include "../qetgraphicsitem/elementtextitemgroup.h"
|
||||
#include "../shownkinds.h"
|
||||
#include "../qetgraphicsitem/terminal.h"
|
||||
#include "addelementtextcommand.h"
|
||||
#include "../TerminalStrip/realterminal.h"
|
||||
@@ -324,7 +325,8 @@ void DeleteQGraphicsItemCommand::redo()
|
||||
//current conductor is visible (that mean the conductor have the single displayed text)
|
||||
//We call adjustTextItemPosition to other conductor at the same potential to keep
|
||||
//a visible text on this potential.
|
||||
if (m_diagram -> defaultConductorProperties.m_one_text_per_folio && c -> textItem() -> isVisible())
|
||||
//wantsVisible(): also while wire texts are hidden (View > Show)
|
||||
if (m_diagram -> defaultConductorProperties.m_one_text_per_folio && ShownKinds::wantsVisible(c -> textItem()))
|
||||
{
|
||||
QList <Conductor *> conductor_list;
|
||||
conductor_list << c -> relatedPotentialConductors(false).values();
|
||||
|
||||
@@ -139,6 +139,14 @@ add_test(NAME tst_itemgroups COMMAND tst_itemgroups)
|
||||
target_include_directories(tst_itemgroups PRIVATE ${QET_DIR}/sources)
|
||||
target_link_libraries(tst_itemgroups PRIVATE Qt::Test Qt::Widgets Qt::Xml)
|
||||
|
||||
# shownkinds.cpp keeps View > Show (bugtracker #301) apart from the item
|
||||
# classes, so it is tested here on a plain scene of rectangles.
|
||||
add_executable(tst_shownkinds tst_shownkinds.cpp ${QET_DIR}/sources/shownkinds.cpp)
|
||||
add_test(NAME tst_shownkinds COMMAND tst_shownkinds)
|
||||
set_tests_properties(tst_shownkinds PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
|
||||
target_include_directories(tst_shownkinds PRIVATE ${QET_DIR}/sources)
|
||||
target_link_libraries(tst_shownkinds PRIVATE Qt::Test Qt::Widgets)
|
||||
|
||||
# textanchor.h is header-only: the point of a text chosen by its alignment,
|
||||
# shown as Position X/Y in the text properties (#1155).
|
||||
add_executable(tst_textanchor tst_textanchor.cpp)
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
#include <QtTest>
|
||||
#include <QGraphicsRectItem>
|
||||
#include <QGraphicsScene>
|
||||
|
||||
#include "shownkinds.h"
|
||||
|
||||
class tst_shownkinds : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QGraphicsScene *scene = nullptr;
|
||||
|
||||
QGraphicsRectItem *add(QGraphicsItem *parent = nullptr)
|
||||
{
|
||||
auto item = new QGraphicsRectItem(0, 0, 10, 10, parent);
|
||||
item->setFlag(QGraphicsItem::ItemIsSelectable);
|
||||
if (!parent) {
|
||||
scene->addItem(item);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void init()
|
||||
{
|
||||
scene = new QGraphicsScene;
|
||||
for (int k = 0; k < ShownKinds::KindCount; ++k) {
|
||||
ShownKinds::setShown(ShownKinds::Kind(k), true);
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
delete scene;
|
||||
scene = nullptr;
|
||||
}
|
||||
|
||||
void hideAndShowAgain()
|
||||
{
|
||||
auto shape = add();
|
||||
auto text = add();
|
||||
ShownKinds::tag(shape, ShownKinds::Shapes);
|
||||
ShownKinds::tag(text, ShownKinds::FreeTexts);
|
||||
|
||||
ShownKinds::setShown(ShownKinds::Shapes, false);
|
||||
ShownKinds::apply(scene, ShownKinds::Shapes);
|
||||
QVERIFY(!shape->isVisible());
|
||||
QVERIFY(text->isVisible());
|
||||
QCOMPARE(ShownKinds::hiddenCount(), 1);
|
||||
|
||||
ShownKinds::setShown(ShownKinds::Shapes, true);
|
||||
ShownKinds::apply(scene, ShownKinds::Shapes);
|
||||
QVERIFY(shape->isVisible());
|
||||
QCOMPARE(ShownKinds::hiddenCount(), 0);
|
||||
}
|
||||
|
||||
// Created while its kind is hidden: starts hidden, whatever created it.
|
||||
void createdWhileHidden()
|
||||
{
|
||||
ShownKinds::setShown(ShownKinds::Pictures, false);
|
||||
auto picture = add();
|
||||
ShownKinds::tag(picture, ShownKinds::Pictures);
|
||||
QVERIFY(!picture->isVisible());
|
||||
}
|
||||
|
||||
// Untagged items (symbols, wires) are never touched.
|
||||
void untaggedUntouched()
|
||||
{
|
||||
auto symbol = add();
|
||||
auto hidden_symbol = add();
|
||||
hidden_symbol->setVisible(false);
|
||||
for (int k = 0; k < ShownKinds::KindCount; ++k) {
|
||||
ShownKinds::setShown(ShownKinds::Kind(k), false);
|
||||
ShownKinds::apply(scene, ShownKinds::Kind(k));
|
||||
}
|
||||
QVERIFY(symbol->isVisible());
|
||||
for (int k = 0; k < ShownKinds::KindCount; ++k) {
|
||||
ShownKinds::setShown(ShownKinds::Kind(k), true);
|
||||
ShownKinds::apply(scene, ShownKinds::Kind(k));
|
||||
}
|
||||
QVERIFY(!hidden_symbol->isVisible());
|
||||
}
|
||||
|
||||
// apply() touches only the kind it is given.
|
||||
void applyOnlyThatKind()
|
||||
{
|
||||
auto shape = add();
|
||||
ShownKinds::tag(shape, ShownKinds::Shapes);
|
||||
ShownKinds::setShown(ShownKinds::Shapes, false);
|
||||
ShownKinds::apply(scene, ShownKinds::Tables);
|
||||
QVERIFY(shape->isVisible());
|
||||
}
|
||||
|
||||
// An item that hid itself (a wire number switched off) stays hidden
|
||||
// when its kind is hidden and shown again.
|
||||
void ownHiddenStaysHidden()
|
||||
{
|
||||
auto number = add();
|
||||
ShownKinds::tag(number, ShownKinds::WireNumbers);
|
||||
ShownKinds::setVisible(number, false);
|
||||
ShownKinds::setShown(ShownKinds::WireNumbers, false);
|
||||
ShownKinds::apply(scene, ShownKinds::WireNumbers);
|
||||
ShownKinds::setShown(ShownKinds::WireNumbers, true);
|
||||
ShownKinds::apply(scene, ShownKinds::WireNumbers);
|
||||
QVERIFY(!number->isVisible());
|
||||
}
|
||||
|
||||
// An item asking to be shown while its kind is hidden stays hidden,
|
||||
// and appears when the kind is shown (one text per potential moving
|
||||
// to another wire, a cross-reference changing its snap).
|
||||
void showVetoedThenRestored()
|
||||
{
|
||||
auto number = add();
|
||||
ShownKinds::tag(number, ShownKinds::WireNumbers);
|
||||
ShownKinds::setShown(ShownKinds::WireNumbers, false);
|
||||
ShownKinds::apply(scene, ShownKinds::WireNumbers);
|
||||
ShownKinds::setVisible(number, true);
|
||||
QVERIFY(!number->isVisible());
|
||||
ShownKinds::setShown(ShownKinds::WireNumbers, true);
|
||||
ShownKinds::apply(scene, ShownKinds::WireNumbers);
|
||||
QVERIFY(number->isVisible());
|
||||
}
|
||||
|
||||
// Hidden while its kind is hidden: not shown again with the kind.
|
||||
void hiddenWhileKindHidden()
|
||||
{
|
||||
auto number = add();
|
||||
ShownKinds::tag(number, ShownKinds::WireNumbers);
|
||||
ShownKinds::setShown(ShownKinds::WireNumbers, false);
|
||||
ShownKinds::apply(scene, ShownKinds::WireNumbers);
|
||||
ShownKinds::setVisible(number, false);
|
||||
ShownKinds::setShown(ShownKinds::WireNumbers, true);
|
||||
ShownKinds::apply(scene, ShownKinds::WireNumbers);
|
||||
QVERIFY(!number->isVisible());
|
||||
}
|
||||
|
||||
// wantsVisible() tells the wire carrying a potential's text from the
|
||||
// others while wire texts are hidden, so deleting it moves the text.
|
||||
void wantsVisibleWhileKindHidden()
|
||||
{
|
||||
auto carrier = add();
|
||||
auto other = add();
|
||||
ShownKinds::tag(carrier, ShownKinds::WireNumbers);
|
||||
ShownKinds::tag(other, ShownKinds::WireNumbers);
|
||||
ShownKinds::setVisible(other, false);
|
||||
ShownKinds::setShown(ShownKinds::WireNumbers, false);
|
||||
ShownKinds::apply(scene, ShownKinds::WireNumbers);
|
||||
QVERIFY(!carrier->isVisible());
|
||||
QVERIFY(ShownKinds::wantsVisible(carrier));
|
||||
QVERIFY(!ShownKinds::wantsVisible(other));
|
||||
ShownKinds::setShown(ShownKinds::WireNumbers, true);
|
||||
ShownKinds::apply(scene, ShownKinds::WireNumbers);
|
||||
QVERIFY(ShownKinds::wantsVisible(carrier));
|
||||
QVERIFY(!ShownKinds::wantsVisible(other));
|
||||
}
|
||||
|
||||
// A text under a hidden parent still counts as wanting to be visible.
|
||||
void childOfHiddenParent()
|
||||
{
|
||||
auto group = add();
|
||||
auto text = add(group);
|
||||
ShownKinds::tag(group, ShownKinds::SymbolTexts);
|
||||
ShownKinds::tag(text, ShownKinds::CrossReferences);
|
||||
ShownKinds::setShown(ShownKinds::SymbolTexts, false);
|
||||
ShownKinds::apply(scene, ShownKinds::SymbolTexts);
|
||||
ShownKinds::setShown(ShownKinds::CrossReferences, false);
|
||||
ShownKinds::apply(scene, ShownKinds::CrossReferences);
|
||||
ShownKinds::setShown(ShownKinds::SymbolTexts, true);
|
||||
ShownKinds::apply(scene, ShownKinds::SymbolTexts);
|
||||
QVERIFY(!text->isVisible());
|
||||
ShownKinds::setShown(ShownKinds::CrossReferences, true);
|
||||
ShownKinds::apply(scene, ShownKinds::CrossReferences);
|
||||
QVERIFY(text->isVisible());
|
||||
}
|
||||
|
||||
// isHidden() follows the parents: a cross-reference under a symbol text.
|
||||
void hiddenThroughParent()
|
||||
{
|
||||
auto symbol = add();
|
||||
auto label = add(symbol);
|
||||
auto xref = add(label);
|
||||
ShownKinds::tag(label, ShownKinds::SymbolTexts);
|
||||
ShownKinds::tag(xref, ShownKinds::CrossReferences);
|
||||
QVERIFY(!ShownKinds::isHidden(xref));
|
||||
|
||||
ShownKinds::setShown(ShownKinds::SymbolTexts, false);
|
||||
QVERIFY(ShownKinds::isHidden(xref));
|
||||
QVERIFY(!ShownKinds::isHidden(symbol));
|
||||
}
|
||||
|
||||
// Hidden means safe from Select All, copy and delete: Qt will not
|
||||
// select it, and drops a selection it had.
|
||||
void hiddenIsNotSelectable()
|
||||
{
|
||||
auto text = add();
|
||||
ShownKinds::tag(text, ShownKinds::FreeTexts);
|
||||
text->setSelected(true);
|
||||
ShownKinds::setShown(ShownKinds::FreeTexts, false);
|
||||
ShownKinds::apply(scene, ShownKinds::FreeTexts);
|
||||
QVERIFY(!text->isSelected());
|
||||
text->setSelected(true);
|
||||
QVERIFY(scene->selectedItems().isEmpty());
|
||||
QVERIFY(scene->items(QRectF(-5, -5, 20, 20)).isEmpty());
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_shownkinds)
|
||||
#include "tst_shownkinds.moc"
|
||||
Reference in New Issue
Block a user