mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-05 10:34:13 +02:00
Fix multi-second Ctrl+V stall and cursor jump on paste
Two issues on the interactive paste path: 1. Stall: DiagramEventAddPaste's constructor called Diagram::fromXml() with no database batching, so every addItem() emitted dataBaseUpdated() and each connected table model re-ran its full SQL query. A typical paste (~40 elements + ~40 conductors) triggered ~77 rebuilds of the table models -- measured at ~2.1 s of pure fromXml time on a large project. Project loading already batches this via setUpdateBlocked()/blockSignals() (QETProject::readProjectXml); the paste path now does the same: block during fromXml, one updateDB() after. Measured fromXml: 2114 ms -> 143 ms. 2. Cursor jump: m_initial_cursor was set to the group origin but the physical cursor stayed at the Ctrl+V press location, so the first mouseMoveEvent computed a large delta and the items jumped on first touch. Warp the cursor to the group origin after placement so the baseline and the actual cursor position match.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "../qetapp.h"
|
||||
#include "../qetdiagrameditor.h"
|
||||
#include "../qetgraphicsitem/conductor.h"
|
||||
#include "../qetproject.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
@@ -52,8 +53,25 @@
|
||||
QDomDocument document_xml;
|
||||
if (!document_xml.setContent(clipboard_text)) return;
|
||||
|
||||
//Batch the database work the same way project loading does
|
||||
//(QETProject::readProjectXml): without this, every addItem()
|
||||
//below emits dataBaseUpdated(), which makes each connected
|
||||
//table model re-run its full SQL query -- ~77 queries for a
|
||||
//typical paste, i.e. the multi-second stall on Ctrl+V.
|
||||
auto *db = m_diagram->project() ? m_diagram->project()->dataBase() : nullptr;
|
||||
if (db) {
|
||||
db->blockSignals(true);
|
||||
db->setUpdateBlocked(true);
|
||||
}
|
||||
|
||||
//Load items at their original XML coordinates.
|
||||
m_diagram->fromXml(document_xml, QPointF(), false, &m_content);
|
||||
|
||||
if (db) {
|
||||
db->blockSignals(false);
|
||||
db->setUpdateBlocked(false);
|
||||
db->updateDB();
|
||||
}
|
||||
if (!m_content.count()) return;
|
||||
|
||||
const QList<QGraphicsItem *> movable = m_content.items(MovableItems);
|
||||
@@ -116,6 +134,14 @@
|
||||
if (const auto qde = QETApp::diagramEditorAncestorOf(view)) {
|
||||
m_status_bar = qde->statusBar();
|
||||
}
|
||||
//Warp the cursor to the group's grid-snapped origin so
|
||||
//the actual cursor position matches m_initial_cursor.
|
||||
//Without this the first mouseMoveEvent computes a large
|
||||
//delta (cursor is still at the Ctrl+V press location)
|
||||
//and the items jump on first touch.
|
||||
const QPoint view_pos = view->mapFromScene(m_initial_cursor);
|
||||
const QPoint global_pos = view->viewport()->mapToGlobal(view_pos);
|
||||
QCursor::setPos(global_pos);
|
||||
}
|
||||
}
|
||||
showHint();
|
||||
|
||||
Reference in New Issue
Block a user