mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-13 16:34:14 +02:00
Merge master into stage 2 (#1042) as the base of the stage PRs
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "../../utils/qetsettings.h"
|
||||
#include "../../utils/qetutils.h"
|
||||
#include "../../qetmessagebox.h"
|
||||
#include "../../textgrid.h"
|
||||
#include "../nokde/kcolorbutton.h"
|
||||
#include <QFileDialog>
|
||||
#include <QFontDialog>
|
||||
@@ -71,6 +72,15 @@ GeneralConfigurationPage::GeneralConfigurationPage(QWidget *parent) :
|
||||
ui->m_collection_dblclick_edits->setChecked(!settings.value("elementscollection/double-click-inserts", true).toBool());
|
||||
ui->DiagramEditor_xGrid_sb->setValue(settings.value("diagrameditor/Xgrid", 10).toInt());
|
||||
ui->DiagramEditor_yGrid_sb->setValue(settings.value("diagrameditor/Ygrid", 10).toInt());
|
||||
for (const qreal divisor : TextGrid::divisors)
|
||||
ui->DiagramEditor_textGrid_cb->addItem(
|
||||
divisor > 0 ? TextGrid::ratioLabel(divisor) : tr("Désactivée"),
|
||||
divisor);
|
||||
int text_grid_index = ui->DiagramEditor_textGrid_cb->findData(
|
||||
settings.value(TextGrid::settings_key, 1).toReal());
|
||||
if (text_grid_index < 0)
|
||||
text_grid_index = ui->DiagramEditor_textGrid_cb->findData(qreal(1));
|
||||
ui->DiagramEditor_textGrid_cb->setCurrentIndex(text_grid_index);
|
||||
ui->DiagramEditor_xKeyGrid_sb->setValue(settings.value("diagrameditor/key_Xgrid", 10).toInt());
|
||||
ui->DiagramEditor_yKeyGrid_sb->setValue(settings.value("diagrameditor/key_Ygrid", 10).toInt());
|
||||
ui->DiagramEditor_xKeyGridFine_sb->setValue(settings.value("diagrameditor/key_fine_Xgrid", 1).toInt());
|
||||
@@ -291,6 +301,7 @@ void GeneralConfigurationPage::applyConf()
|
||||
//Grid step and key navigation
|
||||
settings.setValue("diagrameditor/Xgrid", ui->DiagramEditor_xGrid_sb->value());
|
||||
settings.setValue("diagrameditor/Ygrid", ui->DiagramEditor_yGrid_sb->value());
|
||||
settings.setValue(TextGrid::settings_key, ui->DiagramEditor_textGrid_cb->currentData());
|
||||
settings.setValue("diagrameditor/key_Xgrid", ui->DiagramEditor_xKeyGrid_sb->value());
|
||||
settings.setValue("diagrameditor/key_Ygrid", ui->DiagramEditor_yKeyGrid_sb->value());
|
||||
settings.setValue("diagrameditor/key_fine_Xgrid", ui->DiagramEditor_xKeyGridFine_sb->value());
|
||||
|
||||
@@ -794,6 +794,26 @@ Vous pouvez spécifier ici la valeur par défaut de ce champ pour les éléments
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="Label_Diagram_textGrid">
|
||||
<property name="text">
|
||||
<string>Grille des textes déplacés à la souris</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Fraction de la grille des folios. Maintenir Ctrl pendant le déplacement pour placer librement.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QComboBox" name="DiagramEditor_textGrid_cb">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -18,12 +18,15 @@
|
||||
#include "jumptoelementdialog.h"
|
||||
|
||||
#include "../diagram.h"
|
||||
#include "../diagramview.h"
|
||||
#include "../qetproject.h"
|
||||
#include "../qetgraphicsitem/element.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QRegularExpression>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
/**
|
||||
@@ -38,7 +41,7 @@ JumpToElementDialog::JumpToElementDialog(Diagram *diagram, QWidget *parent) :
|
||||
setWindowTitle(tr("Atteindre un élément", "window title"));
|
||||
|
||||
m_filter_edit = new QLineEdit(this);
|
||||
m_filter_edit->setPlaceholderText(tr("Nom, label ou information de l'élément…"));
|
||||
m_filter_edit->setPlaceholderText(tr("Nom, label ou information de l'élément, ou case (ex. B13 ou 3-B13)…"));
|
||||
m_filter_edit->installEventFilter(this);
|
||||
|
||||
m_result_list = new QListWidget(this);
|
||||
@@ -86,6 +89,7 @@ void JumpToElementDialog::buildCandidates()
|
||||
|
||||
Candidate candidate;
|
||||
candidate.element = element;
|
||||
candidate.label = label;
|
||||
candidate.display_text = label.isEmpty() ? name : (label + QStringLiteral(" — ") + name);
|
||||
|
||||
QStringList search_parts;
|
||||
@@ -111,6 +115,7 @@ void JumpToElementDialog::updateFilteredList(const QString &filter_text)
|
||||
m_result_list->clear();
|
||||
|
||||
const QString needle = filter_text.trimmed().toLower();
|
||||
bool exact_label_match = false;
|
||||
for (int i = 0; i < m_candidates.size(); ++i) {
|
||||
const Candidate &candidate = m_candidates.at(i);
|
||||
if (!candidate.element) {
|
||||
@@ -121,6 +126,18 @@ void JumpToElementDialog::updateFilteredList(const QString &filter_text)
|
||||
}
|
||||
auto *list_item = new QListWidgetItem(candidate.display_text, m_result_list);
|
||||
list_item->setData(Qt::UserRole, i);
|
||||
if (candidate.label.compare(needle, Qt::CaseInsensitive) == 0) {
|
||||
exact_label_match = true;
|
||||
}
|
||||
}
|
||||
|
||||
//A cell of the border, on this folio (ex : B13) or on another one
|
||||
//(ex : 3-B13, folio 3, the way cross references write it), comes
|
||||
//first, unless an element is labelled exactly like it: Enter keeps
|
||||
//jumping to that element.
|
||||
if (QListWidgetItem *cell_item = cellItem(needle)) {
|
||||
m_result_list->insertItem(exact_label_match ? m_result_list->count() : 0,
|
||||
cell_item);
|
||||
}
|
||||
|
||||
if (m_result_list->count() > 0) {
|
||||
@@ -142,6 +159,17 @@ void JumpToElementDialog::activateCurrentItem()
|
||||
}
|
||||
|
||||
const int index = current->data(Qt::UserRole).toInt();
|
||||
if (index == -1) {
|
||||
const QList<Diagram *> diagrams = m_diagram->project()
|
||||
? m_diagram->project()->diagrams()
|
||||
: QList<Diagram *>();
|
||||
const int folio = current->data(Qt::UserRole + 2).toInt();
|
||||
if (folio >= 0 && folio < diagrams.size()) {
|
||||
zoomToCell(diagrams.at(folio), current->data(Qt::UserRole + 1).toRectF());
|
||||
}
|
||||
accept();
|
||||
return;
|
||||
}
|
||||
if (index < 0 || index >= m_candidates.size()) {
|
||||
reject();
|
||||
return;
|
||||
@@ -159,6 +187,93 @@ void JumpToElementDialog::activateCurrentItem()
|
||||
accept();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief JumpToElementDialog::cellItem
|
||||
@param needle : the typed text, trimmed and lower case
|
||||
@return a new list item for the cell \a needle names, on m_diagram
|
||||
(ex : b13) or on the folio at a position of the project (ex : 3-b13,
|
||||
3b13, p3b13), or nullptr if \a needle names no cell of an existing
|
||||
folio. The item holds -1, the cell rect and the folio position.
|
||||
*/
|
||||
QListWidgetItem *JumpToElementDialog::cellItem(const QString &needle) const
|
||||
{
|
||||
if (!m_diagram || !m_diagram->project()) {
|
||||
return nullptr;
|
||||
}
|
||||
const QList<Diagram *> diagrams = m_diagram->project()->diagrams();
|
||||
|
||||
Diagram *diagram = m_diagram;
|
||||
QString cell = needle;
|
||||
QString text;
|
||||
QRectF cell_rect = diagram->border_and_titleblock.cellRect(cell);
|
||||
if (cell_rect.isNull()) {
|
||||
//A folio position then a cell, like %f-%l%c in cross references
|
||||
static const QRegularExpression folio_cell_re(
|
||||
QStringLiteral("^p?\\s*(\\d{1,4})\\s*[-/.:]?\\s*([a-z]+\\s*\\d{1,4})$"));
|
||||
const QRegularExpressionMatch match = folio_cell_re.match(needle);
|
||||
if (!match.hasMatch()) {
|
||||
return nullptr;
|
||||
}
|
||||
const int folio = match.captured(1).toInt();
|
||||
if (folio < 1 || folio > diagrams.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
diagram = diagrams.at(folio - 1);
|
||||
cell = match.captured(2);
|
||||
cell_rect = diagram->border_and_titleblock.cellRect(cell);
|
||||
if (cell_rect.isNull()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
cell = cell.remove(QLatin1Char(' ')).toUpper();
|
||||
if (diagram == m_diagram) {
|
||||
text = tr("Case %1").arg(cell);
|
||||
} else {
|
||||
const QString title = diagram->title();
|
||||
text = title.isEmpty()
|
||||
? tr("Folio %1, case %2").arg(diagrams.indexOf(diagram) + 1).arg(cell)
|
||||
: tr("Folio %1 (%2), case %3").arg(diagrams.indexOf(diagram) + 1).arg(title, cell);
|
||||
}
|
||||
|
||||
auto *item = new QListWidgetItem(text);
|
||||
item->setData(Qt::UserRole, -1);
|
||||
item->setData(Qt::UserRole + 1, cell_rect);
|
||||
item->setData(Qt::UserRole + 2, diagrams.indexOf(diagram));
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief JumpToElementDialog::zoomToCell
|
||||
Show \a diagram and zoom its view on \a cell_rect with one cell of
|
||||
context around it.
|
||||
@param diagram : the folio holding the cell
|
||||
@param cell_rect : the cell, in scene coordinate
|
||||
*/
|
||||
void JumpToElementDialog::zoomToCell(Diagram *diagram, const QRectF &cell_rect)
|
||||
{
|
||||
const QRectF rect = cell_rect.adjusted(-cell_rect.width(), -cell_rect.height(),
|
||||
cell_rect.width(), cell_rect.height());
|
||||
const bool other_folio = diagram != m_diagram;
|
||||
if (other_folio) {
|
||||
diagram->showMe();
|
||||
}
|
||||
for (QGraphicsView *view : diagram->views()) {
|
||||
if (auto *diagram_view = qobject_cast<DiagramView *>(view)) {
|
||||
if (other_folio) {
|
||||
//A folio shown for the first time is laid out at
|
||||
//its size once the tab switch has been handled
|
||||
QMetaObject::invokeMethod(diagram_view, [diagram_view, rect]() {
|
||||
diagram_view->zoomToRect(rect);
|
||||
}, Qt::QueuedConnection);
|
||||
} else {
|
||||
diagram_view->zoomToRect(rect);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief JumpToElementDialog::eventFilter
|
||||
Redirect Up/Down/Enter/Escape typed in the filter field to the result
|
||||
|
||||
@@ -25,13 +25,15 @@ class Diagram;
|
||||
class Element;
|
||||
class QLineEdit;
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
|
||||
/**
|
||||
@brief The JumpToElementDialog class
|
||||
A lightweight, transient "quick open" popup: type part of an element's
|
||||
label or other information to live-filter the elements on a diagram,
|
||||
then Enter to select the chosen element on the diagram and scroll it
|
||||
into view. Up/Down move through the filtered list, Escape cancels
|
||||
into view. Typing a cell of the border instead (ex : B13, or 3-B13 for
|
||||
the third folio of the project) offers to zoom on that cell. Up/Down move through the filtered list, Escape cancels
|
||||
without changing the current selection.
|
||||
*/
|
||||
class JumpToElementDialog : public QDialog
|
||||
@@ -51,9 +53,12 @@ class JumpToElementDialog : public QDialog
|
||||
|
||||
private:
|
||||
void buildCandidates();
|
||||
QListWidgetItem *cellItem(const QString &needle) const;
|
||||
void zoomToCell(Diagram *diagram, const QRectF &cell_rect);
|
||||
|
||||
struct Candidate {
|
||||
QPointer<Element> element;
|
||||
QString label;
|
||||
QString display_text;
|
||||
QString search_text;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user