[00:00.000 --> 00:13.440] So this talk will be a follow-up to the one I did at the LibreFist conference last year [00:13.440 --> 00:21.360] in September that was about content controls in write or in general and some of the follow-up [00:21.360 --> 00:28.720] work was expected, some of that was more like a surprise, so a couple of incremental improvements [00:28.720 --> 00:39.120] appeared in the past half year, so it seemed like a good idea to overview where we are compared to [00:41.040 --> 00:48.160] where we were in September. So for those who don't know me, I'm Mikhail Shvindam [00:48.160 --> 00:55.200] and from Hungary, I used to be very much involved in the write or RTF import export [00:55.200 --> 01:02.000] so much these days, but I still focus on write or work for Culebra and [01:04.160 --> 01:11.440] for content controls for the scope of this talk, we talk about these rich tax content controls, [01:12.160 --> 01:20.080] it's like it's for for Finland, we used to have these input fields in write or already [01:20.080 --> 01:27.840] where you can provide some placeholder tax and you can mark that this is the place of the document [01:27.840 --> 01:33.440] where you can type when you fill in some form, but one big limitation of that was that it was [01:33.440 --> 01:39.680] built on fields and fields can't have formatting, so it was really just for plain text and where [01:39.680 --> 01:45.920] write or really shine says more like there can be a rich text, so we want something that provides [01:45.920 --> 01:54.960] rich text, so that's where you can have rich text content controls. The UX mass specification [01:54.960 --> 02:01.520] calls these structured documents tags, but it's really the same thing, they are user interface [02:01.520 --> 02:10.720] calls these content controls, so we also call them content controls, and the way it's structured [02:10.720 --> 02:17.600] is that you can once you have a paragraph text, then you can have multiple text portions inside [02:17.600 --> 02:24.480] that, so let's say you have some text, normal text, then some bold text, and then again normal text, [02:24.480 --> 02:30.480] then we split up the text, paragraph text to three portions, the normal one, the bold one, and again [02:30.480 --> 02:39.040] the normal one, and for fields the restriction was that you can't have multiple of these text [02:39.040 --> 02:45.760] portions inside that's to be filled in, and content controls support this, so you can have [02:45.760 --> 02:52.240] multiple portions, although they are limited to a single paragraph, at least this inline [02:52.240 --> 02:58.880] content controls that I'm talking about, so you can't have a content control starting at some [02:58.880 --> 03:04.720] random point in the document and ending at some random point, perhaps you know that you can do [03:04.720 --> 03:11.280] that with bookmarks, it might start inside the table and outside the table, and fieldmarks can [03:11.280 --> 03:18.240] provide the same thing, content controls are intentionally limited to be inside a single [03:18.240 --> 03:25.200] paragraph, so we enforce that when you create them, we enforce this when you edit them, we [03:25.200 --> 03:33.600] enforce this during exporting to DocEx and ODT, so this is something, this is an invariant [03:33.600 --> 03:40.480] that we want to maintain, another complexity is that it's possible to do nesting for this, [03:41.600 --> 03:48.320] so when you look at how we write this in XML, then XML elements naturally support nesting, [03:48.320 --> 03:55.840] and we call this well-formed nesting, so the outdoor content control starts, and then the [03:55.840 --> 04:01.600] inner one starts, and then it's a requirement that the inner one will finish, and then the [04:01.600 --> 04:09.040] outer one will finish, and so you can do nesting, but you can do these start ones start to finish [04:09.040 --> 04:13.920] them the first and finish the last, similar to what you know from HTML for example, [04:15.520 --> 04:20.400] so we want to support this setup that you can do nesting but not in a random order, [04:21.120 --> 04:27.760] and you can include multiple text portions but not random positions with start and then [04:27.760 --> 04:37.680] bottom constraint that they are in a single program, and if you have fields, then fields [04:37.680 --> 04:42.240] typically have some kind of instruction text like commands, and there is the field result, [04:42.800 --> 04:48.960] content controls are more like annotations and a piece of text, so you have some start and [04:48.960 --> 04:55.120] then you can have a bunch of properties on top of that, we will see you can give it a title, [04:55.120 --> 05:02.080] you can give it an alias, you can define the type and so on, so the rich text is the simplest type [05:02.080 --> 05:09.760] where you just say that you can fill in something here, and if the task is like provide your one [05:09.760 --> 05:16.160] line or command from this for them presentation, then and you say it was really bad, like really, [05:16.160 --> 05:23.040] really, so you select the really and market board because it was really that bad, but you can do [05:23.040 --> 05:30.400] multi-programs, you can't write a novel on how bad that was, so that was a rich text, and [05:35.440 --> 05:43.040] so somehow the picture is missing the top pixels, so you missed the whole point, [05:44.960 --> 05:51.920] but I will explain what you should see there, so it's called, I think the values in the interface [05:51.920 --> 05:57.520] cause this title, but in the markup we call this alias, but it's the same thing, the point is that [05:57.520 --> 06:03.680] you have some complex form and you are supposed to fill in the date, the date and the date and [06:03.680 --> 06:08.400] finally the date, and of course they mean that, that means you are registering your company and [06:08.400 --> 06:14.480] there was a date when you created the company, there was a date when you filed the papers for it, [06:14.480 --> 06:20.960] and there was the date when the first employee was hired and so on, but it's just the date, so [06:20.960 --> 06:26.400] it's very confusing to fill that in, and what content controls can provide is that when you [06:26.400 --> 06:33.520] enter that content control, then there is a small pop-up similar to when you edit headers and you [06:33.520 --> 06:38.560] get the name of the page style and so on, so you get some tooltap explaining what exactly you are [06:38.560 --> 06:45.680] filling in, that might be helpful, so let's say the text would normally just say that you need to [06:45.680 --> 06:53.280] enter information about the, let's say the birth data, but that means that they want the birth [06:53.280 --> 06:58.800] location and the birth date and then when you enter the content control they can give you this hand [06:58.800 --> 07:07.840] so that it's a bit easier, so the output, the field inform might conform to what was expected, [07:07.840 --> 07:14.400] how some regulation is to accept, but when you try to enter it as a more mortal, you are actually [07:14.400 --> 07:20.800] able to fill it in because you don't need to like look up some 10 pages of documentation, [07:20.800 --> 07:26.800] how to fill in that form, you go to the form and you get enough helpful context information so that [07:26.800 --> 07:33.840] you can just do that, so these aliases and tags were initially missing on the right-hand side, [07:33.840 --> 07:43.120] and now we support it, then one other problem was that, I mentioned you can have multiple [07:43.120 --> 07:50.960] text portions inside the single content control, so what you see on the above screenshot is that [07:50.960 --> 07:56.400] we have an x corrector, then a new line break, so we kind of hack it around, technically it's [07:56.400 --> 08:01.920] still a program, a single program, but you see it's on multiple lines, and then we even define [08:01.920 --> 08:08.000] some tab stop and then a tab portion, so technically it's still a single program, but you see that [08:08.000 --> 08:16.880] this is like at least three different text portions, and we used to take each and every text portion [08:16.880 --> 08:22.560] and then it's PDF widgets for that, so in this case when you exported this to PDF and you wanted [08:22.560 --> 08:27.200] to fill in the PDF form, then you got three different widgets, which is a nonsense, this [08:27.200 --> 08:34.880] was not the intention, so in case originally the placeholder text would be multiple portions there, [08:34.880 --> 08:40.880] your right turn, and we still take the bounding rectangle of the content control and just [08:40.880 --> 08:52.400] emit a single widget, as probably the user would expect that, then another thing is the primary [08:52.400 --> 08:59.840] use case we had in mind was that you create some editable writer document, and at the very end [08:59.840 --> 09:05.600] you export that to PDF, and the actual form filling will probably happen in some PDF reader, [09:05.600 --> 09:13.040] but you might also have some slightly different workflow where you mark most of the document [09:13.040 --> 09:20.240] as read only, and then you can have the editable document handed out to users, and they actually [09:20.240 --> 09:25.440] fill in the form in writer, now the trouble is that in case we made the document read only, [09:25.440 --> 09:31.360] then you can't fill in the form because you change this content control, and they are part [09:31.360 --> 09:35.360] of the document, and the whole document is read only, so that content control is also read only, [09:36.080 --> 09:42.000] now this was working with input files before, they had various problems, but this bit was working, [09:42.000 --> 09:47.200] they knew that they are an exception from this general read only thing, so it was possible to [09:47.200 --> 09:56.640] fill in input files, now we do the same, and we can have this setup that the whole document is [09:56.640 --> 10:07.360] read only, but the content control can be still added in. Another thing was that if you look at [10:07.360 --> 10:14.720] what Word provides for VBA, if you want to manipulate these content controls, then they have [10:14.720 --> 10:21.040] an understanding of what is the list of content controls in the document, this can be very handy [10:21.040 --> 10:29.200] in case you want to have some macro that automatically processes the already filled [10:29.200 --> 10:34.880] in document, now there are other ways to do that, but one way is that you write some macro that will [10:34.880 --> 10:40.800] extract all the fielding results from the document, and for that they can just go to the first content [10:40.800 --> 10:46.000] control, the second one query how many content controls you have in the document, but on the [10:46.000 --> 10:50.240] right side this is really just a formatting on a program, so you would have to scan the entire [10:50.240 --> 10:56.080] document to find out if you have any content controls at all, so we don't have this random [10:56.080 --> 11:03.120] access to content controls, until we did not, so initially we ignored this VBA problem, [11:03.840 --> 11:09.040] but when Justin was trying to build a VBA compact layer on top of content controls, [11:09.040 --> 11:13.600] then he found that there is no random access to content controls, so you can't do this [11:14.400 --> 11:18.960] without scanning the whole document, which can be very slow, so this is not great, [11:20.240 --> 11:25.440] and we discovered that actually footnotes already provide this, that's also kind of [11:25.440 --> 11:31.680] formatting on some piece of paragraph text, and that has this manager that will track as footnotes [11:31.680 --> 11:37.200] are created and deleted, and then you can quickly get a list of all the footnotes in the document, [11:37.200 --> 11:44.560] so why can't we do the same for content controls, and yeah you can do that, so now there is some [11:44.560 --> 11:53.200] star basic access, or actually UNO API access, and that's visible with me in basic, and also [11:53.200 --> 11:59.600] there is a VBA compact layer on top of that, where you can query how many content controls you have, [11:59.600 --> 12:08.000] you can, if you fill in these alias things, then you can even say that I want to jump to the birth [12:08.000 --> 12:13.360] date content control, without saying that is the third one, so if you insert something in between, [12:13.360 --> 12:19.760] then it won't break, so this manager provides that, what's necessary here, [12:21.440 --> 12:27.680] another thing was that initially when I was adding drop downs, I wanted to like incrementally extend [12:27.680 --> 12:34.000] what's available in rich text content controls, so the idea was that in case there are list items [12:34.000 --> 12:39.280] for this content control, you know that's then probably a drop down, but there is complexity [12:39.280 --> 12:48.320] there, you can have drop downs, okay, you can have drop downs, and you can have combo boxes, [12:48.320 --> 12:55.520] and it's possible that, and you can't say which one it is, if it has list items, it might be [12:55.520 --> 13:02.000] any of that, and also it turns out it's valid to have a drop down with no items, so that's what [13:02.000 --> 13:07.680] you see there, knows that's working, we explicitly track if that's a combo box or a drop down, and [13:07.680 --> 13:15.120] then you can have both types, we enforce that if it's possible to just choose one item from a [13:15.120 --> 13:21.040] complete list, or you can also have free form tags there, and also in case some existing [13:21.040 --> 13:26.320] document for whatever reason has no list items, then we don't break that, and we don't implicitly [13:26.320 --> 13:32.800] turn that to a rich text content control just because it has no list items. I think this is [13:32.800 --> 13:39.440] the last one, I say Hossain was doing lots of testing on content controls, and of course the [13:39.440 --> 13:47.520] first thing he was trying is some Parisian text, and of course it was breaking, I think it had [13:47.520 --> 13:54.800] three pieces, so one was the positioning, if you have the drop down arrow on the left-hand side now [13:54.800 --> 14:00.800] for archaeal text, that means that if you take the position of the whole bounding rectangle, [14:00.800 --> 14:06.400] then you need to shift that to the left to have the correct position, so fixing up the position [14:06.400 --> 14:14.400] based on the direction of the text frame, so the paragraph is what's one saying, then also what you [14:14.400 --> 14:22.480] were in the render inside the bounding rectangle for the arrow button and for that frame that [14:22.480 --> 14:28.480] needed fixing, and the last thing is that if you see a button, then you might have the silly idea [14:28.480 --> 14:33.360] to click on that button, and you expect that something happens, but we need to do this hit [14:33.360 --> 14:41.280] testing to show, to decide if you clicked on the button or not, and if you do that, then we need [14:41.280 --> 14:48.160] to handle this correctly for RTL versus RTL, so that's no all working, so this is it, there was [14:48.160 --> 14:54.640] some polish since the LibreFist conference is still, what the feature set it provides is still [14:54.640 --> 15:01.520] something that meant to be one-to-one possible to map to the word feature set, we tried to [15:02.640 --> 15:08.400] fully save this to UDF without any loss, you can export that to PDF, there are these various types, [15:08.400 --> 15:15.120] you can see a few types there, and basically more properties are added, some small editing [15:15.120 --> 15:39.120] improvements, and it's a little bit easier to script that now, so that's what we have, thanks for listening.