Skip to content
This repository
Browse code

Set flag to prevent recheck free space on Windows

  • Loading branch information...
commit 8bfad34e5217b37894b915e9d76cf991c32d28eb 1 parent a86f2e8
authored September 06, 2012
1,733  update-app/Wikireader Update.py
... ...
@@ -1,860 +1,873 @@
1  
-#! /usr/bin/env python
2  
-# -*- coding: utf-8 -*-
3  
-# COPYRIGHT: Openmoko Inc. 2012
4  
-# LICENSE: GPL Version 3 or later
5  
-# DESCRIPTION: Create Article Indices
6  
-# AUTHORS: Sean Moss-Pultz <sean@openmoko.com>
7  
-#          Christopher Hall <hsw@openmoko.com>
8  
-#          Hank Wang <hank@openmoko.com>
9  
-
10  
-"""
11  
-WikiReader update app - Main program
12  
-"""
13  
-
14  
-import sys, os
15  
-import wx
16  
-import wx.lib.mixins.listctrl as listmix
17  
-try:
18  
-    from agw import hyperlink as hl
19  
-except ImportError: # if it's not there locally, try the wxPython lib.
20  
-    import wx.lib.agw.hyperlink as hl
21  
-
22  
-import simplejson
23  
-import disk
24  
-import download
25  
-import images
26  
-
27  
-## Debug for deploy version
28  
-#import logging
29  
-# logger = logging.getLogger('WikiReader')
30  
-# hdlr = logging.FileHandler('/var/tmp/WikiReader.log')
31  
-# formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
32  
-# hdlr.setFormatter(formatter)
33  
-# logger.addHandler(hdlr)
34  
-# logger.setLevel(logging.INFO)
35  
-# logger.info('test')
36  
-
37  
-# stuff for debugging
38  
-#print "Python", sys.version
39  
-#print "wx.version:", wx.version()
40  
-#print "pid:", os.getpid()
41  
-#print "uname:", os.uname()
42  
-#print "platform:", wx.Platform
43  
-
44  
-kPackages = None
45  
-checkedItems = []
46  
-
47  
-defaultSmallSize = 11
48  
-defaultFontSize = 14
49  
-defaultBigFontSize = 16
50  
-defaultMaxFontSize = 24
51  
-if wx.Platform == '__WXMSW__':
52  
-    defaultSmallSize = 10
53  
-    defaultFontSize = 12
54  
-    defaultBigFontSize = 14
55  
-    defaultMaxFontSize = 18
56  
-
57  
-class AboutDialog(wx.Dialog):
58  
-    def __init__(self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition, 
59  
-                style=wx.DEFAULT_DIALOG_STYLE,
60  
-            ):
61  
-        pre = wx.PreDialog()
62  
-        pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
63  
-        pre.Create(parent, ID, title, pos, size, style)
64  
-
65  
-        self.PostCreate(pre)
66  
-        wrap = 360
67  
-        linkPosX = 0
68  
-        copyRightPosX = 0
69  
-        if wx.Platform == '__WXMSW__':
70  
-            wrap = 260
71  
-            linkPosX = 30
72  
-            copyRightPosX = -30
73  
-
74  
-        whitePanel = wx.Panel(self, -1, size=(499, 440), pos=(0, 0))
75  
-        whitePanel.SetBackgroundColour("White")
76  
-
77  
-        logoImage = images.geticon_128x128Bitmap()
78  
-        logo = wx.StaticBitmap(whitePanel, -1, logoImage, size=(128, 128), pos=(136, 20))
79  
-
80  
-        versionLabel = wx.StaticText(whitePanel, -1, "Version 1.0.2", pos=(156, 150))
81  
-
82  
-        descLabel = wx.StaticText(whitePanel, -1, 
83  
-"From day one, our goal was to give physical form to Wikipedia, one of the most interesting aspects of the Internet, so people can bring it with them everywhere they go. We want to promote personal growth and the ability to enjoy those unexpected moments when curiosity strikes. WikiReader is our gift for those who have the openness to experience life and the willingness to be changed by it.",
84  
-        pos=(20, 180))
85  
-        descLabel.Wrap(wrap)
86  
-        descLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
87  
-        descLabel.SetFont(descLabelFont)
88  
-
89  
-        hl.HyperLinkCtrl(whitePanel, wx.ID_ANY, "WikiReader uses only open source software",
90  
-                                        URL="https://github.com/wikireader", pos=(70+linkPosX, 340))
91  
-
92  
-        copyrightLabel = wx.StaticText(whitePanel, -1, u"Copyright \N{Copyright Sign} 2012 Openmoko Inc. All rights reserved. The \nWikipedia name and logo are registered trademarks owned by \nthe Wikimedia Foundation and used with permission.", size=(499, 40), pos=(50+copyRightPosX, 370), style=wx.ALIGN_CENTER)
93  
-        copyrightLabelFont = wx.Font(defaultSmallSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
94  
-        copyrightLabel.SetFont(copyrightLabelFont)
95  
-
96  
-
97  
-class WindowsMenuBar(wx.MenuBar):
98  
-    def OnAbout(self, evt):
99  
-        dlg = AboutDialog(self, -1, "About WikiReader Update", size=(400, 462), style=wx.DEFAULT_DIALOG_STYLE)
100  
-        dlg.ShowModal()
101  
-
102  
-    def OnFAQ(self, evt):
103  
-        h = hl.HyperLinkCtrl(self.parent, wx.ID_ANY)
104  
-        h.GotoURL("http://thewikireader.com/#faq", True, True)
105  
-
106  
-    def OnTwitter(self, evt):
107  
-        h = hl.HyperLinkCtrl(self.parent, wx.ID_ANY)
108  
-        h.GotoURL("http://twitter.com/wikireader", True, True)
109  
-
110  
-    def __init__(self, parent):
111  
-
112  
-        if wx.Platform == '__WXMSW__':
113  
-
114  
-            wx.MenuBar.__init__(self)
115  
-            self.parent = parent
116  
-            fileMenu = wx.Menu()
117  
-            qitem = fileMenu.Append(201, "&Exit")
118  
-
119  
-            helpMenu = wx.Menu()
120  
-            faqItem = helpMenu.Append(302, "&Frequently Asked Questions")
121  
-            titem = helpMenu.Append(303, "&Twitter")
122  
-            helpMenu.AppendSeparator()
123  
-            aitem =helpMenu.Append(301, "&About WikiReader Update")
124  
-
125  
-            self.Append(fileMenu, '&File')
126  
-            self.Append(helpMenu, '&Help')
127  
-
128  
-            parent.Bind(wx.EVT_MENU, self.OnAbout, aitem)
129  
-            parent.Bind(wx.EVT_MENU, parent.parent.OnClose, qitem)
130  
-            parent.Bind(wx.EVT_MENU, self.OnFAQ, faqItem)
131  
-            parent.Bind(wx.EVT_MENU, self.OnTwitter, titem)
132  
-
133  
-            parent.SetMenuBar(self)
134  
-
135  
-
136  
-class MacSystemMenuFrame(wx.Frame):
137  
-    def OnAbout(self, evt):
138  
-        dlg = AboutDialog(self, -1, "About WikiReader Update", size=(400, 462), style=wx.DEFAULT_DIALOG_STYLE)
139  
-        dlg.ShowModal()
140  
-
141  
-
142  
-    def OnFAQ(self, evt):
143  
-        h = hl.HyperLinkCtrl(self, wx.ID_ANY)
144  
-        h.GotoURL("http://thewikireader.com/#faq", True, True)
145  
-
146  
-    def OnTwitter(self, evt):
147  
-        h = hl.HyperLinkCtrl(self, wx.ID_ANY)
148  
-        h.GotoURL("http://twitter.com/wikireader", True, True)
149  
-
150  
-    def __init__(self, parent):
151  
-        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 360))
152  
-        self.parent = parent
153  
-
154  
-        menubar = wx.MenuBar()
155  
-        if wx.Platform == '__WXMAC__':
156  
-            menu = wx.Menu()
157  
-            qitem = menu.Append(wx.ID_EXIT,"Quit","Quit Applications")
158  
-            aitem = menu.Append(wx.ID_ABOUT, "&About WikiReader Update")
159  
-            faqItem = menu.Append(555, "Frequently Asked Questions")
160  
-            titem = menu.Append(556, "Twitter")
161  
-            menubar.Append(menu, '&Help')
162  
-
163  
-            self.Bind(wx.EVT_MENU, self.OnAbout, aitem)
164  
-            self.Bind(wx.EVT_MENU, parent.OnClose, qitem)
165  
-            self.Bind(wx.EVT_MENU, self.OnFAQ, faqItem)
166  
-            self.Bind(wx.EVT_MENU, self.OnTwitter, titem)
167  
-            self.SetMenuBar(menubar)
168  
-        else:
169  
-            self.Destroy()
170  
-
171  
-
172  
-class MainFrame(wx.Frame):
173  
-    def __init__(self, parent):
174  
-
175  
-        frameHeight = 0
176  
-        if wx.Platform == '__WXMSW__':
177  
-           frameHeight = 30
178  
-
179  
-        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 360 + frameHeight))
180  
-        self.SetBackgroundColour("black")
181  
-        self.parent = parent
182  
-        self.Bind(wx.EVT_CLOSE, parent.OnClose)
183  
-        WindowsMenuBar(self)
184  
-        
185  
-        
186  
-        whitePanel = wx.Panel(self, -1, size=(499, 93), pos=(0, 245))
187  
-        whitePanel.SetBackgroundColour("White")
188  
-        whitePanel.Bind(wx.EVT_KEY_DOWN, parent.OnKeyDown)
189  
-        whitePanel.SetFocus()
190  
-        
191  
-        blueLinePanel = wx.Panel(self, -1, size=(499, 10), pos=(0, 236))
192  
-        blueLinePanel.SetBackgroundColour(wx.Colour(51, 153, 255))
193  
-        
194  
-        logoImage = images.getlogo_frontBitmap()
195  
-        wx.StaticBitmap(self, -1, logoImage, (39, 17), size=(430, 127))
196  
-        
197  
-        LastLabel = wx.StaticText(self, -1, "Last update on", size=(30, 40), pos=(49, 187))
198  
-        LastLabel.SetForegroundColour("#3399ff")
199  
-        LastLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
200  
-        LastLabel.SetFont(LastLabelFont)
201  
-        self.LastLabel = LastLabel
202  
-        
203  
-        LastUpdateLabel = wx.StaticText(self, -1, "0000.00.00", size=(50, 40), pos=(49, 203))
204  
-        LastUpdateLabel.SetForegroundColour("white")
205  
-        LastUpdateLabelFont = wx.Font(defaultMaxFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Arial, Helvetica", encoding=wx.FONTENCODING_DEFAULT)
206  
-        LastUpdateLabel.SetFont(LastUpdateLabelFont)
207  
-        self.LastUpdateLabel = LastUpdateLabel
208  
-        lastVersion = checkingVersionDialog(self, False)
209  
-
210  
-        if lastVersion == "0000.00.00":
211  
-            self.LastLabel.Hide()
212  
-            self.LastUpdateLabel.Hide()
213  
-        else:
214  
-            self.LastLabel.Show()
215  
-            self.LastUpdateLabel.Show()
216  
-            LastUpdateLabel.SetLabel(lastVersion)
217  
-        
218  
-        HintLabel = wx.StaticText(
219  
-                whitePanel, -1,
220  
-                "The Update tool downloads updates to your PC for easier\ntransfering to the WikiReader.",
221  
-                size=(50, 40), pos=(40, 5)
222  
-            )
223  
-        HintLabel.SetForegroundColour("black")
224  
-        HintLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
225  
-        HintLabel.SetFont(HintLabelFont)
226  
-        
227  
-        updateButton = wx.Button(whitePanel, 40, "Check for updates", pos=(180, 50))
228  
-        updateButton.SetDefault()
229  
-        parent.Bind(wx.EVT_LEFT_DOWN, parent.OnUpdateClick, updateButton)
230  
-        
231  
-        self.Centre()
232  
-        self.Show(True)
233  
-        self.SetIcon(images.icon.GetIcon())
234  
-
235  
-class CheckUpdateFrame(wx.Frame):
236  
-    def __init__(self, parent=None):
237  
-
238  
-        pos = (140, 42)
239  
-        if wx.Platform == '__WXMSW__':
240  
-           pos = (110, 42)
241  
-        
242  
-        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 307))
243  
-        self.SetBackgroundColour("black")
244  
-        self.parent = parent
245  
-        self.Bind(wx.EVT_CLOSE, parent.OnClose)
246  
-        
247  
-        whitePanel = wx.Panel(self, -1, size=(499, 252), pos=(0, 51))
248  
-        whitePanel.SetBackgroundColour("White")
249  
-        
250  
-        logoImage = images.getlogo_topBitmap()
251  
-        wx.StaticBitmap(self, -1, logoImage, pos=(8, 12), size=(336, 39))
252  
-
253  
-        CheckUpdateLabel = wx.StaticText(whitePanel, -1, "Checking for new updates...", size=(50, 40), pos=pos)
254  
-        CheckUpdateLabelFont = wx.Font(defaultBigFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
255  
-        CheckUpdateLabel.SetFont(CheckUpdateLabelFont)
256  
-
257  
-        cancelButton = wx.Button(whitePanel, 9, "Cancel", (211, 137))
258  
-        self.Bind(wx.EVT_BUTTON, parent.OnClose, cancelButton)
259  
-        
260  
-        gauge = wx.Gauge(self, -1, 50, pos=(125, 130), size=(250, 25))
261  
-        gauge.Pulse()
262  
-            
263  
-        self.Centre()
264  
-        self.SetIcon(images.icon.GetIcon())
265  
-        
266  
-
267  
-class PackagesListCtrl(wx.ListCtrl, listmix.CheckListCtrlMixin, listmix.ListCtrlAutoWidthMixin):
268  
-
269  
-    def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES):
270  
-        wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
271  
-        listmix.CheckListCtrlMixin.__init__(self)
272  
-        listmix.ListCtrlAutoWidthMixin.__init__(self)
273  
-        self.parent = parent
274  
-        #self.setColumns()
275  
-    
276  
-    def OnCheckItem(self, index, flag):
277  
-        global checkedItems
278  
-        if flag:
279  
-            checkedItems.append(index)
280  
-        else:
281  
-            checkedItems.remove(index)
282  
-
283  
-        if len(checkedItems) > 0:
284  
-            self.parent.parent.downloadButton.Enable()
285  
-            self.parent.parent.downloadButton.SetDefault()
286  
-        else:
287  
-            self.parent.parent.downloadButton.Disable()   
288  
-
289  
-        self.parent.parent.updateSelectedSize()
290  
-    
291  
-    def setColumns(self):
292  
-        self.InsertColumn(0, 'name')
293  
-        self.InsertColumn(1, 'size', wx.LIST_FORMAT_LEFT)
294  
-        
295  
-        data = {}
296  
-        i = 0
297  
-        for volume in kPackages['volumes']:
298  
-            name = "%s / %s / %s" % (volume['native'].encode("utf-8"), volume['name'].encode("utf-8"), volume['date'].encode("utf-8"))
299  
-            size = volume['size']
300  
-            data[i] = (name, size)
301  
-            i = i + 1
302  
-        
303  
-        items = data.items()
304  
-        for key, values in items:
305  
-            index = self.InsertStringItem(sys.maxint, unicode(values[0], "utf-8"))
306  
-            if index % 2 == 0:
307  
-                self.SetItemBackgroundColour(index, "#F0F0FE")
308  
-                
309  
-            for i in range(len(values)):
310  
-                gap = ""
311  
-                if i == 0:
312  
-                    self.SetStringItem(index, i, gap + unicode(values[i], "utf-8"))
313  
-                else:
314  
-                    self.SetStringItem(index, i, disk.humanable(values[i]))
315  
-                
316  
-        self.SetColumnWidth(0, 330)
317  
-        self.SetColumnWidth(1, 70)
318  
-
319  
-
320  
-class SelectPackageFrame(wx.Frame):
321  
-    def __init__(self, parent=None):
322  
-
323  
-        frameHeight = 0
324  
-        posY = 0
325  
-        if wx.Platform == '__WXMSW__':
326  
-           frameHeight = 40
327  
-           posY = -10
328  
-
329  
-        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 507+frameHeight))
330  
-        self.SetBackgroundColour("black")
331  
-        self.parent = parent
332  
-        self.Bind(wx.EVT_CLOSE, parent.OnClose)
333  
-        WindowsMenuBar(self)
334  
-        
335  
-        whitePanel = wx.Panel(self, -1, size=(499, 451+frameHeight), pos=(0, 51))
336  
-        whitePanel.SetBackgroundColour("White")
337  
-        
338  
-        logoImage = images.getlogo_topBitmap()
339  
-        wx.StaticBitmap(self, -1, logoImage, pos=(8, 12), size=(336, 39))
340  
-
341  
-        WaringLabel = wx.StaticText(whitePanel, -1, "Not Enough Disk Space!", size=(30, 40), pos=(36, 20+posY))
342  
-        WaringLabelFont = wx.Font(defaultBigFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
343  
-        WaringLabel.SetForegroundColour('red')
344  
-        WaringLabel.SetFont(WaringLabelFont)
345  
-        WaringLabel.Hide()
346  
-        self.WaringLabel = WaringLabel
347  
-        
348  
-        TopHintLabel = wx.StaticText(whitePanel, -1, "New updates are available for your WikiReader.", size=(30, 40), pos=(36, 16+posY))
349  
-        TopHintLabelFont = wx.Font(defaultBigFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
350  
-        TopHintLabel.SetFont(TopHintLabelFont)
351  
-        
352  
-        DescLabel = wx.StaticText(whitePanel, -1, "Downloading the updates may take some time.\nIf you're not ready to download now, press Cancel.\nTo continue, check the desired updates and press Download.", size=(30, 40), pos=(36, 36+posY))
353  
-        DescLabel.SetForegroundColour("#666666")
354  
-        DescLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
355  
-        DescLabel.SetFont(DescLabelFont)
356  
-        
357  
-        SelectedSizeLabel = wx.StaticText(whitePanel, -1, "No SDCard detected.", size=(30, 40), pos=(36, 90+posY))
358  
-        SelectedSizeLabel.SetForegroundColour("#666666")
359  
-        SelectedSizeLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
360  
-        SelectedSizeLabel.SetFont(SelectedSizeLabelFont)
361  
-        self.SelectedSizeLabel = SelectedSizeLabel
362  
-        
363  
-        cancelButton = wx.Button(whitePanel, 9, "Cancel", (150, 395+posY))
364  
-        self.Bind(wx.EVT_BUTTON, self.OnClick, cancelButton)
365  
-
366  
-        downloadButton = wx.Button(whitePanel, 10, "Download", (260, 395+posY))
367  
-        downloadButton.Disable()
368  
-        self.downloadButton = downloadButton
369  
-        self.Bind(wx.EVT_BUTTON, self.OnClick, downloadButton)
370  
-        
371  
-        PackagesListPanel = wx.Panel(whitePanel, -1, size=(420, 270), pos=(36, 116+posY))
372  
-        PackagesListPanel.parent = self
373  
-        self.packagesListCtrl = PackagesListCtrl(PackagesListPanel, -1, size=(420, 270), style=wx.LC_REPORT | wx.LC_NO_HEADER)
374  
-        self.packagesListCtrl.setColumns()
375  
-        
376  
-            
377  
-        self.Centre()
378  
-        self.SetIcon(images.icon.GetIcon())
379  
-        self.updateSelectedSize()
380  
-
381  
-    def OnClick(self, event):
382  
-        btnId = event.GetId() 
383  
-        if btnId == 9:
384  
-            self.parent.OnClose(self)
385  
-        elif btnId == 10:
386  
-            self.parent.OnDownload(self)
387  
-        else:
388  
-            event.Skip()
389  
-    
390  
-    def updateSelectedSize(self):
391  
-        TotalSpace, FreeSpace = checkFreeSpace()
392  
-        if TotalSpace:
393  
-            SelectedSpace = 0
394  
-            for i in checkedItems:
395  
-                currentExistsSize = disk.getFolderSize(disk.getSDCardFullPath() + '/' + kPackages['volumes'][i]['folder'])
396  
-                
397  
-                if currentExistsSize <= kPackages['volumes'][i]['size']:
398  
-                    SelectedSpace = SelectedSpace + kPackages['volumes'][i]['size'] - currentExistsSize
399  
-                else:
400  
-                    SelectedSpace = SelectedSpace + kPackages['volumes'][i]['size']
401  
-                    
402  
-            SelectedSpace = SelectedSpace / 1024.0
403  
-            
404  
-            UsedSpace = TotalSpace - FreeSpace
405  
-            SelectedSizeText = "%.1fGB of %.1fGB selected." % ((UsedSpace+SelectedSpace)/1024.0/1024.0, TotalSpace/1024.0/1024.0)
406  
-            
407  
-            if (UsedSpace+SelectedSpace) > TotalSpace:
408  
-                self.WaringLabel.Show()
409  
-                self.downloadButton.Disable()
410  
-            else:
411  
-                self.WaringLabel.Hide()
412  
-                if len(checkedItems) > 0:
413  
-                    self.downloadButton.Enable()
414  
-        else:
415  
-            SelectedSizeText = "No SDCard detected."
416  
-            
417  
-        self.SelectedSizeLabel.SetLabel(SelectedSizeText)
418  
-
419  
-
420  
-class DownloadPackagesListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
421  
-    
422  
-    def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES):
423  
-        wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
424  
-        #listmix.CheckListCtrlMixin.__init__(self)
425  
-        listmix.ListCtrlAutoWidthMixin.__init__(self)
426  
-        self.setColumns()
427  
-    
428  
-    def setColumns(self):
429  
-        self.InsertColumn(0, 'Name')
430  
-        self.InsertColumn(1, 'Progress', wx.LIST_FORMAT_CENTER)
431  
-        self.InsertColumn(2, 'Status', wx.LIST_FORMAT_CENTER)
432  
-        
433  
-        #data = {"1": ("Cymraeg / Wikipedia / 20120623", "255.4MB"),
434  
-        #"2": ("Dansk", "1.27GB"),
435  
-        #"3": ("Deutsch", "328MB"),
436  
-        #"4": ("English", "11MB")}
437  
-        
438  
-        data = {}
439  
-        i = 0
440  
-        for item in checkedItems:
441  
-            volume = kPackages['volumes'][item]
442  
-            name = "%s / %s / %s" % (volume['native'].encode("utf-8"), volume['name'].encode("utf-8"), volume['date'].encode("utf-8"))
443  
-            progress = "0%"
444  
-            time = "Wait"
445  
-            data[i] = (name, progress, time)
446  
-            i = i + 1
447  
-        
448  
-        items = data.items()
449  
-        for key, values in items:
450  
-            index = self.InsertStringItem(sys.maxint, unicode(values[0], "utf-8"))
451  
-            if index % 2 == 0:
452  
-                self.SetItemBackgroundColour(index, "#F0F0FE")
453  
-                
454  
-            for i in range(len(values)):
455  
-                if i==0:
456  
-                    gap = ' '
457  
-                self.SetStringItem(index, i, gap + unicode(values[i], "utf-8"))
458  
-                
459  
-        self.SetColumnWidth(0, 270)
460  
-        self.SetColumnWidth(1, 70)
461  
-        self.SetColumnWidth(2, 60)
462  
-
463  
-class DownloadPackageFrame(wx.Frame):
464  
-
465  
-    thread = None
466  
-    currentDownloadIndex = 0
467  
-    dlg = None
468  
-        
469  
-    def __init__(self, parent=None):
470  
-        
471  
-        frameHeight = 0
472  
-        posY = 0
473  
-        if wx.Platform == '__WXMSW__':
474  
-           frameHeight = 40
475  
-           posY = -60
476  
-
477  
-        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 507+frameHeight))
478  
-        
479  
-        self.parent = parent
480  
-        self.SetBackgroundColour("black")
481  
-        self.Bind(wx.EVT_CLOSE, parent.OnClose)
482  
-        WindowsMenuBar(self)
483  
-        
484  
-        whitePanel = wx.Panel(self, -1, size=(499, 451+frameHeight), pos=(0, 51))
485  
-        whitePanel.SetBackgroundColour("White")
486  
-        
487  
-        logoImage = images.getlogo_topBitmap()
488  
-        wx.StaticBitmap(self, -1, logoImage, pos=(8, 12), size=(336, 39))
489  
-        
490  
-        TopHintLabel = wx.StaticText(whitePanel, -1, "Downloading %d updates.. " % (len(checkedItems)), size=(30, 40), pos=(36, 66+posY))
491  
-        TopHintLabelFont = wx.Font(defaultBigFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
492  
-        TopHintLabel.SetFont(TopHintLabelFont)
493  
-        self.TopHintLabel = TopHintLabel
494  
-        
495  
-        DescLabel = wx.StaticText(whitePanel, -1, "This will take a while. Make sure your computer is connected\nto a power source and please do not disconnect the Internet\nconnection while downloads are in progress.", size=(30, 40), pos=(36, 86+posY))
496  
-        DescLabel.SetForegroundColour("#666666")
497  
-        DescLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
498  
-        DescLabel.SetFont(DescLabelFont)
499  
-
500  
-        cancelButton = wx.Button(whitePanel, 9, "Cancel", (210, 450+posY))
501  
-        self.Bind(wx.EVT_BUTTON, parent.OnCancelDownload, cancelButton)
502  
-        
503  
-        PackagesListPanel = wx.Panel(whitePanel, -1, size=(420, 270), pos=(36, 166+posY))
504  
-        self.packagesListCtrl = DownloadPackagesListCtrl(PackagesListPanel, -1, size=(420, 270), style=wx.LC_REPORT)
505  
-        
506  
-            
507  
-        self.Centre()
508  
-        #self.Show(True)
509  
-        self.SetIcon(images.icon.GetIcon())
510  
-    
511  
-    def checkBaseFile(self):
512  
-        self.dlg = wx.ProgressDialog("WikiReader Updater",
513  
-                               "Checking base files ...",
514  
-                               maximum = 100,
515  
-                               parent=self,
516  
-                               style = 0
517  
-                                | wx.PD_APP_MODAL
518  
-                                #| wx.PD_CAN_ABORT
519  
-                                #| wx.PD_CAN_SKIP
520  
-                                #| wx.PD_ELAPSED_TIME
521  
-                                #| wx.PD_ESTIMATED_TIME
522  
-                                #| wx.PD_REMAINING_TIME
523  
-                                | wx.PD_AUTO_HIDE
524  
-                                )
525  
-        
526  
-        base = kPackages['bases'][0]
527  
-        baseFile = base['files'][0]
528  
-        if not disk.checkFileSize(baseFile['name'], baseFile['size']):
529  
-            self.dlg.Update(0, "Downloading base files ...")
530  
-            download.downloadPackage(self, base, callback=self.finishBaseFile, updateback=self.updateBaseFile)
531  
-        else:
532  
-            self.dlg.Update(100) # set 100 to close the dlg
533  
-            self.finishBaseFile()
534  
-    
535  
-    def updateBaseFile(self, percent):
536  
-        self.dlg.Update(int(float(percent[:-1])))
537  
-        
538  
-    def finishBaseFile(self):
539  
-        self.downloadStart()
540  
-        
541  
-    def downloadStart(self):
542  
-        download.downloadPackage(self, kPackages['volumes'][checkedItems[0]], callback=self.finishDownload, updateback=self.updateProgress)
543  
-    
544  
-    def finishDownload(self):
545  
-        if self:
546  
-            self.packagesListCtrl.SetStringItem(self.currentDownloadIndex, 1, "100%")
547  
-            self.packagesListCtrl.SetStringItem(self.currentDownloadIndex, 2, "Finished")
548  
-            self.currentDownloadIndex = self.currentDownloadIndex + 1
549  
-            
550  
-            if len(checkedItems) == self.currentDownloadIndex:
551  
-                self.parent.GoPrepareInstall()
552  
-            else:
553  
-                download.downloadPackage(self, kPackages['volumes'][checkedItems[self.currentDownloadIndex]], callback=self.finishDownload, updateback=self.updateProgress)
554  
-        
555  
-    def updateProgress(self, percent):
556  
-        if self:
557  
-            self.packagesListCtrl.SetStringItem(self.currentDownloadIndex, 1, percent)
558  
-            self.packagesListCtrl.SetStringItem(self.currentDownloadIndex, 2, "Download")
559  
-        return
560  
-
561  
-
562  
-class PrepareInstallFrame(wx.Frame):
563  
-    def __init__(self, parent=None):
564  
-        
565  
-        frameHeight = 0
566  
-        posY = 0
567  
-        posX = 0
568  
-        imagePosY = 0
569  
-        imagePosX = 0
570  
-        if wx.Platform == '__WXMSW__':
571  
-            frameHeight = 40
572  
-            posY = -0
573  
-            posX = -40
574  
-            imagePosY = -0
575  
-            imagePosX = -30    
576  
-
577  
-        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 320+frameHeight))
578  
-        self.SetBackgroundColour("black")
579  
-        self.parent = parent
580  
-        self.Bind(wx.EVT_CLOSE, parent.OnClose)
581  
-        WindowsMenuBar(self)
582  
-        
583  
-        whitePanel = wx.Panel(self, -1, size=(499, 252+frameHeight), pos=(0, 51))
584  
-        whitePanel.SetBackgroundColour("White")
585  
-        
586  
-        logoImage = images.getlogo_topBitmap()
587  
-        wx.StaticBitmap(self, -1, logoImage, pos=(8, 12), size=(336, 39))
588  
-
589  
-
590  
-        self.posX = posX
591  
-        self.posY = posY
592  
-        
593  
-        HintLabel = wx.StaticText(whitePanel, -1, "Prepare to install ...", size=(499, 40), pos=(68+posX, 20+posY), style=wx.ALIGN_CENTER)
594  
-        HintLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
595  
-        HintLabel.SetFont(HintLabelFont)
596  
-        self.HintLabel = HintLabel
597  
-        
598  
-        deviceImage = images.getdeviceBitmap()
599  
-        wx.StaticBitmap(whitePanel, -1, deviceImage, pos=(75+imagePosX, 65+posY+imagePosY), size=(388, 112))
600  
-        
601  
-        quitButton = wx.Button(whitePanel, 8, "Quit", (150, 195+posY))
602  
-        self.Bind(wx.EVT_BUTTON, parent.OnClose, quitButton)
603  
-
604  
-        self.installButton = wx.Button(whitePanel, 9, "Install", (270, 195+posY))
605  
-        self.Bind(wx.EVT_BUTTON, parent.OnInstall, self.installButton)
606  
-        
607  
-        tryButton = wx.Button(whitePanel, 10, "Try again", (270, 195+posY), (20, 20))
608  
-        self.Bind(wx.EVT_BUTTON, self.OnTryClick, tryButton)
609  
-        tryButton.SetDefault()
610  
-        tryButton.SetSize(tryButton.GetBestSize())
611  
-        self.tryButton = tryButton
612  
-        
613  
-        self.Centre()
614  
-        self.SetIcon(images.icon.GetIcon())
615  
-        
616  
-        self.checkSDcard()
617  
-    
618  
-    def OnTryClick(self, event):
619  
-        self.checkSDcard()
620  
-        
621  
-    def checkSDcard(self):
622  
-        mounts = disk.getMountList()
623  
-        self.HintLabel.SetForegroundColour("red")
624  
-        self.installButton.Show()
625  
-        self.tryButton.Hide()
626  
-            
627  
-        if len(mounts) == 0:
628  
-            self.HintLabel.SetLabel("Insert WikiReader's SD card into a memory card reader\nthat is plugged into this computer.")
629  
-            self.installButton.Hide()
630  
-            self.tryButton.Show()
631  
-            self.HintLabel.SetPosition((68+self.posX, 20+self.posY))
632  
-        elif not disk.enoughSpace(kPackages, checkedItems):
633  
-            self.HintLabel.SetLabel("This is microSD card doesn't have enough free space.")
634  
-            self.installButton.Hide()
635  
-            self.tryButton.Show()
636  
-            self.HintLabel.SetPosition((68+self.posX, 20+self.posY))
637  
-        # elif not disk.getVersion():
638  
-        #     self.HintLabel.SetLabel("This is not wikireader microSD card. continue installation?")
639  
-        #     self.HintLabel.SetPosition((48+self.posX, 20+self.posY))
640  
-        else:
641  
-            self.HintLabel.SetLabel("Click install to continue.")
642  
-            self.HintLabel.SetForegroundColour("black")
643  
-            self.HintLabel.SetPosition((188+self.posX, 20+self.posY))
644  
-
645  
-
646  
-class InstallFrame(wx.Frame):
647  
-    def __init__(self, parent=None):
648  
-        
649  
-        posY = 0
650  
-        posX = 0
651  
-        if wx.Platform == '__WXMSW__':
652  
-            posY = -20
653  
-            posX = -20
654  
-
655  
-        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 307))
656  
-        self.SetBackgroundColour("black")
657  
-        
658  
-        whitePanel = wx.Panel(self, -1, size=(499, 252), pos=(0, 51))
659  
-        whitePanel.SetBackgroundColour("White")
660  
-        self.Bind(wx.EVT_CLOSE, parent.OnClose)
661  
-        
662  
-        logoImage = images.getlogo_topBitmap()
663  
-        wx.StaticBitmap(self, -1, logoImage, pos=(8, 12), size=(336, 39))
664  
-        
665  
-        HintLabel = wx.StaticText(whitePanel, -1, "Installing updates to microSD card..", size=(499, 40), pos=(115+posX, 60+posY))
666  
-        HintLabelFont = wx.Font(defaultBigFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
667  
-        HintLabel.SetFont(HintLabelFont)
668  
-        
669  
-        SubHintLabel = wx.StaticText(whitePanel, -1, "We're almost there..", size=(499, 40), pos=(115+posX, 80+posY))
670  
-        SubHintLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
671  
-        SubHintLabel.SetForegroundColour('gray')
672  
-        SubHintLabel.SetFont(SubHintLabelFont)
673  
-        
674  
-        self.gauge = wx.Gauge(whitePanel, -1, 100, pos=(100, 140+posY), size=(300, 25))
675  
-        self.gauge.SetBezelFace(3)  
676  
-        self.gauge.SetShadowWidth(3)
677  
-        
678  
-            
679  
-        self.Centre()
680  
-        self.SetIcon(images.icon.GetIcon())
681  
-        
682  
-    def updateGauge(self, count):
683  
-        self.gauge.SetValue(count)
684  
-        
685  
-
686  
-class FinishFrame(wx.Frame):
687  
-    def __init__(self, parent=None):
688  
-        
689  
-        frameHeight = 0
690  
-        posY = 0
691  
-        posX = 0
692  
-        if wx.Platform == '__WXMSW__':
693  
-            frameHeight = 70
694  
-            posY = 0
695  
-            posX = -20
696  
-
697  
-        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 307+frameHeight))
698  
-        self.SetBackgroundColour("black")
699  
-        self.parent = parent
700  
-        self.Bind(wx.EVT_CLOSE, parent.OnClose)
701  
-        WindowsMenuBar(self)
702  
-        
703  
-        whitePanel = wx.Panel(self, -1, size=(499, 252+frameHeight), pos=(0, 51))
704  
-        whitePanel.SetBackgroundColour("White")
705  
-        
706  
-        logoImage = images.getlogo_topBitmap()
707  
-        wx.StaticBitmap(self, -1, logoImage, pos=(8, 12), size=(336, 39))
708  
-        
709  
-        HintLabel = wx.StaticText(whitePanel, -1, "Installation complete!", size=(499, 40), pos=(155+posX, 50+posY))
710  
-        HintLabelFont = wx.Font(defaultBigFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
711  
-        HintLabel.SetFont(HintLabelFont)
712  
-        
713  
-        SubHintLabel = wx.StaticText(whitePanel, -1, "Thank you for being so patient. You may now safely eject\nthe microSD card and place it back in your WikiReader.", size=(10, 40), pos=(65+posX, 80+posY), style=wx.ALIGN_CENTER)
714  
-        SubHintLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
715  
-        # SubHintLabel.SetForegroundColour('777777')
716  
-        SubHintLabel.SetFont(SubHintLabelFont)
717  
-
718  
-        doneButton = wx.Button(whitePanel, 8, "Done", (200, 230))
719  
-        doneButton.SetDefault()
720  
-        self.Bind(wx.EVT_BUTTON, parent.OnClose, doneButton)
721  
-        
722  
-        self.Centre()
723  
-        self.SetIcon(images.icon.GetIcon())
724  
-
725  
-
726  
-class WikiReaderUpdater(wx.App):
727  
-    currentThread = None
728  
-    
729  
-    def __init__(self):
730  
-        wx.App.__init__(self, redirect=False)
731  
-
732  
-    def OnInit(self):
733  
-        MacSystemMenuFrame(self).Hide()
734  
-        self.mainFrame = MainFrame(self)
735  
-        self.SetTopWindow(self.mainFrame)
736  
-
737  
-        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
738  
-        self.Bind(wx.EVT_BUTTON, self.OnClose)
739  
-        
740  
-
741  
-        # init tmp dir
742  
-        disk.getTmpDir()
743  
-        
744  
-        # debug
745  
-        # self.mainFrame.Destroy()
746  
-        # self.OnUpdateClick(None)
747  
-        # SelectPackageFrame(self).show()
748  
-        # FinishFrame(self).Show()
749  
-        #self.goSelect()
750  
-        
751  
-        return True
752  
-    
753  
-    def OnClose(self, event):
754  
-        if self.currentThread:
755  
-            self.currentThread.stop()
756  
-        wx.Exit()
757  
-    
758  
-    def OnUpdateClick(self, event):
759  
-        self.mainFrame.Destroy()
760  
-        self.checkUpdateFrame = CheckUpdateFrame(self)
761  
-        self.checkUpdateFrame.Show()
762  
-        self.checkUpdate()
763  
-    
764  
-    def OnKeyDown(self, event):
765  
-        if event.GetKeyCode() == wx.WXK_ESCAPE:
766  
-            wx.Exit()
767  
-        event.Skip()
768  
-        
769  
-    def checkUpdate(self):
770  
-        self.currentThread = download.downloadPackageList(self.finishCheckUpdate)
771  
-    
772  
-    def finishCheckUpdate(self, packages):
773  
-        global kPackages
774  
-        self.currentThread = None
775  
-        kPackages = simplejson.loads(str(packages))
776  
-        self.goSelect()
777  
-
778  
-    def goSelect(self):
779  
-        self.checkUpdateFrame.Destroy()
780  
-        self.selectPackageFrame = SelectPackageFrame(self)
781  
-        self.selectPackageFrame.Show()
782  
-        
783  
-    def OnDownload(self, event):
784  
-        if len(checkedItems) == 0:
785  
-            showMessage("Please select packages to download.")
786  
-        else:
787  
-            self.selectPackageFrame.Hide()
788  
-            self.downloadPackageFrame = DownloadPackageFrame(self)
789  
-            self.downloadPackageFrame.Show()
790  
-            self.downloadPackageFrame.checkBaseFile()
791  
-    
792  
-    def OnCancelDownload(self, event):
793  
-        if self.downloadPackageFrame.thread:
794  
-            self.downloadPackageFrame.thread.stop()
795  
-        self.downloadPackageFrame.Destroy()
796  
-        self.selectPackageFrame.Show()
797  
-        
798  
-    def GoPrepareInstall(self):
799  
-        self.downloadPackageFrame.Destroy()
800  
-        self.prepareInstallFrame = PrepareInstallFrame(self)
801  
-        self.prepareInstallFrame.Show()
802  
-        
803  
-    def OnInstall(self, event):
804  
-        self.prepareInstallFrame.Destroy()
805  
-        self.installFrame = InstallFrame(self)
806  
-        self.installFrame.Show()
807  
-        disk.installPackage(kPackages, checkedItems, self.FinishInstall, self.installFrame.updateGauge)
808  
-    
809  
-    def FinishInstall(self):
810  
-        self.installFrame.Destroy()
811  
-        self.finishFrame = FinishFrame(self)
812  
-        self.finishFrame.Show()
813  
-        
814  
-def checkFreeSpace():
815  
-    mountDisks = disk.getMountList()
816  
-    #if len(mountDisks) > 1:
817  
-    #    print "More than one disks"
818  
-    #elif len(mountDisks) > 0:
819  
-    #    return disk.getFreeSpace(mountDisks[0])
820  
-
821  
-    if len(mountDisks) > 0:
822  
-        return disk.getFreeSpace(mountDisks[0])
823  
-    
824  
-    return None, None
825  
-
826  
-
827  
-def showMessage(msg):
828  
-    wx.MessageBox(msg, 'Info', wx.OK | wx.ICON_INFORMATION)
829  
-
830  
-def checkingVersionDialog(parent, showError=True):
831  
-    dlg = wx.ProgressDialog("WikiReader Updater",
832  
-                               "Checking sdcard ...",
833  
-                               maximum = 100,
834  
-                               parent=parent,
835  
-                               style = 0
836  
-                                | wx.PD_APP_MODAL
837  
-                                | wx.PD_CAN_ABORT
838  
-                                #| wx.PD_CAN_SKIP
839  
-                                #| wx.PD_ELAPSED_TIME
840  
-                                #| wx.PD_ESTIMATED_TIME
841  
-                                #| wx.PD_REMAINING_TIME
842  
-                                #| wx.PD_AUTO_HIDE
843  
-                                )
844  
-        
845  
-    version = disk.getVersion()
846  
-    if not version:
847  
-        version = '0000.00.00'
848  
-    
849  
-    #print version
850  
-    if len(disk.getMountList()) < 1 and showError:
851  
-        wx.MessageBox('We don\'t detected any sdcard on your computer', 'Info', wx.OK | wx.ICON_INFORMATION)
852  
-    
853  
-    dlg.Destroy()
854  
-    
855  
-    return version
856  
-
857  
-
858  
-if __name__ == "__main__":
859  
-    app = WikiReaderUpdater()
860  
-    app.MainLoop()
  1
+#! /usr/bin/env python
  2
+# -*- coding: utf-8 -*-
  3
+# COPYRIGHT: Openmoko Inc. 2012
  4
+# LICENSE: GPL Version 3 or later
  5
+# DESCRIPTION: Create Article Indices
  6
+# AUTHORS: Sean Moss-Pultz <sean@openmoko.com>
  7
+#          Christopher Hall <hsw@openmoko.com>
  8
+#          Hank Wang <hank@openmoko.com>
  9
+
  10
+"""
  11
+WikiReader update app - Main program
  12
+"""
  13
+
  14
+import sys, os
  15
+import wx
  16
+import wx.lib.mixins.listctrl as listmix
  17
+try:
  18
+    from agw import hyperlink as hl
  19
+except ImportError: # if it's not there locally, try the wxPython lib.
  20
+    import wx.lib.agw.hyperlink as hl
  21
+
  22
+import simplejson
  23
+import disk
  24
+import download
  25
+import images
  26
+
  27
+## Debug for deploy version
  28
+#import logging
  29
+# logger = logging.getLogger('WikiReader')
  30
+# hdlr = logging.FileHandler('/var/tmp/WikiReader.log')
  31
+# formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
  32
+# hdlr.setFormatter(formatter)
  33
+# logger.addHandler(hdlr)
  34
+# logger.setLevel(logging.INFO)
  35
+# logger.info('test')
  36
+
  37
+# stuff for debugging
  38
+#print "Python", sys.version
  39
+#print "wx.version:", wx.version()
  40
+#print "pid:", os.getpid()
  41
+#print "uname:", os.uname()
  42
+#print "platform:", wx.Platform
  43
+
  44
+kPackages = None
  45
+checkedItems = []
  46
+
  47
+defaultSmallSize = 11
  48
+defaultFontSize = 14
  49
+defaultBigFontSize = 16
  50
+defaultMaxFontSize = 24
  51
+if wx.Platform == '__WXMSW__':
  52
+    defaultSmallSize = 10
  53
+    defaultFontSize = 12
  54
+    defaultBigFontSize = 14
  55
+    defaultMaxFontSize = 18
  56
+
  57
+class AboutDialog(wx.Dialog):
  58
+    def __init__(self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition, 
  59
+                style=wx.DEFAULT_DIALOG_STYLE,
  60
+            ):
  61
+        pre = wx.PreDialog()
  62
+        pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
  63
+        pre.Create(parent, ID, title, pos, size, style)
  64
+
  65
+        self.PostCreate(pre)
  66
+        wrap = 360
  67
+        linkPosX = 0
  68
+        copyRightPosX = 0
  69
+        if wx.Platform == '__WXMSW__':
  70
+            wrap = 260
  71
+            linkPosX = 30
  72
+            copyRightPosX = -30
  73
+
  74
+        whitePanel = wx.Panel(self, -1, size=(499, 440), pos=(0, 0))
  75
+        whitePanel.SetBackgroundColour("White")
  76
+
  77
+        logoImage = images.geticon_128x128Bitmap()
  78
+        logo = wx.StaticBitmap(whitePanel, -1, logoImage, size=(128, 128), pos=(136, 20))
  79
+
  80
+        versionLabel = wx.StaticText(whitePanel, -1, "Version 1.0.3", pos=(156, 150))
  81
+
  82
+        descLabel = wx.StaticText(whitePanel, -1, 
  83
+"From day one, our goal was to give physical form to Wikipedia, one of the most interesting aspects of the Internet, so people can bring it with them everywhere they go. We want to promote personal growth and the ability to enjoy those unexpected moments when curiosity strikes. WikiReader is our gift for those who have the openness to experience life and the willingness to be changed by it.",
  84
+        pos=(20, 180))
  85
+        descLabel.Wrap(wrap)
  86
+        descLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
  87
+        descLabel.SetFont(descLabelFont)
  88
+
  89
+        hl.HyperLinkCtrl(whitePanel, wx.ID_ANY, "WikiReader uses only open source software",
  90
+                                        URL="https://github.com/wikireader", pos=(70+linkPosX, 340))
  91
+
  92
+        copyrightLabel = wx.StaticText(whitePanel, -1, u"Copyright \N{Copyright Sign} 2012 Openmoko Inc. All rights reserved. The \nWikipedia name and logo are registered trademarks owned by \nthe Wikimedia Foundation and used with permission.", size=(499, 40), pos=(50+copyRightPosX, 370), style=wx.ALIGN_CENTER)
  93
+        copyrightLabelFont = wx.Font(defaultSmallSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
  94
+        copyrightLabel.SetFont(copyrightLabelFont)
  95
+
  96
+
  97
+class WindowsMenuBar(wx.MenuBar):
  98
+    def OnAbout(self, evt):
  99
+        dlg = AboutDialog(self, -1, "About WikiReader Update", size=(400, 462), style=wx.DEFAULT_DIALOG_STYLE)
  100
+        dlg.ShowModal()
  101
+
  102
+    def OnFAQ(self, evt):
  103
+        h = hl.HyperLinkCtrl(self.parent, wx.ID_ANY)
  104
+        h.GotoURL("http://thewikireader.com/#faq", True, True)
  105
+
  106
+    def OnTwitter(self, evt):
  107
+        h = hl.HyperLinkCtrl(self.parent, wx.ID_ANY)
  108
+        h.GotoURL("http://twitter.com/wikireader", True, True)
  109
+
  110
+    def __init__(self, parent):
  111
+
  112
+        if wx.Platform == '__WXMSW__':
  113
+
  114
+            wx.MenuBar.__init__(self)
  115
+            self.parent = parent
  116
+            fileMenu = wx.Menu()
  117
+            qitem = fileMenu.Append(201, "&Exit")
  118
+
  119
+            helpMenu = wx.Menu()
  120
+            faqItem = helpMenu.Append(302, "&Frequently Asked Questions")
  121
+            titem = helpMenu.Append(303, "&Twitter")
  122
+            helpMenu.AppendSeparator()
  123
+            aitem =helpMenu.Append(301, "&About WikiReader Update")
  124
+
  125
+            self.Append(fileMenu, '&File')
  126
+            self.Append(helpMenu, '&Help')
  127
+
  128
+            parent.Bind(wx.EVT_MENU, self.OnAbout, aitem)
  129
+            parent.Bind(wx.EVT_MENU, parent.parent.OnClose, qitem)
  130
+            parent.Bind(wx.EVT_MENU, self.OnFAQ, faqItem)
  131
+            parent.Bind(wx.EVT_MENU, self.OnTwitter, titem)
  132
+
  133
+            parent.SetMenuBar(self)
  134
+
  135
+
  136
+class MacSystemMenuFrame(wx.Frame):
  137
+    def OnAbout(self, evt):
  138
+        dlg = AboutDialog(self, -1, "About WikiReader Update", size=(400, 462), style=wx.DEFAULT_DIALOG_STYLE)
  139
+        dlg.ShowModal()
  140
+
  141
+
  142
+    def OnFAQ(self, evt):
  143
+        h = hl.HyperLinkCtrl(self, wx.ID_ANY)
  144
+        h.GotoURL("http://thewikireader.com/#faq", True, True)
  145
+
  146
+    def OnTwitter(self, evt):
  147
+        h = hl.HyperLinkCtrl(self, wx.ID_ANY)
  148
+        h.GotoURL("http://twitter.com/wikireader", True, True)
  149
+
  150
+    def __init__(self, parent):
  151
+        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 360))
  152
+        self.parent = parent
  153
+
  154
+        menubar = wx.MenuBar()
  155
+        if wx.Platform == '__WXMAC__':
  156
+            menu = wx.Menu()
  157
+            qitem = menu.Append(wx.ID_EXIT,"Quit","Quit Applications")
  158
+            aitem = menu.Append(wx.ID_ABOUT, "&About WikiReader Update")
  159
+            faqItem = menu.Append(555, "Frequently Asked Questions")
  160
+            titem = menu.Append(556, "Twitter")
  161
+            menubar.Append(menu, '&Help')
  162
+
  163
+            self.Bind(wx.EVT_MENU, self.OnAbout, aitem)
  164
+            self.Bind(wx.EVT_MENU, parent.OnClose, qitem)
  165
+            self.Bind(wx.EVT_MENU, self.OnFAQ, faqItem)
  166
+            self.Bind(wx.EVT_MENU, self.OnTwitter, titem)
  167
+            self.SetMenuBar(menubar)
  168
+        else:
  169
+            self.Destroy()
  170
+
  171
+
  172
+class MainFrame(wx.Frame):
  173
+    def __init__(self, parent):
  174
+
  175
+        frameHeight = 0
  176
+        if wx.Platform == '__WXMSW__':
  177
+           frameHeight = 30
  178
+
  179
+        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 360 + frameHeight))
  180
+        self.SetBackgroundColour("black")
  181
+        self.parent = parent
  182
+        self.Bind(wx.EVT_CLOSE, parent.OnClose)
  183
+        WindowsMenuBar(self)
  184
+        
  185
+        
  186
+        whitePanel = wx.Panel(self, -1, size=(499, 93), pos=(0, 245))
  187
+        whitePanel.SetBackgroundColour("White")
  188
+        whitePanel.Bind(wx.EVT_KEY_DOWN, parent.OnKeyDown)
  189
+        whitePanel.SetFocus()
  190
+        
  191
+        blueLinePanel = wx.Panel(self, -1, size=(499, 10), pos=(0, 236))
  192
+        blueLinePanel.SetBackgroundColour(wx.Colour(51, 153, 255))
  193
+        
  194
+        logoImage = images.getlogo_frontBitmap()
  195
+        wx.StaticBitmap(self, -1, logoImage, (39, 17), size=(430, 127))
  196
+        
  197
+        LastLabel = wx.StaticText(self, -1, "Last update on", size=(30, 40), pos=(49, 187))
  198
+        LastLabel.SetForegroundColour("#3399ff")
  199
+        LastLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
  200
+        LastLabel.SetFont(LastLabelFont)
  201
+        self.LastLabel = LastLabel
  202
+        
  203
+        LastUpdateLabel = wx.StaticText(self, -1, "0000.00.00", size=(50, 40), pos=(49, 203))
  204
+        LastUpdateLabel.SetForegroundColour("white")
  205
+        LastUpdateLabelFont = wx.Font(defaultMaxFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Arial, Helvetica", encoding=wx.FONTENCODING_DEFAULT)
  206
+        LastUpdateLabel.SetFont(LastUpdateLabelFont)
  207
+        self.LastUpdateLabel = LastUpdateLabel
  208
+        lastVersion = checkingVersionDialog(self, False)
  209
+
  210
+        if lastVersion == "0000.00.00":
  211
+            self.LastLabel.Hide()
  212
+            self.LastUpdateLabel.Hide()
  213
+        else:
  214
+            self.LastLabel.Show()
  215
+            self.LastUpdateLabel.Show()
  216
+            LastUpdateLabel.SetLabel(lastVersion)
  217
+        
  218
+        HintLabel = wx.StaticText(
  219
+                whitePanel, -1,
  220
+                "The Update tool downloads updates to your PC for easier\ntransfering to the WikiReader.",
  221
+                size=(50, 40), pos=(40, 5)
  222
+            )
  223
+        HintLabel.SetForegroundColour("black")
  224
+        HintLabelFont = wx.Font(defaultFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
  225
+        HintLabel.SetFont(HintLabelFont)
  226
+        
  227
+        updateButton = wx.Button(whitePanel, 40, "Check for updates", pos=(180, 50))
  228
+        updateButton.SetDefault()
  229
+        parent.Bind(wx.EVT_LEFT_DOWN, parent.OnUpdateClick, updateButton)
  230
+        
  231
+        self.Centre()
  232
+        self.Show(True)
  233
+        self.SetIcon(images.icon.GetIcon())
  234
+
  235
+class CheckUpdateFrame(wx.Frame):
  236
+    def __init__(self, parent=None):
  237
+
  238
+        pos = (140, 42)
  239
+        if wx.Platform == '__WXMSW__':
  240
+           pos = (110, 42)
  241
+        
  242
+        wx.Frame.__init__(self, None, -1, "WikiReader Update", size=(499, 307))
  243
+        self.SetBackgroundColour("black")
  244
+        self.parent = parent
  245
+        self.Bind(wx.EVT_CLOSE, parent.OnClose)
  246
+        
  247
+        whitePanel = wx.Panel(self, -1, size=(499, 252), pos=(0, 51))
  248
+        whitePanel.SetBackgroundColour("White")
  249
+        
  250
+        logoImage = images.getlogo_topBitmap()
  251
+        wx.StaticBitmap(self, -1, logoImage, pos=(8, 12), size=(336, 39))
  252
+
  253
+        CheckUpdateLabel = wx.StaticText(whitePanel, -1, "Checking for new updates...", size=(50, 40), pos=pos)
  254
+        CheckUpdateLabelFont = wx.Font(defaultBigFontSize, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False, faceName="Helvetica", encoding=wx.FONTENCODING_DEFAULT)
  255
+        CheckUpdateLabel.SetFont(CheckUpdateLabelFont)
  256
+
  257
+        cancelButton = wx.Button(whitePanel, 9, "Cancel", (211, 137))
  258
+        self.Bind(wx.EVT_BUTTON, parent.OnClose, cancelButton)
  259
+        
  260
+        gauge = wx.Gauge(self, -1, 50, pos=(125, 130), size=(250, 25))
  261
+        gauge.Pulse()
  262
+            
  263
+        self.Centre()
  264
+        self.SetIcon(images.icon.GetIcon())
  265
+        
  266
+
  267
+class PackagesListCtrl(wx.ListCtrl, listmix.CheckListCtrlMixin, listmix.ListCtrlAutoWidthMixin):
  268
+
  269
+    def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES):
  270
+        wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
  271
+        listmix.CheckListCtrlMixin.__init__(self)