# coding: UTF-8
# Copyright 2009, 2010 Thomas Jourdan
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY 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, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import cairo
import os
import sys
import traceback
import ka_debug
import ka_extensionpoint
_marker = 'v' + str(ka_extensionpoint.revision_number)
_populated = False
_themes = []
_rgb_image_list = []
_alpha_image_list = []
_svg_image_list = []
def _populate_theme_list(import_path):
"""
pre: import_path.startswith('/')
"""
for theme in os.listdir(import_path):
abs_name = os.path.join(import_path, theme)
if os.path.isdir(abs_name):
_themes.append(theme)
_populate_imports(abs_name, theme)
_populate_imports(import_path, '')
def _populate_imports(import_path, theme):
"""
pre: import_path.startswith('/')
"""
for element in os.listdir(import_path):
abs_name = os.path.join(import_path, element)
if os.path.isfile(abs_name):
if element.lower().endswith('.png'):
if element.find('.alpha.') == -1:
_rgb_image_list.append( (theme, abs_name) )
else:
_alpha_image_list.append( (theme, abs_name) )
elif element.lower().endswith('.svg'):
_svg_image_list.append( (theme, abs_name) )
def _populate():
global _populated
if _populated:
return
_populated = True
_populate_theme_list(get_import_path())
def get_import_path():
"""
post: os.path.exists(__return__)
"""
import_path = ka_debug.DEBUG_PROFILE_PATH # default path for debugging
if 'SUGAR_BUNDLE_PATH' in os.environ:
import sugar.env
ka_debug.info('profile_path ' + sugar.env.get_profile_path())
import_path = sugar.env.get_profile_path()
import_path = os.path.join(import_path,
'net.sourceforge.kandid/data/collection')
if not os.path.exists(import_path):
try:
os.makedirs(import_path)
except:
print 'failed writing [%s] [%s] [%s]' % \
(import_path, sys.exc_info()[0], sys.exc_info()[1])
traceback.print_exc(file=sys.__stderr__)
ka_debug.info('import_path ' + import_path)
return import_path
def get_tmp_path():
"""
post: os.path.exists(__return__)
"""
tmp_path = ka_debug.DEBUG_PROFILE_PATH # default path for debugging
if 'SUGAR_BUNDLE_PATH' in os.environ:
import sugar.env
ka_debug.info('profile_path ' + sugar.env.get_profile_path())
tmp_path = sugar.env.get_profile_path()
tmp_path = os.path.join(tmp_path, 'net.sourceforge.kandid/tmp')
ka_debug.info('import_path ' + tmp_path)
return tmp_path
def get_theme_list():
_populate()
return _themes
def get_rgb_image_list(theme):
_populate()
return [x[1] for x in _rgb_image_list if x[0] == theme]
def get_alpha_image_list(theme):
"""
post: forall(__return__, lambda x: x.lower().endswith('.alpha.png'))
"""
_populate()
return [x[1] for x in _alpha_image_list if x[0] == theme]
def get_svg_image_list(theme):
"""
post: forall(__return__, lambda x: x.lower().endswith('.svg'))
"""
_populate()
return [x[1] for x in _svg_image_list if x[0] == theme]
def _make_path(target_path, theme):
"""Create output folder
pre: os.path.exists(target_path)
post: os.path.exists(__return__)
"""
ip = os.path.join(target_path, theme) if len(theme) else target_path
if not os.path.exists(ip):
os.makedirs(ip)
return ip
def _write_file(target_path, theme, file_name, content):
"""Write textual content to the file system.
"""
out_file = None
fn = ''
try:
fn = os.path.join(_make_path(target_path, theme), file_name)
if not os.path.exists(fn):
out_file = open(fn, 'w')
out_file.write(content)
except:
ka_debug.err('failed writing [%s] [%s] [%s]' % \
(fn, sys.exc_info()[0], sys.exc_info()[1]))
traceback.print_exc(file=sys.__stderr__)
finally:
if out_file:
out_file.close()
def _write_surface_file(target_path, theme, file_name, surface):
"""Write graphical content to the file system.
"""
fn = ''
try:
fn = os.path.join(_make_path(target_path, theme), file_name)
if not os.path.exists(fn):
surface.write_to_png(fn)
except:
ka_debug.err('failed writing [%s] [%s] [%s]' % \
(fn, sys.exc_info()[0], sys.exc_info()[1]))
traceback.print_exc(file=sys.__stderr__)
def _create_icon(is_plus_sign):
width, height = 16, 16
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(surface)
ctx.scale(width, height)
# paint background
ctx.set_operator(cairo.OPERATOR_OVER)
ctx.set_source_rgb(1.0, 1.0, 1.0)
ctx.paint()
ctx.set_line_width(0.1)
ctx.set_source_rgb(0.5, 0.5, 0.5)
ctx.move_to(0.0, 0.0)
ctx.line_to(1.0, 0.0)
ctx.line_to(1.0, 1.0)
ctx.line_to(0.0, 1.0)
ctx.line_to(0.0, 0.0)
ctx.stroke()
ctx.set_source_rgb(0.0, 0.0, 0.0)
ctx.move_to(0.2, 0.5)
ctx.line_to(0.8, 0.5)
if is_plus_sign:
ctx.move_to(0.5, 0.2)
ctx.line_to(0.5, 0.8)
ctx.stroke()
return surface
def _post_install():
"""
pre: len(_marker) >= 2 and int(_marker[1]) > 2
"""
try:
tmp_path = get_tmp_path()
import_path = get_import_path()
install_marker = os.path.join(import_path, 'install.inf')
reinstall = not os.path.exists(install_marker)
if not reinstall:
in_file = None
try:
in_file = open(install_marker, 'r')
marker = in_file.read()
reinstall = not marker == _marker
except:
reinstall = True
ka_debug.err('failed reading [%s] [%s] [%s]' % \
(install_marker, sys.exc_info()[0], sys.exc_info()[1]))
traceback.print_exc(file=sys.__stderr__)
finally:
if in_file:
in_file.close()
if not reinstall:
return
ka_debug.info('running post installation [%s]' % import_path)
_write_file(import_path, 'segment_of_a_circle', 'stamp_circle.svg',
'''
'''
)
_write_file(import_path, 'segment_of_a_circle', 'stamp_halfcircle_bottom.svg',
'''
'''
)
_write_file(import_path, 'segment_of_a_circle', 'stamp_halfcircle_left.svg',
'''
'''
)
_write_file(import_path, 'segment_of_a_circle', 'stamp_halfcircle_right.svg',
'''
'''
)
_write_file(import_path, 'segment_of_a_circle', 'stamp_halfcircle_top.svg',
'''
'''
)
#---- cybernetic_serendipity
_write_file(import_path, 'cybernetic_serendipity', 'stamp_ascending_path.svg',
'''
'''
)
_write_file(import_path, 'cybernetic_serendipity', 'stamp_circle_path.svg',
'''
'''
)
_write_file(import_path, 'cybernetic_serendipity', 'stamp_descending_path.svg',
'''
'''
)
_write_file(import_path, 'cybernetic_serendipity', 'stamp_horizontal_path.svg',
'''
'''
)
_write_file(import_path, 'cybernetic_serendipity', 'stamp_sawtooth_path.svg',
'''
'''
)
_write_file(import_path, 'cybernetic_serendipity', 'stamp_square_path.svg',
'''
'''
)
_write_file(import_path, 'cybernetic_serendipity', 'stamp_vertical_path.svg',
'''
'''
)
#---- marktree
_write_file(tmp_path, '', 'marktree.js',
'''
/* MarkTree JavaScript code
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Miika Nurminen, 12.7.2004.
*/
/* cross-browser (tested with ie5, mozilla 1 and opera 5) keypress detection */
function get_keycode(evt) {
// IE
code = document.layers ? evt.which
: document.all ? event.keyCode // event.keyCode!=evt.keyCode!
: evt.keyCode;
if (code==0)
code=evt.which; // for NS
return code;
}
var lastnode=null;
var listnodes = null;
var list_index=1;
var lastnodetype=''; // determines if node is a link, input or text;
// up, left, down, right, keypress codes
//ijkl
//var keys = new Array(105,106,107,108);
//num arrows
//var keys = new Array(56,52,50,54);
//wasd
// var press2 = new Array(119,97,115,100);
var press = new Array(47,45,42,43);
// keydown codes
// var keys2=new Array(87,65,83,68);
var keys= new Array(38,37,40,39);
// keyset 1 = keydown, otherwise press
function checkup(keyset,n) {
if (keyset==1) return (n==keys[0]);
return ((n==press[0]) /*|| (n==press2[0])*/)
}
function checkdn(keyset,n) {
if (keyset==1) return (n==keys[2]);
return ((n==press[2]) /*|| (n==press2[2])*/)
}
function checkl(keyset,n) {
if (keyset==1) return (n==keys[1]);
return ((n==press[1]) /*|| (n==press2[1])*/)
}
function checkr(keyset,n) {
if (keyset==1) return (n==keys[3]);
return ((n==press[3]) /*|| (n==press2[3])*/)
}
function is_exp(n) {
if (n==null) return false;
return ((n.className=='exp') || (n.className=='exp_active'));
}
function is_col(n) {
if (n==null) return false;
return ((n.className=='col') || (n.className=='col_active'));
}
function is_basic(n) {
if (n==null) return false;
return ((n.className=='basic') || (n.className=='basic_active'));
}
/* returns i>=0 if true */
function is_active(node) {
if (node.className==null) return false
return node.className.indexOf('_active');
}
function toggle_class(node) {
if ((node==null) || (node.className==null)) return;
str=node.className;
result="";
i = str.indexOf('_active');
if (i>0)
result= str.substr(0,i);
else
result= str+"_active";
node.className=result;
return node;
}
function activate(node) {
node.style.backgroundColor='#eeeeff';
}
function deactivate(node) {
node.style.backgroundColor='#ffffff';
}
function is_list_node(n) {
if (n==null) return false;
if (n.className==null) return false;
if ( (is_exp(n)) ||
(is_col(n)) ||
(is_basic(n)) )
return true; else return false;
}
function get_href(n) {
alist=n.attributes;
if (alist!=null) {
hr = alist.getNamedItem('href');
if (hr!=null) return hr.nodeValue;
}
if (n.childNodes.length==0) return '';
for (var i=0; i=0)
toggle_class(lastnode);
lastnode=n;
if (!(is_active(lastnode)>=0))
toggle_class(lastnode);
/*var d2 = new Date();
var t_mil2 = d2.getMilliseconds();
window.alert(t_mil2-t_mil);*/
}
function next_list_node() {
tempIndex = list_index;
while (tempIndex0) {
tempIndex--;
var x = listnodes[tempIndex];
if (is_list_node(x)) {
list_index=tempIndex;
return;
}
}
}
function getsub (li) {
if (li.childNodes.length==0) return null;
for (var c = 0; c < li.childNodes.length; c++)
if ( (li.childNodes[c].className == 'sub') || (li.childNodes[c].className == 'subexp') )
return li.childNodes[c];
}
function find_listnode_recursive (li) {
if (is_list_node(li)) return li;
if (li.childNodes.length==0) return null;
result=null;
for (var c = 0; c < li.childNodes.length; c++) {
result=find_listnode_recursive(li.childNodes[c]);
if (result!=null) return result;
}
return null;
}
function next_child_listnode(li) {
var result=null;
for (var i=0; i