[storage] New attempt to save cursor position

This commit is contained in:
Laury
2022-06-10 16:15:31 +02:00
parent 1db74c78ab
commit c826e556a1
9 changed files with 91 additions and 2 deletions

View File

@@ -65,13 +65,19 @@ void EditorController::viewWillAppear() {
ViewController::viewWillAppear();
m_editorView.loadSyntaxHighlighter();
if(GlobalPreferences::sharedGlobalPreferences()->cursorSaving()) {
m_editorView.setCursorLocation(m_editorView.text() + strlen(m_editorView.text()));
int offset = m_script.cursorOffset();
if (offset != -1) {
m_editorView.setCursorLocation(m_editorView.text() + offset);
} else {
m_editorView.setCursorLocation(m_editorView.text() + strlen(m_editorView.text()));
}
} else {
m_editorView.setCursorLocation(m_editorView.text() + strlen(m_editorView.text()));
}
}
void EditorController::viewDidDisappear() {
m_script.setCursorOffset(m_editorView.cursorLocation() - m_script.content());
m_editorView.resetSelection();
m_menuController->scriptContentEditionDidFinish();
}

View File

@@ -65,6 +65,21 @@ bool Script::nameCompliant(const char * name) {
return false;
}
uint16_t Script::cursorOffset() {
assert(!isNull());
Ion::Storage::Metadata metadata = Ion::Storage::sharedStorage()->metadataForRecord(*this);
if (metadata.buffer != nullptr) {
assert(metadata.size == 2);
return *((uint16_t*) metadata.buffer);
}
return -1;
}
void Script::setCursorOffset(uint16_t position) {
assert(!isNull());
Ion::Storage::sharedStorage()->setMetadataForRecord(*this, { &position, sizeof(uint16_t) });
}
uint8_t * StatusFromData(Script::Data d) {
return const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer));
}

View File

@@ -50,6 +50,8 @@ public:
void toggleAutoimportationStatus();
const char * content() const;
size_t contentSize() { return value().size - k_statusSize; }
void setCursorOffset(uint16_t position); // -1 if no metadata
uint16_t cursorOffset();
/* Fetched status */
bool fetchedFromConsole() const;

View File

@@ -14,6 +14,11 @@ namespace Ion {
class StorageDelegate;
/**
* Purpose the two storage classes :
* - The first (InternalStorage) is the base, it allows to create, modify and delete records
* - The second (Storage) is the visible part. It handle the trash system and the metadata records
*/
class InternalStorage {
public:
typedef uint16_t record_size_t;
@@ -114,6 +119,7 @@ public:
// Used by Python OS module
int numberOfRecords();
Record recordAtIndex(int index);
protected:
InternalStorage();
/* Getters on address in buffer */

View File

@@ -37,9 +37,16 @@ public:
Record recordAtIndex(int index);
void destroyRecord(Record record);
// Trash
void reinsertTrash(const char * extension);
void emptyTrash();
// Metadata
typedef Record::Data Metadata;
Metadata metadataForRecord(Record record);
Record::ErrorStatus setMetadataForRecord(Record record, Metadata metadata);
void removeMetadataForRecord(Record record);
private:
Storage():
InternalStorage() {}

View File

@@ -26,6 +26,10 @@ int CountOccurrences(const char * s, CodePoint c);
* null terminating char otherwise. */
const char * CodePointSearch(const char * s, CodePoint c, const char * stoppingPosition = nullptr);
/* Returns the last occurrence of a code point in a string, the position of the
* null terminating char otherwise. */
const char * LastCodePoint(const char * s, CodePoint c, const char * stoppingPosition = nullptr);
// Returns true if the text had the code point
bool HasCodePoint(const char * s, CodePoint c, const char * stoppingPosition = nullptr);

View File

@@ -55,7 +55,7 @@ InternalStorage::Record::Record(const char * fullName) {
m_fullNameCRC32 = 0;
return;
}
const char * dotChar = UTF8Helper::CodePointSearch(fullName, k_dotChar);
const char * dotChar = UTF8Helper::LastCodePoint(fullName, k_dotChar);
// If no extension, return empty record
if (*dotChar == 0 || *(dotChar+1) == 0) {
m_fullNameCRC32 = 0;

View File

@@ -61,6 +61,10 @@ bool Storage::hasRecord(Record r) {
void Storage::destroyRecord(Record record) {
emptyTrash();
const Record metadataRecord = recordBaseNamedWithExtension(record.fullName(), "sys");
if (!metadataRecord.isNull()) {
InternalStorage::destroyRecord(metadataRecord);
}
m_trashRecord = record;
}
@@ -177,4 +181,21 @@ void Storage::emptyTrash() {
}
}
Storage::Metadata Storage::metadataForRecord(Record record) {
return recordBaseNamedWithExtension(record.fullName(), "sys").value();
}
Storage::Record::ErrorStatus Storage::setMetadataForRecord(Record record, Metadata data) {
Record metadataRecord = Record(record.fullName(), "sys");
if (!hasRecord(metadataRecord)) {
return createRecordWithExtension(record.fullName(), "sys", data.buffer, data.size);
} else {
return metadataRecord.setValue(data);
}
}
void Storage::removeMetadataForRecord(Record record) {
recordBaseNamedWithExtension(record.fullName(), "sys").destroy();
}
}

View File

@@ -54,6 +54,34 @@ const char * CodePointSearch(const char * s, CodePoint c, const char * stoppingP
return currentPointer;
}
const char * LastCodePoint(const char * s, CodePoint c, const char * stoppingPosition) {
if (UTF8Decoder::CharSizeOfCodePoint(c) == 1) {
const char * result = nullptr;
const char * position = s;
while (*position != 0 && (stoppingPosition == nullptr || position != stoppingPosition)) {
if (*position == c) {
result = position;
}
position++;
}
return result ? result : position;
}
UTF8Decoder decoder(s);
const char * currentPointer = s;
const char * result = nullptr;
CodePoint codePoint = decoder.nextCodePoint();
const char * nextPointer = decoder.stringPosition();
while (codePoint != UCodePointNull && (stoppingPosition == nullptr || currentPointer < stoppingPosition)) {
if (c == codePoint) {
result = currentPointer;
}
currentPointer = nextPointer;
codePoint = decoder.nextCodePoint();
nextPointer = decoder.stringPosition();
}
return result ? result : currentPointer;
}
bool HasCodePoint(const char * s, CodePoint c, const char * stoppingPosition) {
assert(c != 0);
const char * resultPosition = CodePointSearch(s, c, stoppingPosition);