Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/pyqclic_common.py
blob: 56e352bdc0183a08ee4a03f88a77f7a614f63eff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#!/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()