010331c084865d9c0e275019e7e4d6f220ae5c41
[marketstoday] / src / qml / MarketsTodayLegacyApp.qml
1 /*
2 @version: 0.4
3 @author: Sudheer K. <scifi1947 at gmail.com>
4 @license: GNU General Public License
5 */
6
7 import Qt 4.7
8
9 import "Library" as Library
10 import "Library/js/ISODate.js" as DateLib
11 import "Library/js/DBUtility.js" as DBUtility
12 import "Library/js/CSVUtility.js" as CSVUtility
13 import "Library/js/Common.js" as Common
14 import "Library/js/CoreLogic.js" as CoreLib
15
16 Item {
17     id: mainPage
18
19     signal showConfigInNewWindow
20     signal showStockDetails(string strSymbol)
21     signal quoteRefreshStarted
22     signal quoteRefreshCompleted(bool success, string strMessage)
23     signal newsReloadCompleted(bool success, string strMessage)
24     signal checkNetworkStatus
25
26     property int itemHeight: 50
27     property int titleBarHeight: 60
28     property int toolBarHeight: 40
29     property int componentWidth: mainPage.width
30     property int autoUpdateInterval: 300000
31     property bool updateWeekDaysOnly: false
32     property bool updateOnSavedNetworksOnly: false
33     property bool isDesktopWidget: false
34     property string rssURL: "http://finance.yahoo.com/rss/topfinstories"
35     property string lastUpdatedTimeStamp
36     //property string selectedSymbol:"YHOO"
37     property string selectedSymbol:sharedContext.getStockSymbol()
38
39     function reloadData(){
40         CoreLib.reloadQuotes();
41         CoreLib.reloadNews();
42     }
43
44     function initialize(){        
45         var componentToDisplay = sharedContext.getComponentToDisplay();
46         if (componentToDisplay === "StockQuoteDetails"){
47             uiLoader.sourceComponent = stockDetailsComponent;
48             titleBar.buttonType = "Close";
49             titleBar.displayMenu = false;
50             toolBar.displayIcons = false;
51         }
52         else{
53             DBUtility.initialize();
54             uiLoader.sourceComponent = stockQuotesUIComponent;
55             CoreLib.initialize();            
56         }
57     }
58
59     Component.onCompleted: {
60         initialize();
61     }
62
63     Timer {
64         id: autoUpdateTimer
65         interval: autoUpdateInterval
66         //running: (autoUpdateInterval == 0? false:true)
67         repeat: true
68         onTriggered: {
69             if (!updateWeekDaysOnly){
70                 logUtility.logMessage("Allowed to update all days of the week");
71                 mainPage.reloadData();
72                 //checkNetworkStatus();
73             }
74             else if (Common.isTodayAWeekDay()){
75                 logUtility.logMessage("Today is a weekday");
76                 mainPage.reloadData();
77                 //checkNetworkStatus();
78             }
79             else{
80                 logUtility.logMessage("Update not triggered: Today is not a weekday");
81             }
82         }
83     }
84
85     ListModel{
86         id: stockQuoteDataModel
87     }
88
89     ListModel {
90         id: newsDataModel
91     }
92
93     Rectangle {
94         id: background
95         anchors.fill: parent;
96         color: "#343434"
97         clip: true
98
99         Component {
100             id: stockQuotesDelegate
101
102             Item {
103                 id: wrapper; width: mainPage.componentWidth; height: mainPage.itemHeight
104                 Item {
105                     Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: wrapper.height - 2; width: wrapper.width; y: 1
106                         MouseArea {
107                             anchors.fill: parent
108                             onDoubleClicked: {
109                                 mainPage.selectedSymbol = symbol;
110                                 uiLoader.sourceComponent = stockDetailsComponent;
111                                 titleBar.buttonType = "Back";
112                                 titleBar.displayMenu = false;
113                                 toolBar.displayIcons = false;
114                             }
115                         }
116                         /*
117                         Image{
118                             id: informationIcon
119                             width: 32
120                             height: 32
121                             z: 10
122                             anchors {right: parent.right; rightMargin: 10; verticalCenter: parent.verticalCenter}
123                             visible: false
124                             source: "Library/images/information.png"
125                             MouseArea{
126                                 anchors.fill: parent;
127                                 onPressed: {
128                                     //console.log("Image clicked");
129                                     mainPage.selectedSymbol = symbol;
130                                     uiLoader.sourceComponent = stockDetailsComponent;
131                                     titleBar.buttonType = "Back";
132                                     titleBar.displayMenu = false;
133                                     toolBar.displayIcons = false;
134                                 }
135                             }
136                         }
137
138                         MouseArea {
139                             anchors.fill: parent
140                             onPressed:{
141                                 informationIcon.visible = true;
142                                 //console.log("Rectangle clicked");
143                             }
144                         }
145                         */
146                     }
147
148                     Row {
149                         x: 30;y: 15;
150                         width: mainPage.componentWidth - 60;
151                         spacing: 5
152
153                         Text { text: stockName; width: parent.width * 30/100; font.pixelSize: 18; font.bold: true; elide: Text.ElideRight; color: "white"; style: Text.Raised; styleColor: "black" }
154                         Text { text: lastTradedPrice; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" }
155                         Text { text: change !== ""? (change + " ("+changePercentage+")"):""; width: parent.width * 25/100;  font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideRight
156                                 color: if(change >= 0){"green";} else {"red";}
157                                     style: Text.Raised; styleColor: "black" }
158                         Text { text: volume; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" }
159                         Text { text: marketCap; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" }
160                     }
161                 }
162             }
163         }
164
165         Component {
166             id: newsDelegate
167
168             Item {
169                 id: newsWrapper; width: mainPage.componentWidth; height: mainPage.itemHeight
170                 Item {
171                     anchors.fill: parent
172                     Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 }
173                     Text {
174                         anchors.verticalCenter: parent.verticalCenter
175                         anchors.left: parent.left
176                         anchors.leftMargin: 10
177                         anchors.right: parent.right
178                         text: title; font.pixelSize: 18
179                         font.bold: false;
180                         verticalAlignment: Text.AlignVCenter
181                         horizontalAlignment: Text.AlignLeft
182                         elide: Text.ElideRight;
183                         color: "white";
184                         style: Text.Raised;
185                         styleColor: "black"
186                     }
187                     MouseArea{
188                         anchors.fill: parent
189                         onDoubleClicked: Qt.openUrlExternally(link);
190                     }
191                 }
192             }
193         }
194
195         Library.TitleBar {
196             id: titleBar;
197             width: parent.width; height: mainPage.titleBarHeight;
198             anchors.top: parent.top
199             title: "Markets Today";
200             buttonType: "Close";
201             z: 5  //required to keep Titlebar and Menu buttons on top of everything else
202
203             onCloseClicked: Qt.quit()
204
205             onTickersClicked: {
206                 uiLoader.sourceComponent = configTickersComponent;
207                 titleBar.buttonType = "Back";
208                 titleBar.displayMenu = false;
209                 toolBar.displayIcons = false;
210             }
211
212             onOptionsClicked: {
213                 uiLoader.sourceComponent = configParamsComponent;
214                 titleBar.buttonType = "Back";
215                 titleBar.displayMenu = false;
216                 toolBar.displayIcons = false;
217             }
218
219             onBackClicked: {
220                 uiLoader.sourceComponent = stockQuotesUIComponent;
221                 titleBar.buttonType = "Close";
222                 titleBar.displayMenu = false;
223                 toolBar.displayIcons = true;
224                 mainPage.initialize();
225             }
226         }
227
228         Loader {
229             id: uiLoader
230             width: parent.width
231             anchors.top: titleBar.bottom
232             anchors.bottom: toolBar.top            
233         }
234
235         Library.ToolBar {
236             id:toolBar
237             width: parent.width; height: mainPage.toolBarHeight
238             anchors.bottom: parent.bottom
239             opacity: 0.9
240             displayNavigation: false
241             onReloadButtonClicked: mainPage.reloadData();
242
243             onNewsButtonClicked: {
244                 uiLoader.sourceComponent = newsComponent;
245                 toolBar.displayIcons = true;
246                 toolBar.targetContentType = "Stocks";
247             }
248
249             onStocksButtonClicked: {
250                 uiLoader.sourceComponent = stockQuotesUIComponent;
251                 toolBar.displayIcons = true;
252                 toolBar.targetContentType = "News";
253             }
254
255
256             Connections {
257                 target: mainPage
258                 onQuoteRefreshStarted:{
259                     if (!toolBar.updatePending) toolBar.updatePending = true;
260                 }
261                 onQuoteRefreshCompleted:{
262                     toolBar.updatePending = false;
263                 }
264             }
265         }
266
267
268
269         Component {
270             id: stockQuotesUIComponent
271             Item {
272                 Rectangle{
273                     id: listViewWrapper
274                     width: parent.width
275                     anchors.top: parent.top
276                     anchors.bottom: footerTextArea.top
277                     color: "#343434"
278
279                     ListView {
280                         id: stockQuotesView
281                         anchors.fill: parent
282                         flickDeceleration: 500
283                         model: stockQuoteDataModel
284                         delegate:  stockQuotesDelegate
285                         focus:true
286                         snapMode: ListView.SnapToItem
287                     }
288                 }
289
290                 Rectangle {
291                     id: stockStatusMsgArea
292                     height: 100
293                     color: "#343434"
294                     anchors {left: parent.left; leftMargin: 15; right: parent.right; rightMargin: 15;
295                             verticalCenter: parent.verticalCenter}
296                     visible: false
297
298                     Text {
299                         id: stockStatusText
300                         anchors.fill: parent
301                         text: "Loading quotes.."
302                         horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter
303                         width: parent.width; font.pixelSize: 16; elide: Text.ElideNone;
304                         color: "#cccccc"
305                         wrapMode: Text.WrapAtWordBoundaryOrAnywhere
306                         style: Text.Raised; styleColor: "black"
307
308                         Connections {
309                             target: mainPage
310                             onQuoteRefreshCompleted: {
311                                 if (success){
312                                     stockStatusMsgArea.visible = false;
313                                     listViewWrapper.visible = true;
314                                 }
315                                 else{
316                                     stockStatusText.text = strMessage;
317                                     listViewWrapper.visible = false;
318                                     stockStatusMsgArea.visible = true;
319                                 }
320                             }
321                         }
322                     }
323                 }
324
325                 Rectangle{
326                     id: footerTextArea
327                     width: parent.width
328                     height: 25
329                     color: "#343434"
330                     anchors.bottom: parent.bottom
331                     Text {
332                         id: footerMessage
333                         anchors.fill: parent
334                         text: mainPage.lastUpdatedTimeStamp
335                         horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
336                         width: parent.width; font.pixelSize: 12; elide: Text.ElideRight;
337                         color: "#cccccc"
338                         style: Text.Raised; styleColor: "black"                        
339                     }
340
341                     Timer {
342                         id: footerMessageTimer
343                         interval: 10000
344                         repeat: false
345                         onTriggered: {
346                             footerMessage.text = mainPage.lastUpdatedTimeStamp;
347                         }
348                     }
349
350                     Connections {
351                         target: mainPage
352                         onQuoteRefreshCompleted:{
353                             if (success){
354                                 footerMessage.text = "Double-tap on a row to display more details.";
355                                 footerMessageTimer.start();
356                             }
357                             else{
358                                 footerMessage.text = mainPage.lastUpdatedTimeStamp;
359                             }
360                         }
361                     }
362                 }
363             }
364         }
365
366         Component{
367             id: stockDetailsComponent
368             StockDetailsComponent {
369                 symbol: selectedSymbol
370                 onLogRequest: logUtility.logMessage(strMessage)
371             }
372         }
373
374         Component {
375             id: newsComponent
376             Item {
377                 Rectangle{
378                     id: newsViewArea
379                     width: parent.width
380                     anchors.top: parent.top
381                     anchors.bottom: parent.bottom
382                     color: "#343434"
383
384                     ListView {
385                         id: newsView
386                         anchors.fill: parent
387                         flickDeceleration: 500
388                         model: newsDataModel
389                         delegate:  newsDelegate
390                         focus:true
391                         snapMode: ListView.SnapToItem
392                     }
393                 }
394
395                 Rectangle {
396                     id: newsStatusMsgArea
397                     height: 100
398                     color: "#343434"
399                     anchors {left: parent.left; leftMargin: 15; right: parent.right; rightMargin: 15;
400                             verticalCenter: parent.verticalCenter}
401                     visible: false
402
403                     Text {
404                         id: newsStatusText
405                         anchors.fill: parent
406                         text: "Loading news.."
407                         horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter
408                         width: parent.width; font.pixelSize: 16; elide: Text.ElideNone;
409                         color: "#cccccc"
410                         wrapMode: Text.WrapAtWordBoundaryOrAnywhere
411                         style: Text.Raised; styleColor: "black"
412
413                         Connections {
414                             target: mainPage
415                             onNewsReloadCompleted: {
416                                 if (success){
417                                     newsStatusMsgArea.visible = false;
418                                     newsViewArea.visible = true;
419                                 }
420                                 else{
421                                     newsStatusText.text = strMessage;
422                                     newsViewArea.visible = false;
423                                     newsStatusMsgArea.visible = true;
424                                 }
425                             }
426                         }
427                     }
428                 }
429             }
430         }                
431
432         Component {
433             id: configTickersComponent
434
435             ConfigTickersComponent{
436                 itemHeight: mainPage.itemHeight
437                 componentWidth: mainPage.componentWidth
438                 onLogRequest: logUtility.logMessage(strMessage)
439             }
440         }
441
442         Component {
443             id: configParamsComponent
444             ConfigParametersComponent{
445                 onLogRequest: logUtility.logMessage(strMessage)
446             }
447         }       
448     }
449 }