From ca0590453a171f7a484b36db78d2117e71c9a690 Mon Sep 17 00:00:00 2001 From: Rick Blommers Date: Thu, 27 Feb 2025 22:24:49 +0100 Subject: [PATCH] [v0.10.0] #151, Add line based QTextLayout format additions (#153) Via edbee::LineData (LineAppendTextLayoutFormatListField). see: `edbee-lib/doc/line_data.md` for sample --- CHANGELOG.md | 2 + edbee-lib/doc/coding-style.md | 75 ++++++++++++-------------- edbee-lib/doc/index.md | 10 ++-- edbee-lib/doc/line_data.md | 58 ++++++++++++++++++++ edbee-lib/edbee/edbeeversion.h | 4 +- edbee-lib/edbee/models/textlinedata.h | 9 ++-- edbee-lib/edbee/views/textrenderer.cpp | 10 +++- 7 files changed, 119 insertions(+), 49 deletions(-) create mode 100644 edbee-lib/doc/line_data.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 06232a5..8c1578d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +- (2025-02-27) [v0.10.0] #151, Add line based QTextLayout format additions + Via edbee::LineData (LineAppendTextLayoutFormatListField). see: `edbee-lib/doc/line_data.md` for sample - (2025-01-24) [v0.9.0] #150, Add version number (EDBEE_VERSION / Edbee::instance()->version()) - (2025-01-24) #145, Replace onigmo with onigruma diff --git a/edbee-lib/doc/coding-style.md b/edbee-lib/doc/coding-style.md index 44ba548..e753f17 100644 --- a/edbee-lib/doc/coding-style.md +++ b/edbee-lib/doc/coding-style.md @@ -1,59 +1,56 @@ -Coding Style {#coding-style} -============ +# Coding Style {#coding-style} -The coding style is based on google's styleguide: +The coding style is based on google's styleguide: * default names: defaultNames * class names : ClassNames -* const names : CONSTANT_NAMES +* const names : `CONSTANT_NAMES` Reference, pointer location can be placed next to type typename or to the variable name -* good: TypeName* object; TypeName& name; -* good: TypeName *object; TypeName &name; -* bad: TypeName * object; TypeName & name; +* good: `TypeName* object; TypeName& name;` +* good: `TypeName *object; TypeName &name;` +* bad: `TypeName * object; TypeName & name;` Member instances should be private. Subclasses should never access data members directly unless it's stricly necessary. -class members -------------- +## class members A class member name is postfixed with '_'. (To prevent clashes with getter functions) -~~~{.cpp} +```cpp int itemName_; -~~~ +``` -A class member pointer that is NOT owned by the classes show be postfixed with "Ref". +A class member pointer that is NOT owned by the classes show be postfixed with "Ref". For example a reference to a buffer is added like this -~~~{.cpp} +```cpp TextBuffer* bufferRef_; -~~~ +``` When you have a list of reference the following name is used: -~~~{.cpp} +```cpp QList itemRefList_; -~~~ +int x = 12; +``` -Method definitions ------------------- +## Method definitions Separate methods from each other with 2 blank lines. This improves the visible separation of method bodies. -Ownership ---------- +## Ownership In C / C++ you need to do your own garabage collection. So ownership is important. Here are some rules to make the ownership in the code clear: * all class members are 'owned' by the class. If not add the postfix "Ref" (see class members) -* transfering ownership from x => y, prefix the function with the word "give" or "take". +* transfering ownership from x => y, prefix the function with the word "give" or "take". * object.give( x ) gives the ownership of x to object * object.take( x ) removes the ownership of x from object @@ -61,29 +58,28 @@ When it is possible for a class to have the ownership of an object optionally, t * give the class 2 members. For example in the case of a document: * document_, this is the 'owned' document (only if the document is owner else it is 0) -* documentRef_ , this is the reference to the document. This can be a reference to document_ +* documentRef_ , this is the reference to the document. This can be a reference to document_ * For working with the document the documentRef_ member is used * For destruction/giving etc. the document_ member is used -When using lists yout can use the following structure +When using lists yout can use the following structure -~~~{.cpp} -QList objectList_ ; // when owning the items (use qDeleteAll in the destructor) +```cpp +QList objectList_ ; // when owning the items (use qDeleteAll in the destructor) QList objectRefList_; // use this when you do not own the objectlist -~~~ +``` -Memory Leak Detection and include order ---------------------------------------- +## Memory Leak Detection and include order We use custom memory leak detection. To enable this leak detection it is required to include 'debug.h' You must include "debug.h" in every Source file AFTER all pre-compiled items and header files. Example: -~~~{.cpp} +~~~{.cpp} // first you should include the source's header file. (This allows you to see if the headers users 'missing' dependencies' #include "header-file-of-this-source-file.h" -// then include all Qt headers (and other external libraries) (sorted alpabeticly). +// then include all Qt headers (and other external libraries) (sorted alpabeticly). #include // after this include your other header files from your project (alpabeticly is nice!) @@ -97,8 +93,7 @@ This implies that you should never use a new or delete keyword in a header file! main.cpp is different, it includes all DEBUG_NEW stuff below ALL existing header files! -Documentation --------------- +## Documentation We make use of doxygen: @@ -107,18 +102,18 @@ We make use of doxygen: - Put method documentation in the source file of the class -Header files ------------- -- Use #pragma once.. Most platforms support this keyword, so use it. #ifdef structure is outdated +## Header files + +- Use `#pragma once`.. Most platforms support this keyword, so use it. `#ifdef` structure is outdated - Never use code in a header file. Even not for getters and setters. (It has been done in this project on certain places, but recommendation is to not do it, because it can case strange build errors) - You can make an exception (of course) for template classes / function -- limit the use of templates! This slows down the compilation process and gives very crappy error messages -- Prefer pointers/references above class inclusions in the header file +- limit the use of templates! This slows down the compilation process and gives very crappy error messages +- Prefer pointers/references above class inclusions in the header file + +## Enumerations -Enumerations ------------- -On several places in the code you will find enumeration definitions. We do not aways force the enumeration +On several places in the code you will find enumeration definitions. We do not aways force the enumeration type for variables. The reason for this is, that somethimes it's desirable to extends the number of enumeration options. And when forcing a enumeration type, you cannot easy pass a custom value and are limited to the predefined definitions. diff --git a/edbee-lib/doc/index.md b/edbee-lib/doc/index.md index 5c1db45..a04e767 100644 --- a/edbee-lib/doc/index.md +++ b/edbee-lib/doc/index.md @@ -1,8 +1,12 @@ -edbee documentation {#mainpage} -=================== +# edbee documentation {#mainpage} This is the generated documentation for the edbee library. Please use the menu above to navigate... -[Coding Style](@ref coding-style) +[Coding Style](coding-style.md) +### Features + +[Line Data](line_data.md) + +... a big todo to show explain samples/features ... diff --git a/edbee-lib/doc/line_data.md b/edbee-lib/doc/line_data.md new file mode 100644 index 0000000..30f6d6a --- /dev/null +++ b/edbee-lib/doc/line_data.md @@ -0,0 +1,58 @@ +# Line data + +Linedata support add the support for adding custom data to TextDocument lines. +These data items are automaticly moved/delete when inserting/deleting lines. + +The line data is a fixed with array with pointers and is reserved for every line. +The enum `TextLineDataPredefinedFields` defines the predefined fields that are built in edbee. +The `PredefinedFieldCount' value can be used to find out where to start defining your custom types. + +To use extra custom fields you are required to set the number of fields to reserve. +This can be done with `editor->textDocument()->lineDataManager()->setFieldsPerLine(3)` +which needs to have at least the length of PredefinedFieldCount. + + +## General usage + +To set a file for a given line you can invoke the giveLineData method. + +```cpp +textDocument()->giveLineData(line, edbee::LineAppendTextLayoutFormatListField, data); +``` + +Removing can be done by supplying a nullptr to the data + +```cpp +textDocument()->giveLineData(line, edbee::LineAppendTextLayoutFormatListField, nullptr); +``` + +## Predefined variable `LineAppendTextLayoutFormatListField` + +The predefined `LineAppendTextLayoutFormatListField` field type can be used to +add custom `` ranges to the QTextLayout of a line. + +For example, to add a waved red underline: + +```cpp +// Set the line data for a given line (assuming this line is in the document!!) +int line = 2; + +// build a list of QTextLayout::FormatRanges +QList formatRanges; + +QTextLayout::FormatRange formatRange; +formatRange.start = 0; +formatRange.length = editor->textDocument()->lineLength(line); +formatRange.format.setUnderlineStyle(QTextCharFormat::WaveUnderline); +formatRange.format.setUnderlineColor(Qt::red); +formatRanges.append(formatRange); + +// build a line data item (which is added to the TextLineData) +edbee::LineAppendTextLayoutFormatListData *formatRangesListData = new edbee::LineAppendTextLayoutFormatListData(formatRanges); +editor->textDocument()->giveLineData(line, edbee::LineAppendTextLayoutFormatListField, formatRangesListData); +``` + +Because every line has it's own QTextLayout the range offset of the given line is 0. + + + diff --git a/edbee-lib/edbee/edbeeversion.h b/edbee-lib/edbee/edbeeversion.h index 6160d2f..4180f64 100644 --- a/edbee-lib/edbee/edbeeversion.h +++ b/edbee-lib/edbee/edbeeversion.h @@ -1,8 +1,8 @@ #pragma once -#define EDBEE_VERSION "0.9.0" +#define EDBEE_VERSION "0.10.0" #define EDBEE_VERSION_MAJOR 0 -#define EDBEE_VERSION_MINOR 9 +#define EDBEE_VERSION_MINOR 10 #define EDBEE_VERSION_PATCH 0 #define EDBEE_VERSION_POSTFIX "" diff --git a/edbee-lib/edbee/models/textlinedata.h b/edbee-lib/edbee/models/textlinedata.h index dc7627e..643b6a2 100644 --- a/edbee-lib/edbee/models/textlinedata.h +++ b/edbee-lib/edbee/models/textlinedata.h @@ -8,6 +8,7 @@ #include "edbee/exports.h" #include +#include #include "edbee/util/gapvector.h" @@ -16,8 +17,9 @@ namespace edbee { enum TextLineDataPredefinedFields { LineTextScopesField=0, -// LineDataMarkers, /// Bookmarks etc - PredefinedFieldCount=1 + // LineDataMarkers, /// Bookmarks etc + LineAppendTextLayoutFormatListField=1, + PredefinedFieldCount=2 }; @@ -47,8 +49,9 @@ class EDBEE_EXPORT BasicTextLineData : public TextLineData T value_; }; -typedef BasicTextLineData QStringTextLineData; +typedef BasicTextLineData QStringTextLineData; +typedef BasicTextLineData> LineAppendTextLayoutFormatListData; //------- diff --git a/edbee-lib/edbee/views/textrenderer.cpp b/edbee-lib/edbee/views/textrenderer.cpp index d08666d..3ea70ff 100644 --- a/edbee-lib/edbee/views/textrenderer.cpp +++ b/edbee-lib/edbee/views/textrenderer.cpp @@ -12,6 +12,7 @@ #include #include +#include "edbee/models/textlinedata.h" #include "edbee/util/simpleprofiler.h" #include "edbee/models/chardocument/chartextdocument.h" @@ -319,8 +320,8 @@ TextLayout *TextRenderer::textLayoutForLineForPlaceholder(int line) formatRange.length = text.length(); formatRange.format = format; formatRanges.append(formatRange); - textLayout->setFormats(formatRanges); + textLayout->setFormats(formatRanges); textLayout->setText(text); textLayout->buildLayout(); @@ -400,6 +401,13 @@ TextLayout *TextRenderer::textLayoutForLineNormal(int line) } } } + + // append some extra formatting (if available) + edbee::LineAppendTextLayoutFormatListData* formatRangeLineData = dynamic_cast(textDocument()->getLineData(line, edbee::LineAppendTextLayoutFormatListField)); + if (formatRangeLineData) { + formatRanges.append(formatRangeLineData->value()); + } + textLayout->setFormats(formatRanges); #ifdef USE_CONTROL_PICTURES