Skip to content

Commit

Permalink
Configurable additional allowed include paths
Browse files Browse the repository at this point in the history
  • Loading branch information
IgKh committed Jan 22, 2025
1 parent 7e246ec commit 2a570bd
Show file tree
Hide file tree
Showing 15 changed files with 252 additions and 15 deletions.
4 changes: 4 additions & 0 deletions assets/assets.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
<file>icons/go-up.svg</file>
<file>icons/help-about.svg</file>
<file>icons/help-contents.svg</file>
<file>icons/list-add.svg</file>
<file>icons/list-remove.svg</file>
<file>icons/settings-configure.svg</file>
<file>icons/tools-check-spelling.svg</file>
<file>icons/window-close.svg</file>
Expand Down Expand Up @@ -64,6 +66,8 @@
<file>icons-dark/go-up.svg</file>
<file>icons-dark/help-about.svg</file>
<file>icons-dark/help-contents.svg</file>
<file>icons-dark/list-add.svg</file>
<file>icons-dark/list-remove.svg</file>
<file>icons-dark/settings-configure.svg</file>
<file>icons-dark/tools-check-spelling.svg</file>
<file>icons-dark/window-close.svg</file>
Expand Down
7 changes: 7 additions & 0 deletions assets/icons-dark/list-add.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions assets/icons-dark/list-remove.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions assets/icons/list-add.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions assets/icons/list-remove.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions core/katvan_typstdriverwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ void TypstDriverWrapper::resetInputFile(const QString& sourceFileName)
d_status = Status::INITIALIZED;
Q_EMIT compilationStatusChanged();

QMetaObject::invokeMethod(d_engine, "setAllowedPaths", d_allowedPaths);

bool hasPending = false;
if (d_pendingSource) {
setSource(d_pendingSource.value());
Expand Down Expand Up @@ -192,6 +194,15 @@ void TypstDriverWrapper::requestCompletions(int line, int column)
QMetaObject::invokeMethod(d_engine, "requestCompletions", line, column);
}

void TypstDriverWrapper::setAllowedPaths(const QStringList& allowedPaths)
{
d_allowedPaths = allowedPaths;

if (d_status != Status::INITIALIZING) {
QMetaObject::invokeMethod(d_engine, "setAllowedPaths", allowedPaths);
}
}

void TypstDriverWrapper::discardLookupCaches()
{
QMetaObject::invokeMethod(d_engine, "discardLookupCaches");
Expand Down
2 changes: 2 additions & 0 deletions core/katvan_typstdriverwrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public slots:
void inverseSearch(int page, QPointF clickPoint);
void requestToolTip(int line, int column, QPoint pos);
void requestCompletions(int line, int column);
void setAllowedPaths(const QStringList& allowedPaths);
void discardLookupCaches();

private slots:
Expand All @@ -105,6 +106,7 @@ private slots:
QThread* d_thread;

Status d_status;
QStringList d_allowedPaths;
std::optional<QString> d_pendingSource;
QList<PendingEdit> d_pendingEdits;

Expand Down
12 changes: 12 additions & 0 deletions shell/katvan_mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ static constexpr QLatin1StringView SETTING_MAIN_WINDOW_STATE = QLatin1StringView
static constexpr QLatin1StringView SETTING_MAIN_WINDOW_GEOMETRY = QLatin1StringView("MainWindow/geometry");
static constexpr QLatin1StringView SETTING_SPELLING_DICT = QLatin1StringView("spelling/dict");
static constexpr QLatin1StringView SETTING_EDITOR_MODE = QLatin1StringView("editor/mode");
static constexpr QLatin1StringView SETTING_COMPILER_ALLOWED_PATHS = QLatin1StringView("compiler/allowedPaths");

MainWindow::MainWindow()
: QMainWindow(nullptr)
Expand Down Expand Up @@ -357,6 +358,11 @@ void MainWindow::readSettings()
d_backupHandler->setBackupInterval(editorSettings.autoBackupInterval());
typstdriver::PackageManager::applySettings(typstdriver::PackageManagerSettings(settings));

if (settings.contains(SETTING_COMPILER_ALLOWED_PATHS)) {
QStringList allowedPaths = settings.value(SETTING_COMPILER_ALLOWED_PATHS).toStringList();
d_driver->setAllowedPaths(allowedPaths);
}

d_recentFiles->restoreRecents(settings);
d_previewer->restoreSettings(settings);
restoreSpellingDictionary(settings);
Expand Down Expand Up @@ -869,18 +875,23 @@ void MainWindow::showSettingsDialog()
QString mode = settings.value(SETTING_EDITOR_MODE).toString();
EditorSettings editorSettings { mode, EditorSettings::ModeSource::SETTINGS };

QStringList allowedPaths = settings.value(SETTING_COMPILER_ALLOWED_PATHS).toStringList();

d_settingsDialog->setEditorSettings(editorSettings);
d_settingsDialog->setPackageManagerSettings(typstdriver::PackageManagerSettings(settings));
d_settingsDialog->setAllowedPaths(allowedPaths);
d_settingsDialog->open();
}

void MainWindow::settingsDialogAccepted()
{
EditorSettings editorSettings = d_settingsDialog->editorSettings();
typstdriver::PackageManagerSettings packageManagerSettings = d_settingsDialog->packageManagerSettings();
QStringList allowedPaths = d_settingsDialog->allowedPaths();

d_editor->applySettings(editorSettings);
d_backupHandler->setBackupInterval(editorSettings.autoBackupInterval());
d_driver->setAllowedPaths(allowedPaths);
typstdriver::PackageManager::applySettings(packageManagerSettings);

if (!packageManagerSettings.allowPreviewPackages()) {
Expand All @@ -890,6 +901,7 @@ void MainWindow::settingsDialogAccepted()

QSettings settings;
settings.setValue(SETTING_EDITOR_MODE, editorSettings.toModeLine());
settings.setValue(SETTING_COMPILER_ALLOWED_PATHS, allowedPaths);
packageManagerSettings.save(settings);
}

Expand Down
83 changes: 82 additions & 1 deletion shell/katvan_settingsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "katvan_settingsdialog.h"
#include "katvan_utils.h"

#include <QButtonGroup>
#include <QCheckBox>
#include <QDesktopServices>
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QFontComboBox>
#include <QFontDatabase>
#include <QFormLayout>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QLibraryInfo>
#include <QListView>
#include <QLocale>
#include <QPushButton>
#include <QSpinBox>
#include <QStringListModel>
#include <QTabWidget>
#include <QRadioButton>
#include <QVBoxLayout>
Expand Down Expand Up @@ -63,6 +67,16 @@ void SettingsDialog::setPackageManagerSettings(const typstdriver::PackageManager
d_compilerSettingsTab->setSettings(settings);
}

QStringList SettingsDialog::allowedPaths() const
{
return d_compilerSettingsTab->allowedPaths();
}

void SettingsDialog::setAllowedPaths(const QStringList& paths)
{
d_compilerSettingsTab->setAllowedPaths(paths);
}

void SettingsDialog::setupUI()
{
setWindowTitle(tr("Katvan Settings"));
Expand Down Expand Up @@ -292,6 +306,23 @@ void CompilerSettingsTab::setupUI()
{
d_allowPreviewPackages = new QCheckBox(tr("&Allow preview packages"));

d_allowedPathsModel = new QStringListModel();

d_allowedPathsList = new QListView();
d_allowedPathsList->setModel(d_allowedPathsModel);
connect(d_allowedPathsList->selectionModel(), &QItemSelectionModel::currentChanged, this, &CompilerSettingsTab::currentAllowedPathChanged);

QPushButton* addAllowedPathButton = new QPushButton();
addAllowedPathButton->setIcon(utils::themeIcon("list-add"));
addAllowedPathButton->setToolTip(tr("Add an allowed path"));
connect(addAllowedPathButton, &QPushButton::clicked, this, &CompilerSettingsTab::addAllowedPath);

d_removeAllowedPathButton = new QPushButton();
d_removeAllowedPathButton->setIcon(utils::themeIcon("list-remove"));
d_removeAllowedPathButton->setToolTip(tr("Remove the selected path from the list"));
d_removeAllowedPathButton->setEnabled(false);
connect(d_removeAllowedPathButton, &QPushButton::clicked, this, &CompilerSettingsTab::removeAllowedPath);

d_cacheSize = new QLabel();

QPushButton* browseCacheButton = new QPushButton(tr("&Browse..."));
Expand All @@ -303,6 +334,18 @@ void CompilerSettingsTab::setupUI()

universeLayout->addWidget(d_allowPreviewPackages);

QGroupBox* allowedPathsGroup = new QGroupBox(tr("Allowed Paths"));
QVBoxLayout* allowedPathsLayout = new QVBoxLayout(allowedPathsGroup);

QHBoxLayout* allowedPathsButtonLayout = new QHBoxLayout();
allowedPathsButtonLayout->addStretch(1);
allowedPathsButtonLayout->addWidget(addAllowedPathButton);
allowedPathsButtonLayout->addWidget(d_removeAllowedPathButton);

allowedPathsLayout->addWidget(new QLabel(tr("Allow including resources also from the following directories and their subdirectories:")));
allowedPathsLayout->addWidget(d_allowedPathsList, 1);
allowedPathsLayout->addLayout(allowedPathsButtonLayout);

QFormLayout* downloadCacheTopLayout = new QFormLayout();
downloadCacheTopLayout->addRow(tr("Cache size: "), d_cacheSize);

Expand All @@ -317,8 +360,8 @@ void CompilerSettingsTab::setupUI()

QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(universeGroup);
mainLayout->addWidget(allowedPathsGroup, 1);
mainLayout->addWidget(downloadCacheGroup);
mainLayout->addStretch(1);
}

typstdriver::PackageManagerSettings CompilerSettingsTab::settings() const
Expand All @@ -334,12 +377,50 @@ void CompilerSettingsTab::setSettings(const typstdriver::PackageManagerSettings&
d_allowPreviewPackages->setChecked(settings.allowPreviewPackages());
}

QStringList CompilerSettingsTab::allowedPaths() const
{
return d_allowedPathsModel->stringList();
}

void CompilerSettingsTab::setAllowedPaths(const QStringList& paths)
{
d_allowedPathsModel->setStringList(paths);
}

void CompilerSettingsTab::showEvent(QShowEvent* event)
{
QWidget::showEvent(event);
updateCacheSize();
}

void CompilerSettingsTab::addAllowedPath()
{
QString dirName = QFileDialog::getExistingDirectory(this);
if (dirName.isEmpty()) {
return;
}

QStringList values = d_allowedPathsModel->stringList();
if (!values.contains(dirName)) {
values.append(dirName);
d_allowedPathsModel->setStringList(values);
}
}

void CompilerSettingsTab::removeAllowedPath()
{
QModelIndex current = d_allowedPathsList->currentIndex();
if (!current.isValid()) {
return;
}
d_allowedPathsModel->removeRow(current.row());
}

void CompilerSettingsTab::currentAllowedPathChanged()
{
d_removeAllowedPathButton->setEnabled(d_allowedPathsList->currentIndex().isValid());
}

void CompilerSettingsTab::updateCacheSize()
{
auto stats = typstdriver::PackageManager::cacheStatistics();
Expand Down
14 changes: 14 additions & 0 deletions shell/katvan_settingsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ class QCheckBox;
class QComboBox;
class QFontComboBox;
class QLabel;
class QListView;
class QRadioButton;
class QSpinBox;
class QStringListModel;
QT_END_NAMESPACE

namespace katvan {
Expand All @@ -50,6 +52,9 @@ class SettingsDialog : public QDialog
typstdriver::PackageManagerSettings packageManagerSettings() const;
void setPackageManagerSettings(const typstdriver::PackageManagerSettings& settings);

QStringList allowedPaths() const;
void setAllowedPaths(const QStringList& paths);

private:
void setupUI();

Expand Down Expand Up @@ -96,7 +101,13 @@ class CompilerSettingsTab : public QWidget
typstdriver::PackageManagerSettings settings() const;
void setSettings(const typstdriver::PackageManagerSettings& settings);

QStringList allowedPaths() const;
void setAllowedPaths(const QStringList& paths);

private slots:
void addAllowedPath();
void removeAllowedPath();
void currentAllowedPathChanged();
void updateCacheSize();
void browseCache();

Expand All @@ -107,6 +118,9 @@ private slots:
void setupUI();

QCheckBox* d_allowPreviewPackages;
QStringListModel* d_allowedPathsModel;
QListView* d_allowedPathsList;
QPushButton* d_removeAllowedPathButton;
QLabel* d_cacheSize;
};

Expand Down
2 changes: 2 additions & 0 deletions typstdriver/rust/src/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ pub(crate) mod ffi {

fn get_completions(&self, line: usize, column: usize) -> Result<Completions>;

fn set_allowed_paths(&mut self, paths: Vec<String>);

fn discard_lookup_caches(&mut self);

unsafe fn create_engine_impl<'a>(
Expand Down
18 changes: 17 additions & 1 deletion typstdriver/rust/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl<'a> EngineImpl<'a> {
.unwrap_or(diag.span);

let location = self.span_to_location(span);
let hints = diag.hints.iter().map(|hint| hint.as_str()).collect();
let hints = Self::get_diagnostic_hints(diag);

match diag.severity {
typst::diag::Severity::Error => self.logger.log_error(
Expand Down Expand Up @@ -173,6 +173,18 @@ impl<'a> EngineImpl<'a> {
}
}

fn get_diagnostic_hints(diag: &typst::diag::SourceDiagnostic) -> Vec<&str> {
// As per https://github.com/typst/typst/blob/0.12/crates/typst/src/diag.rs#L311
if diag.message.contains("(access denied)") {
vec![
"by default cannot read file outside of document's directory",
"additional allowed paths can be set in compiler settings",
]
} else {
diag.hints.iter().map(|hint| hint.as_str()).collect()
}
}

pub fn render_page(
&self,
page: usize,
Expand Down Expand Up @@ -328,6 +340,10 @@ impl<'a> EngineImpl<'a> {
})
}

pub fn set_allowed_paths(&mut self, paths: Vec<String>) {
self.world.set_allowed_paths(paths);
}

pub fn discard_lookup_caches(&mut self) {
self.world.discard_package_roots_cache();
}
Expand Down
Loading

0 comments on commit 2a570bd

Please # to comment.