Skip to content

Commit

Permalink
employ custom data models for variables and formulary
Browse files Browse the repository at this point in the history
  • Loading branch information
rabauke committed Jan 14, 2024
1 parent 30dd734 commit 4b9acde
Show file tree
Hide file tree
Showing 19 changed files with 626 additions and 176 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,17 @@ add_executable(harbour-babbage
src/harbour-babbage.cpp
src/FormularyExpression.hpp
src/FormularyExpression.cpp
src/FormularyListModel.hpp
src/FormularyListModel.cpp
src/AppModel.hpp
src/AppModel.cpp
src/special_functions.hpp
src/constants.hpp
src/math_parser.hpp
src/Variable.hpp
src/Variable.cpp
src/VariablesListModel.hpp
src/VariablesListModel.cpp
src/Calculator.hpp
src/Calculator.cpp
)
Expand Down
4 changes: 0 additions & 4 deletions qml/harbour-babbage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ ApplicationWindow {
id: appModel
}

Calculator {
id: calculator
}

Item {
id: viewModel
property string formulaText
Expand Down
109 changes: 57 additions & 52 deletions qml/pages/Expressions.qml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ Page {

PullDownMenu {
RemorsePopup {
id: remorse_variables
id: remorse_expressions
}
MenuItem {
text: qsTr('Clear all expressions')
onClicked: remorse_variables.execute(qsTr('Clearing all expressions'),
calculator.clear())
onClicked: remorse_expressions.execute(qsTr('Clearing all expressions'),
function() {
appModel.formulary.clear()
})
}
}

Expand All @@ -36,77 +38,80 @@ Page {
}
}

model: appModel.expressions
model: appModel.formulary

delegate: ListItem {
id: listItem
width: parent.width
contentWidth: parent.width
contentHeight: expressionText.height + descriptionText.height + Theme.paddingLarge
menu: ContextMenu {
MenuItem {
text: qsTr('Use expression')
onClicked: {
viewModel.formulaText = modelData.expression
var res = calculator.calculate(viewModel.formulaText)
resultsListModel.insert(0, res)
pageStack.navigateBack(PageStackAction.Animated)
}
menu: ContextMenu {
MenuItem {
text: qsTr('Use expression')
onClicked: {
viewModel.formulaText = expression
var res = appModel.calculator.calculate(viewModel.formulaText)
resultsListModel.insert(0, res)
pageStack.navigateBack(PageStackAction.Animated)
}
}
MenuItem {
text: qsTr('Copy expression')
onClicked: {
Clipboard.text = modelData.expression
}
onClicked: {
Clipboard.text = expression
}
}
MenuItem {
text: qsTr('Edit expression')
onClicked: {
var dialog = pageStack.push(Qt.resolvedUrl('EditExpression.qml'),
{'expression': modelData.expression,
'description': modelData.description})
dialog.accepted.connect(function() {
appModel.updateExpression(model.index, calculator.typeset(dialog.expression), dialog.description.trim())
})
onClicked: {
var dialog = pageStack.push(Qt.resolvedUrl('EditExpression.qml'),
{'expression': expression,
'description': description})
dialog.accepted.connect(function() {
appModel.formulary.set(model.index, {
expression: appModel.calculator.typeset(dialog.expression),
description: dialog.description.trim()
})
})
}
}
MenuItem {
text: qsTr('Remove expression')
onClicked: listItem.remorseDelete(function () {
appModel.removeExpression(model.index)
})
onClicked: listItem.remorseDelete(function () {
appModel.formulary.remove(model.index)
})
}
}
Text {
id: expressionText
x: Theme.horizontalPageMargin
y: Theme.paddingMedium
width: parent.width - 2 * Theme.horizontalPageMargin
color: Theme.primaryColor
wrapMode: TextEdit.Wrap
font.pixelSize: Theme.fontSizeMedium
horizontalAlignment: TextEdit.AlignLeft
text: modelData.expression
}
Text {
id: descriptionText
x: Theme.horizontalPageMargin
anchors.top: expressionText.bottom
width: parent.width - 2 * Theme.horizontalPageMargin
height: visible ? implicitHeight : 0
color: Theme.secondaryColor
wrapMode: TextEdit.Wrap
font.pixelSize: Theme.fontSizeSmall
horizontalAlignment: TextEdit.AlignLeft
text: modelData.description
visible: text !== ''
}
id: expressionText
x: Theme.horizontalPageMargin
y: Theme.paddingMedium
width: parent.width - 2 * Theme.horizontalPageMargin
color: Theme.primaryColor
wrapMode: TextEdit.Wrap
font.pixelSize: Theme.fontSizeMedium
horizontalAlignment: TextEdit.AlignLeft
text: expression
}
Text {
id: descriptionText
x: Theme.horizontalPageMargin
anchors.top: expressionText.bottom
width: parent.width - 2 * Theme.horizontalPageMargin
height: visible ? implicitHeight : 0
color: Theme.secondaryColor
wrapMode: TextEdit.Wrap
font.pixelSize: Theme.fontSizeSmall
horizontalAlignment: TextEdit.AlignLeft
text: description
visible: text !== ''
}
}
}

onStatusChanged: {
if (status === PageStatus.Active) {
pageStack.pushAttached(Qt.resolvedUrl('Variables.qml'))
}
if (status === PageStatus.Active) {
pageStack.pushAttached(Qt.resolvedUrl('Variables.qml'))
}
}
}
4 changes: 2 additions & 2 deletions qml/pages/MainPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Page {
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhPreferNumbers
EnterKey.enabled: text.length > 0
EnterKey.onClicked: {
var res = calculator.calculate(formula.text)
var res = appModel.calculator.calculate(formula.text)
resultsListModel.insert(0, res)
formula.text = res.variable !== '' ? res.variable + ' = ' + res.formula : res.formula
}
Expand Down Expand Up @@ -95,7 +95,7 @@ Page {
}
MenuItem {
text: qsTr('Add formula to formulary')
onClicked: appModel.addExpression(resultsListModel.get(model.index).formula)
onClicked: appModel.formulary.add({expression: resultsListModel.get(model.index).formula, description: ''})
}
MenuItem {
text: qsTr('Clear output')
Expand Down
14 changes: 7 additions & 7 deletions qml/pages/SimpleCalculator.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ Page {
function enter(str) {
if (str !== '') {
result = ''
formula.text = calculator.typeset(formula.text + str)
formula.text = appModel.calculator.typeset(formula.text + str)
}
}

function evaluate() {
if (formula.text !== '') {
var res = calculator.calculate(formula.text)
var res = appModel.calculator.calculate(formula.text)
resultsListModel.insert(0, res)
result = res.result
}
Expand Down Expand Up @@ -173,11 +173,11 @@ Page {
if (result !== '' && result !== 'nan') {
var res
if (memory !== '') {
res = calculator.calculate(
res = appModel.calculator.calculate(
'( ' + memory + ' ) - ( ' + result + ' )')
memory = res.result
} else {
res = calculator.calculate('- ( ' + result + ' )')
res = appModel.calculator.calculate('- ( ' + result + ' )')
memory = res.result
}
}
Expand All @@ -191,11 +191,11 @@ Page {
if (result !== '' && result !== 'nan') {
var res
if (memory !== '') {
res = calculator.calculate(
res = appModel.calculator.calculate(
'( ' + memory + ' ) + ( ' + result + ' )')
memory = res.result
} else {
res = calculator.calculate('( ' + result + ' )')
res = appModel.calculator.calculate('( ' + result + ' )')
memory = res.result
}
}
Expand Down Expand Up @@ -243,7 +243,7 @@ Page {
text = text.slice(0, -1)
}
}
formula.text = calculator.typeset(text)
formula.text = appModel.calculator.typeset(text)
result = ''
}
}
Expand Down
18 changes: 10 additions & 8 deletions qml/pages/Variables.qml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ Page {
MenuItem {
text: qsTr('Clear all variables')
onClicked: remorse_variables.execute(qsTr('Clearing all variables'),
calculator.clear())
function() {
appModel.calculator.variables.clear()
})
}
}

Expand All @@ -36,7 +38,7 @@ Page {
}
}

model: calculator.variables
model: appModel.calculator.variables

delegate: ListItem {
id: listItem
Expand All @@ -46,22 +48,22 @@ Page {
menu: ContextMenu {
MenuItem {
text: qsTr('Copy value')
onClicked: Clipboard.text = modelData.value
onClicked: Clipboard.text = appModel.calculator.typeset(value)
}
MenuItem {
text: qsTr('Copy variable name')
onClicked: Clipboard.text = modelData.variable
onClicked: Clipboard.text = appModel.calculator.typeset(name)
}
MenuItem {
text: qsTr('Copy variable')
onClicked: Clipboard.text = modelData.variable + ' = ' + modelData.value
onClicked: Clipboard.text = appModel.calculator.typeset(name + ' = ' + value)
}
MenuItem {
text: qsTr('Clear variable')
onClicked: listItem.remorseDelete(function () {
calculator.removeVariable(model.index)
appModel.calculator.variables.remove(model.index)
})
visible: !modelData.protected
visible: !is_protected
}
}
Text {
Expand All @@ -73,7 +75,7 @@ Page {
wrapMode: TextEdit.Wrap
font.pixelSize: Theme.fontSizeMedium
horizontalAlignment: TextEdit.AlignLeft
text: modelData.variable + ' = ' + modelData.value
text: appModel.calculator.typeset(name + '=' + value)
}
}
}
Expand Down
49 changes: 12 additions & 37 deletions src/AppModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ AppModel::AppModel(QObject* parent) : QObject{parent} {
QSequentialIterable iterable{expressions_variant.value<QSequentialIterable>()};
for (const QVariant& v : iterable) {
if (v.canConvert<FormularyExpression>())
m_expressions.append(v);
m_formulary.add(v.value<FormularyExpression>());
}
}
}
Expand All @@ -60,47 +60,22 @@ AppModel::~AppModel() {
if (calculator_type_str != nullptr)
settings.setValue("calculator_type", calculator_type_str);

settings.setValue("expressions", m_expressions);
settings.sync();
}


void AppModel::addExpression(const QString& expression) {
FormularyExpression formularyExpression;
formularyExpression.expression = expression;
formularyExpression.description = "";
QVariant var;
var.setValue(formularyExpression);
m_expressions.append(var);
emit expressionsChanged();
}


void AppModel::removeExpression(qint32 index) {
if (0 <= index && index < m_expressions.size()) {
m_expressions.removeAt(index);
emit expressionsChanged();
QVariantList expressions;
for (const auto& expression : m_formulary) {
QVariant expression_variant;
expression_variant.setValue(expression);
expressions.append(expression_variant);
}
settings.setValue("expressions", expressions);
settings.sync();
}


void AppModel::updateExpression(qint32 index, const QString& expression,
const QString& description) {
if (0 <= index && index < m_expressions.size()) {
FormularyExpression formularyExpression;
formularyExpression.expression = expression;
formularyExpression.description = description;
m_expressions[index].setValue(formularyExpression);
emit expressionsChanged();
}
}

void AppModel::clearExpressions() {
m_expressions.clear();
emit expressionsChanged();
Calculator* AppModel::getCalculator() {
return &m_calculator;
}


QVariantList AppModel::getExpressions() const {
return m_expressions;
FormularyListModel* AppModel::getFormulary() {
return &m_formulary;
}
Loading

0 comments on commit 4b9acde

Please sign in to comment.