Appendix - 8 / 9 -
Note
The BREW RSSReader application tutorial demonstrates the fundamentals of handling HTTP and XML programming with SophiaFramework UNIVERSE.
The classes of interest here are the SFXHTTPConnection class ( for HTTP connections ) and the SFXAnsiString class ( for handling string data ).
* This appendix assumes readers have already gone through the HelloWorld tutorial and appendix.
RSS Reader Class Overview
RSS Reader Header File
RSSReader inherits from the SFRApplication class, meaning that this application will be using the GUI Framework.
It declares a variable of type RSSFeedList ( _feedList ) to manage the list of feeds, and an RSSFeedPtr ( _currentFeed ) that points to the current feed.
Functions to act upon these variables, RSSFeedListPtr GetRSSFeedList() and RSSFeedPtr GetCurrentFeed(), are declared along with a function to set the current feed ( SetCurrentFeed() ).
RSSReader Source File
The RSSReader constructor first validates the DIRECTORY_PATH with the SFXDirectory Exists() function, and creates it if it doesn't exist.
Data is then read from list.txt through the LoadFromFile() function of the RSSFeedList class. If the _feedList is not empty, the list's first item is saved in _currentFeed.
A new SoftKeyWindow ( softkey ) and a new MainWindow ( window ) are created, and assuming a non-empty _currentFeed, the MainWindow's title is set to the _currentFeed's title.
The GetRSSFeedList() function returns a reference to an instance of _feedList, while GetCurrentFeed() does the same for an instance of _currentFeed.
The SetCurrentFeed() function gets an instance of _currentFeed, and sets it to the value of its parameter currentFeed.
SubscriptionWindow Class Overview
SubscriptionWindow Header File
-
The SubscriptionWindow header file creates three SInt16 variables ( _displine, _cursor, _maxline and _move ) to keep track of displayed line information.
An SFXHTTPConection object _http, is declared to access the methods required to establish HTTP communication.
A variable for receiving data streams, SFXAnsiStreamReader _reader, and one for saving data, SFXAnsiString _xml, are also declared.
This class also contains functions to display error messages, update the main window and event handlers.
A callback function that begins and sets up the HTTP connection, CALLBACK_DECLARE_
SFXHTTPCONNECTION(ConnectCallback), is declared.So is a callback function for receiving data over the HTTP connection, CALLBACK_DECLARE_SFXBINARYSTREAMREADER(FetchCallback).
SubscriptionWindow Constructor
The SubscriptionWindow constructor starts off by registering the drawing and key handlers.
Strings associated to the three used soft keys are set by the SetSoftkey() function. The _displine variable is set to the value of the currently displayed line, and that value is then used to initialize the cursor position.
The value of _maxline is calculated by dividing the height of the screen by the font height, and then dividing the result by two ( line space ).
SubscriptionWindow Drawing Handler
OnRenderContent creates an SFXRectangle rectangle with the screen rectangle dimensions, and then sets its height to that of the font.
The SFRTitleWindow ContentHandler() is called to update the contents area.
Each line's color is then set. For the line currently pointed to by the cursor, both its forecolor and backcolor are set. All other lines first have their backcolor determined by the line number being odd or even, then only have their backcolor set to the determined color.
The rectangle representing each data line is filled with its respective backcolor, and if there are items remaining in the feed list, their titles are displayed.
The line currently being pointed to by the cursor, uses _currentRect as its rectangle. _currentRect is translated horizontally by calling the SubX() function, with _move as its argument. This is how horizontal scrolling is implemented.
If there is no title (_title.IsEmptyCString() ), then "[No Title]" is displayed.
The rectangle's y coordinates are incremented by the height for at the end of each line's processing. The rectangle is now modified to display the description of the item currently pointed to by the cursor.
SubscriptionWindow Key Handler
The key handler OnKey starts off by declaring an SFXRectangle rectangle, an SFRMultiDialogPtr pointer dialog, a ParamRec structure dialogParam, and a reference to the feed list RSSFeedListRef feedlist.
If the "Down" directional key is pressed, the handler first checks if the cursor is at the bottom of the screen ( _cursor = = _maxline - 1 ), and if so, the entire screen image is shifted down the page. Otherwise, the _cursor is incremented, which shifts only its position down the page.
If the "Up" directional key is pressed, the handler checks if the cursor is at the top of the screen ( _cursor = = 0 ), and if so, it will shift the entire screen image up the current page ( but only if there is data to be displayed up the page ). Else, the _cursor is decremented, which shifts its position up the displayed page.
In all cases, InvalidateContent() must be called for the changes to be visible on screen. The UpdateMainWindow() function is called at the end of each case to transfer the new data to the MainWindow and redraw it.
If soft key "1" or the "7" key are pressed, a new SFRMultiDialog is created with the attributes set in dialogParam and referenced to dialog. A dialog handler, StartConnection, is registered for dialog.
Pressing the "Left" or "Right" directional keys, respectively increments or decrements the variable _move ( which is used as a scroll factor ).
If the "Clear" or "Select" keys are pressed, the window is closed by invoking an SREVT_RESPONDER_TERMINATE event and the MainWindow's soft keys are set.
If the "Soft Key 2" or the "9" key are pressed, a new InputWindow is created, and its soft keys set.
Steps to Add a Feed to the Feed List
Update Main Window Function
The UpdateMainWindow() function checks to see if there are any feeds remaining to be displayed, and if there is, it sets the current feed to the value of the cursor plus that of the displayed line head ( SetCurrentFeed(feedList[_displine + _cursor]) ).
It also sets the _title of the new feed. When there are no feeds left to be displayed, the current feed is set to NULL and the title is empty ( EmptyInstance() ).
The updated information is copied to the MainWindow parameters, and the screen is redrawn.
Dialog Handler
-
The dialog handler, StartConnection, handles two cases: either an "Yes" button press, or a "No" button press.
In the first case, the SFXHTTPConnection Open() function sets the HTTP state to open, creates a new instance of SFBWeb, sets the default HTTP method and requests an HTTP writer. Then the SFXHTTPConnection SetMethod() function is used to set the HTTP method to "Get".
The actual connection is made by the Connect() function which takes the URL string and the HTTP connection callback function ( ConnectCallback ) as its parameters.
A connectingDialog is created to display the message "Connecting..." and a handler is registered for it. If any errors occurred, the DisplayErrorDialog() is called.
When the "No" button is pressed, the soft keys are set and nothing is done.
Display Error Dialog
The DisplayErrorDialog() function closes the foremost window and checks to see if the multi dialog still exists. If it does exist, it is terminated by invoking a SREVT_RESPONDER_TERMINATE upon it. And if it is empty, then an instance for a message dialog is obtained.
A new SFRMessageDialog displaying the string "Connection Failed" is created and a SREVT_RESPONDER_RENDER event is invoked to update the screen.
Connection Notification Callback
The macro CALLBACK_IMPLEMENT_SFXHTTPCONNECTION's arguments are the class name ( SubscriptionWindow ), the Callback function ( ConnectCallback ) and the error value ( error ).
If there are no errors ( error = = SFERR_NO_ERROR ), a stream for reading data is obtained through the SFXHTTPConnection GetStreamReader() function and referenced to &_reader. The data is then received by calling the FetchCallback function.
If there were any errors, the DisplayErrorDialog() function is called.
Data Reception Callback
The FetchCallback function reads the next string through the ReadSFXAnsiString() function, and appends it to the end of the string for saving data _xml.
The reception is deemed over when the End() function returns true, and the GetReadableSize() is equal to 0. At this time, the HTTP connection is closed by called the SFXHTTPConnection Close() function, the feed date is set through the SFXDate::CurrentDate() function, and after the received string has been parsed ( Parse(_xml ) ), the string is freed and its size set to 0 by the SFXAnsiString Close() function.
If there were no errors, both the feed and the _feedList are saved to file by the SaveToFile() function. The front window is terminated, the soft keys set, and the screen redrawn.
If there remains data to be received, the FetchCallback is called once again. And in case any errors were detected, the DisplayErrorDialog() function is called.