Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Van Assche <nubae@big-nubae.local.lan>2009-09-02 18:10:45 (GMT)
committer David Van Assche <nubae@big-nubae.local.lan>2009-09-02 18:10:45 (GMT)
commit0f7db16a8c64df3fb2e98414d7a64f39ad605c6c (patch)
tree69ba0b8c3f0285b46a2f0053ffd4c66c75f850f0
updating
-rw-r--r--__init__.py0
-rw-r--r--aboutpyclic.pngbin0 -> 15497 bytes
-rw-r--r--pyclic.pngbin0 -> 242713 bytes
-rw-r--r--pyclic.py675
-rw-r--r--pyclic_common.py193
-rw-r--r--pyclicicon.pngbin0 -> 119696 bytes
6 files changed, 868 insertions, 0 deletions
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/__init__.py
diff --git a/aboutpyclic.png b/aboutpyclic.png
new file mode 100644
index 0000000..5bf8d97
--- /dev/null
+++ b/aboutpyclic.png
Binary files differ
diff --git a/pyclic.png b/pyclic.png
new file mode 100644
index 0000000..8f29b2c
--- /dev/null
+++ b/pyclic.png
Binary files differ
diff --git a/pyclic.py b/pyclic.py
new file mode 100644
index 0000000..d49e3d3
--- /dev/null
+++ b/pyclic.py
@@ -0,0 +1,675 @@
+#!/usr/bin/env python
+
+# PyClicAdmin application, Administration interface
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import cairo
+import math
+from xml.dom import minidom
+import os
+import sys
+from pyclic_common import PyClicCommon
+
+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
+
+FILE_EXT = "pcx"
+
+class PyClicAdmin:
+
+ def on_file_open(self, widget):
+
+ xml_file = self.pcc.file_browse(gtk.FILE_CHOOSER_ACTION_OPEN)
+ #If we have a xml_file
+ if (xml_file):
+ if (self.xml_load_from_file(xml_file)):
+ """Allright it all worked! save the current file and
+ set the title."""
+ self.xml_file = xml_file
+ self.pcc.set_window_title_from_file(self.xml_file,self.window)
+
+
+ def xml_load_from_file(self, xml_file):
+ """Load a quiz from an xml file
+ @param xml_file - string - path to file that
+ we will load.
+ @returns boolean - True success. False failure
+ """
+ #Init return value
+ success = False
+
+ #Load the xml_file to a document
+ try:
+ xml_document = minidom.parse(xml_file)
+ if (xml_document):
+ success = ((self.xml_load(xml_document)))
+ except IOError, (errno, strerror):
+ self.show_error_dlg(
+ "Error loading quiz file(%s): %s" % (errno, strerror))
+ return success
+
+ def xml_load(self, xml_document):
+ """Load the current quiz from an xml document.
+ @param xml_document - xml.dom.minidom.Document object -
+ The xml document that we will load the quiz from.
+ @returns boolean True - success. False - Failure."""
+
+ title_loaded = False
+ category_loaded = False
+ question_loaded = False
+ author_loaded = False
+ image_loaded = False
+ coordinates_loaded = False
+ entries_loaded = False
+ questions_loaded = False
+ colors_loaded = False
+ # reset all values before loading document
+ self.on_file_new(self)
+ #Loop through all child nodes of the root.
+ for node in xml_document.documentElement.childNodes:
+ #We are looking for the quiz Node
+ if (node.nodeName == PyClicCommon._xml_tags[QUIZ_TAG]):
+ # Now loop through the quiz nodes children
+ for item_node in node.childNodes:
+ if (item_node.nodeName == PyClicCommon._xml_tags[TITLE_TAG]):
+ """Set the title, the firstChild in this case is
+ the actual title text that we saved."""
+
+ #Make sure it's not a blank string
+ if (item_node.firstChild):
+ self.title_entry.set_text(item_node.firstChild.nodeValue)
+ else:
+ print "nasti"
+ title_loaded = True
+ elif (item_node.nodeName == PyClicCommon._xml_tags[CATEGORY_TAG]):
+ """Set the category, the firstChild in this case is
+ the actual category that we saved."""
+ #Make sure it's not a blank string
+ if (item_node.firstChild):
+ if item_node.firstChild.nodeValue=="Geography":
+ catindex=0
+ elif item_node.firstChild.nodeValue=="Science":
+ catindex=1
+ elif item_node.firstChild.nodeValue=="ICT":
+ catindex=2
+ elif item_node.firstChild.nodeValue=="Languages":
+ catindex=3
+ elif item_node.firstChild.nodeValue=="Maths":
+ catindex=4
+ elif item_node.firstChild.nodeValue=="Music":
+ catindex=5
+ elif item_node.firstChild.nodeValue=="History":
+ catindex=6
+ elif item_node.firstChild.nodeValue=="Business":
+ catindex=7
+ elif item_node.firstChild.nodeValue=="Art":
+ catindex=8
+ self.cb_category.set_active(catindex)
+ else:
+ print "nasti"
+ category_loaded = True
+ elif (item_node.nodeName == PyClicCommon._xml_tags[AUTHOR_TAG]):
+ """Set the author, the firstChild in this case is
+ the actual author that we saved."""
+ #Make sure it's not a blank string
+ if (item_node.firstChild):
+ self.author_entry.set_text(item_node.firstChild.nodeValue)
+ else:
+ print "nasti"
+ author_loaded = True
+ #Break out of the topmost for loop
+ elif (item_node.nodeName == PyClicCommon._xml_tags[IMAGE_TAG]):
+ """Set the image, the firstChild in this case is
+ the image that we saved. Then decode from base64"""
+ #Make sure it's not a blank string
+ if (item_node.firstChild):
+ self.image = self.pcc.decode64(item_node.firstChild.nodeValue)
+ self.window.queue_draw()
+ else:
+ print "nasti"
+ image_loaded = True
+ #Break out of the topmost for loop
+ elif (item_node.nodeName == PyClicCommon._xml_tags[COLOR_TAG]):
+ """Set the image, the firstChild in this case is
+ the image that we saved. Then decode from base64"""
+ #Make sure it's not a blank string
+ if (item_node.firstChild):
+ self.colourred,self.colourgreen,self.colourblue = item_node.firstChild.nodeValue.split(",")
+ self.colorred=self.colourred.replace('[', '')
+ self.colorred=float(self.colorred)
+ self.colorgreen=float(self.colourgreen)
+ self.colorblue=self.colourblue.replace(']', '')
+ self.colorblue=float(self.colorblue)
+ self.window.queue_draw()
+ else:
+ print "nasti"
+ colors_loaded = True
+ #Break out of the topmost for loop
+ #We are looking for the quiz Node
+ elif (node.nodeName == PyClicCommon._xml_tags[QUESTIONS_TAG]):
+ # Now loop through the question nodes children
+ for item_node in node.childNodes:
+ self.questions_list=[]
+ if (item_node.nodeName == PyClicCommon._xml_tags[QUESTION_TAG]):
+ """Grab all the questions."""
+
+ #Make sure it's not a blank string
+ if (item_node.firstChild):
+ self.questions_list.append(item_node.firstChild.nodeValue)
+ for question in self.questions_list:
+ self.label=gtk.Label(question)
+ self.label_list.append(self.label)
+ self.vbox2.pack_start(self.label,False,False,0)
+ self.label.show()
+ else:
+ print "nasti"
+ question_loaded = True
+ self.coordinate=[]
+ if (item_node.nodeName == PyClicCommon._xml_tags[COORDINATES_TAG]):
+ """Grab all the coordinates."""
+
+ #Make sure it's not a blank string
+ if (item_node.firstChild):
+ self.coordinate.append(item_node.firstChild.nodeValue)
+ for coordinate in self.coordinate:
+ x,y = coordinate.split(",")
+ self.coordinates.append((float(x),float(y)))
+ self.window.queue_draw()
+
+
+ else:
+ print "nasti"
+ coordinates_loaded = True
+ self.entradas=[]
+ if (item_node.nodeName == PyClicCommon._xml_tags[ENTRY_TAG]):
+ """Grab all the entries."""
+
+ #Make sure it's not a blank string
+ if (item_node.firstChild):
+ self.entradas.append(item_node.firstChild.nodeValue)
+ for entry in self.entradas:
+ self.entry=gtk.Entry(max=30)
+ self.entry_list.append(self.entry)
+ self.entry.set_text(item_node.firstChild.nodeValue)
+ self.vbox2.pack_start(self.entry,False,False,0)
+ self.entry.show()
+ else:
+ print "nasti"
+ entries_loaded = True
+ break
+ return (title_loaded and category_loaded and author_loaded and image_loaded and entries_loaded and question_loaded and colors_loaded and coordinates_loaded)
+
+
+
+ def xml_save(self, xml_document):
+ """Save the current quiz to an xml document.
+ @param xml_document - xml.dom.minidom.Document object -
+ The xml document that we will save the post to."""
+
+ #create <quiz></quiz>
+ quiz_element = xml_document.createElement(PyClicCommon._xml_tags[QUIZ_TAG])
+ #create <category></category>
+ category_element = xml_document.createElement(PyClicCommon._xml_tags[CATEGORY_TAG])
+ #Create <category>category</category>
+ category_element.appendChild(xml_document.createTextNode(self.Category))
+ #Creates <image></image>
+ image_element = xml_document.createElement(PyClicCommon._xml_tags[IMAGE_TAG])
+ #Create <IMAGE>image<IMAGE>
+ image_element.appendChild(xml_document.createTextNode(self.Image))
+ #Creates <title></title>
+ title_element = xml_document.createElement(PyClicCommon._xml_tags[TITLE_TAG])
+ #Creates <title>title</title>
+ title_element.appendChild(xml_document.createTextNode(self.Title))
+ #Creates <author></author>
+ author_element = xml_document.createElement(PyClicCommon._xml_tags[AUTHOR_TAG])
+ #Creates <author>author</author>
+ author_element.appendChild(xml_document.createTextNode(self.Author))
+ #Creates <color></color>
+ color_element = xml_document.createElement(PyClicCommon._xml_tags[COLOR_TAG])
+ #turn color into list
+ colourvalues = []
+ colourvalues.append(self.colorred)
+ colourvalues.append(self.colorgreen)
+ colourvalues.append(self.colorblue)
+ #Creates <color>author</color>
+ color_element.appendChild(xml_document.createTextNode(str(colourvalues)))
+ quiz_element.appendChild(category_element)
+ quiz_element.appendChild(title_element)
+ quiz_element.appendChild(image_element)
+ quiz_element.appendChild(author_element)
+ quiz_element.appendChild(color_element)
+ #Now add to the xml document
+ xml_document.documentElement.appendChild(quiz_element)
+ #create <questions></questions>
+ questions_element = xml_document.createElement(PyClicCommon._xml_tags[QUESTIONS_TAG])
+ Iterate = 0
+ question = 1
+ while Iterate < len(self.coordinates):
+ #Create <question></question>
+ question_element = xml_document.createElement(PyClicCommon._xml_tags[QUESTION_TAG])
+ #create <question>question<question>
+ question_element.appendChild(xml_document.createTextNode(str(question)))
+ c = self.coordinates[Iterate]
+ #Create <coordinates></coordinates>
+ coordinates_element = xml_document.createElement(PyClicCommon._xml_tags[COORDINATES_TAG])
+ #create <coordinates>x,y<coordinates>
+ coordinates_element.appendChild(xml_document.createTextNode("%d,%d" % (c[0],c[1])))
+ #Create <entry></entry>
+ entry_element = xml_document.createElement(PyClicCommon._xml_tags[ENTRY_TAG])
+ #create <entry>entry<entry>
+ entry_element.appendChild(xml_document.createTextNode(self.Entries[Iterate]))
+
+ #Add above to <questions>
+ questions_element.appendChild(question_element)
+ questions_element.appendChild(coordinates_element)
+ questions_element.appendChild(entry_element)
+ Iterate=Iterate+1
+ question=question+1
+ #Now add to the xml document
+ xml_document.documentElement.appendChild(questions_element)
+
+ def xml_save_to_file(self, widget):
+ """Save the current post to xml_file
+ @param xml_file - string - path to file that
+ we will save the xml to.
+ @returns boolean - True success. False failure
+ """
+ #Init return value
+ success = False
+
+ #Get the available DOM Implementation
+ impl = minidom.getDOMImplementation()
+ #Create the document, with PyClicAdmin as to base node
+ xml_document = impl.createDocument(None, PyClicCommon._xml_tags[MAIN_TAG], None)
+ #Save the questions into the xml
+ self.xml_save(xml_document)
+ #Now actually try to save the file
+ try:
+ save_file = open(self.xml_file, 'w')
+ #write the xml document to disc
+ xml_document.documentElement.writexml(save_file)
+ save_file.close()
+ except IOError, (errno, strerror):
+ self.show_error_dlg(
+ "Error saving quiz(%s): %s" % (errno, strerror))
+ else:
+ #Allright it all worked! Set the return value
+ success = True
+
+ return success
+
+
+ # open image file self.chooser with filter for just image types
+ def open_image(self,widget):
+ self.chooser = gtk.FileChooserDialog(title="Open Image",action=gtk.FILE_CHOOSER_ACTION_OPEN,buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
+ filter = gtk.FileFilter()
+ filter.set_name("Images")
+ filter.add_mime_type("image/png")
+ filter.add_pattern("*.png")
+ self.chooser.add_filter(filter)
+
+ response = self.chooser.run()
+ if response == gtk.RESPONSE_OK:
+ self.image=self.image.create_from_png(self.chooser.get_filename())
+ self.image_scale(self.image)
+ self.image_filename=self.chooser.get_filename()
+ self.image=self.image.create_from_png(self.chooser.get_filename())
+ self.darea.queue_draw()
+ elif response == gtk.RESPONSE_CANCEL:
+ print 'Closed, no files selected'
+ self.chooser.destroy()
+
+ def image_scale(self,image):
+ self.width=self.image.get_width()
+ self.height=self.image.get_height()
+ imgpat = cairo.SurfacePattern(self.image)
+
+ scaler = cairo.Matrix()
+ #image width/640*100,image height/480
+ scaler.scale(self.width/640.0,self.height/480.0)
+ imgpat.set_matrix(scaler)
+
+ #set resampling filter
+ imgpat.set_filter(cairo.FILTER_BEST)
+ canvas = cairo.ImageSurface(cairo.FORMAT_ARGB32,640,480)
+ ctx = cairo.Context(canvas)
+ ctx.set_source(imgpat)
+ ctx.paint()
+ canvas.write_to_png(self.chooser.get_filename())
+
+
+ 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):
+
+ self.cr = widget.window.cairo_create()
+ self.cr.set_source_surface(self.image)
+ self.cr.paint()
+ self.cr.select_font_face("Arial",cairo.FONT_SLANT_NORMAL,cairo.FONT_WEIGHT_BOLD)
+ self.cr.set_font_size(16)
+
+ for x,y in self.coordinates:
+
+
+ self.cr.set_source_rgb(self.colorred,self.colorgreen,self.colorblue)
+ self.cr.arc(x,y,14,0,2 * math.pi)
+ self.cr.stroke
+ self.cr.fill()
+
+ self.string="%s" %(self.coordinates.index((x,y))+1)
+ self.cr.move_to(x-4,y+5)
+ self.cr.set_source_rgb(1, 1, 1)
+
+ self.cr.show_text(self.string)
+
+
+ def get_active_text(combobox):
+ model = combobox.get_model()
+ active = combobox.get_active()
+ if active < 0:
+ return None
+ return model[active][0]
+
+ def encode64(self,filew):
+ try:
+ response = open(filew)
+ data = response.read()
+
+ except IOError, (errno, strerror):
+ self.show_error_dlg("Error saving quiz(%s): %s" % (errno, strerror))
+
+ return data.encode('base64')
+
+ def on_file_save(self, widget):
+ """This function saves the current Quiz as an XML file using sub functions"""
+ # Let the user browse for the save location and name
+ if (self.xml_file == None):
+ self.xml_file = self.pcc.file_browse(gtk.FILE_CHOOSER_ACTION_SAVE)
+ #If we have a xml_file
+ if (self.xml_file):
+ if (self.xml_save_to_file(self.xml_file)):
+ #Allright it all worked! Set the Title
+ self.pcc.set_window_title_from_file(self.xml_file,self.window)
+
+ def on_file_save_as(self, widget):
+ """Let the user save the current file to a new location."""
+
+ xml_file = "Untitled"
+ if (self.xml_file != None):
+ xml_file = os.path.basename(self.xml_file)
+
+ xml_file = self.file_browse(gtk.FILE_CHOOSER_ACTION_SAVE, xml_file)
+ #If we have a xml_file
+ if (xml_file):
+ if (self.xml_save_to_file(xml_file)):
+ """Allright it all worked! save the current file and
+ set the title."""
+ self.xml_file = xml_file
+ PyClicCommon.set_window_title_from_file(self.xml_file)
+
+ def on_changed(self,widget):
+ self.Category = widget.get_active_text()
+
+ def save_details(self,widget):
+ self.Title = self.title_entry.get_text()
+ self.Author = self.author_entry.get_text()
+ # save image to base64
+ self.Image = self.encode64(self.image_filename)
+ # function to grab entries from entry list
+ self.Entries=[]
+ for entry in self.entry_list:
+ self.Entries.append(entry.get_text())
+
+ self.on_file_save(file)
+
+ 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 on_clicked(self, widget):
+ cdia = gtk.ColorSelectionDialog("Select color")
+ response = cdia.run()
+
+ if response == gtk.RESPONSE_OK:
+ colorsel = cdia.colorsel
+ self.colour = colorsel.get_current_color()
+ self.colorred = self.colour.red/65535.0
+ self.colorgreen = self.colour.green/65535.0
+ self.colorblue = self.colour.blue/65535.0
+
+ cdia.destroy()
+ self.window.queue_draw()
+
+ def __init__(self):
+ # create the main window, and attach delete_event signal to terminating
+ # the application
+ self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+
+ #set icon for app
+ try:
+ self.window.set_icon_from_file("pyclicicon.png")
+ except Exception, e:
+ print e.message
+ sys.exit(1)
+
+ self.pcc=PyClicCommon()
+
+ self.window.connect("delete_event", self.pcc.close_application)
+ self.window.set_size_request(775,544)
+ self.window.set_border_width(0)
+
+ self.vbox2 = gtk.VBox(False, 2)
+
+
+ self.xml_file=None
+
+
+ #Insert menubar containing 2 columns
+ mb = gtk.MenuBar()
+ filemenu = gtk.Menu()
+
+ filem = gtk.MenuItem("File")
+ filem.set_submenu(filemenu)
+
+ aboutm = gtk.MenuItem("About PyClicAdmin")
+ aboutm.connect("activate",self.pcc.about_program)
+ filemenu.append(aboutm)
+
+ newquiz = gtk.MenuItem("New File / Clear")
+ newquiz.connect("activate",self.on_file_new)
+ filemenu.append(newquiz)
+
+
+ openquiz = gtk.MenuItem("Open Quiz")
+ openquiz.connect("activate",self.on_file_open,self.xml_file)
+ filemenu.append(openquiz)
+
+ save = gtk.MenuItem("Save Quiz")
+ save.connect("activate",self.save_details,self.xml_file)
+ filemenu.append(save)
+
+ exit = gtk.MenuItem("Exit")
+ exit.connect("activate",gtk.main_quit)
+ filemenu.append(exit)
+
+ viewmenu = gtk.Menu()
+ view = gtk.MenuItem("Options")
+ view.set_submenu(viewmenu)
+
+ open = gtk.MenuItem("Open Image")
+ open.connect("activate",self.open_image)
+ viewmenu.append(open)
+
+ stat = gtk.MenuItem("Change Color")
+ stat.connect("activate", self.on_clicked)
+ viewmenu.append(stat)
+
+ mb.append(filem)
+ mb.append(view)
+ self.hbox = gtk.HBox(False, 2)
+
+
+ #define and start vertical area
+ vbox = gtk.VBox(False, 2)
+ vbox.pack_start(mb,False,False,0)
+
+ #Insert Toolbar with open,save and exit
+ toolbar = gtk.Toolbar()
+ toolbar.set_style(gtk.TOOLBAR_ICONS)
+
+ newtb = gtk.ToolButton(gtk.STOCK_CLEAR)
+ opentb = gtk.ToolButton(gtk.STOCK_OPEN)
+ savetb = gtk.ToolButton(gtk.STOCK_SAVE)
+ colortb = gtk.ToolButton(gtk.STOCK_SELECT_COLOR)
+ importtb = gtk.ToolButton(gtk.STOCK_ORIENTATION_PORTRAIT)
+ sep = gtk.SeparatorToolItem()
+ quittb = gtk.ToolButton(gtk.STOCK_QUIT)
+
+ toolbar.insert(newtb, 0)
+ toolbar.insert(opentb, 1)
+ toolbar.insert(savetb, 2)
+ toolbar.insert(colortb,3)
+ toolbar.insert(importtb,4)
+ toolbar.insert(sep, 5)
+ toolbar.insert(quittb, 6)
+
+ quittb.connect("clicked", gtk.main_quit)
+ newtb.connect("clicked", self.on_file_new)
+ opentb.connect("clicked", self.on_file_open)
+ savetb.connect("clicked", self.save_details)
+ colortb.connect("clicked", self.on_clicked)
+ importtb.connect("clicked",self.open_image)
+
+ vbox.pack_start(toolbar, False, False, 0)
+
+
+ # A drawing area inside a fixed()
+
+ fix = gtk.Fixed()
+ self.darea=gtk.DrawingArea()
+ self.image = cairo.ImageSurface.create_from_png("pyclic.png")
+ self.image_filename="pyclic.png"
+ self.darea.connect("expose_event", self.expose)
+ self.darea.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.darea.connect("button_press_event",self.grab_click)
+
+ self.darea.set_size_request(606,540)
+ fix.put(self.darea,0,0)
+
+ #define coordinates list
+ self.coordinates=[]
+
+ #define text entries list
+ self.entry_list=[]
+
+ self.label_list=[]
+
+ self.question_list=[]
+
+ #define color values for question circle
+ self.colorred=0
+ self.colorblue=0
+ self.colorgreen=0
+
+ # Layout
+ self.window.add(vbox)
+ vbox.add(self.hbox)
+ self.hbox.add(fix)
+
+ # Title and category entry boxes
+ title_label=gtk.Label("Title")
+ self.vbox2.pack_start(title_label,False,False,0)
+
+ self.title_entry=gtk.Entry(max=50)
+ self.vbox2.pack_start(self.title_entry,False,False,0)
+
+ author_label=gtk.Label("Author")
+ self.vbox2.pack_start(author_label,False,False,0)
+
+ self.author_entry=gtk.Entry(max=50)
+ self.vbox2.pack_start(self.author_entry,False,False,0)
+
+
+ title_category=gtk.Label("Category")
+ self.vbox2.pack_start(title_category,False,False,0)
+
+ self.cb_category=gtk.combo_box_new_text()
+ self.cb_category.connect("changed", self.on_changed)
+ self.cb_category.append_text("Geography")
+ self.cb_category.append_text("Science")
+ self.cb_category.append_text("ICT")
+ self.cb_category.append_text("Languages")
+ self.cb_category.append_text("Maths")
+ self.cb_category.append_text("Music")
+ self.cb_category.append_text("History")
+ self.cb_category.append_text("Business")
+ self.cb_category.append_text("Art")
+ self.vbox2.pack_start(self.cb_category,False,False,0)
+
+
+ #submit button for entries
+ submit_button=gtk.Button("Submit")
+ self.vbox2.pack_start(submit_button,False,False,0)
+ submit_button.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ submit_button.connect("clicked",self.save_details)
+
+ clear_button=gtk.Button("Clear")
+ self.vbox2.pack_start(clear_button,False,False,0)
+ clear_button.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ clear_button.connect("clicked",self.on_file_new)
+
+ self.scrollw = gtk.ScrolledWindow()
+ self.scrollw.set_policy(gtk.POLICY_NEVER,gtk.POLICY_AUTOMATIC)
+ self.hbox.pack_start(self.scrollw)
+ self.scrollw.add_with_viewport(self.vbox2)
+
+# self.hbox.add(self.vbox2)
+
+ self.window.show_all()
+
+def main():
+ gtk.main()
+ return 0
+
+if __name__ == "__main__":
+ PyClicAdmin()
+ main()
+
diff --git a/pyclic_common.py b/pyclic_common.py
new file mode 100644
index 0000000..1df9996
--- /dev/null
+++ b/pyclic_common.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python
+
+# PyClicCommon application, Administration interface
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import cairo
+import math
+from xml.dom import minidom
+import os
+import sys
+
+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
+
+FILE_EXT = "pcx"
+
+
+class PyClicCommon:
+
+ # when invoked (via signal delete_event), terminates the application.
+ def close_application(self, widget, event, data=None):
+ gtk.main_quit()
+ return False
+
+ _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"
+ }
+
+ 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 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("PyClicCommon 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("PyClic - %s"
+ % (os.path.basename(xml_file)))
+ else:
+ window.set_title("PyClic - Untitled")
+
+ def decode64(self,data):
+ filew = open('/tmp/ruris.png','w')
+ filew.write(data.decode('base64'))
+ filew.close()
+ image = cairo.ImageSurface.create_from_png("/tmp/ruris.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("PyClic")
+ about.set_version("0.1")
+ 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://www.PyClic.com")
+ 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()
diff --git a/pyclicicon.png b/pyclicicon.png
new file mode 100644
index 0000000..e0a2251
--- /dev/null
+++ b/pyclicicon.png
Binary files differ