Slide 1

Slide 1 text

How to add a new Writer feature? Miklós Vajna 18 October 2012

Slide 2

Slide 2 text

2 How to add a new Writer feature? Introduction Not only features count

Slide 3

Slide 3 text

3 How to add a new Writer feature? How a member of the community can help Helping users (mailing lists, forums, IRC) QA (reporting, confirming issues) Development Writing guides Design Operating the infrastructure

Slide 4

Slide 4 text

4 How to add a new Writer feature? How a developer can help Fixing issues Testing Implementing new features Refactoring Mentoring Documenting

Slide 5

Slide 5 text

5 How to add a new Writer feature? Examples: new Writer features in LibreOffice 3.7 Commenting a text range Different header / footer on first page

Slide 6

Slide 6 text

6 How to add a new Writer feature? Steps for a new feature Document model UNO API Layout Filters UI Tests Documentation Specification

Slide 7

Slide 7 text

7 How to add a new Writer feature? Document model You would think this is the only necessary part

Slide 8

Slide 8 text

8 How to add a new Writer feature? What is the document model Classic Model-View-Controller One open document ↔ SwDoc Basic building block: paragraphs ↔ SwNode Code lives under sw/source/core/ No separate node for text runs, SwpHints instead SwTxtAttr inside for each property: start/end/what Lots of other collections, for example: SwPageDesc: page styles Added for “first page header” feature: SwPageDesc::aFirst

Slide 9

Slide 9 text

9 How to add a new Writer feature? How to explore the document model XML dump: Shift-F12 creates nodes.xml Through UNO: Same for runs $ SW_DEBUG=1 ./soffice.bin enum = ThisComponent.Text.createEnumeration para = enum.NextElement para = enum.NextElement xray para

Slide 10

Slide 10 text

10 How to add a new Writer feature? UNO API To be able to manipulate it from macros

Slide 11

Slide 11 text

11 How to add a new Writer feature? Purpose of the UNO API Macros can read and write the new feature Handy: you can test it before messing with the UI UNO filters use this as well Makes writing testcases easy as well Where it lives: sw/source/core/unocore/

Slide 12

Slide 12 text

12 How to add a new Writer feature? How to play with macros / UNO API Turn on contextual spacing for a paragraph: Enable different header and footer on first pages: Attach comment to a text range: enum = ThisComponent.Text.createEnumeration para = enum.NextElement xray para.ParaContextMargin para.ParaContextMargin = True oDefault = ThisComponent.StyleFamilies.PageStyles.Default oDefault.HeaderIsOn = True oDefault.HeaderIsShared = False oDefault.FirstIsShared = False oTextField = oDoc.createInstance("com.sun.star.text.TextField.Annotation") oTextField.TextRange.String = "Content" oDoc.Text.insertTextContent(oCurs, oTextField, True)

Slide 13

Slide 13 text

13 How to add a new Writer feature? Layout Display what was hidden so far

Slide 14

Slide 14 text

14 How to add a new Writer feature? Layout The “View” from MVC In case of Writer, it has its own model as well: In the document model, it's just paragraphs In the layout, it's “just” frames: One opened document ↔ SwRootFrm One page ↔ SwPageFrm One paragraph ↔ SwTxtFrm One model element ↔ multiple layout elements Headers on each page Paragraphs splitting across pages Linked with SwClient / SwModify Dump: same as document model, but F12, not Shift-F12

Slide 15

Slide 15 text

15 How to add a new Writer feature? Filters Let's try to survive the restart

Slide 16

Slide 16 text

16 How to add a new Writer feature? Filters Export filters: save SwDoc to a stream Import filters: open the stream and populate SwDoc again ~All filters are “alien” It's known that they loose some info during conversion Exception: ODF filters (a.k.a. “own”) Type: UNO: DOCX import, RTF import Builtin – uses the internal sw API: DOC import, Word export Mixed: ODF (mostly UNO, but some bits are internal) Code: sw/source/filter/, writerfilter/, xmloff/

Slide 17

Slide 17 text

17 How to add a new Writer feature? User Interface Let users start to notice your work

Slide 18

Slide 18 text

18 How to add a new Writer feature? Old / new user interface Old: let's not use mouse for building a UI Typically a .src, .hrc and a .cxx file for each dialog Each element has fixed position / size: Add one element in the middle of the dialog And you'll have to move all the remaining controls down New: Glade-powered See Caolán's talk CheckBox CB_SHARED_FIRST { HelpID ="svx:CheckBox:RID_SVXPAGE_HEADER:CB_SHARED_FIRST"; Pos = MAP_APPFONT ( 12 , 46 ) ; Size = MAP_APPFONT ( 152 , 10 ) ; Text [ en-US ] = "Same content on first page" ; };

Slide 19

Slide 19 text

19 How to add a new Writer feature? UI ↔ document model interaction UI is often shared, can't be specific to applications Invented solution: SfxItemSet Checkbox → SfxItemSet: SfxItemSet → document model (SwPageDesc): Similar in the other direction Shared code is under svx/source/dialog/, cui/ Writer-specific code is under sw/source/ui/ aSet.Put(SfxBoolItem(nWSharedFirst,aCntSharedFirstBox.IsChecked())); rPageDesc.ChgFirstShare(((const SfxBoolItem&) rHeaderSet.Get(SID_ATTR_PAGE_SHARED_FIRST)).GetValue());

Slide 20

Slide 20 text

20 How to add a new Writer feature? Testcases Why repeat old bugs, if there are so many new ones?

Slide 21

Slide 21 text

21 How to add a new Writer feature? Testcases Test types in LibreOffice: Unitcheck: at the end of every partial module build Should be super-fast (CVE tests, for example) Slowcheck: at the end of a toplevel build Filter tests typically go here Subsequentcheck: old Java tests Slowly migrated to native code What to test: Document model (UNO API) Layout (XML DUMP + assert XPath expression): CPPUNIT_ASSERT_EQUAL(OUString("First header"), parseDump("/root/page[1]/header/txt/text()"));

Slide 22

Slide 22 text

22 How to add a new Writer feature? Import / export tests Create minimal reproducer Import or import → export → import You know what you want to test Check the resulting document model using UNO API: Make sure it passes Revert the bugfix / feature Make sure it fails Drop the revert, squash the two commits Code: sw/qa/ CPPUNIT_ASSERT_EQUAL(6, getLength());

Slide 23

Slide 23 text

23 How to add a new Writer feature? Documentation When the obvious is not that obvious

Slide 24

Slide 24 text

24 How to add a new Writer feature? User help You know, the thing nobody cares about Comes up every time the user presses F1 Where to add it? Use the UI Find existing text after/before you would insert new content Use git grep under helpcontent2/ Add new content to the XML files Problems No linkoo, so run make dev-install to test Individual ID for each paragraph Don't worry, should be individual inside a file only Copy an existing one and increment

Slide 25

Slide 25 text

25 How to add a new Writer feature? Developer help Use doxygen Document each class – at least a one-liner mission statement Preferably each public method Use bin/find-undocumented-classes Old code uses German comments If you figured out what they mean anyway… … then spend one minute on translating it Use bin/find-german-comments

Slide 26

Slide 26 text

26 How to add a new Writer feature? Specification We should have started with this… or not?

Slide 27

Slide 27 text

27 How to add a new Writer feature? Specification We serialize everything to ODF ODF is an open standard, takes years till it's accepted Catch-22 Solution: we implement first, call it “ODF Extended” Then propose a modification to the standard Ideally: using extension namespaces before it's accepted

Slide 28

Slide 28 text

28 How to add a new Writer feature? ODF JIRA ticket example Rationale: what's the motivation Requested changes to the standard Text changes Schema changes Impacts Backwards compatibility Easy if the new element is optional

Slide 29

Slide 29 text

29 How to add a new Writer feature? All text and image content in this document is licensed under the Creative Commons Attribution-Share Alike 3.0 License (unless otherwise specified). "LibreOffice" and "The Document Foundation" are registered trademarks. Their respective logos and icons are subject to international copyright laws. The use of these therefore is subject to the trademark policy. Thank you … Any questions? Slides: http://vmiklos.hu/odp/