Text and Item Display Options

This chapter collects the display options of the text-bearing report items that are not covered by the Data Formatting chapter: the content modes of HTML text items (rich text, plain text and Markdown), hiding repeated field values, breaking long rich text across pages, and rotating text.

Rich Text, Plain Text and Markdown in Text Items

The Text item (<text> element, HTML Text Properties dialog in the Designer) renders its content with Qt’s rich text engine (QTextDocument). How the content is interpreted depends on two options:

Mode plain markdown Content handling

Rich text (default)

-

-

The content is HTML (the subset of HTML supported by Qt’s rich text engine) and is passed to the document as it is.

Plain text

true

-

The content is plain text. Without Markdown integration (see Markdown in Text Items), each line break becomes <br> and the whole text is wrapped in a paragraph. With Markdown integration built in, the plain text is converted to HTML by the Markdown processor.

Markdown

(true)

true

The content is Markdown text and is loaded with QTextDocument::setMarkdown() (Qt 5.14 or later).

These modes apply to every content source of the text item: static text, file, data source column, parameter, file name from a data source and URL. The content is converted each time the item value is evaluated, so dynamic content (for example a data source column that contains Markdown) is converted record by record.

In the Designer, the options are check boxes in the Options group of the HTML Text Properties dialog:

Plain text

Turns on plain text mode (plain="true"). When it is checked, the WYSIWYG Editor mode is disabled and the dialog switches to Source code mode, because the content is no longer HTML.

Markdown conversion

Turns on Markdown mode (markdown="true"). Checking it also checks Plain text.

Use system font settings

(useFont="true") The item’s own font, text color (forecolor) and alignment, set with the Text properties toolbar, are applied as the defaults of the text document, and the document margin is set to zero. Formatting in the HTML content (for example a <span style="…​">) overrides these defaults. When the option is off, the text color and alignment of the item are not applied; use HTML formatting in the content instead.

The radio buttons Editor mode and Source code mode select the editor used in the dialog: the WYSIWYG rich text editor or the HTML source editor with syntax highlighting. The choice is stored in the editorMode attribute (0 = editor mode, 1 = source code mode); if the attribute is missing, source code mode is used. It only affects editing, not rendering.

When plain text mode is on, the item’s alignment is also saved in the report definition (alignment attribute); together with Use system font settings it becomes the default alignment of the text.

Text case and letter options

Capitalization, letter spacing, rotation, fill character, character length and vertical alignment are options of Label and Field items. They are set on the Text tab of the label and field property dialogs, which is described in the Data Formatting chapter (Text formats). The capitalization is stored in the capital attribute as the numeric value of QFont::Capitalization:

capital Capitalization (Designer)

(not written)

Mixed case (default)

1

All uppercase

2

All lowercase

3

Small caps

4

Capitalize (first letter of each word in uppercase)

Text items have no capitalization option in their property dialog; in HTML content, use the CSS text-transform and font-variant properties supported by Qt’s rich text engine instead.

Markdown in Text Items

Markdown is a lightweight markup language that is easier to write than HTML. NCReport supports Markdown in text items in two ways.

Qt’s built-in Markdown support

If NCReport is built with Qt 5.14 or later, a text item with the markdown="true" attribute loads its content with QTextDocument::setMarkdown(). No additional build option is needed. In the Designer, check Markdown conversion in the HTML Text Properties dialog; this also checks Plain text, so the item is saved with both attributes:

<text id="6JOOM" posX="0.000" posY="0.000" width="168.910" height="124.460"
      useFont="true" fontName="Times New Roman" fontSize="10" forecolor="#5c3566"
      plain="true" markdown="true" editorMode="1" alignment="1">### Title
- subject 1
- subject 2</text>

With Qt versions older than 5.14, the markdown attribute is ignored by the engine (the item is then handled as a plain text item), and the Markdown conversion check box is not available in the Designer unless Markdown integration is built in.

Markdown integration (MARKDOWN_INTEGRATION)

NCReport can also be built with its own Markdown processor, which is based on the Discount Markdown library shipped in src/3rdparty/markdown. To enable it, add the markdown extension to the EXTENSIONS variable in src/config.pri before building:

EXTENSIONS += designer runner consoleapp barcode preview markdown

The extension is not part of the default extension list. When it is enabled, the build defines the MARKDOWN_INTEGRATION macro and compiles the Markdown processor into the engine. The macro has two effects:

  • In the engine, the conversion of plain text content is done by the Markdown processor: a text item with plain="true" is converted from Markdown to HTML instead of the simple line-break conversion.

  • In the Designer, the Markdown conversion check box is always shown, regardless of the Qt version.

When both markdown="true" and plain="true" are set and NCReport is built with Qt 5.14 or later, Qt’s built-in Markdown support takes precedence. The Discount processor is used for items that have only plain="true", and for all plain text items when the Qt version is older than 5.14.

Example

The markdown_test.ncr demo report in the reports directory contains a text item with static Markdown content (a level 3 heading and a bulleted list) in its detail section.

Hiding Repeated Values

In lists sorted by a column, the same value often appears in several consecutive rows, for example the order date in an order list. The Hide repeated values option prints such a value only once: a field is left blank if its value is the same as in the previous record.

In the Designer, the option is a check box on the General tab of the field property dialog (Options group). In the report definition it is the hideRepeated attribute of the field:

<field id="3" posX="0.000" posY="0.000" width="22.490" height="5.027"
       hideRepeated="true" type="date" ftype="ds">OrderDate</field>

How it works

The engine decides at the visibility check of the field (the same check that hides empty fields):

  • The comparison uses the formatted display value of the field, that is, the text that would be printed (after number and date formatting).

  • The value is compared with the value the field had the last time it was evaluated with a non-empty value, which is normally the previous record of the section. If the two are equal, the field is treated as empty and is not printed. The current value is then stored for the next comparison.

  • An empty value is never compared and does not replace the stored value.

  • The stored value is cleared at the start of the report for all fields, and after every page break for the fields of the current detail section. Therefore the first record on each page always shows the value, even if it is the same as the last value on the previous page.

  • The stored value is not cleared when a group changes. If a group starts with the same value as the last record of the previous group, the value is hidden.

  • The option is applied only if the field has no Print When expression. If a Print When expression is set, the expression alone decides whether the field is printed, and repeated values are printed.

Because the hidden field counts as empty, in a section with automatic height a zone that contains only hidden fields is not printed and the section shrinks accordingly (see the Zones chapter).

The hideRepeated attribute is also read and written for label items, but it has no effect on them, and the Designer does not show the option in the label property dialog. Hiding repeated values is a field feature.

Example

The hide_repeated_orderlist_demo.xml demo report lists the records of the orders table and hides the repeated values of the OrderDate field.

Breaking Rich Text Across Pages

A text item with automatic height grows with its content. If the content is longer than the space left on the page, the whole section would normally move to the next page, and a text longer than a page could never be printed completely. NCReport can instead slice such a text item: it prints the part that fits on the current page and continues the rest on the following pages.

Requirements

Slicing works only if all of the following conditions are met:

  1. The item is a Text (HTML text) item. Other item types cannot be sliced.

  2. The item can break: Break to page is checked in the HTML Text Properties dialog (canBreak="true").

  3. The item has automatic height: Automatic height is checked (autoHeight="true"), so its height is calculated from the content.

  4. The section has automatic height (autoHeight="true" on the section), because slicing is part of the zone handling of automatic-height sections.

  5. Page breaks between zones are allowed in the report: Page break is allowed between zones is checked in the Zone settings of the report and page settings (the zoneBreak report option is true).

<options>
    ...
    <zoneBreak>true</zoneBreak>
</options>
...
<detail id="Detail1" height="28.840" autoHeight="true" datasource="text">
    <items>
        <text id="UIMNF" posX="47.625" posY="4.762" width="122.237" height="4.762"
              zoneID="1" resource="datasource" autoHeight="true" canBreak="true"
              useFont="false">text.col3</text>
    </items>
</detail>

How the text is sliced

When the engine renders a section with automatic height, it collects the visible items into zones and calculates the height of each zone. If a zone does not fit into the remaining space of the page and it contains a breakable item, the engine calculates how much of the text fits:

  • The text is divided at line boundaries: the engine walks through the laid-out lines of the text document (block by block, line by line) and takes as many lines as fit into the remaining height. A line is never split.

  • If at least one line fits, the zone is shrunk to the height of the fitting lines, and that part of the text is printed on the current page.

  • If not even one line fits, the section is not printed on the current page; it is moved to the next page.

After the first part has been printed, the engine performs a page break (the page footer and the page header are printed as on any new page) and continues the text from the next unprinted line at the top of the new page. This repeats until the whole text has been printed, so a text can span any number of pages.

Rectangle and line items of the same zone that have automatic height are redrawn around each printed part of the sliced text, so a frame drawn around a text item follows the text onto the following pages.

The sliced parts are painted only in the graphical outputs (preview, printer, PDF, SVG and image). The HTML, Excel and text outputs do not paginate the text this way.

Example

The htmltext_slice_demo.xml demo report prints long rich text values from a static text data source. Its detail section has automatic height and contains a breakable text item with automatic height, and the report has the zoneBreak option turned on.

Rotating Items

The following report items and objects support rotation:

Item XML attribute Notes

Label, Field

rotation (integer, degrees)

Set with Rotation angle on the Text tab of the property dialog (0-360 in the Designer). Described below.

Barcode

rotation (degrees)

Rotation by the Zint library: 0, 90, 180 or 270. See the Barcodes chapter.

Cross-tab cell

rotation (real number, degrees)

Rotation of the cell text in the cell style of the cross-table. See the Cross-Tab Tables chapter.

Whole output

-

NCReport::setRotationAngle() rotates the output pages; the valid angles are 90, -90, 180 and 270. See the Report Outputs chapter.

Text (HTML text), image, shape, chart and table items cannot be rotated.

Rotating labels and fields

A label or field with a non-zero rotation value is drawn rotated by the given angle in degrees (clockwise):

<label id="0" posX="0.000" posY="0.000" width="31.750" height="31.750"
       fontName="Liberation Sans" fontSize="10" rotation="90">Text rotated by 90 degrees</label>
<field id="WAXL7" posX="60.325" posY="1.587" width="47.625" height="49.212"
       resource="datasource" fontName="Arial" fontSize="10" rotation="270"
       type="txt" ftype="ds">name</field>

The engine draws rotated text in a rectangle whose width and height are swapped compared to the item: the height of the item becomes the available line length, and the width of the item becomes the available height of the text. Design rotated items accordingly; for example, a vertical caption needs a tall, narrow item. Alignment and word wrapping are applied within the swapped rectangle.

  • 90: the text runs from top to bottom (rotated clockwise).

  • 270: the text runs from bottom to top (rotated counterclockwise).

The rotated text is positioned inside the item box only for the angles 90 and 270. For other angles, including 180 and arbitrary angles, the engine does not translate the text into the item rectangle, so the text appears outside the item. Check the result in the preview before using other angles.

Limitations

  • Rotation is applied only in the graphical outputs: preview, printer, PDF, SVG and image. The HTML, Excel and text outputs ignore the rotation.

  • The automatic height calculation of labels and fields measures the text horizontally and does not take the rotation into account. Use a fixed item size for rotated text.

  • The Designer accepts rotation angles from 0 to 360 for labels and fields. If you edit an item whose definition contains a negative angle (for example one written by hand), the value is reset to 0 when you click OK in its property dialog.

Examples

The rotation_demo.xml demo report contains labels rotated by 90, 270 and 180 degrees. The lbl270.ncr demo report shows a label and a data field rotated by 270 degrees, a typical layout for vertical captions on labels.