2021-10-15 16:04:52 +01:00
|
|
|
#pragma once
|
|
|
|
|
2020-06-01 17:11:56 +01:00
|
|
|
#include "../mischelpers_global.h"
|
|
|
|
|
2021-10-15 16:04:52 +01:00
|
|
|
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; }
|
|
|
|
|
2022-05-15 11:27:33 +01:00
|
|
|
virtual QList<QStringList> DumpPanel();
|
|
|
|
|
2021-10-15 16:04:52 +01:00
|
|
|
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:
|
2022-07-12 17:39:10 +01:00
|
|
|
void UpdateCopyMenu();
|
|
|
|
void AddCopyMenu(QMenu* pMenu, bool bAddSeparator = true);
|
2022-12-07 16:32:40 +00:00
|
|
|
void FormatAndCopy(QList<QStringList> Rows, bool Header = true);
|
2021-10-15 16:04:52 +01:00
|
|
|
|
|
|
|
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();
|
2022-09-29 17:28:48 +01:00
|
|
|
m_pMainLayout->setContentsMargins(0,0,0,0);
|
2021-10-15 16:04:52 +01:00
|
|
|
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)
|
|
|
|
{
|
2023-01-13 08:11:46 +00:00
|
|
|
m_pFinder = new CFinder(NULL, this, CFinder::eRegExp | CFinder::eCaseSens);
|
2021-10-15 16:04:52 +01:00
|
|
|
m_pMainLayout->addWidget(m_pFinder);
|
2023-01-08 10:49:09 +00:00
|
|
|
QObject::connect(m_pFinder, SIGNAL(SetFilter(const QString&, int, int)), this, SLOT(SetFilter(const QString&, int, int)));
|
2021-10-15 16:04:52 +01:00
|
|
|
}
|
|
|
|
|
2023-09-30 13:20:20 +01:00
|
|
|
static void ApplyFilter(QTreeWidgetEx* pTree, QTreeWidgetItem* pItem, const QRegularExpression* Exp/*, bool bHighLight = false, int Col = -1*/)
|
2021-10-15 16:04:52 +01:00
|
|
|
{
|
|
|
|
for (int j = 0; j < pTree->columnCount(); j++) {
|
2023-09-30 13:20:20 +01:00
|
|
|
pItem->setForeground(j, (m_DarkMode && Exp && pItem->text(j).contains(*Exp)) ? Qt::yellow : pTree->palette().color(QPalette::WindowText));
|
|
|
|
pItem->setBackground(j, (!m_DarkMode && Exp && pItem->text(j).contains(*Exp)) ? Qt::yellow : pTree->palette().color(QPalette::Base));
|
2021-10-15 16:04:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < pItem->childCount(); i++)
|
|
|
|
ApplyFilter(pTree, pItem->child(i), Exp/*, bHighLight, Col*/);
|
|
|
|
}
|
|
|
|
|
2023-09-30 13:20:20 +01:00
|
|
|
static void ApplyFilter(QTreeWidgetEx* pTree, const QRegularExpression* Exp/*, bool bHighLight = false, int Col = -1*/)
|
2021-10-15 16:04:52 +01:00
|
|
|
{
|
|
|
|
for (int i = 0; i < pTree->topLevelItemCount(); i++)
|
|
|
|
ApplyFilter(pTree, pTree->topLevelItem(i), Exp/*, bHighLight, Col*/);
|
|
|
|
}
|
|
|
|
|
|
|
|
private slots:
|
2023-01-12 22:10:50 +00:00
|
|
|
void SetFilter(const QString& Exp, int iOptions, int Col = -1) // -1 = any
|
2021-10-15 16:04:52 +01:00
|
|
|
{
|
2023-09-30 13:20:20 +01:00
|
|
|
QScopedPointer<QRegularExpression> pRegExp;
|
|
|
|
if (!Exp.isEmpty()) {
|
|
|
|
QString ExpStr = ((iOptions & CFinder::eRegExp) == 0) ? Exp : (".*" + QRegularExpression::escape(Exp) + ".*");
|
|
|
|
pRegExp.reset(new QRegularExpression(ExpStr, (iOptions & CFinder::eCaseSens) != 0 ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption));
|
|
|
|
}
|
|
|
|
ApplyFilter(m_pTreeList, pRegExp.data());
|
2021-10-15 16:04:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2022-07-29 09:24:32 +01:00
|
|
|
m_pSortProxy = new CSortFilterProxyModel(this);
|
2021-10-15 16:04:52 +01:00
|
|
|
m_pSortProxy->setSortRole(Qt::EditRole);
|
|
|
|
m_pSortProxy->setSourceModel(m_pModel);
|
|
|
|
m_pSortProxy->setDynamicSortFilter(true);
|
|
|
|
|
|
|
|
m_pTreeList->setModel(m_pSortProxy);
|
|
|
|
|
|
|
|
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;
|
2022-12-07 16:32:40 +00:00
|
|
|
};
|