X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fqml%2FMarketsTodayApp.qml;h=adc6ded7a74d7bb863deb9af2bc2aea32c4a95cf;hb=526c6066678d5eaa6ca355ee7c2073b83eab7e81;hp=c9bdee05e422ff1531914b922f4b57c2fe7f4c1d;hpb=c776af314a4c0ac785ae0208e116e4075132acfc;p=marketstoday diff --git a/src/qml/MarketsTodayApp.qml b/src/qml/MarketsTodayApp.qml index c9bdee0..adc6ded 100644 --- a/src/qml/MarketsTodayApp.qml +++ b/src/qml/MarketsTodayApp.qml @@ -1,10 +1,11 @@ /* -@version: 0.2 +@version: 0.4 @author: Sudheer K. @license: GNU General Public License */ -import Qt 4.7 +import QtQuick 1.1 +import com.nokia.meego 1.0 import "Library" as Library import "Library/js/ISODate.js" as DateLib @@ -12,107 +13,111 @@ import "Library/js/DBUtility.js" as DBUtility import "Library/js/Common.js" as Common import "Library/js/CoreLogic.js" as CoreLib -Item { - id: screen +PageStackWindow { + id: appWindow + initialPage: mainPage + showToolBar: false + showStatusBar: false - signal showConfigInNewWindow - signal showStockDetails(string strSymbol) - signal quoteRefreshStarted - signal quoteRefreshCompleted - signal checkNetworkStatus - - property int itemHeight: 50 - property int titleBarHeight: 60 - property int toolBarHeight: 40 - property int componentWidth: screen.width property int autoUpdateInterval: 300000 property bool updateWeekDaysOnly: false property bool updateOnSavedNetworksOnly: false - property string rssURL: "http://finance.yahoo.com/rss/topstories" + property bool isDesktopWidget: false + property string rssURL: "http://finance.yahoo.com/rss/topfinstories" property string lastUpdatedTimeStamp - property bool isDesktopWidget //property string selectedSymbol:"YHOO" property string selectedSymbol:sharedContext.getStockSymbol() - function reloadData(){ - CoreLib.reloadQuotes(); - CoreLib.reloadNews(); - } + signal showConfigInNewWindow + signal showStockDetails(string strSymbol) + signal quoteRefreshStarted + signal quoteRefreshCompleted(bool success, string strMessage) + signal newsReloadCompleted(bool success, string strMessage) + signal checkNetworkStatus function initialize(){ - var componentToDisplay = sharedContext.getComponentToDisplay(); - if (componentToDisplay === "StockQuoteDetails"){ - uiLoader.sourceComponent = stockDetailsComponent; - titleBar.buttonType = "Close"; - titleBar.displayMenu = false; - toolBar.displayIcons = false; - } - else{ - CoreLib.initialize(); - uiLoader.sourceComponent = stockQuotesUIComponent; - } + mainPage.initializePage(); } - Component.onCompleted: { - initialize(); - } + Page { + id: mainPage - Timer { - id: autoUpdateTimer - interval: autoUpdateInterval - //running: (autoUpdateInterval == 0? false:true) - repeat: true - onTriggered: { - if (!updateWeekDaysOnly){ - logUtility.logMessage("Allowed to update all days of the week"); - reloadData(); - //checkNetworkStatus(); - } - else if (Common.isTodayAWeekDay()){ - logUtility.logMessage("Today is a weekday"); - reloadData(); - //checkNetworkStatus(); + property int itemHeight: 50 + property int titleBarHeight: 60 + property int toolBarHeight: 40 + property int componentWidth: mainPage.width + + function reloadData(){ + CoreLib.reloadQuotes(); + CoreLib.reloadNews(); + } + + function initializePage(){ + var componentToDisplay = sharedContext.getComponentToDisplay(); + if (componentToDisplay === "StockQuoteDetails"){ + uiLoader.sourceComponent = stockDetailsComponent; + titleBar.buttonType = "Close"; + titleBar.displayMenu = false; + toolBar.displayIcons = false; } else{ - logUtility.logMessage("Update not triggered: Today is not a weekday"); + DBUtility.initialize(); + uiLoader.sourceComponent = stockQuotesUIComponent; + CoreLib.initialize(); } } - } - ListModel{ - id: stockQuoteDataModel - } + Component.onCompleted: { + initializePage(); + } - ListModel { - id: newsDataModel - } + Timer { + id: autoUpdateTimer + interval: autoUpdateInterval + //running: (autoUpdateInterval == 0? false:true) + repeat: true + onTriggered: { + if (!updateWeekDaysOnly){ + logUtility.logMessage("Allowed to update all days of the week"); + mainPage.reloadData(); + //checkNetworkStatus(); + } + else if (Common.isTodayAWeekDay()){ + logUtility.logMessage("Today is a weekday"); + mainPage.reloadData(); + //checkNetworkStatus(); + } + else{ + logUtility.logMessage("Update not triggered: Today is not a weekday"); + } + } + } - Rectangle { - id: background - anchors.fill: parent; - color: "#343434" - clip: true + ListModel{ + id: stockQuoteDataModel + } - Component { - id: stockQuotesDelegate + ListModel { + id: newsDataModel + } + + Rectangle { + id: background + anchors.fill: parent; + color: "#343434" + clip: true + + Component { + id: stockQuotesDelegateLandscape - Item { - id: wrapper; width: componentWidth; height: itemHeight Item { - Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: wrapper.height - 2; width: wrapper.width; y: 1 - Image{ - id: informationIcon - width: 32 - height: 32 - z: 10 - anchors {right: parent.right; rightMargin: 10; verticalCenter: parent.verticalCenter} - visible: false - source: "Library/images/information.png" - MouseArea{ - anchors.fill: parent; - onPressed: { - //console.log("Image clicked"); - screen.selectedSymbol = symbol; + id: wrapper; width: mainPage.componentWidth; height: mainPage.itemHeight + Item { + Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: wrapper.height - 2; width: wrapper.width; y: 1 + MouseArea { + anchors.fill: parent + onDoubleClicked: { + appWindow.selectedSymbol = symbol; uiLoader.sourceComponent = stockDetailsComponent; titleBar.buttonType = "Back"; titleBar.displayMenu = false; @@ -121,228 +126,380 @@ Item { } } - MouseArea { - anchors.fill: parent - onPressed:{ - informationIcon.visible = true; - //console.log("Rectangle clicked"); - } + Row { + x: 30;y: 15; + width: mainPage.componentWidth - 60; + spacing: 5 + + Text { text: stockName; width: parent.width * 30/100; font.pixelSize: 18; font.bold: true; elide: Text.ElideRight; color: "white"; style: Text.Raised; styleColor: "black" } + Text { text: lastTradedPrice; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" } + Text { text: change !== ""? (change + " ("+changePercentage+")"):""; width: parent.width * 25/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideRight + color: if(change >= 0){"green";} else {"red";} + style: Text.Raised; styleColor: "black" } + Text { text: volume; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" } + Text { text: marketCap; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" } } } + } + } + + Component { + id: stockQuotesDelegatePortrait + + Item { + id: wrapperItem; width: mainPage.componentWidth; height: mainPage.itemHeight + Item { + Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: wrapperItem.height - 2; width: wrapperItem.width; y: 1 + MouseArea { + anchors.fill: parent + onDoubleClicked: { + appWindow.selectedSymbol = symbol; + uiLoader.sourceComponent = stockDetailsComponent; + titleBar.buttonType = "Back"; + titleBar.displayMenu = false; + toolBar.displayIcons = false; + } + } + } - Row { - x: 30;y: 15; - width: componentWidth - 60; - spacing: 5 - - Text { text: stockName; width: parent.width * 30/100; font.pixelSize: 18; font.bold: true; elide: Text.ElideRight; color: "white"; style: Text.Raised; styleColor: "black" } - Text { text: lastTradedPrice; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" } - Text { text: change !== ""? (change + " ("+changePercentage+")"):""; width: parent.width * 25/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideRight - color: if(change >= 0){"green";} else {"red";} - style: Text.Raised; styleColor: "black" } - Text { text: volume; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" } - Text { text: marketCap; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" } + Row { + x: 10;y: 15; + width: mainPage.componentWidth - 5; + spacing: 3 + + Text { text: stockName; width: parent.width * 42/100; font.pixelSize: 18; font.bold: true; elide: Text.ElideRight; color: "white"; style: Text.Raised; styleColor: "black" } + Text { text: lastTradedPrice; width: parent.width * 20/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" } + Column { + y: -15; + width: parent.width * 18/100; height: parent.height + spacing: 2 + Text { text: change; font.pixelSize: 16; horizontalAlignment: Text.AlignLeft; elide: Text.ElideRight + color: if(change >= 0){"green";} else {"red";} + style: Text.Raised; styleColor: "black" } + Text { text: changePercentage; font.pixelSize: 16; horizontalAlignment: Text.AlignLeft; elide: Text.ElideRight; + color: if(change >= 0){"green";} else {"red";} + style: Text.Raised; styleColor: "black" } + } + Text { text: volume; width: parent.width * 20/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" } + } } } } - } - Component { - id: newsDelegate + Component { + id: newsDelegate - Item { - id: newsWrapper; width: componentWidth; height: itemHeight Item { - anchors.fill: parent - Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 } - Text { - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: 10 - anchors.right: parent.right - text: title; font.pixelSize: 18 - font.bold: false; - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - elide: Text.ElideRight; - color: "white"; - style: Text.Raised; - styleColor: "black" - } - MouseArea{ + id: newsWrapper; width: mainPage.componentWidth; height: mainPage.itemHeight + Item { anchors.fill: parent - onClicked: Qt.openUrlExternally(link); + Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 } + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.right: parent.right + text: title; font.pixelSize: 18 + font.bold: false; + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + elide: Text.ElideRight; + color: "white"; + style: Text.Raised; + styleColor: "black" + } + MouseArea{ + anchors.fill: parent + onDoubleClicked: Qt.openUrlExternally(link); + } } } } - } - Library.TitleBar { - id: titleBar; - width: parent.width; height: screen.titleBarHeight; - anchors.top: parent.top - title: "Markets Today"; - buttonType: "Close"; - z: 5 //required to keep Titlebar and Menu buttons on top of everything else - - onCloseClicked: Qt.quit() + Library.TitleBar { + id: titleBar; + width: parent.width; height: mainPage.titleBarHeight; + anchors.top: parent.top + title: "Markets Today"; + buttonType: "Close"; + z: 5 //required to keep Titlebar and Menu buttons on top of everything else + + onCloseClicked: Qt.quit() + + onTickersClicked: { + uiLoader.sourceComponent = configTickersComponent; + titleBar.buttonType = "Back"; + titleBar.displayMenu = false; + toolBar.displayIcons = false; + } - onTickersClicked: { - uiLoader.sourceComponent = configTickersComponent; - titleBar.buttonType = "Back"; - titleBar.displayMenu = false; - toolBar.displayIcons = false; - } + onOptionsClicked: { + uiLoader.sourceComponent = configParamsComponent; + titleBar.buttonType = "Back"; + titleBar.displayMenu = false; + toolBar.displayIcons = false; + } - onOptionsClicked: { - uiLoader.sourceComponent = configParamsComponent; - titleBar.buttonType = "Back"; - titleBar.displayMenu = false; - toolBar.displayIcons = false; + onBackClicked: { + uiLoader.sourceComponent = stockQuotesUIComponent; + titleBar.buttonType = "Close"; + titleBar.displayMenu = false; + toolBar.displayIcons = true; + mainPage.initializePage(); + } } - onBackClicked: { - uiLoader.sourceComponent = stockQuotesUIComponent; - titleBar.buttonType = "Close"; - titleBar.displayMenu = false; - toolBar.displayIcons = true; - screen.initialize(); + Loader { + id: uiLoader + width: parent.width + anchors.top: titleBar.bottom + anchors.bottom: toolBar.top } - } - Loader { - id: uiLoader - width: parent.width - anchors.top: titleBar.bottom - anchors.bottom: toolBar.top - } - - Library.ToolBar { - id:toolBar - width: parent.width; height: screen.toolBarHeight - anchors.bottom: parent.bottom - opacity: 0.9 - displayNavigation: false - onReloadButtonClicked: screen.reloadData(); - - onNewsButtonClicked: { - uiLoader.sourceComponent = newsComponent; - toolBar.displayIcons = true; - toolBar.targetContentType = "Stocks"; - } + Library.ToolBar { + id:toolBar + width: parent.width; height: mainPage.toolBarHeight + anchors.bottom: parent.bottom + opacity: 0.9 + displayNavigation: false + onReloadButtonClicked: mainPage.reloadData(); + + onNewsButtonClicked: { + uiLoader.sourceComponent = newsComponent; + toolBar.displayIcons = true; + toolBar.targetContentType = "Stocks"; + } - onStocksButtonClicked: { - uiLoader.sourceComponent = stockQuotesUIComponent; - toolBar.displayIcons = true; - toolBar.targetContentType = "News"; - } + onStocksButtonClicked: { + uiLoader.sourceComponent = stockQuotesUIComponent; + toolBar.displayIcons = true; + toolBar.targetContentType = "News"; + } - Connections { - target: screen - onQuoteRefreshStarted:{ - if (!toolBar.updatePending) toolBar.updatePending = true; - } - onQuoteRefreshCompleted:{ - toolBar.updatePending = false; + Connections { + target: appWindow + onQuoteRefreshStarted:{ + if (!toolBar.updatePending) toolBar.updatePending = true; + } + onQuoteRefreshCompleted:{ + toolBar.updatePending = false; + } } } - } - Component { - id: stockQuotesUIComponent - Item { - Rectangle{ - id: listViewWrapper - width: parent.width - anchors.top: parent.top - anchors.bottom: footerText.top - color: "#343434" + Component { + id: stockQuotesUIComponent + Item { + Rectangle{ + id: listViewWrapper + width: parent.width + anchors.top: parent.top + anchors.bottom: footerTextArea.top + color: "#343434" + + ListView { + id: stockQuotesView + anchors.fill: parent + flickDeceleration: 500 + model: stockQuoteDataModel + delegate: listViewWrapper.height > listViewWrapper.width ? stockQuotesDelegatePortrait : stockQuotesDelegateLandscape + focus:true + snapMode: ListView.SnapToItem + } + } - ListView { - id: stockQuotesView - anchors.fill: parent - flickDeceleration: 500 - model: stockQuoteDataModel - delegate: stockQuotesDelegate - focus:true - snapMode: ListView.SnapToItem + Rectangle { + id: stockStatusMsgArea + height: 100 + color: "#343434" + anchors {left: parent.left; leftMargin: 15; right: parent.right; rightMargin: 15; + verticalCenter: parent.verticalCenter} + visible: false + + Text { + id: stockStatusText + anchors.fill: parent + text: "Loading quotes.." + horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter + width: parent.width; font.pixelSize: 16; elide: Text.ElideNone; + color: "#cccccc" + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + style: Text.Raised; styleColor: "black" + + Connections { + target: appWindow + onQuoteRefreshCompleted: { + if (success){ + stockStatusMsgArea.visible = false; + listViewWrapper.visible = true; + } + else{ + stockStatusText.text = strMessage; + stockStatusMsgArea.visible = true; + listViewWrapper.visible = true; + } + } + } + } } - } - Rectangle{ - id: footerText - width: parent.width - height: 25 - color: "#343434" - anchors.bottom: parent.bottom - Text { - id: timeStamp - anchors.fill: parent - text: screen.lastUpdatedTimeStamp - horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter - width: parent.width; font.pixelSize: 12; elide: Text.ElideRight; - color: "#cccccc" - style: Text.Raised; styleColor: "black" + Rectangle{ + id: footerTextArea + width: parent.width + height: 25 + color: "#343434" + anchors.bottom: parent.bottom + Text { + id: footerMessage + anchors.fill: parent + text: lastUpdatedTimeStamp + horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter + width: parent.width; font.pixelSize: 12; elide: Text.ElideRight; + color: "#cccccc" + style: Text.Raised; styleColor: "black" + } + + Timer { + id: footerMessageTimer + interval: 10000 + repeat: false + onTriggered: { + footerMessage.text = appWindow.lastUpdatedTimeStamp; + } + } Connections { - target: screen + target: appWindow onQuoteRefreshCompleted:{ - timeStamp.text = screen.lastUpdatedTimeStamp; + if (success){ + footerMessage.text = "Double-tap on a row to display more details."; + footerMessageTimer.start(); + } + else{ + footerMessage.text = appWindow.lastUpdatedTimeStamp; + } } } } } } - } - Component{ - id: stockDetailsComponent - StockDetailsComponent { - symbol: selectedSymbol - onLogRequest: logUtility.logMessage(strMessage) + Component{ + id: stockDetailsComponent + StockDetailsComponent { + id: detailsComponent + symbol: selectedSymbol + onLogRequest: logUtility.logMessage(strMessage) + orientation: (appWindow.inPortrait)? "Portrait":"Landscape"; //Initial Orientation + states: [ + State { + name: "inLandscape" + when: !appWindow.inPortrait + PropertyChanges { + target: detailsComponent + orientation: "Landscape" + } + }, + State { + name: "inPortrait" + when: appWindow.inPortrait + PropertyChanges { + target: detailsComponent + orientation: "Portrait" + } + } + ] + + Component.onCompleted: { + if (appWindow.inPortrait){ + logUtility.logMessage("Initial orientation is Portrait"); + } + else + { + logUtility.logMessage("Initial orientation is Landscape"); + } + } + } } - } - Component { - id: newsComponent - Item { - Rectangle{ - width: parent.width - anchors.top: parent.top - anchors.bottom: parent.bottom - color: "#343434" - - ListView { - id: newsView - anchors.fill: parent - flickDeceleration: 500 - model: newsDataModel - delegate: newsDelegate - focus:true - snapMode: ListView.SnapToItem + Component { + id: newsComponent + Item { + Rectangle{ + id: newsViewArea + width: parent.width + anchors.top: parent.top + anchors.bottom: parent.bottom + color: "#343434" + + ListView { + id: newsView + anchors.fill: parent + flickDeceleration: 500 + model: newsDataModel + delegate: newsDelegate + focus:true + snapMode: ListView.SnapToItem + } } + + Rectangle { + id: newsStatusMsgArea + height: 100 + color: "#343434" + anchors {left: parent.left; leftMargin: 15; right: parent.right; rightMargin: 15; + verticalCenter: parent.verticalCenter} + visible: false + + Text { + id: newsStatusText + anchors.fill: parent + text: "Loading news.." + horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter + width: parent.width; font.pixelSize: 16; elide: Text.ElideNone; + color: "#cccccc" + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + style: Text.Raised; styleColor: "black" + + Connections { + target: appWindow + onNewsReloadCompleted: { + if (success){ + newsStatusMsgArea.visible = false; + newsViewArea.visible = true; + } + else{ + newsStatusText.text = strMessage; + newsViewArea.visible = false; + newsStatusMsgArea.visible = true; + } + } + } + } + } + } } - } - Component { - id: configTickersComponent + Component { + id: configTickersComponent - ConfigTickersComponent{ - itemHeight: screen.itemHeight - componentWidth: screen.componentWidth - onLogRequest: logUtility.logMessage(strMessage) + ConfigTickersComponent{ + itemHeight: mainPage.itemHeight + componentWidth: mainPage.componentWidth + onLogRequest: logUtility.logMessage(strMessage) + } } - } - Component { - id: configParamsComponent - ConfigParametersComponent{ - onLogRequest: logUtility.logMessage(strMessage) + Component { + id: configParamsComponent + ConfigParametersComponent{ + onLogRequest: logUtility.logMessage(strMessage) + } } - } + } } }