Last week I wrote a quite long help page on a poorly known feature of LibreOffice aimed to Basic macro programmers.
LibreOffice - since it was named OpenOffice.org long time ago - carried a set of Basic libraries with no documentation (that I was able to find). The libraries were created to support some important features such as Euro conversion or WikiEditor, but also had a set of modules and macro very handy for the ad-hoc or professional Basic programmer of LibreOffice.
The library is distributed in the LibreOffice installers and can be opened in the LibreOffice Macros container, accessible when opening the Basic IDE.
I got fond of the TOOLS library because it has many handy macros that otherwise requires quite a lot of hard code writing and LibreOffice API knowledge even for simple operations.
Things like getting the last used row in a spreadsheet, get the value of a cell, get the filename out of a long URI are the kind of Function's and Sub's we don't want to write again but use GetLastUsedRow, GetValueofCellbyName or FileNameoutofPath for the task.
To use the LibreOffice Tools library , add the statement
GlobalScope.BasicLibraries.LoadLibrary("Tools")
before the first macro of your module. The help page is already online in
https://help.libreoffice.org/6.1/en-US/text/sbasic/shared/03/lib_tools.html
Note that not every library is described in details in the set of Help pages but if you feel motivated to peek in the code and write a simple description of the remaining modules and macros, join our documentation team!
Happy macro programming!
Showing posts with label desenvolvimento. Show all posts
Showing posts with label desenvolvimento. Show all posts
Wednesday, June 20, 2018
Tuesday, May 8, 2018
Bringing Localization to New Help UI
As usual, we have a clear vision of the goal we want to achieve and we know it fits perfectly in the framework available, but sometimes we don't get the smart idea the first time you look at the issue.
It was easy to do the proof of concept for the new help and the style sheet transformations, but in the hurry to get the concept, I used a pair of clutches, or plain bad solution, hoping to be able to come back later.
So time has come to fix the localization of the new Help strings, and to work to use the translation infrastructure of The Document Foundation.
The trick was under my eyes for long time. It is called document() function in XSLT. With the document() function, I can open an external document, and process it while transforming a XML file.
So why not call an auxiliary help file, with all User Interface strings translated, and use the results inside your main transformation? That is what I did in my latest patch, where I created a help file (browserhelp.xhp) with all terms of my User Interface.
So here is an excerpt of the document() function usage in the XSLT:
<!-- Strings for the help UI page -->
<xsl:variable name="tmp_href_ui"><xsl:value-of select="concat($urlpre,'text/shared/help/browserhelp.xhp')"/></xsl:variable>
<xsl:variable name="tmp_doc_ui" select="document($tmp_href_ui)"/>
<xsl:variable name ="ui_contents"><xsl:apply-templates select="$tmp_doc_ui//variable[@id='contents']"/></xsl:variable>
where I get the right location in tmp_href_ui and the document in tmp_doc_ui, and just after I get the string which identifier is 'contents'.
Later, I used the string 'contents' in the page like
<xsl:value-of select="$ui_contents"/>
Voilà. And while we are refactoring, I drop most the the other XSLT I was using as clutch (localized.xsl) and exercised some synapses in using the <xsl:for-each> statement to traverse the list of entries in the languages drop-down selector.
Happy translating!
It was easy to do the proof of concept for the new help and the style sheet transformations, but in the hurry to get the concept, I used a pair of clutches, or plain bad solution, hoping to be able to come back later.
So time has come to fix the localization of the new Help strings, and to work to use the translation infrastructure of The Document Foundation.
The trick was under my eyes for long time. It is called document() function in XSLT. With the document() function, I can open an external document, and process it while transforming a XML file.
So why not call an auxiliary help file, with all User Interface strings translated, and use the results inside your main transformation? That is what I did in my latest patch, where I created a help file (browserhelp.xhp) with all terms of my User Interface.
So here is an excerpt of the document() function usage in the XSLT:
<!-- Strings for the help UI page -->
<xsl:variable name="tmp_href_ui"><xsl:value-of select="concat($urlpre,'text/shared/help/browserhelp.xhp')"/></xsl:variable>
<xsl:variable name="tmp_doc_ui" select="document($tmp_href_ui)"/>
<xsl:variable name ="ui_contents"><xsl:apply-templates select="$tmp_doc_ui//variable[@id='contents']"/></xsl:variable>
where I get the right location in tmp_href_ui and the document in tmp_doc_ui, and just after I get the string which identifier is 'contents'.
Later, I used the string 'contents' in the page like
<xsl:value-of select="$ui_contents"/>
Voilà. And while we are refactoring, I drop most the the other XSLT I was using as clutch (localized.xsl) and exercised some synapses in using the <xsl:for-each> statement to traverse the list of entries in the languages drop-down selector.
Happy translating!
Monday, May 7, 2018
Screenshots in LibreOffice Help
An image worth a thousands words.
Indeed, a textual description of a software feature is too often hard to read, but a simple picture tells much about.
So I patched the LibreOffice Math help pages with screenshots taken by the ScreenShot_Test helper designed by bubli and added them to the help pages. To avoid handling images in too many scattered help files, I collected the in a new help file named screenshots.xhp under /06/ folder of the module. This way, the images are embedded at the right page and if the screenshot has to be modifies, it is enough to edit the screenshot.xhp file instead of the target help file, which by the way can be multiple.
The Math module has only 8 screenshots under the module/ folder so it makes it easy to evaluate the impact on the size of the data. For all the supported languages (--with-lang=ALL) it adds 19M bytes of images.
While I was addressing this patch I also had to fix a folder naming issue with the helper, which bubli was so kind to approve and also a fix in the XSLT to handle the special case of the default language, en-US.
See it at work: https://help.libreoffice.org/6.1/en-US/text/smath/01/05030000.html?&DbPAR=MATH&System=UNIX
Indeed, a textual description of a software feature is too often hard to read, but a simple picture tells much about.
So I patched the LibreOffice Math help pages with screenshots taken by the ScreenShot_Test helper designed by bubli and added them to the help pages. To avoid handling images in too many scattered help files, I collected the in a new help file named screenshots.xhp under /06/ folder of the module. This way, the images are embedded at the right page and if the screenshot has to be modifies, it is enough to edit the screenshot.xhp file instead of the target help file, which by the way can be multiple.
The Math module has only 8 screenshots under the module/ folder so it makes it easy to evaluate the impact on the size of the data. For all the supported languages (--with-lang=ALL) it adds 19M bytes of images.
While I was addressing this patch I also had to fix a folder naming issue with the helper, which bubli was so kind to approve and also a fix in the XSLT to handle the special case of the default language, en-US.
See it at work: https://help.libreoffice.org/6.1/en-US/text/smath/01/05030000.html?&DbPAR=MATH&System=UNIX
Thursday, April 26, 2018
Reworking Special Tables in New Help.
Continuing the enhancement of the new help pages, I made some changes in the XSL transformation and CSS file to remove some special tables and sections. In this case I used CSS properties available in HTML5, such as display:flex; .
Many tables were used to position elements in the page. Depending on the CSS class of the table, the purpose of the table changes. Here are the predefined roles worked so far:
onecell: As the name says, the xml table has only one cell. The html table was replaced by a div and proper css, followed by a line break.
icontable: this type of table type is constructed when the first tablecell contains an image. The html table replacement is rendered row by row by a wrapping div with display: flex; attribute and internal divs for the remaining cells in the row.
howtoget: The section "How to get" has now a wrapping div with display: flex; and flex-direction: columns; to stack the heading and contents divs.
Notes, Tips and Warnings: The special paragraphs were mapped into tables and now are mapped in divs with display:flex;
All divs are also associated with named classes, and therefore the CSS can be tweaked independently.
The remaining tables are left as is but will also undergo some cleanup in the near future.
Happy CSS tweaking!
Many tables were used to position elements in the page. Depending on the CSS class of the table, the purpose of the table changes. Here are the predefined roles worked so far:
onecell: As the name says, the xml table has only one cell. The html table was replaced by a div and proper css, followed by a line break.
icontable: this type of table type is constructed when the first tablecell contains an image. The html table replacement is rendered row by row by a wrapping div with display: flex; attribute and internal divs for the remaining cells in the row.
howtoget: The section "How to get" has now a wrapping div with display: flex; and flex-direction: columns; to stack the heading and contents divs.
Notes, Tips and Warnings: The special paragraphs were mapped into tables and now are mapped in divs with display:flex;
All divs are also associated with named classes, and therefore the CSS can be tweaked independently.
The remaining tables are left as is but will also undergo some cleanup in the near future.
Happy CSS tweaking!
Monday, April 16, 2018
Fixing the switchinline transform for Help
Last week I spend quite amount of time chasing a bug on the new Help XSL transformation (XSLT) to implement the <switchinline> tag of the Help.
The initial idea was to map the <switchinline> into a javascript <switch> which is a straightforward to implement, but since the devil is in the details, I had hard times to realize that I set the output of a XSL transform as html, and when it comes to javascript, assigning a string to the output of the transform brings many issues.
Specifically, I had the issue when approaching an output like
with the output of the <xsl:apply-templates/> call resulting in strings with carriage return, apostrophes and quotes, which can't be put inside a javascript string unless adding a post processing to remove at least the LF and CR characters. So I implemented the <switchinline> inside a outer wrapping <span> and each each <case> content output into an inner <span> tag.
Then I played with the "hidden" attribute, emulating the javascript "case" with logic inside the wrapping <span>.
The initial idea was to map the <switchinline> into a javascript <switch> which is a straightforward to implement, but since the devil is in the details, I had hard times to realize that I set the output of a XSL transform as html, and when it comes to javascript, assigning a string to the output of the transform brings many issues.
Specifically, I had the issue when approaching an output like
<![CDATA[case "MAC" : text = "]]>\
<xsl:apply-templates/>\
<![CDATA[");]]>
with the output of the <xsl:apply-templates/> call resulting in strings with carriage return, apostrophes and quotes, which can't be put inside a javascript string unless adding a post processing to remove at least the LF and CR characters. So I implemented the <switchinline> inside a outer wrapping <span> and each each <case> content output into an inner <span> tag.
<span hidden="true" id="{$auxID}">\
<xsl:apply-templates/>\
</span>
Then I played with the "hidden" attribute, emulating the javascript "case" with logic inside the wrapping <span>.
Wednesday, April 11, 2018
New LibreOffice Help is also an UNO Extension Package
Today I finished a patch for LibreOffice 6.1 that displays the new Help when it is installed as a UNO extension package.
The patch consider the extension valid when the extension is installed (from XPackageInformationProvider service) and the extension version matches the product version. When both situations are true, LibreOffice opens the HTML help pages from the extension in your default browser.
The fall-back logic implemented for LibreOffice help activation is now:
The extension identifier is a critical parameter and is formed with the <locale> of the user interface. No big deal, the identifier will take the shape of <locale>.help.libreoffice.org.
The extension can be assembled from the offline build of the new help. Pass the param --with-help=html to your autogen.input and build the help. Then zip the files needed for your locale.
Preliminary tests indicates that the extension will be of size above 12MB per language. It contains all necessary files for autonomous navigation, that means, all internal links are reachable within the pages of the extension. Media files were added too.
For the next LibreOffice 6.1, you can test master build only and download a temporary Help package from
https://helponline.libreoffice.org/Help_en-US_6.1.oxt
Enjoy!
The patch consider the extension valid when the extension is installed (from XPackageInformationProvider service) and the extension version matches the product version. When both situations are true, LibreOffice opens the HTML help pages from the extension in your default browser.
The fall-back logic implemented for LibreOffice help activation is now:
- The extension help (this one). If not,
- The new help in distribution package format (when it becomes available). If not,
- The old, ancient local help. If not,
- The new online Help.
The extension identifier is a critical parameter and is formed with the <locale> of the user interface. No big deal, the identifier will take the shape of <locale>.help.libreoffice.org.
The extension can be assembled from the offline build of the new help. Pass the param --with-help=html to your autogen.input and build the help. Then zip the files needed for your locale.
Preliminary tests indicates that the extension will be of size above 12MB per language. It contains all necessary files for autonomous navigation, that means, all internal links are reachable within the pages of the extension. Media files were added too.
For the next LibreOffice 6.1, you can test master build only and download a temporary Help package from
https://helponline.libreoffice.org/Help_en-US_6.1.oxt
Enjoy!
Wednesday, September 28, 2011
Sobre desenvolvimento de software livre, o caso LibreOffice
Hoje caí numa página com uma entrevista do Linus Torvalds sobre gerência de projetos em software livre. Fiquei muito satisfeito por ver que minha experiência com a industria de software e do software livre em particular está em fase com a dele.
Cito aqui os trechos mais relevantes. Diz o Linus:
"A primeira coisa é pensar que basta jogar na rede suas coisas e pedir ajuda das pessoas". No software livre, ele afirma: "Não é assim que funciona. Você pode publicar, mas assuma que será você a fazer todo o trabalho, para depois pedir sugestões sobre o que fazer, e não o que as pessoas devem fazer. Talvez elas até ajudem, mas você deve iniciar com a premissa que será você o mantenedor, e quem fará praticamente todo o trabalho". Torvald continua: "Se você começar muito animado pensando que pessoas de todo o mundo se juntarão para fazer um mundo melhor trabalhando em seu projeto, com certeza você não irá muito longe".
Tenho quase 10 anos de vivência no software livre, e iniciei com o OpenOffice.org, na área que eu podia contribuir relacionada a localização do software para o português do Brasil. Hoje eu sei que se algo está para ser feito em software livre, melhor saber fazê-lo por conta própria do que depender da boa vontade das pessoas. Não se trata de desmerecer o colega ou o voluntário. Trata-se de ter a noção real de que software demanda muita energia e entender que é natural que as pessoas tenham suas prioridades, quando estão colaborando. Se fossem contratadas, seria outra história.
Nesse ponto seu projeto tem de acomodar os riscos de não poder contar com a mão de obra que inicialmente se ofereceu para ajudar. Trabalhar com prazos em software livre, com voluntários e sem uma gerência de projeto e de recursos que acomode a deficiência de produtividade de voluntários, é arriscado demais.
Seu projeto de software livre precisa de controlabilidade.
A segunda afirmação de Linus Torvalds refere-se aos usuários e aos desenvolvedores:
" A outra coisa - algo relacionado - que as pessoas parecem não entender, é pensar que somente o código delas importa", diz Linus. "Não. Mesmo que você escreva 100% do código, e mesmo que você seja o melhor programador do mundo e não precisar da ajuda de mais ninguém. a coisa que realmente importa são os usuários de seu código. O código em si não importa; o projeto só é útil se as pessoas assim o acharem".
Minhas palavras para essa observação são as seguintes: O que determina o sucesso de um software livre ou fechado é sua base instalada. E sua base instalada é uma consequência do fato que seu software agradou aos usuário e agregou valor na ponta.
Interessante como esse conceito se aplica ao LibreOffice. A base instalada do LibreOffice é muito grande, prova de seu valor para os usuários. Nesse primeiro ano de existência da The Document Foundation, o LibreOffice sofreu modificações internas que o tornaram muito mais rápido e com melhorias na sua usabilidade. Mas é observando a lista dos desenvolvedores e lendo suas opiniões e trabalho que vejo as palavras de Linus mais aguçadas: temos um time de desenvolvedores de alto calibre, muito ansioso por trabalhar em detalhes, mas que vejo com preocupação o distanciamento das reais necessidades dos usuários.
Tenho visto muitas contribuições para com a velocidade e a facilidade da compilação, algo de muito complexo no processo de desenvolvimento e que visa torná-lo mais simples e acessível a desenvolvedores novatos, mas que nada acrescenta ao produto final e que não chega ao usuário, pelo menos diretamente. Outra posição um tanto mais arrogante talvez, refere-se a pedidos de melhoria ou de novas funcionalidades: os desenvolvedores terminam por chutar a bola de volta para que o usuário consiga por conta própria implementar a funcionalidade ou contratar seu desenvolvimento. Não é uma posição simpática, mesmo sendo realista.
Precisamos romper com o autismo endêmico dos desenvolvedores. Ouvir os usuários e para eles trabalhar.
Subscribe to:
Posts (Atom)





