(* * Module Authoring defines the operations needed to perform Authoring * within a Lesson in CSTutor. * *) module Authoring; from LessonDB import Lesson, InfoNode, Node, NodeProperties, LessonProperties, CodeSegment, LinkPath, NavLink, Color, Red, Green, Blue, NodeItem, Region, FontStyle, Image, QuizNode, NextNode, PrevNode, NodeTitle, LessonTitle, NodeSummary, Author, DateMade, Text, CodeTextArea, StraightLine, CurveLine, Rectangle, Oval, Question, ScoreTable, URL; from File import File, FileName; operation AddInfoNode is inputs: lesson:Lesson; outputs: node:InfoNode, lesson':Lesson; description: (* Adding a node to an empty lesson requires only the lesson you are working on. A new empty node is returned to you. This is the first thing an instructor must do when creating a lesson. *); precondition: (* no nodes in the lesson. *) (lesson.node_count = 0); postcondition: (* the lesson contains the new node, node_count = 1 *) (node in lesson'.info_node) and (lesson.node_count = 1); end AddInfoNode; -- if nodes exsist in the lesson operation AddInfoNode is inputs: old_node:InfoNode, lesson:Lesson; outputs: new_node:Node; description: (* Adding an info_node to the current lesson requires a InfoNode and the Lesson it will be contained in. A new Lesson is returned that contains the new InfoNode as the last node in the lesson. *); precondition: (* The max number of nodes has not been exceeded *) (lesson.node_count < (lesson.node_limit-1)); postcondition: (* The node is the last in the lesson, the lesson gets the last node being worked on in the editor added to the lesson. *) (lesson.node_count = lesson.node_count + 1) and (new_node = nil) and (* updates links *) (new_node in lesson.info_node); end AddInfoNode; operation AddQuizNode is inputs: quiz_node:Node, lesson:Lesson; outputs: new_node:QuizNode; description: (* Adding an quiz_node to the current lesson requires a QuizNode and the Lesson it will be contained in. A new Lesson is returned that contains the new QuizNode as the last node in the lesson. *); precondition: (* The max number of nodes has not been exceeded *) (lesson.node_count < (lesson.node_limit-1)); postcondition: (* The node is the last in the lesson, the lesson is 100% intact and unchanged except for the addition of the quiz_node. *) (lesson.node_count = lesson.node_count + 1) and (new_node = nil) and (* updates links *) (new_node in lesson.quiz_node); end AddQuizNode; operation DeleteNode is inputs: node:Node, lesson:Lesson; outputs: lesson':Lesson, node':Node; description: (* Deleting any node requires the node and the lesson. The lesson is returned without the selected node. *); preconditions: (* a node is in the current lesson *) (exists(node in lesson.info_node) node = nil) or (exists(node in lesson.quiz_node) node = nil); postconditions: (* The remaining nodes in the lesson fall linearly into place. The lesson is 100% intact and unchanged except for the removal of the quiz_node. *) (lesson.node_count = lesson.node_count - 1) and (* update links *) (node'.prev_node = node.prev_node) and (node'.nxt_node = node.nxt_node) and (lesson' = lesson); end DeleteNode; operation EditNodeProperties is inputs: node:Node, old_properties:NodeProperties, new_properties:NodeProperties; outputs: node':Node; precondition: (* make sure the fields being edit are not empty *) (old_properties.title != nil) and (old_properties.summary != nil) and (new_properties.title != nil) and (new_properties.summary != nil); postcondition: (* The pertinent data edited by the author: title, summary and position are contained in the Node, and this update is reflected in the Lesson. *) (old_properties = new_properties) and (node' = node); description: (* Editing the NodeProperties requires the Node you are editing information on, its Lesson and its pertinent subdata. A new Lesson is returned that contains the new nodes data. *); end EditNodeProperties; -- End of Node Functions -- Lesson Functions operation EditLessonProperties is inputs: lesson:Lesson, old_properties:LessonProperties, new_properties:LessonProperties; outputs: lesson':Lesson; precondition: (* make sure the fields are not empty *) (lesson != nil) and (old_properties.author != nil) and (old_properties.made != nil) and (old_properties.title != nil) and (new_properties.author != nil) and (new_properties.made != nil) and (new_properties.title != nil); postcondition: (* The pertinent data edited by the author are contained in the Lesson, and this update is reflected in the Lesson. *) (old_properties = new_properties) and (lesson' = lesson); description: (* Editing the LessonProperties requires the Lesson you are editing and its pertinent subdata. A new Lesson is returned that contains the new lesson properties. *); end EditLessonProperties; -- NodeTool Functions operation addText is inputs: node:Node, text:Text; outputs: node':Node; description: (* Adding Text to a node requires the Lesson, the node you are editing and all the data need for the Text to be in the node. A new node is returned to the user with the updates, the lesson is also updated. *); preconditions: (* the maximum number of items in a node has not been reached *); postconditions: (* The node you were working on is updated to reflect the changes the author has done. Also the lesson is updated to reflect these changes. *); end addText; operation editText is inputs: node:Node, text:Text; outputs: node':Node; description: (* Adding Text to a node requires the Lesson, the node you are editing and all the data need for the Text to be in the node. A new node is returned to the user with the updates, the lesson is also updated. *); preconditions: (* the maximum number of items in a node has not been reached *); postconditions: (* The node you were working on is updated to reflect the changes the author has done. Also the lesson is updated to reflect these changes. *); end editText; operation editFont is inputs: node:Node, text:Text; outputs: node':Node; description: (* Adding Text to a node requires the Lesson, the node you are editing and all the data need for the Text to be in the node. A new node is returned to the user with the updates, the lesson is also updated. *); preconditions: (* the maximum number of items in a node has not been reached *); postconditions: (* The node you were working on is updated to reflect the changes the author has done. Also the lesson is updated to reflect these changes. *); end editFont; operation addCodeSegment is inputs: node:Node, code_object:CodeSegment; outputs: node':Node; description: (* Adding a codeseg to a node requires the Lesson, the node you are editing and all the data need for the codeseg to be in the node. A new node is returned to the user with the codeseg object, the lesson is also updated. *); preconditions: (* the maximum number of items in a node has not been reached *); postconditions: (* The node you were working on is updated to reflect the changes the author has done. Also the lesson is updated to reflect these changes. *); end addCodeSegment; operation editCode is inputs: node:Node, text:CodeTextArea; outputs: node':Node; description: (* editing code to a node requires the Lesson, the node you are editing and all the data needed for the code to be in the node. A new node is returned to the user with the updates, the lesson is also updated. *); preconditions: (* the maximum number of items in a node has not been reached *); postconditions: (* The node you were working on is updated to reflect the changes the author has done. Also the lesson is updated to reflect these changes. *); end editCode; -- NavLink type 1: URL given operation addNavLink is inputs: node:Node, url:URL; outputs: node':Node, navlink:NavLink; description: (* Adding a url navlink to a node requires the Lesson, the node you are editing and all the data need for the url to be in the node. A new node is returned to the user with the updates, the lesson is also updated. *); preconditions: (* the maximum number of items in a node has not been reached *); postconditions: (* The node you were working on is updated to reflect the changes the author has done. Also the lesson is updated to reflect these changes. *); end addNavLink; -- this operation is here from the Enter URL window...that operation has be modeled. -- and get lesson path for a node not in the lesson also has to be modeled, this -- action is done using a view of the Lesson Explorer. operation GetURL(url:string)->URL; operation GetLessonPath(path:string)->string; operation addNavLink is inputs: node:Node, lessonPath:LinkPath, title:LessonTitle; outputs: node':Node, navlink:NavLink; description: (* Adding a navlink button requires information of the linkpath and the lessons title (to be placed on top of the button. *); preconditions: (* the maximum number of nodes has not been reached. CSTutor does not check that lessons exist after a navlink is inserted. if they don't exist an error is thrown. *); postconditions: (* The navlink object is in the node and selected. *); end addNavLink; operation InsertImage is inputs: node:Node, lesson:Lesson, image:Image; outputs: node':Node; preconditions: (* the maximum number of items in a node has not been reached and the image is supported by CSTutor *) (node.item_count < ( node.item_limit-1 )) and canRead(image); postconditions: (* The node you were working on is updated to reflect the changes the author has done. The image. *) (node' in lesson.info_node) and (lesson.node_count = lesson.node_count + 1); description: (* Adding an image to a node requires the Lesson, the node you are editing and the file of the image to be in the node. A new node is returned to the user with the updates, the lesson is also updated. *); end InsertImage; operation addStraightLine is inputs: node:Node, line:StraightLine; outputs: node':Node; description: (* adding a line *); preconditions: (* The max number of items in a node has not been exceeded or met. *) (node.item_count < (node.item_limit - 1)); postconditions: (* The selected items' bounding box appears. *) (node.item_count = node.item_count + 1) and (node' = node); end addStraightLine; operation addCurveLine is inputs: node: Node, line:CurveLine, lesson:Lesson; outputs: node':InfoNode; description: (* adding a curveline. *); preconditions: (* The max number of items in a node has not been exceeded or met. *) (node.item_count < (node.item_count - 1)); postconditions: (* The selected item appears in node *) (node.item_count = node.item_count + 1) and (node'.item_count = node.item_count) and (node' in lesson.info_node); end addCurveLine; operation addRectangle is inputs: node:Node, rectangle:Rectangle; outputs: node':Node; description: (* adding a rectangle outline *); preconditions: (* the max number of items in a node has not been exceeded or met. *); postconditions: (* the rectangle is in the node, it is update and so is the lesson. *); end addRectangle; operation addOval is inputs: node:Node, oval:Oval; outputs: node':Node; description: (* adds a oval outline. *); pre: (* the max number of items in a node has not been exceeded or met. *); post: (* the rectangle is in the node, it is update and so is the lesson. *); end addOval; -- Support Functions -- For all items except Image, and Text. operation modifyColor is inputs: color:Color; outputs: color': Color; description: (* Changing the color requires the current color and Item being edited, then that item is returned with the new color. *); preconditions: (* the item has an editable color. *); postconditions: (* The node you were working on is updated to reflect the changes the author has done. Also the lesson is updated to reflect these changes. *); end ChooseNewColor; operation getRGB(red:Red, blue:Blue, green:Green)->Color; (* this is the color function when a user views the color wheel and click on the mouse, they get a color composed of a rgb. *) operation SelectItem is inputs: item: NodeItem, node:Node; outputs: is_selected':boolean; description: (* selecting an item. *); preconditions: (* There are items in the Node. *); postconditions: (* The selected items' bounding box appears. *); end SelectItem; -- support functions for Select/Move/Resize tool. operation MoveItem is inputs: item: NodeItem, node:Node; outputs: region':Region, node':Node; description: (* moving an item *); preconditions: (* There is at least one item in the node and it is selected. *); postconditions: (* the items region (x1, y1, x2, y2) values are changed. 'area' is unchanged. *); end MoveItem; operation ResizeItem is inputs: item:NodeItem, region:Region, node:Node; outputs: region':Region, node':Node; description: (* Resizing an Item. *); preconditions: (* An item is selected. *); postconditions: (* The item (x1, y1) position stay the same, it's area variable is changed. *); end ResizeItem; operation changeFontStyle is inputs: text:string, begin_index:integer, end_index:integer, old_style:FontStyle, new_style:FontStyle; outputs: text':string, old_style':FontStyle; description: (* changing the font style *); preconditions: (* The text field is selected *); postconditions: (* The selected text field will show the desired changes *); end changeFontStyle; operation changeFontType is inputs: text:string, begin_index:integer, end_index:integer, old_style:FontStyle, new_style:FontStyle; outputs: text':string, old_style':FontStyle; description: (* changing the font type *); preconditions: (* The text field is selected *); postconditions: (* The selected text field will show the desired changes *); end changeFontType; operation changeFontSize is inputs: text:string, begin_index:integer, end_index:integer, old_style:FontStyle, new_style:FontStyle; outputs: text':string, old_style':FontStyle; description: (* changing the font size *); preconditions: (* The text field is selected *); postconditions: (* The selected text field will show the desired changes *); end changeFontSize; operation addBackground is inputs: node:Node, color:Color, image:Image; outputs: node':Node; preconditions: (* a node is opened *); postconditions: (* The node you were working on is updated to reflect the changes the author has done. *); description: (* Adding a background to a node requires the Lesson, the node you are editing and the file of the image to be in the node or a color. A new node is returned to the user with the updates, the lesson is also updated. *); end addBackground; -- QuizNode Funtions operation AddQuestion is inputs: node:QuizNode, question:Question, lesson:Lesson; outputs: node':QuizNode; preconditions: (* a node is opened and is a quiz node *) node in lesson.quiz_node; postconditions: (* The node you were working on is updated to reflect the changes the author has done. *) (node' = node); description: (* Adding a question in a node requires the node you are editing. A new node is returned to the user with the updates, node is also updated. *); end AddQuestion; operation RemoveQuestion is inputs: node:QuizNode, lesson:Lesson; outputs: node':QuizNode; preconditions: (* a node is opened and is a quiz node *) node in lesson.quiz_node; postconditions: (* The node you were working on is updated to reflect the changes the author has done. *) (node.question = nil) and (node' = node); description: (* Removing a question in a node requires the node you are editing. A new node is returned to the user with the updates. *); end RemoveQuestion; operation addScoreTable is inputs: node:QuizNode, lesson:Lesson; outputs: node':QuizNode; preconditions: (* a node is opened and is a quiz node *) node in lesson.quiz_node; postconditions: (* The node you were working on is updated to reflect the changes the author has done. *) (node'.table = node.table); description: (* Adding a background to a node requires the Lesson, the node you are editing and the file of the image to be in the node or a color. A new node is returned to the user with the updates, the lesson is also updated. *); end addScoreTable; -- auxillury functions used by CSTutor behind the scenes. function canRead(image:Image)->boolean = ( -- checking the type of file. -- where '.name' is a component of the obj File in File.rsl -- that is the filename of the file, checking the last chars. (image.name = ".jpg") or (image.name = ".gif"); ) end; end Authoring;