This commit is contained in:
j 2025-01-31 18:43:02 +05:30
commit 2a9f5822e5
28 changed files with 4155 additions and 0 deletions

273
bin/calcool Executable file
View file

@ -0,0 +1,273 @@
#!/usr/bin/python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
### BEGIN LICENSE
# Copyright (C) 2010 jan gerber <j@mailb.org>
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
### END LICENSE
from __future__ import division
import sys
import os
import gtk
from gtksourceview2 import View as GtkSourceView
from math import *
safe_list = ['math','acos', 'asin', 'atan', 'atan2', 'ceil', 'cos',
'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod',
'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi',
'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
#use the list to filter the local namespace
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
#add any needed builtins back in.
safe_dict['abs'] = abs
import re
# Check if we are working in the source tree or from the installed
# package and mangle the python path accordingly
if os.path.dirname(sys.argv[0]) != ".":
if sys.argv[0][0] == "/":
fullPath = os.path.dirname(sys.argv[0])
else:
fullPath = os.getcwd() + "/" + os.path.dirname(sys.argv[0])
else:
fullPath = os.getcwd()
sys.path.insert(0, os.path.dirname(fullPath))
from calcool import AboutCalcoolDialog
from calcool.calcoolconfig import getdatapath
class CalcoolWindow(gtk.Window):
__gtype_name__ = "CalcoolWindow"
record_type = "http://wiki.ubuntu.com/Quickly/CalcoolDocument"
database_name = "calcool"
filename = ''
def __init__(self):
"""__init__ - This function is typically not called directly.
Creation a CalcoolWindow requires redeading the associated ui
file and parsing the ui definition extrenally,
and then calling CalcoolWindow.finish_initializing().
Use the convenience function NewCalcoolWindow to create
CalcoolWindow object.
"""
pass
def finish_initializing(self, builder):
"""finish_initalizing should be called after parsing the ui definition
and creating a CalcoolWindow object with it in order to finish
initializing the start of the new CalcoolWindow instance.
"""
#get a reference to the builder and set up the signals
self.builder = builder
self.builder.connect_signals(self)
def about(self, widget, data=None):
"""about - display the about box for calcool """
about = AboutCalcoolDialog.NewAboutCalcoolDialog()
response = about.run()
about.destroy()
def quit(self, widget, data=None):
"""quit - signal handler for closing the CalcoolWindow"""
self.destroy()
def on_destroy(self, widget, data=None):
"""on_destroy - called when the CalcoolWindow is close. """
#clean up code for saving application state should be added here
gtk.main_quit()
def update_output(self):
self.builder.get_object('status').set_text('Calculating...')
txt = self.builder.get_object('input').get_buffer()
text = txt.get_text(txt.get_start_iter(), txt.get_end_iter())
rows = text.split('\n')
otxt = []
computed_values = []
def expand_lines(line):
return re.sub('line(\d+)', lambda m: 'line%010d'%int(m.groups(0)[0]), line)
def resolve_row(r, line):
#if r not in self._results:
try:
r_ = r
r_ = expand_lines(r_)
match = re.compile('line(\d+)').findall(r)
match = filter(lambda l: int(l) <= len(rows), match)
if match:
for l in match:
l = int(l)
assert(l!=line)
value = '(%s)' % expand_lines(rows[l-1])
r_ = r_.replace('line%010d' % l, value)
r_ = resolve_row(r_, line)
#print r, r_
result = str(eval(r_, {"__builtins__":None}, safe_dict))
#highlight computed values
if result != r:
offset = len('\n'.join(otxt))
computed_values.append((offset, offset+len(result)+1))
except:
result = r
return result
for i, r in enumerate(rows):
otxt.append(resolve_row(r, i+1))
output = self.builder.get_object('output').get_buffer()
output.set_text('\n'.join(otxt))
tagTable = output.get_tag_table()
computed = tagTable.lookup('computed')
if not computed:
computed = gtk.TextTag('computed')
computed.set_property('weight', 700) # pango.WEIGHT_BOLD = 700
tagTable.add(computed)
for start, end in computed_values:
currentIter = output.get_iter_at_offset(start)
currentEndIter = output.get_iter_at_offset(end)
output.apply_tag(computed, currentIter, currentEndIter)
self.builder.get_object('status').set_text('')
def keypressed(self, widget, data=None):
self.update_output()
def new_file(self, widget, data=None):
self.filename = ''
buff = self.builder.get_object("input").get_buffer()
buff.set_text("")
self.update_output()
def load_file(self, filename):
with open(filename) as f:
text = f.read().decode('utf-8')
#set the UI to display the string
buff = self.builder.get_object("input").get_buffer()
buff.set_text(text)
self.update_output()
self.filename = filename
def open_file(self, widget, data=None):
dialog = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
dialog.set_default_response(gtk.RESPONSE_OK)
filter = gtk.FileFilter()
filter.set_name("Calcool Documents")
filter.add_mime_type("text/x-calcool")
filter.add_pattern("*.calc")
dialog.add_filter(filter)
filter = gtk.FileFilter()
filter.set_name("All files")
filter.add_pattern("*")
dialog.add_filter(filter)
response = dialog.run()
if response == gtk.RESPONSE_OK:
filename = dialog.get_filename()
dialog.destroy()
self.load_file(filename)
else:
dialog.destroy()
def save_file(self, widget, data=None):
if not self.filename:
return self.save_as_file(widget)
title = self.filename
buff = self.builder.get_object("input").get_buffer()
start_iter = buff.get_start_iter()
end_iter = buff.get_end_iter()
text = buff.get_text(start_iter,end_iter)
with open(self.filename, "w") as f:
f.write(text.encode('utf-8'))
def save_as_file(self, widget, data=None):
dialog = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_SAVE,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
filter = gtk.FileFilter()
filter.set_name("Calcool Documents")
filter.add_mime_type("text/x-calcool")
filter.add_pattern("*.calc")
dialog.add_filter(filter)
filter = gtk.FileFilter()
filter.set_name("All files")
filter.add_pattern("*")
dialog.add_filter(filter)
response = dialog.run()
if response == gtk.RESPONSE_OK:
self.filename = dialog.get_filename()
self.save_file(widget)
dialog.destroy()
def cut(self, widget, data=None):
pass
def copy(self, widget, data=None):
pass
def paste(self, widget, data=None):
pass
def delete(self, widget, data=None):
pass
def NewCalcoolWindow():
"""NewCalcoolWindow - returns a fully instantiated
CalcoolWindow object. Use this function rather than
creating a CalcoolWindow directly.
"""
#look for the ui file that describes the ui
ui_filename = os.path.join(getdatapath(), 'ui', 'CalcoolWindow.ui')
if not os.path.exists(ui_filename):
ui_filename = None
builder = gtk.Builder()
builder.add_from_file(ui_filename)
window = builder.get_object("calcool_window")
window.finish_initializing(builder)
return window
if __name__ == "__main__":
#support for command line options
import logging, optparse
parser = optparse.OptionParser(version="%prog %ver")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="Show debug messages")
(options, args) = parser.parse_args()
#set the logging level to show debug messages
if options.verbose:
logging.basicConfig(level=logging.DEBUG)
logging.debug('logging enabled')
#run the application
window = NewCalcoolWindow()
window.show()
if args:
window.load_file(args[0])
gtk.main()
def save_file(self, widget, data=None):
print "save"