[gcalctool] Show currency conversion below display



commit 825da6b4f53c37ac23ba822b33bc0933a31a5882
Author: Robert Ancell <robert ancell gmail com>
Date:   Tue Jun 8 15:01:02 2010 +1000

    Show currency conversion below display

 NEWS                      |    4 +
 data/buttons-financial.ui | 1591 +++++++++++++++++++++------------------------
 data/gcalctool.schemas.in |   22 +
 src/currency.c            |   74 ++-
 src/currency.h            |   92 ++--
 src/gcalctool.c           |    9 +
 src/math-buttons.c        |  583 +++++++++--------
 src/math-equation.c       |  182 ++++--
 src/math-equation.h       |    6 +
 9 files changed, 1305 insertions(+), 1258 deletions(-)
---
diff --git a/NEWS b/NEWS
index ddf4f6f..e220cde 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,10 @@
  *  All Rights Reserved.
  */
  
+Overview of changes in gcalctool 5.31.4
+
+    * Show currency conversion below display
+ 
 Overview of changes in gcalctool 5.31.3
 
     * Support complex trigonometry
diff --git a/data/buttons-financial.ui b/data/buttons-financial.ui
index 787ca85..0626752 100644
--- a/data/buttons-financial.ui
+++ b/data/buttons-financial.ui
@@ -4,750 +4,803 @@
   <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkWindow" id="window1">
     <child>
-      <object class="GtkTable" id="button_panel">
+      <object class="GtkVBox" id="button_panel">
         <property name="visible">True</property>
-        <property name="n_rows">4</property>
-        <property name="n_columns">10</property>
-        <property name="homogeneous">True</property>
+        <property name="spacing">6</property>
         <child>
-          <object class="GtkButton" id="calc_store_button">
+          <object class="GtkHBox" id="hbox1">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="focus_on_click">False</property>
-            <child internal-child="accessible">
-              <object class="AtkObject" id="calc_store_button-atkobject">
-                <property name="AtkObject::accessible-name" translatable="yes" comments="Accessible name for the store value button">Store</property>
-              </object>
-            </child>
-            <signal name="clicked" handler="store_cb"/>
+            <property name="spacing">6</property>
             <child>
-              <object class="GtkHBox" id="hbox20">
+              <object class="GtkHBox" id="hbox2">
                 <property name="visible">True</property>
-                <property name="spacing">3</property>
                 <child>
-                  <object class="GtkLabel" id="label23">
+                  <object class="GtkComboBox" id="source_currency_combo">
                     <property name="visible">True</property>
-                    <property name="label" translatable="yes" comments="The label on the memory store button">&#x2192; R</property>
+                    <property name="focus_on_click">False</property>
                   </object>
                   <packing>
+                    <property name="expand">False</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkArrow" id="arrow14">
+                  <object class="GtkLabel" id="label1">
                     <property name="visible">True</property>
-                    <property name="arrow_type">down</property>
+                    <property name="xalign">1</property>
+                    <property name="label"> in </property>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkComboBox" id="target_currency_combo">
+                    <property name="visible">True</property>
+                    <property name="focus_on_click">False</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="currency_label">
+                <property name="visible">True</property>
+                <property name="xalign">1</property>
+                <property name="label" comments="Example content">$100 = &#x20AC;120</property>
               </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
             </child>
           </object>
           <packing>
-            <property name="left_attach">5</property>
-            <property name="right_attach">6</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+            <property name="expand">False</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
-          <object class="GtkButton" id="calc_recall_button">
+          <object class="GtkTable" id="button_table">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="focus_on_click">False</property>
-            <child internal-child="accessible">
-              <object class="AtkObject" id="calc_recall_button-atkobject">
-                <property name="AtkObject::accessible-name" translatable="yes" comments="Accessible name for the recall value button">Recall</property>
-              </object>
-            </child>
-            <signal name="clicked" handler="recall_cb"/>
+            <property name="n_rows">4</property>
+            <property name="n_columns">10</property>
+            <property name="homogeneous">True</property>
             <child>
-              <object class="GtkHBox" id="hbox19">
+              <object class="GtkButton" id="calc_store_button">
                 <property name="visible">True</property>
-                <property name="spacing">3</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="focus_on_click">False</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" id="calc_store_button-atkobject">
+                    <property name="AtkObject::accessible-name" translatable="yes" comments="Accessible name for the store value button">Store</property>
+                  </object>
+                </child>
+                <signal name="clicked" handler="store_cb"/>
                 <child>
-                  <object class="GtkLabel" id="label22">
+                  <object class="GtkHBox" id="hbox20">
                     <property name="visible">True</property>
-                    <property name="label" translatable="yes" comments="The label on the memory recall button">&#x2190; R</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label23">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes" comments="The label on the memory store button">&#x2192; R</property>
+                      </object>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkArrow" id="arrow14">
+                        <property name="visible">True</property>
+                        <property name="arrow_type">down</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
+              </object>
+              <packing>
+                <property name="left_attach">5</property>
+                <property name="right_attach">6</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_recall_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="focus_on_click">False</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" id="calc_recall_button-atkobject">
+                    <property name="AtkObject::accessible-name" translatable="yes" comments="Accessible name for the recall value button">Recall</property>
+                  </object>
+                </child>
+                <signal name="clicked" handler="recall_cb"/>
                 <child>
-                  <object class="GtkArrow" id="arrow13">
+                  <object class="GtkHBox" id="hbox19">
                     <property name="visible">True</property>
-                    <property name="arrow_type">down</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label22">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes" comments="The label on the memory recall button">&#x2190; R</property>
+                      </object>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkArrow" id="arrow13">
+                        <property name="visible">True</property>
+                        <property name="arrow_type">down</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
+              <packing>
+                <property name="left_attach">4</property>
+                <property name="right_attach">5</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
             </child>
-          </object>
-          <packing>
-            <property name="left_attach">4</property>
-            <property name="right_attach">5</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_logarithm_button">
-            <property name="label">log</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="button_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">6</property>
-            <property name="right_attach">7</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_4_button">
-            <property name="label">4</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_7_button">
-            <property name="label">7</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_8_button">
-            <property name="label">8</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_9_button">
-            <property name="label">9</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">2</property>
-            <property name="right_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_5_button">
-            <property name="label">5</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_6_button">
-            <property name="label">6</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">2</property>
-            <property name="right_attach">3</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_divide_button">
-            <property name="label">&#xF7;</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="button_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">3</property>
-            <property name="right_attach">4</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_1_button">
-            <property name="label">1</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_2_button">
-            <property name="label">2</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_0_button">
-            <property name="label">0</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_numeric_point_button">
-            <property name="label" comments="Label is set in gtk.c to comply with LC flags">.</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="numeric_point_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_percentage_button">
-            <property name="label">%</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="button_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">2</property>
-            <property name="right_attach">3</property>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_3_button">
-            <property name="label">3</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="digit_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">2</property>
-            <property name="right_attach">3</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_multiply_button">
-            <property name="label">&#xD7;</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="button_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">3</property>
-            <property name="right_attach">4</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_subtract_button">
-            <property name="label">&#x2212;</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="subtract_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">3</property>
-            <property name="right_attach">4</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_add_button">
-            <property name="label">+</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="button_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">3</property>
-            <property name="right_attach">4</property>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_result_button">
-            <property name="label" translatable="yes" comments="Label on the solve button (clicking this solves the displayed calculation)">=</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="solve_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">4</property>
-            <property name="right_attach">6</property>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_start_group_button">
-            <property name="label">(</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="button_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">4</property>
-            <property name="right_attach">5</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_end_group_button">
-            <property name="label">)</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="button_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">5</property>
-            <property name="right_attach">6</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_clear_button">
-            <property name="label" translatable="yes" comments="Label on the clear display button">Clear</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="clear_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">5</property>
-            <property name="right_attach">6</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_compounding_term_button">
-            <property name="label" translatable="yes" comments="Calculates the number of compounding periods necessary to increase an investment of present value pv to a future value of fv, at a fixed interest rate of int per compounding period. See also: http://en.wikipedia.org/wiki/Compound_interest";>Ctrm</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">7</property>
-            <property name="right_attach">8</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_double_declining_depreciation_button">
-            <property name="label" translatable="yes" comments="Calculates the depreciation allowance on an asset for a specified period of time, using the double-declining balance method. See also: http://en.wikipedia.org/wiki/Depreciation";>Ddb</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">8</property>
-            <property name="right_attach">9</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_future_value_button">
-            <property name="label" translatable="yes" comments="Calculates the future value of an investment based on a series of equal payments, each of amount pmt, at a periodic interest rate of int, over the number of payment periods in the term. See also: http://en.wikipedia.org/wiki/Future_value";>Fv</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">9</property>
-            <property name="right_attach">10</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_term_button">
-            <property name="label" translatable="yes" comments="Calculates the number of payment periods that are necessary during the term of an ordinary annuity, to accumulate a future value of fv, at a periodic interest rate of int. Each payment is equal to amount pmt. See also: http://en.wikipedia.org/wiki/Annuity_(finance_theory)">Term</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">8</property>
-            <property name="right_attach">9</property>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_currency_button">
-            <property name="label" translatable="yes" comments="The label on the currency button">&#xA4;$&#x20AC;</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="currency_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">9</property>
-            <property name="right_attach">10</property>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_sum_of_the_years_digits_depreciation_button">
-            <property name="label" translatable="yes" comments="Calculates the depreciation allowance on an asset for a specified period of time, using the Sum-Of-The-Years'-Digits method. This method of depreciation accelerates the rate of depreciation, so that more depreciation expense occurs in earlier periods than in later ones. The depreciable cost is cost - salvage. The useful life is the number of periods, typically years, over which an asset is depreciated. See also: http://en.wikipedia.org/wiki/Depreciation";>Syd</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">9</property>
-            <property name="right_attach">10</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_straight_line_depreciation_button">
-            <property name="label" translatable="yes" comments="Calculates the straight-line depreciation of an asset for one period. The depreciable cost is cost - salvage. The straight-line method of depreciation divides the depreciable cost evenly over the useful life of an asset. The useful life is the number of periods, typically years, over which an asset is depreciated. See also: http://en.wikipedia.org/wiki/Depreciation";>Sln</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">8</property>
-            <property name="right_attach">9</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_periodic_interest_rate_button">
-            <property name="label" translatable="yes" comments="Calculates the periodic interest necessary to increase an investment of present value pv to a future value of fv, over the number of compounding periods in term. See also: http://en.wikipedia.org/wiki/Interest                                      ">Rate</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">7</property>
-            <property name="right_attach">8</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_present_value_button">
-            <property name="label" translatable="yes" comments="Calculates the present value of an investment based on a series of equal payments, each of amount pmt, discounted at a periodic interest rate of int, over the number of payment periods in the term. See also: http://en.wikipedia.org/wiki/Present_value";>Pv</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">9</property>
-            <property name="right_attach">10</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_periodic_payment_button">
-            <property name="label" translatable="yes" comments="Calculates the amount of the periodic payment of a loan, where payments are made at the end of each payment period. See also: http://en.wikipedia.org/wiki/Amortization_schedule";>Pmt</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">8</property>
-            <property name="right_attach">9</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_finc_gross_profit_margin_button">
-            <property name="label" translatable="yes" comments="Calculates the resale price of a product, based on the product cost and the wanted gross profit margin. See also: http://en.wikipedia.org/wiki/Gross_profit_margin";>Gpm</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="finc_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">7</property>
-            <property name="right_attach">8</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_undo_button">
-            <property name="label" translatable="yes" comments="Label on the clear display button">Undo</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-          </object>
-          <packing>
-            <property name="left_attach">4</property>
-            <property name="right_attach">5</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <placeholder/>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_x_pow_y_button">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="focus_on_click">False</property>
-            <child internal-child="accessible">
-              <object class="AtkObject" id="calc_x_pow_y_button-atkobject">
-                <property name="AtkObject::accessible-name" translatable="yes" comments="Accessible name for the exponentiation (x to the power of y) button">Exponent</property>
+            <child>
+              <object class="GtkButton" id="calc_logarithm_button">
+                <property name="label">log</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="button_cb"/>
               </object>
+              <packing>
+                <property name="left_attach">6</property>
+                <property name="right_attach">7</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
             </child>
-            <signal name="clicked" handler="button_cb"/>
             <child>
-              <object class="GtkLabel" id="x_pow_y_label">
+              <object class="GtkButton" id="calc_4_button">
+                <property name="label">4</property>
                 <property name="visible">True</property>
-                <property name="label">&lt;i&gt;x&lt;/i&gt;&lt;sup&gt;&lt;i&gt;y&lt;/i&gt;&lt;/sup&gt;</property>
-                <property name="use_markup">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
               </object>
+              <packing>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_7_button">
+                <property name="label">7</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
+              </object>
+              <packing>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_8_button">
+                <property name="label">8</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_9_button">
+                <property name="label">9</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_5_button">
+                <property name="label">5</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_6_button">
+                <property name="label">6</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_divide_button">
+                <property name="label">&#xF7;</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="button_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">3</property>
+                <property name="right_attach">4</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_1_button">
+                <property name="label">1</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
+              </object>
+              <packing>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_2_button">
+                <property name="label">2</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_0_button">
+                <property name="label">0</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
+              </object>
+              <packing>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_numeric_point_button">
+                <property name="label" comments="Label is set in gtk.c to comply with LC flags">.</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="numeric_point_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_percentage_button">
+                <property name="label">%</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="button_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_3_button">
+                <property name="label">3</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="digit_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_multiply_button">
+                <property name="label">&#xD7;</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="button_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">3</property>
+                <property name="right_attach">4</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_subtract_button">
+                <property name="label">&#x2212;</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="subtract_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">3</property>
+                <property name="right_attach">4</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_add_button">
+                <property name="label">+</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="button_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">3</property>
+                <property name="right_attach">4</property>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_result_button">
+                <property name="label" translatable="yes" comments="Label on the solve button (clicking this solves the displayed calculation)">=</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="solve_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">4</property>
+                <property name="right_attach">6</property>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_start_group_button">
+                <property name="label">(</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="button_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">4</property>
+                <property name="right_attach">5</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_end_group_button">
+                <property name="label">)</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="button_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">5</property>
+                <property name="right_attach">6</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_clear_button">
+                <property name="label" translatable="yes" comments="Label on the clear display button">Clear</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="clear_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">5</property>
+                <property name="right_attach">6</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_compounding_term_button">
+                <property name="label" translatable="yes" comments="Calculates the number of compounding periods necessary to increase an investment of present value pv to a future value of fv, at a fixed interest rate of int per compounding period. See also: http://en.wikipedia.org/wiki/Compound_interest";>Ctrm</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">7</property>
+                <property name="right_attach">8</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_double_declining_depreciation_button">
+                <property name="label" translatable="yes" comments="Calculates the depreciation allowance on an asset for a specified period of time, using the double-declining balance method. See also: http://en.wikipedia.org/wiki/Depreciation";>Ddb</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">8</property>
+                <property name="right_attach">9</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_future_value_button">
+                <property name="label" translatable="yes" comments="Calculates the future value of an investment based on a series of equal payments, each of amount pmt, at a periodic interest rate of int, over the number of payment periods in the term. See also: http://en.wikipedia.org/wiki/Future_value";>Fv</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">9</property>
+                <property name="right_attach">10</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_term_button">
+                <property name="label" translatable="yes" comments="Calculates the number of payment periods that are necessary during the term of an ordinary annuity, to accumulate a future value of fv, at a periodic interest rate of int. Each payment is equal to amount pmt. See also: http://en.wikipedia.org/wiki/Annuity_(finance_theory)">Term</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">8</property>
+                <property name="right_attach">9</property>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_sum_of_the_years_digits_depreciation_button">
+                <property name="label" translatable="yes" comments="Calculates the depreciation allowance on an asset for a specified period of time, using the Sum-Of-The-Years'-Digits method. This method of depreciation accelerates the rate of depreciation, so that more depreciation expense occurs in earlier periods than in later ones. The depreciable cost is cost - salvage. The useful life is the number of periods, typically years, over which an asset is depreciated. See also: http://en.wikipedia.org/wiki/Depreciation";>Syd</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">9</property>
+                <property name="right_attach">10</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_straight_line_depreciation_button">
+                <property name="label" translatable="yes" comments="Calculates the straight-line depreciation of an asset for one period. The depreciable cost is cost - salvage. The straight-line method of depreciation divides the depreciable cost evenly over the useful life of an asset. The useful life is the number of periods, typically years, over which an asset is depreciated. See also: http://en.wikipedia.org/wiki/Depreciation";>Sln</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">8</property>
+                <property name="right_attach">9</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_periodic_interest_rate_button">
+                <property name="label" translatable="yes" comments="Calculates the periodic interest necessary to increase an investment of present value pv to a future value of fv, over the number of compounding periods in term. See also: http://en.wikipedia.org/wiki/Interest                                      ">Rate</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">7</property>
+                <property name="right_attach">8</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_present_value_button">
+                <property name="label" translatable="yes" comments="Calculates the present value of an investment based on a series of equal payments, each of amount pmt, discounted at a periodic interest rate of int, over the number of payment periods in the term. See also: http://en.wikipedia.org/wiki/Present_value";>Pv</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">9</property>
+                <property name="right_attach">10</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_periodic_payment_button">
+                <property name="label" translatable="yes" comments="Calculates the amount of the periodic payment of a loan, where payments are made at the end of each payment period. See also: http://en.wikipedia.org/wiki/Amortization_schedule";>Pmt</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">8</property>
+                <property name="right_attach">9</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_finc_gross_profit_margin_button">
+                <property name="label" translatable="yes" comments="Calculates the resale price of a product, based on the product cost and the wanted gross profit margin. See also: http://en.wikipedia.org/wiki/Gross_profit_margin";>Gpm</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="finc_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">7</property>
+                <property name="right_attach">8</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_undo_button">
+                <property name="label" translatable="yes" comments="Label on the clear display button">Undo</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+              </object>
+              <packing>
+                <property name="left_attach">4</property>
+                <property name="right_attach">5</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_x_pow_y_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="focus_on_click">False</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" id="calc_x_pow_y_button-atkobject">
+                    <property name="AtkObject::accessible-name" translatable="yes" comments="Accessible name for the exponentiation (x to the power of y) button">Exponent</property>
+                  </object>
+                </child>
+                <signal name="clicked" handler="button_cb"/>
+                <child>
+                  <object class="GtkLabel" id="x_pow_y_label">
+                    <property name="visible">True</property>
+                    <property name="label">&lt;i&gt;x&lt;/i&gt;&lt;sup&gt;&lt;i&gt;y&lt;/i&gt;&lt;/sup&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">6</property>
+                <property name="right_attach">7</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="calc_root_button">
+                <property name="label">&#x221A;</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <signal name="clicked" handler="button_cb"/>
+              </object>
+              <packing>
+                <property name="left_attach">6</property>
+                <property name="right_attach">7</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
             </child>
           </object>
           <packing>
-            <property name="left_attach">6</property>
-            <property name="right_attach">7</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="calc_root_button">
-            <property name="label">&#x221A;</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="use_underline">True</property>
-            <property name="focus_on_click">False</property>
-            <signal name="clicked" handler="button_cb"/>
-          </object>
-          <packing>
-            <property name="left_attach">6</property>
-            <property name="right_attach">7</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
-            <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
@@ -2518,148 +2571,4 @@
       <action-widget response="-5">button18</action-widget>
     </action-widgets>
   </object>
-  <object class="GtkDialog" id="currency_dialog">
-    <property name="border_width">6</property>
-    <property name="title" translatable="yes">Currency Conversion</property>
-    <property name="type_hint">normal</property>
-    <property name="has_separator">False</property>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox11">
-        <property name="visible">True</property>
-        <property name="spacing">2</property>
-        <child>
-          <object class="GtkTable" id="table11">
-            <property name="visible">True</property>
-            <property name="border_width">6</property>
-            <property name="n_rows">3</property>
-            <property name="n_columns">2</property>
-            <property name="column_spacing">6</property>
-            <property name="row_spacing">6</property>
-            <child>
-              <object class="GtkLabel" id="label42">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Converts between different currencies. Enter the amount and the currency you want to convert from on the upper row, and the currency you want to convert to on the lower row, and the amount will be displayed on the lower row.</property>
-                <property name="wrap">True</property>
-              </object>
-              <packing>
-                <property name="right_attach">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkSpinButton" id="currency_amount_upper">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="invisible_char">&#x25CF;</property>
-                <property name="adjustment">adjustment1</property>
-                <property name="digits">2</property>
-                <property name="numeric">True</property>
-                <signal name="value_changed" handler="currency_amount_cb"/>
-              </object>
-              <packing>
-                <property name="top_attach">1</property>
-                <property name="bottom_attach">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkSpinButton" id="currency_amount_lower">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="invisible_char">&#x25CF;</property>
-                <property name="adjustment">adjustment2</property>
-                <property name="digits">2</property>
-                <property name="numeric">True</property>
-                <signal name="value_changed" handler="currency_amount_cb"/>
-              </object>
-              <packing>
-                <property name="top_attach">2</property>
-                <property name="bottom_attach">3</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkComboBox" id="currency_type_upper">
-                <property name="visible">True</property>
-                <signal name="changed" handler="currency_type_cb"/>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
-                <property name="top_attach">1</property>
-                <property name="bottom_attach">2</property>
-                <property name="y_options"></property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkComboBox" id="currency_type_lower">
-                <property name="visible">True</property>
-                <signal name="changed" handler="currency_type_cb"/>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
-                <property name="top_attach">2</property>
-                <property name="bottom_attach">3</property>
-                <property name="y_options"></property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area11">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="button22">
-                <property name="label">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="button21">
-                <property name="label">C_alculate</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-    <action-widgets>
-      <action-widget response="-6">button22</action-widget>
-      <action-widget response="-5">button21</action-widget>
-    </action-widgets>
-  </object>
-  <object class="GtkAdjustment" id="adjustment1">
-    <property name="upper">999999999999</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
-  <object class="GtkAdjustment" id="adjustment2">
-    <property name="upper">999999999999</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
 </interface>
diff --git a/data/gcalctool.schemas.in b/data/gcalctool.schemas.in
index 958421a..99de815 100644
--- a/data/gcalctool.schemas.in
+++ b/data/gcalctool.schemas.in
@@ -148,6 +148,28 @@ To change the gconftool target use the - -config-source=blah option to gconftool
         </long>
       </locale>
     </schema>
+    <schema>
+      <applyto>/apps/gcalctool/source_currency</applyto>
+      <key>/schemas/apps/gcalctool/source_currency</key>
+      <owner>gcalctool</owner>
+      <type>string</type>
+      <default></default>
+      <locale name="C">
+        <short>Source currency</short>
+        <long>Currency of the current calculation</long>
+      </locale>
+    </schema>
+    <schema>
+      <applyto>/apps/gcalctool/target_currency</applyto>
+      <key>/schemas/apps/gcalctool/target_currency</key>
+      <owner>gcalctool</owner>
+      <type>string</type>
+      <default></default>
+      <locale name="C">
+        <short>Target currency</short>
+        <long>Currency to convert the current calculation into</long>
+      </locale>
+    </schema>
     <schema> 
       <applyto>/apps/gcalctool/xposition</applyto>
       <key>/schemas/apps/gcalctool/xposition</key> 
diff --git a/src/currency.c b/src/currency.c
index 3d63795..72d5844 100644
--- a/src/currency.c
+++ b/src/currency.c
@@ -18,6 +18,9 @@ typedef struct {
 static currency *currencies = NULL;
 static int currency_count = 0;
 
+static gboolean downloading_rates = FALSE;
+static gboolean loaded_rates = FALSE;
+
 static char*
 get_rate_filepath()
 {
@@ -27,7 +30,7 @@ get_rate_filepath()
                             NULL);
 }
 
-int
+static int
 currency_get_index(const char *short_name)
 {
     int i;
@@ -47,7 +50,7 @@ currency_get_index(const char *short_name)
 /* A file needs to be redownloaded if it doesn't exist, or every 7 days.
  * When an error occur, it probably won't hurt to try to download again.
  */
-int
+static int
 currency_rates_needs_update()
 {
     gchar *filename = get_rate_filepath ();
@@ -70,13 +73,30 @@ currency_rates_needs_update()
     return 0;
 }
 
-/* FIXME: This code is synchronous, and should thus be accessed from a thread */
-int
+
+static void
+download_cb(GObject *object, GAsyncResult *result, gpointer user_data)
+{
+    GError *error = NULL;
+
+    if (g_file_copy_finish(G_FILE(object), result, &error))
+        g_debug("Rates updated");
+
+    if (error != NULL)
+        g_warning("Couldn't download currency file: %s\n", error->message);
+    g_clear_error(&error);
+    downloading_rates = FALSE;
+}
+
+
+static void
 currency_download_rates()
 {
     gchar *filename, *directory;
-    GError *e = NULL;
     GFile *source, *dest;
+
+    downloading_rates = TRUE;
+    g_debug("Downloading rates");
    
     filename = get_rate_filepath();
     directory = g_path_get_dirname(filename);
@@ -87,19 +107,12 @@ currency_download_rates()
     dest = g_file_new_for_path (filename);
     g_free(filename);
 
-    g_file_copy (source, dest, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &e);
+    g_file_copy_async (source, dest, G_FILE_COPY_OVERWRITE, G_PRIORITY_DEFAULT, NULL, NULL, NULL, download_cb, NULL);
     g_object_unref(source);
     g_object_unref(dest);
-
-    if (e != NULL) {
-        fprintf(stderr, "Couldn't download currency file: %s\n", e->message);
-        g_error_free (e);
-        return 0;
-    }
-
-    return 1;
 }
 
+
 static void
 set_rate (xmlNodePtr node, currency *cur)
 {
@@ -115,7 +128,7 @@ set_rate (xmlNodePtr node, currency *cur)
     }
 }
 
-void
+static void
 currency_load_rates()
 {
     char *filename = get_rate_filepath();
@@ -176,22 +189,45 @@ currency_load_rates()
     xmlXPathFreeContext(xpath_ctx);
     xmlFreeDoc(document);
     xmlCleanupParser();
+
+    g_debug("Rates loaded");
+    loaded_rates = TRUE;
 }
 
-void
+
+gboolean
 currency_convert(const MPNumber *from_amount,
-                 int from_index,
-                 int to_index,
+                 const char *source_currency, const char *target_currency,
                  MPNumber *to_amount)
 {
+    int from_index, to_index;
+
+    if (downloading_rates)
+        return FALSE;
+
+    /* Update currency if necessary */
+    if (currency_rates_needs_update()) {
+        currency_download_rates();
+        return FALSE;
+    }
+    if (!loaded_rates)
+        currency_load_rates();
+  
+    from_index = currency_get_index(source_currency);
+    to_index = currency_get_index(target_currency);
+    if (from_index < 0 || to_index < 0)
+        return FALSE;
+
     if (mp_is_zero(&currencies[from_index].value) ||
         mp_is_zero(&currencies[to_index].value)) {
         mp_set_from_integer(0, to_amount);
-        return;
+        return FALSE;
     }
 
     mp_divide(from_amount, &currencies[from_index].value, to_amount);
     mp_multiply(to_amount, &currencies[to_index].value, to_amount);
+
+    return TRUE;
 }
 
 void
diff --git a/src/currency.h b/src/currency.h
index 2ac8488..1ea08c5 100644
--- a/src/currency.h
+++ b/src/currency.h
@@ -7,6 +7,7 @@
 
 struct currency_name {
     char *short_name;
+    char *symbol;
     char *long_name;
 };
 
@@ -15,63 +16,50 @@ struct currency_name {
  * with euro added.
  */
 static const struct currency_name currency_names[] = {
-    {"AUD", N_("Australian dollar")},
-    {"BGN", N_("Bulgarian lev")},
-    {"BRL", N_("Brazilian real")},
-    {"CAD", N_("Canadian dollar")},
-    {"CHF", N_("Swiss franc")},
-    {"CNY", N_("Chinese yuan renminbi")},
-    {"CZK", N_("Czech koruna")},
-    {"DKK", N_("Danish krone")},
-    {"EEK", N_("Estonian kroon")},
-    {"EUR", N_("Euro")},
-    {"GBP", N_("Pound sterling")},
-    {"HKD", N_("Hong Kong dollar")},
-    {"HRK", N_("Croatian kuna")},
-    {"HUF", N_("Hungarian forint")},
-    {"IDR", N_("Indonesian rupiah")},
-    {"INR", N_("Indian rupee")},
-    {"ISK", N_("Icelandic krona")},
-    {"JPY", N_("Japanese yen")},
-    {"KRW", N_("South Korean won")},
-    {"LTL", N_("Lithuanian litas")},
-    {"LVL", N_("Latvian lats")},
-    {"MXN", N_("Mexican peso")},
-    {"MYR", N_("Malaysian ringgit")},
-    {"NOK", N_("Norwegian krone")},
-    {"NZD", N_("New Zealand dollar")},
-    {"PHP", N_("Philippine peso")},
-    {"PLN", N_("Polish zloty")},
-    {"RON", N_("New Romanian leu")},
-    {"RUB", N_("Russian rouble")},
-    {"SEK", N_("Swedish krona")},
-    {"SGD", N_("Singapore dollar")},
-    {"THB", N_("Thai baht")},
-    {"TRY", N_("New Turkish lira")},
-    {"USD", N_("US dollar")},
-    {"ZAR", N_("South African rand")},
+    {"AUD", "$",  N_("Australian dollar")},
+    {"BGN", "лв", N_("Bulgarian lev")},
+    {"BRL", "R$", N_("Brazilian real")},
+    {"CAD", "$",  N_("Canadian dollar")},
+    {"CHF", "Fr", N_("Swiss franc")},
+    {"CNY", "å??", N_("Chinese yuan renminbi")},
+    {"CZK", "KÄ?", N_("Czech koruna")},
+    {"DKK", "kr", N_("Danish krone")},
+    {"EEK", "KR", N_("Estonian kroon")},
+    {"EUR", "â?¬",  N_("Euro")},
+    {"GBP", "£",  N_("Pound sterling")},
+    {"HKD", "$",  N_("Hong Kong dollar")},
+    {"HRK", "kn", N_("Croatian kuna")},
+    {"HUF", "Ft", N_("Hungarian forint")},
+    {"IDR", "Rp", N_("Indonesian rupiah")},
+    {"INR", "Rs", N_("Indian rupee")},
+    {"ISK", "kr", N_("Icelandic krona")},
+    {"JPY", "Â¥",  N_("Japanese yen")},
+    {"KRW", "â?©",  N_("South Korean won")},
+    {"LTL", "Lt", N_("Lithuanian litas")},
+    {"LVL", "Ls", N_("Latvian lats")},
+    {"MXN", "$",  N_("Mexican peso")},
+    {"MYR", "RM", N_("Malaysian ringgit")},
+    {"NOK", "kr", N_("Norwegian krone")},
+    {"NZD", "$",  N_("New Zealand dollar")},
+    {"PHP", "â?±",  N_("Philippine peso")},
+    {"PLN", "zÅ?", N_("Polish zloty")},
+    {"RON", "L",  N_("New Romanian leu")},
+    {"RUB", "Ñ?Ñ?б.", N_("Russian rouble")},
+    {"SEK", "kr", N_("Swedish krona")},
+    {"SGD", "$",  N_("Singapore dollar")},
+    {"THB", "฿",  N_("Thai baht")},
+    {"TRY", "TL", N_("New Turkish lira")},
+    {"USD", "$",  N_("US dollar")},
+    {"ZAR", "R",  N_("South African rand")},
     {NULL, NULL}
 };
 
-/* Returns 1 if the user needs to update his/her rates, 0 otherwise */
-int currency_rates_needs_update();
-
-/* Dowloads new rates. Returns 1 on success, 0 otherwise */
-int currency_download_rates();
-
-/* Loads rates from disk. Should be called after having made sure the rates
- * are not outdated, but before anything else. */
-void currency_load_rates();
-
-/* Returns an internal index for each short name to be used with
- * currency_convert. A negative value means invalid. */
-int currency_get_index(const char *short_name);
+// FIXME: Should indicate when rates are updated to UI
 
 /* Converts an amount of money from one currency to another */
-void currency_convert(const MPNumber *from_amount,
-                      int from_index,
-                      int to_index,
-                      MPNumber *to_amount);
+gboolean currency_convert(const MPNumber *from_amount,
+                          const char *source_currency, const char *target_currency,
+                          MPNumber *to_amount);
 
 /* Frees up all allocated resources */
 void currency_free_resources();
diff --git a/src/gcalctool.c b/src/gcalctool.c
index 6de9e4c..00b5e52 100644
--- a/src/gcalctool.c
+++ b/src/gcalctool.c
@@ -290,6 +290,8 @@ quit_cb(MathWindow *window)
     gconf_client_set_string(client, "/apps/gcalctool/angle_units", angle_unit_to_string(math_equation_get_angle_units(equation)), NULL);
     gconf_client_set_string(client, "/apps/gcalctool/button_layout", button_mode_to_string(math_buttons_get_mode(buttons)), NULL);
     gconf_client_set_int(client, "/apps/gcalctool/base", math_buttons_get_programming_base(buttons), NULL);
+    gconf_client_set_string(client, "/apps/gcalctool/source_currency", math_equation_get_source_currency(equation), NULL);
+    gconf_client_set_string(client, "/apps/gcalctool/target_currency", math_equation_get_target_currency(equation), NULL);
 
     currency_free_resources();
     gtk_main_quit();
@@ -329,6 +331,7 @@ main(int argc, char **argv)
     int accuracy = 9, word_size = 64, base = 10;
     gboolean show_tsep = FALSE, show_zeroes = FALSE;
     gchar *number_format, *angle_units, *button_mode;
+    gchar *source_currency, *target_currency;
 
     g_type_init();
 
@@ -353,6 +356,8 @@ main(int argc, char **argv)
     number_format = gconf_client_get_string(client, "/apps/gcalctool/result_format", NULL);
     angle_units = gconf_client_get_string(client, "/apps/gcalctool/angle_units", NULL);
     button_mode = gconf_client_get_string(client, "/apps/gcalctool/button_layout", NULL);
+    source_currency = gconf_client_get_string(client, "/apps/gcalctool/source_currency", NULL);
+    target_currency = gconf_client_get_string(client, "/apps/gcalctool/target_currency", NULL);
 
     math_equation_set_accuracy(equation, accuracy);
     math_equation_set_word_size(equation, word_size);
@@ -360,8 +365,12 @@ main(int argc, char **argv)
     math_equation_set_show_trailing_zeroes(equation, show_zeroes);
     math_equation_set_number_format(equation, string_to_number_format(number_format));
     math_equation_set_angle_units(equation, string_to_angle_unit(angle_units));
+    math_equation_set_source_currency(equation, source_currency);
+    math_equation_set_target_currency(equation, target_currency);
     g_free(number_format);
     g_free(angle_units);
+    g_free(source_currency);
+    g_free(target_currency);
 
     gtk_init(&argc, &argv);
 
diff --git a/src/math-buttons.c b/src/math-buttons.c
index 48e731f..992497d 100644
--- a/src/math-buttons.c
+++ b/src/math-buttons.c
@@ -61,6 +61,10 @@ struct MathButtonsPrivate
     GtkWidget *bit_panel;
     GtkWidget *bit_labels[MAXBITS];
 
+    GtkWidget *source_currency_combo;
+    GtkWidget *target_currency_combo;
+    GtkWidget *currency_label;
+
     GtkWidget *character_code_dialog;
     GtkWidget *character_code_entry;
 };
@@ -282,9 +286,6 @@ static ButtonData button_data[] = {
     {"finc_gross_profit_margin", NULL, FUNCTION,
       /* Tooltip for the gross profit margin button */
       N_("Gross Profit Margin")},
-    {"currency", NULL, FUNCTION,
-      /* Tooltip for the currency button */
-      N_("Currency Converter")},
     {NULL, NULL, 0, NULL}
 };
 
@@ -364,12 +365,6 @@ static void
 load_finc_dialogs(MathButtons *buttons)
 {
     int i, j;
-    GtkListStore *currency_store;
-    GtkCellRenderer *render;
-    GtkSpinButton *currency_amount_upper;
-    GtkSpinButton *currency_amount_lower;
-    GtkComboBox   *currency_type_upper;
-    GtkComboBox   *currency_type_lower;
 
     set_int_data(buttons->priv->financial_ui, "ctrm_dialog", "finc_dialog", FINC_CTRM_DIALOG);
     set_int_data(buttons->priv->financial_ui, "ddb_dialog", "finc_dialog", FINC_DDB_DIALOG);
@@ -392,167 +387,189 @@ load_finc_dialogs(MathButtons *buttons)
             g_object_set_data(o, "finc_dialog", GINT_TO_POINTER(i));
         }
     }
-
-    currency_amount_upper = GTK_SPIN_BUTTON(gtk_builder_get_object(buttons->priv->financial_ui, "currency_amount_upper"));
-    currency_amount_lower = GTK_SPIN_BUTTON(gtk_builder_get_object(buttons->priv->financial_ui, "currency_amount_lower"));
-    currency_type_upper = GTK_COMBO_BOX(gtk_builder_get_object(buttons->priv->financial_ui, "currency_type_upper"));
-    currency_type_lower = GTK_COMBO_BOX(gtk_builder_get_object(buttons->priv->financial_ui, "currency_type_lower"));
-
-    currency_store = gtk_list_store_new(2,
-                                        G_TYPE_INT,
-                                        G_TYPE_STRING);
-
-    gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(currency_store),
-                                         1,
-                                         GTK_SORT_ASCENDING);
-
-    gtk_combo_box_set_model(currency_type_upper, GTK_TREE_MODEL(currency_store));
-    gtk_combo_box_set_model(currency_type_lower, GTK_TREE_MODEL(currency_store));
-
-    render = gtk_cell_renderer_text_new();
-
-    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(currency_type_upper),
-                               render,
-                               TRUE);
-    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(currency_type_lower),
-                               render,
-                               TRUE);
-
-    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(currency_type_upper),
-                                  render,
-                                  "text",
-                                  1);
-    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(currency_type_lower),
-                                  render,
-                                  "text",
-                                  1);
-
-    set_int_data(buttons->priv->financial_ui, "currency_amount_upper", "target", CURRENCY_TARGET_LOWER);
-    set_int_data(buttons->priv->financial_ui, "currency_amount_lower", "target", CURRENCY_TARGET_UPPER);
 }
 
 
 static void
-display_changed_cb(MathEquation *equation, GParamSpec *spec, MathButtons *buttons)
+update_angle_label (MathButtons *buttons)
 {
     MPNumber x;
-    gboolean is_number;
-
-    is_number = math_equation_get_number(equation, &x);
+    MPNumber pi, max_value, min_value, fraction, input, output;
+    char *label, input_text[1024], output_text[1024];
 
-    if (buttons->priv->angle_label && is_number) {
-        MPNumber pi, max_value, min_value, fraction, input, output;
-        char *label, input_text[1024], output_text[1024];
-
-        mp_get_pi(&pi);
-        switch (math_equation_get_angle_units(equation)) {
-        default:
-        case MP_DEGREES:
-            label = g_strdup("");
-            break;
-        case MP_RADIANS:
-            /* Clip to the range ±2Ï? */
-            mp_multiply_integer(&pi, 2, &max_value);
-            mp_invert_sign(&max_value, &min_value);
-            if (!mp_is_equal(&x, &max_value) && !mp_is_equal(&x, &min_value)) {
-                mp_divide(&x, &max_value, &fraction);
-                mp_fractional_component(&fraction, &fraction);
-                mp_multiply(&fraction, &max_value, &input);
-            }
-            else {
-                mp_set_from_mp(&x, &input);
-                mp_set_from_integer(mp_is_negative(&input) ? -1 : 1, &fraction);
-            }
-            mp_cast_to_string(&input, 10, 10, 2, false, input_text, 1024);
+    if (!buttons->priv->angle_label)
+        return;
 
-            mp_multiply_integer(&fraction, 360, &output);
-            mp_cast_to_string(&output, 10, 10, 2, false, output_text, 1024);
-            label = g_strdup_printf("%s radians = %s degrees", input_text, output_text);
-            break;
-        case MP_GRADIANS:
-            /* Clip to the range ±400 */
-            mp_set_from_integer(400, &max_value);
-            mp_invert_sign(&max_value, &min_value);
-            if (!mp_is_equal(&x, &max_value) && !mp_is_equal(&x, &min_value)) {
-                mp_divide(&x, &max_value, &fraction);
-                mp_fractional_component(&fraction, &fraction);
-                mp_multiply(&fraction, &max_value, &input);
-            }
-            else {
-                mp_set_from_mp(&x, &input);
-                mp_set_from_integer(mp_is_negative(&input) ? -1 : 1, &fraction);
-            }
+    if (!math_equation_get_number(buttons->priv->equation, &x))
+        return;
 
-            mp_cast_to_string(&input, 10, 10, 2, false, input_text, 1024);
+    mp_get_pi(&pi);
+    switch (math_equation_get_angle_units(buttons->priv->equation)) {
+    default:
+    case MP_DEGREES:
+        label = g_strdup("");
+        break;
+    case MP_RADIANS:
+        /* Clip to the range ±2Ï? */
+        mp_multiply_integer(&pi, 2, &max_value);
+        mp_invert_sign(&max_value, &min_value);
+        if (!mp_is_equal(&x, &max_value) && !mp_is_equal(&x, &min_value)) {
+            mp_divide(&x, &max_value, &fraction);
+            mp_fractional_component(&fraction, &fraction);
+            mp_multiply(&fraction, &max_value, &input);
+        }
+        else {
+            mp_set_from_mp(&x, &input);
+            mp_set_from_integer(mp_is_negative(&input) ? -1 : 1, &fraction);
+        }
+        mp_cast_to_string(&input, 10, 10, 2, false, input_text, 1024);
 
-            mp_multiply_integer(&fraction, 360, &output);
-            mp_cast_to_string(&output, 10, 10, 2, false, output_text, 1024);
-            label = g_strdup_printf("%s gradians = %s degrees", input_text, output_text);
-            break;
+        mp_multiply_integer(&fraction, 360, &output);
+        mp_cast_to_string(&output, 10, 10, 2, false, output_text, 1024);
+        label = g_strdup_printf("%s radians = %s degrees", input_text, output_text);
+        break;
+    case MP_GRADIANS:
+        /* Clip to the range ±400 */
+        mp_set_from_integer(400, &max_value);
+        mp_invert_sign(&max_value, &min_value);
+        if (!mp_is_equal(&x, &max_value) && !mp_is_equal(&x, &min_value)) {
+            mp_divide(&x, &max_value, &fraction);
+            mp_fractional_component(&fraction, &fraction);
+            mp_multiply(&fraction, &max_value, &input);
+        }
+        else {
+            mp_set_from_mp(&x, &input);
+            mp_set_from_integer(mp_is_negative(&input) ? -1 : 1, &fraction);
         }
 
-        gtk_label_set_text(GTK_LABEL(buttons->priv->angle_label), label);
-        g_free(label);
+        mp_cast_to_string(&input, 10, 10, 2, false, input_text, 1024);
+
+        mp_multiply_integer(&fraction, 360, &output);
+        mp_cast_to_string(&output, 10, 10, 2, false, output_text, 1024);
+        label = g_strdup_printf("%s gradians = %s degrees", input_text, output_text);
+        break;
     }
+
+    gtk_label_set_text(GTK_LABEL(buttons->priv->angle_label), label);
+    g_free(label);
+}
+
+
+static void
+update_bit_panel(MathButtons *buttons)
+{
+    MPNumber x;
+    gboolean enabled;
+    guint64 bits;
+    int i;
+    GString *label;
+    gint base;
+
+    if (!buttons->priv->bit_panel)
+        return;
   
-    if (buttons->priv->bit_panel) {
-        gboolean enabled = is_number;
-        guint64 bits;
+    enabled = math_equation_get_number(buttons->priv->equation, &x);
 
-        if (enabled) {
-            MPNumber max, fraction;
+    if (enabled) {
+        MPNumber max, fraction;
 
-            mp_set_from_unsigned_integer(G_MAXUINT64, &max);
-            mp_fractional_part(&x, &fraction);
-            if (mp_is_negative(&x) || mp_is_greater_than(&x, &max) || !mp_is_zero(&fraction))
-                enabled = FALSE;
-            else
-                bits = mp_cast_to_unsigned_int(&x);
-        }
+        mp_set_from_unsigned_integer(G_MAXUINT64, &max);
+        mp_fractional_part(&x, &fraction);
+        if (mp_is_negative(&x) || mp_is_greater_than(&x, &max) || !mp_is_zero(&fraction))
+            enabled = FALSE;
+        else
+            bits = mp_cast_to_unsigned_int(&x);
+    }
 
-        gtk_widget_set_sensitive(buttons->priv->bit_panel, enabled);
-        gtk_widget_set_sensitive(buttons->priv->base_label, enabled);
+    gtk_widget_set_sensitive(buttons->priv->bit_panel, enabled);
+    gtk_widget_set_sensitive(buttons->priv->base_label, enabled);
       
-        if (enabled) {
-            int i;
-            GString *label;
-            gint base;
-
-            for (i = 0; i < MAXBITS; i++) {
-                const gchar *label;
-
-                if (bits & (1LL << (MAXBITS-i-1)))
-                    label = " 1";
-                else
-                    label = " 0";
-                gtk_label_set_text(GTK_LABEL(buttons->priv->bit_labels[i]), label);
-            }
+    if (!enabled)
+        return;
 
-            base = math_equation_get_base(equation);      
-            label = g_string_new("");
-            if (base != 8) {
-                if (label->len != 0)
-                    g_string_append(label, " = ");
-                g_string_append_printf(label, "%lo", bits);
-                g_string_append(label, "â??");
-            }
-            if (base != 10) {
-                if (label->len != 0)
-                    g_string_append(label, " = ");
-                g_string_append_printf(label, "%lu", bits);
-                g_string_append(label, "â??â??");
-            }
-            if (base != 16) {
-                if (label->len != 0)
-                    g_string_append(label, " = ");
-                g_string_append_printf(label, "%lX", bits);
-                g_string_append(label, "â??â??");
-            }
+    for (i = 0; i < MAXBITS; i++) {
+        const gchar *label;
 
-            gtk_label_set_text(GTK_LABEL(buttons->priv->base_label), label->str);
-            g_string_free(label, TRUE);
-        }
+        if (bits & (1LL << (MAXBITS-i-1)))
+            label = " 1";
+        else
+            label = " 0";
+        gtk_label_set_text(GTK_LABEL(buttons->priv->bit_labels[i]), label);
+    }
+
+    base = math_equation_get_base(buttons->priv->equation);      
+    label = g_string_new("");
+    if (base != 8) {
+        if (label->len != 0)
+            g_string_append(label, " = ");
+        g_string_append_printf(label, "%lo", bits);
+        g_string_append(label, "â??");
     }
+    if (base != 10) {
+        if (label->len != 0)
+            g_string_append(label, " = ");
+        g_string_append_printf(label, "%lu", bits);
+        g_string_append(label, "â??â??");
+    }
+    if (base != 16) {
+        if (label->len != 0)
+            g_string_append(label, " = ");
+        g_string_append_printf(label, "%lX", bits);
+        g_string_append(label, "â??â??");
+    }
+
+    gtk_label_set_text(GTK_LABEL(buttons->priv->base_label), label->str);
+    g_string_free(label, TRUE);
+}
+
+
+static void
+update_currency_label(MathButtons *buttons)
+{
+    MPNumber x, value;
+    int source_index, target_index;
+    char *label;
+
+    if (!buttons->priv->currency_label)
+        return;
+
+    if (!math_equation_get_number(buttons->priv->equation, &x))
+        return;
+  
+    if (currency_convert(&x,
+                         math_equation_get_source_currency(buttons->priv->equation),
+                         math_equation_get_target_currency(buttons->priv->equation),
+                         &value)) {
+        char input_text[1024], output_text[1024];
+        const char *source_symbol, *target_symbol;
+        int i;
+
+        mp_cast_to_string(&x, 10, 10, 2, false, input_text, 1024);
+        mp_cast_to_string(&value, 10, 10, 2, false, output_text, 1024);
+
+        for (i = 0; strcmp(math_equation_get_source_currency(buttons->priv->equation), currency_names[i].short_name) != 0; i++);
+        source_symbol = currency_names[i].symbol;
+        for (i = 0; strcmp(math_equation_get_target_currency(buttons->priv->equation), currency_names[i].short_name) != 0; i++);
+        target_symbol = currency_names[i].symbol;
+
+        label = g_strdup_printf("%s%s = %s%s",
+                                source_symbol, input_text,
+                                target_symbol, output_text);
+    }
+    else
+        label = g_strdup_printf("");
+
+    gtk_label_set_text(GTK_LABEL(buttons->priv->currency_label), label);
+    g_free(label);
+}
+
+
+static void
+display_changed_cb(MathEquation *equation, GParamSpec *spec, MathButtons *buttons)
+{
+    update_angle_label(buttons);
+    update_currency_label(buttons);
+    update_bit_panel(buttons);
 }
 
 
@@ -639,6 +656,102 @@ base_changed_cb(MathEquation *equation, GParamSpec *spec, MathButtons *buttons)
 }
 
 
+static void
+source_currency_combo_changed_cb(GtkWidget *combo, MathButtons *buttons)
+{
+    gchar *value;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+
+    model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
+    gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter);
+    gtk_tree_model_get(model, &iter, 0, &value, -1);
+
+    math_equation_set_source_currency(buttons->priv->equation, value);
+    g_free (value);
+}
+
+
+static void
+source_currency_changed_cb(MathEquation *equation, GParamSpec *spec, MathButtons *buttons)
+{
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    gboolean valid;
+  
+    if (buttons->priv->mode != FINANCIAL)
+        return;
+
+    model = gtk_combo_box_get_model(GTK_COMBO_BOX(buttons->priv->source_currency_combo));
+    valid = gtk_tree_model_get_iter_first(model, &iter);
+
+    while (valid) {
+        gchar *v;
+        gboolean matched;
+
+        gtk_tree_model_get(model, &iter, 0, &v, -1);
+        matched = strcmp (math_equation_get_source_currency(buttons->priv->equation), v) == 0;
+        g_free (v);
+        if (matched)
+            break;
+        valid = gtk_tree_model_iter_next(model, &iter);
+    }
+    if (!valid)
+        valid = gtk_tree_model_get_iter_first(model, &iter);
+
+    gtk_combo_box_set_active_iter(GTK_COMBO_BOX(buttons->priv->source_currency_combo), &iter);
+    update_currency_label(buttons);
+}
+
+
+static void
+target_currency_combo_changed_cb(GtkWidget *combo, MathButtons *buttons)
+{
+    gchar *value;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+
+    model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
+    gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter);
+    gtk_tree_model_get(model, &iter, 0, &value, -1);
+
+    math_equation_set_target_currency(buttons->priv->equation, value);
+    g_free (value);
+}
+
+
+static void
+target_currency_changed_cb(MathEquation *equation, GParamSpec *spec, MathButtons *buttons)
+{
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    gboolean valid;
+  
+    if (buttons->priv->mode != FINANCIAL)
+        return;
+
+    model = gtk_combo_box_get_model(GTK_COMBO_BOX(buttons->priv->target_currency_combo));
+    valid = gtk_tree_model_get_iter_first(model, &iter);
+
+    while (valid) {
+        gchar *v;
+        gboolean matched;
+
+        gtk_tree_model_get(model, &iter, 0, &v, -1);
+        matched = strcmp (math_equation_get_target_currency(buttons->priv->equation), v) == 0;
+        g_free (v);
+        if (matched)
+            break;
+        valid = gtk_tree_model_iter_next(model, &iter);
+    }
+    if (!valid)
+        valid = gtk_tree_model_get_iter_first(model, &iter);
+
+    gtk_combo_box_set_active_iter(GTK_COMBO_BOX(buttons->priv->target_currency_combo), &iter);
+    update_currency_label(buttons);
+}
+
+
 static GtkWidget *
 load_mode(MathButtons *buttons, ButtonMode mode)
 {
@@ -841,8 +954,41 @@ load_mode(MathButtons *buttons, ButtonMode mode)
 
     /* Setup financial functions */
     if (mode == FINANCIAL) {
+        GtkListStore *model;
+        GtkCellRenderer *renderer;
+
         load_finc_dialogs(buttons);
 
+        buttons->priv->source_currency_combo = GET_WIDGET(builder, "source_currency_combo");
+        buttons->priv->target_currency_combo = GET_WIDGET(builder, "target_currency_combo");
+        buttons->priv->currency_label = GET_WIDGET(builder, "currency_label");
+
+        model = gtk_list_store_new(1, G_TYPE_STRING);
+
+        for (i = 0; currency_names[i].short_name != NULL; i++) {
+            GtkTreeIter iter;
+
+            gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+            gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, currency_names[i].short_name, -1);
+        }
+
+        gtk_combo_box_set_model(GTK_COMBO_BOX(buttons->priv->source_currency_combo), GTK_TREE_MODEL(model));
+        gtk_combo_box_set_model(GTK_COMBO_BOX(buttons->priv->target_currency_combo), GTK_TREE_MODEL(model));
+
+        renderer = gtk_cell_renderer_text_new();
+        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(buttons->priv->source_currency_combo), renderer, TRUE);
+        gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(buttons->priv->source_currency_combo), renderer, "text", 0);
+        renderer = gtk_cell_renderer_text_new();
+        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(buttons->priv->target_currency_combo), renderer, TRUE);
+        gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(buttons->priv->target_currency_combo), renderer, "text", 0);
+
+        g_signal_connect(buttons->priv->source_currency_combo, "changed", G_CALLBACK(source_currency_combo_changed_cb), buttons);
+        g_signal_connect(buttons->priv->target_currency_combo, "changed", G_CALLBACK(target_currency_combo_changed_cb), buttons);
+        g_signal_connect(buttons->priv->equation, "notify::source-currency", G_CALLBACK(source_currency_changed_cb), buttons);
+        g_signal_connect(buttons->priv->equation, "notify::target-currency", G_CALLBACK(target_currency_changed_cb), buttons);
+        source_currency_changed_cb(buttons->priv->equation, NULL, buttons);
+        target_currency_changed_cb(buttons->priv->equation, NULL, buttons);
+
         set_data(builder, "calc_finc_compounding_term_button", "finc_dialog", "ctrm_dialog");
         set_data(builder, "calc_finc_double_declining_depreciation_button", "finc_dialog", "ddb_dialog");
         set_data(builder, "calc_finc_future_value_button", "finc_dialog", "fv_dialog");
@@ -1412,145 +1558,6 @@ finc_response_cb(GtkWidget *widget, gint response_id, MathButtons *buttons)
 }
 
 
-static void
-recalculate_currency(MathButtons *buttons, CurrencyTargetRow target)
-{
-    int upper_index, lower_index;
-
-    GtkComboBox *combo_upper = GTK_COMBO_BOX(gtk_builder_get_object(buttons->priv->financial_ui, "currency_type_upper"));
-    GtkComboBox *combo_lower = GTK_COMBO_BOX(gtk_builder_get_object(buttons->priv->financial_ui, "currency_type_lower"));
-    GtkSpinButton *spin_upper = GTK_SPIN_BUTTON(gtk_builder_get_object(buttons->priv->financial_ui, "currency_amount_upper"));
-    GtkSpinButton *spin_lower = GTK_SPIN_BUTTON(gtk_builder_get_object(buttons->priv->financial_ui, "currency_amount_lower"));
-
-    GtkTreeModel *model = gtk_combo_box_get_model(combo_upper);
-    GtkTreeIter iter;
-
-    if (!gtk_combo_box_get_active_iter(combo_upper, &iter))
-        return;
-    gtk_tree_model_get(model, &iter, 0, &upper_index, -1);
-
-    if (!gtk_combo_box_get_active_iter(combo_lower, &iter))
-        return;
-    gtk_tree_model_get(model, &iter, 0, &lower_index, -1);
-
-    if (target == CURRENCY_TARGET_LOWER) {
-        MPNumber input, output;
-        mp_set_from_double (gtk_spin_button_get_value(spin_upper), &input);
-        currency_convert(&input, upper_index, lower_index, &output);
-        if (!mp_is_zero(&output))
-            gtk_spin_button_set_value(spin_lower, mp_cast_to_double(&output));
-    } else {
-        MPNumber input, output;
-        mp_set_from_double (gtk_spin_button_get_value(spin_lower), &input);
-        currency_convert(&input, lower_index, upper_index, &output);
-        if (!mp_is_zero(&output))
-            gtk_spin_button_set_value(spin_upper, mp_cast_to_double(&output));
-    }
-}
-
-
-G_MODULE_EXPORT
-void
-currency_type_cb(GtkComboBox *combo, gpointer user_data, MathButtons *buttons)
-{
-    recalculate_currency(buttons, CURRENCY_TARGET_LOWER);
-}
-
-
-G_MODULE_EXPORT
-void
-currency_amount_cb (GtkSpinButton *spinbutton, gpointer user_data, MathButtons *buttons)
-{
-    recalculate_currency(buttons, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spinbutton), "target")));
-}
-
-static void
-setup_currency_rates(MathButtons *buttons)
-{
-    static int has_run = 0;
-    int i;
-    GtkListStore *currency_store;
-    GObject *currency_type;
-
-    if (has_run)
-        return;
-
-    if (currency_rates_needs_update()) {
-        GtkWidget *dialog = gtk_message_dialog_new(NULL, 0,
-                                        GTK_MESSAGE_INFO,
-                                        GTK_BUTTONS_YES_NO,
-                                        /* Translators: Title of the error dialog when prompting to download currency rates */
-                                        _("You don't have any recent currency rates. Should some be downloaded now?"));
-        int response = gtk_dialog_run(GTK_DIALOG(dialog));
-        gtk_widget_destroy(dialog);
-
-        if (response == GTK_RESPONSE_YES) {
-            if (!currency_download_rates()) {
-                dialog = gtk_message_dialog_new(NULL, 0,
-                                                GTK_MESSAGE_ERROR,
-                                                GTK_BUTTONS_OK,
-                                                /* Translators: Title of the error dialog when unable to download currency rates */
-                                                _("Currency rates could not be downloaded. You may receive inaccurate results, or you may not receive any results at all."));
-            }
-        }
-    }
-    currency_load_rates();
-
-    currency_type = gtk_builder_get_object(buttons->priv->financial_ui, "currency_type_upper");
-    currency_store = GTK_LIST_STORE(gtk_combo_box_get_model(
-        GTK_COMBO_BOX(currency_type)));
-
-    for (i = 0; currency_names[i].short_name; i++) {
-        GtkTreeIter iter;
-        int index;
-
-        if ((index = currency_get_index(currency_names[i].short_name)) < 0) {
-            continue;
-        }
-        gtk_list_store_append(currency_store, &iter);
-        gtk_list_store_set(currency_store, &iter,
-                           0, index,
-                           1, gettext(currency_names[i].long_name),
-                           -1);
-    }
-
-    has_run = 1;
-}
-
-
-G_MODULE_EXPORT
-void
-currency_cb(GtkWidget *widget, MathButtons *buttons)
-{
-    GtkDialog *win;
-    GtkSpinButton *c_amount_upper, *c_amount_lower;
-    MPNumber display_val;
-
-    setup_currency_rates(buttons);
-
-    win = GTK_DIALOG(gtk_builder_get_object(buttons->priv->financial_ui, "currency_dialog"));
-    c_amount_upper = GTK_SPIN_BUTTON(gtk_builder_get_object(buttons->priv->financial_ui, "currency_amount_upper"));
-    c_amount_lower = GTK_SPIN_BUTTON(gtk_builder_get_object(buttons->priv->financial_ui, "currency_amount_lower"));
-    if (math_equation_get_number(buttons->priv->equation, &display_val)) {
-        double start_val = mp_cast_to_double(&display_val);
-        gtk_spin_button_set_value(c_amount_upper, start_val);
-    }
-    gtk_widget_grab_focus(GTK_WIDGET(c_amount_upper));
-
-    if (gtk_dialog_run(win) == GTK_RESPONSE_OK) {
-        gchar *result;
-
-        result = g_strdup_printf("%.2f", gtk_spin_button_get_value(c_amount_lower));
-        mp_set_from_string(result, 10, &display_val);
-        g_free(result);
-
-        math_equation_set_number(buttons->priv->equation, &display_val);
-    }
-
-    gtk_widget_hide(GTK_WIDGET(win));
-}
-
-
 G_MODULE_EXPORT
 void
 character_code_dialog_response_cb(GtkWidget *dialog, gint response_id, MathButtons *buttons)
diff --git a/src/math-equation.c b/src/math-equation.c
index 823f097..6265d01 100644
--- a/src/math-equation.c
+++ b/src/math-equation.c
@@ -46,7 +46,9 @@ enum {
     PROP_NUMBER_FORMAT,
     PROP_BASE,
     PROP_WORD_SIZE,
-    PROP_ANGLE_UNITS
+    PROP_ANGLE_UNITS,
+    PROP_SOURCE_CURRENCY,
+    PROP_TARGET_CURRENCY
 };
 
 static GType number_mode_type, number_format_type, angle_unit_type;
@@ -75,6 +77,8 @@ struct MathEquationPrivate
     gint accuracy;            /* Number of digits to show */
     gint word_size;           /* Word size in bits */
     MPAngleUnit angle_units;  /* Units for trigonometric functions */
+    char *source_currency;
+    char *target_currency;
     gint base;                /* Numeric base */
     NumberMode number_mode;   /* ??? */
     gboolean can_super_minus; /* TRUE if entering minus can generate a superscript minus */
@@ -649,6 +653,49 @@ math_equation_get_angle_units(MathEquation *equation)
 
 
 void
+math_equation_set_source_currency(MathEquation *equation, const gchar *currency)
+{
+    // FIXME: Pick based on locale  
+    if (!currency || currency[0] == '\0')
+        currency = currency_names[0].short_name;
+
+    if (strcmp(equation->priv->source_currency, currency) == 0)
+        return;
+    g_free(equation->priv->source_currency);
+    equation->priv->source_currency = g_strdup(currency);
+    g_object_notify(G_OBJECT(equation), "source-currency");
+}
+
+const gchar *
+math_equation_get_source_currency(MathEquation *equation)
+{
+    return equation->priv->source_currency;
+}
+
+
+void
+math_equation_set_target_currency(MathEquation *equation, const gchar *currency)
+{
+    // FIXME: Pick based on locale  
+    if (!currency || currency[0] == '\0')
+        currency = currency_names[0].short_name;
+
+    if (strcmp(equation->priv->target_currency, currency) == 0)
+        return;
+    g_free(equation->priv->target_currency);
+    equation->priv->target_currency = g_strdup(currency);
+    g_object_notify(G_OBJECT(equation), "target-currency");
+}
+
+
+const gchar *
+math_equation_get_target_currency(MathEquation *equation)
+{
+    return equation->priv->target_currency;
+}
+
+
+void
 math_equation_set_status(MathEquation *equation, const gchar *status)
 {
     if (strcmp(equation->priv->state.status, status) == 0)
@@ -1048,17 +1095,7 @@ set_variable(const char *name, const MPNumber *x, void *data)
 static int
 convert(const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z, void *data)
 {   
-    /* Update currency if necessary */
-    if (currency_rates_needs_update())
-        currency_download_rates();
-    currency_load_rates();
-    if (currency_get_index(x_units) >= 0 && currency_get_index(z_units) >= 0)
-    {
-        currency_convert(x, currency_get_index(x_units), currency_get_index(z_units), z);
-        return 1;
-    }
-
-    return 0;
+    return currency_convert(x, x_units, z_units, z);
 }
 
 
@@ -1324,35 +1361,41 @@ math_equation_set_property(GObject      *object,
 
     switch (prop_id) {
     case PROP_STATUS:
-      math_equation_set_status(self, g_value_get_string(value));
-      break;
+        math_equation_set_status(self, g_value_get_string(value));
+        break;
     case PROP_DISPLAY:
-      math_equation_set(self, g_value_get_string(value));
-      break;
+        math_equation_set(self, g_value_get_string(value));
+        break;
     case PROP_NUMBER_MODE:
-      math_equation_set_number_mode(self, g_value_get_int(value));
-      break;
+        math_equation_set_number_mode(self, g_value_get_int(value));
+        break;
     case PROP_ACCURACY:
-      math_equation_set_accuracy(self, g_value_get_int(value));
-      break;
+        math_equation_set_accuracy(self, g_value_get_int(value));
+        break;
     case PROP_SHOW_THOUSANDS_SEPARATORS:
-      math_equation_set_show_thousands_separators(self, g_value_get_boolean(value));
-      break;
+        math_equation_set_show_thousands_separators(self, g_value_get_boolean(value));
+        break;
     case PROP_SHOW_TRAILING_ZEROES:
-      math_equation_set_show_trailing_zeroes(self, g_value_get_boolean(value));
-      break;
+        math_equation_set_show_trailing_zeroes(self, g_value_get_boolean(value));
+        break;
     case PROP_NUMBER_FORMAT:
-      math_equation_set_number_format(self, g_value_get_int(value));
-      break;
+        math_equation_set_number_format(self, g_value_get_int(value));
+        break;
     case PROP_BASE:
-      math_equation_set_base(self, g_value_get_int(value));
-      break;
+        math_equation_set_base(self, g_value_get_int(value));
+        break;
     case PROP_WORD_SIZE:
-      math_equation_set_word_size(self, g_value_get_int(value));
-      break;
+        math_equation_set_word_size(self, g_value_get_int(value));
+        break;
     case PROP_ANGLE_UNITS:
-      math_equation_set_angle_units(self, g_value_get_int(value));
-      break;
+        math_equation_set_angle_units(self, g_value_get_int(value));
+        break;
+    case PROP_SOURCE_CURRENCY:
+        math_equation_set_source_currency(self, g_value_get_string(value));
+        break;
+    case PROP_TARGET_CURRENCY:
+        math_equation_set_target_currency(self, g_value_get_string(value));
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -1373,42 +1416,48 @@ math_equation_get_property(GObject    *object,
 
     switch (prop_id) {
     case PROP_STATUS:
-      g_value_set_string(value, self->priv->state.status);
-      break;
+        g_value_set_string(value, self->priv->state.status);
+        break;
     case PROP_DISPLAY:
-      text = math_equation_get_display(self);      
-      g_value_set_string(value, text);
-      g_free(text);
-      break;
+        text = math_equation_get_display(self);      
+        g_value_set_string(value, text);
+        g_free(text);
+        break;
     case PROP_EQUATION:
-      text = math_equation_get_equation(self);
-      g_value_set_string(value, text);
-      g_free(text);
-      break;
+        text = math_equation_get_equation(self);
+        g_value_set_string(value, text);
+        g_free(text);
+        break;
     case PROP_NUMBER_MODE:
-      g_value_set_enum(value, self->priv->number_mode);
-      break;
+        g_value_set_enum(value, self->priv->number_mode);
+        break;
     case PROP_ACCURACY:
-      g_value_set_int(value, self->priv->accuracy);
-      break;
+        g_value_set_int(value, self->priv->accuracy);
+        break;
     case PROP_SHOW_THOUSANDS_SEPARATORS:
-      g_value_set_boolean(value, self->priv->show_tsep);
-      break;
+        g_value_set_boolean(value, self->priv->show_tsep);
+        break;
     case PROP_SHOW_TRAILING_ZEROES:
-      g_value_set_boolean(value, self->priv->show_zeroes);
-      break;
+        g_value_set_boolean(value, self->priv->show_zeroes);
+        break;
     case PROP_NUMBER_FORMAT:
-      g_value_set_enum(value, self->priv->format);
-      break;
+        g_value_set_enum(value, self->priv->format);
+        break;
     case PROP_BASE:
-      g_value_set_int(value, math_equation_get_base(self));
-      break;
+        g_value_set_int(value, math_equation_get_base(self));
+        break;
     case PROP_WORD_SIZE:
-      g_value_set_int(value, self->priv->word_size);
-      break;
+        g_value_set_int(value, self->priv->word_size);
+        break;
     case PROP_ANGLE_UNITS:
-      g_value_set_enum(value, self->priv->angle_units);
-      break;
+        g_value_set_enum(value, self->priv->angle_units);
+        break;
+    case PROP_SOURCE_CURRENCY:
+        g_value_set_string(value, self->priv->source_currency);
+        break;
+    case PROP_TARGET_CURRENCY:
+        g_value_set_string(value, self->priv->target_currency);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -1531,6 +1580,20 @@ math_equation_class_init (MathEquationClass *klass)
                                                       angle_unit_type,
                                                       MP_DEGREES,
                                                       G_PARAM_READWRITE));
+    g_object_class_install_property(object_class,
+                                    PROP_SOURCE_CURRENCY,
+                                    g_param_spec_string("source-currency",
+                                                        "source-currency",
+                                                        "Source Currency",
+                                                        "",
+                                                        G_PARAM_READWRITE));
+    g_object_class_install_property(object_class,
+                                    PROP_TARGET_CURRENCY,
+                                    g_param_spec_string("target-currency",
+                                                        "target-currency",
+                                                        "target Currency",
+                                                        "",
+                                                        G_PARAM_READWRITE));
 }
 
 
@@ -1695,6 +1758,9 @@ math_equation_init(MathEquation *equation)
     equation->priv->accuracy = 9;
     equation->priv->word_size = 32;
     equation->priv->angle_units = MP_DEGREES;
+    // FIXME: Pick based on locale
+    equation->priv->source_currency = g_strdup(currency_names[0].short_name);
+    equation->priv->target_currency = g_strdup(currency_names[0].short_name);
     equation->priv->base = 10;
 
     mp_set_from_integer(0, &equation->priv->state.ans);
diff --git a/src/math-equation.h b/src/math-equation.h
index 14d7c8e..c903922 100644
--- a/src/math-equation.h
+++ b/src/math-equation.h
@@ -96,6 +96,12 @@ gint math_equation_get_word_size(MathEquation *equation);
 void math_equation_set_angle_units(MathEquation *equation, MPAngleUnit angle_unit);
 MPAngleUnit math_equation_get_angle_units(MathEquation *equation);
 
+void math_equation_set_source_currency(MathEquation *equation, const gchar *currency);
+const gchar *math_equation_get_source_currency(MathEquation *equation);
+
+void math_equation_set_target_currency(MathEquation *equation, const gchar *currency);
+const gchar *math_equation_get_target_currency(MathEquation *equation);
+
 const MPNumber *math_equation_get_answer(MathEquation *equation);
 
 void math_equation_copy(MathEquation *equation);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]