Sometimes you may find galimatias in the user interface such as quirky captions, misleading descriptions, too long or to short texts, and strings that are not compliant to the guideline. Why not take this as the perfect start into easyhacking?
As explained in the posting on How to set up your environment, you can always search for unique strings. For example, the text „What‘s this?“ from the help menu brings you to the file GenericCommands.xcu where UNO commands are listed (there are also module-specific *.xcu files).
These are XML files containing the commands with the properties
- Label: A localized text that describes the command; will be used instead of ContextLabel, PopupLabel and TooltipLabel if those are not specified.
- ContextLabel: Used for sub-menu entries, and also in popup menus if PopupLabel is not specified. For instance, the command .uno:SetAnchorAtChar is labeled “Anchor to Character” but in the main menu under Format > Anchor the shorter form of ContextLabel is taken.
- PopupLabel: Used in popup menus to give commands a different label than in the main menu. For instance, the UNO command to open the table properties .uno:TableDialog shows “Properties…” in the main menu and “Table Properties” in the context menu.
- TooltipLabel: Used for Tooltips and defaults to PopupLabel, then Label if empty.
(Note: For further information take a look at Commands.xcs; and the fallback mechanism is currently under revision, see tdf#108458)
Labels can have an optional mnemonic (~Save) and can end with ellipsis (Save ~as…) to specify that a dialog will follow. LibreOffice automatically creates a tooltip, if not provided, where the mnemonic and the ellipsis are removed.
Back to the example: You may want to rename „What‘s this?“ to „Show extended tooltip“ and add a tooltip to the function. This would be done by changing the lines in the two mentioned files to
<node oor:name=".uno:ExtendedHelp" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">~Show Extended Tooltip</value>
<prop oor:name="TooltipLabel" oor:type="xs:string">
<value>Enables extended help tips under the mouse pointer till the next click.</value>
<prop oor:name="Properties" oor:type="xs:int">
Figure 1: Example dialog
Another area for strings are dialogs, which are stored in *.ui files. For example, the dialog shown on Table > Insert Table… looks like figure 1, and you may want to change the sloppy „Heading“ to „Use heading“.
To search for Heading likely returns way too many results but “Don‘t _split table over pages“ (with proper apostrophe and including the underscore for the mnemonic!) brings us to the file sw/uiconfig/swriter/ui/inserttable.ui where you easily find the object GtkCheckButton with the id=”headercb” and its label property below. If you want you can add a tooltip there as well.
<property name="label" translatable="yes" context="inserttable|headercb">
<property name="tooltip_text" translatable="yes" context="inserttable|headercbtip">
Specifies whether to insert a heading line for the columns in the text table
Besides any text or XML editor you can also use Glade to change the ui files visually. But in this case please double check that the property translatable=”yes” is still set after saving the file. And don’t forget context=”Foo” if a property has the translatable flag.
Many strings are dynamically inserted per gettext() such as „Page 1 of 2“ in Writer‘s statusbar, or as well the name of artwork such as colors, gradients, bitmaps etc. These strings are stored at different locations, in sw/inc/strings.hrc for the Page example, where modules and controls have specific files.
#define STR_PAGE_COUNT NC_("STR_PAGE_COUNT", "Page %1 of %2")
In case of non-translatable strings, the text would be stored in header files (*.hxx). Be very careful with changing these strings as they are likely used in a hard-coded form and may break backward compatibility.
Adding a translatable string to the code can be done per SvxResId(<ID>) for example (simplified):
sPageCnt = SwResId(STR_PAGE_COUNT);
sPageCnt = sPageCnt.replaceFirst("%1", OUString::number(nPhyNum));
To get the corresponded label from a UNO command you can use this
sCmdLabel = vcl::CommandInfoProvider::GetLabelForCommand( aCommandURL, aModuleName );
Good usability is the trinity of functional scope, clear feedback, and precise terminology. If you have to explain a feature in the tooltip it is likely not well defined, and the same is true for icons where, for example, a compass as illustration for the Navigator is not easy to understand for beginners looking for an overview.
It also affects the user experience when captions are not consistent. Typical example is the title style capitalization that implicitly makes the user expecting a headline (contemporary guidelines ban title style into only the title). Some of the most important advises:
- Start your sentence with the most important objective first.
- Avoid abbreviations such as ampersand instead of “and” or latin “ie” or “eg” instead of “for example”, acronyms, and tech-babble. Keep in mind that text should be read by screen readers.
- Keep information short and concise; avoid redundancy or wordiness. For instance, do not repeat the dialog title in the dialog text.
- Use title style capitalization for titles (e.g. dialog box, toolbars, column headers), button names, icon labels, menu names and commands. (MSDN Guidelines, macOS HIG, Gnome Guideline, KDE HIG)
- Do not capitalize articles (a, an, the), conjunctions (and, but, for, etc.), prepositions less than five letters (on, at, to, from, by, etc).
- Add a colon at the end of the label when introducing a control except for a command button, tab, group box, option button, or check box.
- Do not put periods at the ends of labels, even if the text constitutes a complete sentence.
- Use an ellipsis at the end of a label if further input or confirmation is required.
Last but not least you should keep in mind that it’s easy to change strings in the sources but entails additional work for all translators and for the documentation. Happy hacking Libreoffice!