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 - 120
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)
42 Component.onCompleted: {
46 chartURL = baseChartURL+"&t=1d&s="+symbol;
50 function loadDetails(){
51 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';
52 logRequest("Loading stock details from "+queryURL);
53 var response = new XMLHttpRequest();
54 response.onreadystatechange = function() {
55 if (response.readyState == XMLHttpRequest.DONE) {
56 refreshDetails(response.responseXML);
60 response.open("GET", queryURL);
65 rssURL = "http://feeds.finance.yahoo.com/rss/2.0/headline?region=US&lang=en-US&s="+symbol;
66 logRequest("Loading news from "+rssURL);
67 var response = new XMLHttpRequest();
68 response.onreadystatechange = function() {
69 if (response.readyState == XMLHttpRequest.DONE) {
70 refreshNewsModel(response.responseXML);
74 response.open("GET", rssURL);
78 function refreshDetails(responseXML){
79 if (!responseXML) return;
80 var xmlDoc = responseXML.documentElement;
81 var results = xmlDoc.firstChild;
84 var quoteNodes = results.childNodes;
86 if (quoteNodes.length === 0) {
87 logRequest("No results for stock quote details");
90 //We are only expecting one quote node per symbol.
91 var quoteElements = quoteNodes[0].childNodes;
93 var lastTradedDate = "", lastTradedTime ="";
94 for (j = 0; j < quoteElements.length; j++){
96 if (quoteElements[j].childNodes[0]) {
97 switch (quoteElements[j].nodeName){
99 stockName = quoteElements[j].childNodes[0].nodeValue;
101 case 'LastTradePriceOnly':
102 lastTradedPrice = quoteElements[j].childNodes[0].nodeValue;
104 case 'LastTradeDate':
105 lastTradedDate = quoteElements[j].childNodes[0].nodeValue;
107 case 'LastTradeTime':
108 lastTradedTime = quoteElements[j].childNodes[0].nodeValue;
111 change = quoteElements[j].childNodes[0].nodeValue;
113 case 'ChangeinPercent':
114 changePercentage = quoteElements[j].childNodes[0].nodeValue;
117 daysRange = quoteElements[j].childNodes[0].nodeValue;
120 yearRange = quoteElements[j].childNodes[0].nodeValue;
123 marketVolume = quoteElements[j].childNodes[0].nodeValue;
125 case 'PreviousClose':
126 prevClose = quoteElements[j].childNodes[0].nodeValue;
128 case 'MarketCapitalization':
129 marketCap = quoteElements[j].childNodes[0].nodeValue;
135 if (lastTradedDate !== "") lastTradedDateTime = lastTradedDate + " " + lastTradedTime;
141 function refreshNewsModel(responseXML){
142 if (!(responseXML && stockNewsDataModel)) return;
144 var xmlDoc = responseXML.documentElement;
145 var channel = xmlDoc.firstChild;
147 //Not the best code I ever wrote, but got no choice
148 //Refer to Memory leak issue with XMLListModel --> http://bugreports.qt.nokia.com/browse/QTBUG-15191
151 var itemNodes = channel.childNodes;
154 logRequest("Clearing News Model");
155 stockNewsDataModel.clear();
158 for (i = 0; i < itemNodes.length; i++) {
160 if (itemNodes[i].nodeName === 'item'){
161 var newsElements = itemNodes[i].childNodes;
163 var newsTitle,newsLink
164 for (j = 0; j < newsElements.length; j++){
166 switch (newsElements[j].nodeName){
168 newsTitle = newsElements[j].childNodes[0].nodeValue;
171 newsLink = newsElements[j].childNodes[0].nodeValue;
176 stockNewsDataModel.append({"title":newsTitle,"link":newsLink});
184 id: stockNewsDataModel
188 id: stockNewsDelegate
191 id: newsWrapper; width: componentWidth; height: itemHeight
194 Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 }
196 anchors {verticalCenter: parent.verticalCenter;left: parent.left;leftMargin: 10;right: parent.right}
197 text: title; font.pixelSize: 14
199 verticalAlignment: Text.AlignVCenter
200 horizontalAlignment: Text.AlignLeft
201 elide: Text.ElideRight;
209 logRequest("Opening news article: "+link);
210 Qt.openUrlExternally(link);
218 id: stockDetailsComponent
225 anchors.top: parent.top
227 anchors.horizontalCenter: parent.horizontalCenter
229 horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter
230 font.pixelSize: 18; font.bold: true; elide: Text.ElideMiddle; color: "#B8B8B8"; style: Text.Raised; styleColor: "black"
231 text: (stockName != "")? (stockName +" ("+symbol+")"):symbol
236 id: stockDetailsSection
238 border.color: "#BFBFBF"
240 anchors {top: stockNameLabel.bottom;left: parent.left;right: parent.right}
245 id: stockDetailsColumn
246 anchors {top: parent.top; left: parent.left; leftMargin: 10}
247 width: (parent.width - 10)
250 label1: "Last Traded"
251 value1: lastTradedPrice
252 cell1Width: stockDetailsColumn.width/2
254 label2: "Day's Range"
256 cell2Width: stockDetailsColumn.width/2
260 label1: "Last Trade Time"
261 value1: lastTradedDateTime
262 cell1Width: stockDetailsColumn.width/2
266 cell2Width: stockDetailsColumn.width/2
271 value1: ((change != "" && changePercentage != "")? change + " ("+changePercentage+")":"")
272 cell1Width: stockDetailsColumn.width/2
276 cell2Width: stockDetailsColumn.width/2
280 label1: "Prev. Close"
282 cell1Width: stockDetailsColumn.width/2
286 cell2Width: stockDetailsColumn.width/2
293 border.color: "#BFBFBF"
296 anchors {top: stockDetailsSection.bottom;topMargin: 5;
297 bottom: parent.bottom;bottomMargin: 20;
301 flickDeceleration: 500
303 model: stockNewsDataModel
304 delegate: stockNewsDelegate
306 snapMode: ListView.SnapToItem
317 visible: (currentScreenIndex > 1)
318 anchors {verticalCenter: parent.verticalCenter; left: parent.left; leftMargin: 10}
323 source: "Library/images/arrow_left.png"
328 switch (currentScreenIndex){
333 stockDetailsLoader.sourceComponent = stockDetailsComponent;
334 currentScreenIndex = currentScreenIndex - 1;
339 logRequest("currentScreenIndex = "+currentScreenIndex);
345 id: stockDetailsLoader
346 anchors{top: parent.top; bottom: parent.bottom
347 left: parent.left; leftMargin: 60
348 right: parent.right; rightMargin: 60}
349 sourceComponent: stockDetailsComponent
356 visible: (currentScreenIndex < 2)
357 anchors {verticalCenter: parent.verticalCenter; right: parent.right; rightMargin: 10}
362 source: "Library/images/arrow_right.png"
367 switch (currentScreenIndex){
369 stockDetailsLoader.sourceComponent = stockChartComponent;
370 currentScreenIndex = currentScreenIndex + 1;
378 logRequest("currentScreenIndex = "+currentScreenIndex);
384 id: stockChartComponent
393 border.color: "#BFBFBF"
396 anchors { top: parent.top;topMargin: 40;
397 bottom: parent.bottom; bottomMargin: 40;
398 left: parent.left; right: parent.right}
401 Library.Loading { anchors.centerIn: parent; visible: chartImg.status == Image.Loading}
405 anchors {left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter}
407 sourceSize.width: 512
408 sourceSize.height: 288
410 fillMode: Image.PreserveAspectFit
414 logRequest("Image is ready");
417 logRequest("Image is loading");
420 logRequest("Image loading failed");
423 logRequest("No image specified");
430 target: stockDetailsScreen
432 chartURL = baseChartURL+"&t="+duration+"&s="+symbol;
433 logRequest(chartURL);
441 anchors {top: parent.top; topMargin: 40; bottom: parent.bottom;
442 right: chartArea.right;rightMargin: 10}
447 anchors.horizontalCenter: parent.horizontalCenter
451 anchors { verticalCenter: parent.verticalCenter}
452 width: 50; height: 32
453 onClicked: loadChart("1d");
459 anchors { verticalCenter: parent.verticalCenter}
460 width: 50; height: 32
461 onClicked: loadChart("5d");
468 anchors.horizontalCenter: parent.horizontalCenter
472 anchors { verticalCenter: parent.verticalCenter}
473 width: 50; height: 32
474 onClicked: loadChart("3m");
480 anchors { verticalCenter: parent.verticalCenter}
481 width: 50; height: 32
482 onClicked: loadChart("6m");
488 anchors.horizontalCenter: parent.horizontalCenter
492 anchors { verticalCenter: parent.verticalCenter}
493 width: 50; height: 32
494 onClicked: loadChart("1y");
500 anchors { verticalCenter: parent.verticalCenter}
501 width: 50; height: 32
502 onClicked: loadChart("2y");
508 anchors.horizontalCenter: parent.horizontalCenter
512 anchors { verticalCenter: parent.verticalCenter}
513 width: 50; height: 32
514 onClicked: loadChart("5y");
520 anchors { verticalCenter: parent.verticalCenter}
521 width: 50; height: 32
522 onClicked: loadChart("my");