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: ""
32 property string orientation: "Portrait"
34 property int currentScreenIndex: 1
36 signal logRequest(string strMessage)
37 signal loadChart(string duration)
44 Library.CustomGestureArea {
46 onSwipeLeft: detailsRect.switchScreen()
47 onSwipeRight: detailsRect.switchScreen()
50 Component.onCompleted: {
54 chartURL = baseChartURL+"&t=1d&s="+symbol;
58 function switchScreen(){
59 switch (currentScreenIndex){
61 stockDetailsLoader.sourceComponent = (stockDetailsScreen.width > stockDetailsScreen.height)? stockChartComponentLandscape : stockChartComponentPortrait;
62 currentScreenIndex = currentScreenIndex + 1;
65 stockDetailsLoader.sourceComponent = stockDetailsComponent;
66 currentScreenIndex = currentScreenIndex - 1;
71 logRequest("currentScreenIndex = "+currentScreenIndex);
74 function loadDetails(){
75 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';
76 logRequest("Loading stock details from "+queryURL);
77 var response = new XMLHttpRequest();
78 response.onreadystatechange = function() {
79 if (response.readyState == XMLHttpRequest.DONE) {
80 refreshDetails(response.responseXML);
84 response.open("GET", queryURL);
89 rssURL = "http://feeds.finance.yahoo.com/rss/2.0/headline?region=US&lang=en-US&s="+symbol;
90 logRequest("Loading news from "+rssURL);
91 var response = new XMLHttpRequest();
92 response.onreadystatechange = function() {
93 if (response.readyState == XMLHttpRequest.DONE) {
94 refreshNewsModel(response.responseXML);
98 response.open("GET", rssURL);
102 function refreshDetails(responseXML){
103 if (!responseXML) return;
104 var xmlDoc = responseXML.documentElement;
105 var results = xmlDoc.firstChild;
108 var quoteNodes = results.childNodes;
110 if (quoteNodes.length === 0) {
111 logRequest("No results for stock quote details");
114 //We are only expecting one quote node per symbol.
115 var quoteElements = quoteNodes[0].childNodes;
117 var lastTradedDate = "", lastTradedTime ="";
118 for (j = 0; j < quoteElements.length; j++){
120 if (quoteElements[j].childNodes[0]) {
121 switch (quoteElements[j].nodeName){
123 stockName = quoteElements[j].childNodes[0].nodeValue;
125 case 'LastTradePriceOnly':
126 lastTradedPrice = quoteElements[j].childNodes[0].nodeValue;
128 case 'LastTradeDate':
129 lastTradedDate = quoteElements[j].childNodes[0].nodeValue;
131 case 'LastTradeTime':
132 lastTradedTime = quoteElements[j].childNodes[0].nodeValue;
135 change = quoteElements[j].childNodes[0].nodeValue;
137 case 'ChangeinPercent':
138 changePercentage = quoteElements[j].childNodes[0].nodeValue;
141 daysRange = quoteElements[j].childNodes[0].nodeValue;
144 yearRange = quoteElements[j].childNodes[0].nodeValue;
147 marketVolume = quoteElements[j].childNodes[0].nodeValue;
149 case 'PreviousClose':
150 prevClose = quoteElements[j].childNodes[0].nodeValue;
152 case 'MarketCapitalization':
153 marketCap = quoteElements[j].childNodes[0].nodeValue;
159 if (lastTradedDate !== "") lastTradedDateTime = lastTradedDate + " " + lastTradedTime;
165 function refreshNewsModel(responseXML){
166 if (!(responseXML && stockNewsDataModel)) return;
168 var xmlDoc = responseXML.documentElement;
169 var channel = xmlDoc.firstChild;
171 //Not the best code I ever wrote, but got no choice
172 //Refer to Memory leak issue with XMLListModel --> http://bugreports.qt.nokia.com/browse/QTBUG-15191
175 var itemNodes = channel.childNodes;
178 logRequest("Clearing News Model");
179 stockNewsDataModel.clear();
182 for (i = 0; i < itemNodes.length; i++) {
184 if (itemNodes[i].nodeName === 'item'){
185 var newsElements = itemNodes[i].childNodes;
187 var newsTitle,newsLink
188 for (j = 0; j < newsElements.length; j++){
190 switch (newsElements[j].nodeName){
192 newsTitle = newsElements[j].childNodes[0].nodeValue;
195 newsLink = newsElements[j].childNodes[0].nodeValue;
200 stockNewsDataModel.append({"title":newsTitle,"link":newsLink});
208 id: stockNewsDataModel
212 id: stockNewsDelegate
215 id: newsWrapper; width: stockDetailsLoader.width; height: itemHeight
218 Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 }
220 anchors {verticalCenter: parent.verticalCenter;left: parent.left;leftMargin: 10;right: parent.right}
221 text: title; font.pixelSize: 14
223 verticalAlignment: Text.AlignVCenter
224 horizontalAlignment: Text.AlignLeft
225 elide: Text.ElideRight;
230 Library.CustomGestureArea {
233 logRequest("Opening news article: "+link);
234 Qt.openUrlExternally(link);
236 onSwipeLeft: detailsRect.switchScreen()
237 onSwipeRight: detailsRect.switchScreen()
244 id: stockDetailsComponent
251 anchors.top: parent.top
253 anchors.horizontalCenter: parent.horizontalCenter
255 horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter
256 font.pixelSize: 18; font.bold: true; elide: Text.ElideMiddle; color: "#B8B8B8"; style: Text.Raised; styleColor: "black"
257 text: (stockName != "")? (stockName +" ("+symbol+")"):symbol
262 id: stockDetailsSection
264 border.color: "#BFBFBF"
266 anchors {top: stockNameLabel.bottom;left: parent.left;right: parent.right}
271 id: stockDetailsColumn
272 anchors {top: parent.top; left: parent.left; leftMargin: 10}
276 label1: "Last Traded"
277 value1: lastTradedPrice
278 cell1Width: stockDetailsColumn.width/2
280 label2: "Day's Range"
282 cell2Width: stockDetailsColumn.width/2
286 label1: "Last Trade Time"
287 value1: lastTradedDateTime
288 cell1Width: stockDetailsColumn.width/2
292 cell2Width: stockDetailsColumn.width/2
297 value1: ((change != "" && changePercentage != "")? change + " ("+changePercentage+")":"")
298 cell1Width: stockDetailsColumn.width/2
302 cell2Width: stockDetailsColumn.width/2
306 label1: "Prev. Close"
308 cell1Width: stockDetailsColumn.width/2
312 cell2Width: stockDetailsColumn.width/2
319 border.color: "#BFBFBF"
322 anchors {top: stockDetailsSection.bottom;topMargin: 5;
323 bottom: parent.bottom;
327 flickDeceleration: 500
329 model: stockNewsDataModel
330 delegate: stockNewsDelegate
332 snapMode: ListView.SnapToItem
340 id: stockDetailsLoader
341 anchors{top: parent.top; bottom: parent.bottom
342 left: parent.left; leftMargin: 10
343 right: parent.right; rightMargin: 10}
344 sourceComponent: stockDetailsComponent
347 target: stockDetailsScreen
348 onOrientationChanged: {
349 logRequest("Orientation Changed");
350 logRequest("New orientation is "+stockDetailsScreen.orientation);
351 logRequest("Margins for StockDetailsLoader are "+stockDetailsLoader.anchors.leftMargin+", "+stockDetailsLoader.anchors.rightMargin);
353 if (currentScreenIndex === 2){
354 if (stockDetailsScreen.orientation == "Landscape")
355 stockDetailsLoader.sourceComponent = stockChartComponentLandscape;
357 stockDetailsLoader.sourceComponent = stockChartComponentPortrait;
364 id: stockChartComponentLandscape
367 id: chartAreaWrapperLand
373 border.color: "#BFBFBF"
376 anchors { top: parent.top;topMargin: 40;
377 bottom: parent.bottom; bottomMargin: 40;
378 left: parent.left; right: parent.right}
381 Library.Loading { anchors.centerIn: parent; visible: chartImg.status == Image.Loading}
385 anchors {left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter}
387 sourceSize.width: 512
388 sourceSize.height: 288
390 fillMode: Image.PreserveAspectFit
394 logRequest("Image is ready");
397 logRequest("Image is loading");
400 logRequest("Image loading failed");
403 logRequest("No image specified");
410 target: stockDetailsScreen
412 chartURL = baseChartURL+"&t="+duration+"&s="+symbol;
413 logRequest(chartURL);
421 anchors {top: parent.top; topMargin: 40; bottom: parent.bottom;
422 right: chartAreaLand.right;rightMargin: 10}
427 anchors.horizontalCenter: parent.horizontalCenter
430 anchors { verticalCenter: parent.verticalCenter}
431 width: 50; height: 32
432 onClicked: loadChart("1d");
437 anchors { verticalCenter: parent.verticalCenter}
438 width: 50; height: 32
439 onClicked: loadChart("5d");
446 anchors.horizontalCenter: parent.horizontalCenter
449 anchors { verticalCenter: parent.verticalCenter}
450 width: 50; height: 32
451 onClicked: loadChart("3m");
456 anchors { verticalCenter: parent.verticalCenter}
457 width: 50; height: 32
458 onClicked: loadChart("6m");
464 anchors.horizontalCenter: parent.horizontalCenter
467 anchors { verticalCenter: parent.verticalCenter}
468 width: 50; height: 32
469 onClicked: loadChart("1y");
474 anchors { verticalCenter: parent.verticalCenter}
475 width: 50; height: 32
476 onClicked: loadChart("2y");
482 anchors.horizontalCenter: parent.horizontalCenter
485 anchors { verticalCenter: parent.verticalCenter}
486 width: 50; height: 32
487 onClicked: loadChart("5y");
492 anchors { verticalCenter: parent.verticalCenter}
493 width: 50; height: 32
494 onClicked: loadChart("my");
503 id: stockChartComponentPortrait
506 id: chartAreaWrapperPort
512 border.color: "#BFBFBF"
515 anchors { top: parent.top;topMargin: 40;
516 bottom: parent.bottom; bottomMargin: 40;
517 left: parent.left; right: parent.right}
520 Library.Loading { anchors.centerIn: parent; visible: chartImgPort.status == Image.Loading}
524 //anchors {left: parent.left; leftMargin: 10; horizontalCenter: parent.horizontalCenter}
525 anchors {horizontalCenter: parent.horizontalCenter; top: parent.top; topMargin: 40}
527 sourceSize.width: 512
528 sourceSize.height: 288
530 fillMode: Image.PreserveAspectFit
531 width: parent.width - 20
535 logRequest("Image is ready");
538 logRequest("Image is loading");
541 logRequest("Image loading failed");
544 logRequest("No image specified");
551 target: stockDetailsScreen
553 chartURL = baseChartURL+"&t="+duration+"&s="+symbol;
554 logRequest(chartURL);
562 anchors {verticalCenter: parent.verticalCenter;verticalCenterOffset: 80; horizontalCenter: parent.horizontalCenter}
567 anchors.horizontalCenter: parent.horizontalCenter
570 anchors { verticalCenter: parent.verticalCenter}
571 width: 50; height: 32
572 onClicked: loadChart("1d");
577 anchors { verticalCenter: parent.verticalCenter}
578 width: 50; height: 32
579 onClicked: loadChart("5d");
584 anchors { verticalCenter: parent.verticalCenter}
585 width: 50; height: 32
586 onClicked: loadChart("3m");
591 anchors { verticalCenter: parent.verticalCenter}
592 width: 50; height: 32
593 onClicked: loadChart("6m");
600 anchors.horizontalCenter: parent.horizontalCenter
603 anchors { verticalCenter: parent.verticalCenter}
604 width: 50; height: 32
605 onClicked: loadChart("1y");
610 anchors { verticalCenter: parent.verticalCenter}
611 width: 50; height: 32
612 onClicked: loadChart("2y");
617 anchors { verticalCenter: parent.verticalCenter}
618 width: 50; height: 32
619 onClicked: loadChart("5y");
624 anchors { verticalCenter: parent.verticalCenter}
625 width: 50; height: 32
626 onClicked: loadChart("my");