Harmattan porting experiments ongoing
[marketstoday] / src / qml / MarketsTodayWidget.qml
1 /*
2 @version: 0.2
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/Common.js" as Common
13 import "Library/js/CoreLogic.js" as CoreLib
14
15 Item {
16     id: screen
17
18     signal showConfigInNewWindow
19     signal showStockDetails(string strSymbol)
20     signal quoteRefreshStarted
21     signal quoteRefreshCompleted
22     signal quoteRefreshFailed(string strMessage)
23     signal checkNetworkStatus
24
25     property int itemHeight: 50
26     property int titleBarHeight: 60
27     property int toolBarHeight: 40
28     property int componentWidth: screen.width
29     property int autoUpdateInterval: 300000
30     property bool updateWeekDaysOnly: false
31     property bool updateOnSavedNetworksOnly: false
32     property string rssURL: "http://finance.yahoo.com/rss/topstories"
33     property string lastUpdatedTimeStamp
34     property bool isDesktopWidget
35     property string selectedSymbol:""
36
37     function reloadData(){
38         CoreLib.reloadQuotes();
39         CoreLib.reloadNews();
40     }
41
42     function initialize(){
43         CoreLib.initialize();
44     }
45
46     Component.onCompleted: {
47         initialize();
48     }
49
50     Timer {
51         id: autoUpdateTimer
52         interval: autoUpdateInterval
53         //running: (autoUpdateInterval == 0? false:true)
54         repeat: true
55         onTriggered: {
56             if (!updateWeekDaysOnly){
57                 logUtility.logMessage("Allowed to update all days of the week");
58                 reloadData();
59                 //checkNetworkStatus();
60             }
61             else if (Common.isTodayAWeekDay()){
62                 logUtility.logMessage("Today is a weekday");
63                 reloadData();
64                 //checkNetworkStatus();
65             }
66             else{
67                 logUtility.logMessage("Update not triggered: Today is not a weekday");
68             }
69         }
70     }
71
72     ListModel{
73         id: stockQuoteDataModel
74     }
75
76     ListModel {
77         id: newsDataModel
78     }
79
80     Rectangle {
81         id: background
82         anchors.fill: parent;
83         color: "#343434"
84         clip: true
85
86         Component.onCompleted: {
87             console.log("Rectangle Height = "+background.height);
88         }
89
90         Component {
91             id: stockQuotesDelegate
92
93             Item {
94                 id: wrapper; width: parent.width; height: itemHeight
95                 Item {
96                     anchors.fill: parent
97                     Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: wrapper.height - 2; width: wrapper.width; y: 1
98                         Image{
99                             id: informationIcon
100                             width: 32
101                             height: 32
102                             z: 10
103                             anchors {right: parent.right; rightMargin: 10; verticalCenter: parent.verticalCenter}
104                             visible: false
105                             source: "Library/images/information.png"
106                             MouseArea{
107                                 anchors.fill: parent;
108                                 onPressed: {
109                                     //console.log("Image clicked");
110                                     showStockDetails(symbol);
111                                 }
112                             }
113                         }
114
115                         MouseArea {
116                             anchors.fill: parent
117                             onPressed:{
118                                 informationIcon.visible = true;
119                                 //console.log("Rectangle clicked");
120                             }
121                         }
122                     }
123                     Row {
124                         y: 15;//x: 30;
125                         anchors {left: parent.left;leftMargin: 10;right: parent.right;rightMargin: 10}
126                         //width: componentWidth;
127                         height: parent.height
128                         spacing: 5
129
130                         Text { text: symbol; width: parent.width * 25/100; font.pixelSize: 18; font.bold: true; verticalAlignment:Text.AlignVCenter; elide: Text.ElideRight; color: "white"; style: Text.Raised; styleColor: "black" }
131                         Text { text: lastTradedPrice; width: parent.width * 25/100; font.pixelSize: 18; verticalAlignment:Text.AlignVCenter; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" }
132                         Column {
133                             y: -15;
134                             width: parent.width * 20/100; height: parent.height
135                             spacing: 2
136                             Text { text: change; font.pixelSize: 16; elide: Text.ElideRight
137                                 color: if(change >= 0){"green";} else {"red";}
138                                     style: Text.Raised; styleColor: "black" }
139                             Text { text: changePercentage; font.pixelSize: 16; elide: Text.ElideRight;
140                                 color: if(change >= 0){"green";} else {"red";}
141                                     style: Text.Raised; styleColor: "black" }
142                         }
143                         Text { text: volume; width: parent.width * 30/100; font.pixelSize: 18; verticalAlignment:Text.AlignVCenter; elide: Text.ElideLeft; color: "#cccccc"; style: Text.Raised; styleColor: "black" }
144                     }
145                 }
146             }
147         }
148
149         Component {
150             id: newsDelegate
151
152             Item {
153                 id: newsWrapper; width: componentWidth; height: itemHeight
154                 Item {
155                     anchors.fill: parent
156                     Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: newsWrapper.height - 2; width: newsWrapper.width; y: 1 }
157                     Text {
158                         anchors.verticalCenter: parent.verticalCenter
159                         anchors.left: parent.left
160                         anchors.leftMargin: 10
161                         anchors.right: parent.right
162                         text: title; font.pixelSize: 14
163                         font.bold: false;
164                         verticalAlignment: Text.AlignVCenter
165                         horizontalAlignment: Text.AlignLeft
166                         elide: Text.ElideRight;
167                         color: "white";
168                         style: Text.Raised;
169                         styleColor: "black"
170                     }
171                     MouseArea{
172                         anchors.fill: parent
173                         onClicked: Qt.openUrlExternally(link);
174                     }
175                 }
176             }
177         }
178
179         Library.TitleBar {
180             id: titleBar
181             width: parent.width; height: screen.titleBarHeight
182             anchors.top: parent.top
183             title: "Markets Today"
184             buttonType: ""
185             displayMenuIcon: false
186
187             onBackClicked: {
188                 uiLoader.sourceComponent = stockQuotesUIComponent;
189                 titleBar.buttonType = "";
190                 titleBar.displayMenu = false;
191                 toolBar.displayIcons = true;
192             }
193         }
194
195         Loader {
196             id: uiLoader
197             width: parent.width
198             anchors.top: titleBar.bottom
199             anchors.bottom: toolBar.top
200             sourceComponent: stockQuotesUIComponent
201         }
202
203         Library.ToolBar {
204             id:toolBar
205             width: parent.width; height: screen.toolBarHeight
206             anchors.bottom: parent.bottom
207             opacity: 0.9
208             displayNavigation: true
209             onReloadButtonClicked: screen.reloadData();
210             onNewsButtonClicked: {
211                 uiLoader.sourceComponent = newsComponent;
212                 toolBar.displayIcons = true;
213                 toolBar.targetContentType = "Stocks";
214             }
215
216             onStocksButtonClicked: {
217                 uiLoader.sourceComponent = stockQuotesUIComponent;
218                 toolBar.displayIcons = true;
219                 toolBar.targetContentType = "News";
220             }
221
222
223             Connections {
224                 target: screen
225                 onQuoteRefreshStarted:{
226                     if (!toolBar.updatePending) toolBar.updatePending = true;
227                 }
228                 onQuoteRefreshCompleted:{
229                     toolBar.updatePending = false;
230                 }
231             }
232         }
233
234         Component {
235             id: stockQuotesUIComponent
236             Item {
237                 Rectangle{
238                     id: pathViewWrapper
239                     width: parent.width
240                     anchors.top: parent.top
241                     anchors.bottom: footerText.top
242                     color: "#343434"
243
244                     PathView {
245                         id: stockQuotesView
246                         anchors.fill: parent
247                         flickDeceleration: 500
248                         //preferredHighlightBegin: 1/stockQuotesView.count
249                         //preferredHighlightEnd: 1/stockQuotesView.count
250                         //pathItemCount: count
251                         focus: true
252                         interactive: true
253                         model: stockQuoteDataModel
254                         delegate:  stockQuotesDelegate
255                         path: Path {
256                             startX: width / 2
257                             startY: itemHeight/2
258                             PathLine {
259                                 x: width / 2
260                                 y: stockQuotesView.count * itemHeight  + itemHeight/2
261                             }
262                         }
263                         Keys.onDownPressed: if (!moving && interactive) incrementCurrentIndex()
264                         Keys.onUpPressed: if (!moving && interactive) decrementCurrentIndex()
265
266                         Connections {
267                             target:  screen
268                             onQuoteRefreshCompleted:{
269                                 stockQuotesView.currentIndex = 0;
270                             }
271                         }
272
273                         Connections {
274                             target: toolBar
275                             onDownButtonClicked: {
276                                 if (!stockQuotesView.moving && stockQuotesView.interactive)
277                                     stockQuotesView.currentIndex = stockQuotesView.currentIndex + 1
278                             }
279                             onUpButtonClicked: {
280                                 if (!stockQuotesView.moving && stockQuotesView.interactive)
281                                     stockQuotesView.currentIndex = stockQuotesView.currentIndex - 1
282                             }
283                        }
284                     }
285                 }
286
287                 Rectangle{
288                     id: footerText
289                     width: parent.width
290                     height: 25
291                     color: "#343434"
292                     anchors.bottom: parent.bottom
293                     Text {
294                         id: timeStamp
295                         anchors.fill: parent
296                         text: screen.lastUpdatedTimeStamp
297                         horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
298                         width: parent.width; font.pixelSize: 12; elide: Text.ElideRight;
299                         color: "#cccccc"
300                         style: Text.Raised; styleColor: "black"
301
302                         Connections {
303                             target: screen
304                             onQuoteRefreshCompleted:{
305                                 timeStamp.text = screen.lastUpdatedTimeStamp;
306                             }
307                         }
308                     }
309                 }
310             }
311         }
312
313         Component {
314             id: newsComponent
315             Item {
316                 Rectangle{
317                     width: parent.width
318                     anchors.top: parent.top
319                     anchors.bottom: parent.bottom
320                     color: "#343434"
321
322                     PathView {
323                         id: newsView
324                         anchors.fill: parent
325                         flickDeceleration: 500
326                         focus: true
327                         interactive: true
328                         model: newsDataModel
329                         delegate:  newsDelegate
330                         path: Path {
331                             startX: width / 2
332                             startY: itemHeight/2
333                             PathLine {
334                                 x: width / 2
335                                 y: newsView.count * itemHeight  + itemHeight/2
336                             }
337                         }
338                         Keys.onDownPressed: if (!moving && interactive) incrementCurrentIndex()
339                         Keys.onUpPressed: if (!moving && interactive) decrementCurrentIndex()
340
341                         Connections {
342                             target:  screen
343                             onQuoteRefreshCompleted:{
344                                 newsView.currentIndex = 0;
345                             }
346                         }
347
348                         Connections {
349                             target: toolBar
350                             onDownButtonClicked: {
351                                 if (!newsView.moving && newsView.interactive)
352                                     newsView.currentIndex = newsView.currentIndex + 1
353                             }
354                             onUpButtonClicked: {
355                                 if (!newsView.moving && newsView.interactive)
356                                     newsView.currentIndex = newsView.currentIndex - 1
357                             }
358                        }
359                     }
360                 }
361             }
362         }
363     }
364 }