Appendix - 9 / 9 -
RSSData Class Overview
RSSData Header File
The RSSData header file is where all the information related to using the RSS format is defined.
It first declares a struct for a single RSS item, RSSItem. Each RSS item consists of a title, description, topic, date and flag to signal whether the item has been read yet.
Next, a class for a single RSS feed is declared. Objects of RSSFeed have a _title, a _url, _date, _filename, and _itemList.
This class also has member functions to perform standard feed operations such as Parse(), SaveToFile(), GetItem(), etc.
The last class declared here is the RSSFeedList class. It consists of an SFXArray _feedArray cast as an RSSFeedPtr where the RSS feeds are saved, and member functions to manipulate that array ( ADD(), GetSize(), etc ).
RSSData Constructors and Destructors
The equal operator ( = = ) is overloaded for the case of two RSSItem arguments. It returns true, if both RSS items titles and dates are the same.
The constructors of both RSSItem and RSSFeed simply initialize the attributes of each respective type.
The destructor of RSSFeed must cycle through each item in the feed list using an Iterator itor and delete them one by one.
The RSSFeedList destructor iterates through the _feedArray, and deletes each feed along the way.
RSSFeed Parse Function
-
The Parse() function is where the XML document is parsed. Parsing is the transforming of input text into a data structure, usually a tree, that is suitable for processing and is of the expected hierarchical form.
The SFXXMLDOMParser Parse() is first called through the object parser, to analyze the XML document.
If no errors occur, the root of the parsed tree structure is obtained by the GetDocument() function and a reference to the first child node , obtained by the SFXXMLNode GetFirstChild() function, is assigned to the SFXXMLNodePtr child.
If the first child is successfully obtained, its immediate children are examined to see if they contain a "title" tag. When found, the title is saved in the SFXAnsiString temp.
Each sibling of the current node is also searched to see if it corresponds to an "item" tag, and if it does, its immediate children are examined to see if they contain either a "title" tag, "description" tag, "dc: subject" tag or "dc: date" tag.
In all cases except "date", the text of the tag is stored in temp and after being converted from UTF8 to ShistJIS, is saved in its respective SFXAnsiString variable.
A string representing a date, must be parsed into the proper date format by the SFXDate parser date.Parse().
After all tags have been processed, a new RSSItem is created with the processed tags. If the item is not duplicated ( !Find(*item) ), the item is inserted into the _itemList.
Save Item to File
After obtaining a temporary path for saving from the SFXFile::GetTemporaryPath() function, the SaveToFile() function opens the temporary path ( OpenReadWrite(temp) ), gets a writing stream ( GetStreamWriter(4096, &writer) ) and iterates through the data, writing it into the file.
While there are still items to write onto file, they are written in a format where each line displays an RSS item with its attributes ( title<>description<>topic... ).
The SFXAnsiStringStreamWriter Flush() function must be called to actually write the data onto file and the file is closed by the SFXFile Close() function.
If there were no errors, the file at the path temp, is renamed to the filename.
Load Item From File
The LoadFromFile() function, first obtains the file's size ( SFXFile::GetSize(path, &size) ), opens the file for reading only ( OpenReadOnly(path) ) and gets a reading stream ( GetStreamReader(size + 1, &reader) ).
The file is read by the SFXAnsiStringStreamReader Fetch() function, and its contents saved in the SFXAnsiString string.
The SFXAnsiString IndexOf() function is used to get the index of each "<>" and these indexes are saved in the Sint32 variables c2 to c6. Those variables are then used as arguments to the SFXAnsiString Substring function, such that each RSSItem attribute is obtained from the string, and used as arguments to the RSSItem constructor.
Once the item is appended to the _itemList, it is deleted.
Does RSS Item Exist in List
The Find() function gets an Iterator itor for the _itemList, and iterates through all the items until it finds a match for the item in its argument.
If item is matched it returns true, otherwise, false is returned.
Add RSS Feed to FeedList
To add a feed to the _feedArray, the Add() function first constructs the feed's filename from its _title and _url.
This name is prevented from overlapping with another file's name by adding to it a random number rand, generated by the SFXLCGRandom class.
The filename is then made random by use of the SFXMailUtility GetMD5() function. MD5 is a well known cryptographic hash function often used to check file integrity and for security functions.
Finally the feed's file name is set, and it is appended to the _feedArray.
Save Feed to File
See "Save Item to File".
Load Feed from File
See "Load Item from File".
MainWindow Class Overview
MainWindow.hpp declares three SInt16 variables representing the head of lines to display ( _displine ), the cursor position ( _cursor ) and the number of lines that can be displayed ( _maxline ). It also declares a function to set the soft key strings, as well as key and drawing handlers.
Set Soft Key Labels
The SetSoftkey() function gets an instance of the SoftkeyWindow, and sets the strings associated to each soft key.
Drawing Handler
-
The MainWindow's drawing handler OnRenderContent, uses almost the exact same rendering techniques as the SubscriptionWindow's drawing handler.
The difference is that the SubscriptionWindow was drawing the feed list, whereas here it is the items of a particular feed that are being drawn.
In the MainWindow, both an item's title and its description can be scrolled. The item title is scrolled horizontally using the _moveX variable, while the description is scrolled using the _moveY variable.
Notice the drawing order is the inverse of that found in the SubscriptionWindow drawing handler; this is done to accommodate scrolling.
If an item's alreadyRead flag is FALSE, it is rendered with a colored font. If the item's flag is TRUE, then it is rendered in standard black font.
A solid SFXRectangle is used to separate the title and description portions of the MainWindow, as opposed to the two lines used in the SubscriptionWindow class.
Key Handler
-
MainWindow's key handler OnKey, also uses the same techniques as the key handler of the SubscriptionWindow. The differences are in the implementations of the soft key 2 and the "Select" key.
Pressing soft key 2 ( or the "9" key ), creates a new SubscriptionWindow.
Pressing the "Select" key, sets the selected feed to current, and then sets the current item's alreadyRead flag to TRUE.
InvalidateContent() is called to update the screen.
SoftkeyWindow Class Overview
SoftkeyWindow Header File
SoftKeyWindow.hpp starts off by defining a new attribute name, which associates the string "Soft" to SOFTKEY.
Three SFXAnsiString variables are declared to save the strings associated to the _left, _center and _right soft keys.
A function to return an instance of SoftkeyWindow, GetInstance() is declared, along with a function to return the height and one to set the three soft key strings.
SoftkeyWindow Source Code
The SoftkeyWindow constructor calls the SFRPlainWindow constructor to create a plain window with plain window behavior and SOFTKEY attributes. It also registers the drawing handler.
The GetInstance() function is used to return a reference to the foremost window that has SOFTKEY attribute.
The GetHeight() function simply returns the SoftkeyWindow's height, which consists of the font height plus the SOFTKEY_MARGIN.
The Set() function updates the three SFXAnsiStrings associated to the soft keys, and redraws the screen with the InvalidateContent() function.
SoftkeyWindow Drawing Handler
The drawing handler OnRenderContent, defines three colors with the AtomRectConst structures of the SFXRGBColor class.
It fills a rectangle representing the entire soft key area with the outer color, then divides the rectangle's width by 3 and deflates it with the Deflate(1, 1) function.
The modified rectangle is now filled with the inner color; thus obtaining a rectangle with a frame.
The strings associated with each button are drawn in their respective rectangles using the DrawText() function.
InputWindow Class Overview
InputWindow Header File
The InputWindow header file declares two SFREditboxControlPtr pointers to point to the title and url input boxes in the input window.
It then declares a function to set the soft keys ( SetSoftkey() ) and declares the handler functions.
InputWindow Constructor
-
An SFXRectangle object, rectangle, is used throughout this constructor to input the coordinates of the edit boxes. The label for the first edit box is made by the SFRLabelControl constructor, using rectangle as an argument.
The coordinates of rectangle are then modified and used as an argument to the SFREditboxControlPtr( ) constructor which creates the first edit box control. The other arguments of this constructor are an SFRResponder pointer and an SFXWideString object which contains data defining behavior, attributes and a wide string for initialization. This process is repeated for both edit box controls.
The OkButton and CancelButton buttons are created using the SFRButtonControl constructor and need only a responder pointer, rectangle and label to be specified.
The max size of entries for each text control is set after error checking ( the focus is set to the head by default ). Handlers for each button control are also registered.
The event diagram to the left starts off in the SubscriptionWindow, and creates the InputWindow when "soft key 2" is pressed. The next two events are down Key presses, and the last event is the pressing of the "Register" button.
The SelectHandler of the SFRResponder class is registered to handle all Select key events. This is a SophiaFramework UNIVERSE handler that needs not be defined, and automatically gives focus to the appropriate UI object when the Select key is pressed.
InputWindow Event Handlers
Key Handler
A clear key press can be handled in two ways. If any of the SFREditboxControls are being targeted, then the clear key press cancels the targeting.
If no edit boxes are being targeted, then the clear key terminates the current window by invoking an SREVT_RESPONDER_TERMINATE event.
An "Up key" press moves the focus to the responder above by calling the FocusUp( ) function, while a "Down key" press moves the focus down by way of the FocusDown( ) function.
Same thing for "Left" and "Right" key presses.
These functions, inherited from the SFRResponder class, shift focus respectively to the responder that is in the selected direction.
Ok Button Handler
-
When the "Register" button is pressed, the title and URL entered in the two edit box controls are obtained by the SFREditboxControl GetText() function, and saved as a new RSSFeed.
If the new feed can be added to the feed list, then it is deleted afterwards. If it cannot be added, then it is saved to file by the SaveToFile() function.
A message
dialog displaying the string "Registered" is created and a handler ( EndHandler ) is registered for it.The soft keys are set through the SubscriptionWindow's SetSoftKeys() function.
Cancel Button Handler
The handler for the "Cancel" button, CancelButtonHandler, simply calls the SubscriptionWindow's SetSoftKeys() function, and terminates the InputWindow by invoking a SREVT_RESPONDER_TERMINATE event.
Handler for Ok Dialog Button
The EndHandler first calls SubscriptionWindow's SetSoftKeys() function, and then proceeds to terminate the InputWindow, and the dialog by invoking SREVT_RESPONDER_TERMINATE events on each.