From 180f93ba4d6be2bd8fae82f0554ee7a1d556f0fc Mon Sep 17 00:00:00 2001 From: gimick Date: Tue, 22 Jun 2010 00:17:38 +0100 Subject: [PATCH 1/6] fpdb.exe + python 2.6 crash at runtime, needs gio --- pyfpdb/py2exe_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/py2exe_setup.py b/pyfpdb/py2exe_setup.py index 97c24526..be6caf2a 100644 --- a/pyfpdb/py2exe_setup.py +++ b/pyfpdb/py2exe_setup.py @@ -135,7 +135,7 @@ setup( options = {'py2exe': { 'packages' : ['encodings', 'matplotlib'], - 'includes' : ['cairo', 'pango', 'pangocairo', 'atk', 'gobject' + 'includes' : ['gio', 'cairo', 'pango', 'pangocairo', 'atk', 'gobject' ,'matplotlib.numerix.random_array' ,'AbsoluteToFpdb', 'BetfairToFpdb' ,'CarbonToFpdb', 'EverleafToFpdb' From 0e92e34085c351e9d02b220951d9936ad11a5fda Mon Sep 17 00:00:00 2001 From: gimick Date: Tue, 22 Jun 2010 00:35:04 +0100 Subject: [PATCH 2/6] add walkthrough of py2exe for python26/fpdb0.20 --- .../windows/py2exeWalkthroughPython26.txt | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 packaging/windows/py2exeWalkthroughPython26.txt diff --git a/packaging/windows/py2exeWalkthroughPython26.txt b/packaging/windows/py2exeWalkthroughPython26.txt new file mode 100644 index 00000000..c7ad72fe --- /dev/null +++ b/packaging/windows/py2exeWalkthroughPython26.txt @@ -0,0 +1,147 @@ +PY2EXE walkthrough for Python 2.6 & FPDB 0.20 +created by Gimick on 22nd June 2010 + + +Step 0 Get a fresh XP installation +---------------------------------- + +0.1/ Using XPhome 32bit + +Step 1, Python install +---------------------- + +1.1/ install the following in sequence (accept all default options) there should be no errors ! + +Python 2.6.5 ... http://www.python.org/ftp/python/2.6.5/python-2.6.5.msi +pywin 214 ... http://sourceforge.net/projects/pywin32/files/pywin32/Build%20214/pywin32-214.win32-py2.6.exe/download +numpy 1.4.1 ... http://sourceforge.net/projects/numpy/files/NumPy/1.4.1/numpy-1.4.1-win32-superpack-python2.6.exe/download +matplotlib 0.99.3 ... http://sourceforge.net/projects/matplotlib/files/matplotlib/matplotlib-0.99.3/matplotlib-0.99.3.win32-py2.6.exe/download +pygtk 2.16.0 ... http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.16/pygtk-2.16.0.win32-py2.6.exe +pycairo 1.8.6 ... http://ftp.gnome.org/pub/GNOME/binaries/win32/pycairo/1.8/pycairo-1.8.6.win32-py2.6.exe +pyGobject 2.20.0 ... http://ftp.gnome.org/pub/GNOME/binaries/win32/pygobject/2.20/pygobject-2.20.0.win32-py2.6.exe +py2exe 0.6.9 ... http://sourceforge.net/projects/py2exe/files/py2exe/0.6.9/py2exe-0.6.9.win32-py2.6.exe/download + + +Step 2 Setup GTK +----------------- + +There are quite a few GTK packages needed, and rather than install them individually, I used the official AllinOne from the GTK project. + +2,1/ Create a new folder c:\GTK + +2.2/ Extract the following zip file into c:\GTK + +GTK+ all in one 2.20.0 ... http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.20/gtk+-bundle_2.20.0-20100406_win32.zip + +2.3/ If everything has worked, you should have c:\GTK\bin \etc \lib \src and so on created. + + +Step 3 Set GTK into the PATH variable +------------------------------------- + +The path for GTK isn't set by default, so need to let the o/s know where the GTK stuff is. + +3.1/ Rightclick on mycomputer to show system properties +3.2/ select advanced/environment Variables +3.3/ in "system variables" NOT "user variables" do the following +3.3.1/ create a new item as name: GTK_BASEPATH value: c:\GTK +3.3.2/ edit the item "path", press home to get to the first character and insert the following text, (no quotes, including semicolon) %GTK_BASEPATH%\bin; + +3.4/ to check, open command prompt and do: + +dos>path ... system should respond with ... PATH=c:\GTK\bin;C:\WIN........ + +3.5/ Give it a spin to test (hopefully an application will start, if not, something has gone wrong) + +dos> gtk-demo + +Step 4 Get the fpdb GIT tree +---------------------------- + +4.1/ Best to take a copy to work with; following steps will assume that the fpdb folder is on the Desktop + + +Step 5 Put MSVCP90.dll temporarily into the fpdb folder +------------------------------------------------------- + +py2exe will check for MSVCP90.dll. The version installed by python2.6.5runtime is not in the path, so we will put it in place TEMPORARILY. This will/must be removed manually once the exe has been created, as we do not have a licence to redistribute. + +Search for MSVCP90.dll (should be found in C:\WINDOWS\WinSxS\... +copy this file TEMPORARILY to the Desktop\fpdb\pyfpdb folder + +Step 6 Run py2exe to generate fpdb.exe +-------------------------------------- + +6.1/ Run the script to create the fpdb.exe bundle + +dos> cd Desktop\fpdb\pyfpdb +dos> c:\python26\python.exe py2exe_setup.py py2exe + +wait a while, watch lots of copying and whatever. + +6.2/ You should next get prompted for the GTK folder. +c:\GTK + +6.3/ If there are no errors reported, it has probably worked, we will test soon. + +Step 7 Delete C++runtime +------------------------ + +This is really really important, this file must NOT be distributed, so get rid of it now to avoid issues. + +7.1/ in Desktop\fpdb\pyfpdb\ remove the file msvcp90.dll + +Step 8 Drag out the completed bundle +------------------------------------ + +py2exe creates a new folder for the created software bundle, drag this out to the desktop for ease of working + +8.1/ Drag Desktop\fpdb\pyfpdb\fpdb-yyyymmdd-exe to Desktop\ + + +Step 9 Initial run +------------------ + +9.1/ Open the Desktop\fpdb-yyyymmdd-exe folder +9.2/ In explorer...tools...folder options...View uncheck "Hide extensions for known file types" +9.3/ Double click run_fpdb.bat +9.4/ check the contents of pyfpdb\fpdb.exe.log, deal with any errors thrown + +Step 10 drum roll....... +------------------------ + +10.1/ hopefully, fpdb will run +10.2/ Try out a few options, deal with any errors reported + +Observe that the msvcp90.dll was provided by the python runtime package, so we don't have to install the separate package from Microsoft. End-users will, however need the dependency. + +Step 11 pruning +--------------- + +11.1/ The generated folder is 100+MB and can be pruned by removing the following directories: + +pyfpdb/lib/glib-2.0 +pyfpdb/lib/gtk-2.0/include +pyfpdb/lib/pkgconfig +pyfpdb/share/aclocal +pyfpdb/share/doc +pyfpdb/share/glib-2.0 +pyfpdb/share/gtk-2.0 +pyfpdb/share/gtk-doc +pyfpdb/share/locale +pyfpdb/share/man + +Step 12 rename folder +--------------------- + +12/ Rename the folder to something meaningful to the community + +Step 13 Compress to executable archive +-------------------------------------- + +13.1/ Download and install 7zip 914 ... http://sourceforge.net/projects/sevenzip/files/7-Zip/9.14/7z914.exe/download +13.2/ Rightclick on fpdb executable folder, select 7zip Add to archive... select SFX archive option switch +13.3/ Test the created exe file + + + From 14146f58d7564a1c3d924caad2d588a56c582c64 Mon Sep 17 00:00:00 2001 From: gimick Date: Tue, 22 Jun 2010 00:46:09 +0100 Subject: [PATCH 3/6] Set version to 0.20-pre1 - to indicate snapshot for the initial python26 .exe build --- pyfpdb/fpdb.pyw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index 748b9a22..f0547451 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -111,7 +111,7 @@ import Database import Configuration import Exceptions -VERSION = "0.20" +VERSION = "0.20-pre1" class fpdb: From 5b1bb5f5f938ba66797178ed18e2cc44ea671b7d Mon Sep 17 00:00:00 2001 From: gimick Date: Thu, 24 Jun 2010 21:34:50 +0100 Subject: [PATCH 4/6] fix focus issues if task switching to fpdb when popups are open --- pyfpdb/GuiPrefs.py | 8 +++++--- pyfpdb/fpdb.pyw | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/pyfpdb/GuiPrefs.py b/pyfpdb/GuiPrefs.py index e5458cc7..4c577de1 100755 --- a/pyfpdb/GuiPrefs.py +++ b/pyfpdb/GuiPrefs.py @@ -30,10 +30,11 @@ import Configuration class GuiPrefs: - def __init__(self, config, mainwin, dia): + def __init__(self, config, mainwin, dia, parentwin): self.config = config self.main_window = mainwin self.dialog = dia + self.parent_window = parentwin #need to pass reference of parent, to set transient self.tree_box = gtk.ScrolledWindow() self.tree_box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) @@ -120,7 +121,7 @@ class GuiPrefs: name = tmodel.get_value( iter, 1 ) val = tmodel.get_value( iter, 2 ) dia_edit = gtk.Dialog(name, - self.main_window, + self.parent_window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) @@ -162,7 +163,8 @@ if __name__=="__main__": (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) dia.set_default_size(700, 500) - prefs = GuiPrefs(config, win, dia.vbox) + pw=dia #pass parent window + prefs = GuiPrefs(config, win, dia.vbox,pw) response = dia.run() if response == gtk.RESPONSE_ACCEPT: # save updated config diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index f0547451..e6013711 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -276,7 +276,7 @@ class fpdb: gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) dia.set_default_size(700, 500) - prefs = GuiPrefs.GuiPrefs(self.config, self.window, dia.vbox) + prefs = GuiPrefs.GuiPrefs(self.config, self.window, dia.vbox, dia) response = dia.run() if response == gtk.RESPONSE_ACCEPT: # save updated config @@ -394,11 +394,13 @@ class fpdb: if self.obtain_global_lock(): # returns true if successful #lock_released = False - dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, + dia_confirm = gtk.MessageDialog(parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables") diastring = "Please confirm that you want to (re-)create the tables. If there already are tables in the database " \ +self.db.database+" on "+self.db.host+" they will be deleted." dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted + # disable windowclose, do not want the the underlying processing interrupted mid-process + dia_confirm.set_deletable(False) response = dia_confirm.run() dia_confirm.destroy() @@ -414,7 +416,7 @@ class fpdb: # for other dbs use same connection as holds global lock # self.fdb_lock.fdb.recreate_tables() # TODO: figure out why this seems to be necessary - dia_restart = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, + dia_restart = gtk.MessageDialog(parent=self.window, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_OK), message_format="Restart fpdb") diastring = "You should now restart fpdb." dia_restart.format_secondary_text(diastring) @@ -428,9 +430,11 @@ class fpdb: def dia_recreate_hudcache(self, widget, data=None): if self.obtain_global_lock(): - self.dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm recreating HUD cache") + self.dia_confirm = gtk.MessageDialog(parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm recreating HUD cache") diastring = "Please confirm that you want to re-create the HUD cache." self.dia_confirm.format_secondary_text(diastring) + # disable windowclose, do not want the the underlying processing interrupted mid-process + self.dia_confirm.set_deletable(False) hb1 = gtk.HBox(True, 1) self.h_start_date = gtk.Entry(max=12) @@ -478,16 +482,19 @@ class fpdb: def dia_rebuild_indexes(self, widget, data=None): if self.obtain_global_lock(): - self.dia_confirm = gtk.MessageDialog(parent=None - ,flags=0 + self.dia_confirm = gtk.MessageDialog(parent=self.window + ,flags=gtk.DIALOG_DESTROY_WITH_PARENT ,type=gtk.MESSAGE_WARNING ,buttons=(gtk.BUTTONS_YES_NO) ,message_format="Confirm rebuilding database indexes") diastring = "Please confirm that you want to rebuild the database indexes." self.dia_confirm.format_secondary_text(diastring) + # disable windowclose, do not want the the underlying processing interrupted mid-process + self.dia_confirm.set_deletable(False) response = self.dia_confirm.run() if response == gtk.RESPONSE_YES: + #FIXME these progress messages do not seem to work lbl = gtk.Label(" Rebuilding Indexes ... ") self.dia_confirm.vbox.add(lbl) lbl.show() @@ -559,8 +566,13 @@ class fpdb: pass def __calendar_dialog(self, widget, entry): - self.dia_confirm.set_modal(False) +# do not alter the modality of the parent +# self.dia_confirm.set_modal(False) d = gtk.Window(gtk.WINDOW_TOPLEVEL) + d.set_transient_for(self.dia_confirm) + d.set_destroy_with_parent(True) + d.set_modal(True) + d.set_title('Pick a date') vb = gtk.VBox() @@ -970,9 +982,15 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") menuItem = gtk.ImageMenuItem(gtk.STOCK_ABOUT) menuItem.connect('activate', self.dia_about) self.statusMenu.append(menuItem) - menuItem = gtk.ImageMenuItem(gtk.STOCK_QUIT) - menuItem.connect('activate', self.quit) - self.statusMenu.append(menuItem) + +# do not allow quit - if any transient (popup) windows are open (rebuild cache, rebuild index etc) +# quit from the tray causes a very very unclean shutdown, lockup of python process and failure to release global lock. +# fpdb window must be re-opened and the windows closed to quit + +# menuItem = gtk.ImageMenuItem(gtk.STOCK_QUIT) +# menuItem.connect('activate', self.quit) +# self.statusMenu.append(menuItem) + self.statusIcon.connect('popup-menu', self.statusicon_menu, self.statusMenu) self.statusIcon.set_visible(True) @@ -1019,7 +1037,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") self.window.present() def info_box(self, str1, str2): - diapath = gtk.MessageDialog( parent=None, flags=0, type=gtk.MESSAGE_INFO + diapath = gtk.MessageDialog( parent=self.window, flags=0, type=gtk.MESSAGE_INFO , buttons=(gtk.BUTTONS_OK), message_format=str1 ) diapath.format_secondary_text(str2) response = diapath.run() @@ -1027,7 +1045,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") return response def warning_box(self, str, diatitle="FPDB WARNING"): - diaWarning = gtk.Dialog(title=diatitle, parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) + diaWarning = gtk.Dialog(title=diatitle, parent=self.window, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) label = gtk.Label(str) diaWarning.vbox.add(label) From 0de6d20340ff4ccdbc28a6be0724f9b34694164c Mon Sep 17 00:00:00 2001 From: gimick Date: Thu, 24 Jun 2010 22:47:42 +0100 Subject: [PATCH 5/6] fix focus of warning when editing prefs if any notebook tabs open --- pyfpdb/fpdb.pyw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index 9b003d3d..b0778610 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -284,12 +284,12 @@ class fpdb: if len(self.nb_tab_names) == 1: # only main tab open, reload profile self.load_profile() + dia.destroy() else: + dia.destroy() # destroy prefs before raising warning, otherwise parent is dia rather than self.window self.warning_box("Updated preferences have not been loaded because " + "windows are open. Re-start fpdb to load them.") - dia.destroy() - def dia_maintain_dbs(self, widget, data=None): self.warning_box("Unimplemented: Maintain Databases") return From b4463b2e9209c1b565d2c5039e39b794aa671830 Mon Sep 17 00:00:00 2001 From: gimick Date: Thu, 24 Jun 2010 23:33:43 +0100 Subject: [PATCH 6/6] fix new bug - prefs cancel button not working --- pyfpdb/fpdb.pyw | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index b0778610..26794cb1 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -289,6 +289,8 @@ class fpdb: dia.destroy() # destroy prefs before raising warning, otherwise parent is dia rather than self.window self.warning_box("Updated preferences have not been loaded because " + "windows are open. Re-start fpdb to load them.") + else: + dia.destroy() def dia_maintain_dbs(self, widget, data=None): self.warning_box("Unimplemented: Maintain Databases")