Harmattan font changes completed
[marketstoday] / src / qml / MarketsTodayLegacyApp.qml
1 /*
2 @version: 0.5
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                     }
118
119                     Row {
120                         x: 30;y: 15;
121                         width: mainPage.componentWidth - 60;
122                         spacing: 5
123
124                         Text { text: stockName; width: parent.width * 30/100; font.pixelSize: 18; font.bold: true; elide: Text.ElideRight; color: "white"; style: Text.Raised; styleColor: "black" }
125                         Text { text: lastTradedPrice; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" }
126                         Text { text: change !== ""? (change + " ("+changePercentage+")"):""; width: parent.width * 25/100;  font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideRight
127                                 color: change >= 0 ? "#00ff00":"#ff0000";
128                                     style: Text.Raised; styleColor: "black" }
129                         Text { text: volume; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" }
130                         Text { text: marketCap; width: parent.width * 15/100; font.pixelSize: 18; horizontalAlignment: Text.AlignLeft; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" }
131                     }
132                 }
133             }
134         }
135
136         Component {
137             id: newsDelegate
138
139             Item {
140                 id: newsWrapper; width: mainPage.componentWidth; height: mainPage.itemHeight
141                 Item {
142                     anchors.fill: parent
143                     Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 }
144                     Text {
145                         anchors.verticalCenter: parent.verticalCenter
146                         anchors.left: parent.left
147                         anchors.leftMargin: 10
148                         anchors.right: parent.right
149                         text: title; font.pixelSize: 18
150                         font.bold: false;
151                         verticalAlignment: Text.AlignVCenter
152                         horizontalAlignment: Text.AlignLeft
153                         elide: Text.ElideRight;
154                         color: "white";
155                         style: Text.Raised;
156                         styleColor: "black"
157                     }
158                     MouseArea{
159                         anchors.fill: parent
160                         onDoubleClicked: Qt.openUrlExternally(link);
161                     }
162                 }
163             }
164         }
165
166         Library.TitleBar {
167             id: titleBar;
168             width: parent.width; height: mainPage.titleBarHeight;
169             anchors.top: parent.top
170             title: "Markets Today";
171             buttonType: "Close";
172             z: 5  //required to keep Titlebar and Menu buttons on top of everything else
173
174             onCloseClicked: Qt.quit()
175
176             onTickersClicked: {
177                 uiLoader.sourceComponent = configTickersComponent;
178                 titleBar.buttonType = "Back";
179                 titleBar.displayMenu = false;
180                 toolBar.displayIcons = false;
181             }
182
183             onOptionsClicked: {
184                 uiLoader.sourceComponent = configParamsComponent;
185                 titleBar.buttonType = "Back";
186                 titleBar.displayMenu = false;
187                 toolBar.displayIcons = false;
188             }
189
190             onBackClicked: {
191                 uiLoader.sourceComponent = stockQuotesUIComponent;
192                 titleBar.buttonType = "Close";
193                 titleBar.displayMenu = false;
194                 toolBar.displayIcons = true;
195                 mainPage.initialize();
196             }
197         }
198
199         Loader {
200             id: uiLoader
201             width: parent.width
202             anchors.top: titleBar.bottom
203             anchors.bottom: toolBar.top            
204         }
205
206         Library.ToolBar {
207             id:toolBar
208             width: parent.width; height: mainPage.toolBarHeight
209             anchors.bottom: parent.bottom
210             opacity: 0.9
211             displayNavigation: false
212             onReloadButtonClicked: mainPage.reloadData();
213
214             onNewsButtonClicked: {
215                 uiLoader.sourceComponent = newsComponent;
216                 toolBar.displayIcons = true;
217                 toolBar.targetContentType = "Stocks";
218             }
219
220             onStocksButtonClicked: {
221                 uiLoader.sourceComponent = stockQuotesUIComponent;
222                 toolBar.displayIcons = true;
223                 toolBar.targetContentType = "News";
224             }
225
226
227             Connections {
228                 target: mainPage
229                 onQuoteRefreshStarted:{
230                     if (!toolBar.updatePending) toolBar.updatePending = true;
231                 }
232                 onQuoteRefreshCompleted:{
233                     toolBar.updatePending = false;
234                 }
235             }
236         }
237
238
239
240         Component {
241             id: stockQuotesUIComponent
242             Item {
243                 Rectangle{
244                     id: listViewWrapper
245                     width: parent.width
246                     anchors.top: parent.top
247                     anchors.bottom: footerTextArea.top
248                     color: "#343434"
249
250                     ListView {
251                         id: stockQuotesView
252                         anchors.fill: parent
253                         flickDeceleration: 500
254                         model: stockQuoteDataModel
255                         delegate:  stockQuotesDelegate
256                         focus:true
257                         snapMode: ListView.SnapToItem
258                     }
259                 }
260
261                 Rectangle {
262                     id: stockStatusMsgArea
263                     height: 100
264                     color: "#343434"
265                     anchors {left: parent.left; leftMargin: 15; right: parent.right; rightMargin: 15;
266                             verticalCenter: parent.verticalCenter}
267                     visible: false
268
269                     Text {
270                         id: stockStatusText
271                         anchors.fill: parent
272                         text: "Loading quotes.."
273                         horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter
274                         width: parent.width; font.pixelSize: 16; elide: Text.ElideNone;
275                         color: "#cccccc"
276                         wrapMode: Text.WrapAtWordBoundaryOrAnywhere
277                         style: Text.Raised; styleColor: "black"
278
279                         Connections {
280                             target: mainPage
281                             onQuoteRefreshCompleted: {
282                                 if (success){
283                                     stockStatusMsgArea.visible = false;
284                                     listViewWrapper.visible = true;
285                                 }
286                                 else{
287                                     stockStatusText.text = strMessage;
288                                     listViewWrapper.visible = false;
289                                     stockStatusMsgArea.visible = true;
290                                 }
291                             }
292                         }
293                     }
294                 }
295
296                 Rectangle{
297                     id: footerTextArea
298                     width: parent.width
299                     height: 25
300                     color: "#343434"
301                     anchors.bottom: parent.bottom
302                     Text {
303                         id: footerMessage
304                         anchors.fill: parent
305                         text: mainPage.lastUpdatedTimeStamp
306                         horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
307                         width: parent.width; font.pixelSize: 12; elide: Text.ElideRight;
308                         color: "#cccccc"
309                         style: Text.Raised; styleColor: "black"                        
310                     }
311
312                     Timer {
313                         id: footerMessageTimer
314                         interval: 10000
315                         repeat: false
316                         onTriggered: {
317                             footerMessage.text = mainPage.lastUpdatedTimeStamp;
318                         }
319                     }
320
321                     Connections {
322                         target: mainPage
323                         onQuoteRefreshCompleted:{
324                             if (success){
325                                 footerMessage.text = "Double-tap on a row to display more details.";
326                                 footerMessageTimer.start();
327                             }
328                             else{
329                                 footerMessage.text = mainPage.lastUpdatedTimeStamp;
330                             }
331                         }
332                     }
333                 }
334             }
335         }
336
337         Component{
338             id: stockDetailsComponent
339             StockDetailsComponent {
340                 symbol: selectedSymbol
341                 onLogRequest: logUtility.logMessage(strMessage)
342             }
343         }
344
345         Component {
346             id: newsComponent
347             Item {
348                 Rectangle{
349                     id: newsViewArea
350                     width: parent.width
351                     anchors.top: parent.top
352                     anchors.bottom: parent.bottom
353                     color: "#343434"
354
355                     ListView {
356                         id: newsView
357                         anchors.fill: parent
358                         flickDeceleration: 500
359                         model: newsDataModel
360                         delegate:  newsDelegate
361                         focus:true
362                         snapMode: ListView.SnapToItem
363                     }
364                 }
365
366                 Rectangle {
367                     id: newsStatusMsgArea
368                     height: 100
369                     color: "#343434"
370                     anchors {left: parent.left; leftMargin: 15; right: parent.right; rightMargin: 15;
371                             verticalCenter: parent.verticalCenter}
372                     visible: false
373
374                     Text {
375                         id: newsStatusText
376                         anchors.fill: parent
377                         text: "Loading news.."
378                         horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter
379                         width: parent.width; font.pixelSize: 16; elide: Text.ElideNone;
380                         color: "#cccccc"
381                         wrapMode: Text.WrapAtWordBoundaryOrAnywhere
382                         style: Text.Raised; styleColor: "black"
383
384                         Connections {
385                             target: mainPage
386                             onNewsReloadCompleted: {
387                                 if (success){
388                                     newsStatusMsgArea.visible = false;
389                                     newsViewArea.visible = true;
390                                 }
391                                 else{
392                                     newsStatusText.text = strMessage;
393                                     newsViewArea.visible = false;
394                                     newsStatusMsgArea.visible = true;
395                                 }
396                             }
397                         }
398                     }
399                 }
400             }
401         }                
402
403         Component {
404             id: configTickersComponent
405
406             ConfigTickersComponent{
407                 itemHeight: mainPage.itemHeight
408                 componentWidth: mainPage.componentWidth
409                 onLogRequest: logUtility.logMessage(strMessage)
410             }
411         }
412
413         Component {
414             id: configParamsComponent
415             ConfigParametersComponent{
416                 onLogRequest: logUtility.logMessage(strMessage)
417             }
418         }       
419     }
420 }