[gnome-calculator] Support entering left/right shift with keyboard (fixes #98)



commit 91f4d06bf31e3e4c27ab6dedf630ec6e08bdba7e
Author: Robert Roth <robert roth off gmail com>
Date:   Tue Mar 26 13:28:50 2019 +0200

    Support entering left/right shift with keyboard (fixes #98)

 lib/equation-lexer.vala    | 17 ++++++++++++++++-
 lib/equation-parser.vala   | 31 +++++++++++++++++++++++++++++++
 lib/math-equation.vala     | 40 ++++++++++++++++++++++++++++++++++++++--
 lib/number.vala            |  2 +-
 src/buttons-programming.ui |  4 ++--
 src/math-buttons.vala      |  2 +-
 src/math-display.vala      | 10 ++++++++++
 7 files changed, 99 insertions(+), 7 deletions(-)
---
diff --git a/lib/equation-lexer.vala b/lib/equation-lexer.vala
index 405f062c..6a5b8d92 100644
--- a/lib/equation-lexer.vala
+++ b/lib/equation-lexer.vala
@@ -54,6 +54,8 @@ public enum LexerTokenType
     FUNCTION,           /* Function */
     UNIT,               /* Unit of conversion */
     VARIABLE,           /* Variable name */
+    SHIFT_LEFT,         /* Shift left */
+    SHIFT_RIGHT,        /* Shift right */
     ASSIGN,             /* = */
     L_R_BRACKET,        /* ( */
     R_R_BRACKET,        /* ) */
@@ -233,6 +235,12 @@ public class PreLexer : Object
         if (c == ';')
             return LexerTokenType.ARGUMENT_SEPARATOR;
 
+        if (c == '»')
+            return LexerTokenType.SHIFT_RIGHT;
+
+        if (c == '«')
+            return LexerTokenType.SHIFT_LEFT;
+
         if (c == ' ' || c == '\r' || c == '\t' || c == '\n')
             return LexerTokenType.PL_SKIP;
 
@@ -379,7 +387,14 @@ public class Lexer : Object
             type = prelexer.get_next_token ();
         }
 
-        if (type == LexerTokenType.AND || type == LexerTokenType.OR || type == LexerTokenType.XOR || type == 
LexerTokenType.NOT || type == LexerTokenType.ADD || type == LexerTokenType.SUBTRACT || type == 
LexerTokenType.MULTIPLY || type == LexerTokenType.DIVIDE || type == LexerTokenType.L_FLOOR || type == 
LexerTokenType.R_FLOOR || type == LexerTokenType.L_CEILING || type == LexerTokenType.R_CEILING || type == 
LexerTokenType.ROOT || type == LexerTokenType.ROOT_3 || type == LexerTokenType.ROOT_4 || type == 
LexerTokenType.ASSIGN || type == LexerTokenType.L_R_BRACKET || type == LexerTokenType.R_R_BRACKET || type == 
LexerTokenType.L_S_BRACKET || type == LexerTokenType.R_S_BRACKET || type == LexerTokenType.L_C_BRACKET || 
type == LexerTokenType.R_C_BRACKET || type == LexerTokenType.ABS || type == LexerTokenType.POWER || type == 
LexerTokenType.FACTORIAL || type == LexerTokenType.PERCENTAGE || type == LexerTokenType.ARGUMENT_SEPARATOR)
+        if (type == LexerTokenType.AND || type == LexerTokenType.OR || type == LexerTokenType.XOR || type == 
LexerTokenType.NOT
+            || type == LexerTokenType.ADD || type == LexerTokenType.SUBTRACT || type == 
LexerTokenType.MULTIPLY || type == LexerTokenType.DIVIDE
+            || type == LexerTokenType.L_FLOOR || type == LexerTokenType.R_FLOOR || type == 
LexerTokenType.L_CEILING || type == LexerTokenType.R_CEILING
+            || type == LexerTokenType.ROOT || type == LexerTokenType.ROOT_3 || type == LexerTokenType.ROOT_4 
|| type == LexerTokenType.ASSIGN
+            || type == LexerTokenType.L_R_BRACKET || type == LexerTokenType.R_R_BRACKET || type == 
LexerTokenType.L_S_BRACKET
+            || type == LexerTokenType.R_S_BRACKET || type == LexerTokenType.L_C_BRACKET || type == 
LexerTokenType.R_C_BRACKET
+            || type == LexerTokenType.ABS || type == LexerTokenType.POWER || type == 
LexerTokenType.FACTORIAL || type == LexerTokenType.PERCENTAGE
+            || type == LexerTokenType.ARGUMENT_SEPARATOR || type == LexerTokenType.SHIFT_LEFT || type == 
LexerTokenType.SHIFT_RIGHT)
             return insert_token (type);
 
         /* [LexerTokenType.PL_SUPER_MINUS][LexerTokenType.PL_SUPER_DIGIT]+ */
diff --git a/lib/equation-parser.vala b/lib/equation-parser.vala
index 8f0d954f..71b53fdb 100644
--- a/lib/equation-parser.vala
+++ b/lib/equation-parser.vala
@@ -39,6 +39,7 @@ private enum Precedence
     UNARY_MINUS     = 10,
     POWER           = 10,
     ROOT            = 10,
+    SHIFT           = 10,
     FACTORIAL       = 11,
     NUMBER_VARIABLE = 12,
     /* DEPTH should be always at the bottom. It stops node jumping off the current depth level. */
@@ -563,6 +564,7 @@ public class AddNode : LRNode
     }
 }
 
+
 public class SubtractNode : LRNode
 {
     public bool do_percentage = false;
@@ -598,6 +600,22 @@ public class MultiplyNode : LRNode
     }
 }
 
+public class ShiftNode : LRNode
+{
+    public ShiftNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
+    {
+        base (parser, token, precedence, associativity);
+    }
+
+    public override Number solve_lr (Number l, Number r)
+    {
+        if (first_token().type == LexerTokenType.SHIFT_LEFT)
+            return l.shift (r.to_integer ());
+        else
+            return l.shift (r.multiply_integer (-1).to_integer ());
+    }
+}
+
 public class DivideNode : LRNode
 {
     public DivideNode (Parser parser, LexerToken? token, uint precedence, Associativity associativity)
@@ -1145,6 +1163,8 @@ public class Parser
             return Precedence.UNIT;
         if (type == LexerTokenType.IN)
             return Precedence.CONVERT;
+        if (type == LexerTokenType.SHIFT_LEFT || type == LexerTokenType.SHIFT_RIGHT)
+            return Precedence.SHIFT;
         return Precedence.TOP;
     }
 
@@ -1811,6 +1831,17 @@ public class Parser
 
             return true;
         }
+        else if (token.type == LexerTokenType.SHIFT_LEFT || token.type == LexerTokenType.SHIFT_RIGHT)
+        {
+            insert_into_tree (new ShiftNode (this, token, make_precedence_t (token.type), get_associativity 
(token)));
+
+            if (!expression_1 ())
+                return false;
+            if (!expression_2 ())
+                return false;
+
+            return true;
+        }
         else if (token.type == LexerTokenType.MOD)
         {
             insert_into_tree (new ModulusDivideNode (this, token, make_precedence_t (token.type), 
get_associativity (token)));
diff --git a/lib/math-equation.vala b/lib/math-equation.vala
index 1932e6a2..463c1187 100644
--- a/lib/math-equation.vala
+++ b/lib/math-equation.vala
@@ -830,6 +830,34 @@ public class MathEquation : Gtk.SourceBuffer
             }
         }
 
+        /* Replace >> with » (not on keyboards) */
+        if (!has_selection && text == ">")
+        {
+            Gtk.TextIter iter, iter_prev;
+            get_iter_at_mark (out iter, get_insert ());
+            get_iter_at_mark (out iter_prev, get_insert ());
+            if (iter_prev.backward_char () &&  iter_prev.get_char ().to_string () == ">" )
+            {
+                (this as Gtk.TextBuffer).backspace (iter, true, true);
+                insert_at_cursor ("»", -1);
+                return;
+            }
+        }
+
+        /* Replace << with « (not on keyboard) */
+        if (!has_selection && text == "<")
+        {
+            Gtk.TextIter iter, iter_prev;
+            get_iter_at_mark (out iter, get_insert ());
+            get_iter_at_mark (out iter_prev, get_insert ());
+            if (iter_prev.backward_char () &&  iter_prev.get_char ().to_string () == "<" )
+            {
+                (this as Gtk.TextBuffer).backspace (iter, true, true);
+                insert_at_cursor ("«", -1);
+                return;
+            }
+        }
+
         /* Can't enter superscript minus after entering digits */
         if ("⁰¹²³⁴⁵⁶⁷⁸⁹".index_of (text) >= 0 || text == "⁻")
             can_super_minus = false;
@@ -1257,7 +1285,7 @@ public class MathEquation : Gtk.SourceBuffer
         clear_ans (false);
     }
 
-    public void shift (int count)
+    public void insert_shift (int count)
     {
         var z = number;
         if (z == null)
@@ -1267,7 +1295,15 @@ public class MathEquation : Gtk.SourceBuffer
             return;
         }
 
-        set_number (z.shift (count));
+        if (count > 0)
+            insert ("«");
+        else {
+            insert ("»");
+            count *= -1;
+        }
+
+        insert (count.to_string ());
+        // set_number (z.shift (count));
     }
 
     public void toggle_bit (uint bit)
diff --git a/lib/number.vala b/lib/number.vala
index 9d340cf3..9ca74180 100644
--- a/lib/number.vala
+++ b/lib/number.vala
@@ -846,7 +846,7 @@ public class Number : Object
     }
 
     /* Sets z = x shifted by 'count' bits.  Positive shift increases the value, negative decreases */
-    public Number shift (int count)
+    public Number shift (int64 count)
     {
         if (!is_integer ())
         {
diff --git a/src/buttons-programming.ui b/src/buttons-programming.ui
index de1bda9e..60a49277 100644
--- a/src/buttons-programming.ui
+++ b/src/buttons-programming.ui
@@ -2005,7 +2005,7 @@
                   <object class="GtkLabel" id="label7">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="label">&lt;</property>
+                    <property name="label">&lt;&lt;</property>
                   </object>
                   <packing>
                     <property name="position">0</property>
@@ -2048,7 +2048,7 @@
                   <object class="GtkLabel" id="label6">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="label">&gt;</property>
+                    <property name="label">&gt;&gt;</property>
                   </object>
                   <packing>
                     <property name="position">0</property>
diff --git a/src/math-buttons.vala b/src/math-buttons.vala
index 2e7f5461..694ec7f1 100644
--- a/src/math-buttons.vala
+++ b/src/math-buttons.vala
@@ -198,7 +198,7 @@ public class MathButtons : Gtk.Box
 
     private void on_bitshift (SimpleAction action, Variant? param)
     {
-        equation.shift (param.get_int32 ());
+        equation.insert_shift (param.get_int32 ());
     }
 
     private void on_insert_numeric_point (SimpleAction action, Variant? param)
diff --git a/src/math-display.vala b/src/math-display.vala
index 87528e0c..aaa8b6bd 100644
--- a/src/math-display.vala
+++ b/src/math-display.vala
@@ -232,6 +232,16 @@ public class MathDisplay : Gtk.Viewport
                 equation.insert ("×");
                 return true;
             }
+            if (c == '>')
+            {
+                equation.insert (">");
+                return true;
+            }
+            if (c == '<')
+            {
+                equation.insert ("<");
+                return true;
+            }
             if (c == '/')
             {
                 equation.insert ("÷");


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