3 @author: Sudheer K. <scifi1947 at gmail.com>
4 @license: GNU General Public License
8 import "Library" as Library
9 import "Library/js/CSVUtility.js" as CSVUtility
16 id: stockDetailsScreen
17 property int componentWidth: width
18 property int itemHeight: 75
19 property int newsItemHeight: 50
20 property int fontSizeMed: 24
21 property int fontSizeSmall: 20
22 property string symbol: "YHOO"
23 property string stockName: ""
24 property string lastTradedPrice: ""
25 property string lastTradedDateTime: ""
26 property string change: ""
27 property string changePercentage: ""
28 property string daysRange: ""
29 property string yearRange: ""
30 property string marketVolume: ""
31 property string prevClose: ""
32 property string marketCap: ""
33 property string baseChartURL: "http://chart.finance.yahoo.com/z?q=&l=&z=m&p=s&a=v&p=s&lang=en-US®ion=US"
34 property string chartURL: ""
35 property string rssURL: ""
36 property string orientation: "Portrait"
38 property int currentScreenIndex: 1
40 signal logRequest(string strMessage)
41 signal loadChart(string duration)
48 Library.CustomGestureArea {
50 onSwipeLeft: detailsRect.switchScreen()
51 onSwipeRight: detailsRect.switchScreen()
54 Component.onCompleted: {
58 chartURL = baseChartURL+"&t=1d&s="+symbol;
62 function switchScreen(){
63 switch (currentScreenIndex){
65 stockDetailsLoader.sourceComponent = (stockDetailsScreen.width > stockDetailsScreen.height)? stockChartComponentLandscape : stockChartComponentPortrait;
66 currentScreenIndex = currentScreenIndex + 1;
69 stockDetailsLoader.sourceComponent = stockDetailsComponent;
70 currentScreenIndex = currentScreenIndex - 1;
75 logRequest("currentScreenIndex = "+currentScreenIndex);
78 function loadDetails(){
79 var queryURL = 'http://download.finance.yahoo.com/d/quotes.csv?s='+symbol+'&f=snl1d1t1c1p2mwvpj1&e=.csv';
80 //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';
81 logRequest("Loading stock details from "+queryURL);
82 var response = new XMLHttpRequest();
83 response.onreadystatechange = function() {
84 if (response.readyState === XMLHttpRequest.DONE) {
85 refreshDetails(response.responseText);
89 response.open("GET", queryURL);
94 rssURL = "http://feeds.finance.yahoo.com/rss/2.0/headline?region=US&lang=en-US&s="+symbol;
95 logRequest("Loading news from "+rssURL);
96 var response = new XMLHttpRequest();
97 response.onreadystatechange = function() {
98 if (response.readyState === XMLHttpRequest.DONE) {
99 refreshNewsModel(response.responseXML);
103 response.open("GET", rssURL);
107 function refreshDetails(responseText){
109 logUtility("No responseText for quote "+symbol);
113 var quoteDetails = CSVUtility.csvToArray(responseText.trim());
114 if (quoteDetails && quoteDetails.length > 0){
115 //We are only expecting one quote row per symbol.
117 var lastTradedDate = "", lastTradedTime ="";
118 stockName = quoteDetails[0][1];
119 lastTradedPrice = quoteDetails[0][2];
120 lastTradedDate = quoteDetails[0][3];
121 lastTradedTime = quoteDetails[0][4];
122 change = quoteDetails[0][5];
123 changePercentage = quoteDetails[0][6];
124 daysRange = quoteDetails[0][7];
125 yearRange = quoteDetails[0][8];
126 marketVolume = quoteDetails[0][9];
127 prevClose = quoteDetails[0][10];
128 marketCap = quoteDetails[0][11];
129 if (lastTradedDate !== "") lastTradedDateTime = lastTradedDate + " " + lastTradedTime;
132 logRequest("No results for stock quote details");
136 function refreshNewsModel(responseXML){
137 if (!(responseXML && stockNewsDataModel)) return;
139 var xmlDoc = responseXML.documentElement;
140 var channel = xmlDoc.firstChild;
142 //Not the best code I ever wrote, but got no choice
143 //Refer to Memory leak issue with XMLListModel --> http://bugreports.qt.nokia.com/browse/QTBUG-15191
146 var itemNodes = channel.childNodes;
149 logRequest("Clearing News Model");
150 stockNewsDataModel.clear();
153 for (i = 0; i < itemNodes.length; i++) {
155 if (itemNodes[i].nodeName === 'item'){
156 var newsElements = itemNodes[i].childNodes;
158 var newsTitle,newsLink
159 for (j = 0; j < newsElements.length; j++){
161 switch (newsElements[j].nodeName){
163 newsTitle = newsElements[j].childNodes[0].nodeValue;
166 newsLink = newsElements[j].childNodes[0].nodeValue;
171 stockNewsDataModel.append({"title":newsTitle,"link":newsLink});
179 id: stockNewsDataModel
183 id: stockNewsDelegate
186 id: newsWrapper; width: stockDetailsLoader.width; height: newsItemHeight
189 Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 }
191 anchors {verticalCenter: parent.verticalCenter;left: parent.left;leftMargin: 10;right: parent.right}
192 text: title; font.pixelSize: stockDetailsScreen.fontSizeSmall
194 verticalAlignment: Text.AlignVCenter
195 horizontalAlignment: Text.AlignLeft
196 elide: Text.ElideRight;
201 Library.CustomGestureArea {
204 logRequest("Opening news article: "+link);
205 Qt.openUrlExternally(link);
207 onSwipeLeft: detailsRect.switchScreen()
208 onSwipeRight: detailsRect.switchScreen()
215 id: stockDetailsComponent
222 anchors.top: parent.top
225 anchors.horizontalCenter: parent.horizontalCenter
226 height: stockDetailsScreen.fontSizeMed + 15
227 horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter
228 font.pixelSize: stockDetailsScreen.fontSizeMed; font.bold: true; elide: Text.ElideMiddle; color: "#B8B8B8"; style: Text.Raised; styleColor: "black"
229 text: (stockName != "")? (stockName +" ("+symbol+")"):symbol
234 id: stockDetailsSection
236 border.color: "#BFBFBF"
238 anchors {top: stockNameLabel.bottom;left: parent.left;right: parent.right}
240 height: (stockDetailsScreen.width > stockDetailsScreen.height)? 105:155
244 id: stockDetailsColumn
245 anchors {top: parent.top; left: parent.left; leftMargin: 10; right: parent.right; rightMargin: 10}
247 //width: parent.width
250 label1: "Last Traded"
251 value1: lastTradedPrice
252 cell1Width: stockDetailsColumn.width/2
253 multilineLabel1: false
254 landscape: (stockDetailsScreen.width > stockDetailsScreen.height)
256 label2: "Day's Range"
258 cell2Width: stockDetailsColumn.width/2
259 multilineLabel2: true
263 label1: "Last Trade Time"
264 value1: lastTradedDateTime
265 cell1Width: stockDetailsColumn.width/2
266 multilineLabel1: true
267 landscape: (stockDetailsScreen.width > stockDetailsScreen.height)
271 cell2Width: stockDetailsColumn.width/2
272 multilineLabel2: true
277 value1: ((change != "" && changePercentage != "")? change + " ("+changePercentage+")":"")
278 cell1Width: stockDetailsColumn.width/2
279 landscape: (stockDetailsScreen.width > stockDetailsScreen.height)
283 cell2Width: stockDetailsColumn.width/2
287 label1: "Prev. Close"
289 cell1Width: stockDetailsColumn.width/2
290 landscape: (stockDetailsScreen.width > stockDetailsScreen.height)
294 cell2Width: stockDetailsColumn.width/2
301 border.color: "#BFBFBF"
304 anchors {top: stockDetailsSection.bottom;topMargin: 10;
305 bottom: parent.bottom;
309 flickDeceleration: 500
311 model: stockNewsDataModel
312 delegate: stockNewsDelegate
314 snapMode: ListView.SnapToItem
322 id: stockDetailsLoader
323 anchors{top: parent.top; bottom: parent.bottom; bottomMargin: 20;
324 left: parent.left; leftMargin: 10
325 right: parent.right; rightMargin: 10}
326 sourceComponent: stockDetailsComponent
329 target: stockDetailsScreen
330 onOrientationChanged: {
331 logRequest("Orientation Changed");
332 logRequest("New orientation is "+stockDetailsScreen.orientation);
333 logRequest("Margins for StockDetailsLoader are "+stockDetailsLoader.anchors.leftMargin+", "+stockDetailsLoader.anchors.rightMargin);
335 if (currentScreenIndex === 2){
336 if (stockDetailsScreen.orientation == "Landscape")
337 stockDetailsLoader.sourceComponent = stockChartComponentLandscape;
339 stockDetailsLoader.sourceComponent = stockChartComponentPortrait;
351 anchors.top: stockDetailsLoader.bottom
355 text: "Swipe horizontally to switch between details and charts."
356 horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
357 width: parent.width; font.pixelSize: 12; elide: Text.ElideRight;
359 style: Text.Raised; styleColor: "black"
363 id: footerMessageTimer
367 footerMessage.text = "";
371 Component.onCompleted: {
372 footerMessageTimer.start();
377 id: stockChartComponentLandscape
380 id: chartAreaWrapperLand
386 border.color: "#BFBFBF"
389 anchors { top: parent.top;topMargin: 40;
390 bottom: parent.bottom; bottomMargin: 20;
391 left: parent.left; right: parent.right}
394 Library.Loading { anchors.centerIn: parent; visible: chartImg.status == Image.Loading}
398 anchors {left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter}
400 sourceSize.width: 512
401 sourceSize.height: 288
403 fillMode: Image.PreserveAspectFit
407 logRequest("Image is ready");
410 logRequest("Image is loading");
413 logRequest("Image loading failed");
416 logRequest("No image specified");
423 target: stockDetailsScreen
425 chartURL = baseChartURL+"&t="+duration+"&s="+symbol;
426 logRequest(chartURL);
434 anchors {top: parent.top; topMargin: 40; bottom: parent.bottom;
435 right: chartAreaLand.right;rightMargin: 60}
440 anchors.horizontalCenter: parent.horizontalCenter
443 anchors { verticalCenter: parent.verticalCenter}
444 width: 75; height: 40
445 onClicked: loadChart("1d");
450 anchors { verticalCenter: parent.verticalCenter}
451 width: 75; height: 40
452 onClicked: loadChart("5d");
459 anchors.horizontalCenter: parent.horizontalCenter
462 anchors { verticalCenter: parent.verticalCenter}
463 width: 75; height: 40
464 onClicked: loadChart("3m");
469 anchors { verticalCenter: parent.verticalCenter}
470 width: 75; height: 40
471 onClicked: loadChart("6m");
477 anchors.horizontalCenter: parent.horizontalCenter
480 anchors { verticalCenter: parent.verticalCenter}
481 width: 75; height: 40
482 onClicked: loadChart("1y");
487 anchors { verticalCenter: parent.verticalCenter}
488 width: 75; height: 40
489 onClicked: loadChart("2y");
495 anchors.horizontalCenter: parent.horizontalCenter
498 anchors { verticalCenter: parent.verticalCenter}
499 width: 75; height: 40
500 onClicked: loadChart("5y");
505 anchors { verticalCenter: parent.verticalCenter}
506 width: 75; height: 40
507 onClicked: loadChart("my");
516 id: stockChartComponentPortrait
519 id: chartAreaWrapperPort
525 border.color: "#BFBFBF"
528 anchors { top: parent.top;topMargin: 40;
529 bottom: parent.bottom; bottomMargin: 20;
530 left: parent.left; right: parent.right}
533 Library.Loading { anchors.centerIn: parent; visible: chartImgPort.status == Image.Loading}
537 //anchors {left: parent.left; leftMargin: 10; horizontalCenter: parent.horizontalCenter}
538 anchors {horizontalCenter: parent.horizontalCenter; top: parent.top; topMargin: 40}
540 sourceSize.width: 512
541 sourceSize.height: 288
543 fillMode: Image.PreserveAspectFit
544 width: parent.width - 20
548 logRequest("Image is ready");
551 logRequest("Image is loading");
554 logRequest("Image loading failed");
557 logRequest("No image specified");
564 target: stockDetailsScreen
566 chartURL = baseChartURL+"&t="+duration+"&s="+symbol;
567 logRequest(chartURL);
575 anchors {verticalCenter: parent.verticalCenter;verticalCenterOffset: 100; horizontalCenter: parent.horizontalCenter}
580 anchors.horizontalCenter: parent.horizontalCenter
583 anchors { verticalCenter: parent.verticalCenter}
584 width: 75; height: 40
585 onClicked: loadChart("1d");
590 anchors { verticalCenter: parent.verticalCenter}
591 width: 75; height: 40
592 onClicked: loadChart("5d");
597 anchors { verticalCenter: parent.verticalCenter}
598 width: 75; height: 40
599 onClicked: loadChart("3m");
604 anchors { verticalCenter: parent.verticalCenter}
605 width: 75; height: 40
606 onClicked: loadChart("6m");
613 anchors.horizontalCenter: parent.horizontalCenter
616 anchors { verticalCenter: parent.verticalCenter}
617 width: 75; height: 40
618 onClicked: loadChart("1y");
623 anchors { verticalCenter: parent.verticalCenter}
624 width: 75; height: 40
625 onClicked: loadChart("2y");
630 anchors { verticalCenter: parent.verticalCenter}
631 width: 75; height: 40
632 onClicked: loadChart("5y");
637 anchors { verticalCenter: parent.verticalCenter}
638 width: 75; height: 40
639 onClicked: loadChart("my");