6e8819f29b
Support XSL attribute "column" and CSS 4 attribute "spread", stored in loext:hyphenation-keep-type, to give better control over hyphenation-keep. E.g. spread: both parts of a hyphenated word shall lie within a single spread, i.e. when the next page is not visible at the same time (e.g. the next page is not a right page of a book). – css::style::ParaHyphenationKeep is a boolean property now, importing hyphenation-keep = "page" as true. – type of ParaHyphenationKeep, including the new non-ODF types is stored in the new ParagraphProperties::ParaHyphenationKeepType. – default value of ParaHyphenationKeepType is COLUMN for interoperability. – Add checkboxes to Text Flow -> Hyphenation Across in paragraph dialog: * Column (previously: Hyphenate across column and page) * Page * Spread – enabling/disabling them follows XSL/CSS 4/loext, i.e. possible combinations: * No Hyphenation across (hyphenation-keep = "page" and loext:hyphenation-keep-type = "column") * Hyphenation across [x] Column (hyphenation-keep = "page" and loext:hyphenation-keep-type = "page") * Hyphenation across [x] Column [x] Page (hyphenation-keep = "page" and loext:hyphenation-keep-type = "spread") * Hyphenation across [x] Column [x] Page [x] Spread (hyphenation-keep = "auto") – Add ODF import/export – Update DOCX import – Add ODF unit tests Note: recent implementation depends on widow settings: disabling widow handling allows hyphenation across columns and pages not only in table cells. Note: RTF import-only, but not used bPageEnd has been renamed to bKeep. Depending on the RTF test results, likely it will need to disable the layout change, e.g. GetKeepType()=ParagraphHyphenationKeepType::AUTO, if PageEnd uses obsolete hyphenation rule, i.e. shifting only the hyphenated word to the next page, not the full line. More information: – COLUMN (standard XSL value, defined in https://www.w3.org/TR/2001/REC-xsl-20011015/slice7.html#hyphenation-keep) – SPREAD and ALWAYS (CSS 4 values of hyphenate-limit-last, equivalent of hyphenation-keep, defined in https://www.w3.org/TR/css-text-4/#hyphenate-line-limits). Follow-up to commit |
||
---|---|---|
.. | ||
inc | ||
qa | ||
sdi | ||
source | ||
uiconfig | ||
util | ||
AllLangMoTarget_sw.mk | ||
CppunitTest_sw_a11y.mk | ||
CppunitTest_sw_accessible_relation_set.mk | ||
CppunitTest_sw_apiterminate.mk | ||
CppunitTest_sw_apitests.mk | ||
CppunitTest_sw_core_accessibilitycheck.mk | ||
CppunitTest_sw_core_attr.mk | ||
CppunitTest_sw_core_crsr.mk | ||
CppunitTest_sw_core_doc.mk | ||
CppunitTest_sw_core_docnode.mk | ||
CppunitTest_sw_core_draw.mk | ||
CppunitTest_sw_core_edit.mk | ||
CppunitTest_sw_core_fields.mk | ||
CppunitTest_sw_core_frmedt.mk | ||
CppunitTest_sw_core_header_footer.mk | ||
CppunitTest_sw_core_layout.mk | ||
CppunitTest_sw_core_objectpositioning.mk | ||
CppunitTest_sw_core_text.mk | ||
CppunitTest_sw_core_theme.mk | ||
CppunitTest_sw_core_tox.mk | ||
CppunitTest_sw_core_txtnode.mk | ||
CppunitTest_sw_core_undo.mk | ||
CppunitTest_sw_core_unocore.mk | ||
CppunitTest_sw_core_view.mk | ||
CppunitTest_sw_dialogs_test.mk | ||
CppunitTest_sw_dialogs_test_2.mk | ||
CppunitTest_sw_docbookexport.mk | ||
CppunitTest_sw_filter_html.mk | ||
CppunitTest_sw_filter_ww8.mk | ||
CppunitTest_sw_filter_xml.mk | ||
CppunitTest_sw_filters_test.mk | ||
CppunitTest_sw_fodfexport.mk | ||
CppunitTest_sw_globalfilter.mk | ||
CppunitTest_sw_htmlexport.mk | ||
CppunitTest_sw_htmlimport.mk | ||
CppunitTest_sw_indexingexport.mk | ||
CppunitTest_sw_layoutwriter.mk | ||
CppunitTest_sw_layoutwriter2.mk | ||
CppunitTest_sw_layoutwriter3.mk | ||
CppunitTest_sw_macros_test.mk | ||
CppunitTest_sw_mailmerge.mk | ||
CppunitTest_sw_mailmerge2.mk | ||
CppunitTest_sw_odfexport.mk | ||
CppunitTest_sw_odfexport2.mk | ||
CppunitTest_sw_odffeatures.mk | ||
CppunitTest_sw_odfimport.mk | ||
CppunitTest_sw_ooxml_theme_export.mk | ||
CppunitTest_sw_ooxmlencryption.mk | ||
CppunitTest_sw_ooxmlexport.mk | ||
CppunitTest_sw_ooxmlexport2.mk | ||
CppunitTest_sw_ooxmlexport3.mk | ||
CppunitTest_sw_ooxmlexport4.mk | ||
CppunitTest_sw_ooxmlexport5.mk | ||
CppunitTest_sw_ooxmlexport6.mk | ||
CppunitTest_sw_ooxmlexport7.mk | ||
CppunitTest_sw_ooxmlexport8.mk | ||
CppunitTest_sw_ooxmlexport9.mk | ||
CppunitTest_sw_ooxmlexport10.mk | ||
CppunitTest_sw_ooxmlexport11.mk | ||
CppunitTest_sw_ooxmlexport12.mk | ||
CppunitTest_sw_ooxmlexport13.mk | ||
CppunitTest_sw_ooxmlexport14.mk | ||
CppunitTest_sw_ooxmlexport15.mk | ||
CppunitTest_sw_ooxmlexport16.mk | ||
CppunitTest_sw_ooxmlexport17.mk | ||
CppunitTest_sw_ooxmlexport18.mk | ||
CppunitTest_sw_ooxmlexport19.mk | ||
CppunitTest_sw_ooxmlexport20.mk | ||
CppunitTest_sw_ooxmlexport21.mk | ||
CppunitTest_sw_ooxmlexport_template.mk | ||
CppunitTest_sw_ooxmlfieldexport.mk | ||
CppunitTest_sw_ooxmlimport.mk | ||
CppunitTest_sw_ooxmlimport2.mk | ||
CppunitTest_sw_ooxmllinks.mk | ||
CppunitTest_sw_ooxmlw14export.mk | ||
CppunitTest_sw_pdf_test.mk | ||
CppunitTest_sw_rtfexport.mk | ||
CppunitTest_sw_rtfexport2.mk | ||
CppunitTest_sw_rtfexport3.mk | ||
CppunitTest_sw_rtfexport4.mk | ||
CppunitTest_sw_rtfexport5.mk | ||
CppunitTest_sw_rtfexport6.mk | ||
CppunitTest_sw_rtfexport7.mk | ||
CppunitTest_sw_rtfexport8.mk | ||
CppunitTest_sw_rtfimport.mk | ||
CppunitTest_sw_tiledrendering.mk | ||
CppunitTest_sw_tiledrendering2.mk | ||
CppunitTest_sw_txtencexport.mk | ||
CppunitTest_sw_txtexport.mk | ||
CppunitTest_sw_txtimport.mk | ||
CppunitTest_sw_uibase_dialog.mk | ||
CppunitTest_sw_uibase_dochdl.mk | ||
CppunitTest_sw_uibase_docvw.mk | ||
CppunitTest_sw_uibase_fldui.mk | ||
CppunitTest_sw_uibase_frmdlg.mk | ||
CppunitTest_sw_uibase_shells.mk | ||
CppunitTest_sw_uibase_uiview.mk | ||
CppunitTest_sw_uibase_unit.mk | ||
CppunitTest_sw_uibase_uno.mk | ||
CppunitTest_sw_uibase_wrtsh.mk | ||
CppunitTest_sw_uiwriter.mk | ||
CppunitTest_sw_uiwriter2.mk | ||
CppunitTest_sw_uiwriter3.mk | ||
CppunitTest_sw_uiwriter4.mk | ||
CppunitTest_sw_uiwriter5.mk | ||
CppunitTest_sw_uiwriter6.mk | ||
CppunitTest_sw_uiwriter7.mk | ||
CppunitTest_sw_uiwriter8.mk | ||
CppunitTest_sw_uiwriter9.mk | ||
CppunitTest_sw_unowriter.mk | ||
CppunitTest_sw_uwriter.mk | ||
CppunitTest_sw_ww8export.mk | ||
CppunitTest_sw_ww8export2.mk | ||
CppunitTest_sw_ww8export3.mk | ||
CppunitTest_sw_ww8export4.mk | ||
CppunitTest_sw_ww8import.mk | ||
CppunitTest_sw_xhtmlexport.mk | ||
CustomTarget_generated.mk | ||
IwyuFilter_sw.yaml | ||
JunitTest_sw_complex.mk | ||
JunitTest_sw_unoapi_1.mk | ||
JunitTest_sw_unoapi_2.mk | ||
JunitTest_sw_unoapi_3.mk | ||
JunitTest_sw_unoapi_4.mk | ||
layoutwriter_setup.mk | ||
Library_msword.mk | ||
Library_sw.mk | ||
Library_swd.mk | ||
Library_swqahelper.mk | ||
Library_swui.mk | ||
Library_vbaswobj.mk | ||
Makefile | ||
Module_sw.mk | ||
ooxmlexport_setup.mk | ||
PythonTest_sw_python.mk | ||
README.md | ||
rtfexport_setup.mk | ||
UIConfig_sglobal.mk | ||
UIConfig_sweb.mk | ||
UIConfig_swform.mk | ||
UIConfig_swreport.mk | ||
UIConfig_swriter.mk | ||
UIConfig_swxform.mk | ||
UITest_chapterNumbering.mk | ||
UITest_classification.mk | ||
UITest_librelogo.mk | ||
UITest_sw_chart.mk | ||
UITest_sw_fieldDialog.mk | ||
UITest_sw_findBar.mk | ||
UITest_sw_findReplace.mk | ||
UITest_sw_navigator.mk | ||
UITest_sw_options.mk | ||
UITest_sw_sidebar.mk | ||
UITest_sw_styleInspector.mk | ||
UITest_sw_table.mk | ||
UITest_sw_ui_fmtui.mk | ||
UITest_sw_ui_frmdlg.mk | ||
UITest_sw_ui_index.mk | ||
UITest_sw_ui_misc.mk | ||
UITest_sw_uibase_docvw.mk | ||
UITest_sw_uibase_shells.mk | ||
UITest_writer_dialogs.mk | ||
UITest_writer_macro_tests.mk | ||
UITest_writer_tests.mk | ||
UITest_writer_tests2.mk | ||
UITest_writer_tests3.mk | ||
UITest_writer_tests4.mk | ||
UITest_writer_tests5.mk | ||
UITest_writer_tests6.mk | ||
UITest_writer_tests7.mk | ||
UITest_writer_tests8.mk | ||
uiwriter_setup.mk | ||
ww8export_setup.mk |
Writer Application Code
Exact history was lost before Sept. 18th, 2000, but old source code comments show that Writer core dates back until at least November 1990.
Module Contents
inc
: headers available to all source files inside the moduleqa
: unit, slow and subsequent testssdi
source
: see belowuiconfig
: user interface configurationutil
: UNO passive registration config
Source Contents
core
: Writer core (document model, layout, UNO API implementation)filter
: Writer internal filtersascii
: plain text filterbasflt
docx
: wrapper for the UNO DOCX import filter (in writerfilter) for autotext purposeshtml
: HTML filterinc
: include files for filtersrtf
: thin copy&paste helper around the UNO RTF import filter (in writerfilter)writer
ww8
: DOC import, DOC/DOCX/RTF exportxml
: ODF import/export, subclassed from xmloff (where most of the work is done)
uibase
: user interface (those parts that are linked intosw
& always loaded)ui
: user interface (optional parts that are loaded on demand (swui
))
Core
There is a good overview documentation of basic architecture of Writer core in the OOo wiki:
- https://wiki.openoffice.org/wiki/Writer/Core_And_Layout
- https://wiki.openoffice.org/wiki/Writer/Text_Formatting
Writer specific WhichIds are defined in sw/inc/hintids.hxx
.
The details below are mainly about details missing from the wiki pages.
SwDoc
The central class for a document is SwDoc
, which represents a document.
A lot of the functionality is split out into separate Manager classes,
each of which implements some IDocument*
interface; there are
SwDoc::getIDocument*()
methods to retrieve the managers.
However there are still too many members and methods in this class, many of which could be moved to some Manager or other...
SwNodes
Basically a (fancy) array of SwNode
pointers. There are special subclasses of
SwNode
(SwStartNode
and SwEndNode
) which are used to encode a nested tree
structure into the flat array; the range of nodes from SwStartNode
to its
corresponding SwEndNode
is sometimes called a "section" (but is not necessarily
what the high-level document model calls a "Section"; that is just one of the
possibilities).
The SwNodes
contains the following top-level sections:
- Empty
- Footnote content
- Frame / Header / Footer content
- Deleted Change Tracking content
- Body content
Undo
The Undo/Redo information is stored in a sw::UndoManager
member of SwDoc
,
which implements the IDocumentUndoRedo
interface.
Its members include a SwNodes
array containing the document content that
is currently not in the actual document but required for Undo/Redo, and
a stack of SwUndo
actions, each of which represents one user-visible
Undo/Redo step.
There are also ListActions
which internally contain several individual SwUndo
actions; these are created by the StartUndo/EndUndo wrapper methods.
Text Attributes
The sub-structure of paragraphs is stored in the SwpHintsArray
member
SwTextNode::m_pSwpHints
. There is a base class SwTextAttr
with numerous
subclasses; the SwTextAttr
has a start and end index and a SfxPoolItem
to store the actual formatting attribute.
There are several sub-categories of SwTextAttr
:
-
formatting attributes: Character Styles (
SwTextCharFormat
,RES_TXTATR_CHARFMT
) and Automatic Styles (no special class,RES_TXTATR_AUTOFMT
): these are handled bySwpHintsArray::BuildPortions
and MergePortions, which create non-overlapping portions of formatting attributes. -
nesting attributes: Hyperlinks (
SwTextINetFormat
,RES_TXTATR_INETFMT
), Ruby (SwTextRuby
,RES_TXTATR_CJK_RUBY
) and Meta/MetaField (SwTextMeta
,RES_TXTATR_META/RES_TXTATR_METAFIELD
): these maintain a properly nested tree structure. The Meta/Metafield are "special" because they have both start/end and a dummy character at the start. -
misc. attributes: Reference Marks, ToX Marks
-
attributes without end: Fields, Footnotes, Flys (
AS_CHAR
) These all have a corresponding dummy character in the paragraph text, which is a placeholder for the "expansion" of the attribute, e.g. field content.
Fields
There are multiple model classes involved for fields:
enum SwFieldIds
enumerates the different types of fields.SwFieldType
contains some shared stuff for all fields of a type. There are many subclasses ofSwFieldType
, one for each different type of field. For most types of fields there is one shared instance of this per type, which is created inDocumentFieldsManager::InitFieldTypes()
but for some there are more than one, and they are dynamically created, seeDocumentFieldsManager::InsertFieldType()
. An example for the latter are variable fields (SwFieldIds::GetExp/SwFieldIds::SetExp
), with oneSwFieldType
per variable.SwXFieldMaster
is the UNO wrapper of a field type. It is aSwClient
registered at theSwFieldType
. Its life-cycle is determined by UNO clients outside ofsw
; it will get disposed when theSwFieldType
dies.SwFormatField
is theSfxPoolItem
of a field. TheSwFormatField
is aSwClient
registered at itsSwFieldType
. TheSwFormatField
owns theSwField
of the field.SwField
contains the core logic of a field. TheSwField
is owned by theSwFormatField
of the field. There are many subclasses ofSwField
, one for each different type of field. Note that there are not many places that can Expand the field to its correct value, since for example page number fields require a View with an up to date layout; therefore the correct expansion is cached.SwTextField
is the text attribute of a field. It owns theSwFormatField
of the field (like all text attributes).SwXTextField
is the UNO wrapper object of a field. It is aSwClient
registered at theSwFormatField
. Its life-cycle is determined by UNO clients outside ofsw
; it will get disposed when theSwFormatField
dies.
Lists
-
SwNumFormat
(subclass ofSvxNumFormat
) determines the formatting of a single numbering level. -
SwNumRule
(NOT a subclass ofSvxNumRule
) is a list style, containing oneSwNumFormat
per list level.SwNumRule::maTextNodeList
is the list ofSwTextNode
that have this list style applied. -
SwNumberTreeNode
is a base class that represents an abstract node in a hierarchical tree of numbered nodes. -
SwNodeNum
is the subclass ofSwNumberTreeNode
that connects it with an actualSwTextNode
and also with aSwNumRule
;SwTextNode::mpNodeNum
points back in the other direction -
SwList
represents a list, which is (mostly) a vector ofSwNodeNum
trees, one perSwNodes
top-level section (why that?). -
IDocumentListsAccess
,sw::DocumentListsManager
owns allSwList
instances, and maintains mappings:- from list-id to
SwList
- from list style name to
SwList
(the "default"SwList
for that list style)
- from list-id to
-
IDocumentListItems
,sw::DocumentListItemsManager
contains a set of allSwNodeNum
instances, ordered bySwNode
index -
the special Outline numbering rule:
SwDoc::mpOutlineRule
-
IDocumentOutlineNodes
,sw::DocumentOutlineNodesManager
maintain a list (which is actually stored inSwNodes::m_pOutlineNodes
) ofSwTextNodes
that either have the Outline numrule applied, or have theRES_PARATR_OUTLINELEVEL
item set (note that in the latter case, theSwTextNode
does not have aSwNodeNum
and is not associated with theSwDoc::mpOutlineRule
). -
SwTextNodes
and paragraph styles have items/properties:RES_PARATR_OUTLINELEVEL/"OutlineLevel"
to specify an outline level without necessarily having the outlineSwNumRule
assignedRES_PARATR_NUMRULE/"NumberingStyleName"
the list style to apply; may be empty""
which means no list style (to override inherited value) OnlySwTextNode
has these items:RES_PARATR_LIST_ID/"ListId"
determines theSwList
to which the node is addedRES_PARATR_LIST_LEVEL/"NumberingLevel"
the level at which theSwTextNode
will appear in the listRES_PARATR_LIST_ISRESTART/"ParaIsNumberingRestart"
restart numbering sequence at thisSwTextNode
RES_PARATR_LIST_RESTARTVALUE/"NumberingStartValue"
restart numbering sequence at thisSwTextNode
with this valueRES_PARATR_LIST_ISCOUNTED/"NumberingIsNumber"
determines if the node is actually counted in the numbering sequence; these are different from"phantoms"
because there's still aSwTextNode
.
Note that there is no UNO service to represent a list.
Layout
The layout is a tree of SwFrame
subclasses, the following relationships are
possible between frames:
- You can visit the tree by following the upper, lower, next and previous pointers.
- The functionality of flowing of a frame across multiple parents (e.g. pages)
is implemented in
SwFlowFrame
, which is not anSwFrame
subclass. The logical chain of such frames can be visited using the follow and precede pointers. ("Leaf" is a term that refers to such a relationship.) - In case a frame is split into multiple parts, then the first one is called master, while the others are called follows.