GUI: Recheck changed files. Ticket: #816

This commit is contained in:
Daniel Marjamäki 2012-02-14 21:16:11 +01:00
parent 2e13a51d08
commit 87a118cd16
10 changed files with 154 additions and 12 deletions

View File

@ -27,6 +27,7 @@ ErrorItem::ErrorItem()
ErrorItem::ErrorItem(const ErrorItem &item)
{
file = item.file;
file0 = item.file0;
files = item.files;
lines = item.lines;
errorId = item.errorId;

View File

@ -105,6 +105,7 @@ public:
QString file;
QStringList files;
QString file0;
QList<unsigned int> lines;
QString errorId;
Severity::SeverityType severity;

View File

@ -582,12 +582,16 @@ void MainWindow::ProgramSettings()
void MainWindow::ReCheck()
{
ClearResults();
CheckLockDownUI(); // lock UI while checking
const QStringList files = mThread->GetReCheckFiles();
if (files.empty())
return;
const int filesCount = mThread->GetPreviousFilesCount();
Q_ASSERT(filesCount > 0); // If no files should not be able to recheck
mUI.mResults->CheckingStarted(filesCount);
// Clear results for changed files
for (int i = 0; i < files.size(); ++i)
mUI.mResults->Clear(files[i]);
CheckLockDownUI(); // lock UI while checking
mUI.mResults->CheckingStarted(files.size());
if (mProject)
qDebug() << "Rechecking project file" << mProject->GetProjectFile()->GetFilename();

View File

@ -134,7 +134,7 @@ void ResultsTree::AddErrorItem(const ErrorItem &item)
line.severity = item.severity;
//Create the base item for the error and ensure it has a proper
//file item as a parent
QStandardItem *stditem = AddBacktraceFiles(EnsureFileItem(line.file, hide),
QStandardItem *stditem = AddBacktraceFiles(EnsureFileItem(line.file, item.file0, hide),
line,
hide,
SeverityToIcon(line.severity));
@ -152,6 +152,7 @@ void ResultsTree::AddErrorItem(const ErrorItem &item)
data["line"] = item.lines[0];
data["id"] = item.errorId;
data["inconclusive"] = item.inconclusive;
data["file0"] = item.file0;
stditem->setData(QVariant(data));
//Add backtrace files as children
@ -303,6 +304,25 @@ void ResultsTree::Clear()
mModel.removeRows(0, mModel.rowCount());
}
void ResultsTree::Clear(const QString &filename)
{
const QString stripped = StripPath(filename, false);
for (int i = 0; i < mModel.rowCount(); ++i) {
const QStandardItem *item = mModel.item(i, 0);
if (!item)
continue;
QVariantMap data = item->data().toMap();
if (stripped == data["file"].toString() ||
filename == data["file0"].toString()) {
mModel.removeRow(i);
break;
}
}
}
void ResultsTree::LoadSettings()
{
for (int i = 0; i < mModel.columnCount(); i++) {
@ -433,7 +453,7 @@ void ResultsTree::RefreshTree()
}
}
QStandardItem *ResultsTree::EnsureFileItem(const QString &fullpath, bool hide)
QStandardItem *ResultsTree::EnsureFileItem(const QString &fullpath, const QString &file0, bool hide)
{
QString name = StripPath(fullpath, false);
// Since item has path with native separators we must use path with
@ -452,6 +472,7 @@ QStandardItem *ResultsTree::EnsureFileItem(const QString &fullpath, bool hide)
//Add user data to that item
QMap<QString, QVariant> data;
data["file"] = fullpath;
data["file0"] = file0;
item->setData(QVariant(data));
mModel.appendRow(item);
@ -828,6 +849,7 @@ void ResultsTree::SaveErrors(Report *report, QStandardItem *item)
item.message = data["message"].toString();
item.errorId = data["id"].toString();
item.inconclusive = data["inconclusive"].toBool();
item.file0 = data["file0"].toString();
QString file = StripPath(data["file"].toString(), true);
unsigned int line = data["line"].toUInt();

View File

@ -66,6 +66,11 @@ public:
*/
void Clear();
/**
* @brief Clear errors for a specific file from the tree
*/
void Clear(const QString &filename);
/**
* @brief Function to show/hide certain type of errors
* Refreshes the tree.
@ -339,10 +344,11 @@ protected:
* @brief Ensures there's a item in the model for the specified file
*
* @param fullpath Full path to the file item.
* @param file0 Source file
* @param hide is the error (we want this file item for) hidden?
* @return QStandardItem to be used as a parent for all errors for specified file
*/
QStandardItem *EnsureFileItem(const QString &fullpath, bool hide);
QStandardItem *EnsureFileItem(const QString &fullpath, const QString &file0, bool hide);
/**
* @brief Show a file item

View File

@ -80,6 +80,19 @@ void ResultsView::Clear()
mUI.mProgress->setFormat("%p%");
}
void ResultsView::Clear(const QString &filename)
{
mUI.mTree->Clear(filename);
mUI.mDetails->setText("");
mErrorsFound = false;
mStatistics->Clear();
// Clear the progressbar
mUI.mProgress->setMaximum(PROGRESS_MAX);
mUI.mProgress->setValue(0);
mUI.mProgress->setFormat("%p%");
}
void ResultsView::Progress(int value, const QString& description)
{
mUI.mProgress->setValue(value);

View File

@ -64,6 +64,11 @@ public:
*/
void Clear();
/**
* @brief Clear results for a specific file
*/
void Clear(const QString &filename);
/**
* @brief Save results to a file
*

View File

@ -17,6 +17,7 @@
*/
#include <QObject>
#include <QFileInfo>
#include <QStringList>
#include <QDebug>
#include "settings.h"
@ -51,7 +52,8 @@ void ThreadHandler::SetFiles(const QStringList &files)
void ThreadHandler::Check(const Settings &settings, bool recheck)
{
if (recheck && mRunningThreadCount == 0) {
mResults.SetFiles(mLastFiles);
// only recheck changed files
mResults.SetFiles(GetReCheckFiles());
}
if (mResults.GetFileCount() == 0 || mRunningThreadCount > 0 || settings._jobs <= 0) {
@ -72,6 +74,9 @@ void ThreadHandler::Check(const Settings &settings, bool recheck)
mThreads[i]->Check(settings);
}
// Date and time when checking starts..
mCheckStartTime = QDateTime::currentDateTime();
mTime.start();
}
@ -124,11 +129,18 @@ void ThreadHandler::ThreadDone()
emit Done();
mScanDuration = mTime.elapsed();
// Set date/time used by the recheck
if (!mCheckStartTime.isNull()) {
mLastCheckTime = mCheckStartTime;
mCheckStartTime = QDateTime();
}
}
}
void ThreadHandler::Stop()
{
mCheckStartTime = QDateTime();
for (int i = 0; i < mThreads.size(); i++) {
mThreads[i]->stop();
}
@ -177,3 +189,59 @@ int ThreadHandler::GetPreviousScanDuration() const
{
return mScanDuration;
}
QStringList ThreadHandler::GetReCheckFiles() const
{
if (mLastCheckTime.isNull())
return mLastFiles;
std::set<QString> modified;
std::set<QString> unmodified;
QStringList files;
for (int i = 0; i < mLastFiles.size(); ++i) {
if (NeedsReCheck(mLastFiles[i], modified, unmodified))
files.push_back(mLastFiles[i]);
}
return files;
}
bool ThreadHandler::NeedsReCheck(const QString &filename, std::set<QString> &modified, std::set<QString> &unmodified) const
{
if (modified.find(filename) != modified.end())
return true;
if (unmodified.find(filename) != unmodified.end())
return false;
if (QFileInfo(filename).lastModified() > mLastCheckTime) {
return true;
}
// Parse included files recursively
QFile f(filename);
if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
// prevent recursion..
unmodified.insert(filename);
QTextStream in(&f);
while (!in.atEnd()) {
QString line = in.readLine();
if (line.startsWith("#include \"")) {
line.remove(0,10);
int i = line.indexOf("\"");
if (i > 0) {
line.remove(i,line.length());
line = QFileInfo(filename).absolutePath() + "/" + line;
if (NeedsReCheck(line, modified, unmodified)) {
modified.insert(line);
return true;
}
}
}
}
return false;
}

View File

@ -22,7 +22,8 @@
#include <QObject>
#include <QStringList>
#include <QTime>
#include <QDateTime>
#include <set>
#include "settings.h"
#include "cppcheck.h"
#include "threadresult.h"
@ -117,6 +118,12 @@ public:
*/
int GetPreviousScanDuration() const;
/**
* @brief Get files that should be rechecked because they have been
* changed.
*/
QStringList GetReCheckFiles() const;
signals:
/**
* @brief Signal that all threads are done
@ -147,6 +154,14 @@ protected:
*/
QStringList mLastFiles;
/** @brief date and time when current checking started */
QDateTime mCheckStartTime;
/**
* @brief when was the files checked the last time (used when rechecking)
*/
QDateTime mLastCheckTime;
/**
* @brief Timer used for measuring scan duration
*
@ -183,6 +198,12 @@ protected:
*/
int mRunningThreadCount;
private:
/**
* @brief Check if a file needs to be rechecked. Recursively checks
* included headers. Used by GetReCheckFiles()
*/
bool NeedsReCheck(const QString &filename, std::set<QString> &modified, std::set<QString> &unmodified) const;
};
/// @}
#endif // THREADHANDLER_H

View File

@ -72,14 +72,15 @@ void ThreadResult::reportErr(const ErrorLogger::ErrorMessage &msg)
}
ErrorItem item;
item.file = QString(callStackToString(msg._callStack).c_str());
item.file = QString::fromStdString(callStackToString(msg._callStack));
item.files = files;
item.errorId = QString(msg._id.c_str());
item.errorId = QString::fromStdString(msg._id);
item.lines = lines;
item.summary = QString::fromStdString(msg.shortMessage());
item.message = QString::fromStdString(msg.verboseMessage());
item.severity = msg._severity;
item.inconclusive = msg._inconclusive;
item.file0 = QString::fromStdString(msg.file0);
if (msg._severity != Severity::debug)
emit Error(item);