diff --git a/apps/code/menu_controller.cpp b/apps/code/menu_controller.cpp index e511b328a..296fd0ad7 100644 --- a/apps/code/menu_controller.cpp +++ b/apps/code/menu_controller.cpp @@ -302,15 +302,22 @@ bool MenuController::textFieldDidFinishEditing(TextField * textField, const char static constexpr int bufferSize = Script::k_defaultScriptNameMaxSize + 1 + ScriptStore::k_scriptExtensionLength; //"script99" + "." + "py" char numberedDefaultName[bufferSize]; - if (strlen(text) <= 1 + strlen(ScriptStore::k_scriptExtension)) { + if (strlen(text) > 1 + strlen(ScriptStore::k_scriptExtension)) { + newName = text; + } else { // The user entered an empty name. Use a numbered default script name. - Script::DefaultName(numberedDefaultName, Script::k_defaultScriptNameMaxSize); + bool foundDefaultName = Script::DefaultName(numberedDefaultName, Script::k_defaultScriptNameMaxSize); int defaultNameLength = strlen(numberedDefaultName); numberedDefaultName[defaultNameLength++] = '.'; strlcpy(&numberedDefaultName[defaultNameLength], ScriptStore::k_scriptExtension, bufferSize - defaultNameLength); + /* If there are already scripts named script1.py, script2.py,... until + * Script::k_maxNumberOfDefaultScriptNames, we want to write the last tried + * default name and let the user modify it. */ + if (!foundDefaultName) { + textField->setText(numberedDefaultName); + textField->setCursorLocation(defaultNameLength); + } newName = const_cast(numberedDefaultName); - } else { - newName = text; } Script::ErrorStatus error = Script::nameCompliant(newName) ? m_scriptStore->scriptAtIndex(m_selectableTableView.selectedRow()).setName(newName) : Script::ErrorStatus::NonCompliantName; if (error == Script::ErrorStatus::None) { diff --git a/apps/code/script.cpp b/apps/code/script.cpp index a66539161..ac3651131 100644 --- a/apps/code/script.cpp +++ b/apps/code/script.cpp @@ -18,23 +18,23 @@ static inline void intToText(int i, char * buffer, int bufferSize) { buffer[2] = 0; } -void Script::DefaultName(char buffer[], size_t bufferSize) { +bool Script::DefaultName(char buffer[], size_t bufferSize) { assert(bufferSize >= k_defaultScriptNameMaxSize); static constexpr char defaultScriptName[] = "script"; static constexpr int defaultScriptNameLength = 6; memcpy(buffer, defaultScriptName, bufferSize); - // We will only name scripts from script1.py to script99.py. int currentScriptNumber = 1; - while (currentScriptNumber < 100) { + while (currentScriptNumber <= k_maxNumberOfDefaultScriptNames) { // Change the number in the script name. intToText(currentScriptNumber, &buffer[defaultScriptNameLength], bufferSize - defaultScriptNameLength ); if (ScriptStore::ScriptNameIsFree(buffer)) { - return; + return true; } currentScriptNumber++; } - assert(false); + // We did not find a new script name + return false; } bool Script::nameCompliant(const char * name) { diff --git a/apps/code/script.h b/apps/code/script.h index 76e4caa41..4ab639c13 100644 --- a/apps/code/script.h +++ b/apps/code/script.h @@ -9,16 +9,18 @@ namespace Code { * Script: | AutoImportationStatus | Content |*/ class Script : public Ion::Storage::Record { +private: + // Default script names are chosen between script1 and script99 + static constexpr int k_maxNumberOfDefaultScriptNames = 99; + static constexpr int k_defaultScriptNameNumberMaxSize = 2; // Numbers from 1 to 99 have 2 digits max public: static constexpr size_t k_importationStatusSize = 1; - static constexpr int k_defaultScriptNameMaxSize = 6 + 2 + 1; - /* k_defaultScriptNameMaxSize is the length of a name between script1 and - * script99 - * 6 = strlen("script") - * 2 = maxLength of integers between 1 and 99 + static constexpr int k_defaultScriptNameMaxSize = 6 + k_defaultScriptNameNumberMaxSize + 1; + /* 6 = strlen("script") + * k_defaultScriptNameNumberMaxSize = maxLength of integers between 1 and 99 * 1 = null-terminating char */ - static void DefaultName(char buffer[], size_t bufferSize); + static bool DefaultName(char buffer[], size_t bufferSize); static bool nameCompliant(const char * name); Script(Ion::Storage::Record r) : Record(r) {} diff --git a/apps/code/script_store.h b/apps/code/script_store.h index bf21e80e2..46273c57d 100644 --- a/apps/code/script_store.h +++ b/apps/code/script_store.h @@ -47,10 +47,10 @@ private: /* If the storage available space has a smaller size than * k_fullFreeSpaceSizeLimit, we consider the script store as full. * To be able to add a new empty record, the available space should at least - * stores a Script with default name "script99.py" (12 char), the importation - * status (1 char), the default content "from math import *\n" (20 char) and - * 10 char of free space. */ - static constexpr int k_fullFreeSpaceSizeLimit = sizeof(Ion::Storage::record_size_t)+12+1+20+10; + * be able to store a Script with default name and its extension, the + * importation status (1 char), the default content "from math import *\n" + * (20 char) and 10 char of free space. */ + static constexpr int k_fullFreeSpaceSizeLimit = sizeof(Ion::Storage::record_size_t)+Script::k_defaultScriptNameMaxSize+k_scriptExtensionLength+1+20+10; static constexpr size_t k_fileInput2ParseNodeStructKind = 1; static constexpr size_t k_functionDefinitionParseNodeStructKind = 3; static constexpr size_t k_expressionStatementParseNodeStructKind = 5; diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 6affa8e51..1f917cd01 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -57,12 +57,15 @@ size_t TextField::ContentView::editedTextLength() const { void TextField::ContentView::setText(const char * text) { reloadRectFromCursorPosition(0); + int textLength = strlen(text) >= m_textBufferSize ? m_textBufferSize-1 : strlen(text); if (m_isEditing) { strlcpy(m_draftTextBuffer, text, m_textBufferSize); - int textLength = strlen(text) >= m_textBufferSize ? m_textBufferSize-1 : strlen(text); m_currentDraftTextLength = textLength; } else { strlcpy(m_textBuffer, text, m_textBufferSize); + if (m_textBuffer == m_draftTextBuffer) { + m_currentDraftTextLength = textLength; + } } reloadRectFromCursorPosition(0); }