Merge lp:~graeme-acm/sahana-eden/RMS into lp:sahana-eden
- RMS
- Merge into trunk
Proposed by
Graeme Foster
Status: | Merged |
---|---|
Merged at revision: | 2954 |
Proposed branch: | lp:~graeme-acm/sahana-eden/RMS |
Merge into: | lp:sahana-eden |
Diff against target: |
589 lines (+233/-43) 3 files modified
controllers/survey.py (+101/-30) models/survey.py (+100/-5) modules/s3/s3survey.py (+32/-8) |
To merge this branch: | bzr merge lp:~graeme-acm/sahana-eden/RMS |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Fran Boon | Pending | ||
Review via email: mp+83409@code.launchpad.net |
Commit message
Description of the change
Finishing off the spreadsheet translation
ticket #1042
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'controllers/survey.py' |
2 | --- controllers/survey.py 2011-11-23 10:48:23 +0000 |
3 | +++ controllers/survey.py 2011-11-25 15:29:24 +0000 |
4 | @@ -28,13 +28,15 @@ |
5 | |
6 | from gluon.contenttype import contenttype |
7 | from gluon.serializers import json |
8 | +from gluon.languages import read_dict, write_dict |
9 | |
10 | from s3survey import S3AnalysisPriority, \ |
11 | survey_question_type, \ |
12 | survey_analysis_type, \ |
13 | S3Chart, \ |
14 | DataMatrix, MatrixElement, \ |
15 | - S3QuestionTypeOptionWidget |
16 | + S3QuestionTypeOptionWidget, \ |
17 | + survey_T |
18 | |
19 | module = request.controller |
20 | prefix = request.controller |
21 | @@ -66,8 +68,18 @@ |
22 | def prep(r): |
23 | if r.component and r.component_name == "translate": |
24 | table = db["survey_translate"] |
25 | - table.file.readable = False |
26 | - table.file.writable = False |
27 | + # list existing translations and allow the addition of a new translation |
28 | + if r.component_id == None: |
29 | + table.file.readable = False |
30 | + table.file.writable = False |
31 | + # edit the selected translation |
32 | + else: |
33 | + table.language.writable = False |
34 | + table.code.writable = False |
35 | + # remove CRUD generated buttons in the tabs |
36 | + s3mgr.configure(table, |
37 | + deletable=False, |
38 | + ) |
39 | else: |
40 | s3_action_buttons(r) |
41 | query = (r.table.status == 1) # Status of Pending |
42 | @@ -88,8 +100,8 @@ |
43 | # Post-processor |
44 | def postp(r, output): |
45 | if r.component: |
46 | + template_id = request.args[0] |
47 | if r.component_name == "section": |
48 | - template_id = request.args[0] |
49 | # Add the section select widget to the form |
50 | sectionSelect = response.s3.survey_section_select_widget(template_id) |
51 | output.update(form = sectionSelect) |
52 | @@ -101,9 +113,18 @@ |
53 | _class="action-btn", |
54 | url=URL(c=module, |
55 | f="templateTranslateDownload", |
56 | - args=["[id]","update"]) |
57 | - ), |
58 | - ) |
59 | + args=["[id]"]) |
60 | + ), |
61 | + ) |
62 | + response.s3.actions.append( |
63 | + dict(label=str(T("Upload")), |
64 | + _class="action-btn", |
65 | + url=URL(c=module, |
66 | + f="template", |
67 | + args=[template_id,"translate","[id]"]) |
68 | + ), |
69 | + ) |
70 | + return output |
71 | |
72 | |
73 | # Add a button to show what the questionnaire looks like |
74 | @@ -147,16 +168,15 @@ |
75 | |
76 | response.s3.prep = prep |
77 | |
78 | - # remove CRUD generated buttons in the tabs |
79 | - s3mgr.configure(tablename, |
80 | - listadd=False, |
81 | - deletable=False, |
82 | - ) |
83 | - |
84 | response.s3.postp = postp |
85 | rheader = response.s3.survey_template_rheader |
86 | + # remove CRUD generated buttons in the tabs |
87 | + s3mgr.configure(tablename, |
88 | + listadd=False, |
89 | + deletable=False, |
90 | + ) |
91 | output = s3_rest_controller(prefix, resourcename, rheader=rheader) |
92 | - |
93 | + |
94 | return output |
95 | |
96 | def templateRead(): |
97 | @@ -249,15 +269,24 @@ |
98 | redirect(URL(c="survey", |
99 | f="templateTranslation", |
100 | args=[], |
101 | - vars = {})) |
102 | + vars = {})) |
103 | code = record.code |
104 | language = record.language |
105 | + lang_fileName = "applications/%s/languages/%s.py" % (request.application, code) |
106 | + try: |
107 | + strings = read_dict(lang_fileName) |
108 | + except: |
109 | + strings = dict() |
110 | template_id = record.template_id |
111 | + template = response.s3.survey_getTemplate(template_id) |
112 | book = xlwt.Workbook(encoding="utf-8") |
113 | sheet = book.add_sheet(language) |
114 | output = StringIO() |
115 | qstnList = response.s3.survey_getAllQuestionsForTemplate(template_id) |
116 | original = {} |
117 | + original[template["name"]] = True |
118 | + if template["description"] != "": |
119 | + original[template["description"]] = True |
120 | for qstn in qstnList: |
121 | original[qstn["name"]] = True |
122 | widgetObj = survey_question_type[qstn["type"]](question_id = qstn["qstn_id"]) |
123 | @@ -267,6 +296,7 @@ |
124 | original[option] = True |
125 | sections = response.s3.survey_getAllSectionsForTemplate(template_id) |
126 | for section in sections: |
127 | + original[section["name"]]=True |
128 | section_id = section["section_id"] |
129 | layoutRules = response.s3.survey_getQstnLayoutRules(template_id, section_id) |
130 | layoutStr = str(layoutRules) |
131 | @@ -290,10 +320,16 @@ |
132 | originalList.sort() |
133 | for text in originalList: |
134 | row += 1 |
135 | + original = unicode(text) |
136 | sheet.write(row, |
137 | 0, |
138 | - unicode(text) |
139 | + original |
140 | ) |
141 | + if (original in strings): |
142 | + sheet.write(row, |
143 | + 1, |
144 | + strings[original] |
145 | + ) |
146 | |
147 | book.save(output) |
148 | output.seek(0) |
149 | @@ -312,6 +348,14 @@ |
150 | |
151 | def prep(r): |
152 | if r.interactive: |
153 | + if r.method == "create": |
154 | + allTemplates = response.s3.survey_getAllTemplates() |
155 | + if len(allTemplates) == 0: |
156 | + session.warning = T("You need to create a template before you can create a series") |
157 | + redirect(URL(c="survey", |
158 | + f="template", |
159 | + args=[], |
160 | + vars = {})) |
161 | if r.id and (r.method == "update"): |
162 | table.template_id.writable = False |
163 | return True |
164 | @@ -347,13 +391,6 @@ |
165 | s3mgr.load(tablename) |
166 | crud_strings = response.s3.crud_strings[tablename] |
167 | |
168 | - # Check that the series_id has been passed in |
169 | - if len(request.args) != 1: |
170 | - output = s3_rest_controller(prefix, |
171 | - resourcename, |
172 | - rheader=response.s3.survey_series_rheader) |
173 | - return output |
174 | - |
175 | try: |
176 | import xlwt |
177 | except ImportError: |
178 | @@ -369,6 +406,22 @@ |
179 | # * The sections within the template |
180 | # * The layout rules for each question |
181 | ###################################################################### |
182 | + # Check that the series_id has been passed in |
183 | + if len(request.args) != 1: |
184 | + output = s3_rest_controller(prefix, |
185 | + resourcename, |
186 | + rheader=response.s3.survey_series_rheader) |
187 | + return output |
188 | + if "translationLanguage" in current.request.post_vars: |
189 | + lang = current.request.post_vars.translationLanguage |
190 | + if lang == "Default": |
191 | + langDict = dict() |
192 | + else: |
193 | + try: |
194 | + lang_fileName = "applications/%s/languages/%s.py" % (request.application, lang) |
195 | + langDict = read_dict(lang_fileName) |
196 | + except: |
197 | + langDict = dict() |
198 | series_id = request.args[0] |
199 | sectionList = response.s3.survey_getAllSectionsForSeries(series_id) |
200 | layout = {} |
201 | @@ -463,7 +516,8 @@ |
202 | (endrow, endcol) = widgetObj.writeToMatrix(matrix, |
203 | row, |
204 | col, |
205 | - answerMatrix=matrixAnswer |
206 | + answerMatrix=matrixAnswer, |
207 | + langDict = langDict |
208 | ) |
209 | except Exception as msg: |
210 | print msg |
211 | @@ -492,7 +546,7 @@ |
212 | row += 1 |
213 | else: |
214 | logo = None |
215 | - title = template.description |
216 | + title = survey_T(template.description, langDict) |
217 | cell = MatrixElement(0,col,title, style="styleHeader") |
218 | cell.merge(vertical=1, horizontal=4) |
219 | matrix.addElement(cell) |
220 | @@ -502,7 +556,7 @@ |
221 | col = 0 |
222 | row += 1 |
223 | rules = layout[section["name"]] |
224 | - cell = MatrixElement(row,col,section["name"], style="styleHeader") |
225 | + cell = MatrixElement(row,col,survey_T(section["name"],langDict), style="styleHeader") |
226 | try: |
227 | matrix.addElement(cell) |
228 | except Exception as msg: |
229 | @@ -952,6 +1006,7 @@ |
230 | |
231 | def postp(r, output): |
232 | if r.interactive: |
233 | + T = current.T |
234 | if "viewing" in current.request.vars: |
235 | dummy, series_id = current.request.vars.viewing.split(".") |
236 | elif "series" in current.request.vars: |
237 | @@ -966,20 +1021,36 @@ |
238 | vars = {})) |
239 | response.s3.survey_answerlist_dataTable_post(r) |
240 | form = response.s3.survey_buildQuestionnaireFromSeries(series_id, None) |
241 | + translationList = response.s3.survey_getAllTranslationsForSeries(series_id) |
242 | urlexport = URL(c=module, |
243 | f="series_export_formatted", |
244 | args=[series_id] |
245 | ) |
246 | + tranForm = FORM(_action=urlexport) |
247 | + tranForm.append(INPUT(_type='checkbox', |
248 | + _name='translationLanguage', |
249 | + _value="Default", |
250 | + value=True, |
251 | + )) |
252 | + tranForm.append(LABEL("Default")) |
253 | + for translation in translationList: |
254 | + tranForm.append(INPUT(_type='checkbox', |
255 | + _name='translationLanguage', |
256 | + _value=translation["code"], |
257 | + )) |
258 | + tranForm.append(LABEL(translation["language"])) |
259 | + exportBtn = INPUT(_type="submit", _id="export_btn", _name="Export_Spreadsheet", _value=T("Export Assessment as a Formatted Spreadsheet")) |
260 | + tranForm.append(exportBtn) |
261 | urlimport = URL(c=module, |
262 | f="complete", |
263 | args=[series_id,"import.xml"], |
264 | vars = {"extra_data":True} |
265 | ) |
266 | - T = current.T |
267 | - buttons = DIV (A(T("Export Assessment as a Formatted Spreadsheet"), _href=urlexport, _id="Excel-export", _class="action-btn"), |
268 | + buttons = DIV (#A(T("Export Assessment as a Formatted Spreadsheet"), _href=urlexport, _id="Excel-export", _class="action-btn"), |
269 | A(T("Import Spreadsheet as an Assessment"), _href=urlimport, _id="Excel-import", _class="action-btn"), |
270 | ) |
271 | - output["subtitle"] = buttons |
272 | + tranForm.append(buttons) |
273 | + output["subtitle"] = tranForm |
274 | output["form"] = form |
275 | return output |
276 | |
277 | @@ -1032,7 +1103,7 @@ |
278 | except ImportError: |
279 | print >> sys.stderr, "ERROR: xlrd & xlwt modules are needed for importing spreadsheets" |
280 | return None |
281 | - workbook = xlrd.open_workbook(filename=uploadFile) |
282 | + workbook = xlrd.open_workbook(filename=uploadFile.file) |
283 | sheetR = workbook.sheet_by_name("Assessment") |
284 | sheetM = workbook.sheet_by_name("Metadata") |
285 | header = '"Series"' |
286 | |
287 | === modified file 'models/survey.py' |
288 | --- models/survey.py 2011-11-23 13:40:47 +0000 |
289 | +++ models/survey.py 2011-11-25 15:29:24 +0000 |
290 | @@ -27,6 +27,8 @@ |
291 | import json |
292 | sys.path.append("applications/%s/modules/s3" % request.application) |
293 | |
294 | + from gluon.languages import read_dict, write_dict |
295 | + |
296 | from s3codec import S3Codec |
297 | from xml.sax.saxutils import unescape |
298 | from s3survey import survey_question_type, \ |
299 | @@ -1334,9 +1336,71 @@ |
300 | s3.crud_strings[tablename] = Storage( |
301 | title_create = T("Add new translation language"), |
302 | ) |
303 | + |
304 | + def translate_onaccept(form): |
305 | + """ |
306 | + If the translation spreadsheet has been uploaded then |
307 | + it needs to be processed. |
308 | + |
309 | + The translation strings need to be extracted from |
310 | + the spreadsheet and inserted into the language file. |
311 | + """ |
312 | + if "file" in form.vars: |
313 | + try: |
314 | + import xlrd |
315 | + except ImportError: |
316 | + print >> sys.stderr, "ERROR: xlrd & xlwt modules are needed for importing spreadsheets" |
317 | + return None |
318 | + |
319 | + msgNone = T("No translations exist in spreadsheet") |
320 | + upload_file = current.request.post_vars.file |
321 | + upload_file.file.seek(0) |
322 | + openFile = upload_file.file.read() |
323 | + lang = form.record.language |
324 | + code = form.record.code |
325 | + try: |
326 | + workbook = xlrd.open_workbook(file_contents=openFile) |
327 | + except: |
328 | + msg = T("Unable to open spreadsheet") |
329 | + current.response.error = msg |
330 | + current.response.flash = None |
331 | + return |
332 | + try: |
333 | + sheetL = workbook.sheet_by_name(lang) |
334 | + except: |
335 | + msg = T("Unable to find sheet %(sheet_name)s in uploaded spreadsheet") % dict(sheet_name=lang) |
336 | + current.response.error = msg |
337 | + current.response.flash = None |
338 | + return |
339 | + if sheetL.ncols == 1: |
340 | + current.response.warning = msgNone |
341 | + current.response.flash = None |
342 | + return |
343 | + count = 0 |
344 | + lang_fileName = "applications/%s/languages/%s.py" % (request.application, code) |
345 | + try: |
346 | + strings = read_dict(lang_fileName) |
347 | + except: |
348 | + strings = dict() |
349 | + for row in xrange(1, sheetL.nrows): |
350 | + original = sheetL.cell_value(row, 0) |
351 | + translation = sheetL.cell_value(row, 1) |
352 | + if (original not in strings) or translation != "": |
353 | + strings[original] = translation |
354 | + count += 1 |
355 | + write_dict(lang_fileName, strings) |
356 | + if count == 0: |
357 | + current.response.warning = msgNone |
358 | + current.response.flash = None |
359 | + else: |
360 | + current.response.flash = T("%(count_of)d translations have been imported to the %(language)s language file") % dict(count_of=count, language=lang) |
361 | + |
362 | # components |
363 | s3mgr.model.add_component("survey_translate", |
364 | survey_template="template_id") |
365 | + s3mgr.configure(tablename, |
366 | + onaccept = translate_onaccept, |
367 | + ) |
368 | #********************************************************************** |
369 | # The bread and butter methods to get data off the database |
370 | #********************************************************************** |
371 | @@ -1390,6 +1454,14 @@ |
372 | #********************************************************************** |
373 | # Functions to get a list of records from the database |
374 | #********************************************************************** |
375 | + def getAllTemplates(): |
376 | + """ |
377 | + function to return all the templates on the database |
378 | + """ |
379 | + table = db.survey_template |
380 | + row = db(table).select() |
381 | + return row |
382 | + |
383 | def getAllSeries(): |
384 | """ |
385 | function to return all the series on the database |
386 | @@ -1398,6 +1470,22 @@ |
387 | row = db(table).select() |
388 | return row |
389 | |
390 | + def getAllTranslationsForTemplate(template_id): |
391 | + """ |
392 | + function to return all the translations for the given template |
393 | + """ |
394 | + table = db.survey_translate |
395 | + row = db(table).select() |
396 | + return row |
397 | + |
398 | + def getAllTranslationsForSeries(series_id): |
399 | + """ |
400 | + function to return all the translations for the given series |
401 | + """ |
402 | + row = getSeries(series_id) |
403 | + template_id = row.template_id |
404 | + return getAllTranslationsForTemplate(template_id) |
405 | + |
406 | def getAllQuestionsForTemplate(template_id): |
407 | """ |
408 | function to return the list of questions for the given template |
409 | @@ -1604,9 +1692,11 @@ |
410 | tabs = [(T("Basic Details"), "read"), |
411 | (T("Question Details"),"templateRead/"), |
412 | (T("Question Summary"),"templateSummary/"), |
413 | - (T("Translate"),"translate"), |
414 | # (T("Sections"), "section"), |
415 | ] |
416 | + if auth.s3_has_permission("create", "survey_translate"): |
417 | + tabs.append((T("Translate"),"translate")) |
418 | + |
419 | rheader_tabs = s3_rheader_tabs(r, tabs) |
420 | |
421 | sectionTable = db["survey_section"] |
422 | @@ -2322,10 +2412,14 @@ |
423 | |
424 | return_dict = dict( |
425 | survey_updateMetaData = updateMetaData, |
426 | + survey_getTemplate = getTemplate, |
427 | survey_getTemplateFromSeries = getTemplateFromSeries, |
428 | survey_getSeries = getSeries, |
429 | survey_getSeriesName = getSeriesName, |
430 | survey_getTranslation = getTranslation, |
431 | + survey_getAllTranslationsForTemplate = getAllTranslationsForTemplate, |
432 | + survey_getAllTranslationsForSeries = getAllTranslationsForSeries, |
433 | + survey_getAllTemplates = getAllTemplates, |
434 | survey_getAllSeries = getAllSeries, |
435 | survey_getAllSectionsForTemplate = getAllSectionsForTemplate, |
436 | survey_getAllSectionsForSeries = getAllSectionsForSeries, |
437 | @@ -2411,8 +2505,9 @@ |
438 | If the record is a duplicate then it will set the job method to update |
439 | |
440 | Rules for finding a duplicate: |
441 | - - Look for a record with the same name, ignoring case |
442 | - - and the same template |
443 | + - Look for a record with the same name |
444 | + - the same template |
445 | + - and the same position within the template |
446 | """ |
447 | # ignore this processing if the id is set |
448 | if job.id: |
449 | @@ -2420,9 +2515,9 @@ |
450 | if job.tablename == "survey_section": |
451 | table = job.table |
452 | name = "name" in job.data and job.data.name |
453 | + posn = "posn" in job.data and job.data.posn |
454 | template = "template" in job.data and job.data.template_id |
455 | - |
456 | - query = table.name.lower().like('%%%s%%' % name.lower()) |
457 | + query = ((table.name==name) & (table.template_id==template) & (table.posn==posn)) |
458 | _duplicate = db(query).select(table.id, limitby=(0, 1)).first() |
459 | if _duplicate: |
460 | job.id = _duplicate.id |
461 | |
462 | === modified file 'modules/s3/s3survey.py' |
463 | --- modules/s3/s3survey.py 2011-11-23 13:42:20 +0000 |
464 | +++ modules/s3/s3survey.py 2011-11-25 15:29:24 +0000 |
465 | @@ -251,6 +251,15 @@ |
466 | return S3QuestionTypeGridWidget(question_id) |
467 | def survey_gridChildType(question_id = None): |
468 | return S3QuestionTypeGridChildWidget(question_id) |
469 | +def survey_T(phrase, langDict): |
470 | + """ |
471 | + Function to translate a phrase using the dictionary passed in |
472 | + """ |
473 | + if phrase in langDict and langDict[phrase] != "": |
474 | + return langDict[phrase] |
475 | + else: |
476 | + return phrase |
477 | + |
478 | |
479 | survey_question_type = { |
480 | "String": survey_stringType, |
481 | @@ -493,10 +502,17 @@ |
482 | """ |
483 | return DIV(self.typeDescription, _class="surveyWidgetType") |
484 | |
485 | + def _Tquestion(self, langDict): |
486 | + """ |
487 | + Function to translate the question using the dictionary passed in |
488 | + """ |
489 | + return survey_T(self.question["name"], langDict) |
490 | + |
491 | def writeToMatrix(self, |
492 | matrix, |
493 | row, |
494 | col, |
495 | + langDict=dict(), |
496 | answerMatrix=None, |
497 | style={"Label": True |
498 | ,"LabelLeft" : True |
499 | @@ -507,7 +523,7 @@ |
500 | """ |
501 | self._store_metadata() |
502 | if "Label" in style and style["Label"]: |
503 | - cell = MatrixElement(row,col,self.question["name"], style="styleSubHeader") |
504 | + cell = MatrixElement(row,col,self._Tquestion(langDict), style="styleSubHeader") |
505 | matrix.addElement(cell) |
506 | if "LabelLeft" in style and style["LabelLeft"]: |
507 | col += 1 |
508 | @@ -867,6 +883,7 @@ |
509 | matrix, |
510 | row, |
511 | col, |
512 | + langDict=dict(), |
513 | answerMatrix=None, |
514 | style={"Label": True |
515 | ,"LabelLeft" : False |
516 | @@ -877,7 +894,7 @@ |
517 | """ |
518 | self._store_metadata() |
519 | if "Label" in style and style["Label"]: |
520 | - cell = MatrixElement(row,col,self.question["name"], style="styleSubHeader") |
521 | + cell = MatrixElement(row,col,self._Tquestion(langDict), style="styleSubHeader") |
522 | matrix.addElement(cell) |
523 | if "LabelLeft" in style and style["LabelLeft"]: |
524 | col += 1 |
525 | @@ -895,7 +912,7 @@ |
526 | answerMatrix.addElement(cell) |
527 | answerCol = 3 |
528 | for option in list: |
529 | - cell = MatrixElement(row,col,option, style="styleText") |
530 | + cell = MatrixElement(row,col,survey_T(option, langDict), style="styleText") |
531 | matrix.addElement(cell) |
532 | cell = MatrixElement(row,col+1,"", style="styleInput") |
533 | matrix.addElement(cell) |
534 | @@ -1327,6 +1344,7 @@ |
535 | matrix, |
536 | row, |
537 | col, |
538 | + langDict=dict(), |
539 | answerMatrix=None, |
540 | style={"Label": True |
541 | ,"LabelLeft" : True |
542 | @@ -1343,7 +1361,7 @@ |
543 | gridStyle = style |
544 | gridStyle["Label"] = False |
545 | if self.data != None: |
546 | - cell = MatrixElement(row,col,self.subtitle, style="styleSubHeader") |
547 | + cell = MatrixElement(row,col,survey_T(self.subtitle, langDict), style="styleSubHeader") |
548 | matrix.addElement(cell) |
549 | # Add a *mostly* blank line for the heading. |
550 | # This will be added on the first run through the list |
551 | @@ -1356,12 +1374,12 @@ |
552 | for line in self.data: |
553 | col = startcol |
554 | row = nextrow |
555 | - cell = MatrixElement(row,col,self.rows[posn], style="styleText") |
556 | + cell = MatrixElement(row,col,survey_T(self.rows[posn], langDict), style="styleText") |
557 | matrix.addElement(cell) |
558 | col += 1 |
559 | for cell in line: |
560 | if firstRun: |
561 | - cell = MatrixElement(row-1,col,self.columns[colCnt], style="styleSubHeader") |
562 | + cell = MatrixElement(row-1,col,survey_T(self.columns[colCnt], langDict), style="styleSubHeader") |
563 | matrix.addElement(cell) |
564 | colCnt += 1 |
565 | if cell == "Blank": |
566 | @@ -1372,7 +1390,12 @@ |
567 | childWidget = self.getChildWidget(code) |
568 | type = childWidget.get("Type") |
569 | realWidget = survey_question_type[type](childWidget.id) |
570 | - (endrow, col) = realWidget.writeToMatrix(matrix, row, col, answerMatrix, style) |
571 | + (endrow, col) = realWidget.writeToMatrix(matrix, |
572 | + row, |
573 | + col, |
574 | + langDict, |
575 | + answerMatrix, |
576 | + style) |
577 | if endrow > nextrow: |
578 | nextrow = endrow |
579 | posn += 1 |
580 | @@ -1501,7 +1524,8 @@ |
581 | def writeToMatrix(self, |
582 | matrix, |
583 | row, |
584 | - col, |
585 | + col, |
586 | + langDict=dict(), |
587 | answerMatrix=None, |
588 | style={} |
589 | ): |