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