forked from qt-creator/qt-creator
QmlProfiler: show a warning if unsaved notes are to be discarded
Change-Id: I5152f0eefd1f0beec2b0f4fc9e27fedeb3bf7a14 Task-number: QTCREATORBUG-13318 Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com> Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace QmlProfiler {
|
||||
|
||||
NotesModel::NotesModel(QObject *parent) : QObject(parent), m_modelManager(0)
|
||||
NotesModel::NotesModel(QObject *parent) : QObject(parent), m_modelManager(0), m_modified(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ int NotesModel::add(int timelineModel, int timelineIndex, const QString &text)
|
||||
int typeId = model->range(timelineIndex).typeId;
|
||||
Note note = { text, timelineModel, timelineIndex };
|
||||
m_data << note;
|
||||
m_modified = true;
|
||||
emit changed(typeId, timelineModel, timelineIndex);
|
||||
return m_data.count() - 1;
|
||||
}
|
||||
@@ -123,6 +124,7 @@ void NotesModel::update(int index, const QString &text)
|
||||
Note ¬e = m_data[index];
|
||||
if (text != note.text) {
|
||||
note.text = text;
|
||||
m_modified = true;
|
||||
emit changed(typeId(index), note.timelineModel, note.timelineIndex);
|
||||
}
|
||||
}
|
||||
@@ -134,9 +136,15 @@ void NotesModel::remove(int index)
|
||||
int timelineModel = note.timelineModel;
|
||||
int timelineIndex = note.timelineIndex;
|
||||
m_data.removeAt(index);
|
||||
m_modified = true;
|
||||
emit changed(noteType, timelineModel, timelineIndex);
|
||||
}
|
||||
|
||||
bool NotesModel::isModified() const
|
||||
{
|
||||
return m_modified;
|
||||
}
|
||||
|
||||
void NotesModel::removeTimelineModel(QObject *timelineModel)
|
||||
{
|
||||
for (auto i = m_timelineModels.begin(); i != m_timelineModels.end();) {
|
||||
@@ -176,12 +184,14 @@ int NotesModel::add(int typeId, qint64 start, qint64 duration, const QString &te
|
||||
|
||||
Note note = { text, timelineModel, timelineIndex };
|
||||
m_data << note;
|
||||
m_modified = true;
|
||||
return m_data.count() - 1;
|
||||
}
|
||||
|
||||
void NotesModel::clear()
|
||||
{
|
||||
m_data.clear();
|
||||
m_modified = false;
|
||||
emit changed(-1, -1, -1);
|
||||
}
|
||||
|
||||
@@ -194,6 +204,7 @@ void NotesModel::loadData()
|
||||
const QmlProfilerDataModel::QmlEventNoteData ¬e = notes[i];
|
||||
add(note.typeIndex, note.startTime, note.duration, note.text);
|
||||
}
|
||||
m_modified = false; // reset after loading
|
||||
emit changed(-1, -1, -1);
|
||||
}
|
||||
|
||||
@@ -213,5 +224,6 @@ void NotesModel::saveData()
|
||||
notes.append(save);
|
||||
}
|
||||
m_modelManager->qmlModel()->setNoteData(notes);
|
||||
m_modified = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,9 +68,11 @@ public:
|
||||
int add(int timelineModel, int timelineIndex, const QString &text);
|
||||
void update(int index, const QString &text);
|
||||
void remove(int index);
|
||||
bool isModified() const;
|
||||
|
||||
void loadData();
|
||||
void saveData();
|
||||
void clear();
|
||||
|
||||
signals:
|
||||
void changed(int typeId, int timelineModel, int timelineIndex);
|
||||
@@ -82,9 +84,9 @@ protected:
|
||||
QmlProfilerModelManager *m_modelManager;
|
||||
QList<Note> m_data;
|
||||
QHash<int, const AbstractTimelineModel *> m_timelineModels;
|
||||
bool m_modified;
|
||||
|
||||
int add(int typeId, qint64 startTime, qint64 duration, const QString &text);
|
||||
void clear();
|
||||
};
|
||||
}
|
||||
#endif // NOTESMODEL_H
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace QmlProfiler {
|
||||
namespace Internal {
|
||||
@@ -447,6 +448,7 @@ void QmlProfilerModelManager::clear()
|
||||
d->model->clear();
|
||||
d->v8Model->clear();
|
||||
d->traceTime->clear();
|
||||
d->notesModel->clear();
|
||||
|
||||
setState(QmlProfilerDataState::Empty);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "qmlprofilermodelmanager.h"
|
||||
#include "qmlprofilerdetailsrewriter.h"
|
||||
#include "timelinerenderer.h"
|
||||
#include "notesmodel.h"
|
||||
|
||||
#include <analyzerbase/analyzermanager.h>
|
||||
#include <analyzerbase/analyzerruncontrol.h>
|
||||
@@ -272,7 +273,10 @@ QWidget *QmlProfilerTool::createWidgets()
|
||||
d->m_clearButton->setIcon(QIcon(QLatin1String(":/qmlprofiler/clean_pane_small.png")));
|
||||
d->m_clearButton->setToolTip(tr("Discard data"));
|
||||
|
||||
connect(d->m_clearButton,SIGNAL(clicked()), this, SLOT(clearData()));
|
||||
connect(d->m_clearButton, &QAbstractButton::clicked, [this](){
|
||||
if (checkForUnsavedNotes())
|
||||
clearData();
|
||||
});
|
||||
|
||||
layout->addWidget(d->m_clearButton);
|
||||
|
||||
@@ -324,7 +328,16 @@ void QmlProfilerTool::populateFileFinder(QString projectDirectory, QString activ
|
||||
|
||||
void QmlProfilerTool::recordingButtonChanged(bool recording)
|
||||
{
|
||||
d->m_profilerState->setClientRecording(recording);
|
||||
if (recording && d->m_profilerState->currentState() == QmlProfilerStateManager::AppRunning) {
|
||||
if (checkForUnsavedNotes()) {
|
||||
clearData(); // clear right away, before the application starts
|
||||
d->m_profilerState->setClientRecording(true);
|
||||
} else {
|
||||
d->m_recordButton->setChecked(false);
|
||||
}
|
||||
} else {
|
||||
d->m_profilerState->setClientRecording(recording);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlProfilerTool::setRecording(bool recording)
|
||||
@@ -447,6 +460,13 @@ static void startRemoteTool(IAnalyzerTool *tool, StartMode mode)
|
||||
|
||||
void QmlProfilerTool::startTool(StartMode mode)
|
||||
{
|
||||
if (d->m_recordButton->isChecked()) {
|
||||
if (!checkForUnsavedNotes())
|
||||
return;
|
||||
else
|
||||
clearData(); // clear right away to suppress second warning on server recording change
|
||||
}
|
||||
|
||||
// Make sure mode is shown.
|
||||
AnalyzerManager::showMode();
|
||||
|
||||
@@ -499,6 +519,9 @@ void QmlProfilerTool::showSaveDialog()
|
||||
|
||||
void QmlProfilerTool::showLoadDialog()
|
||||
{
|
||||
if (!checkForUnsavedNotes())
|
||||
return;
|
||||
|
||||
if (ModeManager::currentMode()->id() != MODE_ANALYZE)
|
||||
AnalyzerManager::showMode();
|
||||
|
||||
@@ -514,6 +537,22 @@ void QmlProfilerTool::showLoadDialog()
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Checks if we have unsaved notes. If so, shows a warning dialog. Returns true if we can continue
|
||||
with a potentially destructive operation and discard the warnings, or false if not. We don't
|
||||
want to show a save/discard dialog here because that will often result in a confusing series of
|
||||
different dialogs: first "save" and then immediately "load" or "connect".
|
||||
*/
|
||||
bool QmlProfilerTool::checkForUnsavedNotes()
|
||||
{
|
||||
if (!d->m_profilerModelManager->notesModel()->isModified())
|
||||
return true;
|
||||
return QMessageBox::warning(QApplication::activeWindow(), tr("QML Profiler"),
|
||||
tr("You are about to discard the profiling data, including unsaved "
|
||||
"notes. Do you want to continue?"),
|
||||
QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes;
|
||||
}
|
||||
|
||||
void QmlProfilerTool::clientsDisconnected()
|
||||
{
|
||||
// If the application stopped by itself, check if we have all the data
|
||||
@@ -646,13 +685,25 @@ void QmlProfilerTool::clientRecordingChanged()
|
||||
void QmlProfilerTool::serverRecordingChanged()
|
||||
{
|
||||
if (d->m_profilerState->currentState() == QmlProfilerStateManager::AppRunning) {
|
||||
setRecording(d->m_profilerState->serverRecording());
|
||||
// clear the old data each time we start a new profiling session
|
||||
if (d->m_profilerState->serverRecording()) {
|
||||
// We cannot stop it here, so we cannot give the usual yes/no dialog. Show a dialog
|
||||
// offering to immediately save the data instead.
|
||||
if (d->m_profilerModelManager->notesModel()->isModified() &&
|
||||
QMessageBox::warning(QApplication::activeWindow(), tr("QML Profiler"),
|
||||
tr("Starting a new profiling session will discard the "
|
||||
"previous data, including unsaved notes.\nDo you want "
|
||||
"to save the data first?"),
|
||||
QMessageBox::Save, QMessageBox::Discard) ==
|
||||
QMessageBox::Save)
|
||||
showSaveDialog();
|
||||
|
||||
setRecording(true);
|
||||
d->m_clearButton->setEnabled(false);
|
||||
clearData();
|
||||
d->m_profilerModelManager->prepareForWriting();
|
||||
} else {
|
||||
setRecording(false);
|
||||
d->m_clearButton->setEnabled(true);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -94,6 +94,7 @@ private:
|
||||
void populateFileFinder(QString projectDirectory = QString(), QString activeSysroot = QString());
|
||||
template<QmlDebug::ProfileFeature feature>
|
||||
void updateFeaturesMenu(quint64 features);
|
||||
bool checkForUnsavedNotes();
|
||||
|
||||
class QmlProfilerToolPrivate;
|
||||
QmlProfilerToolPrivate *d;
|
||||
|
||||
Reference in New Issue
Block a user