1.6.6
This commit is contained in:
parent
e5f40dd9d8
commit
7ce252fb36
|
@ -10,6 +10,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
- improved trace log retrival greately improving performance
|
- improved trace log retrival greately improving performance
|
||||||
|
- improved list/tree finder
|
||||||
|
- improved trace logging
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- fixed potential BSOD issue in the driver
|
- fixed potential BSOD issue in the driver
|
||||||
|
|
|
@ -553,6 +553,8 @@ _FX void Session_MonitorPutEx(ULONG type, const WCHAR** strings, ULONG* lengths,
|
||||||
|
|
||||||
if (session->monitor_log) {
|
if (session->monitor_log) {
|
||||||
|
|
||||||
|
LARGE_INTEGER timestamp = Util_GetTimestamp();
|
||||||
|
|
||||||
ULONG pid = (ULONG)hpid;
|
ULONG pid = (ULONG)hpid;
|
||||||
ULONG tid = (ULONG)htid;
|
ULONG tid = (ULONG)htid;
|
||||||
|
|
||||||
|
@ -561,12 +563,13 @@ _FX void Session_MonitorPutEx(ULONG type, const WCHAR** strings, ULONG* lengths,
|
||||||
data_len += ((lengths ? lengths [i] : wcslen(strings[i])) + 1) * sizeof(WCHAR);
|
data_len += ((lengths ? lengths [i] : wcslen(strings[i])) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
|
||||||
//[Type 4][PID 4][TID 4][Data n*2]
|
//[Time 8][Type 4][PID 4][TID 4][Data n*2]
|
||||||
SIZE_T entry_size = 4 + 4 + 4 + data_len;
|
SIZE_T entry_size = 8 + 4 + 4 + 4 + data_len;
|
||||||
|
|
||||||
CHAR* write_ptr = log_buffer_push_entry((LOG_BUFFER_SIZE_T)entry_size, session->monitor_log, FALSE);
|
CHAR* write_ptr = log_buffer_push_entry((LOG_BUFFER_SIZE_T)entry_size, session->monitor_log, FALSE);
|
||||||
if (write_ptr) {
|
if (write_ptr) {
|
||||||
WCHAR null_char = L'\0';
|
WCHAR null_char = L'\0';
|
||||||
|
log_buffer_push_bytes((CHAR*)×tamp.QuadPart, 8, &write_ptr, session->monitor_log);
|
||||||
log_buffer_push_bytes((CHAR*)&type, 4, &write_ptr, session->monitor_log);
|
log_buffer_push_bytes((CHAR*)&type, 4, &write_ptr, session->monitor_log);
|
||||||
log_buffer_push_bytes((CHAR*)&pid, 4, &write_ptr, session->monitor_log);
|
log_buffer_push_bytes((CHAR*)&pid, 4, &write_ptr, session->monitor_log);
|
||||||
log_buffer_push_bytes((CHAR*)&tid, 4, &write_ptr, session->monitor_log);
|
log_buffer_push_bytes((CHAR*)&tid, 4, &write_ptr, session->monitor_log);
|
||||||
|
@ -925,6 +928,7 @@ _FX NTSTATUS Session_Api_MonitorGetEx(PROCESS* proc, ULONG64* parms)
|
||||||
API_MONITOR_GET_EX_ARGS* args = (API_MONITOR_GET_EX_ARGS*)parms;
|
API_MONITOR_GET_EX_ARGS* args = (API_MONITOR_GET_EX_ARGS*)parms;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
//ULONG* seq_num;
|
//ULONG* seq_num;
|
||||||
|
LARGE_INTEGER timestamp;
|
||||||
ULONG* log_type;
|
ULONG* log_type;
|
||||||
ULONG* log_pid;
|
ULONG* log_pid;
|
||||||
ULONG* log_tid;
|
ULONG* log_tid;
|
||||||
|
@ -1007,7 +1011,9 @@ _FX NTSTATUS Session_Api_MonitorGetEx(PROCESS* proc, ULONG64* parms)
|
||||||
// __leave;
|
// __leave;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//[Type 4][PID 4][TID 4][Data n*2]
|
//[Time 8][Type 4][PID 4][TID 4][Data n*2]
|
||||||
|
|
||||||
|
log_buffer_get_bytes((CHAR*)×tamp.QuadPart, 8, &read_ptr, session->monitor_log);
|
||||||
|
|
||||||
log_buffer_get_bytes((CHAR*)log_type, 4, &read_ptr, session->monitor_log);
|
log_buffer_get_bytes((CHAR*)log_type, 4, &read_ptr, session->monitor_log);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||||
* Copyright 2020-2021 David Xanatos, xanasoft.com
|
* Copyright 2020-2023 David Xanatos, xanasoft.com
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -443,3 +443,30 @@ retry:
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Util_GetTime
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
_FX LARGE_INTEGER Util_GetTimestamp(void)
|
||||||
|
{
|
||||||
|
static LARGE_INTEGER gMonitorStartCounter;
|
||||||
|
static LARGE_INTEGER gPerformanceFrequency;
|
||||||
|
static LARGE_INTEGER gMonitorStartTime = { 0 };
|
||||||
|
|
||||||
|
if (gMonitorStartTime.QuadPart == 0) {
|
||||||
|
KeQuerySystemTime(&gMonitorStartTime);
|
||||||
|
gMonitorStartCounter = KeQueryPerformanceCounter(&gPerformanceFrequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
LARGE_INTEGER Time;
|
||||||
|
LARGE_INTEGER CounterNow = KeQueryPerformanceCounter(NULL);
|
||||||
|
LONGLONG CounterOff = CounterNow.QuadPart - gMonitorStartCounter.QuadPart;
|
||||||
|
|
||||||
|
Time.QuadPart = gMonitorStartTime.QuadPart +
|
||||||
|
(10000000 * (CounterOff / gPerformanceFrequency.QuadPart)) +
|
||||||
|
((10000000 * (CounterOff % gPerformanceFrequency.QuadPart)) / gPerformanceFrequency.QuadPart);
|
||||||
|
|
||||||
|
return Time;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||||
* Copyright 2020 David Xanatos, xanasoft.com
|
* Copyright 2020-2023 David Xanatos, xanasoft.com
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -110,6 +110,8 @@ NTSTATUS MyValidateCertificate(void);
|
||||||
HANDLE Util_GetProcessPidByName(const WCHAR* name);
|
HANDLE Util_GetProcessPidByName(const WCHAR* name);
|
||||||
|
|
||||||
|
|
||||||
|
LARGE_INTEGER Util_GetTimestamp(void);
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,16 @@
|
||||||
|
|
||||||
bool CFinder::m_DarkMode = false;
|
bool CFinder::m_DarkMode = false;
|
||||||
|
|
||||||
QWidget* CFinder::AddFinder(QWidget* pList, QObject* pFilterTarget, int iOptions, CFinder** ppFinder)
|
QWidget* CFinder::AddFinder(QTreeView* pTree, QObject* pFilterTarget, int iOptions, CFinder** ppFinder)
|
||||||
{
|
{
|
||||||
QWidget* pWidget = new QWidget();
|
QWidget* pWidget = new QWidget();
|
||||||
QVBoxLayout* pLayout = new QVBoxLayout();
|
QVBoxLayout* pLayout = new QVBoxLayout();
|
||||||
pLayout->setContentsMargins(0,0,0,0);
|
pLayout->setContentsMargins(0,0,0,0);
|
||||||
pWidget->setLayout(pLayout);
|
pWidget->setLayout(pLayout);
|
||||||
|
|
||||||
pLayout->addWidget(pList);
|
pLayout->addWidget(pTree);
|
||||||
CFinder* pFinder = new CFinder(pFilterTarget, pWidget, iOptions);
|
CFinder* pFinder = new CFinder(pFilterTarget, pWidget, iOptions);
|
||||||
|
pFinder->SetTree(pTree);
|
||||||
pLayout->addWidget(pFinder);
|
pLayout->addWidget(pFinder);
|
||||||
|
|
||||||
if (ppFinder)
|
if (ppFinder)
|
||||||
|
@ -52,9 +53,10 @@ CFinder::CFinder(QObject* pFilterTarget, QWidget *parent, int iOptions)
|
||||||
else
|
else
|
||||||
m_pRegExp = NULL;
|
m_pRegExp = NULL;
|
||||||
|
|
||||||
m_pSortProxy = qobject_cast<QSortFilterProxyModel*>(pFilterTarget);
|
m_pTree = NULL;
|
||||||
|
m_pModel = qobject_cast<QAbstractProxyModel*>(pFilterTarget);
|
||||||
|
|
||||||
if (m_pSortProxy) {
|
if (m_pModel) {
|
||||||
m_pColumn = new QComboBox();
|
m_pColumn = new QComboBox();
|
||||||
m_pSearchLayout->addWidget(m_pColumn);
|
m_pSearchLayout->addWidget(m_pColumn);
|
||||||
connect(m_pColumn, SIGNAL(currentIndexChanged(int)), this, SLOT(OnUpdate()));
|
connect(m_pColumn, SIGNAL(currentIndexChanged(int)), this, SLOT(OnUpdate()));
|
||||||
|
@ -66,7 +68,8 @@ CFinder::CFinder(QObject* pFilterTarget, QWidget *parent, int iOptions)
|
||||||
if ((iOptions & eHighLight) != 0)
|
if ((iOptions & eHighLight) != 0)
|
||||||
{
|
{
|
||||||
m_pHighLight = new QCheckBox(tr("Highlight"));
|
m_pHighLight = new QCheckBox(tr("Highlight"));
|
||||||
//m_pHighLight->setChecked(true);
|
if ((iOptions & eHighLightDefault) == eHighLightDefault)
|
||||||
|
m_pHighLight->setChecked(true);
|
||||||
m_pSearchLayout->addWidget(m_pHighLight);
|
m_pSearchLayout->addWidget(m_pHighLight);
|
||||||
connect(m_pHighLight, SIGNAL(stateChanged(int)), this, SLOT(OnUpdate()));
|
connect(m_pHighLight, SIGNAL(stateChanged(int)), this, SLOT(OnUpdate()));
|
||||||
}
|
}
|
||||||
|
@ -103,7 +106,7 @@ CFinder::CFinder(QObject* pFilterTarget, QWidget *parent, int iOptions)
|
||||||
|
|
||||||
if (pFilterTarget) {
|
if (pFilterTarget) {
|
||||||
QObject::connect(this, SIGNAL(SetFilter(const QString&, int, int)), pFilterTarget, SLOT(SetFilter(const QString&, int, int)));
|
QObject::connect(this, SIGNAL(SetFilter(const QString&, int, int)), pFilterTarget, SLOT(SetFilter(const QString&, int, int)));
|
||||||
QObject::connect(this, SIGNAL(SelectNext()), pFilterTarget, SLOT(SelectNext()));
|
//QObject::connect(this, SIGNAL(SelectNext()), pFilterTarget, SLOT(SelectNext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pTimer = new QTimer(this);
|
m_pTimer = new QTimer(this);
|
||||||
|
@ -118,6 +121,12 @@ CFinder::~CFinder()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CFinder::SetTree(QTreeView* pTree)
|
||||||
|
{
|
||||||
|
m_pTree = pTree;
|
||||||
|
QObject::connect(this, SIGNAL(SelectNext()), this, SLOT(OnSelectNext()));
|
||||||
|
}
|
||||||
|
|
||||||
bool CFinder::eventFilter(QObject* source, QEvent* event)
|
bool CFinder::eventFilter(QObject* source, QEvent* event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::KeyPress && ((QKeyEvent*)event)->key() == Qt::Key_Escape
|
if (event->type() == QEvent::KeyPress && ((QKeyEvent*)event)->key() == Qt::Key_Escape
|
||||||
|
@ -132,11 +141,11 @@ bool CFinder::eventFilter(QObject* source, QEvent* event)
|
||||||
|
|
||||||
void CFinder::Open()
|
void CFinder::Open()
|
||||||
{
|
{
|
||||||
if (m_pSortProxy && m_pColumn->count() == 0)
|
if (m_pModel && m_pColumn->count() == 0)
|
||||||
{
|
{
|
||||||
m_pColumn->addItem(tr("All columns"), -1);
|
m_pColumn->addItem(tr("All columns"), -1);
|
||||||
for (int i = 0; i < m_pSortProxy->columnCount(); i++)
|
for (int i = 0; i < m_pModel->columnCount(); i++)
|
||||||
m_pColumn->addItem(m_pSortProxy->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(), i);
|
m_pColumn->addItem(m_pModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(), i);
|
||||||
m_pColumn->setVisible(true);
|
m_pColumn->setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +167,12 @@ void CFinder::OnUpdate()
|
||||||
iOptions |= eCaseSens;
|
iOptions |= eCaseSens;
|
||||||
if (GetHighLight())
|
if (GetHighLight())
|
||||||
iOptions |= eHighLight;
|
iOptions |= eHighLight;
|
||||||
SetFilter(m_pSearch->text(), iOptions, GetColumn());
|
QString Exp = m_pSearch->text();
|
||||||
|
|
||||||
|
QString ExpStr = ((iOptions & CFinder::eRegExp) == 0) ? Exp : (".*" + QRegularExpression::escape(Exp) + ".*");
|
||||||
|
m_RegExp = QRegularExpression(ExpStr, (iOptions & CFinder::eCaseSens) != 0 ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption);
|
||||||
|
|
||||||
|
SetFilter(Exp, iOptions, GetColumn());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFinder::OnText()
|
void CFinder::OnText()
|
||||||
|
@ -179,3 +193,125 @@ void CFinder::Close()
|
||||||
emit SetFilter(QString());
|
emit SetFilter(QString());
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
|
||||||
|
bool CFinder::MatchString(const QString& value)
|
||||||
|
{
|
||||||
|
return value.contains(m_RegExp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFinder::MatchCell(QModelIndex idx, int column)
|
||||||
|
{
|
||||||
|
QModelIndex tmp = idx.sibling(idx.row(), column);
|
||||||
|
|
||||||
|
QString str = m_pModel->data(tmp, Qt::DisplayRole).toString();
|
||||||
|
return MatchString(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFinder::MatchRow(QModelIndex idx)
|
||||||
|
{
|
||||||
|
int iColumn = GetColumn();
|
||||||
|
if (iColumn != -1)
|
||||||
|
return MatchCell(idx, iColumn);
|
||||||
|
|
||||||
|
for(int col = 0; col < m_pModel->columnCount(idx); col++) {
|
||||||
|
if (MatchCell(idx, col))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex CFinder::FindNext(QModelIndex idx, bool next, int depth)
|
||||||
|
{
|
||||||
|
if (MatchRow(idx) && !next)
|
||||||
|
return idx;
|
||||||
|
//Q_ASSERT(depth < 100);
|
||||||
|
|
||||||
|
if (m_pModel->hasChildren(idx))
|
||||||
|
{
|
||||||
|
int numRows = m_pModel->rowCount(idx);
|
||||||
|
for (int count = 0; count < numRows; count++) {
|
||||||
|
QModelIndex tmp = FindNext(m_pModel->index(count, 0, idx), false, depth + 1);
|
||||||
|
if (tmp.isValid())
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
QModelIndex par = m_pModel->parent(idx);
|
||||||
|
if (!par.isValid() && depth > 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int numRows = m_pModel->rowCount(par);
|
||||||
|
for (int count = idx.row() + 1; count < numRows; count++) {
|
||||||
|
QModelIndex tmp = FindNext(m_pModel->index(count, 0, par), false, depth + 1);
|
||||||
|
if (tmp.isValid())
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!par.isValid())
|
||||||
|
break;
|
||||||
|
idx = par;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex CFinder::FindPrev(QModelIndex idx, bool next, int depth)
|
||||||
|
{
|
||||||
|
if (MatchRow(idx) && !next)
|
||||||
|
return idx;
|
||||||
|
//Q_ASSERT(depth < 100);
|
||||||
|
|
||||||
|
if (m_pModel->hasChildren(idx))
|
||||||
|
{
|
||||||
|
int numRows = m_pModel->rowCount(idx);
|
||||||
|
for (int count = numRows-1; count >= 0; count++) {
|
||||||
|
QModelIndex tmp = FindNext(m_pModel->index(count, 0, idx), false, depth + 1);
|
||||||
|
if (tmp.isValid())
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
QModelIndex par = m_pModel->parent(idx);
|
||||||
|
if (!par.isValid() && depth > 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int numRows = m_pModel->rowCount(par);
|
||||||
|
for (int count = idx.row() - 1; count >= 0; count--) {
|
||||||
|
QModelIndex tmp = FindNext(m_pModel->index(count, 0, par), false, depth + 1);
|
||||||
|
if (tmp.isValid())
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!par.isValid())
|
||||||
|
break;
|
||||||
|
idx = par;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFinder::OnSelectNext()
|
||||||
|
{
|
||||||
|
bool next = true;
|
||||||
|
QModelIndex idx = m_pTree->currentIndex();
|
||||||
|
if (!(next = idx.isValid()))
|
||||||
|
idx = m_pModel->index(0, 0);
|
||||||
|
|
||||||
|
//if (QApplication::keyboardModifiers() & Qt::ControlModifier)
|
||||||
|
if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
|
||||||
|
idx = FindPrev(idx, next);
|
||||||
|
else
|
||||||
|
idx = FindNext(idx, next);
|
||||||
|
|
||||||
|
if (idx.isValid())
|
||||||
|
m_pTree->setCurrentIndex(idx);
|
||||||
|
else
|
||||||
|
QApplication::beep();
|
||||||
|
}
|
|
@ -10,21 +10,21 @@ public:
|
||||||
CFinder(QObject* pFilterTarget, QWidget *parent = NULL, int iOptions = eRegExp | eCaseSens | eHighLight);
|
CFinder(QObject* pFilterTarget, QWidget *parent = NULL, int iOptions = eRegExp | eCaseSens | eHighLight);
|
||||||
~CFinder();
|
~CFinder();
|
||||||
|
|
||||||
|
void SetTree(QTreeView* pTree);
|
||||||
|
|
||||||
static void SetDarkMode(bool bDarkMode) { m_DarkMode = bDarkMode; }
|
static void SetDarkMode(bool bDarkMode) { m_DarkMode = bDarkMode; }
|
||||||
static bool GetDarkMode() { return m_DarkMode; }
|
static bool GetDarkMode() { return m_DarkMode; }
|
||||||
|
|
||||||
static QWidget* AddFinder(QWidget* pList, QObject* pFilterTarget, int iOptions = eRegExp | eCaseSens | eHighLight, CFinder** ppFinder = NULL);
|
static QWidget* AddFinder(QTreeView* pTree, QObject* pFilterTarget, int iOptions = eRegExp | eCaseSens | eHighLight, CFinder** ppFinder = NULL);
|
||||||
|
|
||||||
bool GetCaseSensitive() const { return m_pCaseSensitive ? m_pCaseSensitive->isChecked() : false; }
|
QRegularExpression GetSearchExp() const { return m_RegExp; }
|
||||||
bool GetRegExp() const { return m_pRegExp ? m_pRegExp->isChecked() : false; }
|
|
||||||
bool GetHighLight() const { return m_pHighLight ? m_pHighLight->isChecked() : false; }
|
|
||||||
int GetColumn() const { return m_pColumn ? m_pColumn->currentData().toInt() : -1; }
|
|
||||||
|
|
||||||
enum EOptions
|
enum EOptions
|
||||||
{
|
{
|
||||||
eRegExp = 0x01,
|
eRegExp = 0x01,
|
||||||
eCaseSens = 0x02,
|
eCaseSens = 0x02,
|
||||||
eHighLight = 0x04,
|
eHighLight = 0x04,
|
||||||
|
eHighLightDefault = eHighLight | 0x08,
|
||||||
};
|
};
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -40,9 +40,22 @@ private slots:
|
||||||
void OnText();
|
void OnText();
|
||||||
void OnReturn();
|
void OnReturn();
|
||||||
|
|
||||||
|
void OnSelectNext();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool GetCaseSensitive() const { return m_pCaseSensitive ? m_pCaseSensitive->isChecked() : false; }
|
||||||
|
bool GetRegExp() const { return m_pRegExp ? m_pRegExp->isChecked() : false; }
|
||||||
|
bool GetHighLight() const { return m_pHighLight ? m_pHighLight->isChecked() : false; }
|
||||||
|
int GetColumn() const { return m_pColumn ? m_pColumn->currentData().toInt() : -1; }
|
||||||
|
|
||||||
bool eventFilter(QObject* source, QEvent* event);
|
bool eventFilter(QObject* source, QEvent* event);
|
||||||
|
|
||||||
|
virtual bool MatchString(const QString& value);
|
||||||
|
bool MatchCell(QModelIndex idx, int column);
|
||||||
|
bool MatchRow(QModelIndex idx);
|
||||||
|
QModelIndex FindNext(QModelIndex idx, bool next = false, int depth = 0);
|
||||||
|
QModelIndex FindPrev(QModelIndex idx, bool next = false, int depth = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QHBoxLayout* m_pSearchLayout;
|
QHBoxLayout* m_pSearchLayout;
|
||||||
|
@ -53,7 +66,10 @@ private:
|
||||||
QComboBox* m_pColumn;
|
QComboBox* m_pColumn;
|
||||||
QCheckBox* m_pHighLight;
|
QCheckBox* m_pHighLight;
|
||||||
|
|
||||||
QSortFilterProxyModel* m_pSortProxy;
|
QRegularExpression m_RegExp;
|
||||||
|
|
||||||
|
QTreeView* m_pTree;
|
||||||
|
QAbstractProxyModel*m_pModel;
|
||||||
|
|
||||||
QTimer* m_pTimer;
|
QTimer* m_pTimer;
|
||||||
|
|
||||||
|
|
|
@ -136,10 +136,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void SetFilter(const QString& Exp, int iFormat, int Col = -1) // -1 = any
|
void SetFilter(const QString& Exp, int iOptions, int Col = -1) // -1 = any
|
||||||
{
|
{
|
||||||
QString ExpStr = ((iFormat & CFinder::eRegExp) == 0) ? Exp : (".*" + QRegularExpression::escape(Exp) + ".*");
|
QString ExpStr = ((iOptions & CFinder::eRegExp) == 0) ? Exp : (".*" + QRegularExpression::escape(Exp) + ".*");
|
||||||
QRegularExpression RegExp(ExpStr, (iFormat & CFinder::eCaseSens) != 0 ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption);
|
QRegularExpression RegExp(ExpStr, (iOptions & CFinder::eCaseSens) != 0 ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption);
|
||||||
ApplyFilter(m_pTreeList, RegExp);
|
ApplyFilter(m_pTreeList, RegExp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,8 +164,6 @@ public:
|
||||||
m_pSortProxy->setDynamicSortFilter(true);
|
m_pSortProxy->setDynamicSortFilter(true);
|
||||||
|
|
||||||
m_pTreeList->setModel(m_pSortProxy);
|
m_pTreeList->setModel(m_pSortProxy);
|
||||||
((CSortFilterProxyModel*)m_pSortProxy)->setView(m_pTreeList);
|
|
||||||
|
|
||||||
|
|
||||||
m_pTreeList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
m_pTreeList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
|
@ -14,16 +14,10 @@ public:
|
||||||
{
|
{
|
||||||
m_bHighLight = false;
|
m_bHighLight = false;
|
||||||
m_iColumn = 0;
|
m_iColumn = 0;
|
||||||
m_pView = NULL;
|
|
||||||
|
|
||||||
this->setSortCaseSensitivity(Qt::CaseInsensitive);
|
this->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setView(QTreeView* pView)
|
|
||||||
{
|
|
||||||
m_pView = pView;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
|
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
|
||||||
{
|
{
|
||||||
if (m_bHighLight)
|
if (m_bHighLight)
|
||||||
|
@ -86,124 +80,16 @@ public slots:
|
||||||
QRegularExpression RegExp(ExpStr, (iOptions & CFinder::eCaseSens) != 0 ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption);
|
QRegularExpression RegExp(ExpStr, (iOptions & CFinder::eCaseSens) != 0 ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption);
|
||||||
|
|
||||||
QModelIndex idx;
|
QModelIndex idx;
|
||||||
//if (m_pView) idx = m_pView->currentIndex();
|
|
||||||
m_iColumn = Col;
|
m_iColumn = Col;
|
||||||
m_bHighLight = (iOptions & CFinder::eHighLight) != 0;
|
m_bHighLight = (iOptions & CFinder::eHighLight) != 0;
|
||||||
setFilterKeyColumn(Col);
|
setFilterKeyColumn(Col);
|
||||||
setFilterRegularExpression(RegExp);
|
setFilterRegularExpression(RegExp);
|
||||||
//if (m_pView) m_pView->setCurrentIndex(idx);
|
|
||||||
if (m_bHighLight)
|
if (m_bHighLight)
|
||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectNext()
|
|
||||||
{
|
|
||||||
if (!m_pView)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool next = true;
|
|
||||||
QModelIndex idx = m_pView->currentIndex();
|
|
||||||
if (!(next = idx.isValid()))
|
|
||||||
idx = index(0, 0);
|
|
||||||
|
|
||||||
//if (QApplication::keyboardModifiers() & Qt::ControlModifier)
|
|
||||||
if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
|
|
||||||
idx = FindPrev(idx, next);
|
|
||||||
else
|
|
||||||
idx = FindNext(idx, next);
|
|
||||||
|
|
||||||
if (idx.isValid())
|
|
||||||
m_pView->setCurrentIndex(idx);
|
|
||||||
else
|
|
||||||
QApplication::beep();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool m_bHighLight;
|
bool m_bHighLight;
|
||||||
int m_iColumn;
|
int m_iColumn;
|
||||||
QTreeView* m_pView;
|
|
||||||
|
|
||||||
bool MatchCell(QModelIndex idx, int column)
|
|
||||||
{
|
|
||||||
QModelIndex tmp = idx.sibling(idx.row(), column);
|
|
||||||
|
|
||||||
QString str = data(tmp, filterRole()).toString();
|
|
||||||
if (str.contains(filterRegularExpression()))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MatchRow(QModelIndex idx)
|
|
||||||
{
|
|
||||||
if (m_iColumn != -1)
|
|
||||||
return MatchCell(idx, m_iColumn);
|
|
||||||
|
|
||||||
for(int col = 0; col < columnCount(idx); col++) {
|
|
||||||
if (MatchCell(idx, col))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex FindNext(QModelIndex idx, bool next = false)
|
|
||||||
{
|
|
||||||
if (MatchRow(idx) && !next)
|
|
||||||
return idx;
|
|
||||||
|
|
||||||
if (hasChildren(idx))
|
|
||||||
{
|
|
||||||
int numRows = rowCount(idx);
|
|
||||||
for (int count = 0; count < numRows; count++) {
|
|
||||||
QModelIndex tmp = FindNext(index(count, 0, idx));
|
|
||||||
if (tmp.isValid())
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
QModelIndex par = parent(idx);
|
|
||||||
|
|
||||||
int numRows = rowCount(par);
|
|
||||||
for (int count = idx.row() + 1; count < numRows; count++) {
|
|
||||||
QModelIndex tmp = FindNext(index(count, 0, par));
|
|
||||||
if (tmp.isValid())
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = par;
|
|
||||||
} while (idx.isValid());
|
|
||||||
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex FindPrev(QModelIndex idx, bool next = false)
|
|
||||||
{
|
|
||||||
if (MatchRow(idx) && !next)
|
|
||||||
return idx;
|
|
||||||
|
|
||||||
if (hasChildren(idx))
|
|
||||||
{
|
|
||||||
int numRows = rowCount(idx);
|
|
||||||
for (int count = numRows-1; count >= 0; count++) {
|
|
||||||
QModelIndex tmp = FindNext(index(count, 0, idx));
|
|
||||||
if (tmp.isValid())
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
QModelIndex par = parent(idx);
|
|
||||||
|
|
||||||
int numRows = rowCount(par);
|
|
||||||
for (int count = idx.row() - 1; count >= 0; count--) {
|
|
||||||
QModelIndex tmp = FindNext(index(count, 0, par));
|
|
||||||
if (tmp.isValid())
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = par;
|
|
||||||
} while (idx.isValid());
|
|
||||||
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2533,7 +2533,7 @@ bool CSbieAPI::GetMonitor()
|
||||||
pos += (len + 1) * sizeof(WCHAR);
|
pos += (len + 1) * sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTraceEntryPtr LogEntry = CTraceEntryPtr(new CTraceEntry(pid, tid, type, LogData));
|
CTraceEntryPtr LogEntry = CTraceEntryPtr(new CTraceEntry(0, pid, tid, type, LogData));
|
||||||
|
|
||||||
QMutexLocker Lock(&m_TraceMutex);
|
QMutexLocker Lock(&m_TraceMutex);
|
||||||
m_TraceCache.append(LogEntry);
|
m_TraceCache.append(LogEntry);
|
||||||
|
@ -2570,6 +2570,10 @@ bool CSbieAPI::GetMonitor()
|
||||||
ULONG uSize = *(ULONG*)ptr;
|
ULONG uSize = *(ULONG*)ptr;
|
||||||
ptr += sizeof(ULONG);
|
ptr += sizeof(ULONG);
|
||||||
|
|
||||||
|
LONGLONG uTimestamp = *(LONGLONG*)ptr;
|
||||||
|
ptr += sizeof(LONGLONG);
|
||||||
|
uSize -= sizeof(LONGLONG);
|
||||||
|
|
||||||
ULONG uType = *(ULONG*)ptr;
|
ULONG uType = *(ULONG*)ptr;
|
||||||
ptr += sizeof(ULONG);
|
ptr += sizeof(ULONG);
|
||||||
uSize -= sizeof(ULONG);
|
uSize -= sizeof(ULONG);
|
||||||
|
@ -2590,7 +2594,7 @@ bool CSbieAPI::GetMonitor()
|
||||||
}
|
}
|
||||||
ptr += uSize;
|
ptr += uSize;
|
||||||
|
|
||||||
CTraceEntryPtr LogEntry = CTraceEntryPtr(new CTraceEntry(uPid, uTid, uType, LogData));
|
CTraceEntryPtr LogEntry = CTraceEntryPtr(new CTraceEntry(FILETIME2ms(uTimestamp), uPid, uTid, uType, LogData));
|
||||||
|
|
||||||
QMutexLocker Lock(&m_TraceMutex);
|
QMutexLocker Lock(&m_TraceMutex);
|
||||||
m_TraceCache.append(LogEntry);
|
m_TraceCache.append(LogEntry);
|
||||||
|
|
|
@ -60,7 +60,7 @@ QString ErrorString(qint32 err)
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
CTraceEntry::CTraceEntry(quint32 ProcessId, quint32 ThreadId, quint32 Type, const QStringList& LogData)
|
CTraceEntry::CTraceEntry(quint64 Timestamp, quint32 ProcessId, quint32 ThreadId, quint32 Type, const QStringList& LogData)
|
||||||
{
|
{
|
||||||
m_ProcessId = ProcessId;
|
m_ProcessId = ProcessId;
|
||||||
m_ThreadId = ThreadId;
|
m_ThreadId = ThreadId;
|
||||||
|
@ -69,7 +69,7 @@ CTraceEntry::CTraceEntry(quint32 ProcessId, quint32 ThreadId, quint32 Type, cons
|
||||||
m_SubType = LogData.length() > 2 ? LogData.at(2) : QString();
|
m_SubType = LogData.length() > 2 ? LogData.at(2) : QString();
|
||||||
m_Type.Flags = Type;
|
m_Type.Flags = Type;
|
||||||
|
|
||||||
m_TimeStamp = QDateTime::currentDateTime(); // ms resolution
|
m_TimeStamp = Timestamp ? Timestamp : QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||||
|
|
||||||
m_BoxPtr = 0;
|
m_BoxPtr = 0;
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,13 @@
|
||||||
class QSBIEAPI_EXPORT CTraceEntry : public QSharedData
|
class QSBIEAPI_EXPORT CTraceEntry : public QSharedData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CTraceEntry(quint32 ProcessId, quint32 ThreadId, quint32 Type, const QStringList& LogData);
|
CTraceEntry(quint64 Timestamp, quint32 ProcessId, quint32 ThreadId, quint32 Type, const QStringList& LogData);
|
||||||
|
|
||||||
virtual QString GetName() const { return m_Name; }
|
virtual QString GetName() const { return m_Name; }
|
||||||
virtual QString GetMessage() const { return m_Message; }
|
virtual QString GetMessage() const { return m_Message; }
|
||||||
virtual quint32 GetProcessId() const { return m_ProcessId; }
|
virtual quint32 GetProcessId() const { return m_ProcessId; }
|
||||||
virtual quint32 GetThreadId() const { return m_ThreadId; }
|
virtual quint32 GetThreadId() const { return m_ThreadId; }
|
||||||
virtual QDateTime GetTimeStamp() const { return m_TimeStamp; }
|
virtual quint64 GetTimeStamp() const { return m_TimeStamp; }
|
||||||
|
|
||||||
virtual quint8 GetType() const { return m_Type.Type; }
|
virtual quint8 GetType() const { return m_Type.Type; }
|
||||||
static QList<quint32>AllTypes();
|
static QList<quint32>AllTypes();
|
||||||
|
@ -72,7 +72,7 @@ protected:
|
||||||
QString m_SubType;
|
QString m_SubType;
|
||||||
quint32 m_ProcessId;
|
quint32 m_ProcessId;
|
||||||
quint32 m_ThreadId;
|
quint32 m_ThreadId;
|
||||||
QDateTime m_TimeStamp;
|
quint64 m_TimeStamp;
|
||||||
QString m_ProcessName;
|
QString m_ProcessName;
|
||||||
void* m_BoxPtr;
|
void* m_BoxPtr;
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,17 @@ void CTraceModel::FreeNode(STreeNode* pNode)
|
||||||
//delete pNode;
|
//delete pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CTraceModel::TestHighLight(STreeNode* pNode) const
|
||||||
|
{
|
||||||
|
if (m_HighLightExp.isEmpty())
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < eCount; i++) {
|
||||||
|
if (NodeData(pNode, Qt::DisplayRole, i).toString().contains(m_HighLightExp))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QVariant CTraceModel::NodeData(STreeNode* pNode, int role, int section) const
|
QVariant CTraceModel::NodeData(STreeNode* pNode, int role, int section) const
|
||||||
{
|
{
|
||||||
const CTraceEntryPtr& pEntry = pNode->pEntry;
|
const CTraceEntryPtr& pEntry = pNode->pEntry;
|
||||||
|
@ -183,9 +194,10 @@ QVariant CTraceModel::NodeData(STreeNode* pNode, int role, int section) const
|
||||||
if(!m_bTree) {
|
if(!m_bTree) {
|
||||||
QString Name = pEntry->GetProcessName();
|
QString Name = pEntry->GetProcessName();
|
||||||
return QString("%1 (%2, %3) - %4").arg(Name.isEmpty() ? tr("Unknown") : Name)
|
return QString("%1 (%2, %3) - %4").arg(Name.isEmpty() ? tr("Unknown") : Name)
|
||||||
.arg(pEntry->GetProcessId()).arg(pEntry->GetThreadId()).arg(pEntry->GetTimeStamp().toString("hh:mm:ss.zzz"));
|
.arg(pEntry->GetProcessId()).arg(pEntry->GetThreadId())
|
||||||
|
.arg(QDateTime::fromMSecsSinceEpoch(pEntry->GetTimeStamp()).toString("hh:mm:ss.zzz"));
|
||||||
} else
|
} else
|
||||||
return pEntry->GetTimeStamp().toString("hh:mm:ss.zzz");
|
return QDateTime::fromMSecsSinceEpoch(pEntry->GetTimeStamp()).toString("hh:mm:ss.zzz");
|
||||||
}
|
}
|
||||||
case eType: return pEntry->GetTypeStr();
|
case eType: return pEntry->GetTypeStr();
|
||||||
case eStatus: return pEntry->GetStautsStr();
|
case eStatus: return pEntry->GetStautsStr();
|
||||||
|
@ -198,6 +210,18 @@ QVariant CTraceModel::NodeData(STreeNode* pNode, int role, int section) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case Qt::BackgroundRole:
|
||||||
|
{
|
||||||
|
if(!CTreeItemModel::GetDarkMode())
|
||||||
|
return TestHighLight(pNode) ? QColor(Qt::yellow) : QVariant();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Qt::ForegroundRole:
|
||||||
|
{
|
||||||
|
if(CTreeItemModel::GetDarkMode())
|
||||||
|
return TestHighLight(pNode) ? QColor(Qt::yellow) : QVariant();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
|
@ -15,6 +15,8 @@ public:
|
||||||
void SetTree(bool bTree) { m_bTree = bTree; }
|
void SetTree(bool bTree) { m_bTree = bTree; }
|
||||||
bool IsTree() const { return m_bTree; }
|
bool IsTree() const { return m_bTree; }
|
||||||
|
|
||||||
|
void SetHighLight(const QString& Exp) { m_HighLightExp = Exp; }
|
||||||
|
|
||||||
QList<QModelIndex> Sync(const QVector<CTraceEntryPtr>& EntryList);
|
QList<QModelIndex> Sync(const QVector<CTraceEntryPtr>& EntryList);
|
||||||
|
|
||||||
CTraceEntryPtr GetEntry(const QModelIndex& index) const;
|
CTraceEntryPtr GetEntry(const QModelIndex& index) const;
|
||||||
|
@ -96,5 +98,9 @@ protected:
|
||||||
STreeNode* m_Root;
|
STreeNode* m_Root;
|
||||||
QHash<quint64, STreeNode*> m_Branches;
|
QHash<quint64, STreeNode*> m_Branches;
|
||||||
|
|
||||||
|
QString m_HighLightExp;
|
||||||
|
|
||||||
|
bool TestHighLight(STreeNode* pNode) const;
|
||||||
|
|
||||||
static PoolAllocator<sizeof(STreeNode)> m_NodeAllocator;
|
static PoolAllocator<sizeof(STreeNode)> m_NodeAllocator;
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent)
|
||||||
|
|
||||||
//m_UserConfigChanged = false;
|
//m_UserConfigChanged = false;
|
||||||
|
|
||||||
m_pSbieModel = new CSbieModel();
|
m_pSbieModel = new CSbieModel(this);
|
||||||
m_pSbieModel->SetTree(true);
|
m_pSbieModel->SetTree(true);
|
||||||
m_pSbieModel->SetUseIcons(true);
|
m_pSbieModel->SetUseIcons(true);
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent)
|
||||||
m_pSbieModel->SetLargeIcons();
|
m_pSbieModel->SetLargeIcons();
|
||||||
m_pSbieTree->setIconSize(QSize(32, 32));
|
m_pSbieTree->setIconSize(QSize(32, 32));
|
||||||
}
|
}
|
||||||
((CSortFilterProxyModel*)m_pSortProxy)->setView(m_pSbieTree);
|
|
||||||
|
|
||||||
m_pSbieTree->setDragDropMode(QAbstractItemView::InternalMove);
|
m_pSbieTree->setDragDropMode(QAbstractItemView::InternalMove);
|
||||||
|
|
||||||
|
@ -82,7 +81,9 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent)
|
||||||
m_pMainLayout->addWidget(m_pSbieTree);
|
m_pMainLayout->addWidget(m_pSbieTree);
|
||||||
//
|
//
|
||||||
|
|
||||||
m_pMainLayout->addWidget(new CFinder(m_pSortProxy, this));
|
CFinder* pFinder = new CFinder(m_pSortProxy, this);
|
||||||
|
m_pMainLayout->addWidget(pFinder);
|
||||||
|
pFinder->SetTree(m_pSbieTree);
|
||||||
|
|
||||||
|
|
||||||
connect(m_pSbieModel, SIGNAL(ToolTipCallback(const QVariant&, QString&)), this, SLOT(OnToolTipCallback(const QVariant&, QString&)), Qt::DirectConnection);
|
connect(m_pSbieModel, SIGNAL(ToolTipCallback(const QVariant&, QString&)), this, SLOT(OnToolTipCallback(const QVariant&, QString&)), Qt::DirectConnection);
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
CTraceTree::CTraceTree(QWidget* parent)
|
CTraceTree::CTraceTree(QWidget* parent)
|
||||||
: CPanelWidget<QTreeViewEx>(parent)
|
: CPanelWidget<QTreeViewEx>(parent)
|
||||||
{
|
{
|
||||||
|
m_bHighLight = false;
|
||||||
|
//m_FilterCol = -1;
|
||||||
|
|
||||||
m_pTreeList->setAlternatingRowColors(theConf->GetBool("Options/AltRowColors", false));
|
m_pTreeList->setAlternatingRowColors(theConf->GetBool("Options/AltRowColors", false));
|
||||||
|
|
||||||
m_pTreeList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
m_pTreeList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
@ -83,7 +86,8 @@ CTraceTree::CTraceTree(QWidget* parent)
|
||||||
//connect(m_pBoxTree, SIGNAL(ColumnChanged(int, bool)), this, SLOT(OnColumnsChanged()));
|
//connect(m_pBoxTree, SIGNAL(ColumnChanged(int, bool)), this, SLOT(OnColumnsChanged()));
|
||||||
|
|
||||||
//m_pMainLayout->addWidget(CFinder::AddFinder(m_pTreeList, m_pSortProxy));
|
//m_pMainLayout->addWidget(CFinder::AddFinder(m_pTreeList, m_pSortProxy));
|
||||||
m_pMainLayout->addWidget(CFinder::AddFinder(m_pTreeList, this, CFinder::eHighLight));
|
m_pMainLayout->addWidget(CFinder::AddFinder(m_pTreeList, this, CFinder::eHighLightDefault));
|
||||||
|
//QObject::connect(pFinder, SIGNAL(SelectNext()), this, SLOT(SelectNext()));
|
||||||
|
|
||||||
|
|
||||||
QByteArray Columns = theConf->GetBlob("MainWindow/TraceLog_Columns");
|
QByteArray Columns = theConf->GetBlob("MainWindow/TraceLog_Columns");
|
||||||
|
@ -98,6 +102,23 @@ CTraceTree::~CTraceTree()
|
||||||
theConf->SetBlob("MainWindow/TraceLog_Columns", GetView()->header()->saveState());
|
theConf->SetBlob("MainWindow/TraceLog_Columns", GetView()->header()->saveState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTraceTree::SetFilter(const QString& Exp, int iOptions, int Column)
|
||||||
|
{
|
||||||
|
bool bReset = m_FilterExp != Exp || m_bHighLight != ((iOptions & CFinder::eHighLight) != 0);
|
||||||
|
|
||||||
|
//QString ExpStr = ((iOptions & CFinder::eRegExp) == 0) ? Exp : (".*" + QRegularExpression::escape(Exp) + ".*");
|
||||||
|
//QRegularExpression RegExp(ExpStr, (iOptions & CFinder::eCaseSens) != 0 ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption);
|
||||||
|
//m_FilterExp = RegExp;
|
||||||
|
m_FilterExp = Exp;
|
||||||
|
m_bHighLight = (iOptions & CFinder::eHighLight) != 0;
|
||||||
|
//m_FilterCol = Col;
|
||||||
|
|
||||||
|
if(bReset)
|
||||||
|
emit FilterChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// CMonitorList
|
// CMonitorList
|
||||||
|
|
||||||
|
@ -117,8 +138,6 @@ CMonitorList::CMonitorList(QWidget* parent)
|
||||||
m_pSortProxy->setDynamicSortFilter(true);
|
m_pSortProxy->setDynamicSortFilter(true);
|
||||||
|
|
||||||
m_pTreeList->setModel(m_pSortProxy);
|
m_pTreeList->setModel(m_pSortProxy);
|
||||||
m_pSortProxy->setView(m_pTreeList);
|
|
||||||
|
|
||||||
|
|
||||||
QStyle* pStyle = QStyleFactory::create("windows");
|
QStyle* pStyle = QStyleFactory::create("windows");
|
||||||
m_pTreeList->setStyle(pStyle);
|
m_pTreeList->setStyle(pStyle);
|
||||||
|
@ -163,8 +182,6 @@ CTraceView::CTraceView(bool bStandAlone, QWidget* parent) : QWidget(parent)
|
||||||
m_LastCount = 0;
|
m_LastCount = 0;
|
||||||
m_bUpdatePending = false;
|
m_bUpdatePending = false;
|
||||||
|
|
||||||
m_bHighLight = false;
|
|
||||||
//m_FilterCol = -1;
|
|
||||||
m_FilterPid = 0;
|
m_FilterPid = 0;
|
||||||
m_FilterTid = 0;
|
m_FilterTid = 0;
|
||||||
m_FilterStatus = 0;
|
m_FilterStatus = 0;
|
||||||
|
@ -177,7 +194,7 @@ CTraceView::CTraceView(bool bStandAlone, QWidget* parent) : QWidget(parent)
|
||||||
|
|
||||||
m_pMonitorMode = m_pTraceToolBar->addAction(CSandMan::GetIcon("Monitor"), tr("Monitor mode"), this, SLOT(OnSetMode()));
|
m_pMonitorMode = m_pTraceToolBar->addAction(CSandMan::GetIcon("Monitor"), tr("Monitor mode"), this, SLOT(OnSetMode()));
|
||||||
m_pMonitorMode->setCheckable(true);
|
m_pMonitorMode->setCheckable(true);
|
||||||
m_pMonitorMode->setChecked(theConf->GetBool("Options/UseMonitorMode"));
|
m_pMonitorMode->setChecked(theConf->GetBool("Options/UseMonitorMode", true));
|
||||||
|
|
||||||
m_pTraceTree = m_pTraceToolBar->addAction(CSandMan::GetIcon("Tree"), tr("Show as task tree"), this, SLOT(OnSetTree()));
|
m_pTraceTree = m_pTraceToolBar->addAction(CSandMan::GetIcon("Tree"), tr("Show as task tree"), this, SLOT(OnSetTree()));
|
||||||
m_pTraceTree->setCheckable(true);
|
m_pTraceTree->setCheckable(true);
|
||||||
|
@ -258,7 +275,7 @@ CTraceView::CTraceView(bool bStandAlone, QWidget* parent) : QWidget(parent)
|
||||||
|
|
||||||
m_pLayout->addWidget(m_pTrace);
|
m_pLayout->addWidget(m_pTrace);
|
||||||
|
|
||||||
QObject::connect(m_pTrace, SIGNAL(FilterSet(const QString&, int, int)), this, SLOT(SetFilter(const QString&, int, int)));
|
QObject::connect(m_pTrace, SIGNAL(FilterChanged()), this, SLOT(OnFilterChanged()));
|
||||||
|
|
||||||
m_pMonitor = new CMonitorList(this);
|
m_pMonitor = new CMonitorList(this);
|
||||||
m_pMonitor->m_pMonitorModel->SetObjTree(m_pObjectTree->isChecked());
|
m_pMonitor->m_pMonitorModel->SetObjTree(m_pObjectTree->isChecked());
|
||||||
|
@ -335,8 +352,8 @@ void CTraceView::Refresh()
|
||||||
if (m_LastCount == ResourceLog.count())
|
if (m_LastCount == ResourceLog.count())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//bool bHasFilter = !m_FilterExp.pattern().isEmpty();
|
//bool bHasFilter = !m_pTrace->m_FilterExp.pattern().isEmpty();
|
||||||
bool bHasFilter = !m_FilterExp.isEmpty();
|
bool bHasFilter = !m_pTrace->m_FilterExp.isEmpty();
|
||||||
|
|
||||||
quint64 start = GetCurCycle();
|
quint64 start = GetCurCycle();
|
||||||
for (; i < ResourceLog.count(); i++)
|
for (; i < ResourceLog.count(); i++)
|
||||||
|
@ -381,12 +398,12 @@ void CTraceView::Refresh()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bHasFilter && !m_bHighLight) {
|
if (bHasFilter && !m_pTrace->m_bHighLight) {
|
||||||
if (!pEntry->GetName().contains(m_FilterExp)
|
if (!pEntry->GetName().contains(m_pTrace->m_FilterExp)
|
||||||
&& !pEntry->GetMessage().contains(m_FilterExp)
|
&& !pEntry->GetMessage().contains(m_pTrace->m_FilterExp)
|
||||||
//&& !pEntry->GetTypeStr().contains(m_FilterExp) // dont filter on non static strings !!!
|
//&& !pEntry->GetTypeStr().contains(m_pTrace->m_FilterExp) // dont filter on non static strings !!!
|
||||||
//&& !pEntry->GetStautsStr().contains(m_FilterExp) // dont filter on non static strings !!!
|
//&& !pEntry->GetStautsStr().contains(m_pTrace->m_FilterExp) // dont filter on non static strings !!!
|
||||||
&& !pEntry->GetProcessName().contains(m_FilterExp))
|
&& !pEntry->GetProcessName().contains(m_pTrace->m_FilterExp))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,6 +451,11 @@ void CTraceView::Refresh()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (m_pTrace->m_bHighLight)
|
||||||
|
m_pTrace->m_pTraceModel->SetHighLight(m_pTrace->m_FilterExp);
|
||||||
|
else
|
||||||
|
m_pTrace->m_pTraceModel->SetHighLight(QString());
|
||||||
|
|
||||||
quint64 start = GetCurCycle();
|
quint64 start = GetCurCycle();
|
||||||
QList<QModelIndex> NewBranches = m_pTrace->m_pTraceModel->Sync(m_TraceList);
|
QList<QModelIndex> NewBranches = m_pTrace->m_pTraceModel->Sync(m_TraceList);
|
||||||
qDebug() << "Sync took" << (GetCurCycle() - start) / 1000000.0 << "s";
|
qDebug() << "Sync took" << (GetCurCycle() - start) / 1000000.0 << "s";
|
||||||
|
@ -538,15 +560,8 @@ void CTraceView::UpdateFilters()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraceView::SetFilter(const QString& Exp, int iOptions, int Col)
|
void CTraceView::OnFilterChanged()
|
||||||
{
|
{
|
||||||
//QString ExpStr = ((iOptions & CFinder::eRegExp) == 0) ? Exp : (".*" + QRegularExpression::escape(Exp) + ".*");
|
|
||||||
//QRegularExpression RegExp(ExpStr, (iOptions & CFinder::eCaseSens) != 0 ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption);
|
|
||||||
//m_FilterExp = RegExp;
|
|
||||||
m_FilterExp = Exp;
|
|
||||||
m_bHighLight = (iOptions & CFinder::eHighLight) != 0;
|
|
||||||
//m_FilterCol = Col;
|
|
||||||
|
|
||||||
m_FullRefresh = true;
|
m_FullRefresh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,7 +641,7 @@ void CTraceView::SaveToFile()
|
||||||
const CTraceEntryPtr& pEntry = ResourceLog.at(i);
|
const CTraceEntryPtr& pEntry = ResourceLog.at(i);
|
||||||
|
|
||||||
QStringList Line;
|
QStringList Line;
|
||||||
Line.append(pEntry->GetTimeStamp().toString("hh:mm:ss.zzz"));
|
Line.append(QDateTime::fromMSecsSinceEpoch(pEntry->GetTimeStamp()).toString("hh:mm:ss.zzz"));
|
||||||
QString Name = pEntry->GetProcessName();
|
QString Name = pEntry->GetProcessName();
|
||||||
Line.append(Name.isEmpty() ? tr("Unknown") : Name);
|
Line.append(Name.isEmpty() ? tr("Unknown") : Name);
|
||||||
Line.append(QString("%1").arg(pEntry->GetProcessId()));
|
Line.append(QString("%1").arg(pEntry->GetProcessId()));
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#include "../Models/SbieModel.h"
|
#include "../Models/SbieModel.h"
|
||||||
#include "../Models/TraceModel.h"
|
#include "../Models/TraceModel.h"
|
||||||
#include "../Models/MonitorModel.h"
|
#include "../Models/MonitorModel.h"
|
||||||
|
#include "../../MiscHelpers/Common/SortFilterProxyModel.h"
|
||||||
|
|
||||||
class CTraceFilterProxyModel;
|
|
||||||
|
|
||||||
class CTraceTree : public CPanelWidget<QTreeViewEx>
|
class CTraceTree : public CPanelWidget<QTreeViewEx>
|
||||||
{
|
{
|
||||||
|
@ -19,13 +19,20 @@ public:
|
||||||
CTraceModel* m_pTraceModel;
|
CTraceModel* m_pTraceModel;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void SetFilter(const QString& Exp, int iOptions = 0, int Column = -1) {
|
void SetFilter(const QString& Exp, int iOptions = 0, int Column = -1);
|
||||||
emit FilterSet(Exp, iOptions, Column);
|
|
||||||
}
|
|
||||||
void SelectNext() {}
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void FilterSet(const QString& Exp, int iOptions = 0, int Column = -1);
|
void FilterChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class CTraceView;
|
||||||
|
|
||||||
|
QString GetFilterExp() const { return m_FilterExp; }
|
||||||
|
|
||||||
|
//QRegularExpression m_FilterExp;
|
||||||
|
QString m_FilterExp;
|
||||||
|
bool m_bHighLight;
|
||||||
|
//int m_FilterCol;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMonitorList : public CPanelWidget<QTreeViewEx>
|
class CMonitorList : public CPanelWidget<QTreeViewEx>
|
||||||
|
@ -61,7 +68,7 @@ public slots:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void UpdateFilters();
|
void UpdateFilters();
|
||||||
void SetFilter(const QString& Exp, int iOptions = 0, int Col = -1); // -1 = any
|
void OnFilterChanged();
|
||||||
|
|
||||||
void SaveToFile();
|
void SaveToFile();
|
||||||
|
|
||||||
|
@ -85,10 +92,6 @@ protected:
|
||||||
protected:
|
protected:
|
||||||
bool m_FullRefresh;
|
bool m_FullRefresh;
|
||||||
|
|
||||||
//QRegularExpression m_FilterExp;
|
|
||||||
QString m_FilterExp;
|
|
||||||
bool m_bHighLight;
|
|
||||||
//int m_FilterCol;
|
|
||||||
quint32 m_FilterPid;
|
quint32 m_FilterPid;
|
||||||
quint32 m_FilterTid;
|
quint32 m_FilterTid;
|
||||||
QList<quint32> m_FilterTypes;
|
QList<quint32> m_FilterTypes;
|
||||||
|
|
|
@ -65,7 +65,7 @@ CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, bool bImmediate, QWidg
|
||||||
|
|
||||||
ui.btnDeleteAll->setVisible(false);
|
ui.btnDeleteAll->setVisible(false);
|
||||||
|
|
||||||
m_pFileModel = new CSimpleTreeModel();
|
m_pFileModel = new CSimpleTreeModel(this);
|
||||||
m_pFileModel->SetUseIcons(true);
|
m_pFileModel->SetUseIcons(true);
|
||||||
m_pFileModel->AddColumn(tr("File Name"), "FileName");
|
m_pFileModel->AddColumn(tr("File Name"), "FileName");
|
||||||
m_pFileModel->AddColumn(tr("File Size"), "FileSize");
|
m_pFileModel->AddColumn(tr("File Size"), "FileSize");
|
||||||
|
@ -79,13 +79,14 @@ CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, bool bImmediate, QWidg
|
||||||
//ui.treeFiles->setItemDelegate(theGUI->GetItemDelegate());
|
//ui.treeFiles->setItemDelegate(theGUI->GetItemDelegate());
|
||||||
|
|
||||||
ui.treeFiles->setModel(m_pSortProxy);
|
ui.treeFiles->setModel(m_pSortProxy);
|
||||||
((CSortFilterProxyModel*)m_pSortProxy)->setView(ui.treeFiles);
|
|
||||||
|
|
||||||
ui.treeFiles->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
ui.treeFiles->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
ui.treeFiles->setSortingEnabled(true);
|
ui.treeFiles->setSortingEnabled(true);
|
||||||
//ui.treeFiles->setUniformRowHeights(true);
|
//ui.treeFiles->setUniformRowHeights(true);
|
||||||
|
|
||||||
ui.gridLayout->addWidget(new CFinder(m_pSortProxy, this, true), 3, 0, 1, 5);
|
CFinder* pFinder = new CFinder(m_pSortProxy, this);
|
||||||
|
ui.gridLayout->addWidget(pFinder, 3, 0, 1, 5);
|
||||||
|
pFinder->SetTree(ui.treeFiles);
|
||||||
ui.finder->deleteLater(); // remove place holder
|
ui.finder->deleteLater(); // remove place holder
|
||||||
|
|
||||||
//connect(ui.treeFiles, SIGNAL(clicked(const QModelIndex&)), this, SLOT(UpdateSnapshot(const QModelIndex&)));
|
//connect(ui.treeFiles, SIGNAL(clicked(const QModelIndex&)), this, SLOT(UpdateSnapshot(const QModelIndex&)));
|
||||||
|
|
|
@ -34,7 +34,7 @@ CSnapshotsWindow::CSnapshotsWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
||||||
ui.treeSnapshots->setItemDelegate(new CTreeItemDelegate());
|
ui.treeSnapshots->setItemDelegate(new CTreeItemDelegate());
|
||||||
ui.treeSnapshots->setExpandsOnDoubleClick(false);
|
ui.treeSnapshots->setExpandsOnDoubleClick(false);
|
||||||
|
|
||||||
m_pSnapshotModel = new CSimpleTreeModel();
|
m_pSnapshotModel = new CSimpleTreeModel(this);
|
||||||
m_pSnapshotModel->AddColumn(tr("Snapshot"), "Name");
|
m_pSnapshotModel->AddColumn(tr("Snapshot"), "Name");
|
||||||
|
|
||||||
/*m_pSortProxy = new CSortFilterProxyModel(this);
|
/*m_pSortProxy = new CSortFilterProxyModel(this);
|
||||||
|
|
Loading…
Reference in New Issue