enhancement: sort folders before files in project view
This commit is contained in:
parent
13ee2d7f33
commit
96f8804edd
|
@ -116,8 +116,9 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
connect(mEditorList, &EditorList::editorClosed,
|
connect(mEditorList, &EditorList::editorClosed,
|
||||||
this, &MainWindow::onEditorClosed);
|
this, &MainWindow::onEditorClosed);
|
||||||
mProject = nullptr;
|
mProject = nullptr;
|
||||||
ui->projectView->setModel(&mProjectProxyModel);
|
mProjectProxyModel = new ProjectModelSortFilterProxy(this);
|
||||||
mProjectProxyModel.setDynamicSortFilter(false);
|
ui->projectView->setModel(mProjectProxyModel);
|
||||||
|
mProjectProxyModel->setDynamicSortFilter(false);
|
||||||
setupActions();
|
setupActions();
|
||||||
ui->EditorTabsRight->setVisible(false);
|
ui->EditorTabsRight->setVisible(false);
|
||||||
|
|
||||||
|
@ -2396,8 +2397,9 @@ void MainWindow::buildContextMenus()
|
||||||
ui->projectView);
|
ui->projectView);
|
||||||
connect(mProject_Rename_Unit, &QAction::triggered,
|
connect(mProject_Rename_Unit, &QAction::triggered,
|
||||||
[this](){
|
[this](){
|
||||||
if (ui->projectView->currentIndex().isValid())
|
if (ui->projectView->currentIndex().isValid()) {
|
||||||
ui->projectView->edit(ui->projectView->currentIndex());
|
ui->projectView->edit(ui->projectView->currentIndex());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
mProject_Add_Folder = createActionFor(
|
mProject_Add_Folder = createActionFor(
|
||||||
tr("Add Folder"),
|
tr("Add Folder"),
|
||||||
|
@ -2406,7 +2408,7 @@ void MainWindow::buildContextMenus()
|
||||||
[this](){
|
[this](){
|
||||||
if (!mProject)
|
if (!mProject)
|
||||||
return;
|
return;
|
||||||
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->currentIndex());
|
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->currentIndex());
|
||||||
if (!current.isValid()) {
|
if (!current.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2438,8 +2440,9 @@ void MainWindow::buildContextMenus()
|
||||||
ui->projectView);
|
ui->projectView);
|
||||||
connect(mProject_Rename_Folder, &QAction::triggered,
|
connect(mProject_Rename_Folder, &QAction::triggered,
|
||||||
[this](){
|
[this](){
|
||||||
if (ui->projectView->currentIndex().isValid())
|
if (ui->projectView->currentIndex().isValid()) {
|
||||||
ui->projectView->edit(ui->projectView->currentIndex());
|
ui->projectView->edit(ui->projectView->currentIndex());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
mProject_Remove_Folder = createActionFor(
|
mProject_Remove_Folder = createActionFor(
|
||||||
tr("Remove Folder"),
|
tr("Remove Folder"),
|
||||||
|
@ -2448,7 +2451,7 @@ void MainWindow::buildContextMenus()
|
||||||
[this](){
|
[this](){
|
||||||
if (!mProject)
|
if (!mProject)
|
||||||
return;
|
return;
|
||||||
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->currentIndex());
|
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->currentIndex());
|
||||||
if (!current.isValid()) {
|
if (!current.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2840,7 +2843,7 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos)
|
||||||
bool onRoot = false;
|
bool onRoot = false;
|
||||||
bool folderEmpty = false;
|
bool folderEmpty = false;
|
||||||
int unitIndex = -1;
|
int unitIndex = -1;
|
||||||
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->selectionModel()->currentIndex());
|
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->selectionModel()->currentIndex());
|
||||||
if (current.isValid() && mProject) {
|
if (current.isValid() && mProject) {
|
||||||
FolderNode * node = static_cast<FolderNode*>(current.internalPointer());
|
FolderNode * node = static_cast<FolderNode*>(current.internalPointer());
|
||||||
PFolderNode pNode = mProject->pointerToNode(node);
|
PFolderNode pNode = mProject->pointerToNode(node);
|
||||||
|
@ -3467,36 +3470,22 @@ void MainWindow::closeProject(bool refreshEditor)
|
||||||
void MainWindow::updateProjectView()
|
void MainWindow::updateProjectView()
|
||||||
{
|
{
|
||||||
if (mProject) {
|
if (mProject) {
|
||||||
if (mProjectProxyModel.sourceModel()!=mProject->model()) {
|
if (mProjectProxyModel->sourceModel()!=mProject->model()) {
|
||||||
mProjectProxyModel.setSourceModel(mProject->model());
|
mProjectProxyModel->setSourceModel(mProject->model());
|
||||||
connect(mProject->model(),&ProjectModel::dataChanged, &mProjectProxyModel,
|
mProjectProxyModel->sort(0);
|
||||||
[this]() {
|
connect(mProject->model(), &ProjectModel::dataChanged,
|
||||||
mProjectProxyModel.invalidate();
|
this, &MainWindow::invalidateProjectProxyModel);
|
||||||
});
|
|
||||||
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);
|
|
||||||
connect(mProject->model(), &QAbstractItemModel::modelReset,
|
connect(mProject->model(), &QAbstractItemModel::modelReset,
|
||||||
ui->projectView,&QTreeView::expandAll);
|
ui->projectView,&QTreeView::expandAll);
|
||||||
}
|
} else
|
||||||
mProjectProxyModel.invalidate();
|
mProjectProxyModel->invalidate();
|
||||||
ui->projectView->expandAll();
|
ui->projectView->expandAll();
|
||||||
openCloseLeftPanel(true);
|
openCloseLeftPanel(true);
|
||||||
ui->tabProject->setVisible(true);
|
ui->tabProject->setVisible(true);
|
||||||
ui->tabInfos->setCurrentWidget(ui->tabProject);
|
ui->tabInfos->setCurrentWidget(ui->tabProject);
|
||||||
} else {
|
} else {
|
||||||
// Clear project browser
|
// Clear project browser
|
||||||
mProjectProxyModel.setSourceModel(nullptr);
|
mProjectProxyModel->setSourceModel(nullptr);
|
||||||
ui->tabProject->setVisible(false);
|
ui->tabProject->setVisible(false);
|
||||||
}
|
}
|
||||||
updateProjectActions();
|
updateProjectActions();
|
||||||
|
@ -4903,9 +4892,10 @@ std::shared_ptr<Project> MainWindow::project()
|
||||||
|
|
||||||
void MainWindow::on_projectView_doubleClicked(const QModelIndex &index)
|
void MainWindow::on_projectView_doubleClicked(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
QModelIndex sourceIndex = mProjectProxyModel->mapToSource(index);
|
||||||
|
if (!sourceIndex.isValid())
|
||||||
return;
|
return;
|
||||||
FolderNode * node = static_cast<FolderNode*>(index.internalPointer());
|
FolderNode * node = static_cast<FolderNode*>(sourceIndex.internalPointer());
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
if (node->unitIndex>=0) {
|
if (node->unitIndex>=0) {
|
||||||
|
@ -5055,7 +5045,7 @@ void MainWindow::on_actionAdd_to_project_triggered()
|
||||||
dialog.setFileMode(QFileDialog::ExistingFiles);
|
dialog.setFileMode(QFileDialog::ExistingFiles);
|
||||||
dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
if (dialog.exec()) {
|
if (dialog.exec()) {
|
||||||
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->currentIndex());
|
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->currentIndex());
|
||||||
FolderNode * node = nullptr;
|
FolderNode * node = nullptr;
|
||||||
if (current.isValid()) {
|
if (current.isValid()) {
|
||||||
node = static_cast<FolderNode*>(current.internalPointer());
|
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()){
|
foreach (const QModelIndex& index, ui->projectView->selectionModel()->selectedIndexes()){
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
continue;
|
continue;
|
||||||
QModelIndex realIndex = mProjectProxyModel.mapToSource(index);
|
QModelIndex realIndex = mProjectProxyModel->mapToSource(index);
|
||||||
FolderNode * node = static_cast<FolderNode*>(realIndex.internalPointer());
|
FolderNode * node = static_cast<FolderNode*>(realIndex.internalPointer());
|
||||||
PFolderNode folderNode = mProject->pointerToNode(node);
|
PFolderNode folderNode = mProject->pointerToNode(node);
|
||||||
if (!folderNode)
|
if (!folderNode)
|
||||||
|
@ -5308,7 +5298,7 @@ void MainWindow::newProjectUnitFile()
|
||||||
if (!mProject)
|
if (!mProject)
|
||||||
return;
|
return;
|
||||||
int idx = -1;
|
int idx = -1;
|
||||||
QModelIndex current = mProjectProxyModel.mapToSource(ui->projectView->currentIndex());
|
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->currentIndex());
|
||||||
FolderNode * node = nullptr;
|
FolderNode * node = nullptr;
|
||||||
if (current.isValid()) {
|
if (current.isValid()) {
|
||||||
node = static_cast<FolderNode*>(current.internalPointer());
|
node = static_cast<FolderNode*>(current.internalPointer());
|
||||||
|
@ -5347,6 +5337,11 @@ void MainWindow::newProjectUnitFile()
|
||||||
editor->activate();
|
editor->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::invalidateProjectProxyModel()
|
||||||
|
{
|
||||||
|
mProjectProxyModel->invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::onEditorRenamed(const QString &oldFilename, const QString &newFilename, bool firstSave)
|
void MainWindow::onEditorRenamed(const QString &oldFilename, const QString &newFilename, bool firstSave)
|
||||||
{
|
{
|
||||||
if (firstSave)
|
if (firstSave)
|
||||||
|
|
|
@ -251,6 +251,7 @@ private:
|
||||||
void newProjectUnitFile();
|
void newProjectUnitFile();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void invalidateProjectProxyModel();
|
||||||
void onEditorRenamed(const QString& oldFilename, const QString& newFilename, bool firstSave);
|
void onEditorRenamed(const QString& oldFilename, const QString& newFilename, bool firstSave);
|
||||||
void onAutoSaveTimeout();
|
void onAutoSaveTimeout();
|
||||||
void onFileChanged(const QString& path);
|
void onFileChanged(const QString& path);
|
||||||
|
@ -674,7 +675,7 @@ private:
|
||||||
QAction * mProblem_OpenSource;
|
QAction * mProblem_OpenSource;
|
||||||
QAction * mProblem_Properties;
|
QAction * mProblem_Properties;
|
||||||
|
|
||||||
QSortFilterProxyModel mProjectProxyModel;
|
QSortFilterProxyModel* mProjectProxyModel;
|
||||||
|
|
||||||
// QWidget interface
|
// QWidget interface
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1811,6 +1811,11 @@ void ProjectModel::endUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Project *ProjectModel::project() const
|
||||||
|
{
|
||||||
|
return mProject;
|
||||||
|
}
|
||||||
|
|
||||||
QModelIndex ProjectModel::index(int row, int column, const QModelIndex &parent) const
|
QModelIndex ProjectModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
|
@ -1906,6 +1911,7 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
|
||||||
if (newName.isEmpty())
|
if (newName.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
mProject->setName(newName);
|
mProject->setName(newName);
|
||||||
|
emit dataChanged(index,index);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int idx = node->unitIndex;
|
int idx = node->unitIndex;
|
||||||
|
@ -1973,6 +1979,7 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
|
||||||
|
|
||||||
// Add new filename to file minitor
|
// Add new filename to file minitor
|
||||||
pMainWindow->fileSystemWatcher()->addPath(newName);
|
pMainWindow->fileSystemWatcher()->addPath(newName);
|
||||||
|
emit dataChanged(index,index);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
//change folder name
|
//change folder name
|
||||||
|
@ -1984,6 +1991,7 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
|
||||||
node->text = newName;
|
node->text = newName;
|
||||||
mProject->updateFolders();
|
mProject->updateFolders();
|
||||||
mProject->saveAll();
|
mProject->saveAll();
|
||||||
|
emit dataChanged(index,index);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2134,3 +2142,31 @@ QMimeData *ProjectModel::mimeData(const QModelIndexList &indexes) const
|
||||||
data->setData(format, encoded);
|
data->setData(format, encoded);
|
||||||
return data;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define PROJECT_H
|
#define PROJECT_H
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "projectoptions.h"
|
#include "projectoptions.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -119,6 +120,18 @@ public:
|
||||||
Qt::DropActions supportedDropActions() const override;
|
Qt::DropActions supportedDropActions() const override;
|
||||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||||
QMimeData *mimeData(const QModelIndexList &indexes) const 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;
|
class ProjectTemplate;
|
||||||
|
|
Loading…
Reference in New Issue