3 @author: Sudheer K. <scifi1947 at gmail.com>
4 @license: GNU General Public License
8 import "Library" as Library
15 id: stockDetailsScreen
16 property int componentWidth: width
17 property int itemHeight: 50
18 property string symbol: "YHOO"
19 property string stockName: ""
20 property string lastTradedPrice: ""
21 property string lastTradedDateTime: ""
22 property string change: ""
23 property string changePercentage: ""
24 property string daysRange: ""
25 property string yearRange: ""
26 property string marketVolume: ""
27 property string prevClose: ""
28 property string marketCap: ""
29 property string baseChartURL: "http://chart.finance.yahoo.com/z?q=&l=&z=m&p=s&a=v&p=s&lang=en-US®ion=US"
30 property string chartURL: ""
31 property string rssURL: ""
33 property int currentScreenIndex: 1
35 signal logRequest(string strMessage)
36 signal loadChart(string duration)
37 signal lockInLandscape()
38 signal unlockOrientation()
45 Library.CustomGestureArea {
47 onSwipeLeft: detailsRect.switchScreen()
48 onSwipeRight: detailsRect.switchScreen()
51 Component.onCompleted: {
55 chartURL = baseChartURL+"&t=1d&s="+symbol;
59 function switchScreen(){
60 switch (currentScreenIndex){
62 stockDetailsScreen.lockInLandscape();
63 stockDetailsLoader.sourceComponent = stockChartComponent;
64 currentScreenIndex = currentScreenIndex + 1;
67 stockDetailsScreen.unlockOrientation();
68 stockDetailsLoader.sourceComponent = stockDetailsComponent;
69 currentScreenIndex = currentScreenIndex - 1;
74 logRequest("currentScreenIndex = "+currentScreenIndex);
77 function loadDetails(){
78 var queryURL = 'http://query.yahooapis.com/v1/public/yql?q=select Symbol,Name,LastTradePriceOnly,LastTradeDate,LastTradeTime,Change,ChangeinPercent,DaysRange,YearRange,Volume,PreviousClose,MarketCapitalization from yahoo.finance.quotes where symbol in ("'+symbol+'")&env=store://datatables.org/alltableswithkeys';
79 logRequest("Loading stock details from "+queryURL);
80 var response = new XMLHttpRequest();
81 response.onreadystatechange = function() {
82 if (response.readyState == XMLHttpRequest.DONE) {
83 refreshDetails(response.responseXML);
87 response.open("GET", queryURL);
92 rssURL = "http://feeds.finance.yahoo.com/rss/2.0/headline?region=US&lang=en-US&s="+symbol;
93 logRequest("Loading news from "+rssURL);
94 var response = new XMLHttpRequest();
95 response.onreadystatechange = function() {
96 if (response.readyState == XMLHttpRequest.DONE) {
97 refreshNewsModel(response.responseXML);
101 response.open("GET", rssURL);
105 function refreshDetails(responseXML){
106 if (!responseXML) return;
107 var xmlDoc = responseXML.documentElement;
108 var results = xmlDoc.firstChild;
111 var quoteNodes = results.childNodes;
113 if (quoteNodes.length === 0) {
114 logRequest("No results for stock quote details");
117 //We are only expecting one quote node per symbol.
118 var quoteElements = quoteNodes[0].childNodes;
120 var lastTradedDate = "", lastTradedTime ="";
121 for (j = 0; j < quoteElements.length; j++){
123 if (quoteElements[j].childNodes[0]) {
124 switch (quoteElements[j].nodeName){
126 stockName = quoteElements[j].childNodes[0].nodeValue;
128 case 'LastTradePriceOnly':
129 lastTradedPrice = quoteElements[j].childNodes[0].nodeValue;
131 case 'LastTradeDate':
132 lastTradedDate = quoteElements[j].childNodes[0].nodeValue;
134 case 'LastTradeTime':
135 lastTradedTime = quoteElements[j].childNodes[0].nodeValue;
138 change = quoteElements[j].childNodes[0].nodeValue;
140 case 'ChangeinPercent':
141 changePercentage = quoteElements[j].childNodes[0].nodeValue;
144 daysRange = quoteElements[j].childNodes[0].nodeValue;
147 yearRange = quoteElements[j].childNodes[0].nodeValue;
150 marketVolume = quoteElements[j].childNodes[0].nodeValue;
152 case 'PreviousClose':
153 prevClose = quoteElements[j].childNodes[0].nodeValue;
155 case 'MarketCapitalization':
156 marketCap = quoteElements[j].childNodes[0].nodeValue;
162 if (lastTradedDate !== "") lastTradedDateTime = lastTradedDate + " " + lastTradedTime;
168 function refreshNewsModel(responseXML){
169 if (!(responseXML && stockNewsDataModel)) return;
171 var xmlDoc = responseXML.documentElement;
172 var channel = xmlDoc.firstChild;
174 //Not the best code I ever wrote, but got no choice
175 //Refer to Memory leak issue with XMLListModel --> http://bugreports.qt.nokia.com/browse/QTBUG-15191
178 var itemNodes = channel.childNodes;
181 logRequest("Clearing News Model");
182 stockNewsDataModel.clear();
185 for (i = 0; i < itemNodes.length; i++) {
187 if (itemNodes[i].nodeName === 'item'){
188 var newsElements = itemNodes[i].childNodes;
190 var newsTitle,newsLink
191 for (j = 0; j < newsElements.length; j++){
193 switch (newsElements[j].nodeName){
195 newsTitle = newsElements[j].childNodes[0].nodeValue;
198 newsLink = newsElements[j].childNodes[0].nodeValue;
203 stockNewsDataModel.append({"title":newsTitle,"link":newsLink});
211 id: stockNewsDataModel
215 id: stockNewsDelegate
218 id: newsWrapper; width: stockDetailsLoader.width; height: itemHeight
221 Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 }
223 anchors {verticalCenter: parent.verticalCenter;left: parent.left;leftMargin: 10;right: parent.right}
224 text: title; font.pixelSize: 14
226 verticalAlignment: Text.AlignVCenter
227 horizontalAlignment: Text.AlignLeft
228 elide: Text.ElideRight;
233 Library.CustomGestureArea {
236 logRequest("Opening news article: "+link);
237 Qt.openUrlExternally(link);
239 onSwipeLeft: detailsRect.switchScreen()
240 onSwipeRight: detailsRect.switchScreen()
247 id: stockDetailsComponent
254 anchors.top: parent.top
256 anchors.horizontalCenter: parent.horizontalCenter
258 horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter
259 font.pixelSize: 18; font.bold: true; elide: Text.ElideMiddle; color: "#B8B8B8"; style: Text.Raised; styleColor: "black"
260 text: (stockName != "")? (stockName +" ("+symbol+")"):symbol
265 id: stockDetailsSection
267 border.color: "#BFBFBF"
269 anchors {top: stockNameLabel.bottom;left: parent.left;right: parent.right}
274 id: stockDetailsColumn
275 anchors {top: parent.top; left: parent.left; leftMargin: 10}
279 label1: "Last Traded"
280 value1: lastTradedPrice
281 cell1Width: stockDetailsColumn.width/2
283 label2: "Day's Range"
285 cell2Width: stockDetailsColumn.width/2
289 label1: "Last Trade Time"
290 value1: lastTradedDateTime
291 cell1Width: stockDetailsColumn.width/2
295 cell2Width: stockDetailsColumn.width/2
300 value1: ((change != "" && changePercentage != "")? change + " ("+changePercentage+")":"")
301 cell1Width: stockDetailsColumn.width/2
305 cell2Width: stockDetailsColumn.width/2
309 label1: "Prev. Close"
311 cell1Width: stockDetailsColumn.width/2
315 cell2Width: stockDetailsColumn.width/2
322 border.color: "#BFBFBF"
325 anchors {top: stockDetailsSection.bottom;topMargin: 5;
326 bottom: parent.bottom;
330 flickDeceleration: 500
332 model: stockNewsDataModel
333 delegate: stockNewsDelegate
335 snapMode: ListView.SnapToItem
343 id: stockDetailsLoader
344 anchors{top: parent.top; bottom: parent.bottom
345 left: parent.left; leftMargin: 10
346 right: parent.right; rightMargin: 10}
347 sourceComponent: stockDetailsComponent
352 id: stockChartComponent
361 border.color: "#BFBFBF"
364 anchors { top: parent.top;topMargin: 40;
365 bottom: parent.bottom; bottomMargin: 40;
366 left: parent.left; right: parent.right}
369 Library.Loading { anchors.centerIn: parent; visible: chartImg.status == Image.Loading}
373 anchors {left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter}
375 sourceSize.width: 512
376 sourceSize.height: 288
378 fillMode: Image.PreserveAspectFit
382 logRequest("Image is ready");
385 logRequest("Image is loading");
388 logRequest("Image loading failed");
391 logRequest("No image specified");
398 target: stockDetailsScreen
400 chartURL = baseChartURL+"&t="+duration+"&s="+symbol;
401 logRequest(chartURL);
409 anchors {top: parent.top; topMargin: 40; bottom: parent.bottom;
410 right: chartArea.right;rightMargin: 10}
415 anchors.horizontalCenter: parent.horizontalCenter
419 anchors { verticalCenter: parent.verticalCenter}
420 width: 50; height: 32
421 onClicked: loadChart("1d");
427 anchors { verticalCenter: parent.verticalCenter}
428 width: 50; height: 32
429 onClicked: loadChart("5d");
436 anchors.horizontalCenter: parent.horizontalCenter
440 anchors { verticalCenter: parent.verticalCenter}
441 width: 50; height: 32
442 onClicked: loadChart("3m");
448 anchors { verticalCenter: parent.verticalCenter}
449 width: 50; height: 32
450 onClicked: loadChart("6m");
456 anchors.horizontalCenter: parent.horizontalCenter
460 anchors { verticalCenter: parent.verticalCenter}
461 width: 50; height: 32
462 onClicked: loadChart("1y");
468 anchors { verticalCenter: parent.verticalCenter}
469 width: 50; height: 32
470 onClicked: loadChart("2y");
476 anchors.horizontalCenter: parent.horizontalCenter
480 anchors { verticalCenter: parent.verticalCenter}
481 width: 50; height: 32
482 onClicked: loadChart("5y");
488 anchors { verticalCenter: parent.verticalCenter}
489 width: 50; height: 32
490 onClicked: loadChart("my");