diff options
author | Eike Ziller <eike.ziller@qt.io> | 2020-04-07 11:13:58 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2020-04-07 11:13:58 +0200 |
commit | 10114dc036aff90df34de8c8f3e4c357382e8899 (patch) | |
tree | 0554f94011c2185d6fa202a5f2b53c34f706b48f /src/plugins | |
parent | 45e7b78dc3a25c42f19d4275e7b678cfbd4c5771 (diff) | |
parent | c98f213ae95752cfeba5b12efa2a1bfe71f76a2a (diff) |
Merge remote-tracking branch 'origin/4.12'
Conflicts:
src/plugins/android/androidmanifesteditorwidget.cpp
Change-Id: I8143d9e02837dcd78a637da7b333a6eeebb105cb
Diffstat (limited to 'src/plugins')
38 files changed, 634 insertions, 345 deletions
diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp index d82282238a..7e1dbf540e 100644 --- a/src/plugins/android/androidmanifesteditorwidget.cpp +++ b/src/plugins/android/androidmanifesteditorwidget.cpp @@ -1045,8 +1045,7 @@ bool AndroidManifestEditorWidget::parseMetaData(QXmlStreamReader &reader, QXmlSt { Q_ASSERT(reader.isStartElement()); - const int parseItemsCount = 2; - int counter = 0; + bool found = false; QXmlStreamAttributes attributes = reader.attributes(); QXmlStreamAttributes result; QStringList keys; @@ -1056,13 +1055,13 @@ bool AndroidManifestEditorWidget::parseMetaData(QXmlStreamReader &reader, QXmlSt keys = QStringList("android:value"); values = QStringList(m_targetLineEdit->currentText()); result = modifyXmlStreamAttributes(attributes, keys, values); - ++counter; + found = true; } else if (attributes.value(QLatin1String("android:name")) == QLatin1String("android.app.extract_android_style")) { keys = QStringList("android:value"); values = QStringList(m_styleExtractMethod->currentText()); result = modifyXmlStreamAttributes(attributes, keys, values); - ++counter; + found = true; } else { result = attributes; } @@ -1075,7 +1074,7 @@ bool AndroidManifestEditorWidget::parseMetaData(QXmlStreamReader &reader, QXmlSt while (!reader.atEnd()) { if (reader.isEndElement()) { writer.writeCurrentToken(reader); - return counter == parseItemsCount; + return found; } else if (reader.isStartElement()) { parseUnknownElement(reader, writer); } else { @@ -1083,7 +1082,7 @@ bool AndroidManifestEditorWidget::parseMetaData(QXmlStreamReader &reader, QXmlSt } reader.readNext(); } - return counter == parseItemsCount; // should never be reached + return found; // should never be reached } void AndroidManifestEditorWidget::parseUsesSdk(QXmlStreamReader &reader, QXmlStreamWriter & writer) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 963dd3ffab..74115668fb 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1115,6 +1115,7 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters) showMessage(response.data["msg"].data(), LogError); } watchHandler()->notifyUpdateFinished(); + updateToolTips(); }; runCommand(cmd); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 4f3984d4c4..72d1a43194 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -2358,6 +2358,10 @@ void DebuggerEngine::updateItem(const QString &iname) QTC_CHECK(item); WatchModelBase *model = handler->model(); QTC_CHECK(model); + if (item && !item->wantsChildren) { + updateToolTips(); + return; + } if (item && !model->hasChildren(model->indexForItem(item))) { handler->notifyUpdateStarted(UpdateParameters(iname)); item->setValue(decodeData({}, "notaccessible")); diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index e4d88ca38a..700fec6108 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -302,6 +302,11 @@ DebuggerMainWindow::DebuggerMainWindow() cmd->setAttribute(Command::CA_Hide); viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE); + // HACK: See QTCREATORBUG-23755. This ensures the showCentralWidget() + // call in restorePersistentSettings() below has something to operate on, + // and a plain QWidget is what we'll use anyway as central widget. + setCentralWidget(new QWidget); + restorePersistentSettings(); } diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 73c8a2ade8..cc7c1fba25 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -515,7 +515,7 @@ public: documentAndRightPane->setStretchFactor(0, 1); documentAndRightPane->setStretchFactor(1, 0); - auto centralEditorWidget = new QWidget; + auto centralEditorWidget = mainWindow->centralWidget(); auto centralLayout = new QVBoxLayout(centralEditorWidget); centralEditorWidget->setLayout(centralLayout); centralLayout->setContentsMargins(0, 0, 0, 0); @@ -544,7 +544,6 @@ public: splitter->setStretchFactor(1, 1); splitter->setObjectName("DebugModeWidget"); - mainWindow->setCentralWidget(centralEditorWidget); mainWindow->addSubPerspectiveSwitcher(EngineManager::engineChooser()); setWidget(splitter); diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index a815f17c70..49aa316571 100644 --- a/src/plugins/debugger/debuggertooltipmanager.cpp +++ b/src/plugins/debugger/debuggertooltipmanager.cpp @@ -1179,7 +1179,7 @@ DebuggerToolTipManagerPrivate::DebuggerToolTipManagerPrivate(DebuggerEngine *eng this, &DebuggerToolTipManagerPrivate::saveSessionData); connect(SessionManager::instance(), &SessionManager::aboutToUnloadSession, this, &DebuggerToolTipManagerPrivate::sessionAboutToChange); - setupEditors(); + debugModeEntered(); } void DebuggerToolTipManagerPrivate::slotTooltipOverrideRequested @@ -1241,8 +1241,6 @@ void DebuggerToolTipManagerPrivate::slotTooltipOverrideRequested DEBUG("SYNC IN STATE" << tooltip->state); tooltip->updateTooltip(m_engine); - *handled = true; - } else { context.iname = "tooltip." + toHex(context.expression); @@ -1256,7 +1254,6 @@ void DebuggerToolTipManagerPrivate::slotTooltipOverrideRequested tooltip->context.mousePosition = point; ToolTip::move(point, DebuggerMainWindow::instance()); DEBUG("UPDATING DELAYED."); - *handled = true; } else { DEBUG("CREATING DELAYED."); tooltip = new DebuggerToolTipHolder(context); @@ -1272,6 +1269,8 @@ void DebuggerToolTipManagerPrivate::slotTooltipOverrideRequested } } } + + *handled = true; } void DebuggerToolTipManagerPrivate::slotEditorOpened(IEditor *e) @@ -1323,6 +1322,7 @@ void DebuggerToolTipManagerPrivate::leavingDebugMode() foreach (IEditor *e, DocumentModel::editorsForOpenedDocuments()) { if (auto toolTipEditor = qobject_cast<BaseTextEditor *>(e)) { toolTipEditor->editorWidget()->verticalScrollBar()->disconnect(this); + toolTipEditor->editorWidget()->disconnect(this); toolTipEditor->disconnect(this); } } diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 9c67a651a6..1518e1ee8e 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -4818,6 +4818,7 @@ void GdbEngine::handleFetchVariables(const DebuggerResponse &response) m_inUpdateLocals = false; updateLocalsView(response.data); watchHandler()->notifyUpdateFinished(); + updateToolTips(); } QString GdbEngine::msgPtraceError(DebuggerStartMode sm) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 70f2c70881..61d9012ccb 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -279,6 +279,7 @@ void LldbEngine::setupEngine() cmd2.arg("environment", rp.inferior.environment.toStringList()); cmd2.arg("processargs", toHex(QtcProcess::splitArgs(rp.inferior.commandLineArguments).join(QChar(0)))); cmd2.arg("platform", rp.platform); + cmd2.arg("symbolfile", rp.symbolFile); if (terminal()) { const qint64 attachedPID = terminal()->applicationPid(); @@ -785,6 +786,7 @@ void LldbEngine::doUpdateLocals(const UpdateParameters ¶ms) cmd.callback = [this](const DebuggerResponse &response) { updateLocalsView(response.data); watchHandler()->notifyUpdateFinished(); + updateToolTips(); }; runCommand(cmd); diff --git a/src/plugins/debugger/uvsc/uvscengine.cpp b/src/plugins/debugger/uvsc/uvscengine.cpp index 351c527986..0d6ff36b5c 100644 --- a/src/plugins/debugger/uvsc/uvscengine.cpp +++ b/src/plugins/debugger/uvsc/uvscengine.cpp @@ -774,6 +774,7 @@ void UvscEngine::handleUpdateLocals(bool partial) updateLocalsView(all); watchHandler()->notifyUpdateFinished(); + updateToolTips(); } void UvscEngine::handleInsertBreakpoint(const QString &exp, const Breakpoint &bp) diff --git a/src/plugins/mcusupport/CMakeLists.txt b/src/plugins/mcusupport/CMakeLists.txt index f2c8cf9b76..2af652f260 100644 --- a/src/plugins/mcusupport/CMakeLists.txt +++ b/src/plugins/mcusupport/CMakeLists.txt @@ -1,6 +1,6 @@ add_qtc_plugin(McuSupport DEPENDS Qt5::Core - PLUGIN_DEPENDS Core ProjectExplorer Debugger CMakeProjectManager + PLUGIN_DEPENDS Core ProjectExplorer Debugger CMakeProjectManager QtSupport SOURCES mcusupport.qrc mcusupport_global.h diff --git a/src/plugins/mcusupport/mcusupport.qbs b/src/plugins/mcusupport/mcusupport.qbs index f3bb8a12e9..f3200d49b1 100644 --- a/src/plugins/mcusupport/mcusupport.qbs +++ b/src/plugins/mcusupport/mcusupport.qbs @@ -11,6 +11,7 @@ QtcPlugin { Depends { name: "ProjectExplorer" } Depends { name: "Debugger" } Depends { name: "CMakeProjectManager" } + Depends { name: "QtSupport" } files: [ "mcusupport.qrc", diff --git a/src/plugins/mcusupport/mcusupport_dependencies.pri b/src/plugins/mcusupport/mcusupport_dependencies.pri index 1f2dd5bc64..f68cd308a9 100644 --- a/src/plugins/mcusupport/mcusupport_dependencies.pri +++ b/src/plugins/mcusupport/mcusupport_dependencies.pri @@ -8,4 +8,5 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ projectexplorer \ debugger \ - cmakeprojectmanager + cmakeprojectmanager \ + qtsupport diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index 159c88e7a0..6d888b48f5 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -39,6 +39,7 @@ #include <projectexplorer/kitmanager.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/devicesupport/devicemanager.h> +#include <qtsupport/qtversionmanager.h> #include <utils/algorithm.h> #include <utils/fileutils.h> #include <utils/infolabel.h> @@ -356,22 +357,45 @@ void McuSupportOptions::populatePackagesAndTargets() setQulDir(Utils::FilePath::fromUserInput(qtForMCUsSdkPackage->path())); } +static Utils::FilePath qulDocsDir() +{ + const Utils::FilePath qulDir = McuSupportOptions::qulDirFromSettings(); + if (qulDir.isEmpty() || !qulDir.exists()) + return {}; + const Utils::FilePath docsDir = qulDir.pathAppended("docs"); + return docsDir.exists() ? docsDir : Utils::FilePath(); +} + void McuSupportOptions::registerQchFiles() { - const QString qulDir = qulDirFromSettings().toString(); - if (qulDir.isEmpty() || !QFileInfo::exists(qulDir)) + const QString docsDir = qulDocsDir().toString(); + if (docsDir.isEmpty()) return; - const QString docsPath = qulDir + "/docs/"; const QStringList qchFiles = { - docsPath + "quickultralite.qch", - docsPath + "quickultralitecmake.qch" + docsDir + "/quickultralite.qch", + docsDir + "/quickultralitecmake.qch" }; Core::HelpManager::registerDocumentation( Utils::filtered(qchFiles, [](const QString &file) { return QFileInfo::exists(file); })); } +void McuSupportOptions::registerExamples() +{ + const Utils::FilePath docsDir = qulDocsDir(); + if (docsDir.isEmpty()) + return; + + const Utils::FilePath examplesDir = + McuSupportOptions::qulDirFromSettings().pathAppended("demos"); + if (!examplesDir.exists()) + return; + + QtSupport::QtVersionManager::registerExampleSet("Qt for MCUs", docsDir.toString(), + examplesDir.toString()); +} + void McuSupportOptions::deletePackagesAndTargets() { qDeleteAll(packages); diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index b22f32375e..92790bac13 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -168,6 +168,7 @@ public: ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget); void populatePackagesAndTargets(); static void registerQchFiles(); + static void registerExamples(); private: void deletePackagesAndTargets(); diff --git a/src/plugins/mcusupport/mcusupportplugin.cpp b/src/plugins/mcusupport/mcusupportplugin.cpp index 4182713e86..3028c7e80e 100644 --- a/src/plugins/mcusupport/mcusupportplugin.cpp +++ b/src/plugins/mcusupport/mcusupportplugin.cpp @@ -76,6 +76,7 @@ bool McuSupportPlugin::initialize(const QStringList& arguments, QString* errorSt dd = new McuSupportPluginPrivate; McuSupportOptions::registerQchFiles(); + McuSupportOptions::registerExamples(); ProjectExplorer::JsonWizardFactory::addWizardPath( Utils::FilePath::fromString(":/mcusupport/wizards/")); diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h b/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h index 132a95a790..038f3a3d0b 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h @@ -73,6 +73,8 @@ struct CurveItemStyleOption QColor color = QColor(0, 200, 0); QColor selectionColor = QColor(200, 200, 200); QColor easingCurveColor = QColor(200, 0, 200); + QColor lockedColor = QColor(50, 50, 50); + QColor hoverColor = QColor(200, 0, 200); }; struct PlayheadStyleOption diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp index 9489928d07..e8dd168580 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp @@ -118,10 +118,10 @@ void CurveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidg pen.setColor(m_style.easingCurveColor); } else { if (locked()) - pen.setColor(Qt::black); + pen.setColor(m_style.lockedColor); else if (isUnderMouse()) - pen.setColor(Qt::red); - else if (hasSelection()) + pen.setColor(m_style.hoverColor); + else if (hasSelectedKeyframe()) pen.setColor(m_style.selectionColor); else pen.setColor(m_style.color); @@ -146,7 +146,25 @@ bool CurveItem::isDirty() const return m_itemDirty; } -bool CurveItem::hasSelection() const +bool CurveItem::hasActiveKeyframe() const +{ + for (auto *frame : m_keyframes) { + if (frame->activated()) + return true; + } + return false; +} + +bool CurveItem::hasActiveHandle() const +{ + for (auto *frame : m_keyframes) { + if (frame->hasActiveHandle()) + return true; + } + return false; +} + +bool CurveItem::hasSelectedKeyframe() const { for (auto *frame : m_keyframes) { if (frame->selected()) @@ -203,7 +221,7 @@ std::vector<AnimationCurve> CurveItem::curves() const std::vector<Keyframe> tmp; - for (size_t i = 0; i < m_keyframes.size(); ++i) { + for (int i = 0; i < m_keyframes.size(); ++i) { KeyframeItem *item = m_keyframes[i]; Keyframe current = item->keyframe(); @@ -233,6 +251,33 @@ std::vector<AnimationCurve> CurveItem::curves() const return out; } +QVector<KeyframeItem *> CurveItem::keyframes() const +{ + return m_keyframes; +} + +QVector<KeyframeItem *> CurveItem::selectedKeyframes() const +{ + QVector<KeyframeItem *> out; + for (auto *frame : m_keyframes) { + if (frame->selected()) + out.push_back(frame); + } + return out; +} + +QVector<HandleItem *> CurveItem::handles() const +{ + QVector<HandleItem *> out; + for (auto *frame : m_keyframes) { + if (auto *left = frame->leftHandle()) + out.push_back(left); + if (auto *right = frame->rightHandle()) + out.push_back(right); + } + return out; +} + void CurveItem::restore() { if (m_keyframes.empty()) @@ -248,7 +293,7 @@ void CurveItem::restore() if (prevItem->hasLeftHandle()) prevItem->setLeftHandle(QPointF()); - for (size_t i = 1; i < m_keyframes.size(); ++i) { + for (int i = 1; i < m_keyframes.size(); ++i) { KeyframeItem *currItem = m_keyframes[i]; bool left = prevItem->hasRightHandle(); @@ -328,7 +373,7 @@ void CurveItem::setInterpolation(Keyframe::Interpolation interpolation) return; KeyframeItem *prevItem = m_keyframes[0]; - for (size_t i = 1; i < m_keyframes.size(); ++i) { + for (int i = 1; i < m_keyframes.size(); ++i) { KeyframeItem *currItem = m_keyframes[i]; if (currItem->selected()) { Keyframe prev = prevItem->keyframe(); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h index a8b18fa698..02d1bf0401 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h @@ -73,7 +73,11 @@ public: bool isDirty() const; - bool hasSelection() const; + bool hasActiveKeyframe() const; + + bool hasActiveHandle() const; + + bool hasSelectedKeyframe() const; unsigned int id() const; @@ -87,6 +91,12 @@ public: std::vector<AnimationCurve> curves() const; + QVector<KeyframeItem *> keyframes() const; + + QVector<KeyframeItem *> selectedKeyframes() const; + + QVector<HandleItem *> handles() const; + void restore(); void setDirty(bool dirty); @@ -126,7 +136,7 @@ private: QTransform m_transform; - std::vector<KeyframeItem *> m_keyframes; + QVector<KeyframeItem *> m_keyframes; bool m_itemDirty; }; diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp index 3b7d848eaa..0d516a0ce5 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp @@ -31,20 +31,60 @@ #include <QGraphicsSceneMouseEvent> +#include <cmath> + namespace DesignTools { GraphicsScene::GraphicsScene(QObject *parent) : QGraphicsScene(parent) + , m_curves() , m_dirty(true) , m_limits() , m_doNotMoveItems(false) {} +GraphicsScene::~GraphicsScene() +{ + m_curves.clear(); +} + bool GraphicsScene::empty() const { return items().empty(); } +bool GraphicsScene::hasActiveKeyframe() const +{ + for (auto *curve : m_curves) { + if (curve->hasActiveKeyframe()) + return true; + } + return false; +} + +bool GraphicsScene::hasActiveHandle() const +{ + for (auto *curve : m_curves) { + if (curve->hasActiveHandle()) + return true; + } + return false; +} + +bool GraphicsScene::hasActiveItem() const +{ + return hasActiveKeyframe() || hasActiveHandle(); +} + +bool GraphicsScene::hasSelectedKeyframe() const +{ + for (auto *curve : m_curves) { + if (curve->hasSelectedKeyframe()) + return true; + } + return false; +} + double GraphicsScene::minimumTime() const { return limits().left(); @@ -65,6 +105,103 @@ double GraphicsScene::maximumValue() const return limits().top(); } +QRectF GraphicsScene::rect() const +{ + return sceneRect(); +} + +QVector<CurveItem *> GraphicsScene::curves() const +{ + return m_curves; +} + +QVector<CurveItem *> GraphicsScene::selectedCurves() const +{ + QVector<CurveItem *> out; + for (auto *curve : m_curves) { + if (curve->hasSelectedKeyframe()) + out.push_back(curve); + } + return out; +} + +QVector<KeyframeItem *> GraphicsScene::keyframes() const +{ + QVector<KeyframeItem *> out; + for (auto *curve : m_curves) + out.append(curve->keyframes()); + + return out; +} + +QVector<KeyframeItem *> GraphicsScene::selectedKeyframes() const +{ + QVector<KeyframeItem *> out; + for (auto *curve : m_curves) + out.append(curve->selectedKeyframes()); + + return out; +} + +CurveItem *GraphicsScene::findCurve(unsigned int id) const +{ + for (auto *curve : m_curves) { + if (curve->id() == id) + return curve; + } + return nullptr; +} + +SelectableItem *GraphicsScene::intersect(const QPointF &pos) const +{ + auto hitTest = [pos](QGraphicsObject *item) { + return item->mapRectToScene(item->boundingRect()).contains(pos); + }; + + const auto frames = keyframes(); + for (auto *frame : frames) { + if (hitTest(frame)) + return frame; + + if (auto *leftHandle = frame->leftHandle()) { + if (hitTest(leftHandle)) + return leftHandle; + } + + if (auto *rightHandle = frame->rightHandle()) { + if (hitTest(rightHandle)) + return rightHandle; + } + } + return nullptr; +} + +void GraphicsScene::reset() +{ + m_curves.clear(); + clear(); +} + +void GraphicsScene::deleteSelectedKeyframes() +{ + for (auto *curve : m_curves) + curve->deleteSelectedKeyframes(); +} + +void GraphicsScene::insertKeyframe(double time, bool all) +{ + if (!all) { + for (auto *curve : m_curves) { + if (curve->isUnderMouse()) + curve->insertKeyframeByTime(std::round(time)); + } + return; + } + + for (auto *curve : m_curves) + curve->insertKeyframeByTime(std::round(time)); +} + void GraphicsScene::doNotMoveItems(bool val) { m_doNotMoveItems = val; @@ -76,16 +213,15 @@ void GraphicsScene::addCurveItem(CurveItem *item) item->setDirty(false); item->connect(this); addItem(item); + m_curves.push_back(item); } void GraphicsScene::setComponentTransform(const QTransform &transform) { QRectF bounds; - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) - bounds = bounds.united(curveItem->setComponentTransform(transform)); - } + + for (auto *curve : m_curves) + bounds = bounds.united(curve->setComponentTransform(transform)); if (bounds.isNull()) { if (GraphicsView *gview = graphicsView()) @@ -98,29 +234,20 @@ void GraphicsScene::setComponentTransform(const QTransform &transform) void GraphicsScene::keyframeMoved(KeyframeItem *movedItem, const QPointF &direction) { - const auto itemList = items(); - for (auto *item : itemList) { - if (item == movedItem) - continue; - - if (auto *frameItem = qgraphicsitem_cast<KeyframeItem *>(item)) { - if (frameItem->selected()) - frameItem->moveKeyframe(direction); + for (auto *curve : m_curves) { + for (auto *keyframe : curve->keyframes()) { + if (keyframe != movedItem && keyframe->selected()) + keyframe->moveKeyframe(direction); } } } void GraphicsScene::handleUnderMouse(HandleItem *handle) { - const auto itemList = items(); - for (auto *item : itemList) { - if (item == handle) - continue; - - if (auto *keyItem = qgraphicsitem_cast<KeyframeItem *>(item)) { - if (keyItem->selected()) { - keyItem->setActivated(handle->isUnderMouse(), handle->slot()); - } + for (auto *curve : m_curves) { + for (auto *keyframe : curve->keyframes()) { + if (keyframe->selected()) + keyframe->setActivated(handle->isUnderMouse(), handle->slot()); } } } @@ -142,16 +269,13 @@ void GraphicsScene::handleMoved(KeyframeItem *frame, } }; - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *frameItem = qgraphicsitem_cast<KeyframeItem *>(item)) { - if (item == frame) { - moveUnified(frameItem); - continue; - } - if (frameItem->selected()) { - frameItem->moveHandle(handle, angle, deltaLength); - moveUnified(frameItem); + for (auto *curve : m_curves) { + for (auto *keyframe : curve->keyframes()) { + if (keyframe == frame) + moveUnified(keyframe); + else if (keyframe->selected()) { + keyframe->moveHandle(handle, angle, deltaLength); + moveUnified(keyframe); } } } @@ -159,27 +283,24 @@ void GraphicsScene::handleMoved(KeyframeItem *frame, void GraphicsScene::setPinned(uint id, bool pinned) { - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) { - if (curveItem->id() == id) - curveItem->setPinned(pinned); - } - } + if (CurveItem *curve = findCurve(id)) + curve->setPinned(pinned); } std::vector<CurveItem *> GraphicsScene::takePinnedItems() { std::vector<CurveItem *> out; - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) { - if (curveItem->pinned()) { - removeItem(curveItem); - out.push_back(curveItem); - } - } + for (auto *curve : m_curves) { + if (curve->pinned()) + out.push_back(curve); } + + for (auto *curve : out) { + curve->disconnect(this); + m_curves.removeOne(curve); + removeItem(curve); + } + return out; } @@ -187,12 +308,24 @@ void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { QGraphicsScene::mouseMoveEvent(mouseEvent); - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *handleItem = qgraphicsitem_cast<HandleItem *>(item)) - handleItem->setIsUnderMouse(handleItem->contains(mouseEvent->scenePos())); - else if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) - curveItem->setIsUnderMouse(curveItem->contains(mouseEvent->scenePos())); + QPointF mouse = mouseEvent->scenePos(); + bool hasHandle = false; + + for (auto *curve : m_curves) { + for (auto *handle : curve->handles()) { + bool intersects = handle->contains(mouse); + handle->setIsUnderMouse(intersects); + if (intersects) + hasHandle = true; + } + } + + if (hasHandle) { + for (auto *curve : m_curves) + curve->setIsUnderMouse(false); + } else { + for (auto *curve : m_curves) + curve->setIsUnderMouse(curve->contains(mouseEvent->scenePos())); } } @@ -200,17 +333,13 @@ void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { QGraphicsScene::mouseReleaseEvent(mouseEvent); - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) { - // CurveItems might become invalid after a keyframe-drag operation. - curveItem->restore(); - - if (curveItem->isDirty()) { - m_dirty = true; - curveItem->setDirty(false); - emit curveChanged(curveItem->id(), curveItem->curve()); - } + for (auto *curve : m_curves) { + // CurveItems might become invalid after a keyframe-drag operation. + curve->restore(); + if (curve->isDirty()) { + m_dirty = true; + curve->setDirty(false); + emit curveChanged(curve->id(), curve->curve()); } } @@ -218,40 +347,11 @@ void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) graphicsView()->setZoomY(0.0); } -bool GraphicsScene::hasActiveKeyframe() const -{ - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *kitem = qgraphicsitem_cast<KeyframeItem *>(item)) { - if (kitem->activated()) - return true; - } - } - return false; -} - -bool GraphicsScene::hasActiveHandle() const -{ - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *hitem = qgraphicsitem_cast<HandleItem *>(item)) { - if (hitem->activated()) - return true; - } - } - return false; -} - -bool GraphicsScene::hasActiveItem() const -{ - return hasActiveKeyframe() || hasActiveHandle(); -} - GraphicsView *GraphicsScene::graphicsView() const { const QList<QGraphicsView *> viewList = views(); - for (auto &&view : viewList) { - if (GraphicsView *gview = qobject_cast<GraphicsView *>(view)) + if (viewList.size() == 1) { + if (GraphicsView *gview = qobject_cast<GraphicsView *>(viewList.at(0))) return gview; } return nullptr; @@ -263,22 +363,19 @@ QRectF GraphicsScene::limits() const QPointF min(std::numeric_limits<double>::max(), std::numeric_limits<double>::max()); QPointF max(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest()); - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) { - auto curve = curveItem->resolvedCurve(); - if (min.x() > curve.minimumTime()) - min.rx() = curve.minimumTime(); + for (auto *curveItem : m_curves) { + auto curve = curveItem->resolvedCurve(); + if (min.x() > curve.minimumTime()) + min.rx() = curve.minimumTime(); - if (min.y() > curve.minimumValue()) - min.ry() = curve.minimumValue(); + if (min.y() > curve.minimumValue()) + min.ry() = curve.minimumValue(); - if (max.x() < curve.maximumTime()) - max.rx() = curve.maximumTime(); + if (max.x() < curve.maximumTime()) + max.rx() = curve.maximumTime(); - if (max.y() < curve.maximumValue()) - max.ry() = curve.maximumValue(); - } + if (max.y() < curve.maximumValue()) + max.ry() = curve.maximumValue(); } m_limits = QRectF(QPointF(min.x(), max.y()), QPointF(max.x(), min.y())); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h index 44936a76bd..3ee50672ba 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h @@ -45,6 +45,8 @@ signals: public: GraphicsScene(QObject *parent = nullptr); + ~GraphicsScene() override; + bool empty() const; bool hasActiveKeyframe() const; @@ -53,6 +55,8 @@ public: bool hasActiveItem() const; + bool hasSelectedKeyframe() const; + double minimumTime() const; double maximumTime() const; @@ -61,6 +65,28 @@ public: double maximumValue() const; + QRectF rect() const; + + QVector<CurveItem *> curves() const; + + QVector<CurveItem *> selectedCurves() const; + + QVector<KeyframeItem *> keyframes() const; + + QVector<KeyframeItem *> selectedKeyframes() const; + + QVector<HandleItem *> handles() const; + + CurveItem *findCurve(unsigned int id) const; + + SelectableItem *intersect(const QPointF &pos) const; + + void reset(); + + void deleteSelectedKeyframes(); + + void insertKeyframe(double time, bool all = false); + void doNotMoveItems(bool tmp); void addCurveItem(CurveItem *item); @@ -85,10 +111,16 @@ protected: private: using QGraphicsScene::addItem; + using QGraphicsScene::clear; + + using QGraphicsScene::removeItem; + GraphicsView *graphicsView() const; QRectF limits() const; + QVector<CurveItem *> m_curves; + mutable bool m_dirty; mutable QRectF m_limits; diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp index 855581bd33..a11c978ae9 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp @@ -43,7 +43,7 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent) , m_zoomX(0.0) , m_zoomY(0.0) , m_transform() - , m_scene() + , m_scene(new GraphicsScene()) , m_model(model) , m_playhead(this) , m_selector() @@ -52,7 +52,7 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent) { model->setGraphicsView(this); - setScene(&m_scene); + setScene(m_scene); setAlignment(Qt::AlignLeft | Qt::AlignVCenter); setResizeAnchor(QGraphicsView::NoAnchor); setRenderHint(QPainter::Antialiasing, true); @@ -68,15 +68,23 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent) m_model->setCurve(id, curve); }; - connect(&m_scene, &GraphicsScene::curveChanged, itemSlot); + connect(m_scene, &GraphicsScene::curveChanged, itemSlot); - auto pinSlot = [this](PropertyTreeItem *pti) { m_scene.setPinned(pti->id(), pti->pinned()); }; + auto pinSlot = [this](PropertyTreeItem *pti) { m_scene->setPinned(pti->id(), pti->pinned()); }; connect(m_model, &CurveEditorModel::curveChanged, pinSlot); applyZoom(m_zoomX, m_zoomY); update(); } +GraphicsView::~GraphicsView() +{ + if (m_scene) { + delete m_scene; + m_scene = nullptr; + } +} + CurveEditorModel *GraphicsView::model() const { return m_model; @@ -87,48 +95,26 @@ CurveEditorStyle GraphicsView::editorStyle() const return m_style; } -bool GraphicsView::hasActiveItem() const -{ - return m_scene.hasActiveItem(); -} - -bool GraphicsView::hasActiveHandle() const -{ - return m_scene.hasActiveHandle(); -} - -bool GraphicsView::hasSelectedKeyframe() const -{ - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) { - if (curveItem->hasSelection()) - return true; - } - } - return false; -} - double GraphicsView::minimumTime() const { - bool check = m_model->minimumTime() < m_scene.minimumTime(); - return check ? m_model->minimumTime() : m_scene.minimumTime(); + bool check = m_model->minimumTime() < m_scene->minimumTime(); + return check ? m_model->minimumTime() : m_scene->minimumTime(); } double GraphicsView::maximumTime() const { - bool check = m_model->maximumTime() > m_scene.maximumTime(); - return check ? m_model->maximumTime() : m_scene.maximumTime(); + bool check = m_model->maximumTime() > m_scene->maximumTime(); + return check ? m_model->maximumTime() : m_scene->maximumTime(); } double GraphicsView::minimumValue() const { - return m_scene.empty() ? -1.0 : m_scene.minimumValue(); + return m_scene->empty() ? -1.0 : m_scene->minimumValue(); } double GraphicsView::maximumValue() const { - return m_scene.empty() ? 1.0 : m_scene.maximumValue(); + return m_scene->empty() ? 1.0 : m_scene->maximumValue(); } double GraphicsView::zoomX() const @@ -179,11 +165,9 @@ void GraphicsView::setStyle(const CurveEditorStyle &style) { m_style = style; - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) - curveItem->setStyle(style); - } + const auto curves = m_scene->curves(); + for (auto *curve : curves) + curve->setStyle(style); applyZoom(m_zoomX, m_zoomY); viewport()->update(); @@ -191,12 +175,8 @@ void GraphicsView::setStyle(const CurveEditorStyle &style) void GraphicsView::setLocked(PropertyTreeItem *item) { - const auto itemList = items(); - for (auto *gitem : itemList) { - if (auto *citem = qgraphicsitem_cast<CurveItem *>(gitem)) - if (item->id() == citem->id()) - citem->setLocked(item->locked()); - } + if (CurveItem *curve = m_scene->findCurve(item->id())) + curve->setLocked(item->locked()); } void GraphicsView::setZoomX(double zoom, const QPoint &pivot) @@ -231,9 +211,9 @@ void GraphicsView::scrollContent(double x, double y) void GraphicsView::reset(const std::vector<CurveItem *> &items) { - m_scene.clear(); + m_scene->reset(); for (auto *item : items) - m_scene.addCurveItem(item); + m_scene->addCurveItem(item); applyZoom(m_zoomX, m_zoomY); viewport()->update(); @@ -241,49 +221,31 @@ void GraphicsView::reset(const std::vector<CurveItem *> &items) void GraphicsView::updateSelection(const std::vector<CurveItem *> &items) { - const std::vector<CurveItem *> pinnedItems = m_scene.takePinnedItems(); - auto notPinned = [pinnedItems](CurveItem *item) { - for (auto *pinned : pinnedItems) { - if (pinned->id() == item->id()) - return false; - } - return true; - }; - - m_scene.clear(); - for (auto *item : items) { - if (notPinned(item)) - m_scene.addCurveItem(item); + std::vector<CurveItem *> preservedItems = m_scene->takePinnedItems(); + for (auto *curve : items) { + auto finder = [curve](CurveItem *item) { return curve->id() == item->id(); }; + auto iter = std::find_if(preservedItems.begin(), preservedItems.end(), finder); + if (iter == preservedItems.end()) + preservedItems.push_back(curve); } - - for (auto *item : pinnedItems) - m_scene.addCurveItem(item); - - applyZoom(m_zoomX, m_zoomY); - viewport()->update(); + reset(preservedItems); } void GraphicsView::setInterpolation(Keyframe::Interpolation interpol) { - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *citem = qgraphicsitem_cast<CurveItem *>(item)) - if (citem->hasSelection()) - citem->setInterpolation(interpol); - } + const auto selectedCurves = m_scene->selectedCurves(); + for (auto *curve : selectedCurves) + curve->setInterpolation(interpol); viewport()->update(); } void GraphicsView::toggleUnified() { - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *citem = qgraphicsitem_cast<CurveItem *>(item)) { - if (citem->hasSelection()) - citem->toggleUnified(); - } - } + const auto selectedCurves = m_scene->selectedCurves(); + for (auto *curve : selectedCurves) + curve->toggleUnified(); + viewport()->update(); } @@ -299,7 +261,7 @@ void GraphicsView::keyPressEvent(QKeyEvent *event) if (shortcut == m_style.shortcuts.frameAll) applyZoom(0.0, 0.0); else if (shortcut == m_style.shortcuts.deleteKeyframe) - deleteSelectedKeyframes(); + m_scene->deleteSelectedKeyframes(); } void GraphicsView::mousePressEvent(QMouseEvent *event) @@ -309,7 +271,7 @@ void GraphicsView::mousePressEvent(QMouseEvent *event) Shortcut shortcut(event); if (shortcut == m_style.shortcuts.insertKeyframe) { - insertKeyframe(globalToRaster(event->globalPos()).x()); + m_scene->insertKeyframe(globalToRaster(event->globalPos()).x()); return; } @@ -325,7 +287,7 @@ void GraphicsView::mousePressEvent(QMouseEvent *event) QGraphicsView::mousePressEvent(event); - m_selector.mousePress(event, this); + m_selector.mousePress(event, this, m_scene); } void GraphicsView::mouseMoveEvent(QMouseEvent *event) @@ -335,7 +297,7 @@ void GraphicsView::mouseMoveEvent(QMouseEvent *event) QGraphicsView::mouseMoveEvent(event); - m_selector.mouseMove(event, this, m_playhead); + m_selector.mouseMove(event, this, m_scene, m_playhead); } void GraphicsView::mouseReleaseEvent(QMouseEvent *event) @@ -343,7 +305,7 @@ void GraphicsView::mouseReleaseEvent(QMouseEvent *event) QGraphicsView::mouseReleaseEvent(event); m_playhead.mouseRelease(this); - m_selector.mouseRelease(event, this); + m_selector.mouseRelease(event, m_scene); this->viewport()->update(); } @@ -371,16 +333,16 @@ void GraphicsView::contextMenuEvent(QContextMenuEvent *event) menu.addSeparator(); auto insertKeyframes = [this, event]() { - insertKeyframe(globalToRaster(event->globalPos()).x(), true); + m_scene->insertKeyframe(globalToRaster(event->globalPos()).x(), true); }; QAction *insertKeyframeAction = menu.addAction(tr("Insert Keyframe")); connect(insertKeyframeAction, &QAction::triggered, insertKeyframes); - auto deleteKeyframes = [this, event] { deleteSelectedKeyframes(); }; + auto deleteKeyframes = [this, event] { m_scene->deleteSelectedKeyframes(); }; QAction *deleteKeyframeAction = menu.addAction(tr("Delete Selected Keyframes")); connect(deleteKeyframeAction, &QAction::triggered, deleteKeyframes); - if (!hasSelectedKeyframe()) + if (!m_scene->hasSelectedKeyframe()) deleteKeyframeAction->setEnabled(false); menu.exec(event->globalPos()); @@ -445,7 +407,7 @@ QPointF GraphicsView::globalToRaster(const QPoint &point) const void GraphicsView::applyZoom(double x, double y, const QPoint &pivot) { - m_scene.doNotMoveItems(true); + m_scene->doNotMoveItems(true); QPointF pivotRaster(globalToRaster(pivot)); @@ -469,9 +431,9 @@ void GraphicsView::applyZoom(double x, double y, const QPoint &pivot) double scaleY = lerp(clamp(m_zoomY, 0.0, 1.0), -yZoomedOut, -yZoomedIn); m_transform = QTransform::fromScale(scaleX, scaleY); - m_scene.setComponentTransform(m_transform); + m_scene->setComponentTransform(m_transform); - QRectF sr = m_scene.sceneRect().adjusted( + QRectF sr = m_scene->rect().adjusted( -m_style.valueAxisWidth - m_style.canvasMargin, -m_style.timeAxisHeight - m_style.canvasMargin, m_style.canvasMargin, @@ -486,29 +448,7 @@ void GraphicsView::applyZoom(double x, double y, const QPoint &pivot) scrollContent(mapTimeToX(deltaTransformed.x()), mapValueToY(deltaTransformed.y())); } - m_scene.doNotMoveItems(false); -} - -void GraphicsView::insertKeyframe(double time, bool allVisibleCurves) -{ - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) { - if (allVisibleCurves) - curveItem->insertKeyframeByTime(std::round(time)); - else if (curveItem->isUnderMouse()) - curveItem->insertKeyframeByTime(std::round(time)); - } - } -} - -void GraphicsView::deleteSelectedKeyframes() -{ - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) - curveItem->deleteSelectedKeyframes(); - } + m_scene->doNotMoveItems(false); } void GraphicsView::drawGrid(QPainter *painter, const QRectF &rect) @@ -551,7 +491,7 @@ void GraphicsView::drawExtremaX(QPainter *painter, const QRectF &rect) void GraphicsView::drawExtremaY(QPainter *painter, const QRectF &rect) { - if (m_scene.empty()) + if (m_scene->empty()) return; auto drawHorizontalLine = [rect, painter](double position) { @@ -560,8 +500,8 @@ void GraphicsView::drawExtremaY(QPainter *painter, const QRectF &rect) painter->save(); painter->setPen(Qt::blue); - drawHorizontalLine(mapValueToY(m_scene.minimumValue())); - drawHorizontalLine(mapValueToY(m_scene.maximumValue())); + drawHorizontalLine(mapValueToY(m_scene->minimumValue())); + drawHorizontalLine(mapValueToY(m_scene->maximumValue())); painter->restore(); } diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h index 7100bbd29b..ca062416dd 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h @@ -52,16 +52,12 @@ signals: public: GraphicsView(CurveEditorModel *model, QWidget *parent = nullptr); + ~GraphicsView() override; + CurveEditorModel *model() const; CurveEditorStyle editorStyle() const; - bool hasActiveItem() const; - - bool hasActiveHandle() const; - - bool hasSelectedKeyframe() const; - int mapTimeToX(double time) const; int mapValueToY(double value) const; @@ -136,10 +132,6 @@ protected: private: void applyZoom(double x, double y, const QPoint &pivot = QPoint()); - void insertKeyframe(double time, bool allVisibleCurves = false); - - void deleteSelectedKeyframes(); - void drawGrid(QPainter *painter, const QRectF &rect); #if 0 @@ -167,7 +159,7 @@ private: QTransform m_transform; - GraphicsScene m_scene; + GraphicsScene *m_scene; CurveEditorModel *m_model; diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp index c0026c67f2..e6c8ced356 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp @@ -64,6 +64,22 @@ int HandleItem::type() const return Type; } +bool HandleItem::keyframeSelected() const +{ + if (auto *frame = keyframe()) + return frame->selected(); + + return false; +} + +KeyframeItem *HandleItem::keyframe() const +{ + if (KeyframeItem *parent = qgraphicsitem_cast<KeyframeItem *>(parentItem())) + return parent; + + return nullptr; +} + HandleItem::Slot HandleItem::slot() const { return m_slot; @@ -77,7 +93,7 @@ QRectF HandleItem::boundingRect() const bool HandleItem::contains(const QPointF &point) const { - if (KeyframeItem *parent = qgraphicsitem_cast<KeyframeItem *>(parentItem())) { + if (KeyframeItem *parent = keyframe()) { HandleGeometry geom(pos(), m_style); geom.handle.moveCenter(parent->pos() + pos()); return geom.handle.contains(point); @@ -130,7 +146,7 @@ void HandleItem::setStyle(const CurveEditorStyle &style) QVariant HandleItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionChange) { - if (qgraphicsitem_cast<KeyframeItem *>(parentItem())) { + if (keyframe()) { QPointF pos = value.toPointF(); if (m_slot == HandleItem::Slot::Left) { if (pos.x() > 0.0) diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.h index e5854f4677..f8349ac475 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.h @@ -30,6 +30,8 @@ namespace DesignTools { +class KeyframeItem; + class HandleItem : public SelectableItem { Q_OBJECT @@ -53,6 +55,10 @@ public: void underMouseCallback() override; + bool keyframeSelected() const; + + KeyframeItem *keyframe() const; + Slot slot() const; void setStyle(const CurveEditorStyle &style); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp index bc8bd2f0e6..b0cfa5e7b6 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp @@ -116,6 +116,27 @@ bool KeyframeItem::hasRightHandle() const return m_frame.hasRightHandle(); } +bool KeyframeItem::hasActiveHandle() const +{ + if (m_left && m_left->activated()) + return true; + + if (m_right && m_right->activated()) + return true; + + return false; +} + +HandleItem *KeyframeItem::leftHandle() const +{ + return m_left; +} + +HandleItem *KeyframeItem::rightHandle() const +{ + return m_right; +} + QTransform KeyframeItem::transform() const { return m_transform; diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h index b6807a1232..bb91f64565 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h @@ -72,6 +72,12 @@ public: bool hasRightHandle() const; + bool hasActiveHandle() const; + + HandleItem *leftHandle() const; + + HandleItem *rightHandle() const; + QTransform transform() const; void setHandleVisibility(bool visible); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.cpp index f6d569def0..40500427b0 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.cpp @@ -83,7 +83,6 @@ SelectableItem::SelectableItem(QGraphicsItem *parent) : CurveEditorItem(parent) , m_active(false) , m_selected(false) - , m_locked(false) , m_preSelected(SelectionMode::Undefined) { setFlag(QGraphicsItem::ItemIsSelectable, false); @@ -139,7 +138,7 @@ void SelectableItem::setSelected(bool selected) void SelectableItem::setPreselected(SelectionMode mode) { - if (m_locked) + if (locked()) return; m_preSelected = mode; @@ -158,7 +157,7 @@ void SelectableItem::selectionCallback() {} void SelectableItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { - if (m_locked) + if (locked()) return; m_active = true; @@ -168,7 +167,7 @@ void SelectableItem::mousePressEvent(QGraphicsSceneMouseEvent *event) void SelectableItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - if (m_locked) + if (locked()) return; if (type() == KeyframeItem::Type && !selected()) @@ -179,7 +178,7 @@ void SelectableItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void SelectableItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { - if (m_locked) + if (locked()) return; m_active = false; diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.h index 1a10c5c7a0..920c13a938 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.h @@ -99,8 +99,6 @@ private: bool m_selected; - bool m_locked; - SelectionMode m_preSelected; }; diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp index 632039c865..82f2125413 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp @@ -23,6 +23,7 @@ ** ****************************************************************************/ #include "selector.h" +#include "graphicsscene.h" #include "graphicsview.h" #include "keyframeitem.h" #include "playhead.h" @@ -55,29 +56,40 @@ void Selector::paint(QPainter *painter) painter->restore(); } -void Selector::mousePress(QMouseEvent *event, GraphicsView *view) +void Selector::mousePress(QMouseEvent *event, GraphicsView *view, GraphicsScene *scene) { m_shortcut = Shortcut(event); - if (view->hasActiveHandle()) - return; + QPointF click = view->globalToScene(event->globalPos()); - m_mouseInit = event->globalPos(); - m_mouseCurr = event->globalPos(); + if (SelectableItem *sitem = scene->intersect(click)) { + KeyframeItem *kitem = qobject_cast<KeyframeItem *>(sitem); + if (HandleItem *hitem = qobject_cast<HandleItem *>(sitem)) + kitem = hitem->keyframe(); - QPointF click = view->globalToScene(m_mouseInit); + if (!kitem->selected()) { + if (select(SelectionTool::Undefined, click, scene)) + applyPreSelection(scene); + } + } else { + if (select(SelectionTool::Undefined, click, scene)) + applyPreSelection(scene); - if (!isOverSelectedKeyframe(click, view)) - if (select(SelectionTool::Undefined, click, view)) - applyPreSelection(view); + // Init selection tools. + m_mouseInit = event->globalPos(); + m_mouseCurr = event->globalPos(); - m_lasso = QPainterPath(click); - m_lasso.closeSubpath(); + m_lasso = QPainterPath(click); + m_lasso.closeSubpath(); - m_rect = QRectF(click, click); + m_rect = QRectF(click, click); + } } -void Selector::mouseMove(QMouseEvent *event, GraphicsView *view, Playhead &playhead) +void Selector::mouseMove(QMouseEvent *event, + GraphicsView *view, + GraphicsScene *scene, + Playhead &playhead) { if (m_mouseInit.isNull()) return; @@ -89,10 +101,10 @@ void Selector::mouseMove(QMouseEvent *event, GraphicsView *view, Playhead &playh if (m_shortcut == m_shortcuts.newSelection || m_shortcut == m_shortcuts.addToSelection || m_shortcut == m_shortcuts.removeFromSelection || m_shortcut == m_shortcuts.toggleSelection) { - if (view->hasActiveItem()) + if (scene->hasActiveItem()) return; - select(m_tool, view->globalToScene(event->globalPos()), view); + select(m_tool, view->globalToScene(event->globalPos()), scene); event->accept(); view->viewport()->update(); @@ -111,11 +123,11 @@ void Selector::mouseMove(QMouseEvent *event, GraphicsView *view, Playhead &playh } } -void Selector::mouseRelease(QMouseEvent *event, GraphicsView *view) +void Selector::mouseRelease(QMouseEvent *event, GraphicsScene *scene) { Q_UNUSED(event) - applyPreSelection(view); + applyPreSelection(scene); m_shortcut = Shortcut(); m_mouseInit = QPoint(); @@ -124,50 +136,73 @@ void Selector::mouseRelease(QMouseEvent *event, GraphicsView *view) m_rect = QRectF(); } -bool Selector::isOverSelectedKeyframe(const QPointF &pos, GraphicsView *view) +bool Selector::isOverMovableItem(const QPointF &pos, GraphicsScene *scene) { - const auto itemList = view->items(); - for (auto *item : itemList) { - if (auto *frame = qgraphicsitem_cast<KeyframeItem *>(item)) { - QRectF itemRect = frame->mapRectToScene(frame->boundingRect()); - if (itemRect.contains(pos)) - return frame->selected(); + auto intersect = [pos](QGraphicsObject *item) { + return item->mapRectToScene(item->boundingRect()).contains(pos); + }; + + const auto frames = scene->keyframes(); + for (auto *frame : frames) { + if (intersect(frame)) + return true; + + if (auto *leftHandle = frame->leftHandle()) { + if (intersect(leftHandle)) + return true; } + + if (auto *rightHandle = frame->rightHandle()) { + if (intersect(rightHandle)) + return true; + } + } + return false; +} + +bool Selector::isOverSelectedKeyframe(const QPointF &pos, GraphicsScene *scene) +{ + const auto frames = scene->selectedKeyframes(); + for (auto *frame : frames) { + QRectF frameRect = frame->mapRectToScene(frame->boundingRect()); + if (frameRect.contains(pos)) + return true; } return false; } -bool Selector::select(const SelectionTool &tool, const QPointF &pos, GraphicsView *view) +bool Selector::select(const SelectionTool &tool, const QPointF &pos, GraphicsScene *scene) { - auto selectWidthTool = [this, tool](SelectionMode mode, const QPointF &pos, GraphicsView *view) { + auto selectWidthTool = [this, + tool](SelectionMode mode, const QPointF &pos, GraphicsScene *scene) { switch (tool) { case SelectionTool::Lasso: - return lassoSelection(mode, pos, view); + return lassoSelection(mode, pos, scene); case SelectionTool::Rectangle: - return rectangleSelection(mode, pos, view); + return rectangleSelection(mode, pos, scene); default: - return pressSelection(mode, pos, view); + return pressSelection(mode, pos, scene); } }; if (m_shortcut == m_shortcuts.newSelection) { - clearSelection(view); - return selectWidthTool(SelectionMode::New, pos, view); + clearSelection(scene); + return selectWidthTool(SelectionMode::New, pos, scene); } else if (m_shortcut == m_shortcuts.addToSelection) { - return selectWidthTool(SelectionMode::Add, pos, view); + return selectWidthTool(SelectionMode::Add, pos, scene); } else if (m_shortcut == m_shortcuts.removeFromSelection) { - return selectWidthTool(SelectionMode::Remove, pos, view); + return selectWidthTool(SelectionMode::Remove, pos, scene); } else if (m_shortcut == m_shortcuts.toggleSelection) { - return selectWidthTool(SelectionMode::Toggle, pos, view); + return selectWidthTool(SelectionMode::Toggle, pos, scene); } return false; } -bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view) +bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene) { bool out = false; - const auto itemList = view->items(); + const auto itemList = scene->items(); for (auto *item : itemList) { if (auto *frame = qgraphicsitem_cast<KeyframeItem *>(item)) { QRectF itemRect = frame->mapRectToScene(frame->boundingRect()); @@ -176,15 +211,25 @@ bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsVi out = true; } } + + if (auto *handle = qgraphicsitem_cast<HandleItem *>(item)) { + QRectF itemRect = handle->mapRectToScene(handle->boundingRect()); + if (itemRect.contains(pos)) { + if (auto *frame = handle->keyframe()) { + frame->setPreselected(mode); + out = true; + } + } + } } return out; } -bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view) +bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene) { bool out = false; m_rect.setBottomRight(pos); - const auto itemList = view->items(); + const auto itemList = scene->items(); for (auto *item : itemList) { if (auto *keyframeItem = qgraphicsitem_cast<KeyframeItem *>(item)) { if (m_rect.contains(keyframeItem->pos())) { @@ -198,11 +243,11 @@ bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, Graphi return out; } -bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view) +bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene) { bool out = false; m_lasso.lineTo(pos); - const auto itemList = view->items(); + const auto itemList = scene->items(); for (auto *item : itemList) { if (auto *keyframeItem = qgraphicsitem_cast<KeyframeItem *>(item)) { if (m_lasso.contains(keyframeItem->pos())) { @@ -216,20 +261,22 @@ bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsVi return out; } -void Selector::clearSelection(GraphicsView *view) +void Selector::clearSelection(GraphicsScene *scene) { - const auto itemList = view->items(); + const auto itemList = scene->items(); for (auto *item : itemList) { if (auto *frameItem = qgraphicsitem_cast<KeyframeItem *>(item)) { frameItem->setPreselected(SelectionMode::Clear); frameItem->applyPreselection(); + frameItem->setActivated(false, HandleItem::Slot::Left); + frameItem->setActivated(false, HandleItem::Slot::Right); } } } -void Selector::applyPreSelection(GraphicsView *view) +void Selector::applyPreSelection(GraphicsScene *scene) { - const auto itemList = view->items(); + const auto itemList = scene->items(); for (auto *item : itemList) { if (auto *keyframeItem = qgraphicsitem_cast<KeyframeItem *>(item)) keyframeItem->applyPreselection(); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selector.h b/src/plugins/qmldesigner/components/curveeditor/detail/selector.h index 8077f8da3c..5b72243908 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selector.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selector.h @@ -31,6 +31,7 @@ namespace DesignTools { class GraphicsView; +class GraphicsScene; class Playhead; enum class SelectionTool { Undefined, Lasso, Rectangle }; @@ -42,26 +43,28 @@ public: void paint(QPainter *painter); - void mousePress(QMouseEvent *event, GraphicsView *view); + void mousePress(QMouseEvent *event, GraphicsView *view, GraphicsScene *scene); - void mouseMove(QMouseEvent *event, GraphicsView *view, Playhead &playhead); + void mouseMove(QMouseEvent *event, GraphicsView *view, GraphicsScene *scene, Playhead &playhead); - void mouseRelease(QMouseEvent *event, GraphicsView *view); + void mouseRelease(QMouseEvent *event, GraphicsScene *scene); private: - bool isOverSelectedKeyframe(const QPointF &pos, GraphicsView *view); + bool isOverSelectedKeyframe(const QPointF &pos, GraphicsScene *scene); - bool select(const SelectionTool &tool, const QPointF &pos, GraphicsView *view); + bool isOverMovableItem(const QPointF &pos, GraphicsScene *scene); - bool pressSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view); + bool select(const SelectionTool &tool, const QPointF &pos, GraphicsScene *scene); - bool rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view); + bool pressSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene); - bool lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view); + bool rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene); - void clearSelection(GraphicsView *view); + bool lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene); - void applyPreSelection(GraphicsView *view); + void clearSelection(GraphicsScene *scene); + + void applyPreSelection(GraphicsScene *scene); Shortcuts m_shortcuts; diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/utils.h b/src/plugins/qmldesigner/components/curveeditor/detail/utils.h index 9142435ea4..4a236c76b9 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/utils.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/utils.h @@ -50,7 +50,7 @@ QRectF bbox(const QRectF &rect, const QTransform &transform); QPalette singleColorPalette(const QColor &color); template<typename T> -inline void freeClear(std::vector<T *> &vec) +inline void freeClear(T &vec) { for (auto *&el : vec) delete el; diff --git a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp index 70f382e859..ad4d02df89 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp @@ -26,7 +26,7 @@ #include "setframevaluedialog.h" #include "ui_setframevaluedialog.h" -#include <QIntValidator> +#include <QtGui/qvalidator.h> namespace QmlDesigner { @@ -40,9 +40,13 @@ SetFrameValueDialog::SetFrameValueDialog(qreal frame, const QVariant &value, setFixedSize(size()); ui->lineEditFrame->setValidator(new QIntValidator(0, 99999, this)); + auto dv = new QDoubleValidator(this); + dv->setDecimals(2); + ui->lineEditValue->setValidator(dv); - ui->lineEditFrame->setText(QString::number(frame)); - ui->lineEditValue->setText(value.toString()); + QLocale l; + ui->lineEditFrame->setText(l.toString(qRound(frame))); + ui->lineEditValue->setText(l.toString(value.toDouble(), 'f', 2)); ui->labelValue->setText(propertyName); } @@ -53,12 +57,14 @@ SetFrameValueDialog::~SetFrameValueDialog() qreal SetFrameValueDialog::frame() const { - return ui->lineEditFrame->text().toDouble(); + QLocale l; + return l.toDouble(ui->lineEditFrame->text()); } QVariant SetFrameValueDialog::value() const { - return QVariant(ui->lineEditValue->text()); + QLocale l; + return QVariant(l.toDouble(ui->lineEditValue->text())); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp index 3ba547742a..07ee742c84 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp @@ -367,11 +367,18 @@ void QmlObjectNode::destroy() stateOperation.modelNode().destroy(); //remove of belonging StatesOperations } - for (const ModelNode &timelineNode : view()->allModelNodes()) { - if (QmlTimeline::isValidQmlTimeline(timelineNode)) { - QmlTimeline timeline(timelineNode); - timeline.destroyKeyframesForTarget(modelNode()); - } + QVector<ModelNode> timelineNodes; + const auto allNodes = view()->allModelNodes(); + for (const auto &timelineNode : allNodes) { + if (QmlTimeline::isValidQmlTimeline(timelineNode)) + timelineNodes.append(timelineNode); + } + + const auto subNodes = modelNode().allSubModelNodesAndThisNode(); + for (auto &timelineNode : qAsConst(timelineNodes)) { + QmlTimeline timeline(timelineNode); + for (const auto &subNode : subNodes) + timeline.destroyKeyframesForTarget(subNode); } if (QmlFlowActionAreaNode::isValidQmlFlowActionAreaNode(modelNode())) diff --git a/src/plugins/qtsupport/exampleslistmodel.cpp b/src/plugins/qtsupport/exampleslistmodel.cpp index a5bf950bf5..96bfa90629 100644 --- a/src/plugins/qtsupport/exampleslistmodel.cpp +++ b/src/plugins/qtsupport/exampleslistmodel.cpp @@ -107,6 +107,7 @@ ExampleSetModel::ExampleSetModel() << ", examplesPath=" << set.examplesPath; } } + m_extraExampleSets += pluginRegisteredExampleSets(); connect(QtVersionManager::instance(), &QtVersionManager::qtVersionsLoaded, this, &ExampleSetModel::qtVersionManagerLoaded); diff --git a/src/plugins/qtsupport/exampleslistmodel.h b/src/plugins/qtsupport/exampleslistmodel.h index ad86b12e66..a371e8bc0b 100644 --- a/src/plugins/qtsupport/exampleslistmodel.h +++ b/src/plugins/qtsupport/exampleslistmodel.h @@ -45,6 +45,14 @@ class ExampleSetModel : public QStandardItemModel Q_OBJECT public: + struct ExtraExampleSet + { + QString displayName; + QString manifestPath; + QString examplesPath; + }; + static QVector<ExtraExampleSet> pluginRegisteredExampleSets(); + ExampleSetModel(); int selectedExampleSet() const { return m_selectedExampleSetIndex; } @@ -56,11 +64,6 @@ signals: void selectedExampleSetChanged(int); private: - struct ExtraExampleSet { - QString displayName; - QString manifestPath; - QString examplesPath; - }; enum ExampleSetType { InvalidExampleSet, @@ -87,8 +90,7 @@ private: void helpManagerInitialized(); void tryToInitialize(); - QList<ExtraExampleSet> m_extraExampleSets; - QList<BaseQtVersion*> m_qtVersions; + QVector<ExtraExampleSet> m_extraExampleSets; int m_selectedExampleSetIndex = -1; QSet<Core::Id> m_selectedQtTypes; diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index 82d2fb9e2d..4616ec9e51 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -25,10 +25,11 @@ #include "qtversionmanager.h" -#include "qtkitinformation.h" -#include "qtversionfactory.h" #include "baseqtversion.h" +#include "exampleslistmodel.h" +#include "qtkitinformation.h" #include "qtsupportconstants.h" +#include "qtversionfactory.h" #include <coreplugin/icore.h> #include <coreplugin/helpmanager.h> @@ -77,6 +78,7 @@ static QtVersionManager *m_instance = nullptr; static FileSystemWatcher *m_configFileWatcher = nullptr; static QTimer *m_fileWatcherTimer = nullptr; static PersistentSettingsWriter *m_writer = nullptr; +static QVector<ExampleSetModel::ExtraExampleSet> m_pluginRegisteredExampleSets; static Q_LOGGING_CATEGORY(log, "qtc.qt.versions", QtWarningMsg); @@ -100,6 +102,11 @@ static bool restoreQtVersions(); static void findSystemQt(); static void saveQtVersions(); +QVector<ExampleSetModel::ExtraExampleSet> ExampleSetModel::pluginRegisteredExampleSets() +{ + return m_pluginRegisteredExampleSets; +} + // -------------------------------------------------------------------------- // QtVersionManager // -------------------------------------------------------------------------- @@ -471,6 +478,13 @@ void QtVersionManager::removeVersion(BaseQtVersion *version) delete version; } +void QtVersionManager::registerExampleSet(const QString &displayName, + const QString &manifestPath, + const QString &examplesPath) +{ + m_pluginRegisteredExampleSets.append({displayName, manifestPath, examplesPath}); +} + using Path = QString; using FileName = QString; static QList<std::pair<Path, FileName>> documentationFiles(BaseQtVersion *v) diff --git a/src/plugins/qtsupport/qtversionmanager.h b/src/plugins/qtsupport/qtversionmanager.h index 7f71547b49..a5bf92d7d1 100644 --- a/src/plugins/qtsupport/qtversionmanager.h +++ b/src/plugins/qtsupport/qtversionmanager.h @@ -63,6 +63,11 @@ public: static void addVersion(BaseQtVersion *version); static void removeVersion(BaseQtVersion *version); + // Call latest in extensionsInitialized of plugin depending on QtSupport + static void registerExampleSet(const QString &displayName, + const QString &manifestPath, + const QString &examplesPath); + signals: // content of BaseQtVersion objects with qmake path might have changed void qtVersionsChanged(const QList<int> &addedIds, const QList<int> &removedIds, const QList<int> &changedIds); diff --git a/src/plugins/vcsbase/vcsoutputformatter.cpp b/src/plugins/vcsbase/vcsoutputformatter.cpp index b6ad20304c..cf2c167119 100644 --- a/src/plugins/vcsbase/vcsoutputformatter.cpp +++ b/src/plugins/vcsbase/vcsoutputformatter.cpp @@ -38,7 +38,7 @@ VcsOutputFormatter::VcsOutputFormatter() : m_regexp( "(https?://\\S*)" // https://codereview.org/c/1234 "|(v[0-9]+\\.[0-9]+\\.[0-9]+[\\-A-Za-z0-9]*)" // v0.1.2-beta3 - "|([0-9a-f]{6,}(?:\\.\\.[0-9a-f]{6,}" // 789acf or 123abc..456cde + "|([0-9a-f]{6,}(?:\\.{2,3}[0-9a-f]{6,}" // 789acf or 123abc..456cde "|\\^+|~\\d+)?)") // or 789acf^ or 123abc~99 { } |