Start: add optional custom folder view (#19473)

* Start: add optional additional folder view

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Added logic to migrate ShowCustomFolder parameter

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Rename Additional to Custom folder

* Change Start page text to sentence case for consistency

* Fix breakage created by pre-commit.ci

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Rearrange migration logic to make it more explicit

* Revert "Change Start page text to sentence case for consistency"

This reverts commit 8a31a1238c0380ddbe13e6e5838a3be6b13400a5.

* Make parameterGroup local

* Apply suggestions and linter improvements

* Adapted suggestion to simplify migration logic

* Start: Warning -> Message for rename of ShowCustomFolder

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
This commit is contained in:
Furgo
2025-02-17 17:18:35 +01:00
committed by GitHub
parent cc21acb325
commit 2e07d3be95
5 changed files with 164 additions and 0 deletions

View File

@@ -37,6 +37,8 @@ SET(Start_SRCS
DisplayedFilesModel.h
ExamplesModel.cpp
ExamplesModel.h
CustomFolderModel.cpp
CustomFolderModel.h
PreCompiled.cpp
PreCompiled.h
RecentFilesModel.cpp

View File

@@ -0,0 +1,61 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2024 The FreeCAD Project Association AISBL *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* FreeCAD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QDir>
#endif
#include "CustomFolderModel.h"
#include <App/Application.h>
using namespace Start;
CustomFolderModel::CustomFolderModel(QObject* parent)
: DisplayedFilesModel(parent)
{
Base::Reference<ParameterGrp> parameterGroup = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Start");
_customFolderDirectory =
QDir(QString::fromStdString(parameterGroup->GetASCII("CustomFolder", "")));
}
void CustomFolderModel::loadCustomFolder()
{
beginResetModel();
clear();
if (!_customFolderDirectory.isReadable()) {
Base::Console().Warning(
"BaseApp/Preferences/Mod/Start/CustomFolder: cannot read custom folder %s\n",
_customFolderDirectory.absolutePath().toStdString().c_str());
}
auto entries = _customFolderDirectory.entryList(QDir::Filter::Files | QDir::Filter::Readable,
QDir::SortFlag::Name);
for (const auto& entry : entries) {
addFile(_customFolderDirectory.filePath(entry));
}
endResetModel();
}

View File

@@ -0,0 +1,53 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2024 The FreeCAD Project Association AISBL *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* FreeCAD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#ifndef FREECAD_START_CUSTOMFOLDERMODEL_H
#define FREECAD_START_CUSTOMFOLDERMODEL_H
#include <QAbstractListModel>
#include <QDir>
#include <Base/Parameter.h>
#include "DisplayedFilesModel.h"
#include "../StartGlobal.h"
namespace Start
{
/// A model for displaying a list of files including a thumbnail or icon, plus various file
/// statistics.
class StartExport CustomFolderModel: public DisplayedFilesModel
{
Q_OBJECT
public:
explicit CustomFolderModel(QObject* parent = nullptr);
void loadCustomFolder();
private:
QDir _customFolderDirectory;
};
} // namespace Start
#endif // FREECAD_START_CUSTOMFOLDERMODEL_H

View File

@@ -185,6 +185,7 @@ StartView::StartView(QWidget* parent)
, _newFileLabel {nullptr}
, _examplesLabel {nullptr}
, _recentFilesLabel {nullptr}
, _customFolderLabel {nullptr}
, _showOnStartupCheckBox {nullptr}
{
setObjectName(QLatin1String("StartView"));
@@ -193,6 +194,30 @@ StartView::StartView(QWidget* parent)
auto cardSpacing = hGrp->GetInt("FileCardSpacing", 15); // NOLINT
auto showExamples = hGrp->GetBool("ShowExamples", true); // NOLINT
// Migrate legacy property, can be removed in later releases
std::string legacyCustomFolder(hGrp->GetASCII("ShowCustomFolder", ""));
if (!legacyCustomFolder.empty()) {
hGrp->SetASCII("CustomFolder", legacyCustomFolder);
hGrp->RemoveASCII("ShowCustomFolder");
Base::Console().Message("v1.1: renamed ShowCustomFolder parameter to CustomFolder\n");
}
// End of migration code
// Verify that the folder specified in preferences is available before showing it
std::string customFolder(hGrp->GetASCII("CustomFolder", ""));
bool showCustomFolder = false;
if (!customFolder.empty()) {
auto customFolderDirectory = QDir(QString::fromStdString(customFolder));
if (customFolderDirectory.exists()) {
showCustomFolder = true;
}
else {
Base::Console().Warning(
"BaseApp/Preferences/Mod/Start/CustomFolder: '%s' does not exist\n",
customFolderDirectory.absolutePath().toStdString().c_str());
}
}
// First start page
auto firstStartScrollArea = gsl::owner<QScrollArea*>(new QScrollArea());
auto firstStartScrollWidget = gsl::owner<QWidget*>(new QWidget(firstStartScrollArea));
@@ -245,6 +270,15 @@ StartView::StartView(QWidget* parent)
connect(recentFilesListWidget, &QListView::clicked, this, &StartView::fileCardSelected);
documentsContentLayout->addWidget(recentFilesListWidget);
auto customFolderListWidget = gsl::owner<FileCardView*>(new FileCardView(_contents));
customFolderListWidget->setVisible(showCustomFolder);
_customFolderLabel = gsl::owner<QLabel*>(new QLabel());
_customFolderLabel->setVisible(showCustomFolder);
documentsContentLayout->addWidget(_customFolderLabel);
connect(customFolderListWidget, &QListView::clicked, this, &StartView::fileCardSelected);
documentsContentLayout->addWidget(customFolderListWidget);
auto examplesListWidget = gsl::owner<FileCardView*>(new FileCardView(_contents));
examplesListWidget->setVisible(showExamples);
_examplesLabel = gsl::owner<QLabel*>(new QLabel());
@@ -281,6 +315,7 @@ StartView::StartView(QWidget* parent)
// Set startup widget according to the first start parameter
auto firstStart = hGrp->GetBool("FirstStart2024", true); // NOLINT
_contents->setCurrentWidget(firstStart ? firstStartScrollArea : documentsWidget);
configureCustomFolderListWidget(customFolderListWidget);
configureExamplesListWidget(examplesListWidget);
configureRecentFilesListWidget(recentFilesListWidget, _recentFilesLabel);
@@ -370,6 +405,14 @@ void StartView::configureExamplesListWidget(QListView* examplesListWidget)
}
void StartView::configureCustomFolderListWidget(QListView* customFolderListWidget)
{
_customFolderModel.loadCustomFolder();
customFolderListWidget->setModel(&_customFolderModel);
configureFileCardWidget(customFolderListWidget);
}
void StartView::newEmptyFile() const
{
Gui::Application::Instance->commandManager().runCommandByName("Std_New");
@@ -529,6 +572,7 @@ void StartView::retranslateUi()
_newFileLabel->setText(h1Start + tr("New File") + h1End);
_examplesLabel->setText(h1Start + tr("Examples") + h1End);
_recentFilesLabel->setText(h1Start + tr("Recent Files") + h1End);
_customFolderLabel->setText(h1Start + tr("Custom Folder") + h1End);
QString application = QString::fromUtf8(App::Application::Config()["ExeName"].c_str());
_openFirstStart->setText(tr("Open first start setup"));

View File

@@ -31,6 +31,7 @@
#include "../App/DisplayedFilesModel.h"
#include "../App/RecentFilesModel.h"
#include "../App/ExamplesModel.h"
#include "../App/CustomFolderModel.h"
class QCheckBox;
class QEvent;
@@ -86,6 +87,7 @@ protected:
static void configureFileCardWidget(QListView* fileCardWidget);
void configureRecentFilesListWidget(QListView* recentFilesListWidget, QLabel* recentFilesLabel);
void configureExamplesListWidget(QListView* examplesListWidget);
void configureCustomFolderListWidget(QListView* customFolderListWidget);
void postStart(PostStartBehavior behavior) const;
@@ -101,9 +103,11 @@ private:
QStackedWidget* _contents = nullptr;
Start::RecentFilesModel _recentFilesModel;
Start::ExamplesModel _examplesModel;
Start::CustomFolderModel _customFolderModel;
QLabel* _newFileLabel;
QLabel* _examplesLabel;
QLabel* _recentFilesLabel;
QLabel* _customFolderLabel;
QPushButton* _openFirstStart;
QCheckBox* _showOnStartupCheckBox;