Improved exceptions and added error message dialog UI

This commit is contained in:
GPayne
2020-09-16 07:11:50 -06:00
parent 0dcf4a5e82
commit 831bf87d0c
14 changed files with 345 additions and 96 deletions

View File

@@ -27,6 +27,7 @@ set(HEADER_FILES
include/assettreemodel.h
include/camera.h
include/deltatimes.h
include/errordialog.h
include/filesystemaccess.h
include/keybindings.h
include/launcherwindow.h
@@ -40,6 +41,7 @@ set(HEADER_FILES
include/ui_assets.h
include/ui_camera.h
include/ui_deltatimes.h
include/ui_errordialog.h
include/ui_keybindings.h
include/ui_launcherwindow.h
include/ui_marknodes.h
@@ -57,6 +59,7 @@ set(SOURCE_FILES
src/assettreemodel.cpp
src/camera.cpp
src/deltatimes.cpp
src/errordialog.cpp
src/filesystemaccess.cpp
src/keybindings.cpp
src/launcherwindow.cpp

View File

@@ -23,7 +23,7 @@ public slots:
void parseSelections();
public:
explicit assets(openspace::Profile* imported, std::string& reportAssets,
explicit assets(openspace::Profile* imported, const std::string reportAssets,
QWidget *parent = nullptr);
~assets();
std::string createTextSummary();

View File

@@ -25,8 +25,11 @@ struct DeltaTimes {
std::vector<double> _times;
DeltaTimes() {
_times.resize(sizeof(_defaultDeltaTimes)/sizeof(double));
zeroValues();
};
DeltaTimes(std::vector<double> dt) {
_times.resize(sizeof(_defaultDeltaTimes)/sizeof(double));
zeroValues();
_times = dt;
};
void loadValues(std::vector<double>& dt) {
@@ -39,7 +42,7 @@ struct DeltaTimes {
return std::distance(_times.begin(), it);
};
size_t totalSize() {
return sizeof(_defaultDeltaTimes) / sizeof(double);
return (sizeof(_defaultDeltaTimes) / sizeof(double));
}
void zeroValues() {
for (size_t i = 0; i < _times.size(); ++i) {

View File

@@ -0,0 +1,29 @@
#ifndef ERRORDIALOG_H
#define ERRORDIALOG_H
#include <QDir>
#include <QDialog>
#include <QLineEdit>
#include "ui_errordialog.h"
namespace Ui {
class errordialog;
}
class errordialog : public QDialog
{
Q_OBJECT
public slots:
//void accept();
public:
explicit errordialog(QString message, QWidget *parent = nullptr);
~errordialog();
private:
Ui::errordialog *ui;
QWidget* _parent;
};
#endif // ERRORDIALOG_H

View File

@@ -15,6 +15,7 @@
#include "marknodes.h"
#include "ostime.h"
#include <openspace/scene/profile.h>
#include <errordialog.h>
QT_BEGIN_NAMESPACE
namespace Ui {
@@ -22,20 +23,6 @@ class ProfileEdit;
}
QT_END_NAMESPACE
/*struct ProfileBlock {
openspace::Profile::Meta& _metaData;
std::vector<openspace::Profile::Module>& _moduleData;
std::vector<openspace::Profile::Asset>& _assetData;
std::string& _reportAssetsInFilesystem;
std::vector<openspace::Profile::Property>& _propsData;
std::vector<openspace::Profile::Keybinding>& _keybindingsData;
DeltaTimes& _deltaTimesData;
openspace::Profile::Time& _timeData;
openspace::Profile::CameraType& _cameraData;
std::vector<std::string>& _markNodesData;
std::string& _addedScriptsData;
};*/
class ProfileEdit : public QDialog
{
Q_OBJECT
@@ -51,14 +38,17 @@ public slots:
void openDeltaTimes();
void openCamera();
void openMarkNodes();
void cancel();
void approved();
public:
explicit ProfileEdit(std::string filename, std::string reportedAssets, QWidget *parent = nullptr);
explicit ProfileEdit(std::string filename, const std::string reportedAssets, QWidget *parent = nullptr);
~ProfileEdit();
//void setProfileName(QString profileToSet);
void setProfileName(QString profileToSet);
private:
void loadProfileFromFile(std::string filename);
bool loadProfileFromFile(std::string filename);
void displayProfileParseErrorDialogThenQuit(std::string msg);
void initSummaryTextForEachCategory();
QString summarizeText_meta();
QString summarizeText_modules();
@@ -73,6 +63,7 @@ private:
Ui::ProfileEdit *ui;
QWidget* _parent;
errordialog* _myDialog;
meta* _meta;
properties* _properties;
osmodules* _modules;
@@ -87,7 +78,7 @@ private:
//ProfileBlock _pData;
openspace::Profile* _pData = nullptr;
std::vector<std::string> _content;
std::string& _reportedAssets;
const std::string _reportedAssets;
};
#endif // PROFILEEDIT_H

View File

@@ -0,0 +1,66 @@
/********************************************************************************
** Form generated from reading UI file 'errordialog.ui'
**
** Created by: Qt User Interface Compiler version 5.15.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_ERRORDIALOG_H
#define UI_ERRORDIALOG_H
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDialog>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QLabel>
QT_BEGIN_NAMESPACE
class Ui_errordialog
{
public:
QDialogButtonBox *buttonBox;
QLabel *label;
void setupUi(QDialog *errordialog)
{
if (errordialog->objectName().isEmpty())
errordialog->setObjectName(QString::fromUtf8("errordialog"));
errordialog->resize(400, 181);
buttonBox = new QDialogButtonBox(errordialog);
buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setGeometry(QRect(140, 120, 91, 32));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Ok);
label = new QLabel(errordialog);
label->setObjectName(QString::fromUtf8("label"));
label->setGeometry(QRect(20, 10, 360, 100));
QFont font;
font.setFamily(QString::fromUtf8("Arial"));
font.setPointSize(12);
label->setFont(font);
label->setWordWrap(true);
retranslateUi(errordialog);
QObject::connect(buttonBox, SIGNAL(accepted()), errordialog, SLOT(accept()));
QObject::connect(buttonBox, SIGNAL(rejected()), errordialog, SLOT(reject()));
QMetaObject::connectSlotsByName(errordialog);
} // setupUi
void retranslateUi(QDialog *errordialog)
{
errordialog->setWindowTitle(QCoreApplication::translate("errordialog", "Profile Format Error", nullptr));
label->setText(QCoreApplication::translate("errordialog", "TextLabel", nullptr));
} // retranslateUi
};
namespace Ui {
class errordialog: public Ui_errordialog {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_ERRORDIALOG_H

View File

@@ -7,7 +7,7 @@
#include <string>
#include <openspace/scene/profile.h>
assets::assets(openspace::Profile* imported, std::string& reportAssets, QWidget *parent)
assets::assets(openspace::Profile* imported, const std::string reportAssets, QWidget *parent)
: QDialog(parent)
, ui(new Ui::assets)
, _imported(imported)

View File

@@ -1,6 +1,7 @@
#include "deltatimes.h"
#include "./ui_deltatimes.h"
#include <qevent.h>
#include <iostream>
deltaTimes::deltaTimes(openspace::Profile* imported, QWidget *parent)
: QDialog(parent)
@@ -10,7 +11,7 @@ deltaTimes::deltaTimes(openspace::Profile* imported, QWidget *parent)
{
ui->setupUi(this);
for (size_t d = 0; d < _data.totalSize(); ++d) {
for (size_t d = 0; d < _data.size(); ++d) {
QString summary = createSummaryForDeltaTime(d, _data._times.at(d), true);
_deltaListItems.push_back(new QListWidgetItem(summary));
ui->listWidget->addItem(_deltaListItems[d]);
@@ -69,6 +70,9 @@ void deltaTimes::listItemSelected() {
}
int deltaTimes::lastSelectableItem() {
if (_data.size() == 0) {
return 0;
}
int i;
for (i = _data.size() - 1; i >= 0; --i) {
if (_data._times.at(i) != 0) {
@@ -112,11 +116,19 @@ QString deltaTimes::checkForTimeDescription(int intervalIndex, double value) {
void deltaTimes::saveDeltaTimeValue() {
QListWidgetItem *item = ui->listWidget->currentItem();
int index = ui->listWidget->row(item);
if (isNumericalValue(ui->line_seconds) && index <= lastSelectableItem() + 1) {
_data._times.at(index) = ui->line_seconds->text().toDouble();
QString summary = createSummaryForDeltaTime(index, _data._times.at(index), true);
_deltaListItems.at(index)->setText(summary);
if (item != nullptr) {
int index = ui->listWidget->row(item);
if (isNumericalValue(ui->line_seconds) && index <= lastSelectableItem() + 1) {
_data._times.at(index) = ui->line_seconds->text().toDouble();
QString summary = createSummaryForDeltaTime(index, _data._times.at(index), true);
_deltaListItems.at(index)->setText(summary);
}
}
else if (_data.size() == 0) {
_data._times.at(0) = ui->line_seconds->text().toDouble();
QString summary = createSummaryForDeltaTime(0, _data._times.at(0), true);
_deltaListItems.push_back(new QListWidgetItem(summary));
ui->listWidget->addItem(_deltaListItems[0]);
}
}

View File

@@ -0,0 +1,23 @@
#include "errordialog.h"
#include "ui_errordialog.h"
#include <QFileSystemModel>
#include <QScreen>
#include <sstream>
errordialog::errordialog(QString message, QWidget *parent)
: QDialog(parent)
, ui(new Ui::errordialog)
{
ui->setupUi(this);
ui->label->setText(message);
//connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(cancel()));
}
errordialog::~errordialog() {
delete ui;
}
//void errordialog::accept() {
// reject();
//}

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>errordialog</class>
<widget class="QDialog" name="errordialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>181</height>
</rect>
</property>
<property name="windowTitle">
<string>Profile Format Error</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>140</x>
<y>120</y>
<width>91</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>60</x>
<y>30</y>
<width>261</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>errordialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>errordialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -15,17 +15,6 @@ LauncherWindow::LauncherWindow(std::string basePath, QWidget *parent)
, _filesystemAccess(".asset", {"scene", "global", "customization", "examples"},
true, true)
, _basePath(QString::fromUtf8(basePath.c_str()))
/*, _pData({_metaData,
_moduleData,
_assetData,
_reportAssetsInFilesystem,
_propsData,
_keybindingsData,
_deltaTimesData,
_timeData,
_cameraData,
_markNodesData,
_addedScriptsData})*/
{
ui->setupUi(this);
QString logoPath = _basePath + "/data/openspace-horiz-logo.png";
@@ -78,6 +67,7 @@ void LauncherWindow::openWindow_edit() {
editProfilePath += profileToSet.toUtf8().constData();
editProfilePath += ".profile";
myEditorWindow = new ProfileEdit(editProfilePath, _reportAssetsInFilesystem);
myEditorWindow->setProfileName(profileToSet);
myEditorWindow->exec();
}

View File

@@ -6,7 +6,7 @@
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
ProfileEdit::ProfileEdit(std::string filename, std::string reportedAssets, QWidget *parent)
ProfileEdit::ProfileEdit(std::string filename, const std::string reportedAssets, QWidget *parent)
: QDialog(parent)
, ui(new Ui::ProfileEdit)
, _reportedAssets(reportedAssets)
@@ -15,7 +15,6 @@ ProfileEdit::ProfileEdit(std::string filename, std::string reportedAssets, QWidg
loadProfileFromFile(filename);
initSummaryTextForEachCategory();
connect(ui->edit_meta, SIGNAL(clicked()), this, SLOT(openMeta()));
connect(ui->edit_properties, SIGNAL(clicked()), this, SLOT(openProperties()));
connect(ui->edit_modules, SIGNAL(clicked()), this, SLOT(openModules()));
@@ -26,6 +25,8 @@ ProfileEdit::ProfileEdit(std::string filename, std::string reportedAssets, QWidg
connect(ui->edit_deltatimes, SIGNAL(clicked()), this, SLOT(openDeltaTimes()));
connect(ui->edit_camera, SIGNAL(clicked()), this, SLOT(openCamera()));
connect(ui->edit_marknodes, SIGNAL(clicked()), this, SLOT(openMarkNodes()));
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(approved()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(cancel()));
}
ProfileEdit::~ProfileEdit() {
@@ -33,7 +34,7 @@ ProfileEdit::~ProfileEdit() {
delete _pData;
}
void ProfileEdit::loadProfileFromFile(std::string filename) {
bool ProfileEdit::loadProfileFromFile(std::string filename) {
if (filename.length() > 0) {
std::ifstream inFile;
try {
@@ -41,16 +42,53 @@ void ProfileEdit::loadProfileFromFile(std::string filename) {
}
catch (const std::ifstream::failure& e) {
throw ghoul::RuntimeError(fmt::format(
"Exception opening profile file for read: {} ({})",
filename, e.what())
);
"Exception opening {} profile for read: ({})",
filename,
e.what()
));
}
std::string line;
while (std::getline(inFile, line)) {
_content.push_back(std::move(line));
}
}
_pData = new openspace::Profile(_content);
try {
_pData = new openspace::Profile(_content);
}
catch (const ghoul::MissingCaseException& e) {
displayProfileParseErrorDialogThenQuit(fmt::format(
"Missing case exception in {}: {}",
filename,
e.what()
));
return false;
}
catch (const openspace::Profile::ParsingError& e) {
displayProfileParseErrorDialogThenQuit(fmt::format(
"ParsingError exception in {}: {}, {}",
filename,
e.component,
e.message
));
return false;
}
catch (const ghoul::RuntimeError& e) {
displayProfileParseErrorDialogThenQuit(fmt::format(
"RuntimeError exception in {}, component {}: {}",
filename,
e.component,
e.message
));
return false;
}
return true;
}
void ProfileEdit::displayProfileParseErrorDialogThenQuit(std::string msg) {
//New instance of info dialog window
_myDialog = new errordialog(QString(msg.c_str()));
_myDialog->exec();
cancel();
}
void ProfileEdit::initSummaryTextForEachCategory() {
@@ -85,9 +123,9 @@ void ProfileEdit::initSummaryTextForEachCategory() {
ui->text_additionalscripts->setReadOnly(true);
}
/*void ProfileEdit::setProfileName(QString profileToSet) {
void ProfileEdit::setProfileName(QString profileToSet) {
ui->line_profile->setText(profileToSet);
}*/
}
void ProfileEdit::openMeta() {
if (_pData) {
@@ -343,3 +381,11 @@ QString ProfileEdit::summarizeText_markNodes() {
}
return results;
}
void ProfileEdit::cancel() {
reject();
rejected();
}
void ProfileEdit::approved() {
}

View File

@@ -109,6 +109,18 @@ public:
std::optional<double> altitude;
};
using CameraType = std::variant<CameraNavState, CameraGoToGeo>;
struct ParsingError : public ghoul::RuntimeError {
explicit ParsingError(std::string msg)
: ghoul::RuntimeError(std::move(msg), "profileFile")
{}
ParsingError(unsigned int lineNum, std::string msg)
: ghoul::RuntimeError(
fmt::format("Error @ line {}: {}", lineNum, std::move(msg)),
"profileFile"
)
{}
};
Profile() = default;
Profile(const std::vector<std::string>& content);

View File

@@ -54,19 +54,6 @@ namespace {
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
struct ProfileParsingError : public ghoul::RuntimeError {
explicit ProfileParsingError(std::string msg)
: ghoul::RuntimeError(std::move(msg), "profileFile")
{}
ProfileParsingError(unsigned int lineNum, std::string msg)
: ghoul::RuntimeError(
fmt::format("Error @ line {}: {}", lineNum, std::move(msg)),
"profileFile"
)
{}
};
std::vector<properties::Property*> changedProperties(
const properties::PropertyOwner& po)
{
@@ -111,7 +98,7 @@ namespace {
if (line == headerMarkNodes) { return Section::MarkNodes; }
if (line == headerAdditionalScripts) { return Section::AdditionalScripts; }
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Invalid section header: {}", line)
);
@@ -121,7 +108,7 @@ namespace {
{
std::vector<std::string> parts = ghoul::tokenizeString(line, '.');
if (parts.size() > 2) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected 1-2 version components, got {}", parts.size())
);
@@ -141,7 +128,7 @@ namespace {
return version;
}
catch (const std::invalid_argument&) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
"Error parsing Version. Version number is not a number"
);
@@ -151,7 +138,7 @@ namespace {
[[ nodiscard ]] Profile::Module parseModule(const std::string& line, int lineNumber) {
std::vector<std::string> fields = ghoul::tokenizeString(line, '\t');
if (fields.size() != 3) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected 3 fields in a Module entry, got {}", fields.size())
);
@@ -178,7 +165,7 @@ namespace {
{
std::vector<std::string> fields = ghoul::tokenizeString(line, '\t');
if (fields.size() < 2) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected 2 fields in a Meta line, got {}", fields.size())
);
@@ -210,7 +197,7 @@ namespace {
return { MetaLineType::License, content };
}
else {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Unknown meta line type '{}'", type)
);
@@ -220,7 +207,7 @@ namespace {
[[ nodiscard ]] Profile::Asset parseAsset(const std::string& line, int lineNumber) {
std::vector<std::string> fields = ghoul::tokenizeString(line, '\t');
if (fields.size() != 2) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected 2 fields in an Asset entry, got {}", fields.size())
);
@@ -235,7 +222,7 @@ namespace {
[[ nodiscard ]] Profile::Property parseProperty(const std::string& line, int lineNumber) {
std::vector<std::string> fields = ghoul::tokenizeString(line, '\t');
if (fields.size() != 3) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected 3 fields in Property entry, got {}", fields.size())
);
@@ -248,7 +235,7 @@ namespace {
if (type == "setPropertyValueSingle") {
return Profile::Property::SetType::SetPropertyValueSingle;
}
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format(
"Expected property set type 'setPropertyValue' or "
@@ -265,7 +252,7 @@ namespace {
[[ nodiscard ]] Profile::Keybinding parseKeybinding(const std::string& line, int lineNumber) {
std::vector<std::string> fields = ghoul::tokenizeString(line, '\t');
if (fields.size() != 6) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected 6 fields in Keybinding entry, got {}", fields.size())
);
@@ -275,7 +262,7 @@ namespace {
kb.key = stringToKey(fields[0]);
}
catch (const ghoul::RuntimeError& e) {
throw ProfileParsingError(lineNumber, e.what());
throw Profile::ParsingError(lineNumber, e.what());
}
kb.documentation = fields[1];
kb.name = fields[2];
@@ -287,7 +274,7 @@ namespace {
if (local == "true") {
return true;
}
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected 'false' or 'true' for the local path, got {}", local)
);
@@ -299,7 +286,7 @@ namespace {
[[ nodiscard ]] Profile::Time parseTime(const std::string& line, int lineNumber) {
std::vector<std::string> fields = ghoul::tokenizeString(line, '\t');
if (fields.size() != 2) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected 2 fields in Time entry, got {}", fields.size())
);
@@ -312,7 +299,7 @@ namespace {
if (type == "relative") {
return Profile::Time::Type::Relative;
}
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected 'absolute' or 'relative' for the type, got {}", type)
);
@@ -326,7 +313,7 @@ namespace {
return std::stod(line);
}
catch (const std::invalid_argument&) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format("Expected a number for delta time entry, got '{}'", line)
);
@@ -340,7 +327,7 @@ namespace {
{
if (type == Profile::CameraNavState::Type) {
if (fields.size() != 8) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format(
"Expected 8 fields in the Camera entry, got {}", fields.size()
@@ -355,7 +342,7 @@ namespace {
std::vector<std::string> position = ghoul::tokenizeString(fields[4], ' ');
if (position.size() != 3) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format(
"Expected 3 fields for the camera's position, got {}",
@@ -371,7 +358,7 @@ namespace {
);
}
catch (const std::invalid_argument&) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
"Camera's position components must be numbers"
);
@@ -379,7 +366,7 @@ namespace {
std::vector<std::string> up = ghoul::tokenizeString(fields[5], ' ');
if (up.size() != 0 && up.size() != 3) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format(
"Expected 0 or 3 fields for the camera's up vector, got {}",
@@ -396,7 +383,7 @@ namespace {
);
}
catch (const std::invalid_argument&) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
"Camera's up vector components must be numbers"
);
@@ -408,7 +395,7 @@ namespace {
camera.yaw = std::stod(fields[6]);
}
catch (const std::invalid_argument&) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
"Camera's yaw value must be a number"
);
@@ -420,7 +407,7 @@ namespace {
camera.pitch = std::stod(fields[7]);
}
catch (const std::invalid_argument&) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
"Camera's pitch value must be a number"
);
@@ -430,7 +417,7 @@ namespace {
}
if (type == Profile::CameraGoToGeo::Type) {
if (fields.size() != 5) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format(
"Expected 5 fields in the Camera entry, got {}", fields.size()
@@ -447,7 +434,7 @@ namespace {
}
return camera;
}
throw ProfileParsingError(
throw Profile::ParsingError(
lineNumber,
fmt::format(
"Expected 'setNavigationState' or 'goToGeo' for the type, got {}",
@@ -764,7 +751,7 @@ Profile::Profile(const std::vector<std::string>& content) {
}
if (currentSection != Section::None && line[0] == '#') {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Sections in profile must be separated by empty lines"
);
@@ -775,7 +762,7 @@ Profile::Profile(const std::vector<std::string>& content) {
currentSection = parseSection(line, lineNum);
if (!foundVersion && currentSection != Section::Version) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
fmt::format(
"First header in the file must be Version, but got {}", line
@@ -784,7 +771,7 @@ Profile::Profile(const std::vector<std::string>& content) {
}
if (currentSection == Section::Meta && foundMeta) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Meta section can only appear once per profile"
);
@@ -792,7 +779,7 @@ Profile::Profile(const std::vector<std::string>& content) {
break;
case Section::Version:
if (foundVersion) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Version section can only appear once per profile"
);
@@ -811,7 +798,7 @@ Profile::Profile(const std::vector<std::string>& content) {
switch (m.first) {
case MetaLineType::Name:
if (!_meta->name.empty()) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Meta information 'Name' specified twice"
);
@@ -820,7 +807,7 @@ Profile::Profile(const std::vector<std::string>& content) {
break;
case MetaLineType::Version:
if (!_meta->version.empty()) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Meta information 'Version' specified twice"
);
@@ -829,7 +816,7 @@ Profile::Profile(const std::vector<std::string>& content) {
break;
case MetaLineType::Description:
if (!_meta->description.empty()) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Meta information 'Description' specified twice"
);
@@ -838,7 +825,7 @@ Profile::Profile(const std::vector<std::string>& content) {
break;
case MetaLineType::Author:
if (!_meta->author.empty()) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Meta information 'Author' specified twice"
);
@@ -847,7 +834,7 @@ Profile::Profile(const std::vector<std::string>& content) {
break;
case MetaLineType::URL:
if (!_meta->url.empty()) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Meta information 'URL' specified twice"
);
@@ -856,7 +843,7 @@ Profile::Profile(const std::vector<std::string>& content) {
break;
case MetaLineType::License:
if (!_meta->license.empty()) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Meta information 'License' specified twice"
);
@@ -895,7 +882,7 @@ Profile::Profile(const std::vector<std::string>& content) {
}
case Section::Time:
if (foundTime) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Time section can only appear once per profile"
);
@@ -912,7 +899,7 @@ Profile::Profile(const std::vector<std::string>& content) {
}
case Section::Camera:
if (foundCamera) {
throw ProfileParsingError(
throw Profile::ParsingError(
lineNum,
"Camera section can only appear once per profile"
);