Changed zouba directory heirarchy.
[ptas] / zouba / misc / rss / RSSReader.js
diff --git a/zouba/misc/rss/RSSReader.js b/zouba/misc/rss/RSSReader.js
new file mode 100644 (file)
index 0000000..586b9d6
--- /dev/null
@@ -0,0 +1,418 @@
+///////////////////////////////////////////////////////////////////////////////\r
+// RSS Reader example widget that demonstrates use of the WRTKit UI toolkit\r
+// in a real-world widget.\r
+\r
+// Feed update frequency.\r
+var updateFrequencyOptions = [\r
+    { value: -1, text: "never" },\r
+    { value: (1000 * 60 * 5), text: "every 5 min" },\r
+    { value: (1000 * 60 * 15), text: "every 15 min" },\r
+    { value: (1000 * 60 * 60), text: "every 60 min" },\r
+];\r
+\r
+// Feed update broker.\r
+var feedUpdateBroker = null;\r
+\r
+// Reference to current feed items controls.\r
+var feedItemControls = [];\r
+\r
+// Feed item control pool.\r
+var feedItemControlPool = [];\r
+\r
+// Time when the feed was last modified.\r
+var feedLastModified = null;\r
+\r
+// Flag that tracks if a feed update is commanded or automatic.\r
+var feedUpdateCommanded = false;\r
+\r
+// Reference to the WRTKit user interface manager and views.\r
+var uiManager;\r
+var mainView;\r
+var settingsView;\r
+\r
+// Reference to settings controls.\r
+var feedNameText;\r
+var feedUrlText;\r
+var feedSelection;\r
+var feedUpdateFrequencySelection;\r
+var settingsSaveButton;\r
+var settingsCancelButton;\r
+\r
+// Constants for menu item identifiers.\r
+var MENU_ITEM_SETTINGS = 0;\r
+var MENU_ITEM_REFRESH = 1;\r
+var MENU_ITEM_ABOUT = 2;\r
+\r
+// Feed update timer identifier.\r
+var updateTimerId = null;\r
+\r
+//About menu lable\r
+var aboutLabel;\r
+\r
+// Feed name, URL and update frequency (in milliseconds; -1 if no auto update).\r
+var feedName = "CNN Top Stories";\r
+var feedURL = "http://rss.cnn.com/rss/cnn_topstories.rss";\r
+//var feedURL = "feed.xml";\r
+var feedUpdateFrequency = -1;\r
+\r
+// Next scheduled update time; -1 if never.\r
+var feedUpdateTime = -1;\r
+\r
+// Called from the onload event handler to initialize the widget.\r
+function init() {\r
+    if (window.widget) {\r
+        // set tab-navigation mode and show softkeys\r
+        widget.setNavigationEnabled(false);\r
+        window.menu.showSoftkeys();\r
+        \r
+        // create menu\r
+        var settingsMenuItem = new MenuItem("Settings", MENU_ITEM_SETTINGS);\r
+        settingsMenuItem.onSelect = menuItemSelected;\r
+        menu.append(settingsMenuItem);\r
+        var refreshMenuItem = new MenuItem("Refresh", MENU_ITEM_REFRESH);\r
+        refreshMenuItem.onSelect = menuItemSelected;\r
+        menu.append(refreshMenuItem);\r
+               var aboutMenuItem = new MenuItem("About", MENU_ITEM_ABOUT);\r
+               aboutMenuItem.onSelect = menuItemSelected;\r
+               menu.append(aboutMenuItem);\r
+    }\r
+    \r
+       // load preferences\r
+       loadPreferences();\r
+\r
+    // create UI manager\r
+    uiManager = new UIManager();\r
+    \r
+    // create main view\r
+    mainView = new ListView();\r
+    \r
+    // create settings view\r
+    settingsView = new ListView(null, "Settings");\r
+       \r
+       //Create about view\r
+       aboutView = new ListView(null, "RSS Reader");\r
+    \r
+    // feed name control\r
+    feedNameText = new TextField('feedNameText', "Feed name", feedName);\r
+    settingsView.addControl(feedNameText);\r
+       \r
+    // feed url control\r
+    feedUrlText = new TextField('feedUrlText', "Feed URL", feedURL);\r
+    settingsView.addControl(feedUrlText);\r
+\r
+       // About lable control\r
+       aboutLabel = new Label();\r
+       aboutView.addControl(aboutLabel);\r
+       \r
+    // feed update frequency selection control\r
+    feedUpdateFrequencySelection = new SelectionList(null, "Check for updates", updateFrequencyOptions);\r
+    settingsView.addControl(feedUpdateFrequencySelection);\r
+    \r
+    // save settings button\r
+    settingsSaveButton = new FormButton(null, "Save");\r
+    settingsSaveButton.addEventListener("ActionPerformed", saveSettingsClicked);\r
+    settingsView.addControl(settingsSaveButton);\r
+    \r
+    // cancel settings button\r
+    settingsCancelButton = new FormButton(null, "Cancel");\r
+    settingsCancelButton.addEventListener("ActionPerformed", showMainView);\r
+    settingsView.addControl(settingsCancelButton);\r
+    \r
+    // display the main view if a feed has been configured\r
+    // otherwise show the settings view\r
+       if (feedURL != null) {\r
+        showMainView();\r
+        updateFeed();\r
+    } else {\r
+        showSettings();\r
+    }\r
+    // start feed update timer (called once every second)\r
+    updateTimerId = setInterval(updateFeedTimerFunc, 1000);\r
+}\r
+\r
+// Callback for when menu items are selected.\r
+function menuItemSelected(id) {\r
+    switch (id) {\r
+        case MENU_ITEM_SETTINGS:\r
+            showSettings();\r
+            break;\r
+        case MENU_ITEM_REFRESH:\r
+            updateFeed();\r
+            break;\r
+               case MENU_ITEM_ABOUT:\r
+                       showAboutView();\r
+                       break;\r
+    }\r
+}\r
+\r
+// Loads widget preferences.\r
+function loadPreferences() {\r
+    if (window.widget) {\r
+        // read feed URL, name and update frequency from the widget settings\r
+               \r
+               if (typeof widget.preferenceForKey("FeedURL") != 'undefined' && typeof widget.preferenceForKey("FeedName") != 'undefined') {\r
+                       feedURL = widget.preferenceForKey("FeedURL");\r
+                       feedName = widget.preferenceForKey("FeedName");\r
+                       var feedUpdateFrequencyStr = widget.preferenceForKey("FeedUpdateFrequency");\r
+                       feedUpdateFrequency = (feedUpdateFrequencyStr == null) ? -1 : parseInt(feedUpdateFrequencyStr);\r
+               }\r
+    }\r
+}\r
+\r
+// Loads widget preferences.\r
+function savePreferences() {\r
+    if (window.widget) {\r
+        // save settings in widget preferences store\r
+        widget.setPreferenceForKey(feedURL, "FeedURL");\r
+        widget.setPreferenceForKey(feedName, "FeedName");\r
+        widget.setPreferenceForKey(feedUpdateFrequency.toString(), "FeedUpdateFrequency");\r
+    }\r
+}\r
+\r
+// Callback for settings view save button.\r
+function saveSettingsClicked() {\r
+    // remember old URL\r
+    var oldURL = feedURL;\r
+    \r
+    // update feed name and URL\r
+    var selectedFeed = feedUrlText.getText();\r
+\r
+    if (selectedFeed != null) {\r
+        feedURL = selectedFeed;\r
+        feedName = feedNameText.getText();\r
+    } else {\r
+        feedURL = null;\r
+        feedName = null;\r
+    }\r
+    \r
+    // update frequency\r
+    var selectedFrequency = feedUpdateFrequencySelection.getSelected();\r
+    feedUpdateFrequency = (selectedFrequency != null) ? selectedFrequency.value : -1;\r
+    \r
+    // save preferences\r
+    savePreferences();\r
+    \r
+    // return to main view\r
+    showMainView();\r
+    \r
+    // update the feed if the feed URL has changed\r
+    if (feedURL != oldURL) {\r
+        feedLastModified = null;\r
+        removeFeedItems();\r
+        updateFeed();\r
+    }\r
+}\r
+\r
+// Show main view.\r
+function showMainView() {\r
+    // set main view caption from feed name\r
+    var mainViewCaption = (feedName == null) ? null : feedName;\r
+    mainView.setCaption(mainViewCaption);\r
+    \r
+    // set right softkey to "exit"\r
+    if (window.widget) {\r
+        menu.setRightSoftkeyLabel("", null);\r
+    }\r
+    \r
+    // show the main view\r
+    uiManager.setView(mainView);\r
+}\r
+\r
+// Show settings view.\r
+function showSettings() {\r
+    // Feed Name\r
+    feedNameText.setText(feedName);\r
+\r
+    // URL\r
+    feedUrlText.setText(feedURL);\r
+               \r
+    // frequency\r
+    var feedUpdateFrequencyOption = feedUpdateFrequencySelection.getOptionForValue(feedUpdateFrequency);\r
+    feedUpdateFrequencySelection.setSelected(feedUpdateFrequencyOption);\r
+    \r
+    if (feedURL == null) {\r
+        // no valid configuration\r
+        // disable cancel button - set right softkey to "exit"\r
+        settingsCancelButton.setEnabled(false);\r
+        if (window.widget) {\r
+            menu.setRightSoftkeyLabel("", null);\r
+        }\r
+    } else {\r
+        // we have a valid configuration\r
+        // enable cancel button - set right softkey to "cancel"\r
+        settingsCancelButton.setEnabled(true);\r
+        if (window.widget) {\r
+            menu.setRightSoftkeyLabel("Cancel", showMainView);\r
+        }\r
+    }\r
+    \r
+    // show the settings view\r
+    uiManager.setView(settingsView);\r
+}\r
+\r
+//Displays the About view\r
+function showAboutView(){\r
+       aboutLabel.setText("This Widget includes software licensed from Nokia &copy 2008");\r
+       \r
+       setAboutViewSoftkeys();\r
+       uiManager.setView(aboutView);\r
+}\r
+\r
+// Sets the softkeys for about view.\r
+function setAboutViewSoftkeys() {\r
+    if (window.widget) {\r
+        // set right softkey to "Ok" (returns to main view)\r
+        menu.setRightSoftkeyLabel("Ok", showMainView);\r
+    }\r
+}\r
+\r
+// Schedules an immediate feed update.\r
+function updateFeed() {\r
+    feedUpdateTime = 0;\r
+    feedUpdateCommanded = true;\r
+}\r
+\r
+\r
+// Timer function for feed updates - called once every second.\r
+function updateFeedTimerFunc() {\r
+    var now = new Date().getTime();\r
+    \r
+    // check if a feed update has been scheduled, if it's time to update now,\r
+    // and if there's no update currently in progress and if we're in the main view\r
+    if ((feedURL != null) &&\r
+                (feedUpdateTime != -1) &&\r
+                (now > feedUpdateTime) &&\r
+                (feedUpdateBroker == null) && \r
+                (uiManager.getView() == mainView)) {\r
+        // show progress dialog if this is a commanded feed update\r
+        if (feedUpdateCommanded) {\r
+            // no auto hiding, wait-type notification, unknown progress\r
+            uiManager.showNotification(-1, "wait", "Loading feed...", -1);\r
+        }\r
+        \r
+        // fetch the feed from the specified URL\r
+        feedUpdateBroker = new FeedUpdateBroker();\r
+        feedUpdateBroker.fetchFeed(feedURL, feedUpdateCompleted);\r
+        \r
+        if (feedUpdateFrequency != -1) {\r
+            // schedule next update\r
+            feedUpdateTime = now + feedUpdateFrequency;\r
+        } else {\r
+            // feed update frequency is "never"\r
+            feedUpdateTime = -1;\r
+        }\r
+    }\r
+}\r
+\r
+// Callback function that gets called when a feed update has completed.\r
+function feedUpdateCompleted(event) {\r
+    if (event.status == "ok") {\r
+        // if there aren't any feed items yet, we'll hide the progress dialog\r
+        if (feedUpdateCommanded) {\r
+            uiManager.hideNotification();\r
+        }\r
+        \r
+        // check if the feed has updated\r
+        if (event.lastModified != feedLastModified) {\r
+            // remember the last modified timestamp\r
+            feedLastModified = event.lastModified;\r
+            \r
+            // feed fetched and parsed successfully\r
+            setFeedItems(event.items);\r
+            \r
+            // focus the first feed item control\r
+            // (but only if we are in the main view)\r
+            if (uiManager.getView() == mainView) {\r
+                feedItemControls[0].setFocused(true);\r
+            }\r
+        }\r
+    } else {\r
+        // show error message\r
+        uiManager.showNotification(3000, "warning", "Error while updating feed!<br/>(check network settings)");\r
+    }\r
+    \r
+    // null the broker reference to indicate that there's no current\r
+    // update in progress\r
+    feedUpdateBroker = null;\r
+    \r
+    // reset commanded feed update flag\r
+    feedUpdateCommanded = false;\r
+}\r
+\r
+// Removes feed items.\r
+function removeFeedItems() {\r
+    // remove all current feed items from the main view\r
+    for (var i = 0; i < feedItemControls.length; i++) {\r
+        mainView.removeControl(feedItemControls[i]);\r
+    }\r
+    \r
+    // reset feed item control array\r
+    feedItemControls = [];\r
+}\r
+\r
+// Sets feed items.\r
+function setFeedItems(items) {\r
+    // start by removing all current feed items\r
+    removeFeedItems();\r
+    \r
+    // create new feed items and add them to the main view\r
+    // use feed item pool to recycle controls\r
+    for (var i = 0; i < items.length; i++) {\r
+        // get a feed item control from the pool or create one and\r
+        // place it in the pool if there aren't enough feed item controls\r
+        var feedItemControl;\r
+        if (i == feedItemControlPool.length) {\r
+            feedItemControl = new ContentPanel(null, null, null, true);\r
+            feedItemControlPool.push(feedItemControl);\r
+        } else {\r
+            feedItemControl = feedItemControlPool[i];\r
+        }\r
+        \r
+        // initialize feed item control\r
+        var item = items[i];\r
+        feedItemControl.setCaption(item.title);\r
+        feedItemControl.setContent(getContentHTMLForFeedItem(item));\r
+        feedItemControl.setExpanded(false);\r
+        \r
+        // add the feed item control to the main view\r
+        feedItemControls.push(feedItemControl);\r
+        mainView.addControl(feedItemControl);\r
+    }\r
+}\r
+\r
+// Returns the content HTML for a feed item.\r
+function getContentHTMLForFeedItem(item) {\r
+    var buf = "";\r
+    \r
+    // item date\r
+    if (item.date != null) {\r
+        buf += "<div class=\"FeedItemDate\">" + item.date + "</div>";\r
+    }\r
+    \r
+    // item description\r
+    if (item.description != null) {\r
+        buf += "<div class=\"FeedItemDescription\">" + item.description + "</div>";\r
+    }\r
+    \r
+    // item URL\r
+    if (item.url != null) {\r
+        buf += "<div class=\"FeedItemLink\">";\r
+            buf += "<a href=\"JavaScript:void(0)\" onclick=\"openURL('" + item.url + "'); return false;\">";\r
+            buf += "Read more...";\r
+            buf += "</a>";\r
+        buf += "</div>";\r
+    }\r
+    \r
+    return buf;\r
+}\r
+\r
+// Opens a URL.\r
+function openURL(url) {\r
+    if (window.widget) {\r
+        // in WRT\r
+        widget.openURL(url);\r
+    } else {\r
+        // outside WRT\r
+        window.open(url, "NewWindow");\r
+    }\r
+}\r