Blame SOURCES/0005-math-converter-Hide-currency-conversion-UI-if-there-.patch

bb3dc4
From 213feffa73f09303914f0032ba9976ecb17629cd Mon Sep 17 00:00:00 2001
bb3dc4
From: Ray Strode <rstrode@redhat.com>
bb3dc4
Date: Thu, 13 May 2021 11:29:33 -0400
bb3dc4
Subject: [PATCH 5/5] math-converter: Hide currency conversion UI if there
bb3dc4
 isn't a loaded currency provider
bb3dc4
bb3dc4
If the admin sets a currency refresh-interval of 0, then the currency
bb3dc4
conversion data will be missing or woefully out of date.
bb3dc4
bb3dc4
This commit changes the code to hide the conversion UI in this case.
bb3dc4
---
bb3dc4
 lib/currency.vala         |  15 ++-
bb3dc4
 src/gnome-calculator.vala |   1 +
bb3dc4
 src/math-converter.ui     | 264 ++++++++++++++++++++++++--------------
bb3dc4
 src/math-converter.vala   |  18 ++-
bb3dc4
 4 files changed, 197 insertions(+), 101 deletions(-)
bb3dc4
bb3dc4
diff --git a/lib/currency.vala b/lib/currency.vala
bb3dc4
index 2adb11e4..4270b701 100644
bb3dc4
--- a/lib/currency.vala
bb3dc4
+++ b/lib/currency.vala
bb3dc4
@@ -1,53 +1,62 @@
bb3dc4
 /*
bb3dc4
  * Copyright (C) 2008-2012 Robert Ancell.
bb3dc4
  *
bb3dc4
  * This program is free software: you can redistribute it and/or modify it under
bb3dc4
  * the terms of the GNU General Public License as published by the Free Software
bb3dc4
  * Foundation, either version 3 of the License, or (at your option) any later
bb3dc4
  * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
bb3dc4
  * license.
bb3dc4
  */
bb3dc4
 
bb3dc4
 static bool downloading_imf_rates = false;
bb3dc4
 static bool downloading_ecb_rates = false;
bb3dc4
-static bool loaded_rates = false;
bb3dc4
 private static CurrencyManager? default_currency_manager = null;
bb3dc4
 
bb3dc4
 public class CurrencyManager : Object
bb3dc4
 {
bb3dc4
     private List<Currency> currencies;
bb3dc4
 
bb3dc4
     public int refresh_interval { get; set; }
bb3dc4
 
bb3dc4
     public signal void updated ();
bb3dc4
 
bb3dc4
+    public bool loaded { get; private set; }
bb3dc4
+
bb3dc4
+    public void refresh_sync () {
bb3dc4
+        loaded = false;
bb3dc4
+        load_rates ();
bb3dc4
+
bb3dc4
+        if (!loaded)
bb3dc4
+            updated ();
bb3dc4
+    }
bb3dc4
+
bb3dc4
     public static CurrencyManager get_default ()
bb3dc4
     {
bb3dc4
         if (default_currency_manager != null)
bb3dc4
             return default_currency_manager;
bb3dc4
 
bb3dc4
         default_currency_manager = new CurrencyManager ();
bb3dc4
 
bb3dc4
         default_currency_manager.currencies.append (new Currency ("AED", _("UAE Dirham"), "إ.د"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("AUD", _("Australian Dollar"), "$"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("BGN", _("Bulgarian Lev"), "лв"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("BHD", _("Bahraini Dinar"), ".ب.د"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("BND", _("Brunei Dollar"), "$"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("BRL", _("Brazilian Real"), "R$"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("BWP", _("Botswana Pula"), "P"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("CAD", _("Canadian Dollar"), "$"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("CFA", _("CFA Franc"), "Fr"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("CHF", _("Swiss Franc"), "Fr"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("CLP", _("Chilean Peso"), "$"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("CNY", _("Chinese Yuan"), "¥"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("COP", _("Colombian Peso"), "$"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("CZK", _("Czech Koruna"), "Kč"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("DKK", _("Danish Krone"), "kr"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("DZD", _("Algerian Dinar"), "ج.د"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("EEK", _("Estonian Kroon"), "KR"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("EUR", _("Euro"), "€"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("GBP", _("British Pound Sterling"), "£"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("HKD", _("Hong Kong Dollar"), "$"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("HRK", _("Croatian Kuna"), "kn"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("HUF", _("Hungarian Forint"), "Ft"));
bb3dc4
         default_currency_manager.currencies.append (new Currency ("IDR", _("Indonesian Rupiah"), "Rp"));
bb3dc4
@@ -377,81 +386,81 @@ public class CurrencyManager : Object
bb3dc4
         }
bb3dc4
 
bb3dc4
         Xml.Parser.cleanup ();
bb3dc4
     }
bb3dc4
 
bb3dc4
     private void download_rates ()
bb3dc4
     {
bb3dc4
         if (refresh_interval == 0)
bb3dc4
             return;
bb3dc4
 
bb3dc4
         /* Update rates if necessary */
bb3dc4
         var path = get_imf_rate_filepath ();
bb3dc4
         if (!downloading_imf_rates && file_needs_update (path, refresh_interval))
bb3dc4
         {
bb3dc4
             downloading_imf_rates = true;
bb3dc4
             debug ("Downloading rates from the IMF...");
bb3dc4
             download_file.begin ("https://www.imf.org/external/np/fin/data/rms_five.aspx?tsvflag=Y", path, "IMF");
bb3dc4
         }
bb3dc4
         path = get_ecb_rate_filepath ();
bb3dc4
         if (!downloading_ecb_rates && file_needs_update (path, refresh_interval))
bb3dc4
         {
bb3dc4
             downloading_ecb_rates = true;
bb3dc4
             debug ("Downloading rates from the ECB...");
bb3dc4
             download_file.begin ("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml", path, "ECB");
bb3dc4
         }
bb3dc4
     }
bb3dc4
 
bb3dc4
     private bool load_rates ()
bb3dc4
     {
bb3dc4
         /* Already loaded */
bb3dc4
-        if (loaded_rates)
bb3dc4
+        if (loaded)
bb3dc4
             return true;
bb3dc4
 
bb3dc4
         if (refresh_interval == 0)
bb3dc4
             return false;
bb3dc4
 
bb3dc4
         /* In process */
bb3dc4
         if (downloading_imf_rates || downloading_ecb_rates)
bb3dc4
             return false;
bb3dc4
 
bb3dc4
         /* Use the IMF provided values and top up with currencies tracked by the ECB and not the IMF */
bb3dc4
         load_imf_rates ();
bb3dc4
         load_ecb_rates ();
bb3dc4
 
bb3dc4
         /* Check if we couldn't find out a currency */
bb3dc4
         foreach (var c in currencies)
bb3dc4
             if (c.get_value () == null || c.get_value ().is_zero ())
bb3dc4
                 warning ("Currency %s is not provided by IMF or ECB", c.name);
bb3dc4
 
bb3dc4
         debug ("Rates loaded");
bb3dc4
-        loaded_rates = true;
bb3dc4
+        loaded = true;
bb3dc4
 
bb3dc4
         updated ();
bb3dc4
 
bb3dc4
         return true;
bb3dc4
     }
bb3dc4
 
bb3dc4
     public Number? get_value (string currency)
bb3dc4
     {
bb3dc4
         /* Make sure that the rates we're returning are up to date. (Just in case the application is running from a long long time) */
bb3dc4
         download_rates ();
bb3dc4
 
bb3dc4
         if (!load_rates ())
bb3dc4
             return null;
bb3dc4
 
bb3dc4
         var c = get_currency (currency);
bb3dc4
         if (c != null)
bb3dc4
             return c.get_value ();
bb3dc4
         else
bb3dc4
             return null;
bb3dc4
     }
bb3dc4
 
bb3dc4
     private async void download_file (string uri, string filename, string source)
bb3dc4
     {
bb3dc4
 
bb3dc4
         var directory = Path.get_dirname (filename);
bb3dc4
         DirUtils.create_with_parents (directory, 0755);
bb3dc4
 
bb3dc4
         var dest = File.new_for_path (filename);
bb3dc4
         var session = new Soup.Session ();
bb3dc4
         var message = new Soup.Message ("GET", uri);
bb3dc4
diff --git a/src/gnome-calculator.vala b/src/gnome-calculator.vala
bb3dc4
index 89a83450..0aa0054e 100644
bb3dc4
--- a/src/gnome-calculator.vala
bb3dc4
+++ b/src/gnome-calculator.vala
bb3dc4
@@ -104,60 +104,61 @@ public class Calculator : Gtk.Application
bb3dc4
         }
bb3dc4
 
bb3dc4
         var menu = builder.get_object ("appmenu") as MenuModel;
bb3dc4
         set_app_menu (menu);
bb3dc4
 
bb3dc4
         set_accels_for_action ("win.mode::basic", {"<alt>B"});
bb3dc4
         set_accels_for_action ("win.mode::advanced", {"<alt>A"});
bb3dc4
         set_accels_for_action ("win.mode::financial", {"<alt>F"});
bb3dc4
         set_accels_for_action ("win.mode::programming", {"<alt>P"});
bb3dc4
         set_accels_for_action ("win.mode::keyboard", {"<alt>K"});
bb3dc4
         set_accels_for_action ("win.copy", {"<control>C"});
bb3dc4
         set_accels_for_action ("win.paste", {"<control>V"});
bb3dc4
         set_accels_for_action ("win.undo", {"<control>Z"});
bb3dc4
         set_accels_for_action ("win.close", {"<control>W"});
bb3dc4
         set_accels_for_action ("win.redo", {"<control><shift>Z"});
bb3dc4
         return current_window;
bb3dc4
     }
bb3dc4
 
bb3dc4
     protected override void startup ()
bb3dc4
     {
bb3dc4
         base.startup ();
bb3dc4
 
bb3dc4
         settings = new Settings ("org.gnome.calculator");
bb3dc4
         last_opened_window = create_new_window (settings);
bb3dc4
         // restore the first window position from the settings
bb3dc4
         load_window_position (last_opened_window);
bb3dc4
         CurrencyManager.get_default ().refresh_interval = settings.get_int ("refresh-interval");
bb3dc4
 
bb3dc4
         settings.changed["refresh-interval"].connect(() => {
bb3dc4
             CurrencyManager.get_default ().refresh_interval = settings.get_int ("refresh-interval");
bb3dc4
+            CurrencyManager.get_default ().refresh_sync ();
bb3dc4
         });
bb3dc4
     }
bb3dc4
 
bb3dc4
     private MathWindow get_active_math_window ()
bb3dc4
     {
bb3dc4
         return (MathWindow) get_active_window ();
bb3dc4
     }
bb3dc4
 
bb3dc4
     protected override void activate ()
bb3dc4
     {
bb3dc4
         base.activate ();
bb3dc4
 
bb3dc4
         last_opened_window.present ();
bb3dc4
         if (equation_string != "" && equation_string != null)
bb3dc4
         {
bb3dc4
             var equations = (equation_string.compress ()).split ("\n",0);
bb3dc4
             for (var i = 0; i < equations.length; i++)
bb3dc4
             {
bb3dc4
                 if ((equations [i].strip ()).length > 0)
bb3dc4
                     last_opened_window.equation.set (equations [i]);
bb3dc4
                 else
bb3dc4
                     last_opened_window.equation.solve ();
bb3dc4
             }
bb3dc4
         }
bb3dc4
         if (mode_string != "" && mode_string != null)
bb3dc4
         {
bb3dc4
             var mode = ButtonMode.BASIC;
bb3dc4
 
bb3dc4
             switch (mode_string)
bb3dc4
             {
bb3dc4
diff --git a/src/math-converter.ui b/src/math-converter.ui
bb3dc4
index 9ec03820..fb633f10 100644
bb3dc4
--- a/src/math-converter.ui
bb3dc4
+++ b/src/math-converter.ui
bb3dc4
@@ -1,137 +1,207 @@
bb3dc4
 
bb3dc4
 
bb3dc4
 <interface>
bb3dc4
   <requires lib="gtk+" version="3.16"/>
bb3dc4
   <template class="MathConverter" parent="GtkGrid">
bb3dc4
-    <property name="visible">False</property>
bb3dc4
-    <property name="can_focus">False</property>
bb3dc4
-    <property name="row_spacing">6</property>
bb3dc4
-    <property name="column_spacing">6</property>
bb3dc4
     <child>
bb3dc4
-      <object class="GtkButton" id="swap_button">
bb3dc4
-        <property name="label">⇆</property>
bb3dc4
-        <property name="visible">True</property>
bb3dc4
-        <property name="can_focus">False</property>
bb3dc4
-        <property name="receives_default">False</property>
bb3dc4
-        <property name="tooltip_text" translatable="yes">Switch conversion units</property>
bb3dc4
-        <property name="relief">none</property>
bb3dc4
-        <signal name="clicked" handler="swap_button_clicked_cb" swapped="no"/>
bb3dc4
-      </object>
bb3dc4
-      <packing>
bb3dc4
-        <property name="left_attach">3</property>
bb3dc4
-        <property name="top_attach">0</property>
bb3dc4
-      </packing>
bb3dc4
-    </child>
bb3dc4
-    <child>
bb3dc4
-      <object class="GtkButton" id="in_button">
bb3dc4
-        <property name="visible">True</property>
bb3dc4
-        <property name="can_focus">False</property>
bb3dc4
-        <property name="label" translatable="yes"> to </property>
bb3dc4
-        <signal name="clicked" handler="convert_button_clicked_cb" swapped="no"/>
bb3dc4
-        <style>
bb3dc4
-          <class name="flat"/>
bb3dc4
-        </style>
bb3dc4
-      </object>
bb3dc4
-      <packing>
bb3dc4
-        <property name="left_attach">1</property>
bb3dc4
-        <property name="top_attach">0</property>
bb3dc4
-      </packing>
bb3dc4
-    </child>
bb3dc4
-    <child>
bb3dc4
-      <object class="GtkComboBox" id="from_combo">
bb3dc4
-        <property name="visible">True</property>
bb3dc4
-        <property name="can_focus">False</property>
bb3dc4
-        <signal name="changed" handler="from_combobox_changed_cb" swapped="no"/>
bb3dc4
-        <child>
bb3dc4
-          <object class="GtkCellRendererText" id="from_renderer"/>
bb3dc4
-          <attributes>
bb3dc4
-            <attribute name="text">0</attribute>
bb3dc4
-          </attributes>
bb3dc4
-        </child>
bb3dc4
-      </object>
bb3dc4
-      <packing>
bb3dc4
-        <property name="left_attach">0</property>
bb3dc4
-        <property name="top_attach">0</property>
bb3dc4
-      </packing>
bb3dc4
-    </child>
bb3dc4
-    <child>
bb3dc4
-      <object class="GtkComboBox" id="to_combo">
bb3dc4
-        <property name="visible">True</property>
bb3dc4
-        <property name="can_focus">False</property>
bb3dc4
-        <property name="opacity">0.88</property>
bb3dc4
-        <signal name="changed" handler="to_combobox_changed_cb" swapped="no"/>
bb3dc4
-        <child>
bb3dc4
-          <object class="GtkCellRendererText" id="to_renderer"/>
bb3dc4
-          <attributes>
bb3dc4
-            <attribute name="text">0</attribute>
bb3dc4
-          </attributes>
bb3dc4
-        </child>
bb3dc4
-      </object>
bb3dc4
-      <packing>
bb3dc4
-        <property name="left_attach">2</property>
bb3dc4
-        <property name="top_attach">0</property>
bb3dc4
-      </packing>
bb3dc4
-    </child>
bb3dc4
-    <child>
bb3dc4
-      <object class="GtkBox" id="result_holder">
bb3dc4
-        <property name="visible">True</property>
bb3dc4
+      <object class="GtkBox" id="outer_box">
bb3dc4
+        <property name="visible" bind-source="MathConverter" bind-property="outer-box-visible" bind-flags="sync-create|bidirectional"/>
bb3dc4
         <property name="orientation">horizontal</property>
bb3dc4
         <property name="sensitive">True</property>
bb3dc4
-        <property name="spacing">6</property>
bb3dc4
         <property name="can_focus">False</property>
bb3dc4
-        <property name="halign">end</property>
bb3dc4
+        <property name="halign">center</property>
bb3dc4
         <property name="valign">center</property>
bb3dc4
         <property name="hexpand">True</property>
bb3dc4
         <property name="vexpand">False</property>
bb3dc4
         <child>
bb3dc4
-          <object class="GtkLabel" id="from_label">
bb3dc4
+          <object class="GtkComboBox" id="from_combo">
bb3dc4
             <property name="visible">True</property>
bb3dc4
-            <property name="sensitive">True</property>
bb3dc4
             <property name="can_focus">False</property>
bb3dc4
-            <property name="halign">start</property>
bb3dc4
-            <property name="valign">center</property>
bb3dc4
             <property name="hexpand">True</property>
bb3dc4
-            <property name="vexpand">False</property>
bb3dc4
-            <property name="justify">center</property>
bb3dc4
-            <property name="xalign">0</property>
bb3dc4
-            <property name="yalign">0</property>
bb3dc4
+            <signal name="changed" handler="from_combobox_changed_cb" swapped="no"/>
bb3dc4
+            <child>
bb3dc4
+              <object class="GtkCellRendererText" id="from_renderer">
bb3dc4
+                <property name="ellipsize">end</property>
bb3dc4
+              </object>
bb3dc4
+              <attributes>
bb3dc4
+                <attribute name="text">0</attribute>
bb3dc4
+              </attributes>
bb3dc4
+            </child>
bb3dc4
+          </object>
bb3dc4
+        </child>
bb3dc4
+        <child>
bb3dc4
+          <object class="GtkButton" id="in_button">
bb3dc4
+            <property name="visible">True</property>
bb3dc4
+            <property name="can_focus">False</property>
bb3dc4
+            <property name="label" translatable="yes"> to </property>
bb3dc4
+            <signal name="clicked" handler="convert_button_clicked_cb" swapped="no"/>
bb3dc4
+            <style>
bb3dc4
+              <class name="flat"/>
bb3dc4
+            </style>
bb3dc4
+          </object>
bb3dc4
+        </child>
bb3dc4
+        <child>
bb3dc4
+          <object class="GtkComboBox" id="to_combo">
bb3dc4
+            <property name="visible">True</property>
bb3dc4
+            <property name="can_focus">False</property>
bb3dc4
+            <property name="opacity">0.88</property>
bb3dc4
+            <property name="hexpand">True</property>
bb3dc4
+            <signal name="changed" handler="to_combobox_changed_cb" swapped="no"/>
bb3dc4
+            <child>
bb3dc4
+              <object class="GtkCellRendererText" id="to_renderer">
bb3dc4
+                <property name="ellipsize">end</property>
bb3dc4
+              </object>
bb3dc4
+              <attributes>
bb3dc4
+                <attribute name="text">0</attribute>
bb3dc4
+              </attributes>
bb3dc4
+            </child>
bb3dc4
+          </object>
bb3dc4
+        </child>
bb3dc4
+        <child>
bb3dc4
+          <object class="GtkButton" id="swap_button">
bb3dc4
+            <property name="label">⇆</property>
bb3dc4
+            <property name="visible">True</property>
bb3dc4
+            <property name="can_focus">False</property>
bb3dc4
+            <property name="receives_default">False</property>
bb3dc4
+            <property name="tooltip_text" translatable="yes">Switch conversion units</property>
bb3dc4
+            <property name="relief">none</property>
bb3dc4
+            <signal name="clicked" handler="swap_button_clicked_cb" swapped="no"/>
bb3dc4
           </object>
bb3dc4
         </child>
bb3dc4
         <child>
bb3dc4
-          <object class="GtkLabel" id="convert_equals">
bb3dc4
+          <object class="GtkBox" id="result_holder">
bb3dc4
             <property name="visible">True</property>
bb3dc4
+            <property name="orientation">horizontal</property>
bb3dc4
             <property name="sensitive">True</property>
bb3dc4
+            <property name="spacing">6</property>
bb3dc4
+            <property name="margin-end">2</property>
bb3dc4
             <property name="can_focus">False</property>
bb3dc4
-            <property name="halign">center</property>
bb3dc4
+            <property name="halign">end</property>
bb3dc4
             <property name="valign">center</property>
bb3dc4
-            <property name="hexpand">False</property>
bb3dc4
+            <property name="hexpand">True</property>
bb3dc4
             <property name="vexpand">False</property>
bb3dc4
-            <property name="justify">center</property>
bb3dc4
-            <property name="xalign">0</property>
bb3dc4
-            <property name="yalign">0</property>
bb3dc4
-            <property name="label" translatable="yes" context="convertion equals label">=</property>
bb3dc4
+            <property name="visible">True</property>
bb3dc4
+            <child>
bb3dc4
+              <object class="GtkLabel" id="from_label">
bb3dc4
+                <property name="visible">True</property>
bb3dc4
+                <property name="sensitive">True</property>
bb3dc4
+                <property name="selectable">True</property>
bb3dc4
+                <property name="can_focus">False</property>
bb3dc4
+                <property name="halign">start</property>
bb3dc4
+                <property name="valign">center</property>
bb3dc4
+                <property name="hexpand">True</property>
bb3dc4
+                <property name="vexpand">False</property>
bb3dc4
+                <property name="justify">center</property>
bb3dc4
+                <property name="ellipsize">end</property>
bb3dc4
+                <property name="xalign">0</property>
bb3dc4
+                <property name="yalign">0</property>
bb3dc4
+              </object>
bb3dc4
+            </child>
bb3dc4
+            <child>
bb3dc4
+              <object class="GtkLabel" id="convert_equals">
bb3dc4
+                <property name="visible">True</property>
bb3dc4
+                <property name="sensitive">True</property>
bb3dc4
+                <property name="can_focus">False</property>
bb3dc4
+                <property name="halign">center</property>
bb3dc4
+                <property name="valign">center</property>
bb3dc4
+                <property name="hexpand">False</property>
bb3dc4
+                <property name="vexpand">False</property>
bb3dc4
+                <property name="justify">center</property>
bb3dc4
+                <property name="xalign">0</property>
bb3dc4
+                <property name="yalign">0</property>
bb3dc4
+                <property name="label" translatable="yes" context="convertion equals label">=</property>
bb3dc4
+              </object>
bb3dc4
+            </child>
bb3dc4
+            <child>
bb3dc4
+              <object class="GtkLabel" id="to_label">
bb3dc4
+                <property name="visible">True</property>
bb3dc4
+                <property name="sensitive">True</property>
bb3dc4
+                <property name="selectable">True</property>
bb3dc4
+                <property name="can_focus">False</property>
bb3dc4
+                <property name="halign">fill</property>
bb3dc4
+                <property name="valign">center</property>
bb3dc4
+                <property name="hexpand">True</property>
bb3dc4
+                <property name="vexpand">False</property>
bb3dc4
+                <property name="justify">center</property>
bb3dc4
+                <property name="ellipsize">end</property>
bb3dc4
+                <property name="xalign">0</property>
bb3dc4
+                <property name="yalign">0</property>
bb3dc4
+              </object>
bb3dc4
+              <packing>
bb3dc4
+                <property name="expand">false</property>
bb3dc4
+              </packing>
bb3dc4
+            </child>
bb3dc4
           </object>
bb3dc4
         </child>
bb3dc4
         <child>
bb3dc4
-          <object class="GtkLabel" id="to_label">
bb3dc4
-            <property name="visible">True</property>
bb3dc4
+          <object class="GtkBox">
bb3dc4
+            <property name="orientation">horizontal</property>
bb3dc4
             <property name="sensitive">True</property>
bb3dc4
+            <property name="spacing">6</property>
bb3dc4
             <property name="can_focus">False</property>
bb3dc4
             <property name="halign">end</property>
bb3dc4
             <property name="valign">center</property>
bb3dc4
             <property name="hexpand">True</property>
bb3dc4
             <property name="vexpand">False</property>
bb3dc4
-            <property name="justify">center</property>
bb3dc4
-            <property name="xalign">0</property>
bb3dc4
-            <property name="yalign">0</property>
bb3dc4
+            <property name="visible" bind-source="result_holder" bind-property="visible" bind-flags="sync-create|invert-boolean"/>
bb3dc4
+            <child>
bb3dc4
+              <object class="GtkLabel">
bb3dc4
+                <property name="visible">True</property>
bb3dc4
+                <property name="sensitive">True</property>
bb3dc4
+                <property name="selectable">True</property>
bb3dc4
+                <property name="can_focus">False</property>
bb3dc4
+                <property name="halign">start</property>
bb3dc4
+                <property name="valign">center</property>
bb3dc4
+                <property name="hexpand">True</property>
bb3dc4
+                <property name="vexpand">False</property>
bb3dc4
+                <property name="justify">center</property>
bb3dc4
+                <property name="ellipsize">end</property>
bb3dc4
+                <property name="xalign">0</property>
bb3dc4
+                <property name="yalign">0</property>
bb3dc4
+                <property name="label" bind-source="from_label" bind-property="label" bind-flags="sync-create|bidirectional"/>
bb3dc4
+              </object>
bb3dc4
+            </child>
bb3dc4
+            <child>
bb3dc4
+              <object class="GtkLabel">
bb3dc4
+                <property name="visible">True</property>
bb3dc4
+                <property name="sensitive">True</property>
bb3dc4
+                <property name="can_focus">False</property>
bb3dc4
+                <property name="halign">center</property>
bb3dc4
+                <property name="valign">center</property>
bb3dc4
+                <property name="hexpand">False</property>
bb3dc4
+                <property name="vexpand">False</property>
bb3dc4
+                <property name="justify">center</property>
bb3dc4
+                <property name="xalign">0</property>
bb3dc4
+                <property name="yalign">0</property>
bb3dc4
+                <property name="label" bind-source="convert_equals" bind-property="label" bind-flags="sync-create|bidirectional"/>
bb3dc4
+              </object>
bb3dc4
+            </child>
bb3dc4
+            <child>
bb3dc4
+              <object class="GtkLabel">
bb3dc4
+                <property name="visible">True</property>
bb3dc4
+                <property name="sensitive">True</property>
bb3dc4
+                <property name="selectable">True</property>
bb3dc4
+                <property name="can_focus">False</property>
bb3dc4
+                <property name="halign">fill</property>
bb3dc4
+                <property name="valign">center</property>
bb3dc4
+                <property name="hexpand">True</property>
bb3dc4
+                <property name="vexpand">False</property>
bb3dc4
+                <property name="justify">center</property>
bb3dc4
+                <property name="ellipsize">end</property>
bb3dc4
+                <property name="xalign">0</property>
bb3dc4
+                <property name="yalign">0</property>
bb3dc4
+                <property name="label" bind-source="to_label" bind-property="label" bind-flags="sync-create|bidirectional"/>
bb3dc4
+              </object>
bb3dc4
+            </child>
bb3dc4
           </object>
bb3dc4
-          <packing>
bb3dc4
-            <property name="expand">false</property>
bb3dc4
-            <property name="fill">true</property>
bb3dc4
-          </packing>
bb3dc4
         </child>
bb3dc4
       </object>
bb3dc4
+      <packing>
bb3dc4
+        <property name="left-attach">0</property>
bb3dc4
+        <property name="top-attach">1</property>
bb3dc4
+        <property name="width">4</property>
bb3dc4
+      </packing>
bb3dc4
     </child>
bb3dc4
   </template>
bb3dc4
 </interface>
bb3dc4
 
bb3dc4
diff --git a/src/math-converter.vala b/src/math-converter.vala
bb3dc4
index a83dea24..c470b91f 100644
bb3dc4
--- a/src/math-converter.vala
bb3dc4
+++ b/src/math-converter.vala
bb3dc4
@@ -1,128 +1,144 @@
bb3dc4
 /*
bb3dc4
  * Copyright (C) 2008-2012 Robert Ancell
bb3dc4
  *
bb3dc4
  * This program is free software: you can redistribute it and/or modify it under
bb3dc4
  * the terms of the GNU General Public License as published by the Free Software
bb3dc4
  * Foundation, either version 3 of the License, or (at your option) any later
bb3dc4
  * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
bb3dc4
  * license.
bb3dc4
  */
bb3dc4
 
bb3dc4
 [GtkTemplate (ui = "/org/gnome/calculator/math-converter.ui")]
bb3dc4
 public class MathConverter : Gtk.Grid
bb3dc4
 {
bb3dc4
     private MathEquation equation = null;
bb3dc4
 
bb3dc4
     private string category;
bb3dc4
 
bb3dc4
     [GtkChild]
bb3dc4
     private Gtk.CellRendererText from_renderer;
bb3dc4
 
bb3dc4
     [GtkChild]
bb3dc4
     private Gtk.ComboBox from_combo;
bb3dc4
     [GtkChild]
bb3dc4
     private Gtk.ComboBox to_combo;
bb3dc4
     [GtkChild]
bb3dc4
     private Gtk.Label from_label;
bb3dc4
     [GtkChild]
bb3dc4
     private Gtk.Label to_label;
bb3dc4
+    public bool outer_box_visible { set; get; default = false; }
bb3dc4
 
bb3dc4
     public signal void changed ();
bb3dc4
 
bb3dc4
     construct
bb3dc4
     {
bb3dc4
         from_combo.set_cell_data_func (from_renderer, from_cell_data_func);
bb3dc4
-        CurrencyManager.get_default ().updated.connect (() => { update_result_label (); });
bb3dc4
+        CurrencyManager.get_default ().updated.connect (() => {
bb3dc4
+            update_visibility ();
bb3dc4
+            update_result_label ();
bb3dc4
+        });
bb3dc4
 
bb3dc4
+        update_visibility ();
bb3dc4
         update_from_model ();
bb3dc4
     }
bb3dc4
 
bb3dc4
     public MathConverter (MathEquation equation)
bb3dc4
     {
bb3dc4
       set_equation (equation);
bb3dc4
     }
bb3dc4
 
bb3dc4
     public void set_equation (MathEquation equation)
bb3dc4
     {
bb3dc4
         this.equation = equation;
bb3dc4
         equation.notify["display"].connect ((pspec) => { update_result_label (); });
bb3dc4
     }
bb3dc4
 
bb3dc4
     public void set_category (string? category)
bb3dc4
     {
bb3dc4
         if (this.category == category)
bb3dc4
             return;
bb3dc4
         this.category = category;
bb3dc4
 
bb3dc4
+        update_visibility ();
bb3dc4
         update_from_model ();
bb3dc4
     }
bb3dc4
 
bb3dc4
     public string get_category ()
bb3dc4
     {
bb3dc4
         return category;
bb3dc4
     }
bb3dc4
 
bb3dc4
     public void set_conversion (/*string category,*/ string unit_a, string unit_b)
bb3dc4
     {
bb3dc4
         var ua = UnitManager.get_default ().get_unit_by_name (unit_a);
bb3dc4
         var ub = UnitManager.get_default ().get_unit_by_name (unit_b);
bb3dc4
         if (ua == null || ub == null)
bb3dc4
         {
bb3dc4
             /* Select the first unit */
bb3dc4
             var model = from_combo.get_model ();
bb3dc4
             Gtk.TreeIter iter;
bb3dc4
             if (model.get_iter_first (out iter))
bb3dc4
             {
bb3dc4
                 Gtk.TreeIter child_iter;
bb3dc4
                 while (model.iter_children (out child_iter, iter))
bb3dc4
                     iter = child_iter;
bb3dc4
                 from_combo.set_active_iter (iter);
bb3dc4
             }
bb3dc4
             return;
bb3dc4
         }
bb3dc4
 
bb3dc4
         set_active_unit (from_combo, null, ua);
bb3dc4
         set_active_unit (to_combo, null, ub);
bb3dc4
     }
bb3dc4
 
bb3dc4
     public void get_conversion (out Unit from_unit, out Unit to_unit)
bb3dc4
     {
bb3dc4
         Gtk.TreeIter from_iter, to_iter;
bb3dc4
 
bb3dc4
         from_combo.get_active_iter (out from_iter);
bb3dc4
         to_combo.get_active_iter (out to_iter);
bb3dc4
 
bb3dc4
         from_combo.get_model ().get (from_iter, 2, out from_unit, -1);
bb3dc4
         to_combo.get_model ().get (to_iter, 2, out to_unit, -1);
bb3dc4
     }
bb3dc4
 
bb3dc4
+    private void update_visibility ()
bb3dc4
+    {
bb3dc4
+        if (category != "currency") {
bb3dc4
+            this.outer_box_visible = true;
bb3dc4
+            return;
bb3dc4
+        }
bb3dc4
+
bb3dc4
+        this.outer_box_visible = CurrencyManager.get_default ().loaded;
bb3dc4
+    }
bb3dc4
+
bb3dc4
     private void update_result_label ()
bb3dc4
     {
bb3dc4
         var x = equation.number;
bb3dc4
         if (x == null)
bb3dc4
             return;
bb3dc4
 
bb3dc4
         Unit source_unit, target_unit;
bb3dc4
         var z = convert_equation (x, out source_unit, out target_unit);
bb3dc4
         if (z != null)
bb3dc4
         {
bb3dc4
             var source_text = source_unit.format (x);
bb3dc4
             var target_text = target_unit.format (z);
bb3dc4
             from_label.set_text (source_text);
bb3dc4
             to_label.set_text (target_text);
bb3dc4
         }
bb3dc4
     }
bb3dc4
 
bb3dc4
     private void update_from_model ()
bb3dc4
     {
bb3dc4
         var from_model = new Gtk.TreeStore (3, typeof (string), typeof (UnitCategory), typeof (Unit));
bb3dc4
 
bb3dc4
         if (category == null)
bb3dc4
         {
bb3dc4
             var categories = UnitManager.get_default ().get_categories ();
bb3dc4
             foreach (var category in categories)
bb3dc4
             {
bb3dc4
                 Gtk.TreeIter parent;
bb3dc4
                 from_model.append (out parent, null);
bb3dc4
                 from_model.set (parent, 0, category.display_name, 1, category, -1);
bb3dc4
 
bb3dc4
-- 
bb3dc4
2.31.1
bb3dc4