Files
hpr_website/eps/hpr2877/hpr2877_full_shownotes.html
2025-10-28 18:39:57 +01:00

303 lines
13 KiB
HTML
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<meta name="author" content="Dave Morriss">
<title>Using Zenity with Pdmenu (HPR Show 2877)</title>
<style type="text/css">code{white-space: pre;}</style>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="stylesheet" href="http://hackerpublicradio.org/css/hpr.css">
</head>
<body id="home">
<div id="container" class="shadow">
<header>
<h1 class="title">Using Zenity with Pdmenu (HPR Show 2877)</h1>
<h2 class="subtitle">Zenity is a rather cool program that will display GTK+ dialogs from a script</h2>
<h2 class="author">Dave Morriss</h2>
<hr/>
</header>
<main id="maincontent">
<article>
<header>
<h1>Table of Contents</h1>
<nav id="TOC">
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#what-is-zenity">What is Zenity?</a></li>
<li><a href="#the-calendar-dialog">The Calendar dialog</a><ul>
<li><a href="#how-i-use-the-calendar-dialog-with-pdmenu">How I use the Calendar Dialog with Pdmenu</a></li>
</ul></li>
<li><a href="#the-forms-dialog">The Forms Dialog</a><ul>
<li><a href="#how-i-use-the-forms-dialog-with-pdmenu">How I use the Forms Dialog with Pdmenu</a></li>
</ul></li>
<li><a href="#summary">Summary</a></li>
<li><a href="#links">Links</a></li>
</ul>
</nav>
</header>
<h2 id="overview">Overview</h2>
<p>I use <code>pdmenu</code> a lot to help me do work on my main desktop PC. I did an HPR show on <a href="http://hackerpublicradio.org/eps/hpr2443" title="hpr2443 :: pdmenu"><code>pdmenu</code></a> on 13 December 2017 and the author <a href="https://joeyh.name/" title="Joey Hess">Joey Hess</a> responded in show <a href="http://hackerpublicradio.org/eps/hpr2459" title="hpr2459 :: free software&#39;s long tail">2459</a>.</p>
<p>In the intervening time I have also integrated <a href="https://help.gnome.org/users/zenity/" title="Zenity Manual"><code>Zenity</code></a> into my menus. This is a GUI tool which generates a number of different pop-up windows known as <em>dialogs</em>, which can display information, or into which information can be typed. The capabilities provided by <code>pdmenu</code> are a little too basic to enable me to do what I need to do.</p>
<p>I thought it might be of interest to show some examples of how I use this tool with <code>pdmenu</code>.</p>
<h2 id="what-is-zenity">What is Zenity?</h2>
<p>According to the manual:</p>
<blockquote>
<p>Zenity is a rewrite of <code>gdialog</code>, the GNOME port of <code>dialog</code> which allows you to display dialog boxes from the command line and shell scripts.</p>
</blockquote>
<p>Zenity runs on Linux, BSD and Windows, and a port to Mac OS X is available.</p>
<p>Its invoked from the command line or a script as:</p>
<pre><code>zenity [options]</code></pre>
<p>The most important option is one that defines what type of dialog is required. The types are:</p>
<table>
<thead>
<tr class="header">
<th>Dialog Option</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>--calendar</code></td>
<td>Display calendar dialog</td>
</tr>
<tr class="even">
<td><code>--entry</code></td>
<td>Display text entry dialog</td>
</tr>
<tr class="odd">
<td><code>--error</code></td>
<td>Display error dialog</td>
</tr>
<tr class="even">
<td><code>--file-selection</code></td>
<td>Display file selection dialog</td>
</tr>
<tr class="odd">
<td><code>--info</code></td>
<td>Display info dialog</td>
</tr>
<tr class="even">
<td><code>--list</code></td>
<td>Display list dialog</td>
</tr>
<tr class="odd">
<td><code>--notification</code></td>
<td>Display notification</td>
</tr>
<tr class="even">
<td><code>--progress</code></td>
<td>Display progress indication dialog</td>
</tr>
<tr class="odd">
<td><code>--question</code></td>
<td>Display question dialog</td>
</tr>
<tr class="even">
<td><code>--text-info</code></td>
<td>Display text information dialog</td>
</tr>
<tr class="odd">
<td><code>--warning</code></td>
<td>Display warning dialog</td>
</tr>
<tr class="even">
<td><code>--scale</code></td>
<td>Display scale dialog</td>
</tr>
<tr class="odd">
<td><code>--color-selection</code></td>
<td>Display color selection dialog</td>
</tr>
<tr class="even">
<td><code>--password</code></td>
<td>Display password dialog</td>
</tr>
<tr class="odd">
<td><code>--forms</code></td>
<td>Display forms dialog</td>
</tr>
</tbody>
</table>
<p>I will not go into lot of detail here because the manpage covers the subject well, as does the <a href="https://help.gnome.org/users/zenity/" title="Zenity Manual">online manual</a>. I will show a couple of examples of how I use Zenity dialogs with Pdmenu.</p>
<p>Each of these dialog selection options takes a set of further options which control the configuration and behaviour of the dialog window.</p>
<p>There are a few general options:</p>
<table>
<thead>
<tr class="header">
<th>Option</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>--title</code></td>
<td>Window title for the dialog box</td>
</tr>
<tr class="even">
<td><code>--window-icon=ICONPATH</code></td>
<td>Set the window icon.</td>
</tr>
<tr class="odd">
<td><code>--width=WIDTH</code></td>
<td>Set the dialog width</td>
</tr>
<tr class="even">
<td><code>--height=HEIGHT</code></td>
<td>Set the dialog height</td>
</tr>
<tr class="odd">
<td><code>--timeout=TIMEOUT</code></td>
<td>Set the dialog timeout in seconds</td>
</tr>
</tbody>
</table>
<h2 id="the-calendar-dialog">The Calendar dialog</h2>
<p>This takes the following options:</p>
<table>
<thead>
<tr class="header">
<th>Option</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>--text=STRING</code></td>
<td>Set the dialog text</td>
</tr>
<tr class="even">
<td><code>--day=INT</code></td>
<td>Set the calendar day</td>
</tr>
<tr class="odd">
<td><code>--month=INT</code></td>
<td>Set the calendar month</td>
</tr>
<tr class="even">
<td><code>--year=INT</code></td>
<td>Set the calendar year</td>
</tr>
<tr class="odd">
<td><code>--date-format=PATTERN</code></td>
<td>Set the format for the returned date</td>
</tr>
</tbody>
</table>
<p>Any of the options <code>--day=INT</code>, <code>--month=INT</code> or <code>--year=INT</code> will default to the values for the current day if omitted.</p>
<p>The format of the date returned can be controlled with the <code>--date-format=PATTERN</code> option which uses the <code>strftime</code> codes, like <code>%Y</code> for the 4-digit year.</p>
<p>Example:</p>
<pre><code>$ zenity --calendar --title=Test --date-format=&#39;%Y-%m-%d&#39;
2019-07-25</code></pre>
<figure>
<img src="hpr2877_zenity_calendar.png" alt="Zenity Calendar Dialog" /><figcaption><em>Zenity Calendar Dialog</em></figcaption>
</figure>
<h3 id="how-i-use-the-calendar-dialog-with-pdmenu">How I use the Calendar Dialog with Pdmenu</h3>
<p>Here is a menu definition from my <code>.pdmenurc</code> file:</p>
<pre><code>#
# Menu cnews3 - Update Wiki from wiki.db
#
menu:cnews3:Update Wiki from wiki.db:Update Wiki from wiki.db
exec:Update the _Wiki for this month:display:$HOME/HPR/Community_News/update_wiki
exec:Update the Wiki for any _month:pause:\
rep=$(zenity --calendar --title=&#39;Update Wiki&#39; --text=&quot;Select a month&quot; --date-format=&#39;01-%b-%Y&#39;) &amp;&amp;\
{ echo &quot;$rep&quot;; $HOME/HPR/Community_News/update_wiki &quot;$rep&quot;; }
nop:--
exit:E_xit Update Wiki from wiki.db</code></pre>
<p>I keep a SQLite database of HPR shows and my notes about them and use the notes when I am recording the monthly Community News episodes.</p>
<p>I have a script which will update a MediaWiki Wiki on one of my Raspberry Pis from this database, and thats whats being done here. I have a Wiki page per month of HPR shows and update these individually. That way I have the shows and my notes all organised together.</p>
<figure>
<img src="hpr2877_update_wiki_menu.png" alt="Pdmenu sub-menu" /><figcaption><em>Pdmenu sub-menu</em></figcaption>
</figure>
<p>For the action <code>&quot;Update the Wiki for any month&quot;</code> the menu will show a Zenity calendar and will return the date of the start of the month as <code>'01-Jul-2019'</code> for example.</p>
<p>Notice that <code>zenity</code> is being invoked in a command substitution, and the result is being stored in a variable called <code>rep</code>. The statement setting this variable may succeed (with a value in <code>$rep</code>) or may fail. The <code>&amp;&amp; { list }</code> part at the end handles the success case. In it the date returned is echoed (so I know what it is) and is passed to a script that updates the wiki for the particular month.</p>
<p>All I have to do to update a particular month when presented with the calendar dialog is to click the <code>'&lt;'</code> or <code>'&gt;'</code> sign to the left or right of the month name and it moves backward or forward one month. I then click <code>'OK'</code> when I have found the month I need, paying no heed to the day since its replaced by <code>'01'</code> in the menu.</p>
<h2 id="the-forms-dialog">The Forms Dialog</h2>
<p>This takes the following options:</p>
<table>
<thead>
<tr class="header">
<th>Option</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>--text=STRING</code></td>
<td>Set the dialog text</td>
</tr>
<tr class="even">
<td><code>--add-entry=FIELDNAME</code></td>
<td>Add a new Entry in forms dialog</td>
</tr>
<tr class="odd">
<td><code>--add-password=FIELDNAME</code></td>
<td>Add a new Password Entry in forms dialog</td>
</tr>
<tr class="even">
<td><code>--add-calendar=FIELDNAME</code></td>
<td>Add a new Calendar in forms dialog</td>
</tr>
<tr class="odd">
<td><code>--separator=STRING</code></td>
<td>Set output separator character</td>
</tr>
<tr class="even">
<td><code>--forms-date-format=PATTERN</code></td>
<td>Set the format for the returned date</td>
</tr>
</tbody>
</table>
<p>This dialog lets you assemble some other dialog types into a form.</p>
<p>Example:</p>
<pre><code>$ zenity --forms --text=&quot;Name and DoB&quot; --add-entry=FirstName --add-entry=LastName \
--add-calendar=DoB --forms-date-format=&#39;%Y-%m-%d&#39;
Joe|Bloggs|2000-04-01</code></pre>
<figure>
<img src="hpr2877_form_example.png" alt="Zenity Forms Dialog" /><figcaption><em>Zenity Forms Dialog</em></figcaption>
</figure>
<h3 id="how-i-use-the-forms-dialog-with-pdmenu">How I use the Forms Dialog with Pdmenu</h3>
<p>Here is a piece of a menu definition from my <code>.pdmenurc</code> file:</p>
<pre><code> exec:_Collect JSON from IA:pause:\
rep=$(zenity --forms --text=&#39;Enter show numbers&#39; --add-entry=Start --add-entry=End) &amp;&amp;\
$HOME/HPR/InternetArchive/collect_show_data &quot;${rep%|*}&quot; &quot;${rep#*|}&quot;</code></pre>
<p>I keep another SQLite database with information about HPR shows which have been written to the Internet Archive (archive.org). I have scripts which collect data from archive.org in the JSON format, save it in a file and then add it to my database.</p>
<p>The above menu fragment takes in the start and end show numbers in a range that has been uploaded (usually a weeks worth, 5 shows at a time), then it queries archive.org for details of shows.</p>
<p>This is what the full menu looks like:</p>
<figure>
<img src="hpr2877_IA_menu.png" alt="Pdmenu for IA management" /><figcaption><em>Pdmenu for IA management</em></figcaption>
</figure>
<p>The following dialog is shown to enable show number entry:</p>
<figure>
<img src="hpr2877_IA_form.png" alt="Zenity range dialog" /><figcaption><em>Zenity range dialog</em></figcaption>
</figure>
<p>Note that after <code>'&amp;&amp;'</code> in the menu definition we do not need enclosing curly braces since there is only one command.</p>
<p>Note also that the <code>zenity</code> call returns two numbers separated by the default separator (<code>'|'</code>). These are separated out when calling the script that does the work, making use of the shells parameter substitution facilities. See the <em>Bash Tips</em> shows on HPR, particularly episode <a href="http://hackerpublicradio.org/eps/hpr1648" title="hpr1648 :: Bash parameter manipulation">1648</a> (<em>Remove matching prefix pattern</em> and <em>Remove matching suffix pattern</em>).</p>
<h2 id="summary">Summary</h2>
<p>I <em>need</em> menus since I can never remember what I am supposed to do to carry out workflows and other processes! My motto is “<em>If in doubt, write a script</em>”!</p>
<p>The facilities in Pdmenu for prompting and gathering information are a bit too basic for my needs, but Zenity does a fine job for me here. OK, so it has moved me away from my usual preference for command-line stuff, but I find this to be a great compromise!</p>
<p>One slight grumble about Pdmenu is that the shell it uses to run commands is <code>'sh'</code>, not <code>'bash'</code>, so some of the <em>Bashisms</em> Id like to use are not available. Its not hampering me too much now, and when it does Ill maybe consider changing the source of <code>pdmenu</code> to do what I want if I can.</p>
<h2 id="links">Links</h2>
<ul>
<li>Pdmenu:
<ul>
<li><a href="https://joeyh.name/code/pdmenu/">Pdmenu website</a></li>
<li><a href="https://joeyh.name/">Joey Hess</a></li>
</ul></li>
<li>Zenity
<ul>
<li><a href="https://en.wikipedia.org/wiki/Zenity">Wikipedia page</a></li>
<li><a href="https://help.gnome.org/users/zenity/">Zenity Manual</a></li>
</ul></li>
</ul>
</article>
</main>
</div>
</body>
</html>