<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://bayramcicek.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://bayramcicek.github.io/" rel="alternate" type="text/html" /><updated>2025-02-09T17:10:43+00:00</updated><id>https://bayramcicek.github.io/feed.xml</id><title type="html">Bayram Çiçek’s website</title><subtitle>All content written by me is by default released freely under the Public License.</subtitle><author><name>Bayram Çiçek</name></author><entry><title type="html">Final Report - Google Summer of Code 2023 - Search Field in Options</title><link href="https://bayramcicek.github.io/libreoffice-dev/2023/08/26/final-report-2023-gsoc.html" rel="alternate" type="text/html" title="Final Report - Google Summer of Code 2023 - Search Field in Options" /><published>2023-08-26T09:00:00+00:00</published><updated>2023-08-26T09:00:00+00:00</updated><id>https://bayramcicek.github.io/libreoffice-dev/2023/08/26/final-report-2023-gsoc</id><content type="html" xml:base="https://bayramcicek.github.io/libreoffice-dev/2023/08/26/final-report-2023-gsoc.html"><![CDATA[<h3 id="about-project">About project</h3>

<p>LibreOffice is a complex application with a large and growing number of options. It is not easy to find the right needle in the haystack. Like most other complex applications, it will be valuable and useful enhancement to add a search field to the “Tools &gt; Options” dialog that iterates over the various tabs and filters where the search text is found. The <u>Search Field in Options</u> project aims to provide this search functionality in “Tools &gt; Options” page.</p>

<ul>
  <li>Project page: <a href="https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1">https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1</a></li>
  <li>Enhancement request on Bugzilla: <a href="https://bugs.documentfoundation.org/show_bug.cgi?id=49895">https://bugs.documentfoundation.org/show_bug.cgi?id=49895</a></li>
  <li>Patch on Gerrit: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></li>
</ul>

<h3 id="tasks">Tasks</h3>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  Add search field to Options dialog - UI</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  Implement search function</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  Include Options TreeView’s parent and child node names into searching</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  Add <code class="language-plaintext highlighter-rouge">GetAllStrings()</code> method to fetch strings from 69 dialogs step by step</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  Include following element strings into searching:
    <ul class="task-list">
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  labels</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  check buttons</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  radio buttons</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  toggle buttons</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  link buttons</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  buttons</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  Include accessibility elements into searching:
    <ul class="task-list">
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  accessible-names</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  accessible-descriptions</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  tooltip-texts</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  Include option pages from extensions into searching</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  Initialize all dialogs at background if it’s possible (<code class="language-plaintext highlighter-rouge">salhelper::Thread</code> - asynchronously)</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  Initialize all dialogs to get strings properly (not in background - synchronously)
    <ul class="task-list">
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  initialize ~half of them after opening the options</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  and initialize remaining ones after doing a search</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  Update Options TreeView properly after the searching done</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  Expand the first node and select first child-node after search by default</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />  Remove Hyphen (<code class="language-plaintext highlighter-rouge">_</code>) and Tilde (<code class="language-plaintext highlighter-rouge">~</code>) symbols from fetched strings to make the search function work correctly</li>
</ul>

<h3 id="my-work-during-gsoc">My Work during GSoC</h3>

<p>During 13 weeks GSoC program, I added a search field in Options dialog and included the node names and their .ui strings into searching. Since sub-dialogs under the Options are not initialized at startup of Options dialog, it was not possible to access their .ui strings. To overcome this issue we had two options:</p>
<ul>
  <li><b>Option A:</b> <u>Extract .ui strings at build-time and fetch them at run-time</u><br />
This option requires working on file operations, LibreOffice’s build system, makefiles, localization etc. I worked on this option for ~5 weeks but this approach caused a lot of issues that took the project out of its scope. For example, how to deal with localization issue while extracting strings at build-time? This was another big problem…</li>
  <li><b>Option B:</b> <u>Initialize all dialogs in some way and get their strings</u><br />
This option is more understandable and simple. Instructions are clear. No need to worry about localization. No need to work on file operations, extracting and fetching data, working with makefiles etc…</li>
</ul>

<p>When I felt that Option A is just wasting my time (~5 weeks); I switched to Option B where I can -at least- make some progress. The main issue in Option B was initializing all dialogs which takes about 4-8 secs. I tried to initialize them at background but there was some errors on Win10 that I don’t reproduce the issue on my linux machine. Then I tried to see the errors on Win10 with a virtual machine, but it was too slow to test. Therefore I uninstalled Manjaro/Linux (which I’ve been using it more than 1.5 years) from my computer and had to install Win10 (which I last used 6 years ago) on my machine to see the problems in there. There was some visual inconsistencies while initializing sub-dialogs using <code class="language-plaintext highlighter-rouge">salhelper::Thread</code> at background.</p>

<p>After working long hours for weeks meanwhile the time was running out, I decided to initialize almost half of them at Options dialog startup and the remaining ones at the time of searching. In that way, time of initializing process is divided by ~2 which can be acceptable time in some degree in terms of user experience.</p>

<p>There is a single patch on Gerrit for this project: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a>. The patch has more than 30 patchsets and includes “+2255 -47” changes.</p>

<p>The most challenging part was implementing GetAllStrings() function for every ~69 dialogs step by step. Current implementation may not be the best solution for user experience, but at least searching through the numerous options is now possible.</p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/options-dialog-on-Win10.png" alt="options-dialog-on-Win10.png" />
</p>

<h3 id="whats-left-to-do-or-can-be-done">Whats left to do or can be done?</h3>

<p>Following tasks are left and can be implemented after GSoC:</p>
<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  Include accessibility elements into searching:
    <ul class="task-list">
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  accessible-names</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  accessible-descriptions</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  tooltip-texts</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  Include option pages from extensions into searching</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />  Initialize all dialogs at background if it’s possible (<code class="language-plaintext highlighter-rouge">salhelper::Thread</code> - asynchronously)</li>
</ul>

<h3 id="additional-hacks">Additional hacks</h3>

<ul>
  <li>Show modified options with some special indicator (as in KDE settings). (better to discuss this idea in a separate ticket)</li>
  <li>Implement highlighting feature</li>
</ul>

<h3 id="tasks-ill-be-working-on-after-gsoc">Tasks I’ll be working on after GSoC</h3>

<ul>
  <li>improvement on the initialization of the dialogs, maybe it can be possible to initialize them at background without encountering any visual inconsistencies - especially on Windows.</li>
  <li>Implementing the remaining tasks:
    <ul>
      <li>Include accessibility elements into searching</li>
      <li>Include option pages from extensions into searching</li>
    </ul>
  </li>
  <li>If everything works fine I’d like to work on the highlighting feature</li>
  <li>Also it would be prettier if Options dialog have a modified options indicator (as in KDE settings)</li>
</ul>

<h3 id="thanks">Thanks</h3>

<p>I’m very happy that we all reached the end of GSoC. During that time, I know that I had a responsibility for doing everything that I can. Therefore I worked hard and tried to complete as much tasks as I can.</p>

<p>I learned a lot of things during the GSoC. Although GSoC is finished, I will definitely continue to contribute to LibreOffice. I am really happy to be a part of the LibreOffice community and Google Summer of Code. I’m really thankful to LibreOffice and Google for providing us this such a great opportunity which helped me gain this amazing experience!</p>

<p>I always tried to be active on IRC #libreoffice-dev channel, and I want to thank for everybody who helped me about my questions.</p>

<p>And most importantly, greatly thankful to <b><u>Andreas Heinisch</u></b> and <b><u>Heiko Tietze</u></b> who were my mentors throughout the GSoC period. They always guided me everything about my questions. Thank you endlessly for your time and effort. I appreciate that you always motivating and encouraging me in all that I attempt and do. I can never truly express how grateful I am. Your guidance, reviews, help and shared experiences have been invaluable. Thank you very much for everything.</p>

<p>I’d like to express my gratitude to everyone in the LibreOffice community for their help and kindness. They always tried to answer my questions on IRC. I fell very lucky to work with this amazing community. I have learned a lot from you and I will never forget this wonderful experience.</p>

<p align="right">
<i>Regards,<br />
Bayram Çiçek</i>
</p>

<p><strong>All weekly GSoC reports:</strong></p>

<ul>
  <li>26 Aug 2023   <a href="https://bayramcicek.github.io/libreoffice-dev/2023/08/26/final-report-2023-gsoc.html">Final Report - Google Summer of Code 2023 - Search Field in Options</a></li>
  <li>14 Aug 2023   <a href="https://bayramcicek.github.io/libreoffice-dev/2023/08/14/week-07-11-gsoc-report.html">Week #7 - #11 - GSoC 2023 Weekly Report - Search Field in Options</a></li>
  <li>08 Jul 2023   <a href="https://bayramcicek.github.io/libreoffice-dev/2023/07/08/week-05-06-gsoc-report.html">Week #5 and #6 - GSoC 2023 Weekly Report - Search Field in Options</a></li>
  <li>26 Jun 2023   <a href="https://bayramcicek.github.io/libreoffice-dev/2023/06/26/week-04-gsoc-report.html">Week #4 - GSoC 2023 Weekly Report - Search Field in Options</a></li>
  <li>18 Jun 2023   <a href="https://bayramcicek.github.io/libreoffice-dev/2023/06/18/week-03-gsoc-report.html">Week #3 - GSoC 2023 Weekly Report - Search Field in Options</a></li>
  <li>10 Jun 2023   <a href="https://bayramcicek.github.io/libreoffice-dev/2023/06/10/week-02-gsoc-report.html">Week #2 - GSoC 2023 Weekly Report - Search Field in Options</a></li>
  <li>03 Jun 2023   <a href="https://bayramcicek.github.io/libreoffice-dev/2023/06/03/week-01-gsoc-report.html">Week #1 - GSoC 2023 Weekly Report - Search Field in Options</a></li>
  <li>18 May 2023   <a href="https://bayramcicek.github.io/libreoffice-dev/2023/05/18/gsoc-timeline.html">Google Summer of Code 2023 Timeline - Search Field in Options</a></li>
</ul>

<p><strong>Useful links:</strong></p>

<ul>
  <li><a href="https://gerrit.libreoffice.org/q/owner:bayramcicek2125%2540gmail.com">https://gerrit.libreoffice.org/q/owner:bayramcicek2125%2540gmail.com</a> (my all contributions to LibreOffice)</li>
  <li><a href="https://translations.documentfoundation.org/user/bayramcicek/">https://translations.documentfoundation.org/user/bayramcicek/</a> (my translations in LibreOffice)</li>
  <li><a href="https://bayramcicek.github.io/libreoffice/">https://bayramcicek.github.io/libreoffice/</a> (all blog posts related to LibreOffice development)</li>
  <li><a href="https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1">https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1</a> (Google Summer of Code - Project page)</li>
</ul>

<h4 align="right"><i># free as in freedom</i></h4>]]></content><author><name>Bayram Çiçek</name></author><category term="libreoffice-dev" /><summary type="html"><![CDATA[About project]]></summary></entry><entry><title type="html">Week #7 - #11 - GSoC 2023 Weekly Report - Search Field in Options</title><link href="https://bayramcicek.github.io/libreoffice-dev/2023/08/14/week-07-11-gsoc-report.html" rel="alternate" type="text/html" title="Week #7 - #11 - GSoC 2023 Weekly Report - Search Field in Options" /><published>2023-08-14T09:18:00+00:00</published><updated>2023-08-14T09:18:00+00:00</updated><id>https://bayramcicek.github.io/libreoffice-dev/2023/08/14/week-07-11-gsoc-report</id><content type="html" xml:base="https://bayramcicek.github.io/libreoffice-dev/2023/08/14/week-07-11-gsoc-report.html"><![CDATA[<p><em>Thanks to my ‘Search Field in Options’ project mentors <u>Andreas Heinisch</u> and <u>Heiko Tietze</u> for their time and guidance.</em></p>

<h3 id="project-report-for-week-7---11">Project Report for Week #7 - #11</h3>

<ul>
  <li>
    <p>A lot of new patchsets submitted (between patchset 10 and 19): <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></p>
  </li>
  <li>
    <p>We decided to implement Plan B(initialize all strings at Options dialog start-up) instead of “extracting strings at build-time” approach.</p>
  </li>
  <li>
    <p>all (visible) strings of 69 dialogs included in searching. Currently:</p>
    <ul>
      <li>labels,</li>
      <li>check buttons,</li>
      <li>radio buttons and</li>
      <li>buttons are included.</li>
    </ul>
  </li>
</ul>

<p>TODO: add accessible-names, accessible-descriptions and tooltip-texts into searching.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">GetAllStrings()</code> function returns all visible strings. e.g.:</li>
</ul>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="n">OUString</span> <span class="n">ScTpFormulaOptions</span><span class="o">::</span><span class="n">GetAllStrings</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">OUString</span> <span class="n">sAllStrings</span><span class="p">;</span>
    <span class="n">OUString</span> <span class="n">labels</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"label1"</span><span class="p">,</span> <span class="s">"formulasyntaxlabel"</span><span class="p">,</span>
                          <span class="s">"label3"</span><span class="p">,</span> <span class="s">"label6"</span><span class="p">,</span>
                          <span class="s">"label7"</span><span class="p">,</span> <span class="s">"label8"</span><span class="p">,</span>
                          <span class="s">"label2"</span><span class="p">,</span> <span class="s">"label4"</span><span class="p">,</span>
                          <span class="s">"label9"</span><span class="p">,</span> <span class="s">"label10"</span> <span class="p">};</span>

    <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">label</span> <span class="o">:</span> <span class="n">labels</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">m_xBuilder</span><span class="o">-&gt;</span><span class="n">weld_label</span><span class="p">(</span><span class="n">label</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">is_visible</span><span class="p">())</span>
            <span class="n">sAllStrings</span> <span class="o">+=</span> <span class="n">m_xBuilder</span><span class="o">-&gt;</span><span class="n">weld_label</span><span class="p">(</span><span class="n">label</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">get_label</span><span class="p">()</span> <span class="o">+</span> <span class="n">OUString</span><span class="p">(</span><span class="sc">' '</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="n">OUString</span> <span class="n">radioButton</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"calcdefault"</span><span class="p">,</span> <span class="s">"calccustom"</span> <span class="p">};</span>

    <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">radio</span> <span class="o">:</span> <span class="n">radioButton</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">m_xBuilder</span><span class="o">-&gt;</span><span class="n">weld_radio_button</span><span class="p">(</span><span class="n">radio</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">is_visible</span><span class="p">())</span>
            <span class="n">sAllStrings</span> <span class="o">+=</span> <span class="n">m_xBuilder</span><span class="o">-&gt;</span><span class="n">weld_radio_button</span><span class="p">(</span><span class="n">radio</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">get_label</span><span class="p">()</span> <span class="o">+</span> <span class="n">OUString</span><span class="p">(</span><span class="sc">' '</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="n">OUString</span> <span class="n">button</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"reset"</span><span class="p">,</span> <span class="s">"details"</span> <span class="p">};</span>

    <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">btn</span> <span class="o">:</span> <span class="n">button</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">m_xBuilder</span><span class="o">-&gt;</span><span class="n">weld_button</span><span class="p">(</span><span class="n">btn</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">is_visible</span><span class="p">())</span>
            <span class="n">sAllStrings</span> <span class="o">+=</span> <span class="n">m_xBuilder</span><span class="o">-&gt;</span><span class="n">weld_button</span><span class="p">(</span><span class="n">btn</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">get_label</span><span class="p">()</span> <span class="o">+</span> <span class="n">OUString</span><span class="p">(</span><span class="sc">' '</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="c1">// check button</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">mxCbEnglishFuncName</span><span class="o">-&gt;</span><span class="n">is_visible</span><span class="p">())</span>
        <span class="n">sAllStrings</span> <span class="o">+=</span> <span class="n">mxCbEnglishFuncName</span><span class="o">-&gt;</span><span class="n">get_label</span><span class="p">()</span> <span class="o">+</span> <span class="n">OUString</span><span class="p">(</span><span class="sc">' '</span><span class="p">);</span>

    <span class="k">return</span> <span class="n">sAllStrings</span><span class="p">.</span><span class="n">replaceAll</span><span class="p">(</span><span class="s">"_"</span><span class="p">,</span> <span class="s">""</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>

<p><br /></p>
<ul>
  <li>Some screenshots from the development</li>
</ul>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-07-11-0-writer-basic-fonts.png" alt="w-07-11-0-writer-basic-fonts.png" title="writer-basic-fonts" />
</p>
<p><br /></p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-07-11-1-writer-color.png" alt="w-07-11-1-writer-color.png" title="writer-color" />
</p>
<p><br /></p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-07-11-2-writer-general.png" alt="w-07-11-2-writer-general.png" title="writer-general" />
</p>
<p><br /></p>

<h3 id="summary">Summary</h3>

<ul>
  <li>New patchsets submitted (between patchset 10 and 19): <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></li>
  <li>Implementation of Plan B is completed. (initialize all strings at Options dialog start-up)</li>
  <li>all (visible) strings of 69 dialogs included in searching.:
    <ul>
      <li>labels,</li>
      <li>check buttons,</li>
      <li>radio buttons and</li>
      <li>buttons are included.</li>
    </ul>
  </li>
</ul>

<p align="center">
    ***
</p>

<p>Patch: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></p>

<p>Project Mentors: <u>Andreas Heinisch</u> and <u>Heiko Tietze</u> (Thanks for their time and guidance)</p>

<p>GSoC project page: <a href="https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1">https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1</a></p>

<p>Enhancement request on Bugzilla: <a href="https://bugs.documentfoundation.org/show_bug.cgi?id=49895">https://bugs.documentfoundation.org/show_bug.cgi?id=49895</a></p>]]></content><author><name>Bayram Çiçek</name></author><category term="libreoffice-dev" /><summary type="html"><![CDATA[Thanks to my ‘Search Field in Options’ project mentors Andreas Heinisch and Heiko Tietze for their time and guidance.]]></summary></entry><entry><title type="html">How to clang-format LibreOffice code-base only for selected code piece(s) - VSCode</title><link href="https://bayramcicek.github.io/libreoffice-dev/2023/07/08/clang-format-lo-code-base.html" rel="alternate" type="text/html" title="How to clang-format LibreOffice code-base only for selected code piece(s) - VSCode" /><published>2023-07-08T19:16:00+00:00</published><updated>2023-07-08T19:16:00+00:00</updated><id>https://bayramcicek.github.io/libreoffice-dev/2023/07/08/clang-format-lo-code-base</id><content type="html" xml:base="https://bayramcicek.github.io/libreoffice-dev/2023/07/08/clang-format-lo-code-base.html"><![CDATA[<p>According to <a href="https://wiki.documentfoundation.org/Development/clang-format">https://wiki.documentfoundation.org/Development/clang-format</a>:</p>

<figure class="highlight"><pre><code class="language-console" data-lang="console"><span class="gp">$</span><span class="w"> </span>wget https://dev-www.libreoffice.org/bin/clang-format-5.0.0-linux64
<span class="gp">$</span><span class="w"> </span><span class="nb">chmod</span> +x clang-format-5.0.0-linux64
<span class="gp">$</span><span class="w"> </span><span class="nb">sudo mkdir</span> <span class="nt">-p</span> /opt/lo/bin/
<span class="gp">$</span><span class="w"> </span><span class="nb">sudo cp </span>clang-format-5.0.0-linux64 /opt/lo/bin/clang-format</code></pre></figure>

<p>Then, to reformat the whole file:</p>

<figure class="highlight"><pre><code class="language-console" data-lang="console"><span class="gp">$</span><span class="w"> </span>/opt/lo/bin/clang-format <span class="nt">-i</span> path/to/thefile.cxx</code></pre></figure>

<p>We can reformat a file easily. But what if we want to do clang-format only for a specific code-piece(s) (e.g. a function, class, if-else …) instead?</p>

<p>On <code class="language-plaintext highlighter-rouge">VSCode</code> (Linux):</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">File</code> &gt; <code class="language-plaintext highlighter-rouge">Preferences</code> &gt; <code class="language-plaintext highlighter-rouge">Settings</code>.</li>
  <li>Search for <code class="language-plaintext highlighter-rouge">clang-format</code>.</li>
  <li>in <code class="language-plaintext highlighter-rouge">C_Cpp: Clang_format_path</code> section, set the path of the clang-format executable as <code class="language-plaintext highlighter-rouge">/opt/lo/bin/clang-format</code>.</li>
</ul>

<p>For example, let’s only select the if statement here:</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="p">...</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">PageIdToFileNameMap_Impl</span><span class="o">&amp;</span> <span class="n">rEntry</span> <span class="o">:</span> <span class="n">FileMap_Impl</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span>    <span class="p">(</span>        <span class="n">rEntry</span><span class="p">.</span><span class="n">m_nPageId</span> <span class="o">==</span> <span class="n">nPageId</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="n">OStringToOUString</span><span class="p">(</span><span class="cm">/*...*/</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">...</span></code></pre></figure>

<p><br />
Then <code class="language-plaintext highlighter-rouge">right click</code> on the selection and select <code class="language-plaintext highlighter-rouge">Format Selection</code>:</p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/format-selection-dialog-vscode.png" alt="format-selection-dialog-vscode.png" title="format-selection-dialog-vscode" />
</p>
<p><br /></p>

<p>Finally, formatting only for if statement should work:</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="p">...</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">PageIdToFileNameMap_Impl</span><span class="o">&amp;</span> <span class="n">rEntry</span> <span class="o">:</span> <span class="n">FileMap_Impl</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">rEntry</span><span class="p">.</span><span class="n">m_nPageId</span> <span class="o">==</span> <span class="n">nPageId</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="n">OStringToOUString</span><span class="p">(</span><span class="cm">/*...*/</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">...</span></code></pre></figure>]]></content><author><name>Bayram Çiçek</name></author><category term="libreoffice-dev" /><summary type="html"><![CDATA[According to https://wiki.documentfoundation.org/Development/clang-format:]]></summary></entry><entry><title type="html">Week #5 and #6 - GSoC 2023 Weekly Report - Search Field in Options</title><link href="https://bayramcicek.github.io/libreoffice-dev/2023/07/08/week-05-06-gsoc-report.html" rel="alternate" type="text/html" title="Week #5 and #6 - GSoC 2023 Weekly Report - Search Field in Options" /><published>2023-07-08T11:39:00+00:00</published><updated>2023-07-08T11:39:00+00:00</updated><id>https://bayramcicek.github.io/libreoffice-dev/2023/07/08/week-05-06-gsoc-report</id><content type="html" xml:base="https://bayramcicek.github.io/libreoffice-dev/2023/07/08/week-05-06-gsoc-report.html"><![CDATA[<p><em>Thanks to my ‘Search Field in Options’ project mentors <u>Andreas Heinisch</u> and <u>Heiko Tietze</u> for their time and guidance. Additionally, thanks to <u>Christian Lohmaier</u> for his reviews and comments about text extraction and makefiles.</em></p>

<h3 id="project-report-for-week-5-and-6">Project Report for Week #5 and #6</h3>

<ul>
  <li>
    <p>New patchsets submitted (between patchset 5 and 10): <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></p>
  </li>
  <li>
    <p>Modified uiex python script to generate ui strings.</p>
  </li>
</ul>

<p>I removed the <code class="language-plaintext highlighter-rouge">./solenv/bin/uiex_options</code> script that almost the same with <code class="language-plaintext highlighter-rouge">./solenv/bin/uiex</code>. Instead of creating a new script, adding an additional option to the existing uiex script -to only print the msgid instead of the full entry-, is better than a different file.</p>

<p><code class="language-plaintext highlighter-rouge">./solenv/bin/uiex</code>:</p>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="p">...</span>

<span class="k">if</span> <span class="p">(</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s">"getString"</span><span class="p">)</span> <span class="p">):</span>
    <span class="n">mode</span> <span class="o">=</span> <span class="s">"w"</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">mode</span> <span class="o">=</span> <span class="s">"a"</span>

<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">ofile</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span> <span class="k">as</span> <span class="n">output</span><span class="p">:</span>
    <span class="nb">input</span> <span class="o">=</span> <span class="n">check_output</span><span class="p">([</span><span class="s">"xgettext"</span><span class="p">,</span> <span class="s">"--add-comments"</span><span class="p">,</span> <span class="s">"--no-wrap"</span><span class="p">,</span> <span class="n">ifile</span><span class="p">,</span> <span class="s">"-o"</span><span class="p">,</span> <span class="s">"-"</span><span class="p">],</span> <span class="n">encoding</span><span class="o">=</span><span class="s">"UTF-8"</span><span class="p">)</span>
    <span class="n">po</span> <span class="o">=</span> <span class="n">polib</span><span class="p">.</span><span class="n">pofile</span><span class="p">(</span><span class="nb">input</span><span class="p">)</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">po</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">""</span><span class="p">,</span> <span class="nb">file</span><span class="o">=</span><span class="n">output</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">po</span><span class="p">:</span>
            <span class="c1"># skip 'stock' entries like "cancel", "help", "ok", etc
</span>            <span class="c1"># l10ntools/source/localize.cxx will insert one entry for each stock per .po
</span>            <span class="k">if</span> <span class="n">entry</span><span class="p">.</span><span class="n">msgctxt</span> <span class="o">==</span> <span class="s">"stock"</span><span class="p">:</span>
                <span class="k">continue</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">mode</span> <span class="o">==</span> <span class="s">"a"</span><span class="p">):</span>
                <span class="n">keyid</span> <span class="o">=</span> <span class="n">entry</span><span class="p">.</span><span class="n">msgctxt</span> <span class="o">+</span> <span class="s">'|'</span> <span class="o">+</span> <span class="n">entry</span><span class="p">.</span><span class="n">msgid</span>
                <span class="k">print</span><span class="p">(</span><span class="s">'#. '</span> <span class="o">+</span> <span class="n">polib</span><span class="p">.</span><span class="n">genKeyId</span><span class="p">(</span><span class="n">keyid</span><span class="p">),</span> <span class="nb">file</span><span class="o">=</span><span class="n">output</span><span class="p">)</span>

            <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">occurrence</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">entry</span><span class="p">.</span><span class="n">occurrences</span><span class="p">):</span>
                <span class="n">entry</span><span class="p">.</span><span class="n">occurrences</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">occurrence</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">os</span><span class="p">.</span><span class="n">environ</span><span class="p">[</span><span class="s">'SRCDIR'</span><span class="p">]),</span> <span class="n">occurrence</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>

            <span class="k">if</span> <span class="p">(</span><span class="n">mode</span> <span class="o">==</span> <span class="s">"a"</span><span class="p">):</span>
                <span class="k">print</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="nb">file</span><span class="o">=</span><span class="n">output</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">print</span><span class="p">(</span><span class="n">entry</span><span class="p">.</span><span class="n">msgid</span><span class="p">,</span> <span class="nb">file</span><span class="o">=</span><span class="n">output</span><span class="p">)</span></code></pre></figure>

<p><br /></p>
<ul>
  <li>Search function now removes the child-nodes that do not match with the search term.</li>
</ul>

<p>The search function now gives better results than the previous version.</p>

<p><br /></p>
<p align="center">
<b>Before:</b> (All child-nodes are shown - which is very confusing)
</p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-05-06-0-japanese-search-before.png" alt="w-05-06-0-japanese-search-before.png" title="japanese search results - before" />
</p>
<p><br /></p>

<p><br /></p>
<p align="center">
<b>After:</b> (Child-nodes that do not match with the search term are removed. thus, better results!)
</p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-05-06-1-japanese-search-after.png" alt="w-05-06-1-japanese-search-after.png" title="japanese search results - after" />
</p>
<p><br /></p>

<ul>
  <li>
    <p>Refactored the code with clang-format.</p>
  </li>
  <li>
    <p>Search field now goes into focus when Options dialog opens.</p>
  </li>
</ul>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="p">...</span>
<span class="n">m_xSearchEdit</span><span class="o">-&gt;</span><span class="n">grab_focus</span><span class="p">();</span>
<span class="n">SelectHdl_Impl</span><span class="p">();</span></code></pre></figure>

<ul>
  <li>Finally, first node expands itself and selects its first child automatically after the search done.</li>
</ul>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp">    <span class="c1">// select first child of first node after the search done</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">nMatchFound</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">weld</span><span class="o">::</span><span class="n">TreeIter</span><span class="o">&gt;</span> <span class="n">xEntry</span><span class="p">;</span>

        <span class="p">{</span>
            <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">weld</span><span class="o">::</span><span class="n">TreeIter</span><span class="o">&gt;</span> <span class="n">xTemp</span> <span class="o">=</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">make_iterator</span><span class="p">();</span>
            <span class="kt">bool</span> <span class="n">bTemp</span> <span class="o">=</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">get_iter_first</span><span class="p">(</span><span class="o">*</span><span class="n">xTemp</span><span class="p">);</span>
            <span class="k">while</span> <span class="p">(</span><span class="n">bTemp</span><span class="p">)</span>
            <span class="p">{</span>
                <span class="c1">// select only the first child</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">get_iter_depth</span><span class="p">(</span><span class="o">*</span><span class="n">xTemp</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">get_id</span><span class="p">(</span><span class="o">*</span><span class="n">xTemp</span><span class="p">).</span><span class="n">toInt64</span><span class="p">())</span>
                <span class="p">{</span>
                    <span class="n">xEntry</span> <span class="o">=</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">make_iterator</span><span class="p">(</span><span class="n">xTemp</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
                    <span class="k">break</span><span class="p">;</span>
                <span class="p">}</span>
                <span class="n">bTemp</span> <span class="o">=</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">iter_next</span><span class="p">(</span><span class="o">*</span><span class="n">xTemp</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">xEntry</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">xEntry</span> <span class="o">=</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">make_iterator</span><span class="p">();</span>
            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">get_iter_first</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">)</span> <span class="o">||</span> <span class="o">!</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">iter_next</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">))</span>
                <span class="n">xEntry</span><span class="p">.</span><span class="n">reset</span><span class="p">();</span>
        <span class="p">}</span>

        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">xEntry</span><span class="p">)</span>
            <span class="k">return</span><span class="p">;</span>

        <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">weld</span><span class="o">::</span><span class="n">TreeIter</span><span class="o">&gt;</span> <span class="n">xParent</span><span class="p">(</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">make_iterator</span><span class="p">(</span><span class="n">xEntry</span><span class="p">.</span><span class="n">get</span><span class="p">()));</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">iter_parent</span><span class="p">(</span><span class="o">*</span><span class="n">xParent</span><span class="p">);</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">expand_row</span><span class="p">(</span><span class="o">*</span><span class="n">xParent</span><span class="p">);</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">scroll_to_row</span><span class="p">(</span><span class="o">*</span><span class="n">xParent</span><span class="p">);</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">scroll_to_row</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">);</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">set_cursor</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">);</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">select</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">);</span>
        <span class="n">SelectHdl_Impl</span><span class="p">();</span>
    <span class="p">}</span></code></pre></figure>

<p><br /></p>
<ul>
  <li>Some screenshots from the development</li>
</ul>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-05-06-2-console-debug-nodes.png" alt="w-05-06-2-console-debug-nodes.png" title="console-debug-nodes" />
</p>
<p><br /></p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-05-06-3-fonts-search-results.png" alt="w-05-06-3-fonts-search-results.png" title="fonts-search-results" />
</p>
<p><br /></p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-05-06-4-writer-grid-search-results.png" alt="w-05-06-4-writer-grid-search-results.png" title="writer-grid-search-results" />
</p>
<p><br /></p>

<h3 id="summary">Summary</h3>

<ul>
  <li>New patchsets submitted (between patchset 5 and 10): <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></li>
  <li>Modified uiex python script to generate ui strings.</li>
  <li>Search function now removes the child-nodes that do not match with the search term.
    <ul>
      <li>The search function now gives better results than the previous version.</li>
    </ul>
  </li>
  <li>Refactored the code with clang-format.</li>
  <li>Search field now goes into focus when Options dialog opens.</li>
  <li>Finally, first node expands itself and selects its first child automatically after the search done.</li>
</ul>

<p align="center">
    ***
</p>

<p>Steps for implementing search functionality in “Tools &gt; Options”:</p>

<table style="width:100%">
    <tbody>
        <tr>
            <td style="width:75%">1) Add Search field to “Tools &gt; Options” dialog.</td>
            <td colspan="2"><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>2) Include Options treeview into searching.</td>
            <td colspan="2"><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>3) Include Sub-tree elements (child nodes) into searching.</td>
            <td><b>DONE - week #2</b></td>
        </tr>
        <tr>
            <td>4) Generate all strings(labels), accessible-names, accessible-descriptions and tooltip-texts of all .ui files in ./cui/* directory, at build-time.</td>
            <td><b>DONE - week #3, #4 (most challenging part)</b></td>
        </tr>
        <tr>
            <td>5) Fetch the generated data - at run-time.</td>
            <td><b>DONE - week #3, #4</b></td>
        </tr>
        <tr>
            <td>6) Include strings(labels), accessible-names, accessible-descriptions and tooltip-texts into searching.</td>
            <td><b>DONE - week #3, #4</b></td>
        </tr>
        <tr>
            <td>7) Refactoring the code-base and trying to fix some issues.</td>
            <td><b>now</b></td>
        </tr>
        <tr>
            <td>8) Implement highlighting feature.</td>
            <td><b>next step</b></td>
        </tr>
        <tr>
            <td>...</td>
            <td><b>...</b></td>
        </tr>
    </tbody>
</table>

<p align="center">
    ***
</p>

<p>Patch: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></p>

<p>Project Mentors: <u>Andreas Heinisch</u> and <u>Heiko Tietze</u> (Thanks for their time and guidance)</p>

<p>GSoC project page: <a href="https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1">https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1</a></p>

<p>Enhancement request on Bugzilla: <a href="https://bugs.documentfoundation.org/show_bug.cgi?id=49895">https://bugs.documentfoundation.org/show_bug.cgi?id=49895</a></p>]]></content><author><name>Bayram Çiçek</name></author><category term="libreoffice-dev" /><summary type="html"><![CDATA[Thanks to my ‘Search Field in Options’ project mentors Andreas Heinisch and Heiko Tietze for their time and guidance. Additionally, thanks to Christian Lohmaier for his reviews and comments about text extraction and makefiles.]]></summary></entry><entry><title type="html">Week #4 - GSoC 2023 Weekly Report - Search Field in Options</title><link href="https://bayramcicek.github.io/libreoffice-dev/2023/06/26/week-04-gsoc-report.html" rel="alternate" type="text/html" title="Week #4 - GSoC 2023 Weekly Report - Search Field in Options" /><published>2023-06-26T05:38:00+00:00</published><updated>2023-06-26T05:38:00+00:00</updated><id>https://bayramcicek.github.io/libreoffice-dev/2023/06/26/week-04-gsoc-report</id><content type="html" xml:base="https://bayramcicek.github.io/libreoffice-dev/2023/06/26/week-04-gsoc-report.html"><![CDATA[<p><em>Thanks to my ‘Search Field in Options’ project mentors <u>Andreas Heinisch</u> and <u>Heiko Tietze</u> for their time and guidance. Additionally, thanks to <u>Caolán McNamara</u> for giving me the ‘generating ui strings at build-time’ idea.</em></p>

<h3 id="project-report-for-week-4">Project Report for Week #4</h3>

<ul>
  <li>
    <p>New patchset submitted: <a href="https://gerrit.libreoffice.org/c/core/+/152519/4">https://gerrit.libreoffice.org/c/core/+/152519/4</a></p>
  </li>
  <li>
    <p>Added new python script to generate ui strings</p>
  </li>
</ul>

<p>I added new python script called <code class="language-plaintext highlighter-rouge">./solenv/bin/uiex_options</code> to extract strings(<code class="language-plaintext highlighter-rouge">labels</code>, <code class="language-plaintext highlighter-rouge">accessible-names</code>, <code class="language-plaintext highlighter-rouge">accessible-descriptions</code> and <code class="language-plaintext highlighter-rouge">tooltip-texts</code>) from ui files. This script is almost the same with <code class="language-plaintext highlighter-rouge">./solenv/bin/uiex</code>. The only difference is the new script extracts only <code class="language-plaintext highlighter-rouge">entry.msgid</code> which contains the strings we need. Any other outputs like <code class="language-plaintext highlighter-rouge">entry.msgctxt</code> is not needed so I kept only <code class="language-plaintext highlighter-rouge">entry.msgid</code> in the new script.</p>

<p>For example <code class="language-plaintext highlighter-rouge">./solenv/bin/uiex</code> script:</p>
<pre>
$ ./solenv/bin/uiex -i ./cui/uiconfig/ui/optopenclpage.ui -o output.txt
</pre>

<p>will extract:</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="cp">#. QYxCN
#: ../cui/uiconfig/ui/optopenclpage.ui:24
</span><span class="n">msgctxt</span> <span class="s">"optopenclpage|useopencl"</span>
<span class="n">msgid</span> <span class="s">"Allow use of OpenCL"</span>
<span class="n">msgstr</span> <span class="s">""</span>

<span class="cp">#. MAc4P
#: ../cui/uiconfig/ui/optopenclpage.ui:41
</span><span class="n">msgctxt</span> <span class="s">"optopenclpage|openclused"</span>
<span class="n">msgid</span> <span class="s">"OpenCL is available for use."</span>
<span class="n">msgstr</span> <span class="s">""</span>

<span class="cp">#. fAEQH
#: ../cui/uiconfig/ui/optopenclpage.ui:53
</span><span class="n">msgctxt</span> <span class="s">"optopenclpage|openclnotused"</span>
<span class="n">msgid</span> <span class="s">"OpenCL is not used."</span>
<span class="n">msgstr</span> <span class="s">""</span>

<span class="cp">#. xWE5i
#: ../cui/uiconfig/ui/optopenclpage.ui:67
</span><span class="n">msgctxt</span> <span class="s">"optopenclpage|label1"</span>
<span class="n">msgid</span> <span class="s">"OpenCL Options"</span>
<span class="n">msgstr</span> <span class="s">""</span></code></pre></figure>

<p>But we only need strings inside <code class="language-plaintext highlighter-rouge">msgid</code> here. Others are not needed.</p>

<p><code class="language-plaintext highlighter-rouge">./solenv/bin/uiex_options</code> extracts only strings inside <code class="language-plaintext highlighter-rouge">msgid</code>:</p>

<pre>
$ ./solenv/bin/uiex_options -i ./cui/uiconfig/ui/optopenclpage.ui -o output.txt
</pre>

<p>will extract:</p>
<pre>
Allow use of OpenCL
OpenCL is available for use.
OpenCL is not used.
OpenCL Options
</pre>

<p><br /></p>
<ul>
  <li>Extraction at build-time</li>
</ul>

<p>Added all ui files that belong to Options dialog, inside <code class="language-plaintext highlighter-rouge">cui/UIConfig_cui.mk</code> file:</p>

<figure class="highlight"><pre><code class="language-console" data-lang="console"><span class="gp">$</span><span class="o">(</span><span class="nb">eval</span> <span class="si">$(</span>call gb_UIConfig_generate_options_uifiles,cui/uiconfig/uioptions, <span class="se">\</span>
<span class="go">    cui/uiconfig/ui/optuserpage \
    cui/uiconfig/ui/optgeneralpage \
    cui/uiconfig/ui/optviewpage \
    cui/uiconfig/ui/optpathspage \
    cui/uiconfig/ui/optfontspage \
    cui/uiconfig/ui/optsecuritypage \
    cui/uiconfig/ui/personalization_tab \
    cui/uiconfig/ui/optappearancepage \
    cui/uiconfig/ui/optaccessibilitypage \
    cui/uiconfig/ui/optadvancedpage \
    cui/uiconfig/ui/optbasicidepage \
    cui/uiconfig/ui/optonlineupdatepage \
    cui/uiconfig/ui/optopenclpage \
    cui/uiconfig/ui/optlanguagespage \
    cui/uiconfig/ui/optlingupage \
    cui/uiconfig/ui/optjsearchpage \
    cui/uiconfig/ui/optasianpage \
    cui/uiconfig/ui/optctlpage \
    cui/uiconfig/ui/langtoolconfigpage \
    cui/uiconfig/ui/optdeeplpage \
    cui/uiconfig/ui/optproxypage \
    cui/uiconfig/ui/optemailpage \
    cui/uiconfig/ui/optsavepage \
    cui/uiconfig/ui/optfltrpage \
    cui/uiconfig/ui/optfltrembedpage \
    cui/uiconfig/ui/opthtmlpage \
    cui/uiconfig/ui/optchartcolorspage \
    cui/uiconfig/ui/connpooloptions \
    cui/uiconfig/ui/dbregisterpage \
    cui/uiconfig/ui/areatabpage \
    sw/uiconfig/swriter/ui/optgeneralpage \
    sw/uiconfig/swriter/ui/viewoptionspage \
    sw/uiconfig/swriter/ui/optformataidspage \
    sw/uiconfig/swriter/ui/optfonttabpage \
    sw/uiconfig/swriter/ui/printoptionspage \
    sw/uiconfig/swriter/ui/opttablepage \
    sw/uiconfig/swriter/ui/optredlinepage \
    sw/uiconfig/swriter/ui/optcomparison \
    sw/uiconfig/swriter/ui/optcompatpage \
    sw/uiconfig/swriter/ui/optcaptionpage \
    sw/uiconfig/swriter/ui/mailconfigpage \
    sc/uiconfig/scalc/ui/scgeneralpage \
    sc/uiconfig/scalc/ui/optdefaultpage \
    sc/uiconfig/scalc/ui/tpviewpage \
    sc/uiconfig/scalc/ui/optcalculatepage \
    sc/uiconfig/scalc/ui/optformula \
    sc/uiconfig/scalc/ui/optsortlists \
    sc/uiconfig/scalc/ui/optchangespage \
    sc/uiconfig/scalc/ui/optcompatibilitypage \
    sc/uiconfig/scalc/ui/optdlg \
    sd/uiconfig/simpress/ui/optimpressgeneralpage \
    sd/uiconfig/simpress/ui/sdviewpage \
    sd/uiconfig/simpress/ui/prntopts \
    svx/uiconfig/ui/optgridpage \
    sfx2/uiconfig/ui/optprintpage \
    starmath/uiconfig/smath/ui/smathsettings \
))</span></code></pre></figure>

<p>this calls <code class="language-plaintext highlighter-rouge">gb_UIConfig_generate_options_uifiles</code> function with <code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions</code> as first parameter and list of ui files as second parameter.</p>

<p><code class="language-plaintext highlighter-rouge">solenv/gbuild/UIConfig.mk</code>:</p>

<figure class="highlight"><pre><code class="language-console" data-lang="console"><span class="go">define gb_UIConfig_run_uiex_options_script
</span><span class="gp">$</span><span class="o">(</span>shell <span class="si">$(</span>SRCDIR<span class="si">)</span>/solenv/bin/uiex_options <span class="nt">-i</span> <span class="si">$(</span>SRCDIR<span class="si">)</span>/<span class="si">$(</span>2<span class="si">)</span>.ui <span class="nt">-o</span> <span class="si">$(</span>1<span class="si">)</span>/<span class="si">$(</span>3<span class="si">)</span>.txt<span class="o">)</span>
<span class="gp">$</span><span class="o">(</span>info extracting... <span class="si">$(</span>1<span class="si">)</span>/<span class="si">$(</span>3<span class="si">)</span>.txt<span class="o">)</span>
<span class="go">
endef

define gb_UIConfig_handle_uiex_options_script
</span><span class="gp">$</span><span class="o">(</span>call gb_UIConfig_run_uiex_options_script,<span class="si">$(</span>SRCDIR<span class="si">)</span>/<span class="si">$(</span>1<span class="si">)</span>/<span class="si">$(</span>firstword <span class="si">$(</span>subst /, ,<span class="si">$(</span>2<span class="si">)))</span>,<span class="si">$(</span>2<span class="si">)</span>,<span class="si">$(</span>notdir <span class="si">$(</span>2<span class="si">))</span><span class="o">)</span>
<span class="go">
endef

define gb_UIConfig_generate_options_uifiles
</span><span class="gp">$</span><span class="o">(</span>info running ./solenv/bin/uiex_options script...<span class="o">)</span>
<span class="gp">$</span><span class="o">(</span>foreach uifile,<span class="si">$(</span>2<span class="si">)</span>,<span class="si">$(</span>call gb_UIConfig_handle_uiex_options_script,<span class="si">$(</span>1<span class="si">)</span>,<span class="si">$(</span>uifile<span class="si">))</span><span class="o">)</span>
<span class="gp">$</span><span class="o">(</span>info ...extraction <span class="k">done</span>.<span class="o">)</span>
<span class="go">
endef</span></code></pre></figure>

<p><br /></p>
<ul>
  <li>Extracted file location</li>
</ul>

<p>All extracted files located in <code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions/*</code>.</p>

<p><code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions/cui/*</code>        for ui files in <code class="language-plaintext highlighter-rouge">./cui/uiconfig/ui/*.ui</code></p>

<p><code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions/sc/*</code>         for ui files in <code class="language-plaintext highlighter-rouge">./sc/uiconfig/scalc/ui/*.ui</code></p>

<p><code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions/sd/*</code>         for ui files in <code class="language-plaintext highlighter-rouge">./sd/uiconfig/simpress/ui/*.ui</code></p>

<p><code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions/sfx2/*</code>       for ui files in <code class="language-plaintext highlighter-rouge">./sfx2/uiconfig/ui/*.ui</code></p>

<p><code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions/starmath/*</code>   for ui files in <code class="language-plaintext highlighter-rouge">./starmath/uiconfig/smath/ui/*.ui</code></p>

<p><code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions/svx/*</code>        for ui files in <code class="language-plaintext highlighter-rouge">./svx/uiconfig/ui/*.ui</code></p>

<p><code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions/sw/*</code>         for ui files in <code class="language-plaintext highlighter-rouge">./sw/uiconfig/ui/*.ui</code></p>

<p>and all of sub-directories contain a <code class="language-plaintext highlighter-rouge">README.md</code> file.</p>

<p>e.g. <code class="language-plaintext highlighter-rouge">cui/uiconfig/uioptions/sfx2/README.md</code>:</p>

<pre style="white-space: pre-wrap">
This directory contains txt files that extracted form build-time. All files contains labels, accessible-names, accessible-descriptions and tooltip-texts from all ./sfx2/uiconfig/ui/*.ui files that exist in Tools-Options dialog.

All .txt file names is the same as their .ui names.

e.g.: optprintpage.txt has strings from ./sfx2/uiconfig/ui/optprintpage.ui
</pre>

<p><br /></p>
<ul>
  <li>Created new class to fetch the extracted strings and use them in searching.</li>
</ul>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">OptionsPageIdInfo</span><span class="p">;</span>

<span class="p">...</span>

<span class="c1">// class TreeOptHelper -----------------------------------------------</span>

<span class="k">class</span> <span class="nc">TreeOptHelper</span>
<span class="p">{</span>
<span class="nl">public:</span>
    <span class="n">TreeOptHelper</span><span class="p">();</span>
    <span class="o">~</span><span class="n">TreeOptHelper</span><span class="p">();</span>

    <span class="kt">void</span> <span class="n">storeStringsFromUiFile</span><span class="p">(</span><span class="n">sal_uInt16</span> <span class="n">nPageId</span><span class="p">);</span>
    <span class="n">OUString</span> <span class="n">getAllStringsFrom</span><span class="p">(</span><span class="n">sal_uInt16</span> <span class="n">nPageId</span><span class="p">);</span>
<span class="p">};</span></code></pre></figure>

<p>Vector <code class="language-plaintext highlighter-rouge">std::vector&lt; OptionsPageIdInfo* &gt; m_aTreePageIds</code> contains all informatin related to extracted strings.</p>

<pre>
m_aTreePageIds.push_back(new OptionsPageIdInfo(sParentName, xTreeLB-&gt;get_text(*xEntry), aParentId, pPageInfo-&gt;m_nPageId));
</pre>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">OptionsPageIdInfo</span>
<span class="p">{</span>
    <span class="n">OUString</span>        <span class="n">m_sParentName</span><span class="p">;</span>
    <span class="n">OUString</span>        <span class="n">m_sPageName</span><span class="p">;</span>
    <span class="n">sal_uInt16</span>      <span class="n">m_nParentId</span><span class="p">;</span>
    <span class="n">sal_uInt16</span>      <span class="n">m_nPageId</span><span class="p">;</span>

    <span class="n">OptionsPageIdInfo</span><span class="p">(</span> <span class="n">OUString</span> <span class="n">sParentName</span><span class="p">,</span> <span class="n">OUString</span> <span class="n">sPageName</span><span class="p">,</span>
                       <span class="n">sal_uInt16</span> <span class="n">nParentId</span><span class="p">,</span> <span class="n">sal_uInt16</span> <span class="n">nPageId</span> <span class="p">)</span> <span class="o">:</span>
        <span class="n">m_sParentName</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span> <span class="n">sParentName</span> <span class="p">)),</span>
        <span class="n">m_sPageName</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span> <span class="n">sPageName</span> <span class="p">)),</span>
        <span class="n">m_nParentId</span><span class="p">(</span> <span class="n">nParentId</span> <span class="p">),</span>
        <span class="n">m_nPageId</span><span class="p">(</span> <span class="n">nPageId</span> <span class="p">)</span> <span class="p">{}</span>
<span class="p">};</span></code></pre></figure>

<p><br /></p>
<ul>
  <li>Updated the <code class="language-plaintext highlighter-rouge">applySearchFilter()</code> function</li>
</ul>

<p>The searching is made only in the variable <code class="language-plaintext highlighter-rouge">sPageNameAndStrings</code>. It contains the dialog page name and its strings.</p>

<p><code class="language-plaintext highlighter-rouge">OUString sPageNameAndStrings = sParentName + " " + sPageName + " " + sPageStrings;</code></p>

<p>Then the searching is made:</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="c1">// start searching in strings (label, accessible-name, accessible-description, tooltip-text) and all page names</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">textSearch</span><span class="p">.</span><span class="n">SearchForward</span><span class="p">(</span><span class="n">sPageNameAndStrings</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">aStartPos</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">aEndPos</span><span class="p">))</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
<span class="k">else</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span></code></pre></figure>

<p><code class="language-plaintext highlighter-rouge">applySearchFilter(OUString const&amp; rSearchTerm)</code> function:</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="kt">int</span> <span class="n">OfaTreeOptionsDialog</span><span class="o">::</span><span class="n">applySearchFilter</span><span class="p">(</span><span class="n">OUString</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">rSearchTerm</span><span class="p">)</span>
<span class="p">{</span>
    <span class="c1">// debug ("applySearchFilter(), rSearchTerm text =&gt; : " &lt;&lt; rSearchTerm);</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">rSearchTerm</span><span class="p">.</span><span class="n">isEmpty</span><span class="p">())</span>
    <span class="p">{</span>
        <span class="n">clearOptionsDialog</span><span class="p">();</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">clear</span><span class="p">();</span>
        <span class="n">Initialize</span><span class="p">(</span><span class="n">m_xFrame</span><span class="p">);</span>
        <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">m_options</span><span class="p">.</span><span class="n">searchString</span> <span class="o">=</span> <span class="n">rSearchTerm</span><span class="p">;</span>
    <span class="n">utl</span><span class="o">::</span><span class="n">TextSearch</span> <span class="n">textSearch</span><span class="p">(</span><span class="n">m_options</span><span class="p">);</span>

    <span class="n">clearOptionsDialog</span><span class="p">();</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">n_children</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">clear</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">sal_uInt16</span><span class="o">&gt;</span> <span class="n">aFoundIdsVector</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">m_aTreePageIds</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">OUString</span> <span class="n">sParentName</span> <span class="o">=</span> <span class="n">m_aTreePageIds</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">m_sParentName</span><span class="p">;</span>
        <span class="n">OUString</span> <span class="n">sPageName</span> <span class="o">=</span> <span class="n">m_aTreePageIds</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">m_sPageName</span><span class="p">;</span>
        <span class="n">sal_uInt16</span> <span class="n">nParentId</span> <span class="o">=</span> <span class="n">m_aTreePageIds</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">m_nParentId</span><span class="p">;</span>
        <span class="n">sal_uInt16</span> <span class="n">nPageId</span> <span class="o">=</span> <span class="n">m_aTreePageIds</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">m_nPageId</span><span class="p">;</span>

        <span class="n">OUString</span> <span class="n">sPageStrings</span> <span class="o">=</span> <span class="n">pOptionsTreeStrings</span><span class="p">.</span><span class="n">getAllStringsFrom</span><span class="p">(</span><span class="n">nPageId</span><span class="p">);</span>
        <span class="n">OUString</span> <span class="n">sPageNameAndStrings</span> <span class="o">=</span> <span class="n">sParentName</span> <span class="o">+</span> <span class="s">" "</span> <span class="o">+</span> <span class="n">sPageName</span> <span class="o">+</span> <span class="s">" "</span> <span class="o">+</span> <span class="n">sPageStrings</span><span class="p">;</span>

        <span class="n">sal_Int32</span> <span class="n">aStartPos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="n">sal_Int32</span> <span class="n">aEndPos</span> <span class="o">=</span> <span class="n">sPageStrings</span><span class="p">.</span><span class="n">getLength</span><span class="p">();</span>

        <span class="c1">// start searching in strings (label, accessible-name, accessible-description, tooltip-text) and all page names</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">textSearch</span><span class="p">.</span><span class="n">SearchForward</span><span class="p">(</span><span class="n">sPageNameAndStrings</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">aStartPos</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">aEndPos</span><span class="p">))</span>
        <span class="p">{</span>
            <span class="c1">// debug ("not found: " &lt;&lt; sPageName &lt;&lt; " : " &lt;&lt; nParentId &lt;&lt; " : " &lt;&lt; nPageId);</span>
        <span class="p">}</span>
        <span class="k">else</span>
        <span class="p">{</span>
            <span class="c1">// debug ("found: " &lt;&lt; sPageName &lt;&lt; " : " &lt;&lt; nParentId &lt;&lt; " : " &lt;&lt; nPageId);</span>
            <span class="c1">// debug ("sPageStrings: " &lt;&lt; sPageNameAndStrings);</span>

            <span class="kt">bool</span> <span class="n">isFound</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
            <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="n">aEntryId</span> <span class="o">:</span> <span class="n">aFoundIdsVector</span><span class="p">)</span>
            <span class="p">{</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">aEntryId</span> <span class="o">==</span> <span class="n">nParentId</span><span class="p">)</span>
                <span class="p">{</span>
                    <span class="n">isFound</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
                <span class="p">}</span>
            <span class="p">}</span>

            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isFound</span><span class="p">)</span>
            <span class="p">{</span>
                <span class="n">aFoundIdsVector</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">nParentId</span><span class="p">);</span>
                <span class="n">showDialog</span><span class="p">(</span><span class="n">nParentId</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// if treeview is empty, return -1</span>
    <span class="k">return</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">n_children</span><span class="p">()</span> <span class="o">?</span> <span class="mi">0</span> <span class="o">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<p><br /></p>
<ul>
  <li>Added new cxx file <code class="language-plaintext highlighter-rouge">cui/source/options/treeopthelper.cxx</code></li>
</ul>

<p>This file contains the file path of extracted strings with thair page-id and strings.</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">PageIdToFileNameMap_Impl</span>
<span class="p">{</span>
    <span class="n">sal_uInt16</span>      <span class="n">m_nPageId</span><span class="p">;</span>
    <span class="k">const</span> <span class="kt">char</span><span class="o">*</span>     <span class="n">m_pPageStringFileName</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span>     <span class="n">m_sContent</span><span class="p">;</span>
<span class="p">};</span>

<span class="c1">// 70 entries</span>
<span class="n">PageIdToFileNameMap_Impl</span> <span class="n">FileMap_Impl</span><span class="p">[]</span> <span class="o">=</span>
<span class="p">{</span>
    <span class="c1">// PAGE-ID                                  FILE-PATH-OF-EXTRACTED-STRINGS                          CONTENT       PAGE-NAME             UI-FILE-PATH</span>

    <span class="c1">// ProductName, SID_GENERAL_OPTIONS</span>
    <span class="p">{</span> <span class="n">RID_SFXPAGE_GENERAL</span><span class="p">,</span>                      <span class="s">"cui/uiconfig/uioptions/cui/optuserpage.txt"</span><span class="p">,</span>           <span class="s">""</span>      <span class="p">},</span> <span class="c1">// UserData              ./cui/uiconfig/ui/optuserpage.ui</span>
    <span class="p">{</span> <span class="n">OFA_TP_MISC</span><span class="p">,</span>                              <span class="s">"cui/uiconfig/uioptions/cui/optgeneralpage.txt"</span><span class="p">,</span>        <span class="s">""</span>      <span class="p">},</span> <span class="c1">// General               ./cui/uiconfig/ui/optgeneralpage.ui</span>

    <span class="p">...</span> <span class="p">(</span><span class="n">and</span> <span class="n">other</span> <span class="mi">68</span> <span class="n">entries</span><span class="p">)</span>
<span class="p">}</span></code></pre></figure>

<p>The function <code class="language-plaintext highlighter-rouge">storeStringsFromUiFile(sal_uInt16 nPageId)</code> reads the data inside txt files and fetch them into <code class="language-plaintext highlighter-rouge">PageIdToFileNameMap_Impl</code> struct as <code class="language-plaintext highlighter-rouge">rEntry.m_sContent += sLine + " ";</code></p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="kt">void</span> <span class="n">TreeOptHelper</span><span class="o">::</span><span class="n">storeStringsFromUiFile</span><span class="p">(</span><span class="n">sal_uInt16</span> <span class="n">nPageId</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">PageIdToFileNameMap_Impl</span><span class="o">&amp;</span> <span class="n">rEntry</span> <span class="o">:</span> <span class="n">FileMap_Impl</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">rEntry</span><span class="p">.</span><span class="n">m_nPageId</span> <span class="o">==</span> <span class="n">nPageId</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">std</span><span class="o">::</span><span class="n">ifstream</span> <span class="n">rIFStream</span><span class="p">(</span><span class="n">rEntry</span><span class="p">.</span><span class="n">m_pPageStringFileName</span><span class="p">);</span>

            <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">sTemp</span><span class="p">;</span>
            <span class="n">std</span><span class="o">::</span><span class="n">getline</span><span class="p">(</span><span class="n">rIFStream</span><span class="p">,</span> <span class="n">sTemp</span><span class="p">);</span>

            <span class="k">if</span><span class="p">(</span> <span class="n">rIFStream</span><span class="p">.</span><span class="n">eof</span><span class="p">()</span> <span class="o">||</span> <span class="n">sTemp</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span> <span class="p">)</span>
            <span class="p">{</span>
                <span class="n">SAL_WARN</span><span class="p">(</span><span class="s">""</span><span class="p">,</span><span class="s">" file: "</span> <span class="o">&lt;&lt;</span> <span class="n">rEntry</span><span class="p">.</span><span class="n">m_pPageStringFileName</span> <span class="o">&lt;&lt;</span> <span class="s">" could not be opened for reading!"</span><span class="p">);</span>
                <span class="k">return</span><span class="p">;</span>
            <span class="p">}</span>

            <span class="k">if</span> <span class="p">(</span><span class="n">rEntry</span><span class="p">.</span><span class="n">m_sContent</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
            <span class="p">{</span>
                <span class="c1">// debug ("fetching data from " &lt;&lt; rEntry.m_pPageStringFileName);</span>

                <span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="n">rIFStream</span><span class="p">.</span><span class="n">eof</span><span class="p">())</span>
                <span class="p">{</span>
                    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">sLine</span><span class="p">(</span><span class="n">sTemp</span><span class="p">.</span><span class="n">data</span><span class="p">(),</span> <span class="n">sTemp</span><span class="p">.</span><span class="n">length</span><span class="p">());</span>

                    <span class="n">rEntry</span><span class="p">.</span><span class="n">m_sContent</span> <span class="o">+=</span> <span class="n">sLine</span> <span class="o">+</span> <span class="s">" "</span><span class="p">;</span>

                    <span class="n">getline</span><span class="p">(</span><span class="n">rIFStream</span><span class="p">,</span> <span class="n">sTemp</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="c1">// debug ("fetching done\n");</span>
                <span class="k">break</span><span class="p">;</span>
            <span class="p">}</span>
            <span class="k">else</span>
            <span class="p">{</span>
                <span class="c1">// debug ("no data or data is already fetched from : " &lt;&lt; rEntry.m_pPageStringFileName);</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre></figure>

<p>The function <code class="language-plaintext highlighter-rouge">getAllStringsFrom(sal_uInt16 nPageId)</code> gets the strings from the given pageId:</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="n">OUString</span> <span class="n">TreeOptHelper</span><span class="o">::</span><span class="n">getAllStringsFrom</span><span class="p">(</span><span class="n">sal_uInt16</span> <span class="n">nPageId</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">nPageId</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">OUString</span><span class="p">();</span>

    <span class="k">for</span> <span class="p">(</span><span class="n">PageIdToFileNameMap_Impl</span><span class="o">&amp;</span> <span class="n">rEntry</span> <span class="o">:</span> <span class="n">FileMap_Impl</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">rEntry</span><span class="p">.</span><span class="n">m_nPageId</span> <span class="o">==</span> <span class="n">nPageId</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="n">OStringToOUString</span><span class="p">(</span><span class="n">rEntry</span><span class="p">.</span><span class="n">m_sContent</span><span class="p">,</span> <span class="n">RTL_TEXTENCODING_ASCII_US</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">OUString</span><span class="p">();</span>
<span class="p">}</span></code></pre></figure>

<p><br /></p>
<ul>
  <li>Some screenshots from the development</li>
</ul>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-04-0-extracting-debug-messages.png" alt="w-04-0-extracting-debug-messages.png" title="debug messages while extracting" />
</p>
<p><br /></p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-04-1-extracted-txt-files.png" alt="w-04-1-extracted-txt-files.png" title="extracted txt files" />
</p>
<p><br /></p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-04-2-options-dialog-search.png" alt="w-04-2-options-dialog-search.png" title="searching in options dialog" />
</p>
<p><br /></p>

<h3 id="summary">Summary</h3>

<ul>
  <li>Strings in ui files are now can be generated at build-time.</li>
  <li>labels, accessible-names, accessible-descriptions and tooltip-texts from all ui files that resides inside Options dialog, are now included in searching.</li>
</ul>

<p align="center">
    ***
</p>

<p>Steps for implementing search functionality in “Tools &gt; Options”:</p>

<table style="width:100%">
    <tbody>
        <tr>
            <td style="width:75%">1) Add Search field to “Tools &gt; Options” dialog.</td>
            <td colspan="2"><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>2) Include Options treeview into searching.</td>
            <td colspan="2"><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>3) Include Sub-tree elements (child nodes) into searching.</td>
            <td><b>DONE - week #2</b></td>
        </tr>
        <tr>
            <td>4) Generate all strings(labels), accessible-names, accessible-descriptions and tooltip-texts of all .ui files in ./cui/* directory, at build-time.</td>
            <td><b>DONE - week #3, #4 (most challenging part)</b></td>
        </tr>
        <tr>
            <td>5) Fetch the generated data - at run-time.</td>
            <td><b>DONE - week #3, #4</b></td>
        </tr>
        <tr>
            <td>6) Include strings(labels), accessible-names, accessible-descriptions and tooltip-texts into searching.</td>
            <td><b>DONE - week #3, #4</b></td>
        </tr>
        <tr>
            <td>7) Implement highlighting feature.</td>
            <td><b>next step</b></td>
        </tr>
        <tr>
            <td>...</td>
            <td><b>...</b></td>
        </tr>
    </tbody>
</table>

<p align="center">
    ***
</p>

<p>Patch: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></p>

<p>Project Mentors: <u>Andreas Heinisch</u> and <u>Heiko Tietze</u> (Thanks for their time and guidance)</p>

<p>GSoC project page: <a href="https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1">https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1</a></p>

<p>Enhancement request on Bugzilla: <a href="https://bugs.documentfoundation.org/show_bug.cgi?id=49895">https://bugs.documentfoundation.org/show_bug.cgi?id=49895</a></p>]]></content><author><name>Bayram Çiçek</name></author><category term="libreoffice-dev" /><summary type="html"><![CDATA[Thanks to my ‘Search Field in Options’ project mentors Andreas Heinisch and Heiko Tietze for their time and guidance. Additionally, thanks to Caolán McNamara for giving me the ‘generating ui strings at build-time’ idea.]]></summary></entry><entry><title type="html">Week #3 - GSoC 2023 Weekly Report - Search Field in Options</title><link href="https://bayramcicek.github.io/libreoffice-dev/2023/06/18/week-03-gsoc-report.html" rel="alternate" type="text/html" title="Week #3 - GSoC 2023 Weekly Report - Search Field in Options" /><published>2023-06-18T05:23:00+00:00</published><updated>2023-06-18T05:23:00+00:00</updated><id>https://bayramcicek.github.io/libreoffice-dev/2023/06/18/week-03-gsoc-report</id><content type="html" xml:base="https://bayramcicek.github.io/libreoffice-dev/2023/06/18/week-03-gsoc-report.html"><![CDATA[<h3 id="project-report-for-week-3">Project Report for Week #3</h3>

<ul>
  <li>The Problem in Options sub-dialogs</li>
</ul>

<p>I’ve been working with Options dialog which has more than 30 sub-dialogs. On the left pane of the Options dialog, the TreeView headers and their sub-headers were included in searching. There is no problem here. However, when it comes to adding all sub-dialogs’ <code class="language-plaintext highlighter-rouge">labels</code>, <code class="language-plaintext highlighter-rouge">accessible-names</code>, <code class="language-plaintext highlighter-rouge">accessible-descriptions</code> and <code class="language-plaintext highlighter-rouge">tooltip-texts</code> to the searching, there is a problem arise: When Options dialog opens, it does not initialize all dialogs so it is <code class="language-plaintext highlighter-rouge">NOT</code> possible to access their methods - until they were clicked manually.</p>

<p>I asked about this problem on <code class="language-plaintext highlighter-rouge">IRC #libreoffice-dev</code> channel:</p>

<pre style="white-space: pre-wrap">

[11:26:53 AM] &lt;bayramcicek&gt; Hi. Is it possible to fetch all strings(labels), tooltip-texts and accessible-descriptions for a .ui file without initializing its class/ctor?

[11:30:35 AM] &lt;caolanm&gt; bayramcicek, might need more context. We do extract those at build-time for translation purposes for example, but that might not be useful for your case

[11:33:37 AM] &lt;caolanm&gt; solenv/bin/uiex is that thing

[11:33:53 AM] &lt;bayramcicek&gt; caolanm: I'm trying to add search functionality to `Tools &gt; Options` dialog. Options dialog has a lot of sub-dialogs. I need to get all strings(labels), tooltip-texts and accessible-descriptions in each dialog to include them in search function. I think I should write a method for every single dialog to get all strings/desc/tooltips they contain. Is there a better way/approach to do this?

[11:34:45 AM] &lt;caolanm&gt; <b>options dialog is a super-duper pain, cause the various contents of that don't exist until created on-demand when you switch to the page</b>

[11:38:19 AM] &lt;bayramcicek&gt; <b>Exactly. When Options dialog opens, it does not initialize all dialogs so I couldn't access their methods until I click them manually.</b>

[11:40:01 AM] &lt;caolanm&gt; its also what that dialog is (uniquely) one that has a fixed size and doesn't adapt to its contents if there is a page that is too large

[11:43:49 AM] &lt;bayramcicek&gt; caolanm: "solenv/bin/uiex is that thing" -&gt; thanks. I'll check that.

[11:57:36 AM] &lt;caolanm&gt; bayramcicek, yeah, there might be some use in a build-time approach to attempt to build the index of data you need during the build, rather than at runtime.

</pre>

<p>It is not possible to access all sub-dialogs when Options dialog opens. We can only have access to their <code class="language-plaintext highlighter-rouge">pageIDs</code> and <code class="language-plaintext highlighter-rouge">pageNames(headers)</code>, but we can’t access their methods since they aren’t instantiated. Otherwise, fetching the all data we need would be very easy with a method implemented by all dialogs - something like <code class="language-plaintext highlighter-rouge">pPageInfo-&gt;m_xPage-&gt;getAllTooltips()</code> etc..</p>

<p>Initializing all dialogs when Options dialog opens is another idea. But this is not a good idea since it takes long to create/initialize all sub-dialogs.</p>

<p><br /></p>
<ul>
  <li>About <code class="language-plaintext highlighter-rouge">./solenv/bin/uiex</code> script</li>
</ul>

<p>In <code class="language-plaintext highlighter-rouge">./core</code> directory; e.g. for <code class="language-plaintext highlighter-rouge">optopenclpage.ui</code> file, running</p>

<pre>
 $ ./solenv/bin/uiex -i ./cui/uiconfig/ui/optopenclpage.ui -o output.txt
</pre>

<p>extracts:</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="o">---</span>

<span class="cp">#. QYxCN
#: ../cui/uiconfig/ui/optopenclpage.ui:24
</span><span class="n">msgctxt</span> <span class="s">"optopenclpage|useopencl"</span>
<span class="n">msgid</span> <span class="s">"Allow use of OpenCL"</span>
<span class="n">msgstr</span> <span class="s">""</span>

<span class="cp">#. MAc4P
#: ../cui/uiconfig/ui/optopenclpage.ui:41
</span><span class="n">msgctxt</span> <span class="s">"optopenclpage|openclused"</span>
<span class="n">msgid</span> <span class="s">"OpenCL is available for use."</span>
<span class="n">msgstr</span> <span class="s">""</span>

<span class="cp">#. fAEQH
#: ../cui/uiconfig/ui/optopenclpage.ui:53
</span><span class="n">msgctxt</span> <span class="s">"optopenclpage|openclnotused"</span>
<span class="n">msgid</span> <span class="s">"OpenCL is not used."</span>
<span class="n">msgstr</span> <span class="s">""</span>

<span class="cp">#. xWE5i
#: ../cui/uiconfig/ui/optopenclpage.ui:67
</span><span class="n">msgctxt</span> <span class="s">"optopenclpage|label1"</span>
<span class="n">msgid</span> <span class="s">"OpenCL Options"</span>
<span class="n">msgstr</span> <span class="s">""</span>

<span class="o">---</span></code></pre></figure>

<p>As far as I understand,  the <code class="language-plaintext highlighter-rouge">./solenv/bin/uiex</code> script extracts all strings that have</p>

<pre>
&lt;... translatable="yes" ... &gt;
</pre>

<p>property. This also extracts all <code class="language-plaintext highlighter-rouge">label</code>, <code class="language-plaintext highlighter-rouge">accessible-name</code>, <code class="language-plaintext highlighter-rouge">accessible-description</code> and <code class="language-plaintext highlighter-rouge">tooltip-text</code> values which are the exact data we need. But this happens only running <code class="language-plaintext highlighter-rouge">./solenv/bin/uiex</code> script. We need the data at build-time.</p>

<p><br /></p>
<ul>
  <li>Extracting the data at build-time</li>
</ul>

<p>The extraction happens when running <code class="language-plaintext highlighter-rouge">$ make translations</code>. <code class="language-plaintext highlighter-rouge">$ make</code> doesn’t extract the data. (or - does it ?)</p>

<p><code class="language-plaintext highlighter-rouge">$ make translations</code> extracts the all information from the following file extensions. (imho, probably this is why it takes longer than expected - on my computer it took 1 min 56 secs.)</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp">    <span class="k">static</span> <span class="n">Command</span> <span class="k">const</span> <span class="n">commands</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
        <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">u16string_view</span><span class="p">(</span><span class="s">u".hrc"</span><span class="p">),</span> <span class="s">"hrcex"</span><span class="p">,</span> <span class="nb">false</span> <span class="p">},</span>
        <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">u16string_view</span><span class="p">(</span><span class="s">u".ulf"</span><span class="p">),</span> <span class="s">"ulfex"</span><span class="p">,</span> <span class="nb">false</span> <span class="p">},</span>
        <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">u16string_view</span><span class="p">(</span><span class="s">u".xcu"</span><span class="p">),</span> <span class="s">"cfgex"</span><span class="p">,</span> <span class="nb">false</span> <span class="p">},</span>
        <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">u16string_view</span><span class="p">(</span><span class="s">u".xrm"</span><span class="p">),</span> <span class="s">"xrmex"</span><span class="p">,</span> <span class="nb">false</span> <span class="p">},</span>
        <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">u16string_view</span><span class="p">(</span><span class="s">u"description.xml"</span><span class="p">),</span> <span class="s">"xrmex"</span><span class="p">,</span> <span class="nb">true</span> <span class="p">},</span>
        <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">u16string_view</span><span class="p">(</span><span class="s">u".xhp"</span><span class="p">),</span> <span class="s">"helpex"</span><span class="p">,</span> <span class="nb">false</span> <span class="p">},</span>
        <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">u16string_view</span><span class="p">(</span><span class="s">u".properties"</span><span class="p">),</span> <span class="s">"propex"</span><span class="p">,</span> <span class="nb">false</span> <span class="p">},</span>
        <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">u16string_view</span><span class="p">(</span><span class="s">u".ui"</span><span class="p">),</span> <span class="s">"uiex"</span><span class="p">,</span> <span class="nb">false</span> <span class="p">},</span>
        <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">u16string_view</span><span class="p">(</span><span class="s">u".tree"</span><span class="p">),</span> <span class="s">"treex"</span><span class="p">,</span> <span class="nb">false</span> <span class="p">}</span>
    <span class="p">};</span></code></pre></figure>

<p><code class="language-plaintext highlighter-rouge">$ make translations</code> extracts all strings into <code class="language-plaintext highlighter-rouge">./workdir/pot/*</code> directory.</p>

<p>Extraction happens in <code class="language-plaintext highlighter-rouge">handleFile(...)</code> function at <code class="language-plaintext highlighter-rouge">./l10ntools/source/localize.cxx</code> (<a href="https://opengrok.libreoffice.org/xref/core/l10ntools/source/localize.cxx?r=eaf07139#189">https://opengrok.libreoffice.org/xref/core/l10ntools/source/localize.cxx?r=eaf07139#189</a>)</p>

<p>The extracted file <code class="language-plaintext highlighter-rouge">./workdir/pot/cui/messages.pot</code> includes all strings for <code class="language-plaintext highlighter-rouge">.ui</code> files that inside <code class="language-plaintext highlighter-rouge">./cui/*</code>. But <code class="language-plaintext highlighter-rouge">messages.pot</code> also has strings that unnecessary for our case.</p>

<p>I imagine a script similar to <code class="language-plaintext highlighter-rouge">./solenv/bin/uiex</code> that extracts all <code class="language-plaintext highlighter-rouge">.ui</code> files that Options dialog has, into a file (xml or txt etc. ?), during <code class="language-plaintext highlighter-rouge">$ make</code>. Then we can retrieve the data into a vector and use it at run-time (maybe - when options dialog opens ?).</p>

<p><code class="language-plaintext highlighter-rouge">./workdir/pot/cui/messages.pot</code> file:</p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-03-0-messages-pot.png" alt="w-03-1-messages-pot.png" title="messages.pot file" />
</p>
<p><br /></p>

<p>Debug messages after <code class="language-plaintext highlighter-rouge">$ make translations</code>:</p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-03-1-terminal.png" alt="w-03-2-terminal.png" title="terminal messages after $ make translations" />
</p>
<p><br /></p>

<h3 id="summary">Summary</h3>

<ul>
  <li>There is a problem with accessing methods of sub-dialogs in Options dialog. (the reason is that the sub-dialogs don’t exist until the page is switched)</li>
  <li>We decided that strings in all <code class="language-plaintext highlighter-rouge">.ui</code> files will be generated at build-time. (which will be the most challenging part in this project)</li>
  <li>I’ll be trying to generate the data at build-time in the following weeks.</li>
</ul>

<p align="center">
    ***
</p>

<p>Steps for implementing search functionality in “Tools &gt; Options”:</p>

<table style="width:100%">
    <tbody>
        <tr>
            <td style="width:75%">1) Add Search field to “Tools &gt; Options” dialog.</td>
            <td colspan="2"><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>2) Include Options treeview into searching.</td>
            <td colspan="2"><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>3) Include Sub-tree elements (child nodes) into searching.</td>
            <td><b>DONE - week #2</b></td>
        </tr>
        <tr>
            <td>4) Generate all strings(labels), accessible-names, accessible-descriptions and tooltip-texts of all .ui files in ./cui/* directory, at build-time.</td>
            <td><b>Next step (most challenging part)</b></td>
        </tr>
        <tr>
            <td>5) Fetch the generated data - at run-time.</td>
            <td><b>...</b></td>
        </tr>
        <tr>
            <td>6) Include strings(labels), accessible-names, accessible-descriptions and tooltip-texts into searching.</td>
            <td><b>...</b></td>
        </tr>
        <tr>
            <td>7) Implement highlighting feature - if enough time remains.</td>
            <td><b>...</b></td>
        </tr>
        <tr>
            <td>...</td>
            <td><b>...</b></td>
        </tr>
    </tbody>
</table>

<p align="center">
    ***
</p>

<p>Patch: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></p>

<p>Project Mentors: <u>Andreas Heinisch</u> and <u>Heiko Tietze</u> (Thanks for their time and guidance)</p>

<p>GSoC project page: <a href="https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1">https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1</a></p>

<p>Enhancement request on Bugzilla: <a href="https://bugs.documentfoundation.org/show_bug.cgi?id=49895">https://bugs.documentfoundation.org/show_bug.cgi?id=49895</a></p>]]></content><author><name>Bayram Çiçek</name></author><category term="libreoffice-dev" /><summary type="html"><![CDATA[Project Report for Week #3]]></summary></entry><entry><title type="html">Week #2 - GSoC 2023 Weekly Report - Search Field in Options</title><link href="https://bayramcicek.github.io/libreoffice-dev/2023/06/10/week-02-gsoc-report.html" rel="alternate" type="text/html" title="Week #2 - GSoC 2023 Weekly Report - Search Field in Options" /><published>2023-06-10T06:03:00+00:00</published><updated>2023-06-10T06:03:00+00:00</updated><id>https://bayramcicek.github.io/libreoffice-dev/2023/06/10/week-02-gsoc-report</id><content type="html" xml:base="https://bayramcicek.github.io/libreoffice-dev/2023/06/10/week-02-gsoc-report.html"><![CDATA[<h3 id="project-report-for-week-2">Project Report for Week #2</h3>

<ul>
  <li>In week #1, search functionality was implemented only for headers of the options TreeView. (“Tools &gt; Options” - left pane tree).</li>
</ul>

<p>We should expand the search functionality to include the sub-headers(sub-elements) of the nodes. For example; if you type <code class="language-plaintext highlighter-rouge">“libre”</code>, search function will look if there is any match only in headers. But we should also check their child nodes(sub-headers) to be ensure if there will be any match with the search term.</p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-01-02-search.png" alt="w-01-02-search.png" title="searching for headers" />
</p>
<p><br /></p>

<ul>
  <li>Sub-tree elements(child nodes) are now included in searching.</li>
</ul>

<p>Patchset 2: <a href="https://gerrit.libreoffice.org/c/core/+/152519/2">https://gerrit.libreoffice.org/c/core/+/152519/2</a></p>

<p>If user types <code class="language-plaintext highlighter-rouge">"japanese"</code>, search function will find the match in <code class="language-plaintext highlighter-rouge">"Searching in Japanese"</code> and will show its parent node - which is <code class="language-plaintext highlighter-rouge">"Language Settings"</code>, as shown below. However, if we only search in headers, this would not be possible and the left pane would be empty - nothing would be shown.</p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-02-01-sub-tree-search.png" alt="w-02-01-sub-tree-search.png" title="searching for headers and sub-headers" />
</p>
<p><br /></p>

<p>As you can see at the bottom line of the terminal; if there is a match, debug prints <code class="language-plaintext highlighter-rouge">"found: &lt;full string of where search item found&gt; : &lt;its parent ID&gt;"</code>.</p>

<p><br /></p>
<ul>
  <li>Some technical details</li>
</ul>

<p>All TreeView nodes and their child nodes are stored in a <code class="language-plaintext highlighter-rouge">std::vector</code> as a <code class="language-plaintext highlighter-rouge">std::pair</code>.</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">OUString</span><span class="p">,</span> <span class="n">sal_uInt16</span><span class="o">&gt;&gt;</span> <span class="n">storedIdVector</span><span class="p">;</span></code></pre></figure>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="c1">// store Options tree with their sub elements</span>
<span class="kt">void</span> <span class="n">OfaTreeOptionsDialog</span><span class="o">::</span><span class="n">storeOptionsTree</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">storedIdVector</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
    <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">weld</span><span class="o">::</span><span class="n">TreeIter</span><span class="o">&gt;</span> <span class="n">xEntry</span> <span class="o">=</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">make_iterator</span><span class="p">();</span>
        <span class="kt">bool</span> <span class="n">bEntry</span> <span class="o">=</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">get_iter_first</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">);</span>

        <span class="n">sal_uInt16</span> <span class="n">currentTreeElementId</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

        <span class="c1">// iterate over the tree and their sub-tree elements</span>
        <span class="k">while</span> <span class="p">(</span><span class="n">bEntry</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">OptionsGroupInfo</span><span class="o">*</span> <span class="n">pGroupInfo</span> <span class="o">=</span> <span class="n">weld</span><span class="o">::</span><span class="n">fromId</span><span class="o">&lt;</span><span class="n">OptionsGroupInfo</span><span class="o">*&gt;</span><span class="p">(</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">get_id</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">));</span>
            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">get_iter_depth</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">))</span>
            <span class="p">{</span>
                <span class="n">currentTreeElementId</span> <span class="o">=</span> <span class="n">pGroupInfo</span><span class="o">-&gt;</span><span class="n">m_nDialogId</span><span class="p">;</span>
                <span class="n">storedIdVector</span><span class="p">.</span><span class="n">push_back</span><span class="p">({</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">get_text</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">)</span> <span class="p">,</span><span class="n">currentTreeElementId</span><span class="p">});</span>
            <span class="p">}</span>
            <span class="k">else</span>
            <span class="p">{</span>
                <span class="n">storedIdVector</span><span class="p">.</span><span class="n">push_back</span><span class="p">({</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">get_text</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">)</span> <span class="p">,</span><span class="n">currentTreeElementId</span><span class="p">});</span>
            <span class="p">}</span>
            <span class="n">bEntry</span> <span class="o">=</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">iter_next</span><span class="p">(</span><span class="o">*</span><span class="n">xEntry</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre></figure>

<p>Search function searchs through all first elements of <code class="language-plaintext highlighter-rouge">std::pair&lt;OUString, sal_uInt16&gt;</code>. If there is a match, the second element - which is the ID of the parent node - will be added to left pane as a node.</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="kt">int</span> <span class="n">OfaTreeOptionsDialog</span><span class="o">::</span><span class="n">applySearchFilter</span><span class="p">(</span><span class="n">OUString</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">rSearchTerm</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">rSearchTerm</span><span class="p">.</span><span class="n">isEmpty</span><span class="p">())</span>
    <span class="p">{</span>
        <span class="n">clearOptionsDialog</span><span class="p">();</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">clear</span><span class="p">();</span>
        <span class="n">Initialize</span><span class="p">(</span><span class="n">m_xFrame</span><span class="p">);</span>
        <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">m_options</span><span class="p">.</span><span class="n">searchString</span> <span class="o">=</span> <span class="n">rSearchTerm</span><span class="p">;</span>
    <span class="n">utl</span><span class="o">::</span><span class="n">TextSearch</span> <span class="n">textSearch</span><span class="p">(</span><span class="n">m_options</span><span class="p">);</span>

    <span class="n">clearOptionsDialog</span><span class="p">();</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">n_children</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">clear</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">sal_uInt16</span><span class="o">&gt;</span> <span class="n">foundIdsVector</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">storedIdVector</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">OUString</span> <span class="n">itemName</span> <span class="o">=</span> <span class="n">storedIdVector</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">first</span><span class="p">;</span>
        <span class="n">sal_uInt16</span> <span class="n">itemId</span> <span class="o">=</span> <span class="n">storedIdVector</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">second</span><span class="p">;</span>

        <span class="n">sal_Int32</span> <span class="n">aStartPos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="n">sal_Int32</span> <span class="n">aEndPos</span> <span class="o">=</span> <span class="n">itemName</span><span class="p">.</span><span class="n">getLength</span><span class="p">();</span>

        <span class="c1">// make search</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">textSearch</span><span class="p">.</span><span class="n">SearchForward</span><span class="p">(</span><span class="n">itemName</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">aStartPos</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">aEndPos</span><span class="p">))</span>
        <span class="p">{</span>
            <span class="c1">// debug ("not found: " &lt;&lt; itemName &lt;&lt; " : " &lt;&lt; itemId);</span>
        <span class="p">}</span>
        <span class="k">else</span>
        <span class="p">{</span>
            <span class="c1">// debug ("found: " &lt;&lt; itemName &lt;&lt; " : " &lt;&lt; itemId);</span>

            <span class="kt">bool</span> <span class="n">isFound</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
            <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="n">entryId</span> <span class="o">:</span> <span class="n">foundIdsVector</span><span class="p">)</span>
            <span class="p">{</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">entryId</span> <span class="o">==</span> <span class="n">itemId</span><span class="p">)</span>
                <span class="p">{</span>
                    <span class="n">isFound</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
                <span class="p">}</span>
            <span class="p">}</span>

            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isFound</span><span class="p">)</span>
            <span class="p">{</span>
                <span class="n">foundIdsVector</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">itemId</span><span class="p">);</span>

                <span class="cm">/*
                    void generalOptions();      // SID_GENERAL_OPTIONS
                    void loadAndSaveOptions();  // SID_FILTER_DLG
                    void languageOptions();     // SID_LANGUAGE_OPTIONS
                    void writerOptions();       // SID_SW_EDITOPTIONS
                    void writerWebOptions();    // SID_SW_ONLINEOPTIONS
                    void calcOptions();         // SID_SC_EDITOPTIONS
                    void impressOptions();      // SID_SD_EDITOPTIONS
                    void drawOptions();         // SID_SD_GRAPHIC_OPTIONS
                    void mathOptions();         // SID_SM_EDITOPTIONS
                    void databaseOptions();     // SID_SB_STARBASEOPTIONS
                    void chartOptions();        // SID_SCH_EDITOPTIONS
                    void internetOptions();     // SID_INET_DLG
                */</span>

                <span class="k">switch</span><span class="p">(</span><span class="n">itemId</span><span class="p">)</span>
                <span class="p">{</span>
                    <span class="k">case</span> <span class="n">SID_GENERAL_OPTIONS</span><span class="p">:</span>
                        <span class="n">generalOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_FILTER_DLG</span><span class="p">:</span>
                        <span class="n">loadAndSaveOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_LANGUAGE_OPTIONS</span><span class="p">:</span>
                        <span class="n">languageOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_SW_EDITOPTIONS</span><span class="p">:</span>
                        <span class="n">writerOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_SW_ONLINEOPTIONS</span><span class="p">:</span>
                        <span class="n">writerWebOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_SC_EDITOPTIONS</span><span class="p">:</span>
                        <span class="n">calcOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_SD_EDITOPTIONS</span><span class="p">:</span>
                        <span class="n">impressOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_SD_GRAPHIC_OPTIONS</span><span class="p">:</span>
                        <span class="n">drawOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_SM_EDITOPTIONS</span><span class="p">:</span>
                        <span class="n">mathOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_SB_STARBASEOPTIONS</span><span class="p">:</span>
                        <span class="n">databaseOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_SCH_EDITOPTIONS</span><span class="p">:</span>
                        <span class="n">chartOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="n">SID_INET_DLG</span><span class="p">:</span>
                        <span class="n">internetOptions</span><span class="p">();</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="nl">default:</span>
                        <span class="k">break</span><span class="p">;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// if treeview is empty, return -1</span>
    <span class="k">return</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">n_children</span><span class="p">()</span> <span class="o">?</span> <span class="mi">0</span> <span class="o">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<h3 id="summary">Summary</h3>

<ul>
  <li>Sub-tree elements(child nodes) are now included in searching.</li>
  <li>Patchset 2 has been submitted: <a href="https://gerrit.libreoffice.org/c/core/+/152519/2">https://gerrit.libreoffice.org/c/core/+/152519/2</a></li>
</ul>

<p align="center">
    ***
</p>

<p>Steps for implementing search functionality in “Tools &gt; Options”:</p>

<table>
    <tbody>
        <tr>
            <td>1) Add Search field to “Tools &gt; Options” dialog.</td>
            <td><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>2) Options treeview.</td>
            <td><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>3) Sub-tree elements (child nodes).</td>
            <td><b>DONE - week #2</b></td>
        </tr>
        <tr>
            <td>4) Strings(labels) in all dialogs.</td>
            <td><b>Next step</b></td>
        </tr>
        <tr>
            <td>5) Tooltip texts.</td>
            <td><b>...</b></td>
        </tr>
        <tr>
            <td>6) Accessible descriptions.</td>
            <td><b>...</b></td>
        </tr>
        <tr>
            <td>...</td>
            <td><b>...</b></td>
        </tr>
    </tbody>
</table>

<p align="center">
    ***
</p>

<p>Patch: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></p>

<p>Project Mentors: <u>Andreas Heinisch</u> and <u>Heiko Tietze</u> (Thanks for their time and guidance)</p>

<p>GSoC project page: <a href="https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1">https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1</a></p>

<p>Enhancement request on Bugzilla: <a href="https://bugs.documentfoundation.org/show_bug.cgi?id=49895">https://bugs.documentfoundation.org/show_bug.cgi?id=49895</a></p>]]></content><author><name>Bayram Çiçek</name></author><category term="libreoffice-dev" /><summary type="html"><![CDATA[Project Report for Week #2]]></summary></entry><entry><title type="html">Week #1 - GSoC 2023 Weekly Report - Search Field in Options</title><link href="https://bayramcicek.github.io/libreoffice-dev/2023/06/03/week-01-gsoc-report.html" rel="alternate" type="text/html" title="Week #1 - GSoC 2023 Weekly Report - Search Field in Options" /><published>2023-06-03T08:08:00+00:00</published><updated>2023-06-03T08:08:00+00:00</updated><id>https://bayramcicek.github.io/libreoffice-dev/2023/06/03/week-01-gsoc-report</id><content type="html" xml:base="https://bayramcicek.github.io/libreoffice-dev/2023/06/03/week-01-gsoc-report.html"><![CDATA[<p><em>Thanks to my ‘Search Field in Options’ project mentors Andreas Heinisch and Heiko Tietze for their time and guidance.</em></p>

<p align="center">
    ***
</p>

<h3 id="project-report-for-week-1">Project Report for Week #1</h3>

<ul>
  <li>
    <p>First patchset has been submitted: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></p>
  </li>
  <li>
    <p>Search bar/field added to “Tools &gt; Options” dialog</p>
  </li>
</ul>

<p><code class="language-plaintext highlighter-rouge">cui/uiconfig/ui/optionsdialog.ui</code>:</p>
<p align="center">
  <img src="../../../../folder/libreoffice-png/w-01-00-search-ui-glade.png" alt="w-01-00-search-ui-glade.png" />
</p>
<p><br /></p>

<p><code class="language-plaintext highlighter-rouge">“Tools &gt; Options”</code> dialog:</p>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-01-01-search-ui-libre.png" alt="w-01-01-search-ui-libre.png" />
</p>
<p><br /></p>

<ul>
  <li>Search functionality implemented for Options TreeView. (in “Tools &gt; Options”)</li>
</ul>

<p align="center">
  <img src="../../../../folder/libreoffice-png/w-01-02-search.png" alt="w-01-02-search.png" />
</p>
<p><br /></p>

<ul>
  <li>Some technical details</li>
</ul>

<p>There is a timer that waits the user to stop typing if user types faster than <code class="language-plaintext highlighter-rouge">350ms</code>. Since searching can be expensive, we shouldn’t perform search for every key press if pressing between two keys are less than 350ms, which will improve the performance.</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="n">IMPL_LINK_NOARG</span><span class="p">(</span><span class="n">OfaTreeOptionsDialog</span><span class="p">,</span> <span class="n">SearchUpdateHdl</span><span class="p">,</span> <span class="n">weld</span><span class="o">::</span><span class="n">Entry</span><span class="o">&amp;</span><span class="p">,</span> <span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">m_aUpdateDataTimer</span><span class="p">.</span><span class="n">Start</span><span class="p">();</span>
    <span class="c1">// debug ("timer -&gt; SearchUpdateHdl()");</span>
<span class="p">}</span></code></pre></figure>

<p><code class="language-plaintext highlighter-rouge">ImplUpdateDataHdl()</code> is called for searching:</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="n">IMPL_LINK_NOARG</span><span class="p">(</span><span class="n">OfaTreeOptionsDialog</span><span class="p">,</span> <span class="n">ImplUpdateDataHdl</span><span class="p">,</span> <span class="n">Timer</span><span class="o">*</span><span class="p">,</span> <span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
    <span class="c1">// Pause redraw (Do not redraw at each removal</span>
    <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">freeze</span><span class="p">();</span>

    <span class="c1">// Apply the search filter to the functions list</span>
    <span class="n">OUString</span> <span class="n">aSearchTerm</span><span class="p">(</span><span class="n">m_xSearchEdit</span><span class="o">-&gt;</span><span class="n">get_text</span><span class="p">());</span>
    <span class="kt">int</span> <span class="n">nMatchFound</span> <span class="o">=</span> <span class="n">applySearchFilter</span><span class="p">(</span><span class="n">aSearchTerm</span><span class="p">);</span>
    <span class="c1">// debug ("nMatchFound: " &lt;&lt; nMatchFound);</span>

    <span class="c1">// Resume redraw</span>
    <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">thaw</span><span class="p">();</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">nMatchFound</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">select</span><span class="p">(</span><span class="n">nMatchFound</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">else</span>
    <span class="p">{</span>

    <span class="p">}</span>
<span class="p">}</span></code></pre></figure>

<p><code class="language-plaintext highlighter-rouge">applySearchFilter(aSearchTerm)</code> function gets the word in search bar and does the search:</p>

<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="kt">int</span> <span class="n">OfaTreeOptionsDialog</span><span class="o">::</span><span class="n">applySearchFilter</span><span class="p">(</span><span class="n">OUString</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">rSearchTerm</span><span class="p">)</span>
<span class="p">{</span>
    <span class="c1">// debug ("applySearchFilter(), rSearchTerm text: " &lt;&lt; rSearchTerm);</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">rSearchTerm</span><span class="p">.</span><span class="n">isEmpty</span><span class="p">())</span>
    <span class="p">{</span>
        <span class="n">ClearAllOptions</span><span class="p">();</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">clear</span><span class="p">();</span>
        <span class="n">Initialize</span><span class="p">(</span><span class="n">m_xFrame</span><span class="p">);</span>
        <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">m_options</span><span class="p">.</span><span class="n">searchString</span> <span class="o">=</span> <span class="n">rSearchTerm</span><span class="p">;</span>
    <span class="n">utl</span><span class="o">::</span><span class="n">TextSearch</span> <span class="n">textSearch</span><span class="p">(</span><span class="n">m_options</span><span class="p">);</span>

    <span class="n">ClearAllOptions</span><span class="p">();</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">n_children</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">clear</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="k">for</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">aDialogIdVector</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="kt">int</span> <span class="n">nEntry</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
        <span class="n">OUString</span> <span class="n">aStr</span> <span class="o">=</span> <span class="n">aDialogIdVector</span><span class="p">[</span><span class="n">nEntry</span><span class="p">].</span><span class="n">first</span><span class="p">;</span>
        <span class="n">sal_uInt16</span> <span class="n">aId</span> <span class="o">=</span> <span class="n">aDialogIdVector</span><span class="p">[</span><span class="n">nEntry</span><span class="p">].</span><span class="n">second</span><span class="p">;</span>
        <span class="c1">// debug ("aDialogIdVector["&lt;&lt; nEntry &lt;&lt; "]: " &lt;&lt; aStr &lt;&lt; " : " &lt;&lt; aId);</span>

        <span class="n">sal_Int32</span> <span class="n">aStartPos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="n">sal_Int32</span> <span class="n">aEndPos</span> <span class="o">=</span> <span class="n">aStr</span><span class="p">.</span><span class="n">getLength</span><span class="p">();</span>

        <span class="c1">// make search</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">textSearch</span><span class="p">.</span><span class="n">SearchForward</span><span class="p">(</span><span class="n">aStr</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">aStartPos</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">aEndPos</span><span class="p">))</span>
        <span class="p">{</span>
            <span class="c1">// debug ("not found: " &lt;&lt; aStr &lt;&lt; " : " &lt;&lt; aId);</span>
        <span class="p">}</span>
        <span class="k">else</span>
        <span class="p">{</span>
            <span class="c1">// debug ("found: " &lt;&lt; aStr &lt;&lt; " : " &lt;&lt; aId);</span>

            <span class="c1">// TODO: convert allDialogIds vector to a pair to hold function pointers.</span>
            <span class="c1">// -&gt; (allDialogIds[i].second)();</span>
            <span class="k">switch</span><span class="p">(</span><span class="n">aId</span><span class="p">)</span>
            <span class="p">{</span>
                <span class="k">case</span> <span class="n">SID_GENERAL_OPTIONS</span><span class="p">:</span>
                    <span class="n">generalOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_FILTER_DLG</span><span class="p">:</span>
                    <span class="n">loadAndSaveOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_LANGUAGE_OPTIONS</span><span class="p">:</span>
                    <span class="n">languageOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_SW_EDITOPTIONS</span><span class="p">:</span>
                    <span class="n">writerOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_SW_ONLINEOPTIONS</span><span class="p">:</span>
                    <span class="n">writerWebOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_SC_EDITOPTIONS</span><span class="p">:</span>
                    <span class="n">calcOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_SD_EDITOPTIONS</span><span class="p">:</span>
                    <span class="n">impressOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_SD_GRAPHIC_OPTIONS</span><span class="p">:</span>
                    <span class="n">drawOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_SM_EDITOPTIONS</span><span class="p">:</span>
                    <span class="n">mathOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_SB_STARBASEOPTIONS</span><span class="p">:</span>
                    <span class="n">databaseOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_SCH_EDITOPTIONS</span><span class="p">:</span>
                    <span class="n">chartOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">SID_INET_DLG</span><span class="p">:</span>
                    <span class="n">internetOptions</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="nl">default:</span>
                    <span class="k">break</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// if treeview is empty, return -1</span>
    <span class="k">return</span> <span class="n">xTreeLB</span><span class="o">-&gt;</span><span class="n">n_children</span><span class="p">()</span> <span class="o">?</span> <span class="mi">0</span> <span class="o">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<h3 id="summary">Summary</h3>

<ul>
  <li>First patchset has been submitted: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></li>
  <li>Search bar/field added to “Tools &gt; Options” dialog.</li>
  <li>Search functionality implemented to Options treeview.</li>
</ul>

<p align="center">
    ***
</p>

<p>Steps for implementing search functionality in “Tools &gt; Options”:</p>

<table>
    <tbody>
        <tr>
            <td>1) Add Search field to “Tools &gt; Options” dialog.</td>
            <td><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>2) Options treeview.</td>
            <td><b>DONE - week #1</b></td>
        </tr>
        <tr>
            <td>3) Sub-tree elements (child nodes).</td>
            <td><b>Next step</b></td>
        </tr>
        <tr>
            <td>4) Strings(labels) in all dialogs.</td>
            <td><b>...</b></td>
        </tr>
        <tr>
            <td>5) Tooltip texts.</td>
            <td><b>...</b></td>
        </tr>
        <tr>
            <td>6) Accessible descriptions.</td>
            <td><b>...</b></td>
        </tr>
        <tr>
            <td>...</td>
            <td><b>...</b></td>
        </tr>
    </tbody>
</table>

<p>Additional hack:</p>
<ul>
  <li>show modified options with some special indicator (as in KDE settings). (<em>better to discuss this idea in a separate ticket</em>)</li>
</ul>

<p align="center">
    ***
</p>

<p>Patch: <a href="https://gerrit.libreoffice.org/c/core/+/152519">https://gerrit.libreoffice.org/c/core/+/152519</a></p>

<p>Project Mentors: <u>Andreas Heinisch</u> and <u>Heiko Tietze</u> (Thanks for their time and guidance)</p>

<p>GSoC project page: <a href="https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1">https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1</a></p>

<p>Enhancement request on Bugzilla: <a href="https://bugs.documentfoundation.org/show_bug.cgi?id=49895">https://bugs.documentfoundation.org/show_bug.cgi?id=49895</a></p>]]></content><author><name>Bayram Çiçek</name></author><category term="libreoffice-dev" /><summary type="html"><![CDATA[Thanks to my ‘Search Field in Options’ project mentors Andreas Heinisch and Heiko Tietze for their time and guidance.]]></summary></entry><entry><title type="html">Google Summer of Code 2023 Timeline - Search Field in Options</title><link href="https://bayramcicek.github.io/libreoffice-dev/2023/05/18/gsoc-timeline.html" rel="alternate" type="text/html" title="Google Summer of Code 2023 Timeline - Search Field in Options" /><published>2023-05-18T08:18:00+00:00</published><updated>2023-05-18T08:18:00+00:00</updated><id>https://bayramcicek.github.io/libreoffice-dev/2023/05/18/gsoc-timeline</id><content type="html" xml:base="https://bayramcicek.github.io/libreoffice-dev/2023/05/18/gsoc-timeline.html"><![CDATA[<h3 id="project-search-field-in-options">Project: Search Field in Options</h3>

<p>I’ll be working on “Search Field in Options” project under the mentorship of Heiko Tietze and Andreas Heinisch throughout the Google Summer of Code 2023 program.</p>

<h3 id="timeline">Timeline</h3>

<style>
.center, td:nth-child(2), td:nth-child(3){
  text-align: center;
  vertical-align: middle;
}
</style>

<table>
    <thead>
        <tr class="center">
            <th style="width:25%"># Week</th>
            <th style="width:43%">Tasks</th>
            <th style="width:32%">Notes</th>
        </tr>
    </thead>
    <tbody>
        <tr style="background-color: yellow">
            <td><b>#1</b> (May 29 - June 5)</td>
            <td>Add a seach field to ./cui/uiconfig/ui/optionsdialog.ui</td>
            <td>First week of coding period</td>
        </tr>
        <tr>
            <td><b>#2</b> (June 5 - 12)</td>
            <td rowspan="3">Connect search field(ui) with Visual Class Library (VCL)</td>
            <td rowspan="3">VCL provides a graphical toolkit similar to gtk+, Qt, SWING etc.</td>
        </tr>
        <tr>
            <td><b>#3</b> (June 12 - 19)</td>
        </tr>
        <tr>
            <td><b>#4</b> (June 19 - 26)</td>
        </tr>
        <tr>
            <td><b>#5</b> (June 26 - July 3)</td>
            <td>Start implement seach funtionality</td>
            <td></td>
        </tr>
        <tr>
            <td><b>#6</b> (July 3 - 10)</td>
            <td>Start by searching the treeview</td>
            <td></td>
        </tr>
        <tr style="background-color: yellow">
            <td><b>#7</b> (July 10 - 17)</td>
            <td>Midterm evaluation for contributors and mentors</td>
            <td>Midterm evaluation deadline (July 14 – 18:00 UTC)</td>
        </tr>
        <tr>
            <td><b>#8</b> (July 17 - 24)</td>
            <td>  Iterate over the tabs and match captions as well as tooltip with the search term</td>
            <td rowspan="2">Update UI</td>
        </tr>
        <tr>
            <td><b>#9</b> (July 24 - 31)</td>
            <td>Expand the search functionality for every single dialog step by step</td>
        </tr>
        <tr>
            <td><b>#10</b> (July 31 - Aug 7)</td>
            <td>UI: Hide tree nodes where the item is not found</td>
            <td></td>
        </tr>
        <tr>
            <td><b>#11</b> (Aug 7 - 14)</td>
            <td>Code refactoring</td>
            <td></td>
        </tr>
        <tr>
            <td><b>#12</b> (Aug 14 - 21)</td>
            <td>Final implementations</td>
            <td></td>
        </tr>
        <tr style="background-color: yellow;">
            <td><b>#13</b> (Aug 21 - 28)</td>
            <td>Final week: Contributor Final Submission</td>
            <td>Final evaluation deadline (Aug 28 – 18:00 UTC)</td>
        </tr>
        <tr>
            <td>(Aug 28 - Sep 4)</td>
            <td> Mentor Final Evaluation</td>
            <td>Mentor evaluations deadline (Sep 4 – 18:00 UTC)</td>
        </tr>
        <tr>
            <td>(Sep 5, 2023)</td>
            <td>Initial results of Google Summer of Code 2023 announced</td>
            <td></td>
        </tr>
    </tbody>
</table>

<h3 id="project-summary">Project Summary</h3>

<p>This enhancement aims to provide a search functionality for “Tools &gt; Options”. LibreOffice is a complex application with a large and growing number of options. It is not easy to find the right needle in the haystack. Like most other complex applications, it will be valuable and useful enhancement to add a search field to the “Tools &gt; Options” dialog that iterates over the various tabs and filters where the search text is found.</p>

<p>Project page: <a href="https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1">https://summerofcode.withgoogle.com/programs/2023/projects/IKtSHIH1</a></p>

<p>Enhancement request on Bugzilla: <a href="https://bugs.documentfoundation.org/show_bug.cgi?id=49895">https://bugs.documentfoundation.org/show_bug.cgi?id=49895</a></p>]]></content><author><name>Bayram Çiçek</name></author><category term="libreoffice-dev" /><summary type="html"><![CDATA[Project: Search Field in Options]]></summary></entry><entry><title type="html">Mini-interview with LibreOffice &amp;amp; The Document Foundation membership</title><link href="https://bayramcicek.github.io/general/2021/11/27/interview-with-libreoffice-tdf-membership.html" rel="alternate" type="text/html" title="Mini-interview with LibreOffice &amp;amp; The Document Foundation membership" /><published>2021-11-27T14:18:51+00:00</published><updated>2021-11-27T14:18:51+00:00</updated><id>https://bayramcicek.github.io/general/2021/11/27/interview-with-libreoffice-tdf-membership</id><content type="html" xml:base="https://bayramcicek.github.io/general/2021/11/27/interview-with-libreoffice-tdf-membership.html"><![CDATA[<h4 id="heres-the-latest-developments-on-my-libreoffice-journey---after-google-summer-of-code-2021">Here’s the latest developments on my LibreOffice journey - after Google Summer of Code 2021:</h4>

<ul>
  <li>I’m a TDF member since October 2021.
    <ul>
      <li><a href="https://www.documentfoundation.org/governance/members/">https://www.documentfoundation.org/governance/members/</a>
<br /><br /></li>
    </ul>
  </li>
  <li>You can read the mini-interview about my contributions to LibreOffice and thoughts about TDF membership - on The Document Foundation blog:
    <ul>
      <li><a href="https://blog.documentfoundation.org/blog/2021/11/22/community-member-monday-bayram-cicek/">https://blog.documentfoundation.org/blog/2021/11/22/community-member-monday-bayram-cicek/</a></li>
    </ul>
  </li>
</ul>

<h4 id="exactly-1-year-after-first-patch">Exactly 1 year after first patch</h4>

<p>One year ago this month, I sent my <a href="https://gerrit.libreoffice.org/c/core/+/106489">first patch to LibreOffice/core</a> and announced it with a blog post titled <a href="https://bayramcicek.github.io/general/2020/11/25/libreoffice.html">Contributing to LibreOffice: First patch</a>. In that day, I couldn’t imagine that I would successfully complete GSoC’21 and become a TDF member within 1 year.</p>

<p>Thanks to LibreOffice community, mentors and developers for their help throughout the journey. Without your help, I couldn’t do it.</p>]]></content><author><name>Bayram Çiçek</name></author><category term="general" /><summary type="html"><![CDATA[Here’s the latest developments on my LibreOffice journey - after Google Summer of Code 2021:]]></summary></entry></feed>