diff options
Diffstat (limited to 'pyqclic_common.py')
-rw-r--r-- | pyqclic_common.py | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/pyqclic_common.py b/pyqclic_common.py new file mode 100644 index 0000000..fb2eb3c --- /dev/null +++ b/pyqclic_common.py @@ -0,0 +1,209 @@ +#!/usr/bin/python + +# PyClicAdmin application, Administration interface. User loads an image, then places lables on them with circled +# numbers in colour of their choice (application has colour changing ability), then user writes meanings of labels on +# right hand side, and stores all this in an XML file. XML file contains tags as listed in pylic-common.py file, +# along with base 64 encoded image. This is for transportability reasons, specifically, transporting across xmpp +# tubes for collaboration. Application uses cairo and pango libraries for drawing and labeling image. It uses the +# minidom library for xml importing/exporting. +# +# This is the pycliccommon libary which was made in order modularize things a bit, though because was created only +# with hindsight and no planning, it doesnt exactly fit like a glove. Some elements should be common to pyclic-user though + +import pygtk +pygtk.require('2.0') +import gtk +import cairo +import math +from xml.dom import minidom +import os +import sys +import locale +from gettext import gettext as _ + +APP_NAME = "pyqclic" + +# Create XML dictionary, for xml_tags below + +MAIN_TAG = 0 +QUIZ_TAG = 1 +CATEGORY_TAG = 2 +TITLE_TAG = 3 +COLOR_TAG = 4 +IMAGE_TAG = 5 +AUTHOR_TAG = 6 +QUESTIONS_TAG = 7 +QUESTION_TAG = 8 +COORDINATES_TAG = 9 +ENTRY_TAG = 10 + +# set extension file to be used for opening and saving quiz files/projects. Currently uses gpx, as that seams unused. +FILE_EXT = "gpx" + + +class PyQClicCommon: + + + _xml_tags = { + MAIN_TAG : "PyClicCommon" + , QUIZ_TAG: "Quiz" + , CATEGORY_TAG : "Category" + , TITLE_TAG: "Title" + , IMAGE_TAG : "Image" + , AUTHOR_TAG : "Author" + , COLOR_TAG : "Colour" + , QUESTIONS_TAG : "Questions" + , QUESTION_TAG : "Question" + , COORDINATES_TAG : "Coordinates" + , ENTRY_TAG : "Answer" + } + + # when invoked (via signal delete_event), terminates the application. + def close_application(self, widget, event, data=None): + gtk.main_quit() + return False + + def file_browse(self, dialog_action, file_name=""): + """This function is used to browse for a pyClic file. + It can be either a save or open dialog depending on + what dialog_action is. + The path to the file will be returned if the user + selects one, however a blank string will be returned + if they cancel or do not select one. + dialog_action - The open or save mode for the dialog either + gtk.FILE_CHOOSER_ACTION_OPEN, gtk.FILE_CHOOSER_ACTION_SAVE + file_name - Default name when doing a save""" + + if (dialog_action==gtk.FILE_CHOOSER_ACTION_OPEN): + dialog_buttons = (gtk.STOCK_CANCEL + , gtk.RESPONSE_CANCEL + , gtk.STOCK_OPEN + , gtk.RESPONSE_OK) + else: + dialog_buttons = (gtk.STOCK_CANCEL + , gtk.RESPONSE_CANCEL + , gtk.STOCK_SAVE + , gtk.RESPONSE_OK) + + file_dialog = gtk.FileChooserDialog(title=_("Select PyQClic Project") + , action=dialog_action + , buttons=dialog_buttons) + """set the filename if we are saving""" + if (dialog_action==gtk.FILE_CHOOSER_ACTION_SAVE): + file_dialog.set_current_name(file_name) + """Create and add the pyclic filter""" + filter = gtk.FileFilter() + filter.set_name("PyQClic File") + filter.add_pattern("*." + FILE_EXT) + file_dialog.add_filter(filter) + """Create and add the 'all files' filter""" + filter = gtk.FileFilter() + filter.set_name(_("All files")) + filter.add_pattern("*") + file_dialog.add_filter(filter) + + """Init the return value""" + result = "" + if file_dialog.run() == gtk.RESPONSE_OK: + result = file_dialog.get_filename() + file_dialog.destroy() + + return result + + def set_window_title_from_file(self,xml_file,window): + """Set the windows title, take it from xml_file. + @param xml_file - string - The xml file name that we will + base the window title off of + """ + if (xml_file): + window.set_title("PyQClic - %s" + % (os.path.basename(xml_file))) + else: + window.set_title(_("PyQClic - Untitled")) + + def decode64(self,data): + filew = open('/tmp/pyqclic_decode.png','w') + filew.write(data.decode('base64')) + filew.close() + image = cairo.ImageSurface.create_from_png("/tmp/pyqclic_decode.png") + return image + + def grab_click(self,widget,event): + x, y = event.get_coords() + self.coordinates.append((x,y)) + gc = widget.window.new_gc() + widget.queue_draw() + + self.label=gtk.Label(self.coordinates.index((x,y))+1) + self.label_list.append(self.label) + self.vbox2.pack_start(self.label,False,False,0) + self.label.show() + + self.entry=gtk.Entry(max=30) + self.entry_list.append(self.entry) + + self.vbox2.pack_start(self.entry,False,False,0) + + self.entry.show() + + def expose(self, widget, event): + + cr = widget.window.cairo_create() + cr.set_source_surface(self.image) + cr.paint() + cr.select_font_face("Arial",cairo.FONT_SLANT_NORMAL,cairo.FONT_WEIGHT_BOLD) + cr.set_font_size(16) + + for x,y in self.coordinates: + + + cr.set_source_rgb(self.colorred,self.colorgreen,self.colorblue) + cr.arc(x,y,14,0,2 * math.pi) + cr.stroke + cr.fill() + + self.string="%s" %(self.coordinates.index((x,y))+1) + cr.move_to(x-4,y+5) + cr.set_source_rgb(1, 1, 1) + + cr.show_text(self.string) + + + def about_program(self,widget): + about = gtk.AboutDialog() + about.set_program_name("PyQClic") + about.set_version("0.2") + about.set_copyright("(c) David Van Assche / ") + about.set_comments(_("PyClic is a tool similar to Jclic but written in python and containing collaboration")) + about.set_website("http://git.sugarlabs.org/projects/pyclic") + about.set_logo(gtk.gdk.pixbuf_new_from_file("aboutpyclic.png")) + about.run() + about.destroy() + + def on_file_new(self,widget): + for entry in self.entry_list: + self.vbox2.remove(entry) + for label in self.label_list: + self.vbox2.remove(label) + self.entry_list=[] + self.Entries=[] + self.coordinates=[] + self.author_entry.set_text("") + self.title_entry.set_text("") + self.question_list=[] + self.xml_file = None + self.entry="" + self.window.queue_draw() + + + def show_error_dlg(self, error_string): + """This Function is used to show an error dialog when + an error occurs. + error_string - The error string that will be displayed + on the dialog. + """ + error_dlg = gtk.MessageDialog(type=gtk.MESSAGE_ERROR + , message_format=error_string + , buttons=gtk.BUTTONS_OK) + error_dlg.run() + error_dlg.destroy() |