Normalize line endings
This commit is contained in:
parent
7e380b8c94
commit
39a431e007
2552
CHANGELOG.md
2552
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,164 +1,164 @@
|
|||
#include "stdafx.h"
|
||||
#include "Finder.h"
|
||||
|
||||
bool CFinder::m_DarkMode = false;
|
||||
|
||||
QWidget* CFinder::AddFinder(QWidget* pList, QObject* pFilterTarget, bool HighLightOption, CFinder** ppFinder)
|
||||
{
|
||||
QWidget* pWidget = new QWidget();
|
||||
QVBoxLayout* pLayout = new QVBoxLayout();
|
||||
pLayout->setMargin(0);
|
||||
pWidget->setLayout(pLayout);
|
||||
|
||||
pLayout->addWidget(pList);
|
||||
CFinder* pFinder = new CFinder(pFilterTarget, pWidget, HighLightOption);
|
||||
pLayout->addWidget(pFinder);
|
||||
|
||||
if (ppFinder)
|
||||
*ppFinder = pFinder;
|
||||
return pWidget;
|
||||
}
|
||||
|
||||
CFinder::CFinder(QObject* pFilterTarget, QWidget *parent, bool HighLightOption)
|
||||
:QWidget(parent)
|
||||
{
|
||||
m_pSearchLayout = new QHBoxLayout();
|
||||
m_pSearchLayout->setMargin(0);
|
||||
m_pSearchLayout->setSpacing(3);
|
||||
m_pSearchLayout->setAlignment(Qt::AlignLeft);
|
||||
|
||||
m_pSearch = new QLineEdit();
|
||||
m_pSearch->setMinimumWidth(150);
|
||||
m_pSearch->setMaximumWidth(350);
|
||||
m_pSearchLayout->addWidget(m_pSearch);
|
||||
QObject::connect(m_pSearch, SIGNAL(textChanged(QString)), this, SLOT(OnText()));
|
||||
QObject::connect(m_pSearch, SIGNAL(returnPressed()), this, SLOT(OnReturn()));
|
||||
|
||||
m_pCaseSensitive = new QCheckBox(tr("Case Sensitive"));
|
||||
m_pSearchLayout->addWidget(m_pCaseSensitive);
|
||||
connect(m_pCaseSensitive, SIGNAL(stateChanged(int)), this, SLOT(OnUpdate()));
|
||||
|
||||
m_pRegExp = new QCheckBox(tr("RegExp"));
|
||||
m_pSearchLayout->addWidget(m_pRegExp);
|
||||
connect(m_pRegExp, SIGNAL(stateChanged(int)), this, SLOT(OnUpdate()));
|
||||
|
||||
m_pColumn = new QComboBox();
|
||||
m_pSearchLayout->addWidget(m_pColumn);
|
||||
connect(m_pColumn, SIGNAL(currentIndexChanged(int)), this, SLOT(OnUpdate()));
|
||||
m_pColumn->setVisible(false);
|
||||
|
||||
if (HighLightOption)
|
||||
{
|
||||
m_pHighLight = new QCheckBox(tr("Highlight"));
|
||||
//m_pHighLight->setChecked(true);
|
||||
m_pSearchLayout->addWidget(m_pHighLight);
|
||||
connect(m_pHighLight, SIGNAL(stateChanged(int)), this, SLOT(OnUpdate()));
|
||||
}
|
||||
else
|
||||
m_pHighLight = NULL;
|
||||
|
||||
QToolButton* pClose = new QToolButton(this);
|
||||
pClose->setIcon(QIcon(":/close.png"));
|
||||
pClose->setAutoRaise(true);
|
||||
pClose->setText(tr("Close"));
|
||||
m_pSearchLayout->addWidget(pClose);
|
||||
QObject::connect(pClose, SIGNAL(clicked()), this, SLOT(Close()));
|
||||
|
||||
QWidget* pSpacer = new QWidget();
|
||||
pSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_pSearchLayout->addWidget(pSpacer);
|
||||
|
||||
setLayout(m_pSearchLayout);
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
||||
//setMaximumHeight(30);
|
||||
|
||||
hide();
|
||||
|
||||
if (parent)
|
||||
{
|
||||
QAction* pFind = new QAction(tr("&Find ..."), parent);
|
||||
pFind->setShortcut(QKeySequence::Find);
|
||||
pFind->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||
parent->addAction(pFind);
|
||||
QObject::connect(pFind, SIGNAL(triggered()), this, SLOT(Open()));
|
||||
}
|
||||
|
||||
m_pSortProxy = qobject_cast<QSortFilterProxyModel*>(pFilterTarget);
|
||||
if (pFilterTarget) {
|
||||
QObject::connect(this, SIGNAL(SetFilter(const QRegExp&, bool, int)), pFilterTarget, SLOT(SetFilter(const QRegExp&, bool, int)));
|
||||
QObject::connect(this, SIGNAL(SelectNext()), pFilterTarget, SLOT(SelectNext()));
|
||||
}
|
||||
|
||||
m_pTimer = new QTimer(this);
|
||||
m_pTimer->setSingleShot(true);
|
||||
m_pTimer->setInterval(500);
|
||||
connect(m_pTimer, SIGNAL(timeout()), SLOT(OnUpdate()));
|
||||
|
||||
this->installEventFilter(this);
|
||||
}
|
||||
|
||||
CFinder::~CFinder()
|
||||
{
|
||||
}
|
||||
|
||||
bool CFinder::eventFilter(QObject* source, QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress && ((QKeyEvent*)event)->key() == Qt::Key_Escape
|
||||
&& ((QKeyEvent*)event)->modifiers() == Qt::NoModifier)
|
||||
{
|
||||
Close();
|
||||
return true; // cancel event
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(source, event);
|
||||
}
|
||||
|
||||
void CFinder::Open()
|
||||
{
|
||||
if (m_pSortProxy && m_pColumn->count() == 0)
|
||||
{
|
||||
m_pColumn->addItem(tr("All columns"), -1);
|
||||
for (int i = 0; i < m_pSortProxy->columnCount(); i++)
|
||||
m_pColumn->addItem(m_pSortProxy->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(), i);
|
||||
m_pColumn->setVisible(true);
|
||||
}
|
||||
|
||||
show();
|
||||
m_pSearch->setFocus(Qt::OtherFocusReason);
|
||||
m_pSearch->selectAll();
|
||||
OnUpdate();
|
||||
}
|
||||
|
||||
QRegExp CFinder::GetRegExp() const
|
||||
{
|
||||
if (!isVisible())
|
||||
return QRegExp();
|
||||
return QRegExp(m_pSearch->text(), m_pCaseSensitive->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive, m_pRegExp->isChecked() ? QRegExp::RegExp : QRegExp::FixedString);
|
||||
}
|
||||
|
||||
void CFinder::OnUpdate()
|
||||
{
|
||||
m_pTimer->stop();
|
||||
emit SetFilter(GetRegExp(), GetHighLight(), GetColumn());
|
||||
}
|
||||
|
||||
void CFinder::OnText()
|
||||
{
|
||||
m_pTimer->stop();
|
||||
m_pTimer->start();
|
||||
}
|
||||
|
||||
void CFinder::OnReturn()
|
||||
{
|
||||
OnUpdate();
|
||||
if (m_pHighLight->isChecked())
|
||||
emit SelectNext();
|
||||
}
|
||||
|
||||
void CFinder::Close()
|
||||
{
|
||||
emit SetFilter(QRegExp());
|
||||
hide();
|
||||
#include "stdafx.h"
|
||||
#include "Finder.h"
|
||||
|
||||
bool CFinder::m_DarkMode = false;
|
||||
|
||||
QWidget* CFinder::AddFinder(QWidget* pList, QObject* pFilterTarget, bool HighLightOption, CFinder** ppFinder)
|
||||
{
|
||||
QWidget* pWidget = new QWidget();
|
||||
QVBoxLayout* pLayout = new QVBoxLayout();
|
||||
pLayout->setMargin(0);
|
||||
pWidget->setLayout(pLayout);
|
||||
|
||||
pLayout->addWidget(pList);
|
||||
CFinder* pFinder = new CFinder(pFilterTarget, pWidget, HighLightOption);
|
||||
pLayout->addWidget(pFinder);
|
||||
|
||||
if (ppFinder)
|
||||
*ppFinder = pFinder;
|
||||
return pWidget;
|
||||
}
|
||||
|
||||
CFinder::CFinder(QObject* pFilterTarget, QWidget *parent, bool HighLightOption)
|
||||
:QWidget(parent)
|
||||
{
|
||||
m_pSearchLayout = new QHBoxLayout();
|
||||
m_pSearchLayout->setMargin(0);
|
||||
m_pSearchLayout->setSpacing(3);
|
||||
m_pSearchLayout->setAlignment(Qt::AlignLeft);
|
||||
|
||||
m_pSearch = new QLineEdit();
|
||||
m_pSearch->setMinimumWidth(150);
|
||||
m_pSearch->setMaximumWidth(350);
|
||||
m_pSearchLayout->addWidget(m_pSearch);
|
||||
QObject::connect(m_pSearch, SIGNAL(textChanged(QString)), this, SLOT(OnText()));
|
||||
QObject::connect(m_pSearch, SIGNAL(returnPressed()), this, SLOT(OnReturn()));
|
||||
|
||||
m_pCaseSensitive = new QCheckBox(tr("Case Sensitive"));
|
||||
m_pSearchLayout->addWidget(m_pCaseSensitive);
|
||||
connect(m_pCaseSensitive, SIGNAL(stateChanged(int)), this, SLOT(OnUpdate()));
|
||||
|
||||
m_pRegExp = new QCheckBox(tr("RegExp"));
|
||||
m_pSearchLayout->addWidget(m_pRegExp);
|
||||
connect(m_pRegExp, SIGNAL(stateChanged(int)), this, SLOT(OnUpdate()));
|
||||
|
||||
m_pColumn = new QComboBox();
|
||||
m_pSearchLayout->addWidget(m_pColumn);
|
||||
connect(m_pColumn, SIGNAL(currentIndexChanged(int)), this, SLOT(OnUpdate()));
|
||||
m_pColumn->setVisible(false);
|
||||
|
||||
if (HighLightOption)
|
||||
{
|
||||
m_pHighLight = new QCheckBox(tr("Highlight"));
|
||||
//m_pHighLight->setChecked(true);
|
||||
m_pSearchLayout->addWidget(m_pHighLight);
|
||||
connect(m_pHighLight, SIGNAL(stateChanged(int)), this, SLOT(OnUpdate()));
|
||||
}
|
||||
else
|
||||
m_pHighLight = NULL;
|
||||
|
||||
QToolButton* pClose = new QToolButton(this);
|
||||
pClose->setIcon(QIcon(":/close.png"));
|
||||
pClose->setAutoRaise(true);
|
||||
pClose->setText(tr("Close"));
|
||||
m_pSearchLayout->addWidget(pClose);
|
||||
QObject::connect(pClose, SIGNAL(clicked()), this, SLOT(Close()));
|
||||
|
||||
QWidget* pSpacer = new QWidget();
|
||||
pSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_pSearchLayout->addWidget(pSpacer);
|
||||
|
||||
setLayout(m_pSearchLayout);
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
||||
//setMaximumHeight(30);
|
||||
|
||||
hide();
|
||||
|
||||
if (parent)
|
||||
{
|
||||
QAction* pFind = new QAction(tr("&Find ..."), parent);
|
||||
pFind->setShortcut(QKeySequence::Find);
|
||||
pFind->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||
parent->addAction(pFind);
|
||||
QObject::connect(pFind, SIGNAL(triggered()), this, SLOT(Open()));
|
||||
}
|
||||
|
||||
m_pSortProxy = qobject_cast<QSortFilterProxyModel*>(pFilterTarget);
|
||||
if (pFilterTarget) {
|
||||
QObject::connect(this, SIGNAL(SetFilter(const QRegExp&, bool, int)), pFilterTarget, SLOT(SetFilter(const QRegExp&, bool, int)));
|
||||
QObject::connect(this, SIGNAL(SelectNext()), pFilterTarget, SLOT(SelectNext()));
|
||||
}
|
||||
|
||||
m_pTimer = new QTimer(this);
|
||||
m_pTimer->setSingleShot(true);
|
||||
m_pTimer->setInterval(500);
|
||||
connect(m_pTimer, SIGNAL(timeout()), SLOT(OnUpdate()));
|
||||
|
||||
this->installEventFilter(this);
|
||||
}
|
||||
|
||||
CFinder::~CFinder()
|
||||
{
|
||||
}
|
||||
|
||||
bool CFinder::eventFilter(QObject* source, QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress && ((QKeyEvent*)event)->key() == Qt::Key_Escape
|
||||
&& ((QKeyEvent*)event)->modifiers() == Qt::NoModifier)
|
||||
{
|
||||
Close();
|
||||
return true; // cancel event
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(source, event);
|
||||
}
|
||||
|
||||
void CFinder::Open()
|
||||
{
|
||||
if (m_pSortProxy && m_pColumn->count() == 0)
|
||||
{
|
||||
m_pColumn->addItem(tr("All columns"), -1);
|
||||
for (int i = 0; i < m_pSortProxy->columnCount(); i++)
|
||||
m_pColumn->addItem(m_pSortProxy->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(), i);
|
||||
m_pColumn->setVisible(true);
|
||||
}
|
||||
|
||||
show();
|
||||
m_pSearch->setFocus(Qt::OtherFocusReason);
|
||||
m_pSearch->selectAll();
|
||||
OnUpdate();
|
||||
}
|
||||
|
||||
QRegExp CFinder::GetRegExp() const
|
||||
{
|
||||
if (!isVisible())
|
||||
return QRegExp();
|
||||
return QRegExp(m_pSearch->text(), m_pCaseSensitive->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive, m_pRegExp->isChecked() ? QRegExp::RegExp : QRegExp::FixedString);
|
||||
}
|
||||
|
||||
void CFinder::OnUpdate()
|
||||
{
|
||||
m_pTimer->stop();
|
||||
emit SetFilter(GetRegExp(), GetHighLight(), GetColumn());
|
||||
}
|
||||
|
||||
void CFinder::OnText()
|
||||
{
|
||||
m_pTimer->stop();
|
||||
m_pTimer->start();
|
||||
}
|
||||
|
||||
void CFinder::OnReturn()
|
||||
{
|
||||
OnUpdate();
|
||||
if (m_pHighLight->isChecked())
|
||||
emit SelectNext();
|
||||
}
|
||||
|
||||
void CFinder::Close()
|
||||
{
|
||||
emit SetFilter(QRegExp());
|
||||
hide();
|
||||
}
|
|
@ -1,53 +1,53 @@
|
|||
#pragma once
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../mischelpers_global.h"
|
||||
|
||||
class MISCHELPERS_EXPORT CFinder: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CFinder(QObject* pFilterTarget, QWidget *parent = NULL, bool HighLightOption = true);
|
||||
~CFinder();
|
||||
|
||||
static void SetDarkMode(bool bDarkMode) { m_DarkMode = bDarkMode; }
|
||||
static bool GetDarkMode() { return m_DarkMode; }
|
||||
|
||||
static QWidget* AddFinder(QWidget* pList, QObject* pFilterTarget, bool HighLightOption = true, CFinder** ppFinder = NULL);
|
||||
|
||||
QRegExp GetRegExp() const;
|
||||
bool GetHighLight() const { return m_pHighLight ? m_pHighLight->isChecked() : false; }
|
||||
int GetColumn() const { return m_pColumn->currentData().toInt(); }
|
||||
|
||||
signals:
|
||||
void SetFilter(const QRegExp& Exp, bool bHighLight = false, int Column = -1);
|
||||
void SelectNext();
|
||||
|
||||
public slots:
|
||||
void Open();
|
||||
void Close();
|
||||
|
||||
private slots:
|
||||
void OnUpdate();
|
||||
void OnText();
|
||||
void OnReturn();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* source, QEvent* event);
|
||||
|
||||
private:
|
||||
|
||||
QHBoxLayout* m_pSearchLayout;
|
||||
|
||||
QLineEdit* m_pSearch;
|
||||
QCheckBox* m_pCaseSensitive;
|
||||
QCheckBox* m_pRegExp;
|
||||
QComboBox* m_pColumn;
|
||||
QCheckBox* m_pHighLight;
|
||||
|
||||
QSortFilterProxyModel* m_pSortProxy;
|
||||
|
||||
QTimer* m_pTimer;
|
||||
|
||||
static bool m_DarkMode;
|
||||
class MISCHELPERS_EXPORT CFinder: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CFinder(QObject* pFilterTarget, QWidget *parent = NULL, bool HighLightOption = true);
|
||||
~CFinder();
|
||||
|
||||
static void SetDarkMode(bool bDarkMode) { m_DarkMode = bDarkMode; }
|
||||
static bool GetDarkMode() { return m_DarkMode; }
|
||||
|
||||
static QWidget* AddFinder(QWidget* pList, QObject* pFilterTarget, bool HighLightOption = true, CFinder** ppFinder = NULL);
|
||||
|
||||
QRegExp GetRegExp() const;
|
||||
bool GetHighLight() const { return m_pHighLight ? m_pHighLight->isChecked() : false; }
|
||||
int GetColumn() const { return m_pColumn->currentData().toInt(); }
|
||||
|
||||
signals:
|
||||
void SetFilter(const QRegExp& Exp, bool bHighLight = false, int Column = -1);
|
||||
void SelectNext();
|
||||
|
||||
public slots:
|
||||
void Open();
|
||||
void Close();
|
||||
|
||||
private slots:
|
||||
void OnUpdate();
|
||||
void OnText();
|
||||
void OnReturn();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* source, QEvent* event);
|
||||
|
||||
private:
|
||||
|
||||
QHBoxLayout* m_pSearchLayout;
|
||||
|
||||
QLineEdit* m_pSearch;
|
||||
QCheckBox* m_pCaseSensitive;
|
||||
QCheckBox* m_pRegExp;
|
||||
QComboBox* m_pColumn;
|
||||
QCheckBox* m_pHighLight;
|
||||
|
||||
QSortFilterProxyModel* m_pSortProxy;
|
||||
|
||||
QTimer* m_pTimer;
|
||||
|
||||
static bool m_DarkMode;
|
||||
};
|
|
@ -1,226 +1,226 @@
|
|||
#include "stdafx.h"
|
||||
#include "PanelView.h"
|
||||
|
||||
bool CPanelView::m_SimpleFormat = false;
|
||||
bool CPanelView::m_DarkMode = false;
|
||||
int CPanelView::m_MaxCellWidth = 0;
|
||||
QString CPanelView::m_CellSeparator = "\t";
|
||||
|
||||
QString CPanelView::m_CopyCell = "Copy Cell";
|
||||
QString CPanelView::m_CopyRow = "Copy Row";
|
||||
QString CPanelView::m_CopyPanel = "Copy Panel";
|
||||
|
||||
CPanelView::CPanelView(QWidget *parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
//m_CopyAll = false;
|
||||
|
||||
m_pMenu = new QMenu();
|
||||
}
|
||||
|
||||
CPanelView::~CPanelView()
|
||||
{
|
||||
}
|
||||
|
||||
void CPanelView::AddPanelItemsToMenu(bool bAddSeparator)
|
||||
{
|
||||
if(bAddSeparator)
|
||||
m_pMenu->addSeparator();
|
||||
m_pCopyCell = m_pMenu->addAction(m_CopyCell, this, SLOT(OnCopyCell()));
|
||||
m_pCopyRow = m_pMenu->addAction(m_CopyRow, this, SLOT(OnCopyRow()));
|
||||
m_pCopyRow->setShortcut(QKeySequence::Copy);
|
||||
m_pCopyRow->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||
this->addAction(m_pCopyRow);
|
||||
m_pCopyPanel = m_pMenu->addAction(m_CopyPanel, this, SLOT(OnCopyPanel()));
|
||||
}
|
||||
|
||||
void CPanelView::OnMenu(const QPoint& Point)
|
||||
{
|
||||
QModelIndex Index = GetView()->currentIndex();
|
||||
|
||||
m_pCopyCell->setEnabled(Index.isValid());
|
||||
m_pCopyRow->setEnabled(Index.isValid());
|
||||
m_pCopyPanel->setEnabled(true);
|
||||
|
||||
m_pMenu->popup(QCursor::pos());
|
||||
}
|
||||
|
||||
void CPanelView::OnCopyCell()
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
QTreeView * pView = GetView();
|
||||
|
||||
QModelIndex Index = pView->currentIndex();
|
||||
QModelIndex ModelIndex = MapToSource(Index);
|
||||
int Column = ModelIndex.column();
|
||||
|
||||
QList<QStringList> Rows;
|
||||
foreach(const QModelIndex& Index, pView->selectionModel()->selectedIndexes())
|
||||
{
|
||||
if (Index.column() != Column)
|
||||
continue;
|
||||
QModelIndex CurIndex = pModel->index(Index.row(), Column, Index.parent());
|
||||
QString Cell = pModel->data(CurIndex, Qt::DisplayRole).toString();
|
||||
Rows.append(QStringList() << Cell);
|
||||
}
|
||||
FormatAndCopy(Rows, false);
|
||||
}
|
||||
|
||||
void CPanelView::OnCopyRow()
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
QTreeView * pView = GetView();
|
||||
|
||||
int Column = 0; // find first not hidden column
|
||||
for (int i = 0; i < pModel->columnCount(); i++)
|
||||
{
|
||||
if (!pView->isColumnHidden(i) || m_ForcedColumns.contains(i))
|
||||
{
|
||||
Column = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QList<QStringList> Rows;
|
||||
foreach(const QModelIndex& Index, pView->selectionModel()->selectedIndexes())
|
||||
{
|
||||
if (Index.column() != Column)
|
||||
continue;
|
||||
|
||||
QModelIndex ModelIndex = MapToSource(Index);
|
||||
Rows.append(CopyRow(ModelIndex));
|
||||
}
|
||||
FormatAndCopy(Rows);
|
||||
}
|
||||
|
||||
QStringList CPanelView::CopyHeader()
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
QTreeView * pView = GetView();
|
||||
|
||||
QStringList Headder;
|
||||
for (int i = 0; i < pModel->columnCount(); i++)
|
||||
{
|
||||
if (/*!m_CopyAll &&*/ pView->isColumnHidden(i) && !m_ForcedColumns.contains(i))
|
||||
continue;
|
||||
QString Cell = pModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
if (!m_SimpleFormat)
|
||||
Cell = "|" + Cell + "|";
|
||||
Headder.append(Cell);
|
||||
}
|
||||
return Headder;
|
||||
}
|
||||
|
||||
QStringList CPanelView::CopyRow(const QModelIndex& ModelIndex, int Level)
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
QTreeView * pView = GetView();
|
||||
|
||||
QStringList Cells;
|
||||
for (int i = 0; i < pModel->columnCount(); i++)
|
||||
{
|
||||
if (/*!m_CopyAll &&*/ pView->isColumnHidden(i) && !m_ForcedColumns.contains(i))
|
||||
continue;
|
||||
QModelIndex CellIndex = pModel->index(ModelIndex.row(), i, ModelIndex.parent());
|
||||
QString Cell = pModel->data(CellIndex, Qt::DisplayRole).toString();
|
||||
if (Level && i == 0)
|
||||
Cell.prepend(QString(Level, '_') + " ");
|
||||
Cells.append(Cell);
|
||||
}
|
||||
return Cells;
|
||||
}
|
||||
|
||||
void CPanelView::RecursiveCopyPanel(const QModelIndex& ModelIndex, QList<QStringList>& Rows, int Level)
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
|
||||
Rows.append(CopyRow(ModelIndex, Level));
|
||||
|
||||
for (int i = 0; i < pModel->rowCount(ModelIndex); i++)
|
||||
{
|
||||
QModelIndex SubIndex = pModel->index(i, 0, ModelIndex);
|
||||
RecursiveCopyPanel(SubIndex, Rows, Level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void CPanelView::OnCopyPanel()
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
|
||||
QList<QStringList> Rows;
|
||||
for (int i = 0; i < pModel->rowCount(); ++i)
|
||||
{
|
||||
QModelIndex ModelIndex = pModel->index(i, 0);
|
||||
RecursiveCopyPanel(ModelIndex, Rows);
|
||||
}
|
||||
FormatAndCopy(Rows);
|
||||
}
|
||||
|
||||
void CPanelView::FormatAndCopy(QList<QStringList> Rows, bool Headder)
|
||||
{
|
||||
int RowCount = Rows.length();
|
||||
|
||||
if (Headder)
|
||||
{
|
||||
Rows.prepend(QStringList());
|
||||
Rows.prepend(CopyHeader());
|
||||
Rows.prepend(QStringList());
|
||||
}
|
||||
|
||||
QStringList TextRows;
|
||||
if (m_SimpleFormat || !Headder)
|
||||
{
|
||||
foreach(const QStringList& Row, Rows)
|
||||
TextRows.append(Row.join(m_CellSeparator));
|
||||
}
|
||||
else if(Rows.size() > (Headder ? 3 : 0))
|
||||
{
|
||||
int Columns = Rows[Headder ? 3 : 0].count();
|
||||
QVector<int> ColumnWidths(Columns, 0);
|
||||
|
||||
foreach(const QStringList& Row, Rows)
|
||||
{
|
||||
for (int i = 0; i < Min(Row.count(), Columns); i++)
|
||||
{
|
||||
int CellWidth = Row[i].length();
|
||||
if (ColumnWidths[i] < CellWidth)
|
||||
ColumnWidths[i] = CellWidth;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(const QStringList& Row, Rows)
|
||||
{
|
||||
if (m_MaxCellWidth != 0 && RowCount > 1)
|
||||
{
|
||||
for (int Pos = 0;;Pos += m_MaxCellWidth)
|
||||
{
|
||||
bool More = false;
|
||||
|
||||
QString RowText;
|
||||
for (int i = 0; i < Min(Row.count(), Columns); i++)
|
||||
{
|
||||
if (Row[i].length() > Pos)
|
||||
RowText.append(Row[i].mid(Pos, m_MaxCellWidth).leftJustified(Min(m_MaxCellWidth, ColumnWidths[i]) + 3));
|
||||
else
|
||||
RowText.append(QString(Min(m_MaxCellWidth, ColumnWidths[i]) + 3, ' '));
|
||||
|
||||
if (Row[i].length() > Pos + m_MaxCellWidth)
|
||||
More = true;
|
||||
}
|
||||
TextRows.append(RowText);
|
||||
|
||||
if (!More)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QString RowText;
|
||||
for (int i = 0; i < Min(Row.count(), Columns); i++)
|
||||
RowText.append(Row[i].leftJustified(ColumnWidths[i] + 3));
|
||||
TextRows.append(RowText);
|
||||
}
|
||||
}
|
||||
}
|
||||
QApplication::clipboard()->setText(TextRows.join("\n"));
|
||||
#include "stdafx.h"
|
||||
#include "PanelView.h"
|
||||
|
||||
bool CPanelView::m_SimpleFormat = false;
|
||||
bool CPanelView::m_DarkMode = false;
|
||||
int CPanelView::m_MaxCellWidth = 0;
|
||||
QString CPanelView::m_CellSeparator = "\t";
|
||||
|
||||
QString CPanelView::m_CopyCell = "Copy Cell";
|
||||
QString CPanelView::m_CopyRow = "Copy Row";
|
||||
QString CPanelView::m_CopyPanel = "Copy Panel";
|
||||
|
||||
CPanelView::CPanelView(QWidget *parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
//m_CopyAll = false;
|
||||
|
||||
m_pMenu = new QMenu();
|
||||
}
|
||||
|
||||
CPanelView::~CPanelView()
|
||||
{
|
||||
}
|
||||
|
||||
void CPanelView::AddPanelItemsToMenu(bool bAddSeparator)
|
||||
{
|
||||
if(bAddSeparator)
|
||||
m_pMenu->addSeparator();
|
||||
m_pCopyCell = m_pMenu->addAction(m_CopyCell, this, SLOT(OnCopyCell()));
|
||||
m_pCopyRow = m_pMenu->addAction(m_CopyRow, this, SLOT(OnCopyRow()));
|
||||
m_pCopyRow->setShortcut(QKeySequence::Copy);
|
||||
m_pCopyRow->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||
this->addAction(m_pCopyRow);
|
||||
m_pCopyPanel = m_pMenu->addAction(m_CopyPanel, this, SLOT(OnCopyPanel()));
|
||||
}
|
||||
|
||||
void CPanelView::OnMenu(const QPoint& Point)
|
||||
{
|
||||
QModelIndex Index = GetView()->currentIndex();
|
||||
|
||||
m_pCopyCell->setEnabled(Index.isValid());
|
||||
m_pCopyRow->setEnabled(Index.isValid());
|
||||
m_pCopyPanel->setEnabled(true);
|
||||
|
||||
m_pMenu->popup(QCursor::pos());
|
||||
}
|
||||
|
||||
void CPanelView::OnCopyCell()
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
QTreeView * pView = GetView();
|
||||
|
||||
QModelIndex Index = pView->currentIndex();
|
||||
QModelIndex ModelIndex = MapToSource(Index);
|
||||
int Column = ModelIndex.column();
|
||||
|
||||
QList<QStringList> Rows;
|
||||
foreach(const QModelIndex& Index, pView->selectionModel()->selectedIndexes())
|
||||
{
|
||||
if (Index.column() != Column)
|
||||
continue;
|
||||
QModelIndex CurIndex = pModel->index(Index.row(), Column, Index.parent());
|
||||
QString Cell = pModel->data(CurIndex, Qt::DisplayRole).toString();
|
||||
Rows.append(QStringList() << Cell);
|
||||
}
|
||||
FormatAndCopy(Rows, false);
|
||||
}
|
||||
|
||||
void CPanelView::OnCopyRow()
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
QTreeView * pView = GetView();
|
||||
|
||||
int Column = 0; // find first not hidden column
|
||||
for (int i = 0; i < pModel->columnCount(); i++)
|
||||
{
|
||||
if (!pView->isColumnHidden(i) || m_ForcedColumns.contains(i))
|
||||
{
|
||||
Column = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QList<QStringList> Rows;
|
||||
foreach(const QModelIndex& Index, pView->selectionModel()->selectedIndexes())
|
||||
{
|
||||
if (Index.column() != Column)
|
||||
continue;
|
||||
|
||||
QModelIndex ModelIndex = MapToSource(Index);
|
||||
Rows.append(CopyRow(ModelIndex));
|
||||
}
|
||||
FormatAndCopy(Rows);
|
||||
}
|
||||
|
||||
QStringList CPanelView::CopyHeader()
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
QTreeView * pView = GetView();
|
||||
|
||||
QStringList Headder;
|
||||
for (int i = 0; i < pModel->columnCount(); i++)
|
||||
{
|
||||
if (/*!m_CopyAll &&*/ pView->isColumnHidden(i) && !m_ForcedColumns.contains(i))
|
||||
continue;
|
||||
QString Cell = pModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
if (!m_SimpleFormat)
|
||||
Cell = "|" + Cell + "|";
|
||||
Headder.append(Cell);
|
||||
}
|
||||
return Headder;
|
||||
}
|
||||
|
||||
QStringList CPanelView::CopyRow(const QModelIndex& ModelIndex, int Level)
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
QTreeView * pView = GetView();
|
||||
|
||||
QStringList Cells;
|
||||
for (int i = 0; i < pModel->columnCount(); i++)
|
||||
{
|
||||
if (/*!m_CopyAll &&*/ pView->isColumnHidden(i) && !m_ForcedColumns.contains(i))
|
||||
continue;
|
||||
QModelIndex CellIndex = pModel->index(ModelIndex.row(), i, ModelIndex.parent());
|
||||
QString Cell = pModel->data(CellIndex, Qt::DisplayRole).toString();
|
||||
if (Level && i == 0)
|
||||
Cell.prepend(QString(Level, '_') + " ");
|
||||
Cells.append(Cell);
|
||||
}
|
||||
return Cells;
|
||||
}
|
||||
|
||||
void CPanelView::RecursiveCopyPanel(const QModelIndex& ModelIndex, QList<QStringList>& Rows, int Level)
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
|
||||
Rows.append(CopyRow(ModelIndex, Level));
|
||||
|
||||
for (int i = 0; i < pModel->rowCount(ModelIndex); i++)
|
||||
{
|
||||
QModelIndex SubIndex = pModel->index(i, 0, ModelIndex);
|
||||
RecursiveCopyPanel(SubIndex, Rows, Level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void CPanelView::OnCopyPanel()
|
||||
{
|
||||
QAbstractItemModel* pModel = GetModel();
|
||||
|
||||
QList<QStringList> Rows;
|
||||
for (int i = 0; i < pModel->rowCount(); ++i)
|
||||
{
|
||||
QModelIndex ModelIndex = pModel->index(i, 0);
|
||||
RecursiveCopyPanel(ModelIndex, Rows);
|
||||
}
|
||||
FormatAndCopy(Rows);
|
||||
}
|
||||
|
||||
void CPanelView::FormatAndCopy(QList<QStringList> Rows, bool Headder)
|
||||
{
|
||||
int RowCount = Rows.length();
|
||||
|
||||
if (Headder)
|
||||
{
|
||||
Rows.prepend(QStringList());
|
||||
Rows.prepend(CopyHeader());
|
||||
Rows.prepend(QStringList());
|
||||
}
|
||||
|
||||
QStringList TextRows;
|
||||
if (m_SimpleFormat || !Headder)
|
||||
{
|
||||
foreach(const QStringList& Row, Rows)
|
||||
TextRows.append(Row.join(m_CellSeparator));
|
||||
}
|
||||
else if(Rows.size() > (Headder ? 3 : 0))
|
||||
{
|
||||
int Columns = Rows[Headder ? 3 : 0].count();
|
||||
QVector<int> ColumnWidths(Columns, 0);
|
||||
|
||||
foreach(const QStringList& Row, Rows)
|
||||
{
|
||||
for (int i = 0; i < Min(Row.count(), Columns); i++)
|
||||
{
|
||||
int CellWidth = Row[i].length();
|
||||
if (ColumnWidths[i] < CellWidth)
|
||||
ColumnWidths[i] = CellWidth;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(const QStringList& Row, Rows)
|
||||
{
|
||||
if (m_MaxCellWidth != 0 && RowCount > 1)
|
||||
{
|
||||
for (int Pos = 0;;Pos += m_MaxCellWidth)
|
||||
{
|
||||
bool More = false;
|
||||
|
||||
QString RowText;
|
||||
for (int i = 0; i < Min(Row.count(), Columns); i++)
|
||||
{
|
||||
if (Row[i].length() > Pos)
|
||||
RowText.append(Row[i].mid(Pos, m_MaxCellWidth).leftJustified(Min(m_MaxCellWidth, ColumnWidths[i]) + 3));
|
||||
else
|
||||
RowText.append(QString(Min(m_MaxCellWidth, ColumnWidths[i]) + 3, ' '));
|
||||
|
||||
if (Row[i].length() > Pos + m_MaxCellWidth)
|
||||
More = true;
|
||||
}
|
||||
TextRows.append(RowText);
|
||||
|
||||
if (!More)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QString RowText;
|
||||
for (int i = 0; i < Min(Row.count(), Columns); i++)
|
||||
RowText.append(Row[i].leftJustified(ColumnWidths[i] + 3));
|
||||
TextRows.append(RowText);
|
||||
}
|
||||
}
|
||||
}
|
||||
QApplication::clipboard()->setText(TextRows.join("\n"));
|
||||
}
|
|
@ -1,185 +1,185 @@
|
|||
#pragma once
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../mischelpers_global.h"
|
||||
|
||||
class MISCHELPERS_EXPORT CPanelView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CPanelView(QWidget *parent = 0);
|
||||
virtual ~CPanelView();
|
||||
|
||||
static void SetSimpleFormat(bool bSimple) { m_SimpleFormat = bSimple; }
|
||||
static void SetDarkMode(bool bDarkMode) { m_DarkMode = bDarkMode; }
|
||||
static void SetMaxCellWidth(int iMaxWidth) { m_MaxCellWidth = iMaxWidth; }
|
||||
static void SetCellSeparator(const QString& Sep) { m_CellSeparator = Sep; }
|
||||
|
||||
static QString m_CopyCell;
|
||||
static QString m_CopyRow;
|
||||
static QString m_CopyPanel;
|
||||
|
||||
protected slots:
|
||||
virtual void OnMenu(const QPoint& Point);
|
||||
|
||||
virtual void OnCopyCell();
|
||||
virtual void OnCopyRow();
|
||||
virtual void OnCopyPanel();
|
||||
|
||||
|
||||
virtual QTreeView* GetView() = 0;
|
||||
virtual QAbstractItemModel* GetModel() = 0;
|
||||
virtual QModelIndex MapToSource(const QModelIndex& Model) { return Model; }
|
||||
static QModelIndexList MapToSource(QModelIndexList Indexes, QSortFilterProxyModel* pProxy) {
|
||||
for (int i = 0; i < Indexes.count(); i++)
|
||||
Indexes[i] = pProxy->mapToSource(Indexes[i]);
|
||||
return Indexes;
|
||||
}
|
||||
|
||||
virtual void AddPanelItemsToMenu(bool bAddSeparator = true);
|
||||
|
||||
virtual void ForceColumn(int column, bool bSet = true) { if (bSet) m_ForcedColumns.insert(column); else m_ForcedColumns.remove(column); }
|
||||
|
||||
virtual QStringList CopyHeader();
|
||||
virtual QStringList CopyRow(const QModelIndex& ModelIndex, int Level = 0);
|
||||
virtual void RecursiveCopyPanel(const QModelIndex& ModelIndex, QList<QStringList>& Rows, int Level = 0);
|
||||
|
||||
protected:
|
||||
void FormatAndCopy(QList<QStringList> Rows, bool Headder = true);
|
||||
|
||||
QMenu* m_pMenu;
|
||||
|
||||
QAction* m_pCopyCell;
|
||||
QAction* m_pCopyRow;
|
||||
QAction* m_pCopyPanel;
|
||||
|
||||
//bool m_CopyAll;
|
||||
QSet<int> m_ForcedColumns;
|
||||
static bool m_SimpleFormat;
|
||||
static bool m_DarkMode;
|
||||
static int m_MaxCellWidth;
|
||||
static QString m_CellSeparator;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class CPanelWidget : public CPanelView
|
||||
{
|
||||
public:
|
||||
CPanelWidget(QWidget *parent = 0) : CPanelView(parent)
|
||||
{
|
||||
m_pMainLayout = new QVBoxLayout();
|
||||
m_pMainLayout->setMargin(0);
|
||||
this->setLayout(m_pMainLayout);
|
||||
|
||||
m_pTreeList = new T();
|
||||
m_pTreeList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_pTreeList, SIGNAL(customContextMenuRequested( const QPoint& )), this, SLOT(OnMenu(const QPoint &)));
|
||||
m_pMainLayout->addWidget(m_pTreeList);
|
||||
m_pTreeList->setMinimumHeight(50);
|
||||
AddPanelItemsToMenu();
|
||||
|
||||
m_pLastAction = m_pMenu->actions()[0];
|
||||
}
|
||||
|
||||
virtual QMenu* GetMenu() { return m_pMenu; }
|
||||
virtual void AddAction(QAction* pAction) { m_pMenu->insertAction(m_pLastAction, pAction); }
|
||||
|
||||
virtual T* GetTree() { return m_pTreeList; }
|
||||
virtual QTreeView* GetView() { return m_pTreeList; }
|
||||
virtual QAbstractItemModel* GetModel() { return m_pTreeList->model(); }
|
||||
|
||||
virtual QVBoxLayout* GetLayout() { return m_pMainLayout; }
|
||||
|
||||
protected:
|
||||
QVBoxLayout* m_pMainLayout;
|
||||
|
||||
T* m_pTreeList;
|
||||
|
||||
QAction* m_pLastAction;
|
||||
};
|
||||
|
||||
#include "TreeWidgetEx.h"
|
||||
#include "Finder.h"
|
||||
class MISCHELPERS_EXPORT CPanelView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CPanelView(QWidget *parent = 0);
|
||||
virtual ~CPanelView();
|
||||
|
||||
class MISCHELPERS_EXPORT CPanelWidgetEx : public CPanelWidget<QTreeWidgetEx>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CPanelWidgetEx(QWidget *parent = 0) : CPanelWidget<QTreeWidgetEx>(parent)
|
||||
{
|
||||
m_pFinder = new CFinder(NULL, this, false);
|
||||
m_pMainLayout->addWidget(m_pFinder);
|
||||
QObject::connect(m_pFinder, SIGNAL(SetFilter(const QRegExp&, bool, int)), this, SLOT(SetFilter(const QRegExp&, bool, int)));
|
||||
}
|
||||
|
||||
static void ApplyFilter(QTreeWidgetEx* pTree, QTreeWidgetItem* pItem, const QRegExp& Exp/*, bool bHighLight = false, int Col = -1*/)
|
||||
{
|
||||
for (int j = 0; j < pTree->columnCount(); j++) {
|
||||
pItem->setForeground(j, (m_DarkMode && !Exp.isEmpty() && pItem->text(j).contains(Exp)) ? Qt::yellow : pTree->palette().color(QPalette::WindowText));
|
||||
pItem->setBackground(j, (!m_DarkMode && !Exp.isEmpty() && pItem->text(j).contains(Exp)) ? Qt::yellow : pTree->palette().color(QPalette::Base));
|
||||
}
|
||||
|
||||
for (int i = 0; i < pItem->childCount(); i++)
|
||||
{
|
||||
ApplyFilter(pTree, pItem->child(i), Exp/*, bHighLight, Col*/);
|
||||
}
|
||||
}
|
||||
|
||||
static void ApplyFilter(QTreeWidgetEx* pTree, const QRegExp& Exp/*, bool bHighLight = false, int Col = -1*/)
|
||||
{
|
||||
for (int i = 0; i < pTree->topLevelItemCount(); i++)
|
||||
ApplyFilter(pTree, pTree->topLevelItem(i), Exp/*, bHighLight, Col*/);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void SetFilter(const QRegExp& Exp, bool bHighLight = false, int Col = -1) // -1 = any
|
||||
{
|
||||
ApplyFilter(m_pTreeList, Exp);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
CFinder* m_pFinder;
|
||||
};
|
||||
|
||||
#include "TreeViewEx.h"
|
||||
#include "SortFilterProxyModel.h"
|
||||
|
||||
class CPanelViewEx: public CPanelWidget<QTreeViewEx>
|
||||
{
|
||||
public:
|
||||
CPanelViewEx(QAbstractItemModel* pModel, QWidget *parent = 0) : CPanelWidget<QTreeViewEx>(parent)
|
||||
{
|
||||
m_pModel = pModel;
|
||||
|
||||
m_pSortProxy = new CSortFilterProxyModel(false, this);
|
||||
m_pSortProxy->setSortRole(Qt::EditRole);
|
||||
m_pSortProxy->setSourceModel(m_pModel);
|
||||
m_pSortProxy->setDynamicSortFilter(true);
|
||||
|
||||
m_pTreeList->setModel(m_pSortProxy);
|
||||
((CSortFilterProxyModel*)m_pSortProxy)->setView(m_pTreeList);
|
||||
|
||||
|
||||
m_pTreeList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
#ifdef WIN32
|
||||
QStyle* pStyle = QStyleFactory::create("windows");
|
||||
m_pTreeList->setStyle(pStyle);
|
||||
#endif
|
||||
m_pTreeList->setExpandsOnDoubleClick(false);
|
||||
m_pTreeList->setSortingEnabled(true);
|
||||
|
||||
m_pTreeList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_pTreeList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OnMenu(const QPoint &)));
|
||||
|
||||
m_pTreeList->setColumnReset(1);
|
||||
//connect(m_pTreeList, SIGNAL(ResetColumns()), m_pTreeList, SLOT(OnResetColumns()));
|
||||
//connect(m_pBoxTree, SIGNAL(ColumnChanged(int, bool)), this, SLOT(OnColumnsChanged()));
|
||||
|
||||
m_pMainLayout->addWidget(CFinder::AddFinder(m_pTreeList, m_pSortProxy));
|
||||
}
|
||||
|
||||
protected:
|
||||
QAbstractItemModel* m_pModel;
|
||||
QSortFilterProxyModel* m_pSortProxy;
|
||||
static void SetSimpleFormat(bool bSimple) { m_SimpleFormat = bSimple; }
|
||||
static void SetDarkMode(bool bDarkMode) { m_DarkMode = bDarkMode; }
|
||||
static void SetMaxCellWidth(int iMaxWidth) { m_MaxCellWidth = iMaxWidth; }
|
||||
static void SetCellSeparator(const QString& Sep) { m_CellSeparator = Sep; }
|
||||
|
||||
static QString m_CopyCell;
|
||||
static QString m_CopyRow;
|
||||
static QString m_CopyPanel;
|
||||
|
||||
protected slots:
|
||||
virtual void OnMenu(const QPoint& Point);
|
||||
|
||||
virtual void OnCopyCell();
|
||||
virtual void OnCopyRow();
|
||||
virtual void OnCopyPanel();
|
||||
|
||||
|
||||
virtual QTreeView* GetView() = 0;
|
||||
virtual QAbstractItemModel* GetModel() = 0;
|
||||
virtual QModelIndex MapToSource(const QModelIndex& Model) { return Model; }
|
||||
static QModelIndexList MapToSource(QModelIndexList Indexes, QSortFilterProxyModel* pProxy) {
|
||||
for (int i = 0; i < Indexes.count(); i++)
|
||||
Indexes[i] = pProxy->mapToSource(Indexes[i]);
|
||||
return Indexes;
|
||||
}
|
||||
|
||||
virtual void AddPanelItemsToMenu(bool bAddSeparator = true);
|
||||
|
||||
virtual void ForceColumn(int column, bool bSet = true) { if (bSet) m_ForcedColumns.insert(column); else m_ForcedColumns.remove(column); }
|
||||
|
||||
virtual QStringList CopyHeader();
|
||||
virtual QStringList CopyRow(const QModelIndex& ModelIndex, int Level = 0);
|
||||
virtual void RecursiveCopyPanel(const QModelIndex& ModelIndex, QList<QStringList>& Rows, int Level = 0);
|
||||
|
||||
protected:
|
||||
void FormatAndCopy(QList<QStringList> Rows, bool Headder = true);
|
||||
|
||||
QMenu* m_pMenu;
|
||||
|
||||
QAction* m_pCopyCell;
|
||||
QAction* m_pCopyRow;
|
||||
QAction* m_pCopyPanel;
|
||||
|
||||
//bool m_CopyAll;
|
||||
QSet<int> m_ForcedColumns;
|
||||
static bool m_SimpleFormat;
|
||||
static bool m_DarkMode;
|
||||
static int m_MaxCellWidth;
|
||||
static QString m_CellSeparator;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class CPanelWidget : public CPanelView
|
||||
{
|
||||
public:
|
||||
CPanelWidget(QWidget *parent = 0) : CPanelView(parent)
|
||||
{
|
||||
m_pMainLayout = new QVBoxLayout();
|
||||
m_pMainLayout->setMargin(0);
|
||||
this->setLayout(m_pMainLayout);
|
||||
|
||||
m_pTreeList = new T();
|
||||
m_pTreeList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_pTreeList, SIGNAL(customContextMenuRequested( const QPoint& )), this, SLOT(OnMenu(const QPoint &)));
|
||||
m_pMainLayout->addWidget(m_pTreeList);
|
||||
m_pTreeList->setMinimumHeight(50);
|
||||
AddPanelItemsToMenu();
|
||||
|
||||
m_pLastAction = m_pMenu->actions()[0];
|
||||
}
|
||||
|
||||
virtual QMenu* GetMenu() { return m_pMenu; }
|
||||
virtual void AddAction(QAction* pAction) { m_pMenu->insertAction(m_pLastAction, pAction); }
|
||||
|
||||
virtual T* GetTree() { return m_pTreeList; }
|
||||
virtual QTreeView* GetView() { return m_pTreeList; }
|
||||
virtual QAbstractItemModel* GetModel() { return m_pTreeList->model(); }
|
||||
|
||||
virtual QVBoxLayout* GetLayout() { return m_pMainLayout; }
|
||||
|
||||
protected:
|
||||
QVBoxLayout* m_pMainLayout;
|
||||
|
||||
T* m_pTreeList;
|
||||
|
||||
QAction* m_pLastAction;
|
||||
};
|
||||
|
||||
#include "TreeWidgetEx.h"
|
||||
#include "Finder.h"
|
||||
|
||||
class MISCHELPERS_EXPORT CPanelWidgetEx : public CPanelWidget<QTreeWidgetEx>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CPanelWidgetEx(QWidget *parent = 0) : CPanelWidget<QTreeWidgetEx>(parent)
|
||||
{
|
||||
m_pFinder = new CFinder(NULL, this, false);
|
||||
m_pMainLayout->addWidget(m_pFinder);
|
||||
QObject::connect(m_pFinder, SIGNAL(SetFilter(const QRegExp&, bool, int)), this, SLOT(SetFilter(const QRegExp&, bool, int)));
|
||||
}
|
||||
|
||||
static void ApplyFilter(QTreeWidgetEx* pTree, QTreeWidgetItem* pItem, const QRegExp& Exp/*, bool bHighLight = false, int Col = -1*/)
|
||||
{
|
||||
for (int j = 0; j < pTree->columnCount(); j++) {
|
||||
pItem->setForeground(j, (m_DarkMode && !Exp.isEmpty() && pItem->text(j).contains(Exp)) ? Qt::yellow : pTree->palette().color(QPalette::WindowText));
|
||||
pItem->setBackground(j, (!m_DarkMode && !Exp.isEmpty() && pItem->text(j).contains(Exp)) ? Qt::yellow : pTree->palette().color(QPalette::Base));
|
||||
}
|
||||
|
||||
for (int i = 0; i < pItem->childCount(); i++)
|
||||
{
|
||||
ApplyFilter(pTree, pItem->child(i), Exp/*, bHighLight, Col*/);
|
||||
}
|
||||
}
|
||||
|
||||
static void ApplyFilter(QTreeWidgetEx* pTree, const QRegExp& Exp/*, bool bHighLight = false, int Col = -1*/)
|
||||
{
|
||||
for (int i = 0; i < pTree->topLevelItemCount(); i++)
|
||||
ApplyFilter(pTree, pTree->topLevelItem(i), Exp/*, bHighLight, Col*/);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void SetFilter(const QRegExp& Exp, bool bHighLight = false, int Col = -1) // -1 = any
|
||||
{
|
||||
ApplyFilter(m_pTreeList, Exp);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
CFinder* m_pFinder;
|
||||
};
|
||||
|
||||
#include "TreeViewEx.h"
|
||||
#include "SortFilterProxyModel.h"
|
||||
|
||||
class CPanelViewEx: public CPanelWidget<QTreeViewEx>
|
||||
{
|
||||
public:
|
||||
CPanelViewEx(QAbstractItemModel* pModel, QWidget *parent = 0) : CPanelWidget<QTreeViewEx>(parent)
|
||||
{
|
||||
m_pModel = pModel;
|
||||
|
||||
m_pSortProxy = new CSortFilterProxyModel(false, this);
|
||||
m_pSortProxy->setSortRole(Qt::EditRole);
|
||||
m_pSortProxy->setSourceModel(m_pModel);
|
||||
m_pSortProxy->setDynamicSortFilter(true);
|
||||
|
||||
m_pTreeList->setModel(m_pSortProxy);
|
||||
((CSortFilterProxyModel*)m_pSortProxy)->setView(m_pTreeList);
|
||||
|
||||
|
||||
m_pTreeList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
#ifdef WIN32
|
||||
QStyle* pStyle = QStyleFactory::create("windows");
|
||||
m_pTreeList->setStyle(pStyle);
|
||||
#endif
|
||||
m_pTreeList->setExpandsOnDoubleClick(false);
|
||||
m_pTreeList->setSortingEnabled(true);
|
||||
|
||||
m_pTreeList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_pTreeList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OnMenu(const QPoint &)));
|
||||
|
||||
m_pTreeList->setColumnReset(1);
|
||||
//connect(m_pTreeList, SIGNAL(ResetColumns()), m_pTreeList, SLOT(OnResetColumns()));
|
||||
//connect(m_pBoxTree, SIGNAL(ColumnChanged(int, bool)), this, SLOT(OnColumnsChanged()));
|
||||
|
||||
m_pMainLayout->addWidget(CFinder::AddFinder(m_pTreeList, m_pSortProxy));
|
||||
}
|
||||
|
||||
protected:
|
||||
QAbstractItemModel* m_pModel;
|
||||
QSortFilterProxyModel* m_pSortProxy;
|
||||
};
|
|
@ -1,208 +1,208 @@
|
|||
#pragma once
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../mischelpers_global.h"
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QTreeView>
|
||||
#include "Finder.h"
|
||||
|
||||
class MISCHELPERS_EXPORT CSortFilterProxyModel: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CSortFilterProxyModel(bool bAlternate, QObject* parrent = 0) : QSortFilterProxyModel(parrent)
|
||||
{
|
||||
m_bAlternate = bAlternate;
|
||||
m_bHighLight = false;
|
||||
m_iColumn = 0;
|
||||
m_pView = NULL;
|
||||
|
||||
this->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
void setView(QTreeView* pView)
|
||||
{
|
||||
m_pView = pView;
|
||||
}
|
||||
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
|
||||
{
|
||||
if (m_bHighLight)
|
||||
return true;
|
||||
|
||||
// allow the item to pass if any of the child items pass
|
||||
if(!filterRegExp().isEmpty())
|
||||
{
|
||||
// get source-model index for current row
|
||||
QModelIndex source_index = sourceModel()->index(source_row, 0, source_parent);
|
||||
if(source_index.isValid())
|
||||
{
|
||||
// if any of children matches the filter, then current index matches the filter as well
|
||||
int nb = sourceModel()->rowCount(source_index);
|
||||
for(int i = 0; i < nb; i++)
|
||||
{
|
||||
if(filterAcceptsRow(i, source_index))
|
||||
return true;
|
||||
}
|
||||
// check current index itself
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
}
|
||||
|
||||
// default behavioure
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QVariant Data = QSortFilterProxyModel::data(index, role);
|
||||
if (m_bHighLight && role == (CFinder::GetDarkMode() ? Qt::ForegroundRole : Qt::BackgroundRole))
|
||||
{
|
||||
if (!filterRegExp().isEmpty())
|
||||
{
|
||||
QString Key = QSortFilterProxyModel::data(index, filterRole()).toString();
|
||||
if (Key.contains(filterRegExp()))
|
||||
return QColor(Qt::yellow);
|
||||
}
|
||||
//return QColor(Qt::white);
|
||||
}
|
||||
|
||||
if (role == Qt::BackgroundRole)
|
||||
{
|
||||
if (m_bAlternate && !Data.isValid())
|
||||
{
|
||||
if (0 == index.row() % 2)
|
||||
return QColor(226, 237, 253);
|
||||
else
|
||||
return QColor(Qt::white);
|
||||
}
|
||||
}
|
||||
return Data;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void SetFilter(const QRegExp& Exp, bool bHighLight = false, int Col = -1) // -1 = any
|
||||
{
|
||||
QModelIndex idx;
|
||||
//if (m_pView) idx = m_pView->currentIndex();
|
||||
m_iColumn = Col;
|
||||
m_bHighLight = bHighLight;
|
||||
setFilterKeyColumn(Col);
|
||||
setFilterRegExp(Exp);
|
||||
//if (m_pView) m_pView->setCurrentIndex(idx);
|
||||
if (m_bHighLight)
|
||||
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:
|
||||
bool m_bAlternate;
|
||||
bool m_bHighLight;
|
||||
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(filterRegExp()))
|
||||
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();
|
||||
}
|
||||
class MISCHELPERS_EXPORT CSortFilterProxyModel: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CSortFilterProxyModel(bool bAlternate, QObject* parrent = 0) : QSortFilterProxyModel(parrent)
|
||||
{
|
||||
m_bAlternate = bAlternate;
|
||||
m_bHighLight = false;
|
||||
m_iColumn = 0;
|
||||
m_pView = NULL;
|
||||
|
||||
this->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
void setView(QTreeView* pView)
|
||||
{
|
||||
m_pView = pView;
|
||||
}
|
||||
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
|
||||
{
|
||||
if (m_bHighLight)
|
||||
return true;
|
||||
|
||||
// allow the item to pass if any of the child items pass
|
||||
if(!filterRegExp().isEmpty())
|
||||
{
|
||||
// get source-model index for current row
|
||||
QModelIndex source_index = sourceModel()->index(source_row, 0, source_parent);
|
||||
if(source_index.isValid())
|
||||
{
|
||||
// if any of children matches the filter, then current index matches the filter as well
|
||||
int nb = sourceModel()->rowCount(source_index);
|
||||
for(int i = 0; i < nb; i++)
|
||||
{
|
||||
if(filterAcceptsRow(i, source_index))
|
||||
return true;
|
||||
}
|
||||
// check current index itself
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
}
|
||||
|
||||
// default behavioure
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QVariant Data = QSortFilterProxyModel::data(index, role);
|
||||
if (m_bHighLight && role == (CFinder::GetDarkMode() ? Qt::ForegroundRole : Qt::BackgroundRole))
|
||||
{
|
||||
if (!filterRegExp().isEmpty())
|
||||
{
|
||||
QString Key = QSortFilterProxyModel::data(index, filterRole()).toString();
|
||||
if (Key.contains(filterRegExp()))
|
||||
return QColor(Qt::yellow);
|
||||
}
|
||||
//return QColor(Qt::white);
|
||||
}
|
||||
|
||||
if (role == Qt::BackgroundRole)
|
||||
{
|
||||
if (m_bAlternate && !Data.isValid())
|
||||
{
|
||||
if (0 == index.row() % 2)
|
||||
return QColor(226, 237, 253);
|
||||
else
|
||||
return QColor(Qt::white);
|
||||
}
|
||||
}
|
||||
return Data;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void SetFilter(const QRegExp& Exp, bool bHighLight = false, int Col = -1) // -1 = any
|
||||
{
|
||||
QModelIndex idx;
|
||||
//if (m_pView) idx = m_pView->currentIndex();
|
||||
m_iColumn = Col;
|
||||
m_bHighLight = bHighLight;
|
||||
setFilterKeyColumn(Col);
|
||||
setFilterRegExp(Exp);
|
||||
//if (m_pView) m_pView->setCurrentIndex(idx);
|
||||
if (m_bHighLight)
|
||||
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:
|
||||
bool m_bAlternate;
|
||||
bool m_bHighLight;
|
||||
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(filterRegExp()))
|
||||
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();
|
||||
}
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -1,187 +1,187 @@
|
|||
#include "stdafx.h"
|
||||
#include "SelectBoxWindow.h"
|
||||
#include "SandMan.h"
|
||||
#include "../MiscHelpers/Common/Settings.h"
|
||||
#include "../SbiePlusAPI.h"
|
||||
#include "../Views/SbieView.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <wtypes.h>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <dbt.h>
|
||||
#endif
|
||||
|
||||
QTreeWidgetItem* CSelectBoxWindow__GetBoxParent(const QMap<QString, QStringList>& Groups, QMap<QString, QTreeWidgetItem*>& GroupItems, QTreeWidget* treeBoxes, const QString& Name, int Depth = 0)
|
||||
{
|
||||
if (Depth > 100)
|
||||
return NULL;
|
||||
for (auto I = Groups.constBegin(); I != Groups.constEnd(); ++I) {
|
||||
if (I->contains(Name)) {
|
||||
if (I.key().isEmpty())
|
||||
return NULL; // global group
|
||||
QTreeWidgetItem*& pParent = GroupItems[I.key()];
|
||||
if (!pParent) {
|
||||
pParent = new QTreeWidgetItem();
|
||||
pParent->setText(0, I.key());
|
||||
QFont fnt = pParent->font(0);
|
||||
fnt.setBold(true);
|
||||
pParent->setFont(0, fnt);
|
||||
if (QTreeWidgetItem* pParent2 = CSelectBoxWindow__GetBoxParent(Groups, GroupItems, treeBoxes, I.key(), ++Depth))
|
||||
pParent2->addChild(pParent);
|
||||
else
|
||||
treeBoxes->addTopLevelItem(pParent);
|
||||
}
|
||||
return pParent;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
double CSelectBoxWindow__GetBoxOrder(const QMap<QString, QStringList>& Groups, const QString& Name, double value = 0.0, int Depth = 0)
|
||||
{
|
||||
if (Depth > 100)
|
||||
return 1000000000;
|
||||
for (auto I = Groups.constBegin(); I != Groups.constEnd(); ++I) {
|
||||
int Pos = I->indexOf(Name);
|
||||
if (Pos != -1) {
|
||||
value = double(Pos) + value / 10.0;
|
||||
if (I.key().isEmpty())
|
||||
return value;
|
||||
return CSelectBoxWindow__GetBoxOrder(Groups, I.key(), value, ++Depth);
|
||||
}
|
||||
}
|
||||
return 1000000000;
|
||||
}
|
||||
|
||||
CSelectBoxWindow::CSelectBoxWindow(const QStringList& Commands, const QString& BoxName, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
m_Commands = Commands;
|
||||
|
||||
Qt::WindowFlags flags = windowFlags();
|
||||
flags |= Qt::CustomizeWindowHint;
|
||||
//flags &= ~Qt::WindowContextHelpButtonHint;
|
||||
//flags &= ~Qt::WindowSystemMenuHint;
|
||||
//flags &= ~Qt::WindowMinMaxButtonsHint;
|
||||
//flags |= Qt::WindowMinimizeButtonHint;
|
||||
//flags &= ~Qt::WindowCloseButtonHint;
|
||||
flags &= ~Qt::WindowContextHelpButtonHint;
|
||||
//flags &= ~Qt::WindowSystemMenuHint;
|
||||
setWindowFlags(flags);
|
||||
|
||||
//setWindowState(Qt::WindowActive);
|
||||
SetForegroundWindow((HWND)QWidget::winId());
|
||||
|
||||
bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false);
|
||||
this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
|
||||
|
||||
if (!bAlwaysOnTop) {
|
||||
HWND hWnd = (HWND)this->winId();
|
||||
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
QTimer::singleShot(100, this, [hWnd]() {
|
||||
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
});
|
||||
}
|
||||
|
||||
ui.setupUi(this);
|
||||
this->setWindowTitle(tr("Sandboxie-Plus - Run Sandboxed"));
|
||||
|
||||
|
||||
connect(ui.radBoxed, SIGNAL(clicked(bool)), this, SLOT(OnBoxType()));
|
||||
connect(ui.radUnBoxed, SIGNAL(clicked(bool)), this, SLOT(OnBoxType()));
|
||||
|
||||
connect(ui.buttonBox, SIGNAL(accepted()), SLOT(OnRun()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), SLOT(reject()));
|
||||
|
||||
connect(ui.treeBoxes, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnBoxDblClick(QTreeWidgetItem*)));
|
||||
|
||||
QList<CSandBoxPtr> Boxes = theAPI->GetAllBoxes().values(); // map is sorted by key (box name)
|
||||
QMap<QString, QStringList> Groups = theGUI->GetBoxView()->GetGroups();
|
||||
|
||||
if (theConf->GetBool("MainWindow/BoxTree_UseOrder", false)) {
|
||||
QMultiMap<double, CSandBoxPtr> Boxes2;
|
||||
foreach(const CSandBoxPtr &pBox, Boxes) {
|
||||
Boxes2.insertMulti(CSelectBoxWindow__GetBoxOrder(Groups, pBox->GetName()), pBox);
|
||||
}
|
||||
Boxes = Boxes2.values();
|
||||
}
|
||||
|
||||
QMap<QString, QTreeWidgetItem*> GroupItems;
|
||||
foreach(const CSandBoxPtr &pBox, Boxes)
|
||||
{
|
||||
if (!pBox->IsEnabled() || !pBox->GetBool("ShowForRunIn", true))
|
||||
continue;
|
||||
|
||||
CSandBoxPlus* pBoxEx = qobject_cast<CSandBoxPlus*>(pBox.data());
|
||||
|
||||
QTreeWidgetItem* pParent = CSelectBoxWindow__GetBoxParent(Groups, GroupItems, ui.treeBoxes, pBox->GetName());
|
||||
|
||||
QTreeWidgetItem* pItem = new QTreeWidgetItem();
|
||||
pItem->setText(0, pBox->GetName().replace("_", " "));
|
||||
pItem->setData(0, Qt::UserRole, pBox->GetName());
|
||||
pItem->setData(0, Qt::DecorationRole, theGUI->GetBoxIcon(pBox->GetActiveProcessCount() > 0, pBoxEx->GetType()));
|
||||
if (pParent)
|
||||
pParent->addChild(pItem);
|
||||
else
|
||||
ui.treeBoxes->addTopLevelItem(pItem);
|
||||
|
||||
if (pBox->GetName().compare(BoxName, Qt::CaseInsensitive) == 0)
|
||||
ui.treeBoxes->setCurrentItem(pItem);
|
||||
}
|
||||
|
||||
ui.treeBoxes->expandAll();
|
||||
|
||||
//ui.treeBoxes->sortByColumn(0, Qt::AscendingOrder);
|
||||
|
||||
//restoreGeometry(theConf->GetBlob("SelectBoxWindow/Window_Geometry"));
|
||||
}
|
||||
|
||||
CSelectBoxWindow::~CSelectBoxWindow()
|
||||
{
|
||||
//theConf->SetBlob("SelectBoxWindow/Window_Geometry", saveGeometry());
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
//emit Closed();
|
||||
this->deleteLater();
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnBoxType()
|
||||
{
|
||||
ui.treeBoxes->setEnabled(!ui.radUnBoxed->isChecked());
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnBoxDblClick(QTreeWidgetItem*)
|
||||
{
|
||||
OnRun();
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnRun()
|
||||
{
|
||||
QTreeWidgetItem* pItem = ui.treeBoxes->currentItem();
|
||||
|
||||
QString BoxName;
|
||||
if (ui.radUnBoxed->isChecked())
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Are you sure you want to run the program outside the sandbox?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
pItem = NULL;
|
||||
}
|
||||
else if (pItem == NULL) {
|
||||
QMessageBox("Sandboxie-Plus", tr("Please select a sandbox."), QMessageBox::Information, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this).exec();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
BoxName = pItem->data(0, Qt::UserRole).toString();
|
||||
}
|
||||
|
||||
|
||||
//QList<SB_STATUS> Results;
|
||||
foreach(const QString & Command, m_Commands) {
|
||||
theAPI->RunStart(BoxName, Command, NULL, ui.chkAdmin->isChecked());
|
||||
}
|
||||
//CSandMan::CheckResults(Results);
|
||||
|
||||
close();
|
||||
#include "stdafx.h"
|
||||
#include "SelectBoxWindow.h"
|
||||
#include "SandMan.h"
|
||||
#include "../MiscHelpers/Common/Settings.h"
|
||||
#include "../SbiePlusAPI.h"
|
||||
#include "../Views/SbieView.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <wtypes.h>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <dbt.h>
|
||||
#endif
|
||||
|
||||
QTreeWidgetItem* CSelectBoxWindow__GetBoxParent(const QMap<QString, QStringList>& Groups, QMap<QString, QTreeWidgetItem*>& GroupItems, QTreeWidget* treeBoxes, const QString& Name, int Depth = 0)
|
||||
{
|
||||
if (Depth > 100)
|
||||
return NULL;
|
||||
for (auto I = Groups.constBegin(); I != Groups.constEnd(); ++I) {
|
||||
if (I->contains(Name)) {
|
||||
if (I.key().isEmpty())
|
||||
return NULL; // global group
|
||||
QTreeWidgetItem*& pParent = GroupItems[I.key()];
|
||||
if (!pParent) {
|
||||
pParent = new QTreeWidgetItem();
|
||||
pParent->setText(0, I.key());
|
||||
QFont fnt = pParent->font(0);
|
||||
fnt.setBold(true);
|
||||
pParent->setFont(0, fnt);
|
||||
if (QTreeWidgetItem* pParent2 = CSelectBoxWindow__GetBoxParent(Groups, GroupItems, treeBoxes, I.key(), ++Depth))
|
||||
pParent2->addChild(pParent);
|
||||
else
|
||||
treeBoxes->addTopLevelItem(pParent);
|
||||
}
|
||||
return pParent;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
double CSelectBoxWindow__GetBoxOrder(const QMap<QString, QStringList>& Groups, const QString& Name, double value = 0.0, int Depth = 0)
|
||||
{
|
||||
if (Depth > 100)
|
||||
return 1000000000;
|
||||
for (auto I = Groups.constBegin(); I != Groups.constEnd(); ++I) {
|
||||
int Pos = I->indexOf(Name);
|
||||
if (Pos != -1) {
|
||||
value = double(Pos) + value / 10.0;
|
||||
if (I.key().isEmpty())
|
||||
return value;
|
||||
return CSelectBoxWindow__GetBoxOrder(Groups, I.key(), value, ++Depth);
|
||||
}
|
||||
}
|
||||
return 1000000000;
|
||||
}
|
||||
|
||||
CSelectBoxWindow::CSelectBoxWindow(const QStringList& Commands, const QString& BoxName, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
m_Commands = Commands;
|
||||
|
||||
Qt::WindowFlags flags = windowFlags();
|
||||
flags |= Qt::CustomizeWindowHint;
|
||||
//flags &= ~Qt::WindowContextHelpButtonHint;
|
||||
//flags &= ~Qt::WindowSystemMenuHint;
|
||||
//flags &= ~Qt::WindowMinMaxButtonsHint;
|
||||
//flags |= Qt::WindowMinimizeButtonHint;
|
||||
//flags &= ~Qt::WindowCloseButtonHint;
|
||||
flags &= ~Qt::WindowContextHelpButtonHint;
|
||||
//flags &= ~Qt::WindowSystemMenuHint;
|
||||
setWindowFlags(flags);
|
||||
|
||||
//setWindowState(Qt::WindowActive);
|
||||
SetForegroundWindow((HWND)QWidget::winId());
|
||||
|
||||
bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false);
|
||||
this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
|
||||
|
||||
if (!bAlwaysOnTop) {
|
||||
HWND hWnd = (HWND)this->winId();
|
||||
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
QTimer::singleShot(100, this, [hWnd]() {
|
||||
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
});
|
||||
}
|
||||
|
||||
ui.setupUi(this);
|
||||
this->setWindowTitle(tr("Sandboxie-Plus - Run Sandboxed"));
|
||||
|
||||
|
||||
connect(ui.radBoxed, SIGNAL(clicked(bool)), this, SLOT(OnBoxType()));
|
||||
connect(ui.radUnBoxed, SIGNAL(clicked(bool)), this, SLOT(OnBoxType()));
|
||||
|
||||
connect(ui.buttonBox, SIGNAL(accepted()), SLOT(OnRun()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), SLOT(reject()));
|
||||
|
||||
connect(ui.treeBoxes, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnBoxDblClick(QTreeWidgetItem*)));
|
||||
|
||||
QList<CSandBoxPtr> Boxes = theAPI->GetAllBoxes().values(); // map is sorted by key (box name)
|
||||
QMap<QString, QStringList> Groups = theGUI->GetBoxView()->GetGroups();
|
||||
|
||||
if (theConf->GetBool("MainWindow/BoxTree_UseOrder", false)) {
|
||||
QMultiMap<double, CSandBoxPtr> Boxes2;
|
||||
foreach(const CSandBoxPtr &pBox, Boxes) {
|
||||
Boxes2.insertMulti(CSelectBoxWindow__GetBoxOrder(Groups, pBox->GetName()), pBox);
|
||||
}
|
||||
Boxes = Boxes2.values();
|
||||
}
|
||||
|
||||
QMap<QString, QTreeWidgetItem*> GroupItems;
|
||||
foreach(const CSandBoxPtr &pBox, Boxes)
|
||||
{
|
||||
if (!pBox->IsEnabled() || !pBox->GetBool("ShowForRunIn", true))
|
||||
continue;
|
||||
|
||||
CSandBoxPlus* pBoxEx = qobject_cast<CSandBoxPlus*>(pBox.data());
|
||||
|
||||
QTreeWidgetItem* pParent = CSelectBoxWindow__GetBoxParent(Groups, GroupItems, ui.treeBoxes, pBox->GetName());
|
||||
|
||||
QTreeWidgetItem* pItem = new QTreeWidgetItem();
|
||||
pItem->setText(0, pBox->GetName().replace("_", " "));
|
||||
pItem->setData(0, Qt::UserRole, pBox->GetName());
|
||||
pItem->setData(0, Qt::DecorationRole, theGUI->GetBoxIcon(pBox->GetActiveProcessCount() > 0, pBoxEx->GetType()));
|
||||
if (pParent)
|
||||
pParent->addChild(pItem);
|
||||
else
|
||||
ui.treeBoxes->addTopLevelItem(pItem);
|
||||
|
||||
if (pBox->GetName().compare(BoxName, Qt::CaseInsensitive) == 0)
|
||||
ui.treeBoxes->setCurrentItem(pItem);
|
||||
}
|
||||
|
||||
ui.treeBoxes->expandAll();
|
||||
|
||||
//ui.treeBoxes->sortByColumn(0, Qt::AscendingOrder);
|
||||
|
||||
//restoreGeometry(theConf->GetBlob("SelectBoxWindow/Window_Geometry"));
|
||||
}
|
||||
|
||||
CSelectBoxWindow::~CSelectBoxWindow()
|
||||
{
|
||||
//theConf->SetBlob("SelectBoxWindow/Window_Geometry", saveGeometry());
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
//emit Closed();
|
||||
this->deleteLater();
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnBoxType()
|
||||
{
|
||||
ui.treeBoxes->setEnabled(!ui.radUnBoxed->isChecked());
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnBoxDblClick(QTreeWidgetItem*)
|
||||
{
|
||||
OnRun();
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnRun()
|
||||
{
|
||||
QTreeWidgetItem* pItem = ui.treeBoxes->currentItem();
|
||||
|
||||
QString BoxName;
|
||||
if (ui.radUnBoxed->isChecked())
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Are you sure you want to run the program outside the sandbox?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
pItem = NULL;
|
||||
}
|
||||
else if (pItem == NULL) {
|
||||
QMessageBox("Sandboxie-Plus", tr("Please select a sandbox."), QMessageBox::Information, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this).exec();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
BoxName = pItem->data(0, Qt::UserRole).toString();
|
||||
}
|
||||
|
||||
|
||||
//QList<SB_STATUS> Results;
|
||||
foreach(const QString & Command, m_Commands) {
|
||||
theAPI->RunStart(BoxName, Command, NULL, ui.chkAdmin->isChecked());
|
||||
}
|
||||
//CSandMan::CheckResults(Results);
|
||||
|
||||
close();
|
||||
}
|
Loading…
Reference in New Issue