enhancement: sort folders before files in project view

This commit is contained in:
Roy Qu 2022-01-08 08:52:50 +08:00
parent 13ee2d7f33
commit 96f8804edd
4 changed files with 80 additions and 35 deletions

View File

@ -116,8 +116,9 @@ MainWindow::MainWindow(QWidget *parent)
connect(mEditorList, &EditorList::editorClosed,
this, &MainWindow::onEditorClosed);
mProject = nullptr;
ui->projectView->setModel(&mProjectProxyModel);
mProjectProxyModel.setDynamicSortFilter(false);
mProjectProxyModel = new ProjectModelSortFilterProxy(this);
ui->projectView->setModel(mProjectProxyModel);
mProjectProxyModel->setDynamicSortFilter(false);
setupActions();
ui->EditorTabsRight->setVisible(false);
@ -2396,8 +2397,9 @@ void MainWindow::buildContextMenus()
ui->projectView);
connect(mProject_Rename_Unit, &QAction::triggered,
[this](){
if (ui->projectView->currentIndex().isValid())
if (ui->projectView->currentIndex().isValid()) {
ui->projectView->edit(ui->projectView->currentIndex());
}
});
mProject_Add_Folder = createActionFor(
tr("Add Folder"),
@ -2406,7 +2408,7 @@ void MainWindow::buildContextMenus()
[this](){
if (!mProject)
return;
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->currentIndex());
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->currentIndex());
if (!current.isValid()) {
return;
}
@ -2438,8 +2440,9 @@ void MainWindow::buildContextMenus()
ui->projectView);
connect(mProject_Rename_Folder, &QAction::triggered,
[this](){
if (ui->projectView->currentIndex().isValid())
if (ui->projectView->currentIndex().isValid()) {
ui->projectView->edit(ui->projectView->currentIndex());
}
});
mProject_Remove_Folder = createActionFor(
tr("Remove Folder"),
@ -2448,7 +2451,7 @@ void MainWindow::buildContextMenus()
[this](){
if (!mProject)
return;
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->currentIndex());
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->currentIndex());
if (!current.isValid()) {
return;
}
@ -2840,7 +2843,7 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos)
bool onRoot = false;
bool folderEmpty = false;
int unitIndex = -1;
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->selectionModel()->currentIndex());
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->selectionModel()->currentIndex());
if (current.isValid() && mProject) {
FolderNode * node = static_cast<FolderNode*>(current.internalPointer());
PFolderNode pNode = mProject->pointerToNode(node);
@ -3467,36 +3470,22 @@ void MainWindow::closeProject(bool refreshEditor)
void MainWindow::updateProjectView()
{
if (mProject) {
if (mProjectProxyModel.sourceModel()!=mProject->model()) {
mProjectProxyModel.setSourceModel(mProject->model());
connect(mProject->model(),&ProjectModel::dataChanged, &mProjectProxyModel,
[this]() {
mProjectProxyModel.invalidate();
});
connect(mProject->model(),&ProjectModel::modelReset, &mProjectProxyModel,
[this]() {
mProjectProxyModel.invalidate();
});
connect(mProject->model(),&ProjectModel::rowsInserted, &mProjectProxyModel,
[this]() {
mProjectProxyModel.invalidate();
});
connect(mProject->model(),&ProjectModel::rowsRemoved, &mProjectProxyModel,
[this]() {
mProjectProxyModel.invalidate();
});
mProjectProxyModel.sort(0);
if (mProjectProxyModel->sourceModel()!=mProject->model()) {
mProjectProxyModel->setSourceModel(mProject->model());
mProjectProxyModel->sort(0);
connect(mProject->model(), &ProjectModel::dataChanged,
this, &MainWindow::invalidateProjectProxyModel);
connect(mProject->model(), &QAbstractItemModel::modelReset,
ui->projectView,&QTreeView::expandAll);
}
mProjectProxyModel.invalidate();
} else
mProjectProxyModel->invalidate();
ui->projectView->expandAll();
openCloseLeftPanel(true);
ui->tabProject->setVisible(true);
ui->tabInfos->setCurrentWidget(ui->tabProject);
} else {
// Clear project browser
mProjectProxyModel.setSourceModel(nullptr);
mProjectProxyModel->setSourceModel(nullptr);
ui->tabProject->setVisible(false);
}
updateProjectActions();
@ -4903,9 +4892,10 @@ std::shared_ptr<Project> MainWindow::project()
void MainWindow::on_projectView_doubleClicked(const QModelIndex &index)
{
if (!index.isValid())
QModelIndex sourceIndex = mProjectProxyModel->mapToSource(index);
if (!sourceIndex.isValid())
return;
FolderNode * node = static_cast<FolderNode*>(index.internalPointer());
FolderNode * node = static_cast<FolderNode*>(sourceIndex.internalPointer());
if (!node)
return;
if (node->unitIndex>=0) {
@ -5055,7 +5045,7 @@ void MainWindow::on_actionAdd_to_project_triggered()
dialog.setFileMode(QFileDialog::ExistingFiles);
dialog.setAcceptMode(QFileDialog::AcceptOpen);
if (dialog.exec()) {
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->currentIndex());
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->currentIndex());
FolderNode * node = nullptr;
if (current.isValid()) {
node = static_cast<FolderNode*>(current.internalPointer());
@ -5084,7 +5074,7 @@ void MainWindow::on_actionRemove_from_project_triggered()
foreach (const QModelIndex& index, ui->projectView->selectionModel()->selectedIndexes()){
if (!index.isValid())
continue;
QModelIndex realIndex = mProjectProxyModel.mapToSource(index);
QModelIndex realIndex = mProjectProxyModel->mapToSource(index);
FolderNode * node = static_cast<FolderNode*>(realIndex.internalPointer());
PFolderNode folderNode = mProject->pointerToNode(node);
if (!folderNode)
@ -5308,7 +5298,7 @@ void MainWindow::newProjectUnitFile()
if (!mProject)
return;
int idx = -1;
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->currentIndex());
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->currentIndex());
FolderNode * node = nullptr;
if (current.isValid()) {
node = static_cast<FolderNode*>(current.internalPointer());
@ -5347,6 +5337,11 @@ void MainWindow::newProjectUnitFile()
editor->activate();
}
void MainWindow::invalidateProjectProxyModel()
{
mProjectProxyModel->invalidate();
}
void MainWindow::onEditorRenamed(const QString &oldFilename, const QString &newFilename, bool firstSave)
{
if (firstSave)

View File

@ -251,6 +251,7 @@ private:
void newProjectUnitFile();
private slots:
void invalidateProjectProxyModel();
void onEditorRenamed(const QString& oldFilename, const QString& newFilename, bool firstSave);
void onAutoSaveTimeout();
void onFileChanged(const QString& path);
@ -674,7 +675,7 @@ private:
QAction * mProblem_OpenSource;
QAction * mProblem_Properties;
QSortFilterProxyModel mProjectProxyModel;
QSortFilterProxyModel* mProjectProxyModel;
// QWidget interface
protected:

View File

@ -1811,6 +1811,11 @@ void ProjectModel::endUpdate()
}
}
Project *ProjectModel::project() const
{
return mProject;
}
QModelIndex ProjectModel::index(int row, int column, const QModelIndex &parent) const
{
if (!parent.isValid()) {
@ -1906,6 +1911,7 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
if (newName.isEmpty())
return false;
mProject->setName(newName);
emit dataChanged(index,index);
return true;
}
int idx = node->unitIndex;
@ -1973,6 +1979,7 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
// Add new filename to file minitor
pMainWindow->fileSystemWatcher()->addPath(newName);
emit dataChanged(index,index);
return true;
} else {
//change folder name
@ -1984,6 +1991,7 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
node->text = newName;
mProject->updateFolders();
mProject->saveAll();
emit dataChanged(index,index);
return true;
}
@ -2134,3 +2142,31 @@ QMimeData *ProjectModel::mimeData(const QModelIndexList &indexes) const
data->setData(format, encoded);
return data;
}
ProjectModelSortFilterProxy::ProjectModelSortFilterProxy(QObject *parent):
QSortFilterProxyModel(parent)
{
}
bool ProjectModelSortFilterProxy::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (!sourceModel())
return false;
ProjectModel* projectModel = dynamic_cast<ProjectModel*>(sourceModel());
FolderNode* pLeft=nullptr;
if (source_left.isValid())
pLeft = static_cast<FolderNode*>(source_left.internalPointer());
FolderNode* pRight=nullptr;
if (source_right.isValid())
pRight = static_cast<FolderNode*>(source_right.internalPointer());
if (!pLeft)
return true;
if (!pRight)
return false;
if (pLeft->unitIndex<0 && pRight->unitIndex>=0)
return true;
if (pLeft->unitIndex>=0 && pRight->unitIndex<0)
return false;
return QString::compare(pLeft->text, pRight->text)<0;
}

View File

@ -18,6 +18,7 @@
#define PROJECT_H
#include <QAbstractItemModel>
#include <QSortFilterProxyModel>
#include <memory>
#include "projectoptions.h"
#include "utils.h"
@ -119,6 +120,18 @@ public:
Qt::DropActions supportedDropActions() const override;
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
QMimeData *mimeData(const QModelIndexList &indexes) const override;
Project *project() const;
};
class ProjectModelSortFilterProxy : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit ProjectModelSortFilterProxy(QObject *parent = nullptr);
// QSortFilterProxyModel interface
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
};
class ProjectTemplate;