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 fontSizeMed: 24
20 property int fontSizeSmall: 20
21 property string symbol: "YHOO"
22 property string stockName: ""
23 property string lastTradedPrice: ""
24 property string lastTradedDateTime: ""
25 property string change: ""
26 property string changePercentage: ""
27 property string daysRange: ""
28 property string yearRange: ""
29 property string marketVolume: ""
30 property string prevClose: ""
31 property string marketCap: ""
32 property string baseChartURL: "http://chart.finance.yahoo.com/z?q=&l=&z=m&p=s&a=v&p=s&lang=en-US®ion=US"
33 property string chartURL: ""
34 property string rssURL: ""
35 property string orientation: "Portrait"
37 property int currentScreenIndex: 1
39 signal logRequest(string strMessage)
40 signal loadChart(string duration)
47 Library.CustomGestureArea {
49 onSwipeLeft: detailsRect.switchScreen()
50 onSwipeRight: detailsRect.switchScreen()
53 Component.onCompleted: {
57 chartURL = baseChartURL+"&t=1d&s="+symbol;
61 function switchScreen(){
62 switch (currentScreenIndex){
64 stockDetailsLoader.sourceComponent = (stockDetailsScreen.width > stockDetailsScreen.height)? stockChartComponentLandscape : stockChartComponentPortrait;
65 currentScreenIndex = currentScreenIndex + 1;
68 stockDetailsLoader.sourceComponent = stockDetailsComponent;
69 currentScreenIndex = currentScreenIndex - 1;
74 logRequest("currentScreenIndex = "+currentScreenIndex);
77 function loadDetails(){
78 var queryURL = 'http://download.finance.yahoo.com/d/quotes.csv?s='+symbol+'&f=snl1d1t1c1p2mwvpj1&e=.csv';
79 //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';
80 logRequest("Loading stock details from "+queryURL);
81 var response = new XMLHttpRequest();
82 response.onreadystatechange = function() {
83 if (response.readyState === XMLHttpRequest.DONE) {
84 refreshDetails(response.responseText);
88 response.open("GET", queryURL);
93 rssURL = "http://feeds.finance.yahoo.com/rss/2.0/headline?region=US&lang=en-US&s="+symbol;
94 logRequest("Loading news from "+rssURL);
95 var response = new XMLHttpRequest();
96 response.onreadystatechange = function() {
97 if (response.readyState === XMLHttpRequest.DONE) {
98 refreshNewsModel(response.responseXML);
102 response.open("GET", rssURL);
106 function refreshDetails(responseText){
108 logUtility("No responseText for quote "+symbol);
112 var quoteDetails = CSVUtility.csvToArray(responseText.trim());
113 if (quoteDetails && quoteDetails.length > 0){
114 //We are only expecting one quote row per symbol.
116 var lastTradedDate = "", lastTradedTime ="";
117 stockName = quoteDetails[0][1];
118 lastTradedPrice = quoteDetails[0][2];
119 lastTradedDate = quoteDetails[0][3];
120 lastTradedTime = quoteDetails[0][4];
121 change = quoteDetails[0][5];
122 changePercentage = quoteDetails[0][6];
123 daysRange = quoteDetails[0][7];
124 yearRange = quoteDetails[0][8];
125 marketVolume = quoteDetails[0][9];
126 prevClose = quoteDetails[0][10];
127 marketCap = quoteDetails[0][11];
128 if (lastTradedDate !== "") lastTradedDateTime = lastTradedDate + " " + lastTradedTime;
131 logRequest("No results for stock quote details");
135 function refreshNewsModel(responseXML){
136 if (!(responseXML && stockNewsDataModel)) return;
138 var xmlDoc = responseXML.documentElement;
139 var channel = xmlDoc.firstChild;
141 //Not the best code I ever wrote, but got no choice
142 //Refer to Memory leak issue with XMLListModel --> http://bugreports.qt.nokia.com/browse/QTBUG-15191
145 var itemNodes = channel.childNodes;
148 logRequest("Clearing News Model");
149 stockNewsDataModel.clear();
152 for (i = 0; i < itemNodes.length; i++) {
154 if (itemNodes[i].nodeName === 'item'){
155 var newsElements = itemNodes[i].childNodes;
157 var newsTitle,newsLink
158 for (j = 0; j < newsElements.length; j++){
160 switch (newsElements[j].nodeName){
162 newsTitle = newsElements[j].childNodes[0].nodeValue;
165 newsLink = newsElements[j].childNodes[0].nodeValue;
170 stockNewsDataModel.append({"title":newsTitle,"link":newsLink});
178 id: stockNewsDataModel
182 id: stockNewsDelegate
185 id: newsWrapper; width: stockDetailsLoader.width; height: itemHeight
188 Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 }
190 anchors {verticalCenter: parent.verticalCenter;left: parent.left;leftMargin: 10;right: parent.right}
191 text: title; font.pixelSize: stockDetailsScreen.fontSizeSmall
193 verticalAlignment: Text.AlignVCenter
194 horizontalAlignment: Text.AlignLeft
195 elide: Text.ElideRight;
200 Library.CustomGestureArea {
203 logRequest("Opening news article: "+link);
204 Qt.openUrlExternally(link);
206 onSwipeLeft: detailsRect.switchScreen()
207 onSwipeRight: detailsRect.switchScreen()
214 id: stockDetailsComponent
221 anchors.top: parent.top
223 anchors.horizontalCenter: parent.horizontalCenter
224 height: stockDetailsScreen.fontSizeMed + 15
225 horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter
226 font.pixelSize: stockDetailsScreen.fontSizeMed; font.bold: true; elide: Text.ElideMiddle; color: "#B8B8B8"; style: Text.Raised; styleColor: "black"
227 text: (stockName != "")? (stockName +" ("+symbol+")"):symbol
232 id: stockDetailsSection
234 border.color: "#BFBFBF"
236 anchors {top: stockNameLabel.bottom;left: parent.left;right: parent.right}
237 height: (stockDetailsScreen.width > stockDetailsScreen.height)? 105:155
241 id: stockDetailsColumn
242 anchors {top: parent.top; left: parent.left; leftMargin: 10; right: parent.right; rightMargin: 10}
244 //width: parent.width
247 label1: "Last Traded"
248 value1: lastTradedPrice
249 cell1Width: stockDetailsColumn.width/2
250 multilineLabel1: false
251 landscape: (stockDetailsScreen.width > stockDetailsScreen.height)
253 label2: "Day's Range"
255 cell2Width: stockDetailsColumn.width/2
256 multilineLabel2: true
260 label1: "Last Trade Time"
261 value1: lastTradedDateTime
262 cell1Width: stockDetailsColumn.width/2
263 multilineLabel1: true
264 landscape: (stockDetailsScreen.width > stockDetailsScreen.height)
268 cell2Width: stockDetailsColumn.width/2
269 multilineLabel2: true
274 value1: ((change != "" && changePercentage != "")? change + " ("+changePercentage+")":"")
275 cell1Width: stockDetailsColumn.width/2
276 landscape: (stockDetailsScreen.width > stockDetailsScreen.height)
280 cell2Width: stockDetailsColumn.width/2
284 label1: "Prev. Close"
286 cell1Width: stockDetailsColumn.width/2
287 landscape: (stockDetailsScreen.width > stockDetailsScreen.height)
291 cell2Width: stockDetailsColumn.width/2
298 border.color: "#BFBFBF"
301 anchors {top: stockDetailsSection.bottom;topMargin: 10;
302 bottom: parent.bottom;
306 flickDeceleration: 500
308 model: stockNewsDataModel
309 delegate: stockNewsDelegate
311 snapMode: ListView.SnapToItem
319 id: stockDetailsLoader
320 anchors{top: parent.top; bottom: parent.bottom; bottomMargin: 20;
321 left: parent.left; leftMargin: 10
322 right: parent.right; rightMargin: 10}
323 sourceComponent: stockDetailsComponent
326 target: stockDetailsScreen
327 onOrientationChanged: {
328 logRequest("Orientation Changed");
329 logRequest("New orientation is "+stockDetailsScreen.orientation);
330 logRequest("Margins for StockDetailsLoader are "+stockDetailsLoader.anchors.leftMargin+", "+stockDetailsLoader.anchors.rightMargin);
332 if (currentScreenIndex === 2){
333 if (stockDetailsScreen.orientation == "Landscape")
334 stockDetailsLoader.sourceComponent = stockChartComponentLandscape;
336 stockDetailsLoader.sourceComponent = stockChartComponentPortrait;
348 anchors.top: stockDetailsLoader.bottom
352 text: "Swipe horizontally to switch between details and charts."
353 horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
354 width: parent.width; font.pixelSize: 12; elide: Text.ElideRight;
356 style: Text.Raised; styleColor: "black"
360 id: footerMessageTimer
364 footerMessage.text = "";
368 Component.onCompleted: {
369 footerMessageTimer.start();
374 id: stockChartComponentLandscape
377 id: chartAreaWrapperLand
383 border.color: "#BFBFBF"
386 anchors { top: parent.top;topMargin: 40;
387 bottom: parent.bottom; bottomMargin: 20;
388 left: parent.left; right: parent.right}
391 Library.Loading { anchors.centerIn: parent; visible: chartImg.status == Image.Loading}
395 anchors {left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter}
397 sourceSize.width: 512
398 sourceSize.height: 288
400 fillMode: Image.PreserveAspectFit
404 logRequest("Image is ready");
407 logRequest("Image is loading");
410 logRequest("Image loading failed");
413 logRequest("No image specified");
420 target: stockDetailsScreen
422 chartURL = baseChartURL+"&t="+duration+"&s="+symbol;
423 logRequest(chartURL);
431 anchors {top: parent.top; topMargin: 40; bottom: parent.bottom;
432 right: chartAreaLand.right;rightMargin: 60}
437 anchors.horizontalCenter: parent.horizontalCenter
440 anchors { verticalCenter: parent.verticalCenter}
441 width: 75; height: 40
442 onClicked: loadChart("1d");
447 anchors { verticalCenter: parent.verticalCenter}
448 width: 75; height: 40
449 onClicked: loadChart("5d");
456 anchors.horizontalCenter: parent.horizontalCenter
459 anchors { verticalCenter: parent.verticalCenter}
460 width: 75; height: 40
461 onClicked: loadChart("3m");
466 anchors { verticalCenter: parent.verticalCenter}
467 width: 75; height: 40
468 onClicked: loadChart("6m");
474 anchors.horizontalCenter: parent.horizontalCenter
477 anchors { verticalCenter: parent.verticalCenter}
478 width: 75; height: 40
479 onClicked: loadChart("1y");
484 anchors { verticalCenter: parent.verticalCenter}
485 width: 75; height: 40
486 onClicked: loadChart("2y");
492 anchors.horizontalCenter: parent.horizontalCenter
495 anchors { verticalCenter: parent.verticalCenter}
496 width: 75; height: 40
497 onClicked: loadChart("5y");
502 anchors { verticalCenter: parent.verticalCenter}
503 width: 75; height: 40
504 onClicked: loadChart("my");
513 id: stockChartComponentPortrait
516 id: chartAreaWrapperPort
522 border.color: "#BFBFBF"
525 anchors { top: parent.top;topMargin: 40;
526 bottom: parent.bottom; bottomMargin: 20;
527 left: parent.left; right: parent.right}
530 Library.Loading { anchors.centerIn: parent; visible: chartImgPort.status == Image.Loading}
534 //anchors {left: parent.left; leftMargin: 10; horizontalCenter: parent.horizontalCenter}
535 anchors {horizontalCenter: parent.horizontalCenter; top: parent.top; topMargin: 40}
537 sourceSize.width: 512
538 sourceSize.height: 288
540 fillMode: Image.PreserveAspectFit
541 width: parent.width - 20
545 logRequest("Image is ready");
548 logRequest("Image is loading");
551 logRequest("Image loading failed");
554 logRequest("No image specified");
561 target: stockDetailsScreen
563 chartURL = baseChartURL+"&t="+duration+"&s="+symbol;
564 logRequest(chartURL);
572 anchors {verticalCenter: parent.verticalCenter;verticalCenterOffset: 100; horizontalCenter: parent.horizontalCenter}
577 anchors.horizontalCenter: parent.horizontalCenter
580 anchors { verticalCenter: parent.verticalCenter}
581 width: 75; height: 40
582 onClicked: loadChart("1d");
587 anchors { verticalCenter: parent.verticalCenter}
588 width: 75; height: 40
589 onClicked: loadChart("5d");
594 anchors { verticalCenter: parent.verticalCenter}
595 width: 75; height: 40
596 onClicked: loadChart("3m");
601 anchors { verticalCenter: parent.verticalCenter}
602 width: 75; height: 40
603 onClicked: loadChart("6m");
610 anchors.horizontalCenter: parent.horizontalCenter
613 anchors { verticalCenter: parent.verticalCenter}
614 width: 75; height: 40
615 onClicked: loadChart("1y");
620 anchors { verticalCenter: parent.verticalCenter}
621 width: 75; height: 40
622 onClicked: loadChart("2y");
627 anchors { verticalCenter: parent.verticalCenter}
628 width: 75; height: 40
629 onClicked: loadChart("5y");
634 anchors { verticalCenter: parent.verticalCenter}
635 width: 75; height: 40
636 onClicked: loadChart("my");