def __init__(self, defaultImage = None): Idevice.__init__(self, x_(u"Image with Text"), x_(u"University of Auckland"), x_(u"""<p> The image with text iDevice can be used in a number of ways to support both the emotional (affective) and learning task (cognitive) dimensions of eXe content. </p><p> <b>Integrating visuals with verbal summaries</b> </p><p> Cognitive psychologists indicate that presenting learners with a representative image and corresponding verbal summary (that is presented simultaneously) can reduce cognitive load and enhance learning retention. This iDevice can be used to present an image (photograph, diagram or graphic) with a brief verbal summary covering the main points relating to the image. For example, if you were teaching the functions of a four-stroke combustion engine, you could have a visual for each of the four positions of the piston with a brief textual summary of the key aspects of each visual. </p>"""), u"", u"") self.emphasis = Idevice.NoEmphasis self.group = Idevice.Media self.image = ImageField(x_(u"Image"), u"") self.image.idevice = self self.image.defaultImage = defaultImage self.text = TextAreaField(x_(u"Text"), x_("""Enter the text you wish to associate with the image.""")) self.text.idevice = self self.float = u"left" self.caption = u"" self._captionInstruc = x_(u"""Provide a caption for the image you have just inserted.""")
def addChance(self, defaultImagePath = None): newLevelImageField = ImageField(x_(u"Image for this chance"), u"") newLevelImageField.idevice = self if defaultImagePath is not None: newLevelImageField.defaultImage = \ str(field_engine_get_template_absolute_path( defaultImagePath)) self.chanceImageFields.append(newLevelImageField)
def process(self, request, status): """ Process """ log.debug("process " + repr(request.args)) self.message = "" if status == "old": for element in self.elements: element.process(request) if "title" in request.args: self.idevice.title = unicode(request.args["title"][0], 'utf8') if "author" in request.args: self.idevice.author = unicode(request.args["author"][0], 'utf8') if "purpose" in request.args: self.idevice.purpose = unicode(request.args["purpose"][0], 'utf8') if "tip" in request.args: self.idevice.tip = unicode(request.args["tip"][0], 'utf8') if "emphasis" in request.args: self.idevice.emphasis = int(request.args["emphasis"][0]) if self.idevice.emphasis == 0: self.idevice.icon = "" if "addText" in request.args: self.idevice.addField(TextField(_(u"Enter the label here"), _(u"Enter instructions for completion here"))) if "addTextArea" in request.args: self.idevice.addField(TextAreaField(_(u"Enter the label here"), _(u"Enter the instructions for completion here"))) if "addImage" in request.args: field = ImageField(_(u"Enter the label here"), _(u"Enter the instructions for completion here")) imagePath = self.webDir/"images"/ImageEditorElement.DefaultImage field.defaultImage = unicode(imagePath.abspath()) self.idevice.addField(field) if "addFeedback" in request.args: self.idevice.addField(FeedbackField(_(u"Enter the label here"), _(u"""Feedback button will not appear if no data is entered into this field."""))) if ("action" in request.args and request.args["action"][0] == "selectIcon"): self.idevice.icon = request.args["object"][0] if "preview" in request.args: if self.idevice.title == "": self.message = _("Please enter an idevice name.") else: self.idevice.edit = False if "edit" in request.args: self.idevice.edit = True if "cancel" in request.args: ideviceId = self.idevice.id self.idevice = self.originalIdevice.clone() self.idevice.id = ideviceId if ("action" in request.args and request.args["action"][0] == "changeStyle"): self.style = request.args["object"][0] self.__buildElements()
def setupImage(self, idevice): """ Creates our image field: no longer needed for new content since images are now embedded straight into the feedbackTextArea, but this routine is kept around for upgrade paths from old elps. """ self.image = ImageField(x_(u"Image"), x_(u"Choose an optional image to be shown to the student " "on completion of this question")) self.image.idevice = idevice self.image.defaultImage = idevice.defaultImage self.image.isFeedback = True
def field_engine_check_field(fieldId, fieldInfoDict, fieldDict, idevice): if fieldId in fieldDict.keys(): return fieldTypeName = fieldInfoDict[fieldId][EXEFIELDINFO_TYPE] defaultVal = getFieldDefaultVal(fieldId, fieldInfoDict) newField = 0 if fieldTypeName == 'image': newField = ImageField(fieldInfoDict[fieldId][EXEFIELDINFO_DESC], fieldInfoDict[fieldId][EXEFIELDINFO_HELP]) #must do this before attempting to set default value newField.idevice = idevice if defaultVal is not None: #right about here do setImage newField.defaultImage = str(field_engine_get_template_absolute_path(defaultVal)) pass elif fieldTypeName == 'text': newField = TextField(fieldInfoDict[fieldId][EXEFIELDINFO_DESC], fieldInfoDict[fieldId][EXEFIELDINFO_HELP]) if defaultVal is not None: newField.content = defaultVal elif fieldTypeName == 'textarea': newField = TextAreaField(fieldInfoDict[fieldId][EXEFIELDINFO_DESC], fieldInfoDict[fieldId][EXEFIELDINFO_HELP]) elif fieldTypeName == 'choice': newField = ChoiceField(idevice, fieldInfoDict[fieldId][EXEFIELDINFO_EXTRAINFODICT]['choices'], fieldInfoDict[fieldId][EXEFIELDINFO_DESC], fieldInfoDict[fieldId][EXEFIELDINFO_HELP]) newField.idevice = idevice if newField != 0: fieldDict[fieldId] = newField
def field_engine_check_field(fieldId, fieldInfoDict, fieldDict, idevice): if fieldId in fieldDict.keys(): return fieldTypeName = fieldInfoDict[fieldId][EXEFIELDINFO_TYPE] defaultVal = getFieldDefaultVal(fieldId, fieldInfoDict) newField = 0 if fieldTypeName == 'image': newField = ImageField(fieldInfoDict[fieldId][EXEFIELDINFO_DESC], fieldInfoDict[fieldId][EXEFIELDINFO_HELP]) #must do this before attempting to set default value newField.idevice = idevice if defaultVal is not None: #right about here do setImage newField.defaultImage = str( field_engine_get_template_absolute_path(defaultVal)) pass elif fieldTypeName == 'text': newField = TextField(fieldInfoDict[fieldId][EXEFIELDINFO_DESC], fieldInfoDict[fieldId][EXEFIELDINFO_HELP]) if defaultVal is not None: newField.content = defaultVal elif fieldTypeName == 'textarea': newField = TextAreaField(fieldInfoDict[fieldId][EXEFIELDINFO_DESC], fieldInfoDict[fieldId][EXEFIELDINFO_HELP]) elif fieldTypeName == 'choice': newField = ChoiceField( idevice, fieldInfoDict[fieldId][EXEFIELDINFO_EXTRAINFODICT]['choices'], fieldInfoDict[fieldId][EXEFIELDINFO_DESC], fieldInfoDict[fieldId][EXEFIELDINFO_HELP]) newField.idevice = idevice if newField != 0: fieldDict[fieldId] = newField
class Question(Persistable): """ A Case iDevice is built up of question and options. Each option can be rendered as an XHTML element """ persistenceVersion = 2 def __init__(self, idevice): """ Initialize """ self.questionTextArea = TextAreaField(u'', u'', u'') self.questionTextArea.idevice = idevice self.feedbackTextArea = Feedback2Field(u'', u'', u'') self.feedbackTextArea.idevice = idevice def setupImage(self, idevice): """ Creates our image field: no longer needed for new content since images are now embedded straight into the feedbackTextArea, but this routine is kept around for upgrade paths from old elps. """ self.image = ImageField(x_(u"Image"), x_(u"Choose an optional image to be shown to the student " "on completion of this question")) self.image.idevice = idevice self.image.defaultImage = idevice.defaultImage self.image.isFeedback = True def getResourcesField(self, this_resource): """ implement the specific resource finding mechanism for this iDevice's Question object: """ # be warned that before upgrading, this iDevice field could not exist: if hasattr(self, 'questionTextArea')\ and hasattr(self.questionTextArea, 'images'): for this_image in self.questionTextArea.images: if hasattr(this_image, '_imageResource') \ and this_resource == this_image._imageResource: return self.questionTextArea # be warned that before upgrading, this iDevice field could not exist: if hasattr(self, 'feedbackTextArea')\ and hasattr(self.feedbackTextArea, 'images'): for this_image in self.feedbackTextArea.images: if hasattr(this_image, '_imageResource') \ and this_resource == this_image._imageResource: return self.feedbackTextArea return None def getRichTextFields(self): """ Like getResourcesField(), a general helper to allow nodes to search through all of their fields without having to know the specifics of each iDevice type. """ fields_list = [] if hasattr(self, 'questionTextArea'): fields_list.append(self.questionTextArea) if hasattr(self, 'feedbackTextArea'): fields_list.append(self.feedbackTextArea) return fields_list def upgradeToVersion1(self): """ Upgrades to version 0.24 """ log.debug(u"Upgrading iDevice") self.image.isFeedback = True def upgradeToVersion2(self): pass def embedImageInFeedback(self): """ Actually do the Converting of each question's CaseStudyIdevice's image -> embedded in its feedback field, now that its TextField can hold embeddded images. """ new_content = "" # if no image resource even exists, then no need to continue: # is there a defined? if self.image is None or self.image.imageResource is None: return # likewise, only proceed if the image resource file is found: if not os.path.exists(self.image.imageResource.path) \ or not os.path.isfile(self.image.imageResource.path): return # and if it's just the default blank image, then nothing to do either: if self.image.isDefaultImage: return # get the current image resource info: new_content += "<img src=\"resources/" \ + self.image.imageResource.storageName + "\" " if self.image.height: new_content += "height=\"" + self.image.height + "\" " if self.image.width: new_content += "width=\"" + self.image.width + "\" " new_content += "/> \n" # prepend the new image content to any already existing feedback, # using its content WITH the resources path: new_content += "<BR>\n" new_content += self.feedbackTextArea.content_w_resourcePaths self.feedbackTextArea.content_w_resourcePaths = new_content # set that to its default content: self.feedbackTextArea.content = \ self.feedbackTextArea.content_w_resourcePaths # and massage its content for exporting without resource paths: self.feedbackTextArea.content_wo_resourcePaths = \ self.feedbackTextArea.MassageContentForRenderView( \ self.feedbackTextArea.content_w_resourcePaths) # in passing GalleryImage into feedbackTextArea, a FieldWithResources, # the field needs to be sure to have an updated parentNode, # courtesy of its idevice: self.feedbackTextArea.setParentNode() # (note: FieldWithResources *usually* take care of this automatically # within ProcessPreviewedImages(), but here in this upgrade # path, we are bypassing the general purpose ProcessPreviewed().) # Not sure why this can't be imported up top, but it gives # ImportError: cannot import name GalleryImages, # so here it be: from exe.engine.galleryidevice import GalleryImage full_image_path = self.image.imageResource.path # note: unapplicable caption set to '' in the 2nd parameter: new_GalleryImage = GalleryImage(self.feedbackTextArea, \ '', full_image_path, mkThumbnail=False) # finally, go ahead and clear out the current image object, # which is best (and most safely) done by setting it back to default: self.image.setDefaultImage()
class ImageWithTextIdevice(Idevice): """ A ImageWithText Idevice is one built up from an image and free text. """ persistenceVersion = 9 def __init__(self, defaultImage = None): Idevice.__init__(self, x_(u"Image with Text"), x_(u"University of Auckland"), x_(u"""<p> The image with text iDevice can be used in a number of ways to support both the emotional (affective) and learning task (cognitive) dimensions of eXe content. </p><p> <b>Integrating visuals with verbal summaries</b> </p><p> Cognitive psychologists indicate that presenting learners with a representative image and corresponding verbal summary (that is presented simultaneously) can reduce cognitive load and enhance learning retention. This iDevice can be used to present an image (photograph, diagram or graphic) with a brief verbal summary covering the main points relating to the image. For example, if you were teaching the functions of a four-stroke combustion engine, you could have a visual for each of the four positions of the piston with a brief textual summary of the key aspects of each visual. </p>"""), u"", u"") self.emphasis = Idevice.NoEmphasis self.group = Idevice.Media self.image = ImageField(x_(u"Image"), u"") self.image.idevice = self self.image.defaultImage = defaultImage self.text = TextAreaField(x_(u"Text"), x_("""Enter the text you wish to associate with the image.""")) self.text.idevice = self self.float = u"left" self.caption = u"" self._captionInstruc = x_(u"""Provide a caption for the image you have just inserted.""") # Properties captionInstruc = lateTranslate('captionInstruc') def upgradeToVersion1(self): """ Called to upgrade from 0.5 release """ self.float = u"left" def upgradeToVersion2(self): """ Called to upgrade from 0.6 release """ self.caption = u"" self.emphasis = Idevice.NoEmphasis def upgradeToVersion3(self): """ Upgrades v0.6 to v0.7. """ self.lastIdevice = False def upgradeToVersion4(self): """ Upgrades to exe v0.10 """ self._upgradeIdeviceToVersion1() def upgradeToVersion5(self): """ Upgrades to v0.12 """ log.debug("upgrade to version 5") self._upgradeIdeviceToVersion2() self.image._upgradeFieldToVersion2() def upgradeToVersion6(self): """ Called to upgrade from 0.13 release """ self._captionInstruc = x_(u"""Provide a caption for the image you have just inserted.""") def upgradeToVersion7(self): """ Called to upgrade to version 0.24 """ self.image.isFeedback = False def upgradeToVersion8(self): """ Converting ImageWithTextIdevice -> FreeTextIdevice, now that FreeText can hold embeddded images. BUT - due to the inconsistent loading of the objects via unpickling, since the resources aren't necessarily properly loaded and upgraded, NOR is the package necessarily, as it might not even have a list of resources yet, all of this conversion code must be done in an afterUpgradeHandler """ G.application.afterUpgradeHandlers.append(self.convertToFreeText) def upgradeToVersion9(self): """ Adds group to idevice """ self.group = Idevice.Media def convertToFreeText(self): """ Actually do the Converting of ImageWithTextIdevice -> FreeTextIdevice, now that FreeText can hold embeddded images. """ new_content = "" # ensure that an image resource still exists on this ImageWithText, # before trying to add it into the FreeText idevice. # Why? corrupt packages have been seen missing resources... # (usually in with extra package objects as well, probably # from old code doing faulty Extracts, or somesuch nonesense) imageResource_exists = False if self.image.imageResource: # also ensure that it has the correct md5 checksum, since there was # a period in which resource checksums were being created before # the resource zip file was fully closed, and not flushed out: self.image.imageResource.checksumCheck() if os.path.exists(self.image.imageResource.path) and \ os.path.isfile(self.image.imageResource.path): imageResource_exists = True else: log.warn("Couldn't find ImageWithText image when upgrading "\ + self.image.imageResource.storageName) if imageResource_exists: new_content += "<img src=\"resources/" \ + self.image.imageResource.storageName + "\" " if self.image.height: new_content += "height=\"" + self.image.height + "\" " if self.image.width: new_content += "width=\"" + self.image.width + "\" " new_content += "/> \n" elif self.image.imageResource: new_content += "<BR>\n[WARNING: missing image: " \ + self.image.imageResource.storageName + "]\n" if self.caption != "": new_content += "<BR>\n[" + self.caption + "]\n" if self.text.content != "": new_content += "<P>\n" + self.text.content + "\n" # note: this is given a text field which itself did NOT yet have # any embedded media! easier, eh? replacementIdev = FreeTextIdevice(new_content) ########### # now, copy that content field's content into its _w_resourcePaths, # and properly remove the resource directory via Massage.... # for its _wo_resourcePaths: # note that replacementIdev's content field's content # is automatically set at its constructor (above), # as is the default content_w_resourcePaths (a copy of content) # AND the default content_wo_resourcePaths (a copy of content), # so only need to update the content_wo_resourcePaths: replacementIdev.content.content_wo_resourcePaths = \ replacementIdev.content.MassageContentForRenderView( \ replacementIdev.content.content_w_resourcePaths) # Design note: ahhhhh, the above is a good looking reason to possibly # have the MassageContentForRenderView() method # just assume its content_w_resourcePaths as the input # and write the output to its content_wo_resourcePaths..... ####### # next step, add the new IDevice into the same node as this one self.parentNode.addIdevice(replacementIdev) # in passing GalleryImage into the FieldWithResources, # that content field needs to be sure to have an updated # parentNode, courtesy of its idevice: replacementIdev.content.setParentNode() # and semi-manually add/create the current image # resource into the FreeTextIdevice's TextAreaField, content. # the content text will have already been taken care of above, # including the ideal <img src=...> including resources path, # but still need the actual image resource: if imageResource_exists: # Not sure why this can't be imported up top, but it gives # ImportError: cannot import name GalleryImages, # so here it be: from exe.engine.galleryidevice import GalleryImage full_image_path = self.image.imageResource.path new_GalleryImage = GalleryImage(replacementIdev.content, \ self.caption, full_image_path, mkThumbnail=False) # and move it up to the position following this node! while ( self.parentNode.idevices.index(replacementIdev) \ > ( (self.parentNode.idevices.index(self) + 1))): replacementIdev.movePrev() # finally: delete THIS idevice itself, deleting it from the node self.delete() def getResourcesField(self, this_resource): """ implement the specific resource finding mechanism for this iDevice: """ # be warned that before upgrading, this iDevice field could not exist: if hasattr(self, 'image') and hasattr(self.image, 'imageResource'): if this_resource == self.image.imageResource: return self.image # be warned that before upgrading, this iDevice field could not exist: if hasattr(self, 'text') and hasattr(self.text, 'images'): for this_image in self.text.images: if hasattr(this_image, '_imageResource') \ and this_resource == this_image._imageResource: return self.text return None def getRichTextFields(self): """ Like getResourcesField(), a general helper to allow nodes to search through all of their fields without having to know the specifics of each iDevice type. """ fields_list = [] if hasattr(self, 'text'): fields_list.append(self.text) return fields_list
class ImageWithTextIdevice(Idevice): """ A ImageWithText Idevice is one built up from an image and free text. """ persistenceVersion = 6 def __init__(self, defaultImage = None): Idevice.__init__(self, x_(u"Image with Text"), x_(u"University of Auckland"), x_(u"""<p> The image with text iDevice can be used in a number of ways to support both the emotional (affective) and learning task (cognitive) dimensions of eXe content. </p><p> <b>Integrating visuals with verbal summaries</b> </p><p> Cognitive psychologists indicate that presenting learners with a representative image and corresponding verbal summary (that is presented simultaneously) can reduce cognitive load and enhance learning retention. This iDevice can be used to present an image (photograph, diagram or graphic) with a brief verbal summary covering the main points relating to the image. For example, if you were teaching the functions of a four-stroke combustion engine, you could have a visual for each of the four positions of the piston with a brief textual summary of the key aspects of each visual. </p>"""), u"", u"") self.emphasis = Idevice.NoEmphasis self.image = ImageField(x_(u"Image"), u"") self.image.idevice = self self.image.defaultImage = defaultImage self.text = TextAreaField(x_(u"Text"), x_("""Enter the text you wish to associate with the image.""")) self.text.idevice = self self.float = u"left" self.caption = u"" self._captionInstruc = x_(u"""Provide a caption for the image you have just inserted.""") captionInstruc = lateTranslate('captionInstruc') def upgradeToVersion1(self): """ Called to upgrade from 0.5 release """ self.float = u"left" def upgradeToVersion2(self): """ Called to upgrade from 0.6 release """ self.caption = u"" self.emphasis = Idevice.NoEmphasis def upgradeToVersion3(self): """ Upgrades v0.6 to v0.7. """ self.lastIdevice = False def upgradeToVersion4(self): """ Upgrades to exe v0.10 """ self._upgradeIdeviceToVersion1() def upgradeToVersion5(self): """ Upgrades to v0.12 """ log.debug("upgrade to version 5") self._upgradeIdeviceToVersion2() self.image._upgradeFieldToVersion2() def upgradeToVersion6(self): """ Called to upgrade from 0.13 release """ self._captionInstruc = x_(u"""Provide a caption for the image you have just inserted.""")
def addChance(self): newLevelImageField = ImageField(x_(u"chance"), u"") newLevelImageField.idevice = self self.chanceImageFields.append(newLevelImageField)
class Question(Persistable): """ A Case iDevice is built up of question and options. Each option can be rendered as an XHTML element """ persistenceVersion = 2 def __init__(self, idevice): """ Initialize """ self.questionTextArea = TextAreaField(u'', u'', u'') self.questionTextArea.idevice = idevice self.feedbackTextArea = Feedback2Field(u'', u'', u'') self.feedbackTextArea.idevice = idevice def setupImage(self, idevice): """ Creates our image field: no longer needed for new content since images are now embedded straight into the feedbackTextArea, but this routine is kept around for upgrade paths from old elps. """ self.image = ImageField( x_(u"Image"), x_(u"Choose an optional image to be shown to the student " "on completion of this question")) self.image.idevice = idevice self.image.defaultImage = idevice.defaultImage self.image.isFeedback = True def getResourcesField(self, this_resource): """ implement the specific resource finding mechanism for this iDevice's Question object: """ # be warned that before upgrading, this iDevice field could not exist: if hasattr(self, 'questionTextArea')\ and hasattr(self.questionTextArea, 'images'): for this_image in self.questionTextArea.images: if hasattr(this_image, '_imageResource') \ and this_resource == this_image._imageResource: return self.questionTextArea # be warned that before upgrading, this iDevice field could not exist: if hasattr(self, 'feedbackTextArea')\ and hasattr(self.feedbackTextArea, 'images'): for this_image in self.feedbackTextArea.images: if hasattr(this_image, '_imageResource') \ and this_resource == this_image._imageResource: return self.feedbackTextArea return None def getRichTextFields(self): """ Like getResourcesField(), a general helper to allow nodes to search through all of their fields without having to know the specifics of each iDevice type. """ fields_list = [] if hasattr(self, 'questionTextArea'): fields_list.append(self.questionTextArea) if hasattr(self, 'feedbackTextArea'): fields_list.append(self.feedbackTextArea) return fields_list def upgradeToVersion1(self): """ Upgrades to version 0.24 """ log.debug(u"Upgrading iDevice") self.image.isFeedback = True def upgradeToVersion2(self): pass def embedImageInFeedback(self): """ Actually do the Converting of each question's CaseStudyIdevice's image -> embedded in its feedback field, now that its TextField can hold embeddded images. """ new_content = "" # if no image resource even exists, then no need to continue: # is there a defined? if self.image is None or self.image.imageResource is None: return # likewise, only proceed if the image resource file is found: if not os.path.exists(self.image.imageResource.path) \ or not os.path.isfile(self.image.imageResource.path): return # and if it's just the default blank image, then nothing to do either: if self.image.isDefaultImage: return # get the current image resource info: new_content += "<img src=\"resources/" \ + self.image.imageResource.storageName + "\" " if self.image.height: new_content += "height=\"" + self.image.height + "\" " if self.image.width: new_content += "width=\"" + self.image.width + "\" " new_content += "/> \n" # prepend the new image content to any already existing feedback, # using its content WITH the resources path: new_content += "<BR>\n" new_content += self.feedbackTextArea.content_w_resourcePaths self.feedbackTextArea.content_w_resourcePaths = new_content # set that to its default content: self.feedbackTextArea.content = \ self.feedbackTextArea.content_w_resourcePaths # and massage its content for exporting without resource paths: self.feedbackTextArea.content_wo_resourcePaths = \ self.feedbackTextArea.MassageContentForRenderView( \ self.feedbackTextArea.content_w_resourcePaths) # in passing GalleryImage into feedbackTextArea, a FieldWithResources, # the field needs to be sure to have an updated parentNode, # courtesy of its idevice: self.feedbackTextArea.setParentNode() # (note: FieldWithResources *usually* take care of this automatically # within ProcessPreviewedImages(), but here in this upgrade # path, we are bypassing the general purpose ProcessPreviewed().) # Not sure why this can't be imported up top, but it gives # ImportError: cannot import name GalleryImages, # so here it be: from exe.engine.galleryidevice import GalleryImage full_image_path = self.image.imageResource.path # note: unapplicable caption set to '' in the 2nd parameter: new_GalleryImage = GalleryImage(self.feedbackTextArea, \ '', full_image_path, mkThumbnail=False) # finally, go ahead and clear out the current image object, # which is best (and most safely) done by setting it back to default: self.image.setDefaultImage()
class Question(Persistable): """ A Case iDevice is built up of question and options. Each option can be rendered as an XHTML element """ persistenceVersion = 1 def __init__(self, idevice): """ Initialize """ self.questionTextArea = TextAreaField(u'', u'', u'') self.questionTextArea.idevice = idevice self.feedbackTextArea = TextAreaField(u'', u'', u'') self.feedbackTextArea.idevice = idevice def setupImage(self, idevice): """ Creates our image field: no longer needed for new content since images are now embedded straight into the feedbackTextArea, but this routine is kept around for upgrade paths from old elps. """ self.image = ImageField(x_(u"Image"), x_(u"Choose an optional image to be shown to the student " "on completion of this question")) self.image.idevice = idevice self.image.defaultImage = idevice.defaultImage self.image.isFeedback = True def getResourcesField(self, this_resource): """ implement the specific resource finding mechanism for this iDevice's Question object: """ if hasattr(self, 'questionTextArea')\ and hasattr(self.questionTextArea, 'images'): for this_image in self.questionTextArea.images: if hasattr(this_image, '_imageResource') \ and this_resource == this_image._imageResource: return self.questionTextArea if hasattr(self, 'feedbackTextArea')\ and hasattr(self.feedbackTextArea, 'images'): for this_image in self.feedbackTextArea.images: if hasattr(this_image, '_imageResource') \ and this_resource == this_image._imageResource: return self.feedbackTextArea return None def getRichTextFields(self): """ Like getResourcesField(), a general helper to allow nodes to search through all of their fields without having to know the specifics of each iDevice type. """ fields_list = [] if hasattr(self, 'questionTextArea'): fields_list.append(self.questionTextArea) if hasattr(self, 'feedbackTextArea'): fields_list.append(self.feedbackTextArea) return fields_list def upgradeToVersion1(self): """ Upgrades to version 0.24 """ log.debug(u"Upgrading iDevice") self.image.isFeedback = True def embedImageInFeedback(self): """ Actually do the Converting of each question's CaseStudyIdevice's image -> embedded in its feedback field, now that its TextField can hold embeddded images. """ new_content = "" if self.image is None or self.image.imageResource is None: return if not os.path.exists(self.image.imageResource.path) \ or not os.path.isfile(self.image.imageResource.path): return if self.image.isDefaultImage: return new_content += "<img src=\"resources/" \ + self.image.imageResource.storageName + "\" " if self.image.height: new_content += "height=\"" + self.image.height + "\" " if self.image.width: new_content += "width=\"" + self.image.width + "\" " new_content += "/> \n" new_content += "<BR>\n" new_content += self.feedbackTextArea.content_w_resourcePaths self.feedbackTextArea.content_w_resourcePaths = new_content self.feedbackTextArea.content = \ self.feedbackTextArea.content_w_resourcePaths self.feedbackTextArea.content_wo_resourcePaths = \ self.feedbackTextArea.MassageContentForRenderView( \ self.feedbackTextArea.content_w_resourcePaths) self.feedbackTextArea.setParentNode() from exe.engine.galleryidevice import GalleryImage full_image_path = self.image.imageResource.path new_GalleryImage = GalleryImage(self.feedbackTextArea, \ '', full_image_path, mkThumbnail=False) self.image.setDefaultImage()
class ImageWithTextIdevice(Idevice): """ A ImageWithText Idevice is one built up from an image and free text. """ persistenceVersion = 8 def __init__(self, defaultImage = None): Idevice.__init__(self, x_(u"Image with Text"), x_(u"University of Auckland"), x_(u"""<p> The image with text iDevice can be used in a number of ways to support both the emotional (affective) and learning task (cognitive) dimensions of eXe content. </p><p> <b>Integrating visuals with verbal summaries</b> </p><p> Cognitive psychologists indicate that presenting learners with a representative image and corresponding verbal summary (that is presented simultaneously) can reduce cognitive load and enhance learning retention. This iDevice can be used to present an image (photograph, diagram or graphic) with a brief verbal summary covering the main points relating to the image. For example, if you were teaching the functions of a four-stroke combustion engine, you could have a visual for each of the four positions of the piston with a brief textual summary of the key aspects of each visual. </p>"""), u"", u"") self.emphasis = Idevice.NoEmphasis self.image = ImageField(x_(u"Image"), u"") self.image.idevice = self self.image.defaultImage = defaultImage self.text = TextAreaField(x_(u"Text"), x_("""Enter the text you wish to associate with the image.""")) self.text.idevice = self self.float = u"left" self.caption = u"" self._captionInstruc = x_(u"""Provide a caption for the image you have just inserted.""") captionInstruc = lateTranslate('captionInstruc') def upgradeToVersion1(self): """ Called to upgrade from 0.5 release """ self.float = u"left" def upgradeToVersion2(self): """ Called to upgrade from 0.6 release """ self.caption = u"" self.emphasis = Idevice.NoEmphasis def upgradeToVersion3(self): """ Upgrades v0.6 to v0.7. """ self.lastIdevice = False def upgradeToVersion4(self): """ Upgrades to exe v0.10 """ self._upgradeIdeviceToVersion1() def upgradeToVersion5(self): """ Upgrades to v0.12 """ log.debug("upgrade to version 5") self._upgradeIdeviceToVersion2() self.image._upgradeFieldToVersion2() def upgradeToVersion6(self): """ Called to upgrade from 0.13 release """ self._captionInstruc = x_(u"""Provide a caption for the image you have just inserted.""") def upgradeToVersion7(self): """ Called to upgrade to version 0.24 """ self.image.isFeedback = False def upgradeToVersion8(self): """ Converting ImageWithTextIdevice -> FreeTextIdevice, now that FreeText can hold embeddded images. BUT - due to the inconsistent loading of the objects via unpickling, since the resources aren't necessarily properly loaded and upgraded, NOR is the package necessarily, as it might not even have a list of resources yet, all of this conversion code must be done in an afterUpgradeHandler """ G.application.afterUpgradeHandlers.append(self.convertToFreeText) def convertToFreeText(self): """ Actually do the Converting of ImageWithTextIdevice -> FreeTextIdevice, now that FreeText can hold embeddded images. """ new_content = "" imageResource_exists = False if self.image.imageResource: self.image.imageResource.checksumCheck() if os.path.exists(self.image.imageResource.path) and \ os.path.isfile(self.image.imageResource.path): imageResource_exists = True else: log.warn("Couldn't find ImageWithText image when upgrading "\ + self.image.imageResource.storageName) if imageResource_exists: new_content += "<img src=\"resources/" \ + self.image.imageResource.storageName + "\" " if self.image.height: new_content += "height=\"" + self.image.height + "\" " if self.image.width: new_content += "width=\"" + self.image.width + "\" " new_content += "/> \n" elif self.image.imageResource: new_content += "<BR>\n[WARNING: missing image: " \ + self.image.imageResource.storageName + "]\n" if self.caption != "": new_content += "<BR>\n[" + self.caption + "]\n" if self.text.content != "": new_content += "<P>\n" + self.text.content + "\n" replacementIdev = FreeTextIdevice(new_content) replacementIdev.content.content_wo_resourcePaths = \ replacementIdev.content.MassageContentForRenderView( \ replacementIdev.content.content_w_resourcePaths) self.parentNode.addIdevice(replacementIdev) replacementIdev.content.setParentNode() if imageResource_exists: from exe.engine.galleryidevice import GalleryImage full_image_path = self.image.imageResource.path new_GalleryImage = GalleryImage(replacementIdev.content, \ self.caption, full_image_path, mkThumbnail=False) while ( self.parentNode.idevices.index(replacementIdev) \ > ( (self.parentNode.idevices.index(self) + 1))): replacementIdev.movePrev() self.delete() def getResourcesField(self, this_resource): """ implement the specific resource finding mechanism for this iDevice: """ if hasattr(self, 'image') and hasattr(self.image, 'imageResource'): if this_resource == self.image.imageResource: return self.image if hasattr(self, 'text') and hasattr(self.text, 'images'): for this_image in self.text.images: if hasattr(this_image, '_imageResource') \ and this_resource == this_image._imageResource: return self.text return None def getRichTextFields(self): """ Like getResourcesField(), a general helper to allow nodes to search through all of their fields without having to know the specifics of each iDevice type. """ fields_list = [] if hasattr(self, 'text'): fields_list.append(self.text) return fields_list