diff options
author | Reinier Heeres <reinier@heeres.eu> | 2007-11-18 10:45:42 (GMT) |
---|---|---|
committer | Reinier Heeres <reinier@heeres.eu> | 2007-11-18 10:45:42 (GMT) |
commit | e0c9a2b65caca0b1d0d8e3c5983917d60aa3866a (patch) | |
tree | 9198c758a2ad914dfa6e66351ac631d150b7b9e3 | |
parent | 19b52ed3f9ababe1b09a5294f6beb12816cb217d (diff) |
Big update; see NEWS
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | calculate.py | 37 | ||||
-rw-r--r-- | eqnparser.py | 8 | ||||
-rw-r--r-- | eqnparserhelp.py | 11 | ||||
-rw-r--r-- | mathlib.py | 63 | ||||
-rw-r--r-- | plotlib.py | 32 | ||||
-rw-r--r-- | toolbars.py | 162 |
7 files changed, 217 insertions, 98 deletions
@@ -2,6 +2,8 @@ * Updates to improve translation #4527 * Mul/Div symbol i18n #4573 * Mul/Div button fixed #3526 +* Addressed #4250 +* Added palettes to buttons in toolbar 12 diff --git a/calculate.py b/calculate.py index 03c2a92..2e98d52 100644 --- a/calculate.py +++ b/calculate.py @@ -115,8 +115,8 @@ class Calculate(activity.Activity): 'plus': '+', 'minus': '-', 'asterisk': '*', - 'multiply': u'⨯', - 'divide': u'÷', + 'multiply': '', + 'divide': '', 'slash': '/', 'BackSpace': lambda o: o.remove_character(-1), 'Delete': lambda o: o.remove_character(1), @@ -153,7 +153,7 @@ class Calculate(activity.Activity): 'End': lambda o: o.expand_selection(1000), } - IDENTIFIER_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ " + IDENTIFIER_CHARS = u"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ " def __init__(self, handle): activity.Activity.__init__(self, handle) @@ -162,12 +162,15 @@ class Calculate(activity.Activity): self.ml = MathLib() self.parser = EqnParser(self.ml) + self.KEYMAP['multiply'] = self.ml.mul_sym + self.KEYMAP['divide'] = self.ml.div_sym self.clipboard = gtk.Clipboard() self.select_reason = self.SELECT_SELECT self.buffer = u"" self.showing_version = 0 self.showing_error = False + self.ans_inserted = False self.show_vars = False self.connect("key_press_event", self.keypress_cb) @@ -322,18 +325,34 @@ class Calculate(activity.Activity): s = unicode(self.text_entry.get_text()) label = unicode(self.label_entry.get_text()) - _logger.debug('process(): parsing \'%r\', label: \'%r\'', s, label) + _logger.debug('process(): parsing %r, label: %r', s, label) res = self.parser.parse(s) + + ansvar = self.parser.get_var('Ans') + if type(res) == types.StringType and res.find('</svg>') > -1: res = SVGImage(data=res) + +# If parsing went ok, see if we have to replace the previous answer +# to get a (more) exact result + elif res is not None and ansvar is not None and self.ans_inserted: + pos = s.find(ansvar) + if len(ansvar) > 6 and pos != -1: + s2 = s.replace(ansvar, 'LastEqn') + _logger.debug('process(): replacing previous answer %r: %r', ansvar, s2) + res = self.parser.parse(s2) + eqn = Equation(label, s, res, self.color, self.owner_id) # Result ok if res is not None: self.add_equation(eqn) self.parser.set_var('Ans', self.ml.format_number(eqn.result)) + self.parser.set_var('AnsExact', eqn.result) + self.parser.set_var('LastEqn', eqn.equation) self.helper.send_message("add_eq", str(eqn)) self.showing_error = False + self.ans_inserted = False self.text_entry.set_text(u'') self.label_entry.set_text(u'') @@ -384,9 +403,10 @@ class Calculate(activity.Activity): def refresh_vars(self): """Create list of TextViews with variables and display""" + reserved = ["Ans", "AnsExact", "LastEqn", "help"] list = [] for name, value in self.parser.get_vars(): - if name == "Ans" or name == "help": + if name in reserved: continue w = gtk.TextView() b = w.get_buffer() @@ -673,11 +693,12 @@ class Calculate(activity.Activity): elif (event.state & gtk.gdk.SHIFT_MASK) and self.SHIFT_KEYMAP.has_key(key): f = self.SHIFT_KEYMAP[key] return f(self) - elif key in self.IDENTIFIER_CHARS: + elif unicode(key) in self.IDENTIFIER_CHARS: self.button_pressed(self.TYPE_TEXT, key) elif self.KEYMAP.has_key(key): f = self.KEYMAP[key] - if type(f) is types.StringType: + if type(f) is types.StringType or \ + type(f) is types.UnicodeType: self.button_pressed(self.TYPE_TEXT, f) else: return f(self) @@ -739,6 +760,7 @@ class Calculate(activity.Activity): elif pos == 0: ans = self.parser.ml.format_number(self.parser.get_var('Ans')) str = ans + str + self.ans_inserted = True self.text_entry.insert_text(str, pos) self.text_entry.set_position(pos + len(str)) @@ -754,6 +776,7 @@ class Calculate(activity.Activity): ans = self.parser.ml.format_number(self.parser.get_var('Ans')) self.text_entry.set_text(ans + str) self.text_entry.set_position(len(ans) + len(str)) + self.ans_inserted = True elif len(sel) is 2: self.text_entry.set_text(text[:start] + str + text[end:]) self.text_entry.set_position(pos + start - end + len(str)) diff --git a/eqnparser.py b/eqnparser.py index c4ccca3..4895918 100644 --- a/eqnparser.py +++ b/eqnparser.py @@ -209,6 +209,7 @@ class EqnParser: self.register_operator('-', self.OP_PRE, 1, lambda x: self.ml.negate(x[0])) self.register_operator('*', self.OP_DIADIC, 1, lambda x: self.ml.mul(x[0], x[1])) self.register_operator(u'⨯', self.OP_DIADIC, 1, lambda x: self.ml.mul(x[0], x[1])) + self.register_operator(u'×', self.OP_DIADIC, 1, lambda x: self.ml.mul(x[0], x[1])) self.register_operator('/', self.OP_DIADIC, 1, lambda x: self.ml.div(x[0], x[1])) self.register_operator(u'÷', self.OP_DIADIC, 1, lambda x: self.ml.div(x[0], x[1])) @@ -297,7 +298,8 @@ class EqnParser: # _logger.error('EqnParser.lookup_var(): recursion detected') # return None # self.variables[name].highest_level = level - if type(self.variables[name]) is types.UnicodeType and self.parse_var[name]: + if (type(self.variables[name]) is types.UnicodeType or type(self.variables[name]) is types.StringType) \ + and self.parse_var[name]: return self.parse(self.variables[name], reset=False) else: return self.variables[name] @@ -353,9 +355,8 @@ class EqnParser: self.ps.set_error(ParserState.PARSE_ERROR, msg=_('Unable to parse argument %d: \'%s\'') % (i, args[i])) return None - res = f(pargs) try: - pass + res = f(pargs) # Maybe we should map exceptions to more obvious error messages except Exception, inst: @@ -543,7 +544,6 @@ class EqnParser: if right_val == None: return None - print('left: %r, right: %r') % (left_val, right_val) res = of([left_val, right_val]) _logger.debug('OP: %s, %s ==> %s', self.ml.format_number(left_val), self.ml.format_number(right_val), self.ml.format_number(res)) left_val = res diff --git a/eqnparserhelp.py b/eqnparserhelp.py index 2eb8d7c..a39167e 100644 --- a/eqnparserhelp.py +++ b/eqnparserhelp.py @@ -35,16 +35,27 @@ class EqnParserHelp(): DICT = { # These are the help topics and should explain how things work "acos": _("help_acos"), + "and": _("help_and"), "asin": _("help_asin"), + "atan": _("help_atan"), "cos": _("help_cos"), + "cosh": _("help_cosh"), "exp": _("help_exp"), + "fac": _("help_fac"), "functions": _("help_functions"), + "ln": _("help_ln"), "operators": _("help_operators"), + "or": _("help_or"), "plot": _("help_plot"), "sin": _("help_sin"), + "sinh": _("help_sinh"), "sqrt": _("help_sqrt"), + "square": _("help_square"), + "tan": _("help_tan"), + "tanh": _("help_tanh"), "test": _("help_test"), "variables": _("help_variables"), + "xor": _("help_xor"), } def __init__(self): @@ -107,14 +107,16 @@ class MathLib: return 'False' elif type(n) is types.StringType: return n + elif type(n) is types.UnicodeType: + return n elif type(n) is types.NoneType: - return 'Error' + return _('Undefined') elif type(n) is types.IntType: n = self.d(n) elif type(n) is types.FloatType: n = self.d(n) elif not isinstance(n, Decimal): - return 'Error: unsupported type' + return _('Error: unsupported type') (sign, digits, exp) = n.as_tuple() if len(digits) > 9: exp += len(digits) - 9 @@ -131,12 +133,20 @@ class MathLib: disp_exp = exp + len(digits) else: disp_exp = 0 - elif 0 < int_len < 6: + elif -5 < int_len < 9: disp_exp = 0 else: disp_exp = int_len - 1 - + dot_pos = int_len - disp_exp + +# _logger.debug('len(digits) %d, exp: %d, int_len: %d, disp_exp: %d, dot_pos: %d', len(digits), exp, int_len, disp_exp, dot_pos) + + if dot_pos < 0: + res = '0' + self.fraction_sep + for i in xrange(dot_pos, 0): + res += '0' + for i in xrange(len(digits)): if i == dot_pos: if i == 0: @@ -145,7 +155,7 @@ class MathLib: res += self.fraction_sep res += str(digits[i]) - if len(digits) < dot_pos: + if int_len > 0 and len(digits) < dot_pos: for i in xrange(len(digits), dot_pos): res += '0' @@ -199,12 +209,12 @@ class MathLib: def pow(self, x, y): if self.is_int(y): - return x ** int(y) + return float(x) ** int(y) else: - return self.d(math.pow(x, y)) + return self.d(math.pow(float(x), float(y))) def sqrt(self, x): - return self.d(math.sqrt(x)) + return self.d(math.sqrt(float(x))) def mod(self, x, y): if self.is_int(y): @@ -213,17 +223,17 @@ class MathLib: return self.d(0) def exp(self, x): - return self.d(math.exp(x)) + return self.d(math.exp(float(x))) def ln(self, x): if x > 0: - return self.d(math.log(x)) + return self.d(math.log(float(x))) else: return 0 def log10(self, x): if x > 0: - return self.d(math.log10(x)) + return self.d(math.log10(float(x))) else: return 0 @@ -241,49 +251,50 @@ class MathLib: return res def sin(self, x): - return self.d(math.sin(x * self.angle_scaling)) + return self.d(math.sin(float(x * self.angle_scaling))) def cos(self, x): - return self.d(math.cos(x * self.angle_scaling)) + _logger.debug('cos of %r, (%r)', x, self.angle_scaling) + return self.d(math.cos(float(x * self.angle_scaling))) def tan(self, x): - return self.d(math.tan(x * self.angle_scaling)) + return self.d(math.tan(float(x * self.angle_scaling))) def asin(self, x): - return self.d(math.asin(x)) / self.angle_scaling + return self.d(math.asin(float(x))) / self.angle_scaling def acos(self, x): - return self.d(math.acos(x)) / self.angle_scaling + return self.d(math.acos(float(x))) / self.angle_scaling def atan(self, x): - return self.d(math.atan(x)) / self.angle_scaling + return self.d(math.atan(float(x))) / self.angle_scaling def sinh(self, x): - return self.d(math.sinh(x)) + return self.d(math.sinh(float(x))) def cosh(self, x): - return self.d(math.cosh(x)) + return self.d(math.cosh(float(x))) def tanh(self, x): - return self.d(math.tanh(x)) + return self.d(math.tanh(float(x))) def asinh(self, x): - return self.d(math.asinh(x)) + return self.d(math.asinh(float(x))) def acosh(self, x): - return self.d(math.acosh(x)) + return self.d(math.acosh(float(x))) def atanh(self, x): - return self.d(math.atanh(x)) + return self.d(math.atanh(float(x))) def round(self, x): - return self.d(round(x)) + return self.d(round(float(x))) def floor(self, x): - return self.d(math.floor(x)) + return self.d(math.floor(float(x))) def ceil(self, x): - return self.d(math.ceil(x)) + return self.d(math.ceil(float(x))) def rand_float(self): return self.d(random.random()) @@ -17,6 +17,8 @@ # Change log: # 2007-09-04: rwh, first version +import types + import logging _logger = logging.getLogger('PlotLib') @@ -83,10 +85,14 @@ class PlotLib: self.svg_data += '" />\n' def add_text(self, c, text, rotate=0): + if type(text) is types.UnicodeType: + text = text.encode('utf-8') c = self.rcoords_to_coords(c) + self.svg_data += '<text x="%f" y="%f"' % (c[0], c[1]) if rotate != 0: self.svg_data += ' transform="rotate(%d)"' % (rotate) + self.svg_data += '>%s</text>\n' % (text) def determine_bounds(self, vals): @@ -98,10 +104,20 @@ class PlotLib: self.maxx = max(float(x), self.maxx) self.maxy = max(float(y), self.maxy) + x_space = 0.02 * (self.maxx - self.minx) + self.minx -= x_space + self.maxx += x_space + + y_space = 0.02 * (self.maxy - self.miny) + self.miny -= y_space + self.maxy += y_space + def rcoords_to_coords(self, pair): + """Convert fractional coordinates to image coordinates""" return (pair[0] * self.width, pair[1] * self.height) def vals_to_rcoords(self, pair): + """Convert values to fractional coordinates""" ret = (0.1 + (pair[0] - self.minx) / (self.maxx - self.minx) * 0.8, \ 0.9 - (pair[1] - self.miny) / (self.maxy - self.miny) * 0.8) return ret @@ -116,6 +132,12 @@ class PlotLib: self.plot_polyline(c, "blue") + def get_label_vals(self, startx, endx, n, opts=()): + """Return label values""" + range = endx - startx + logrange = log(range) + haszero = (startx < 0 & endx < 0) + def draw_axes(self, labelx, labely): self.plot_line((0.08, 0.92), (0.92, 0.92), "black") self.add_text((0.50, 0.98), labelx) @@ -129,13 +151,15 @@ class PlotLib: f.close() def plot(self, eqn, range_spec): + _logger.debug('plot(): %r, %r', eqn, range_spec) + (var, range) = self.parse_range(range_spec) if range is None: _logger.error('Unable to parse range') return False _logger.info('Plot range for var %s: %r', var, range) - self.set_size(200, 200) + self.set_size(250, 250) self.create_image() self.draw_axes(var, eqn) @@ -147,4 +171,8 @@ class PlotLib: self.finish_image() # self.export_plot("/tmp/calculate_graph.svg") - return self.get_svg() + svg = self.get_svg() + if type(svg) is types.UnicodeType: + return svg.encode('utf-8') + else: + return svg diff --git a/toolbars.py b/toolbars.py index cc137dd..600e554 100644 --- a/toolbars.py +++ b/toolbars.py @@ -4,46 +4,70 @@ import pygtk pygtk.require('2.0') import gtk from mathlib import MathLib + +from sugar.graphics.palette import Palette +from sugar.graphics.menuitem import MenuItem from sugar.graphics.toolbutton import ToolButton from sugar.graphics.toggletoolbutton import ToggleToolButton import logging _logger = logging.getLogger('calc-activity') -class TextToolButton(gtk.ToolButton): - def __init__(self, text, cb): - gtk.ToolButton.__init__(self) - self.set_label(text) - self.connect('clicked', cb) +from gettext import gettext as _ class IconToolButton(ToolButton): - def __init__(self, text, cb): - ToolButton.__init__(self, text) + def __init__(self, icon_name, text, cb, help_cb=None): + ToolButton.__init__(self) + + self.set_label(icon_name) + self.create_palette(text, help_cb) + self.connect('clicked', cb) -class TextToggleToolButton(gtk.ToggleToolButton): + def create_palette(self, text, help_cb): + p = Palette(text) + + if help_cb is not None: + item = MenuItem(_('Help'), 'action-help') + item.connect('activate', help_cb) + item.show() + p.menu.append(item) + + self.set_palette(p) + +class IconToggleToolButton(ToggleToolButton): def __init__(self, items, cb): - gtk.ToggleToolButton.__init__(self) + ToggleToolButton.__init__(self) self.items = items - self.set_label(items[0]) + self.set_label(items[0][0]) + self.set_tooltip(items[0][1]) self.selected = 0 self.connect('clicked', self.toggle_button) self.callback = cb def toggle_button(self, w): self.selected = (self.selected + 1) % len(self.items) - self.set_label(self.items[self.selected]) + but = self.items[self.selected] + self.set_label(but[0]) + self.set_tooltip(but[1]) if self.callback is not None: - self.callback(self.items[self.selected]) + self.callback(but[0]) -class IconToggleToolButton(ToggleToolButton): - def __init__(self, text, cb): - ToggleToolButton.__init__(self, text) +class TextToggleToolButton(gtk.ToggleToolButton): + def __init__(self, items, cb): + gtk.ToggleToolButton.__init__(self) + self.items = items + self.set_label(items[0]) + self.selected = 0 self.connect('clicked', self.toggle_button) + self.callback = cb def toggle_button(self, w): + self.selected = (self.selected + 1) % len(self.items) + but = self.items[self.selected] + self.set_label(but) if self.callback is not None: - self.callback(self.items[self.selected]) + self.callback(but) class LineSeparator(gtk.SeparatorToolItem): def __init__(self): @@ -54,109 +78,129 @@ class EditToolbar(gtk.Toolbar): def __init__(self, calc): gtk.Toolbar.__init__(self) - self.insert(TextToolButton('Copy', + self.insert(IconToolButton('copy', _('Copy'), lambda x: calc.text_copy()), -1) - self.insert(TextToolButton('Paste', + self.insert(IconToolButton('paste', _('Paste'), lambda x: calc.text_paste()), -1) - self.insert(TextToolButton('Cut', + self.insert(IconToolButton('cut', _('Cut'), lambda x: calc.text_cut()), -1) class AlgebraToolbar(gtk.Toolbar): def __init__(self, calc): gtk.Toolbar.__init__(self) - self.insert(TextToolButton('square', - lambda x: calc.button_pressed(calc.TYPE_OP_POST, '^2')), -1) + self.insert(IconToolButton('square', _('Square'), + lambda x: calc.button_pressed(calc.TYPE_OP_POST, '^2'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(square)')), -1) - self.insert(TextToolButton('sqrt', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'sqrt')), -1) + self.insert(IconToolButton('sqrt', _('Square root'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'sqrt'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(sqrt)')), -1) self.insert(LineSeparator(), -1) - self.insert(TextToolButton('exp', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'exp')), -1) + self.insert(IconToolButton('exp', _('e to the power x'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'exp'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(exp)')), -1) - self.insert(TextToolButton('ln', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'ln')), -1) + self.insert(IconToolButton('ln', _('Natural logarithm'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'ln'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(sqrt)')), -1) self.insert(LineSeparator(), -1) - self.insert(TextToolButton('fac', - lambda x: calc.button_pressed(calc.TYPE_OP_POST, '!')), -1) + self.insert(IconToolButton('fac', _('Factorial'), + lambda x: calc.button_pressed(calc.TYPE_OP_POST, '!'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(fac)')), -1) class TrigonometryToolbar(gtk.Toolbar): def __init__(self, calc): gtk.Toolbar.__init__(self) - self.insert(TextToolButton('sin', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'sin')), -1) + self.insert(IconToolButton('sin', _('Sine'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'sin'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(sin)')), -1) - self.insert(TextToolButton('cos', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'cos')), -1) + self.insert(IconToolButton('cos', _('Cosine'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'cos'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(cos)')), -1) - self.insert(TextToolButton('tan', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'tan')), -1) + self.insert(IconToolButton('tan', _('Tangent'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'tan'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(tan)')), -1) self.insert(LineSeparator(), -1) - self.insert(TextToolButton('asin', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'asin')), -1) + self.insert(IconToolButton('asin', _('Arc sine'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'asin'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(asin)')), -1) - self.insert(TextToolButton('acos', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'acos')), -1) + self.insert(IconToolButton('acos', _('Arc cosine'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'acos'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(acos)')), -1) - self.insert(TextToolButton('atan', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'atan')), -1) + self.insert(IconToolButton('atan', _('Arc tangent'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'atan'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(atan)')), -1) self.insert(LineSeparator(), -1) - self.insert(TextToolButton('sinh', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'sinh')), -1) + self.insert(IconToolButton('sinh', _('Hyperbolic sine'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'sinh'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(sinh)')), -1) - self.insert(TextToolButton('cosh', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'cosh')), -1) + self.insert(IconToolButton('cosh', _('Hyperbolic cosine'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'cosh'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(cosh)')), -1) - self.insert(TextToolButton('tanh', - lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'tanh')), -1) + self.insert(IconToolButton('tanh', _('Hyperbolic tangent'), + lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'tanh'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(tanh)')), -1) class BooleanToolbar(gtk.Toolbar): def __init__(self, calc): gtk.Toolbar.__init__(self) - self.insert(TextToolButton('and', - lambda x: calc.button_pressed(calc.TYPE_OP_POST, '&')), -1) + self.insert(IconToolButton('and', _('Logical and'), + lambda x: calc.button_pressed(calc.TYPE_OP_POST, '&'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(and))')), -1) - self.insert(TextToolButton('or', - lambda x: calc.button_pressed(calc.TYPE_OP_POST, '|')), -1) + self.insert(IconToolButton('or', _('Logical or'), + lambda x: calc.button_pressed(calc.TYPE_OP_POST, '|'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(or)')), -1) - self.insert(TextToolButton('xor', - lambda x: calc.button_pressed(calc.TYPE_OP_POST, '^')), -1) + self.insert(IconToolButton('xor', _('Logical xor'), + lambda x: calc.button_pressed(calc.TYPE_OP_POST, '^'), + lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(xor)')), -1) self.insert(LineSeparator(), -1) - self.insert(TextToolButton('eq', + self.insert(IconToolButton('eq', _('Equals'), lambda x: calc.button_pressed(calc.TYPE_OP_POST, '=')), -1) - self.insert(TextToolButton('neq', + self.insert(IconToolButton('neq', _('Not equals'), lambda x: calc.button_pressed(calc.TYPE_OP_POST, '!=')), -1) class ConstantsToolbar(gtk.Toolbar): def __init__(self, calc): gtk.Toolbar.__init__(self) - self.insert(TextToolButton('pi', + self.insert(IconToolButton('pi', _('Pi'), lambda x: calc.button_pressed(calc.TYPE_TEXT, 'pi')), -1) - self.insert(TextToolButton('e', + self.insert(IconToolButton('e', _('e'), lambda x: calc.button_pressed(calc.TYPE_TEXT, 'e')), -1) class FormatToolbar(gtk.Toolbar): def __init__(self, calc): gtk.Toolbar.__init__(self) - el = ['deg', 'rad'] - self.insert(TextToggleToolButton(el, + el = [ + ['deg', _('Degrees')], + ['rad', _('Radians')] + ] + self.insert(IconToggleToolButton(el, lambda x: self.update_angle_type(x, calc)), -1) def update_angle_type(self, text, calc): |