Skip to content

Commit e684f82

Browse files
committed
[Project Browser] Add table view, misc fixes and improvements
1 parent c86c641 commit e684f82

1 file changed

Lines changed: 108 additions & 12 deletions

File tree

ui/projectbrowser.h

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
#pragma once
22

3-
#include <QtWidgets/QLabel>
4-
#include <QtGui/QStandardItemModel>
53
#include <qabstractitemmodel.h>
64
#include <qboxlayout.h>
75
#include <qfileiconprovider.h>
86
#include <qfilesystemwatcher.h>
7+
#include <qlabel.h>
98
#include <qlineedit.h>
109
#include <qmimedatabase.h>
1110
#include <qnamespace.h>
@@ -17,10 +16,12 @@
1716
#include <qtextbrowser.h>
1817
#include <qtmetamacros.h>
1918
#include <qtoolbutton.h>
19+
#include <qtableview.h>
2020
#include <qtreeview.h>
2121
#include <qlistwidget.h>
2222
#include <qwidget.h>
2323
#include <qpushbutton.h>
24+
#include <qstackedwidget.h>
2425
#include <globalarea.h>
2526
#include <tabwidget.h>
2627
#include <unordered_map>
@@ -140,7 +141,7 @@ private Q_SLOTS:
140141
};
141142

142143

143-
class BINARYNINJAUIAPI SortFilterProjectItemModel: public QSortFilterProxyModel
144+
class BINARYNINJAUIAPI ProjectTreeFilterModel: public QSortFilterProxyModel
144145
{
145146
bool m_acceptAllFolders = false;
146147

@@ -151,13 +152,93 @@ class BINARYNINJAUIAPI SortFilterProjectItemModel: public QSortFilterProxyModel
151152
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override;
152153

153154
public:
154-
SortFilterProjectItemModel(ProjectRef project, QObject* parent = nullptr): QSortFilterProxyModel(parent), m_project(project) {};
155+
ProjectTreeFilterModel(ProjectRef project, QObject* parent = nullptr): QSortFilterProxyModel(parent), m_project(project) {};
155156

156157
void setAcceptAllFolders(bool accept) { m_acceptAllFolders = accept; }
157158
bool acceptAllFolders() const { return m_acceptAllFolders; }
158159
};
159160

160161

162+
class BINARYNINJAUIAPI ProjectTableItemModel: public QAbstractProxyModel
163+
{
164+
Q_OBJECT
165+
166+
ProjectRef m_project;
167+
168+
QList<QPersistentModelIndex> m_sourceFileIndexes;
169+
QHash<QPersistentModelIndex, int> m_sourceToProxyRow;
170+
QList<int> m_pendingRemovals;
171+
172+
void rebuildMapping();
173+
void collectFileIndexes(const QModelIndex& parent, QList<QModelIndex>& results) const;
174+
QString folderPathForIndex(int row) const;
175+
176+
void sourceRowsInserted(const QModelIndex& parent, int first, int last);
177+
void sourceRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last);
178+
void sourceRowsRemoved();
179+
void sourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QList<int>& roles);
180+
181+
public:
182+
ProjectTableItemModel(ProjectRef project, QObject* parent = nullptr);
183+
184+
enum {
185+
COL_FOLDER = ProjectItemModel::COLUMN_COUNT,
186+
COLUMN_COUNT,
187+
};
188+
189+
void setSourceModel(QAbstractItemModel* sourceModel) override;
190+
191+
QModelIndex mapToSource(const QModelIndex& proxyIndex) const override;
192+
QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override;
193+
194+
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
195+
QModelIndex parent(const QModelIndex& child) const override;
196+
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
197+
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
198+
199+
QVariant data(const QModelIndex& proxyIndex, int role = Qt::DisplayRole) const override;
200+
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
201+
202+
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
203+
Qt::ItemFlags flags(const QModelIndex& index) const override;
204+
};
205+
206+
207+
class BINARYNINJAUIAPI ProjectTableFilterModel: public QSortFilterProxyModel
208+
{
209+
ProjectRef m_project;
210+
211+
protected:
212+
bool lessThan(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const override;
213+
bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override;
214+
215+
public:
216+
ProjectTableFilterModel(ProjectRef project, QObject* parent = nullptr): QSortFilterProxyModel(parent), m_project(project) {};
217+
};
218+
219+
220+
class BINARYNINJAUIAPI ProjectTable: public QTableView, public FilterTarget
221+
{
222+
Q_OBJECT
223+
224+
virtual void scrollToFirstItem() override;
225+
virtual void scrollToCurrentItem() override;
226+
virtual void ensureSelection() override;
227+
virtual void activateSelection() override;
228+
virtual void setFilter(const std::string& filter, FilterOptions options) override;
229+
230+
protected:
231+
void mousePressEvent(QMouseEvent* event) override;
232+
void keyPressEvent(QKeyEvent* event) override;
233+
234+
public:
235+
ProjectTable(QWidget* parent = nullptr);
236+
237+
Q_SIGNALS:
238+
void filterChanged(const QString& filter, FilterOptions options);
239+
};
240+
241+
161242
class BINARYNINJAUIAPI ProjectTreeStyle: public QProxyStyle
162243
{
163244
public:
@@ -173,9 +254,6 @@ class BINARYNINJAUIAPI ProjectTree: public QTreeView, public FilterTarget
173254

174255
QSet<QString> m_expandedIds;
175256

176-
FilterOptions m_filterOptions;
177-
std::string m_filter;
178-
179257
virtual void scrollToFirstItem() override;
180258
virtual void scrollToCurrentItem() override;
181259
virtual void ensureSelection() override;
@@ -287,7 +365,7 @@ class BINARYNINJAUIAPI ProjectBrowser: public QWidget, public UIContextNotificat
287365

288366
ProjectRef m_project;
289367

290-
FilterEdit* m_projectFilterEdit;
368+
FilterEdit* m_treeFilterEdit;
291369
FilteredView* m_filteredTreeView;
292370

293371
FilterEdit* m_recentsFilterEdit;
@@ -296,24 +374,38 @@ class BINARYNINJAUIAPI ProjectBrowser: public QWidget, public UIContextNotificat
296374
DockableTabBar* m_tabBar;
297375

298376
ProjectItemModel* m_projectModel;
299-
SortFilterProjectItemModel* m_sortFilterProjectModel;
377+
ProjectTreeFilterModel* m_sortFilterTreeModel;
378+
ProjectTableItemModel* m_tableModel;
379+
ProjectTableFilterModel* m_sortFilterTableModel;
300380
QLabel* m_nameLabel;
301381
QLabel* m_descriptionLabel;
302382
ProjectTree* m_projectTree;
383+
ProjectTable* m_projectTable;
303384
InfoWidget* m_infoWidget;
304385
QWidget* m_projectContainer;
386+
QStackedWidget* m_viewStack;
387+
388+
FilterEdit* m_tableFilterEdit;
389+
FilteredView* m_filteredTableView;
390+
391+
bool m_useTableView = false;
392+
ClickableIcon* m_viewToggleButton;
305393

306394
RecentsList* m_recentFilesList;
307395

308396
ClickableIcon* m_refreshButton;
309397
ClickableIcon* m_editDetailsButton;
310398

311-
UIActionHandler m_projectActionHandler;
399+
UIActionHandler* m_projectTreeActionHandler = nullptr;
400+
UIActionHandler* m_projectTableActionHandler = nullptr;
312401
ContextMenuManager* m_projectContextMenuManager = nullptr;
313402
Menu m_projectMenu;
314403

315404
ProjectFolderRef GetFolderContainingIndex(const QModelIndex& index) const;
316405
QModelIndex GetCurrentSelectedIndex() const;
406+
QItemSelectionModel* activeSelectionModel() const;
407+
UIActionHandler* activeUIActionHandler() const;
408+
void setUseTableView(bool useTable);
317409

318410
virtual void OnAfterOpenProjectFile(UIContext* context, ProjectFileRef projectFile, ViewFrame* frame) override;
319411

@@ -335,12 +427,16 @@ class BINARYNINJAUIAPI ProjectBrowser: public QWidget, public UIContextNotificat
335427
std::vector<ProjectFileRef> GetSelectedFilesRecursive();
336428

337429
private slots:
338-
void itemDoubleClicked(const QModelIndex& index);
430+
void treeItemDoubleClicked(const QModelIndex& index);
431+
void fileDoubleClicked(ProjectFileRef file);
339432
void openProjectFile(ProjectFileRef file, bool openWithOptions = false);
340-
void itemSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
433+
void treeItemSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
341434
void itemChanged(QStandardItem* item);
342435
void handleItemsDropped(Qt::DropAction action, const QList<QString> fileIds, const QList<QString> folderIds, const QList<QUrl> newUrls, ProjectFolderRef newParentFolder);
343436
void onTreeFilterChanged(const QString& filter, FilterOptions options);
437+
void tableItemDoubleClicked(const QModelIndex& index);
438+
void tableItemSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
439+
void onTableFilterChanged(const QString& filter, FilterOptions options);
344440

345441
protected:
346442
void SelectItems(std::vector<ProjectFileRef> files, std::vector<ProjectFolderRef> folders);

0 commit comments

Comments
 (0)