diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 2cb9b9ab8..c62e8b50c 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -24,6 +24,13 @@ HistoryController::HistoryController(EditExpressionController * editExpressionCo } void HistoryController::reload() { + /* When reloading, we might not used anymore cell that hold previous layouts. + * We clean them all before reloading their content to avoid taking extra + * useless space in the Poincare pool. */ + for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) { + m_calculationHistory[i].resetMemoization(); + } + m_selectableTableView.reloadData(); /* TODO * Replace the following by selectCellAtLocation in order to avoid laying out diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index 0007c0bac..90908a6af 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -200,6 +200,14 @@ bool HistoryViewCell::oneLine() { return outputSize.width() + inputSize.width() < bounds().width() - 6; } +void HistoryViewCell::resetMemoization() { + // Clean the layouts to make room in the pool + // TODO: maybe do this only when the layout won't change to avoid blinking + m_inputView.setLayout(Poincare::Layout()); + m_scrollableOutputView.setLayouts(Poincare::Layout(), Poincare::Layout(), Poincare::Layout()); + m_calculationCRC32 = 0; +} + void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) { uint32_t newCalculationCRC = Ion::crc32Byte((const uint8_t *)calculation, ((char *)calculation->next()) - ((char *) calculation)); if (newCalculationCRC == m_calculationCRC32 && m_calculationExpanded == expanded) { @@ -207,10 +215,8 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) { } Poincare::Context * context = App::app()->localContext(); - // Clean the layouts to make room in the pool // TODO: maybe do this only when the layout won't change to avoid blinking - m_inputView.setLayout(Poincare::Layout()); - m_scrollableOutputView.setLayouts(Poincare::Layout(), Poincare::Layout(), Poincare::Layout()); + resetMemoization(); // Memoization m_calculationCRC32 = newCalculationCRC; diff --git a/apps/calculation/history_view_cell.h b/apps/calculation/history_view_cell.h index b831e49ed..aa525f3e1 100644 --- a/apps/calculation/history_view_cell.h +++ b/apps/calculation/history_view_cell.h @@ -42,6 +42,7 @@ public: } Poincare::Layout layout() const override; KDColor backgroundColor() const override; + void resetMemoization(); void setCalculation(Calculation * calculation, bool expanded); int numberOfSubviews() const override; View * subviewAtIndex(int index) override; diff --git a/apps/code/python_toolbox.cpp b/apps/code/python_toolbox.cpp index 7ca525419..792abf106 100644 --- a/apps/code/python_toolbox.cpp +++ b/apps/code/python_toolbox.cpp @@ -251,7 +251,6 @@ const ToolboxMessageTree catalogChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAbs, I18n::Message::PythonAbs), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAcos, I18n::Message::PythonAcos), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAcosh, I18n::Message::PythonAcosh), - ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAppend, I18n::Message::PythonAppend, false, I18n::Message::PythonCommandAppendWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAsin, I18n::Message::PythonAsin), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAsinh, I18n::Message::PythonAsinh), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAtan, I18n::Message::PythonAtan), @@ -265,14 +264,12 @@ const ToolboxMessageTree catalogChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCeil, I18n::Message::PythonCeil), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandChoice, I18n::Message::PythonChoice), ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandCircle, I18n::Message::PythonTurtleCircle), - ToolboxMessageTree::Leaf(I18n::Message::PythonCommandClear, I18n::Message::PythonClear, false, I18n::Message::PythonCommandClearWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCmathFunction, I18n::Message::PythonCmathFunction, false, I18n::Message::PythonCommandCmathFunctionWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColor, I18n::Message::PythonColor), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandComplex, I18n::Message::PythonComplex), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCopySign, I18n::Message::PythonCopySign), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCos, I18n::Message::PythonCos), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCosh, I18n::Message::PythonCosh), - ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCount, I18n::Message::PythonCount, false, I18n::Message::PythonCommandCountWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDegrees, I18n::Message::PythonDegrees), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDivMod, I18n::Message::PythonDivMod), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawString, I18n::Message::PythonDrawString), @@ -312,9 +309,7 @@ const ToolboxMessageTree catalogChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportRandom, I18n::Message::PythonImportRandom, false), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportTurtle, I18n::Message::PythonImportTurtle, false), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportTime, I18n::Message::PythonImportTime, false), - ToolboxMessageTree::Leaf(I18n::Message::PythonCommandIndex, I18n::Message::PythonIndex, false, I18n::Message::PythonCommandIndexWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandInput, I18n::Message::PythonInput), - ToolboxMessageTree::Leaf(I18n::Message::PythonCommandInsert, I18n::Message::PythonInsert, false, I18n::Message::PythonCommandInsertWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandInt, I18n::Message::PythonInt), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandIonFunction, I18n::Message::PythonIonFunction, false, I18n::Message::PythonCommandIonFunctionWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandIsdown, I18n::Message::PythonTurtleIsdown, false), @@ -327,6 +322,15 @@ const ToolboxMessageTree catalogChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandLeft, I18n::Message::PythonTurtleLeft), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandLength, I18n::Message::PythonLength), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandLgamma, I18n::Message::PythonLgamma), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAppend, I18n::Message::PythonAppend, false, I18n::Message::PythonCommandAppendWithoutArg), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandClear, I18n::Message::PythonClear, false, I18n::Message::PythonCommandClearWithoutArg), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCount, I18n::Message::PythonCount, false, I18n::Message::PythonCommandCountWithoutArg), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandIndex, I18n::Message::PythonIndex, false, I18n::Message::PythonCommandIndexWithoutArg), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandInsert, I18n::Message::PythonInsert, false, I18n::Message::PythonCommandInsertWithoutArg), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPop, I18n::Message::PythonPop, false, I18n::Message::PythonCommandPopWithoutArg), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRemove, I18n::Message::PythonRemove, false, I18n::Message::PythonCommandRemoveWithoutArg), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandReverse, I18n::Message::PythonReverse, false, I18n::Message::PythonCommandReverseWithoutArg), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSort, I18n::Message::PythonSort, false, I18n::Message::PythonCommandSortWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandLog, I18n::Message::PythonLog), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandLog10, I18n::Message::PythonLog10), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandLog2, I18n::Message::PythonLog2), @@ -344,7 +348,6 @@ const ToolboxMessageTree catalogChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PythonCommandConstantPi, I18n::Message::PythonConstantPi, false), ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPink, I18n::Message::PythonTurtlePink, false), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPolar, I18n::Message::PythonPolar), - ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPop, I18n::Message::PythonPop, false, I18n::Message::PythonCommandPopWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPosition, I18n::Message::PythonTurtlePosition, false), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPower, I18n::Message::PythonPower), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPrint, I18n::Message::PythonPrint), @@ -358,9 +361,7 @@ const ToolboxMessageTree catalogChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRangeStop, I18n::Message::PythonRangeStop), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRect, I18n::Message::PythonRect), ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandRed, I18n::Message::PythonTurtleRed, false), - ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRemove, I18n::Message::PythonRemove, false, I18n::Message::PythonCommandRemoveWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandReset, I18n::Message::PythonTurtleReset, false), - ToolboxMessageTree::Leaf(I18n::Message::PythonCommandReverse, I18n::Message::PythonReverse, false, I18n::Message::PythonCommandReverseWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandRight, I18n::Message::PythonTurtleRight), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRound, I18n::Message::PythonRound), ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandSetheading, I18n::Message::PythonTurtleSetheading), @@ -370,7 +371,6 @@ const ToolboxMessageTree catalogChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSin, I18n::Message::PythonSin), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSinh, I18n::Message::PythonSinh), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSleep, I18n::Message::PythonSleep), - ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSort, I18n::Message::PythonSort, false, I18n::Message::PythonCommandSortWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSorted, I18n::Message::PythonSort), ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandSpeed, I18n::Message::PythonTurtleSpeed), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSqrt, I18n::Message::PythonSqrt), diff --git a/apps/settings/base.de.i18n b/apps/settings/base.de.i18n index 6f377cd0a..7be14ce0e 100644 --- a/apps/settings/base.de.i18n +++ b/apps/settings/base.de.i18n @@ -7,9 +7,7 @@ EditionLinear = "Linear " Edition2D = "Natürlich " ComplexFormat = "Komplex" ExamMode = "Testmodus" -ActivateExamMode = "Starten Testmodus" ExamModeActive = "Wieder starten Testmodus" -ActivateDutchExamMode = "Activate Dutch exam mode" ToDeactivateExamMode1 = "Um den Testmodus auszuschalten," ToDeactivateExamMode2 = "schließen Sie den Rechner an einen" ToDeactivateExamMode3 = "Computer oder eine Steckdose an." diff --git a/apps/settings/base.en.i18n b/apps/settings/base.en.i18n index 68661574d..9fb8c3617 100644 --- a/apps/settings/base.en.i18n +++ b/apps/settings/base.en.i18n @@ -7,9 +7,7 @@ EditionLinear = "Linear " Edition2D = "Natural " ComplexFormat = "Complex format" ExamMode = "Exam mode" -ActivateExamMode = "Activate exam mode" ExamModeActive = "Reactivate exam mode" -ActivateDutchExamMode = "Activate Dutch exam mode" ToDeactivateExamMode1 = "To deactivate the exam mode," ToDeactivateExamMode2 = "plug the calculator to a computer" ToDeactivateExamMode3 = "or to a power socket." diff --git a/apps/settings/base.es.i18n b/apps/settings/base.es.i18n index f9701b2e3..b476d7378 100644 --- a/apps/settings/base.es.i18n +++ b/apps/settings/base.es.i18n @@ -7,9 +7,7 @@ EditionLinear = "En línea " Edition2D = "Natural " ComplexFormat = "Forma compleja" ExamMode = "Modo examen" -ActivateExamMode = "Activar el modo examen" ExamModeActive = "Reactivar el modo examen" -ActivateDutchExamMode = "Activate Dutch exam mode" ToDeactivateExamMode1 = "Para desactivar el modo examen," ToDeactivateExamMode2 = "conecte la calculadora a un ordenador" ToDeactivateExamMode3 = "o a un enchufe eléctrico." diff --git a/apps/settings/base.fr.i18n b/apps/settings/base.fr.i18n index b051ae002..4e413d057 100644 --- a/apps/settings/base.fr.i18n +++ b/apps/settings/base.fr.i18n @@ -7,9 +7,7 @@ EditionLinear = "En ligne " Edition2D = "Naturelle " ComplexFormat = "Forme complexe" ExamMode = "Mode examen" -ActivateExamMode = "Activer le mode examen" ExamModeActive = "Réactiver le mode examen" -ActivateDutchExamMode = "Activate Dutch exam mode" ToDeactivateExamMode1 = "Pour désactiver le mode examen," ToDeactivateExamMode2 = "brancher la calculatrice à un" ToDeactivateExamMode3 = "ordinateur ou à une prise de courant." diff --git a/apps/settings/base.hu.i18n b/apps/settings/base.hu.i18n index f40aeef47..6361dbec8 100644 --- a/apps/settings/base.hu.i18n +++ b/apps/settings/base.hu.i18n @@ -7,9 +7,7 @@ EditionLinear = "Lineáris" Edition2D = "Természetes" ComplexFormat = "Komplex formátum" ExamMode = "Vizsga mód" -ActivateExamMode = "A vizsgálati mód aktiválása" ExamModeActive = "A vizsgamód újraaktiválása" -ActivateDutchExamMode = "A holland vizsga mód aktiválása" ToDeactivateExamMode1 = "a vizsga mód kikapcsoláshoz" ToDeactivateExamMode2 = "csatlakoztassa a számológépet a számítógéphez" ToDeactivateExamMode3 = "vagy egy konnektorhoz." diff --git a/apps/settings/base.pt.i18n b/apps/settings/base.pt.i18n index 6371abd2c..0e5218695 100644 --- a/apps/settings/base.pt.i18n +++ b/apps/settings/base.pt.i18n @@ -7,9 +7,7 @@ EditionLinear = "Em linha " Edition2D = "Natural " ComplexFormat = "Complexos" ExamMode = "Modo de exame" -ActivateExamMode = "Activar o modo de exame" ExamModeActive = "Reactivar o modo de exame" -ActivateDutchExamMode = "Activate Dutch exam mode" ToDeactivateExamMode1 = "Para desactivar o modo de exame," ToDeactivateExamMode2 = "ligue a calculadora a um computador" ToDeactivateExamMode3 = "ou a uma tomada eléctrica." diff --git a/apps/shared.de.i18n b/apps/shared.de.i18n index a7fcd3641..12a529e80 100644 --- a/apps/shared.de.i18n +++ b/apps/shared.de.i18n @@ -1,4 +1,6 @@ ActivateDeactivate = "Aktivieren/Deaktivieren" +ActivateDutchExamMode = "Activate Dutch exam mode" +ActivateExamMode = "Starten Testmodus" ActiveExamModeMessage1 = "Alle Ihre Daten werden " ActiveExamModeMessage2 = "gelöscht, wenn Sie den " ActiveExamModeMessage3 = "Testmodus einschalten." diff --git a/apps/shared.en.i18n b/apps/shared.en.i18n index 4dbe4348e..5e62daa44 100644 --- a/apps/shared.en.i18n +++ b/apps/shared.en.i18n @@ -1,4 +1,6 @@ ActivateDeactivate = "Turn on/off" +ActivateExamMode = "Activate exam mode" +ActivateDutchExamMode = "Activate Dutch exam mode" ActiveExamModeMessage1 = "All your data will be " ActiveExamModeMessage2 = "deleted when you activate " ActiveExamModeMessage3 = "the exam mode." diff --git a/apps/shared.es.i18n b/apps/shared.es.i18n index a693d73e6..ff7a855bd 100644 --- a/apps/shared.es.i18n +++ b/apps/shared.es.i18n @@ -1,4 +1,6 @@ ActivateDeactivate = "Activar/Desactivar" +ActivateExamMode = "Activar el modo examen" +ActivateDutchExamMode = "Activate Dutch exam mode" ActiveExamModeMessage1 = "Todos sus datos se " ActiveExamModeMessage2 = "eliminaran al activar " ActiveExamModeMessage3 = "el modo examen." diff --git a/apps/shared.fr.i18n b/apps/shared.fr.i18n index 328c08283..821b9c26c 100644 --- a/apps/shared.fr.i18n +++ b/apps/shared.fr.i18n @@ -1,4 +1,6 @@ ActivateDeactivate = "Activer/Désactiver" +ActivateExamMode = "Activer le mode examen" +ActivateDutchExamMode = "Activate Dutch exam mode" ActiveExamModeMessage1 = "Toutes vos données seront " ActiveExamModeMessage2 = "supprimées si vous activez " ActiveExamModeMessage3 = "le mode examen." diff --git a/apps/shared.hu.i18n b/apps/shared.hu.i18n index 60a125e0e..b44acba08 100644 --- a/apps/shared.hu.i18n +++ b/apps/shared.hu.i18n @@ -1,4 +1,6 @@ ActivateDeactivate = "Ki/Be kapcsolás" +ActivateExamMode = "A vizsgálati mód aktiválása" +ActivateDutchExamMode = "A holland vizsga mód aktiválása" ActiveExamModeMessage1 = "Az összes adatod" ActiveExamModeMessage2 = "törölve lesz ha" ActiveExamModeMessage3 = "aktiválod a vizsga módot." diff --git a/apps/shared.pt.i18n b/apps/shared.pt.i18n index 8c61d7103..2dc5f6e5f 100644 --- a/apps/shared.pt.i18n +++ b/apps/shared.pt.i18n @@ -1,4 +1,6 @@ ActivateDeactivate = "Activar/Desactivar" +ActivateExamMode = "Activar o modo de exame" +ActivateDutchExamMode = "Activate Dutch exam mode" ActiveExamModeMessage1 = "Todos os seus dados serão " ActiveExamModeMessage2 = "apagados se você ligar " ActiveExamModeMessage3 = "o modo de exame." diff --git a/apps/shared/expression_model.cpp b/apps/shared/expression_model.cpp index 530f7b200..c67d399b7 100644 --- a/apps/shared/expression_model.cpp +++ b/apps/shared/expression_model.cpp @@ -24,13 +24,19 @@ ExpressionModel::ExpressionModel() : void ExpressionModel::text(const Storage::Record * record, char * buffer, size_t bufferSize, CodePoint symbol) const { Expression e = expressionClone(record); - if (e.isUninitialized() && bufferSize > 0) { - buffer[0] = 0; - } else { - if (symbol != 0 && !e.isUninitialized()) { - e = e.replaceSymbolWithExpression(Symbol::Builder(UCodePointUnknown), Symbol::Builder(symbol)); + if (e.isUninitialized()) { + if (bufferSize > 0) { + buffer[0] = 0; } - e.serialize(buffer, bufferSize); + return; + } + if (symbol != 0) { + e = e.replaceSymbolWithExpression(Symbol::Builder(UCodePointUnknown), Symbol::Builder(symbol)); + } + int serializedSize = e.serialize(buffer, bufferSize); + if (serializedSize >= bufferSize - 1) { + // It is very likely that the buffer is overflowed + buffer[0] = 0; } } diff --git a/build/targets.device.n0110.mak b/build/targets.device.n0110.mak index 3abc930e4..8f56063df 100644 --- a/build/targets.device.n0110.mak +++ b/build/targets.device.n0110.mak @@ -19,3 +19,31 @@ $(BUILD_DIR)/test.external_flash.write.$(EXE): $(BUILD_DIR)/quiz/src/test_ion_ex sleep 2; \ fi $(Q) $(PYTHON) build/device/dfu.py -u $(word 1,$^) + +.PHONY: %.two_binaries +%.two_binaries: %.elf + @echo "Building an internal and an external binary for $<" + $(Q) $(OBJCOPY) -O binary -j .text.external -j .rodata.external -j .exam_mode_buffer $(BUILD_DIR)/$< $(BUILD_DIR)/$(basename $<).external.bin + $(Q) $(OBJCOPY) -O binary -R .text.external -R .rodata.external -R .exam_mode_buffer $(BUILD_DIR)/$< $(BUILD_DIR)/$(basename $<).internal.bin + @echo "Padding $(basename $<).external.bin and $(basename $<).internal.bin" + $(Q) printf "\xFF\xFF\xFF\xFF" >> $(basename $<).external.bin + $(Q) printf "\xFF\xFF\xFF\xFF" >> $(basename $<).internal.bin + +.PHONY: binpack +binpack: + rm -rf build/binpack + mkdir -p build/binpack + ${MAKE} clean + ${MAKE} $(BUILD_DIR)/flasher.light.bin + cp $(BUILD_DIR)/flasher.light.bin build/binpack + ${MAKE} clean + ${MAKE} $(BUILD_DIR)/bench.flash.bin + ${MAKE} $(BUILD_DIR)/bench.ram.bin + cp $(BUILD_DIR)/bench.ram.bin $(BUILD_DIR)/bench.flash.bin build/binpack + ${MAKE} clean + ${MAKE} epsilon.onboarding.update.two_binaries + cp $(BUILD_DIR)/epsilon.onboarding.update.internal.bin $(BUILD_DIR)/epsilon.onboarding.update.external.bin build/binpack + ${MAKE} clean + cd build && for binary in flasher.light.bin bench.flash.bin bench.ram.bin epsilon.onboarding.internal.bin epsilon.onboarding.external.bin; do shasum -a 256 -b binpack/$${binary} > binpack/$${binary}.sha256;done + cd build && tar cvfz binpack-`git rev-parse HEAD | head -c 7`.tgz binpack + rm -rf build/binpack diff --git a/build/targets.simulator.web.mak b/build/targets.simulator.web.mak index 9011e2831..65abe11f7 100644 --- a/build/targets.simulator.web.mak +++ b/build/targets.simulator.web.mak @@ -6,9 +6,9 @@ $(BUILD_DIR)/epsilon.packed.js: $(call object_for,$(epsilon_src)) .PHONY: workshop_python_emulator workshop_python_emulator: - make PLATFORM=simulator TARGET=web clean_for_apps_selection - make PLATFORM=simulator TARGET=web EPSILON_APPS=code - make PLATFORM=simulator TARGET=web clean_for_apps_selection + $(MAKE) PLATFORM=simulator TARGET=web clean_for_apps_selection + $(MAKE) PLATFORM=simulator TARGET=web EPSILON_APPS=code + $(MAKE) PLATFORM=simulator TARGET=web clean_for_apps_selection .PHONY: clean_for_apps_selection clean_for_apps_selection: diff --git a/escher/src/layout_field.cpp b/escher/src/layout_field.cpp index 000e49808..0feeeefc8 100644 --- a/escher/src/layout_field.cpp +++ b/escher/src/layout_field.cpp @@ -196,7 +196,9 @@ bool LayoutField::ContentView::selectionIsEmpty() const { } void LayoutField::ContentView::deleteSelection() { - assert(!selectionIsEmpty()); + if (selectionIsEmpty()) { + return; + } Layout selectionParent = m_selectionStart.parent(); /* If the selected layout is the upmost layout, it must be an horizontal @@ -318,9 +320,7 @@ bool LayoutField::handleEventWithText(const char * text, bool indentation, bool * - the result of a copy-paste. */ // Delete the selected layouts if needed - if (!m_contentView.selectionIsEmpty()) { - deleteSelection(); - } + deleteSelection(); if (text[0] == 0) { // The text is empty @@ -493,8 +493,11 @@ bool LayoutField::privateHandleEvent(Ion::Events::Event event) { } return true; } - if (event == Ion::Events::Copy && isEditing()) { + if ((event == Ion::Events::Copy || event == Ion::Events::Cut) && isEditing()) { m_contentView.copySelection(context()); + if (event == Ion::Events::Cut) { + m_contentView.deleteSelection(); + } return true; } if (event == Ion::Events::Clear && isEditing()) { diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 6e8cd0303..b9043448d 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -78,6 +78,12 @@ void TextField::ContentView::setText(const char * text) { maxBufferSize = m_draftTextBufferSize; buffer = s_draftTextBuffer; } + if (textRealLength > maxBufferSize - 1) { + // The text was too long to be copied + // TODO Maybe add a warning for the user? + buffer[0] = 0; + return; + } int textLength = minInt(textRealLength, maxBufferSize - 1); // Copy the text strlcpy(buffer, text, maxBufferSize);