From 5dcfbf83e9cef718da4a7460b6c9a87c48898907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 17 May 2018 11:31:28 +0200 Subject: [PATCH] [escher] ExpressionLayoutFieldDelegate should not take a text as parameter but a layout Warning: in ExpressionField: the serialized layout is not guaranteed to be small enough to fill in the text buffer --- .../edit_expression_controller.cpp | 24 +++++++++++-------- apps/calculation/edit_expression_controller.h | 5 ++-- .../expression_layout_field_delegate.cpp | 4 ++-- .../shared/expression_layout_field_delegate.h | 2 +- escher/include/escher/expression_field.h | 5 ++++ .../escher/expression_layout_field_delegate.h | 2 +- escher/include/escher/input_view_controller.h | 3 ++- escher/src/expression_layout_field.cpp | 5 +--- escher/src/input_view_controller.cpp | 2 +- 9 files changed, 29 insertions(+), 23 deletions(-) diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 5356e98b8..8628ef192 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -6,6 +6,7 @@ #include using namespace Shared; +using namespace Poincare; namespace Calculation { @@ -53,10 +54,6 @@ EditExpressionController::EditExpressionController(Responder * parentResponder, m_cacheBuffer[0] = 0; } -const char * EditExpressionController::textBody() { - return ((ContentView *)view())->expressionField()->text(); -} - void EditExpressionController::insertTextBody(const char * text) { ((ContentView *)view())->expressionField()->handleEventWithText(text, false, true); } @@ -88,7 +85,7 @@ bool EditExpressionController::textFieldDidReceiveEvent(::TextField * textField, } bool EditExpressionController::textFieldDidFinishEditing(::TextField * textField, const char * text, Ion::Events::Event event) { - return inputViewDidFinishEditing(text, event); + return inputViewDidFinishEditing(text, nullptr); } bool EditExpressionController::textFieldDidAbortEditing(::TextField * textField) { @@ -102,8 +99,8 @@ bool EditExpressionController::expressionLayoutFieldDidReceiveEvent(::Expression return expressionFieldDelegateApp()->expressionLayoutFieldDidReceiveEvent(expressionLayoutField, event); } -bool EditExpressionController::expressionLayoutFieldDidFinishEditing(::ExpressionLayoutField * expressionLayoutField, const char * text, Ion::Events::Event event) { - return inputViewDidFinishEditing(text, event); +bool EditExpressionController::expressionLayoutFieldDidFinishEditing(::ExpressionLayoutField * expressionLayoutField, ExpressionLayout * layout, Ion::Events::Event event) { + return inputViewDidFinishEditing(nullptr, layout); } bool EditExpressionController::expressionLayoutFieldDidAbortEditing(::ExpressionLayoutField * expressionLayoutField) { @@ -159,10 +156,17 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event return true; } -bool EditExpressionController::inputViewDidFinishEditing(const char * text, Ion::Events::Event event) { + +bool EditExpressionController::inputViewDidFinishEditing(const char * text, ExpressionLayout * layout) { App * calculationApp = (App *)app(); - strlcpy(m_cacheBuffer, textBody(), Calculation::k_printedExpressionSize); - m_calculationStore->push(textBody(), calculationApp->localContext()); + if (layout == nullptr) { + assert(text); + strlcpy(m_cacheBuffer, text, Calculation::k_printedExpressionSize); + } else { + assert(layout); + layout->writeTextInBuffer(m_cacheBuffer, Calculation::k_printedExpressionSize); + } + m_calculationStore->push(m_cacheBuffer, calculationApp->localContext()); m_historyController->reload(); ((ContentView *)view())->mainView()->scrollToCell(0, m_historyController->numberOfRows()-1); ((ContentView *)view())->expressionField()->setEditing(true); diff --git a/apps/calculation/edit_expression_controller.h b/apps/calculation/edit_expression_controller.h index b9867eea9..f9fef4487 100644 --- a/apps/calculation/edit_expression_controller.h +++ b/apps/calculation/edit_expression_controller.h @@ -19,7 +19,6 @@ public: void didBecomeFirstResponder() override; void viewDidDisappear() override; bool handleEvent(Ion::Events::Event event) override; - const char * textBody(); void insertTextBody(const char * text); /* TextFieldDelegate */ @@ -29,7 +28,7 @@ public: /* ExpressionLayoutFieldDelegate */ bool expressionLayoutFieldDidReceiveEvent(::ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override; - bool expressionLayoutFieldDidFinishEditing(::ExpressionLayoutField * expressionLayoutField, const char * text, Ion::Events::Event event) override; + bool expressionLayoutFieldDidFinishEditing(::ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) override; bool expressionLayoutFieldDidAbortEditing(::ExpressionLayoutField * expressionLayoutField) override; void expressionLayoutFieldDidChangeSize(::ExpressionLayoutField * expressionLayoutField) override; @@ -60,7 +59,7 @@ private: void unloadView(View * view) override; void reloadView(); bool inputViewDidReceiveEvent(Ion::Events::Event event); - bool inputViewDidFinishEditing(const char * text, Ion::Events::Event event); + bool inputViewDidFinishEditing(const char * text, Poincare::ExpressionLayout * layout); bool inputViewDidAbortEditing(const char * text); Shared::TextFieldDelegateApp * textFieldDelegateApp() override; Shared::ExpressionFieldDelegateApp * expressionFieldDelegateApp() override; diff --git a/apps/shared/expression_layout_field_delegate.cpp b/apps/shared/expression_layout_field_delegate.cpp index a6cc06de8..31099bd12 100644 --- a/apps/shared/expression_layout_field_delegate.cpp +++ b/apps/shared/expression_layout_field_delegate.cpp @@ -12,8 +12,8 @@ bool ExpressionLayoutFieldDelegate::expressionLayoutFieldDidReceiveEvent(Express return expressionFieldDelegateApp()->expressionLayoutFieldDidReceiveEvent(expressionLayoutField, event); } -bool ExpressionLayoutFieldDelegate::expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, const char * text, Ion::Events::Event event) { - return expressionFieldDelegateApp()->expressionLayoutFieldDidFinishEditing(expressionLayoutField, text, event); +bool ExpressionLayoutFieldDelegate::expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, ExpressionLayout * layout, Ion::Events::Event event) { + return expressionFieldDelegateApp()->expressionLayoutFieldDidFinishEditing(expressionLayoutField, layout, event); } bool ExpressionLayoutFieldDelegate::expressionLayoutFieldDidAbortEditing(ExpressionLayoutField * expressionLayoutField) { diff --git a/apps/shared/expression_layout_field_delegate.h b/apps/shared/expression_layout_field_delegate.h index 5d9ff3c04..f933593ef 100644 --- a/apps/shared/expression_layout_field_delegate.h +++ b/apps/shared/expression_layout_field_delegate.h @@ -10,7 +10,7 @@ class ExpressionLayoutFieldDelegate : public ::ExpressionLayoutFieldDelegate { public: bool expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override; bool expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override; - bool expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, const char * text, Ion::Events::Event event) override; + bool expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) override; bool expressionLayoutFieldDidAbortEditing(ExpressionLayoutField * expressionLayoutField) override; void expressionLayoutFieldDidChangeSize(ExpressionLayoutField * expressionLayoutField) override; Toolbox * toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) override; diff --git a/escher/include/escher/expression_field.h b/escher/include/escher/expression_field.h index acbebfed5..4638bb682 100644 --- a/escher/include/escher/expression_field.h +++ b/escher/include/escher/expression_field.h @@ -13,6 +13,11 @@ public: void setEditing(bool isEditing, bool reinitDraftBuffer = true); bool isEditing() const; + /* Warning: this function is VERY dangerous! Indeed: sometimes the + * m_expressionLayoutField might overflow the m_textBuffer once serialized + * and still have been accepted before because the model can hold a longer + * buffer. This is the case in the application 'Calculation' and we do not + * use text() there... TODO: change text() for fillTextInBuffer?*/ const char * text(); void setText(const char * text); void reload(); diff --git a/escher/include/escher/expression_layout_field_delegate.h b/escher/include/escher/expression_layout_field_delegate.h index 80d284f85..90d68f033 100644 --- a/escher/include/escher/expression_layout_field_delegate.h +++ b/escher/include/escher/expression_layout_field_delegate.h @@ -10,7 +10,7 @@ class ExpressionLayoutFieldDelegate { public: virtual bool expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) = 0; virtual bool expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) = 0; - virtual bool expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, const char * text, Ion::Events::Event event) { return false; } + virtual bool expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) { return false; } virtual bool expressionLayoutFieldDidAbortEditing(ExpressionLayoutField * expressionLayoutField) { return false; } virtual void expressionLayoutFieldDidChangeSize(ExpressionLayoutField * expressionLayoutField) {} virtual Toolbox * toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) = 0; diff --git a/escher/include/escher/input_view_controller.h b/escher/include/escher/input_view_controller.h index 59c9a7366..395c59bab 100644 --- a/escher/include/escher/input_view_controller.h +++ b/escher/include/escher/input_view_controller.h @@ -7,6 +7,7 @@ #include #include #include +#include /* TODO Implement a split view. Because we use a modal view, the main view is * redrawn underneath the modal view, which is visible and ugly. */ @@ -28,7 +29,7 @@ public: /* ExpressionLayoutFieldDelegate */ bool expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override; bool expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override; - bool expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, const char * text, Ion::Events::Event event) override; + bool expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) override; bool expressionLayoutFieldDidAbortEditing(ExpressionLayoutField * expressionLayoutField) override; void expressionLayoutFieldDidChangeSize(ExpressionLayoutField * expressionLayoutField) override; Toolbox * toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) override; diff --git a/escher/src/expression_layout_field.cpp b/escher/src/expression_layout_field.cpp index 1783f8f24..2f2d1d997 100644 --- a/escher/src/expression_layout_field.cpp +++ b/escher/src/expression_layout_field.cpp @@ -120,10 +120,7 @@ bool ExpressionLayoutField::privateHandleEvent(Ion::Events::Event event) { } if (isEditing() && expressionLayoutFieldShouldFinishEditing(event)) { setEditing(false); - int bufferSize = TextField::maxBufferSize(); - char buffer[bufferSize]; - m_contentView.expressionView()->expressionLayout()->writeTextInBuffer(buffer, bufferSize); - if (m_delegate->expressionLayoutFieldDidFinishEditing(this, buffer, event)) { + if (m_delegate->expressionLayoutFieldDidFinishEditing(this, m_contentView.expressionView()->expressionLayout(), event)) { clearLayout(); } return true; diff --git a/escher/src/input_view_controller.cpp b/escher/src/input_view_controller.cpp index c7bec3a3e..6b868626e 100644 --- a/escher/src/input_view_controller.cpp +++ b/escher/src/input_view_controller.cpp @@ -78,7 +78,7 @@ bool InputViewController::expressionLayoutFieldDidReceiveEvent(ExpressionLayoutF return m_expressionLayoutFieldDelegate->expressionLayoutFieldDidReceiveEvent(expressionLayoutField, event); } -bool InputViewController::expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, const char * text, Ion::Events::Event event) { +bool InputViewController::expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) { return inputViewDidFinishEditing(); }