diff --git a/src/plugins/qmlprofiler/qml/MainView.qml b/src/plugins/qmlprofiler/qml/MainView.qml index a7ff62b13e6..01efafec0ac 100644 --- a/src/plugins/qmlprofiler/qml/MainView.qml +++ b/src/plugins/qmlprofiler/qml/MainView.qml @@ -50,6 +50,8 @@ Rectangle { property alias selectionLocked : view.selectionLocked signal updateLockButton property alias selectedItem: view.selectedItem + signal selectedEventIdChanged(int eventId) + property bool lockItemSelection : false property variant names: [ qsTr("Painting"), qsTr("Compiling"), qsTr("Creating"), qsTr("Binding"), qsTr("Handling Signal")] property variant colors : [ "#99CCB3", "#99CCCC", "#99B3CC", "#9999CC", "#CC99B3", "#CC99CC", "#CCCC99", "#CCB399" ] @@ -224,6 +226,9 @@ Rectangle { function recenterOnItem( itemIndex ) { + if (itemIndex === -1) + return; + // if item is outside of the view, jump back to its position if (qmlEventList.getEndTime(itemIndex) < view.startTime || qmlEventList.getStartTime(itemIndex) > view.endTime) { recenter((qmlEventList.getStartTime(itemIndex) + qmlEventList.getEndTime(itemIndex)) / 2); @@ -252,6 +257,23 @@ Rectangle { rangeDetails.line = -1; } + function selectNextWithId( eventId ) + { + if (!lockItemSelection) { + lockItemSelection = true; + var itemIndex = view.nextItemFromId( eventId ); + // select an item, lock to it, and recenter if necessary + if (view.selectedItem != itemIndex) { + view.selectedItem = itemIndex; + if (itemIndex !== -1) { + view.selectionLocked = true; + recenterOnItem(itemIndex); + } + } + lockItemSelection = false; + } + } + // ***** slots onSelectionRangeModeChanged: { selectionRangeControl.enabled = selectionRangeMode; @@ -262,6 +284,14 @@ Rectangle { updateLockButton(); } + onSelectedItemChanged: { + if (selectedItem != -1 && !lockItemSelection) { + lockItemSelection = true; + selectedEventIdChanged( qmlEventList.getEventId(selectedItem) ); + lockItemSelection = false; + } + } + // ***** child items Timer { id: elapsedTimer diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.cpp b/src/plugins/qmlprofiler/qmlprofilereventview.cpp index 8d51a0b4f5f..b5b1ee1eae9 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilereventview.cpp @@ -87,6 +87,7 @@ QmlProfilerEventsWidget::QmlProfilerEventsWidget(QmlJsDebugClient::QmlProfilerEv m_eventTree = new QmlProfilerEventsMainView(model, this); m_eventTree->setViewType(QmlProfilerEventsMainView::EventsView); connect(m_eventTree, SIGNAL(gotoSourceLocation(QString,int)), this, SIGNAL(gotoSourceLocation(QString,int))); + connect(m_eventTree, SIGNAL(showEventInTimeline(int)), this, SIGNAL(showEventInTimeline(int))); m_eventChildren = new QmlProfilerEventsParentsAndChildrenView(model, QmlProfilerEventsParentsAndChildrenView::ChildrenView, this); m_eventParents = new QmlProfilerEventsParentsAndChildrenView(model, QmlProfilerEventsParentsAndChildrenView::ParentsView, this); @@ -171,6 +172,12 @@ void QmlProfilerEventsWidget::copyRowToClipboard() const m_eventTree->copyRowToClipboard(); } +void QmlProfilerEventsWidget::updateSelectedEvent(int eventId) const +{ + if (m_eventTree->selectedEventId() != eventId) + m_eventTree->selectEvent(eventId); +} + //////////////////////////////////////////////////////////////////////////////////// class QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate @@ -546,6 +553,16 @@ void QmlProfilerEventsMainView::getStatisticsInRange(qint64 rangeStart, qint64 r buildModel(); } +int QmlProfilerEventsMainView::selectedEventId() const +{ + QModelIndex index = selectedItem(); + if (!index.isValid()) + return -1; + QStandardItem *item = d->m_model->item(index.row(), 0); + return item->data(EventIdRole).toInt(); +} + + void QmlProfilerEventsMainView::jumpToItem(const QModelIndex &index) { QStandardItem *clickedItem = d->m_model->itemFromIndex(index); @@ -555,12 +572,19 @@ void QmlProfilerEventsMainView::jumpToItem(const QModelIndex &index) else infoItem = d->m_model->item(index.row(), 0); + // show in editor int line = infoItem->data(LineRole).toInt(); QString fileName = infoItem->data(FilenameRole).toString(); if (line!=-1 && !fileName.isEmpty()) emit gotoSourceLocation(fileName, line); + // show in callers/callees subwindow emit eventSelected(infoItem->data(EventIdRole).toInt()); + + // show in timelineview + if (d->m_viewType == EventsView) { + emit showEventInTimeline(infoItem->data(EventIdRole).toInt()); + } } void QmlProfilerEventsMainView::selectEvent(int eventId) diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.h b/src/plugins/qmlprofiler/qmlprofilereventview.h index 580cc5b44a3..f77940cd39d 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventview.h +++ b/src/plugins/qmlprofiler/qmlprofilereventview.h @@ -73,6 +73,10 @@ public: signals: void gotoSourceLocation(const QString &fileName, int lineNumber); void contextMenuRequested(const QPoint &position); + void showEventInTimeline(int eventId); + +public slots: + void updateSelectedEvent(int eventId) const; protected: void contextMenuEvent(QContextMenuEvent *ev); @@ -130,10 +134,12 @@ public: static QString nameForType(int typeNumber); void getStatisticsInRange(qint64 rangeStart, qint64 rangeEnd); + int selectedEventId() const; signals: void gotoSourceLocation(const QString &fileName, int lineNumber); void eventSelected(int eventId); + void showEventInTimeline(int eventId); public slots: void clear(); diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index c2d93ca8b4d..5ce880af1bb 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -338,6 +338,8 @@ QWidget *QmlProfilerTool::createWidgets() d->m_eventsView = new QmlProfilerEventsWidget(d->m_traceWindow->getEventList(), mw); connect(d->m_eventsView, SIGNAL(gotoSourceLocation(QString,int)), this, SLOT(gotoSourceLocation(QString,int))); connect(d->m_eventsView, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); + connect(d->m_eventsView, SIGNAL(showEventInTimeline(int)), d->m_traceWindow, SLOT(selectNextEvent(int))); + connect(d->m_traceWindow, SIGNAL(selectedEventIdChanged(int)), d->m_eventsView, SLOT(updateSelectedEvent(int))); d->m_v8profilerView = new QmlProfilerEventsWidget(d->m_traceWindow->getEventList(), mw); d->m_v8profilerView->switchToV8View(); diff --git a/src/plugins/qmlprofiler/timelineview.cpp b/src/plugins/qmlprofiler/timelineview.cpp index 4e3b732aae6..d578adaa798 100644 --- a/src/plugins/qmlprofiler/timelineview.cpp +++ b/src/plugins/qmlprofiler/timelineview.cpp @@ -328,6 +328,24 @@ QString TimelineView::getDetails(int index) const return m_eventList->getDetails(index); } +int TimelineView::nextItemFromId(int eventId) const +{ + int ndx = -1; + if (m_selectedItem == -1) + ndx = m_eventList->findFirstIndexNoParents(m_startTime); + else + ndx = m_selectedItem + 1; + if (ndx >= m_eventList->count()) + ndx = 0; + int startIndex = ndx; + do { + if (m_eventList->getEventId(ndx) == eventId) + return ndx; + ndx = (ndx+1) % m_eventList->count(); + } while (ndx != startIndex); + return -1; +} + void TimelineView::rowExpanded(int rowIndex, bool expanded) { m_rowsExpanded[rowIndex] = expanded; diff --git a/src/plugins/qmlprofiler/timelineview.h b/src/plugins/qmlprofiler/timelineview.h index 2830b503f79..17b945bcd8f 100644 --- a/src/plugins/qmlprofiler/timelineview.h +++ b/src/plugins/qmlprofiler/timelineview.h @@ -101,6 +101,8 @@ public: Q_INVOKABLE int getLine(int index) const; Q_INVOKABLE QString getDetails(int index) const; + Q_INVOKABLE int nextItemFromId(int eventId) const; + signals: void startTimeChanged(qint64 arg); void endTimeChanged(qint64 arg); diff --git a/src/plugins/qmlprofiler/tracewindow.cpp b/src/plugins/qmlprofiler/tracewindow.cpp index 18b18a13472..71401446575 100644 --- a/src/plugins/qmlprofiler/tracewindow.cpp +++ b/src/plugins/qmlprofiler/tracewindow.cpp @@ -283,6 +283,8 @@ void TraceWindow::reset(QDeclarativeDebugConnection *conn) connect(this, SIGNAL(updateViewZoom(QVariant)), m_mainView->rootObject(), SLOT(updateWindowLength(QVariant))); connect(this, SIGNAL(wheelZoom(QVariant,QVariant)), m_mainView->rootObject(), SLOT(wheelZoom(QVariant,QVariant))); connect(this, SIGNAL(globalZoom()), m_mainView->rootObject(), SLOT(globalZoom())); + connect(this, SIGNAL(selectNextEventInDisplay(QVariant)), m_mainView->rootObject(), SLOT(selectNextWithId(QVariant))); + connect(m_mainView->rootObject(), SIGNAL(selectedEventIdChanged(int)), this, SIGNAL(selectedEventIdChanged(int))); connect(this, SIGNAL(internalClearDisplay()), m_mainView->rootObject(), SLOT(clearAll())); connect(this,SIGNAL(internalClearDisplay()), m_overview->rootObject(), SLOT(clearDisplay())); @@ -488,5 +490,10 @@ void TraceWindow::updateRange() } } +void TraceWindow::selectNextEvent(int eventId) +{ + emit selectNextEventInDisplay(QVariant(eventId)); +} + } // namespace Internal } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/tracewindow.h b/src/plugins/qmlprofiler/tracewindow.h index 6ca931fe838..f9a9ace8ff2 100644 --- a/src/plugins/qmlprofiler/tracewindow.h +++ b/src/plugins/qmlprofiler/tracewindow.h @@ -116,6 +116,7 @@ public slots: void qmlComplete(); void v8Complete(); + void selectNextEvent(int eventId); signals: void viewUpdated(); @@ -139,6 +140,8 @@ signals: void globalZoom(); void contextMenuRequested(const QPoint& position); + void selectNextEventInDisplay(QVariant eventId); + void selectedEventIdChanged(int eventId); private: void contextMenuEvent(QContextMenuEvent *);