2008-08-04 05:44:28 +02:00
#!/usr/bin/python
2010-06-20 13:52:44 +02:00
# -*- coding: utf-8 -*-
2008-08-04 05:44:28 +02:00
2010-07-04 03:05:16 +02:00
#Copyright 2008-2010 Steffen Schaumburg
2008-08-04 05:44:28 +02:00
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU Affero General Public License as published by
#the Free Software Foundation, version 3 of the License.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU Affero General Public License
#along with this program. If not, see <http://www.gnu.org/licenses/>.
2010-07-04 03:05:16 +02:00
#In the "official" distribution you can find the license in agpl-3.0.txt.
2008-08-04 05:44:28 +02:00
2010-09-22 17:46:03 +02:00
import L10n
_ = L10n . get_translation ( )
2008-08-04 05:44:28 +02:00
import os
import sys
2009-08-01 13:45:10 +02:00
import re
2009-12-09 22:58:56 +01:00
import Queue
2009-08-01 13:45:10 +02:00
# if path is set to use an old version of python look for a new one:
# (does this work in linux?)
2010-08-13 04:10:13 +02:00
if os . name == ' nt ' and sys . version [ 0 : 3 ] not in ( ' 2.5 ' , ' 2.6 ' , ' 2.7 ' ) and ' -r ' not in sys . argv :
2009-08-01 13:45:10 +02:00
#print "old path =", os.environ['PATH']
dirs = re . split ( os . pathsep , os . environ [ ' PATH ' ] )
# remove any trailing / or \ chars from dirs:
dirs = [ re . sub ( ' [ \\ /]$ ' , ' ' , p ) for p in dirs ]
# remove any dirs containing 'python' apart from those ending in 'python25', 'python26' or 'python':
2010-08-13 04:10:13 +02:00
dirs = [ p for p in dirs if not re . search ( ' python ' , p , re . I ) or re . search ( ' python25$ ' , p , re . I ) or re . search ( ' python26$ ' , p , re . I ) or re . search ( ' python27$ ' , p , re . I ) ]
2009-08-01 13:45:10 +02:00
tmppath = " ; " . join ( dirs )
#print "new path =", tmppath
if re . search ( ' python ' , tmppath , re . I ) :
os . environ [ ' PATH ' ] = tmppath
2010-08-13 03:28:27 +02:00
print " Python " + sys . version [ 0 : 3 ] + _ ( ' - press return to continue \n ' )
2009-08-01 13:45:10 +02:00
sys . stdin . readline ( )
2010-06-20 13:52:44 +02:00
if os . name == ' nt ' :
2010-07-11 20:00:27 +02:00
os . execvpe ( ' pythonw.exe ' , ( ' pythonw.exe ' , ' fpdb.pyw ' , ' -r ' ) , os . environ ) # first arg is ignored (name of program being run)
else :
os . execvpe ( ' python ' , ( ' python ' , ' fpdb.pyw ' , ' -r ' ) , os . environ ) # first arg is ignored (name of program being run)
2009-08-01 13:45:10 +02:00
else :
2010-08-29 14:21:49 +02:00
print _ ( " \n python 2.5-2.7 not found, please install python 2.5, 2.6 or 2.7 for fpdb \n " )
2010-08-13 03:47:00 +02:00
raw_input ( _ ( " Press ENTER to continue. " ) )
2009-12-03 13:22:33 +01:00
exit ( )
2009-08-01 13:45:10 +02:00
else :
pass
#print "debug - not changing path"
2009-11-22 06:00:23 +01:00
2009-10-26 10:03:25 +01:00
if os . name == ' nt ' :
2009-12-03 13:22:33 +01:00
try :
import win32api
import win32con
except ImportError :
2010-08-13 03:47:00 +02:00
print _ ( " We appear to be running in Windows, but the Windows Python Extensions are not loading. Please install the PYWIN32 package from http://sourceforge.net/projects/pywin32/ " )
raw_input ( _ ( " Press ENTER to continue. " ) )
2009-12-03 13:22:33 +01:00
exit ( )
2009-08-01 13:45:10 +02:00
2010-02-02 22:53:03 +01:00
print " Python " + sys . version [ 0 : 3 ] + ' ... '
2009-08-01 13:45:10 +02:00
2009-10-13 22:53:51 +02:00
import traceback
2009-07-18 23:21:29 +02:00
import threading
2009-06-15 05:14:53 +02:00
import Options
import string
cl_options = string . join ( sys . argv [ 1 : ] )
2009-11-22 06:00:23 +01:00
( options , argv ) = Options . fpdb_options ( )
2008-11-07 01:14:25 +01:00
2009-12-05 16:54:49 +01:00
import logging , logging . config
2010-07-11 19:36:45 +02:00
log = logging . getLogger ( " fpdb " )
2009-07-14 01:04:10 +02:00
2009-12-03 13:22:33 +01:00
try :
import pygtk
pygtk . require ( ' 2.0 ' )
import gtk
2009-12-08 23:17:55 +01:00
import pango
2009-12-03 13:22:33 +01:00
except :
2010-08-29 14:21:49 +02:00
print _ ( " Unable to load PyGTK modules required for GUI. Please install PyCairo, PyGObject, and PyGTK from www.pygtk.org. " )
2010-08-13 03:47:00 +02:00
raw_input ( _ ( " Press ENTER to continue. " ) )
2009-12-03 13:22:33 +01:00
exit ( )
2008-08-04 05:44:28 +02:00
2009-07-19 13:28:17 +02:00
import interlocks
2009-12-08 23:17:55 +01:00
# these imports not required in this module, imported here to report version in About dialog
try :
import matplotlib
matplotlib_version = matplotlib . __version__
except :
matplotlib_version = ' not found '
try :
import numpy
numpy_version = numpy . __version__
except :
numpy_version = ' not found '
try :
import sqlite3
sqlite3_version = sqlite3 . version
sqlite_version = sqlite3 . sqlite_version
except :
sqlite3_version = ' not found '
sqlite_version = ' not found '
2009-06-28 20:19:32 +02:00
2009-11-24 20:50:48 +01:00
import GuiPrefs
2009-12-05 16:54:49 +01:00
import GuiLogView
2010-08-12 23:16:27 +02:00
import GuiDatabase
2008-08-17 02:48:03 +02:00
import GuiBulkImport
2010-11-10 04:49:49 +01:00
import GuiTourneyImport
2010-08-10 03:28:57 +02:00
import GuiImapFetcher
2010-07-11 05:49:58 +02:00
import GuiRingPlayerStats
2010-07-09 04:47:33 +02:00
import GuiTourneyPlayerStats
2010-08-09 23:22:58 +02:00
import GuiTourneyViewer
2009-03-03 12:32:01 +01:00
import GuiPositionalStats
2008-08-17 02:48:03 +02:00
import GuiAutoImport
2008-09-20 06:56:16 +02:00
import GuiGraphViewer
2010-09-04 08:16:46 +02:00
import GuiTourneyGraphViewer
2009-05-26 10:10:27 +02:00
import GuiSessionViewer
2009-06-23 21:45:11 +02:00
import SQL
2009-06-23 00:30:54 +02:00
import Database
2008-10-21 16:22:01 +02:00
import Configuration
2009-11-22 06:00:23 +01:00
import Exceptions
2010-07-16 21:56:44 +02:00
import Stats
2008-08-04 05:44:28 +02:00
2010-08-29 14:25:44 +02:00
VERSION = " 0.20.906 plus git "
2009-01-30 19:00:29 +01:00
2009-12-05 16:54:49 +01:00
2008-08-04 05:44:28 +02:00
class fpdb :
2009-03-03 12:32:01 +01:00
def tab_clicked ( self , widget , tab_name ) :
""" called when a tab button is clicked to activate that tab """
self . display_tab ( tab_name )
def add_and_display_tab ( self , new_tab , new_tab_name ) :
""" just calls the component methods """
self . add_tab ( new_tab , new_tab_name )
self . display_tab ( new_tab_name )
2009-11-29 00:36:54 +01:00
def add_tab ( self , new_page , new_tab_name ) :
2009-03-03 12:32:01 +01:00
""" adds a tab, namely creates the button and displays it and appends all the relevant arrays """
2009-12-07 23:55:12 +01:00
for name in self . nb_tab_names : #todo: check this is valid
2009-11-29 00:36:54 +01:00
if name == new_tab_name :
2009-09-09 12:01:03 +02:00
return # if tab already exists, just go to it
2009-03-03 12:32:01 +01:00
2009-11-29 00:36:54 +01:00
used_before = False
2009-12-07 23:55:12 +01:00
for i , name in enumerate ( self . tab_names ) :
2009-11-29 00:36:54 +01:00
if name == new_tab_name :
used_before = True
event_box = self . tabs [ i ]
page = self . pages [ i ]
break
if not used_before :
event_box = self . create_custom_tab ( new_tab_name , self . nb )
page = new_page
self . pages . append ( new_page )
self . tabs . append ( event_box )
self . tab_names . append ( new_tab_name )
2009-11-30 14:14:03 +01:00
2009-11-29 00:36:54 +01:00
#self.nb.append_page(new_page, gtk.Label(new_tab_name))
self . nb . append_page ( page , event_box )
2009-12-07 23:55:12 +01:00
self . nb_tab_names . append ( new_tab_name )
2009-11-29 00:36:54 +01:00
page . show ( )
2009-03-03 12:32:01 +01:00
def display_tab ( self , new_tab_name ) :
""" displays the indicated tab """
2009-03-16 23:35:56 +01:00
tab_no = - 1
2009-12-07 23:55:12 +01:00
for i , name in enumerate ( self . nb_tab_names ) :
2009-11-29 00:36:54 +01:00
if new_tab_name == name :
2009-03-16 23:35:56 +01:00
tab_no = i
break
2009-11-28 23:00:44 +01:00
if tab_no < 0 or tab_no > = self . nb . get_n_pages ( ) :
raise FpdbError ( " invalid tab_no " + str ( tab_no ) )
2009-03-03 12:32:01 +01:00
else :
2009-11-28 23:00:44 +01:00
self . nb . set_current_page ( tab_no )
2009-03-03 12:32:01 +01:00
2009-11-29 00:36:54 +01:00
def create_custom_tab ( self , text , nb ) :
2009-11-30 14:14:03 +01:00
#create a custom tab for notebook containing a
2009-11-29 00:36:54 +01:00
#label and a button with STOCK_ICON
eventBox = gtk . EventBox ( )
tabBox = gtk . HBox ( False , 2 )
tabLabel = gtk . Label ( text )
2009-11-30 14:14:03 +01:00
tabBox . pack_start ( tabLabel , False )
2009-11-29 00:36:54 +01:00
eventBox . add ( tabBox )
if nb . get_n_pages ( ) > 0 :
tabButton = gtk . Button ( )
tabButton . connect ( ' clicked ' , self . remove_tab , ( nb , text ) )
#Add a picture on a button
self . add_icon_to_button ( tabButton )
tabBox . pack_start ( tabButton , False )
# needed, otherwise even calling show_all on the notebook won't
# make the hbox contents appear.
tabBox . show_all ( )
return eventBox
def add_icon_to_button ( self , button ) :
2009-11-30 14:14:03 +01:00
iconBox = gtk . HBox ( False , 0 )
2009-11-29 00:36:54 +01:00
image = gtk . Image ( )
2009-11-29 18:36:22 +01:00
image . set_from_stock ( gtk . STOCK_CLOSE , gtk . ICON_SIZE_SMALL_TOOLBAR )
2009-11-29 00:36:54 +01:00
gtk . Button . set_relief ( button , gtk . RELIEF_NONE )
settings = gtk . Widget . get_settings ( button ) ;
2009-11-29 18:36:22 +01:00
( w , h ) = gtk . icon_size_lookup_for_settings ( settings , gtk . ICON_SIZE_SMALL_TOOLBAR ) ;
2009-11-29 00:36:54 +01:00
gtk . Widget . set_size_request ( button , w + 4 , h + 4 ) ;
image . show ( )
iconBox . pack_start ( image , True , False , 0 )
button . add ( iconBox )
iconBox . show ( )
2009-11-30 14:14:03 +01:00
return
2009-11-29 00:36:54 +01:00
# Remove a page from the notebook
def remove_tab ( self , button , data ) :
( nb , text ) = data
page = - 1
#print "\n remove_tab: start", text
2009-12-07 23:55:12 +01:00
for i , tab in enumerate ( self . nb_tab_names ) :
2009-11-29 00:36:54 +01:00
if text == tab :
page = i
#print " page =", page
if page > = 0 and page < self . nb . get_n_pages ( ) :
#print " removing page", page
2009-12-07 23:55:12 +01:00
del self . nb_tab_names [ page ]
2009-11-29 00:36:54 +01:00
nb . remove_page ( page )
2009-11-30 14:14:03 +01:00
# Need to refresh the widget --
2009-11-29 00:36:54 +01:00
# This forces the widget to redraw itself.
#nb.queue_draw_area(0,0,-1,-1) needed or not??
2009-03-03 12:32:01 +01:00
def delete_event ( self , widget , event , data = None ) :
return False
def destroy ( self , widget , data = None ) :
2009-05-23 22:42:26 +02:00
self . quit ( widget )
2009-03-03 12:32:01 +01:00
2009-05-23 22:42:26 +02:00
def dia_about ( self , widget , data = None ) :
2009-09-10 03:57:16 +02:00
dia = gtk . AboutDialog ( )
2009-12-03 13:22:33 +01:00
dia . set_name ( " Free Poker Database (FPDB) " )
2009-09-10 03:57:16 +02:00
dia . set_version ( VERSION )
2010-08-13 03:47:00 +02:00
dia . set_copyright ( _ ( " Copyright 2008-2010, Steffen, Eratosthenes, Carl Gherardi, Eric Blade, _mt, sqlcoder, Bostik, and others " ) )
dia . set_comments ( _ ( " You are free to change, and distribute original or changed versions of fpdb within the rules set out by the license " ) )
dia . set_license ( _ ( " Please see fpdb ' s start screen for license information " ) )
2009-09-10 03:57:16 +02:00
dia . set_website ( " http://fpdb.sourceforge.net/ " )
2010-07-11 07:39:19 +02:00
2010-06-21 06:44:13 +02:00
dia . set_authors ( [ ' Steffen ' , ' Eratosthenes ' , ' Carl Gherardi ' ,
2010-08-13 04:09:28 +02:00
' Eric Blade ' , ' _mt ' , ' sqlcoder ' , ' Bostik ' , _ ( ' and others ' ) ] )
2009-12-03 13:22:33 +01:00
dia . set_program_name ( " Free Poker Database (FPDB) " )
2009-12-08 23:17:55 +01:00
db_version = " "
#if self.db is not None:
# db_version = self.db.get_version()
2010-08-13 03:47:00 +02:00
nums = [ ( _ ( ' Operating System ' ) , os . name )
2009-12-08 23:17:55 +01:00
, ( ' Python ' , sys . version [ 0 : 3 ] )
, ( ' GTK+ ' , ' . ' . join ( [ str ( x ) for x in gtk . gtk_version ] ) )
, ( ' PyGTK ' , ' . ' . join ( [ str ( x ) for x in gtk . pygtk_version ] ) )
, ( ' matplotlib ' , matplotlib_version )
, ( ' numpy ' , numpy_version )
, ( ' sqlite3 ' , sqlite3_version )
, ( ' sqlite ' , sqlite_version )
2010-08-26 18:32:01 +02:00
, ( ' fpdb version ' , VERSION )
, ( ' database used ' , self . settings [ ' db-server ' ] )
2009-12-08 23:17:55 +01:00
]
versions = gtk . TextBuffer ( )
w = 20 # width used for module names and version numbers
versions . set_text ( ' \n ' . join ( [ x [ 0 ] . rjust ( w ) + ' ' + x [ 1 ] . ljust ( w ) for x in nums ] ) )
view = gtk . TextView ( versions )
view . set_editable ( False )
view . set_justification ( gtk . JUSTIFY_CENTER )
view . modify_font ( pango . FontDescription ( ' monospace 10 ' ) )
view . show ( )
dia . vbox . pack_end ( view , True , True , 2 )
2010-07-11 07:39:19 +02:00
2010-08-13 03:47:00 +02:00
l = gtk . Label ( _ ( " Your config file is: " ) + self . config . file )
2009-12-08 23:17:55 +01:00
l . set_alignment ( 0.5 , 0.5 )
l . show ( )
dia . vbox . pack_end ( l , True , True , 2 )
2010-08-13 03:47:00 +02:00
l = gtk . Label ( _ ( ' Version Information: ' ) )
2010-07-11 07:39:19 +02:00
l . set_alignment ( 0.5 , 0.5 )
l . show ( )
dia . vbox . pack_end ( l , True , True , 2 )
2009-09-10 03:57:16 +02:00
dia . run ( )
dia . destroy ( )
2010-08-13 03:47:00 +02:00
log . debug ( _ ( " Threads: " ) )
2009-12-07 23:55:12 +01:00
for t in self . threads :
log . debug ( " ......... " + str ( t . __class__ ) )
2009-03-03 12:32:01 +01:00
2009-11-24 20:50:48 +01:00
def dia_preferences ( self , widget , data = None ) :
2010-08-13 03:47:00 +02:00
dia = gtk . Dialog ( _ ( " Preferences " ) ,
2009-11-24 20:50:48 +01:00
self . window ,
gtk . DIALOG_MODAL | gtk . DIALOG_DESTROY_WITH_PARENT ,
( gtk . STOCK_CANCEL , gtk . RESPONSE_REJECT ,
gtk . STOCK_SAVE , gtk . RESPONSE_ACCEPT ) )
2009-12-12 13:08:48 +01:00
dia . set_default_size ( 700 , 500 )
2009-12-13 13:55:15 +01:00
2010-06-24 22:34:50 +02:00
prefs = GuiPrefs . GuiPrefs ( self . config , self . window , dia . vbox , dia )
2009-11-24 20:50:48 +01:00
response = dia . run ( )
if response == gtk . RESPONSE_ACCEPT :
# save updated config
self . config . save ( )
2009-12-13 13:55:15 +01:00
if len ( self . nb_tab_names ) == 1 :
# only main tab open, reload profile
self . load_profile ( )
2010-06-24 23:47:42 +02:00
dia . d estroy ( )
2009-12-13 13:55:15 +01:00
else :
2010-06-24 23:47:42 +02:00
dia . destroy ( ) # destroy prefs before raising warning, otherwise parent is dia rather than self.window
2010-08-13 03:47:00 +02:00
self . warning_box ( _ ( " Updated preferences have not been loaded because windows are open. Re-start fpdb to load them. " ) )
2010-06-25 00:33:43 +02:00
else :
dia . destroy ( )
2009-11-24 20:50:48 +01:00
2010-02-20 19:59:49 +01:00
def dia_maintain_dbs ( self , widget , data = None ) :
2010-07-19 22:36:45 +02:00
#self.warning_box("Unimplemented: Maintain Databases")
#return
2010-02-20 19:59:49 +01:00
if len ( self . tab_names ) == 1 :
2010-07-10 21:11:59 +02:00
if self . obtain_global_lock ( " dia_maintain_dbs " ) : # returns true if successful
2010-02-20 19:59:49 +01:00
# only main tab has been opened, open dialog
2010-08-13 03:47:00 +02:00
dia = gtk . Dialog ( _ ( " Maintain Databases " ) ,
2010-02-20 19:59:49 +01:00
self . window ,
gtk . DIALOG_MODAL | gtk . DIALOG_DESTROY_WITH_PARENT ,
( gtk . STOCK_CANCEL , gtk . RESPONSE_REJECT ,
gtk . STOCK_SAVE , gtk . RESPONSE_ACCEPT ) )
dia . set_default_size ( 700 , 320 )
prefs = GuiDatabase . GuiDatabase ( self . config , self . window , dia )
response = dia . run ( )
if response == gtk . RESPONSE_ACCEPT :
2010-08-13 03:47:00 +02:00
log . info ( _ ( ' saving updated db data ' ) )
2010-02-20 19:59:49 +01:00
# save updated config
self . config . save ( )
2010-07-19 22:36:45 +02:00
self . load_profile ( )
for name in self . config . supported_databases : #db_ip/db_user/db_pass/db_server
log . info ( ' fpdb: name,desc= ' + name + ' , ' + self . config . supported_databases [ name ] . db_desc )
else :
2010-08-13 03:47:00 +02:00
log . info ( _ ( ' guidb response was ' ) + str ( response ) )
2010-02-20 19:59:49 +01:00
self . release_global_lock ( )
dia . destroy ( )
else :
2010-08-13 03:47:00 +02:00
self . warning_box ( _ ( " Cannot open Database Maintenance window because other windows have been opened. Re-start fpdb to use this option. " ) )
2009-03-03 12:32:01 +01:00
2009-05-23 22:42:26 +02:00
def dia_database_stats ( self , widget , data = None ) :
2010-08-13 03:47:00 +02:00
self . warning_box ( str = _ ( " Number of Hands: " ) + str ( self . db . getHandCount ( ) ) +
_ ( " \n Number of Tourneys: " ) + str ( self . db . getTourneyCount ( ) ) +
_ ( " \n Number of TourneyTypes: " ) + str ( self . db . getTourneyTypeCount ( ) ) ,
diatitle = _ ( " Database Statistics " ) )
2010-07-10 02:07:47 +02:00
#end def dia_database_stats
2009-03-03 12:32:01 +01:00
2010-07-15 03:32:10 +02:00
def diaHudConfigurator ( self , widget , data = None ) :
2010-07-17 00:23:48 +02:00
""" Opens dialog to set parameters (game category, row count, column count for HUD stat configurator """
2010-07-16 20:27:43 +02:00
self . hudConfiguratorRows = None
self . hudConfiguratorColumns = None
self . hudConfiguratorGame = None
2010-08-13 03:47:00 +02:00
diaSelections = gtk . Dialog ( _ ( " HUD Configurator - choose category " ) ,
2010-07-15 03:32:10 +02:00
self . window ,
gtk . DIALOG_MODAL | gtk . DIALOG_DESTROY_WITH_PARENT ,
( gtk . STOCK_OK , gtk . RESPONSE_ACCEPT ,
gtk . STOCK_CANCEL , gtk . RESPONSE_REJECT ) )
2010-08-13 03:47:00 +02:00
label = gtk . Label ( _ ( " Please select the game category for which you want to configure HUD stats: " ) )
2010-07-15 03:32:10 +02:00
diaSelections . vbox . add ( label )
label . show ( )
comboGame = gtk . combo_box_new_text ( )
comboGame . connect ( " changed " , self . hudConfiguratorComboSelection )
diaSelections . vbox . add ( comboGame )
games = self . config . get_supported_games ( )
for game in games :
comboGame . append_text ( game )
2010-07-16 20:32:01 +02:00
comboGame . set_active ( 0 )
2010-07-15 03:32:10 +02:00
comboGame . show ( )
comboRows = gtk . combo_box_new_text ( )
comboRows . connect ( " changed " , self . hudConfiguratorComboSelection )
diaSelections . vbox . add ( comboRows )
for i in range ( 1 , 8 ) :
comboRows . append_text ( str ( i ) + " rows " )
2010-07-16 20:32:01 +02:00
comboRows . set_active ( 0 )
2010-07-15 03:32:10 +02:00
comboRows . show ( )
comboColumns = gtk . combo_box_new_text ( )
comboColumns . connect ( " changed " , self . hudConfiguratorComboSelection )
diaSelections . vbox . add ( comboColumns )
for i in range ( 1 , 8 ) :
comboColumns . append_text ( str ( i ) + " columns " )
2010-07-16 20:32:01 +02:00
comboColumns . set_active ( 0 )
2010-07-15 03:32:10 +02:00
comboColumns . show ( )
response = diaSelections . run ( )
diaSelections . destroy ( )
2010-07-16 20:27:43 +02:00
if response == gtk . RESPONSE_ACCEPT and self . hudConfiguratorRows != None and self . hudConfiguratorColumns != None and self . hudConfiguratorGame != None :
2010-07-17 00:23:48 +02:00
#print "clicked ok and selected:", self.hudConfiguratorGame,"with", str(self.hudConfiguratorRows), "rows and", str(self.hudConfiguratorColumns), "columns"
2010-07-16 20:27:43 +02:00
self . diaHudConfiguratorTable ( )
2010-07-15 03:32:10 +02:00
#end def diaHudConfigurator
def hudConfiguratorComboSelection ( self , widget ) :
2010-07-17 00:23:48 +02:00
#TODO: remove this and handle it directly in diaHudConfigurator
2010-07-15 03:32:10 +02:00
result = widget . get_active_text ( )
if result . endswith ( " rows " ) :
self . hudConfiguratorRows = int ( result [ 0 ] )
elif result . endswith ( " columns " ) :
self . hudConfiguratorColumns = int ( result [ 0 ] )
else :
self . hudConfiguratorGame = result
#end def hudConfiguratorComboSelection
2010-07-16 20:27:43 +02:00
def diaHudConfiguratorTable ( self ) :
2010-07-17 00:23:48 +02:00
""" shows dialogue with Table of ComboBoxes to allow choosing of HUD stats """
#TODO: add notices to hud configurator: no duplicates, no empties, display options
2010-07-16 20:27:43 +02:00
#TODO: show explanation of what each stat means
2010-08-13 03:47:00 +02:00
diaHudTable = gtk . Dialog ( _ ( " HUD Configurator - please choose your stats " ) ,
2010-07-16 20:27:43 +02:00
self . window ,
gtk . DIALOG_MODAL | gtk . DIALOG_DESTROY_WITH_PARENT ,
( gtk . STOCK_SAVE , gtk . RESPONSE_ACCEPT ,
gtk . STOCK_CANCEL , gtk . RESPONSE_REJECT ) )
2010-08-13 03:47:00 +02:00
label = gtk . Label ( _ ( " Please choose the stats you wish to use in the below table. " ) )
2010-07-17 03:09:55 +02:00
diaHudTable . vbox . add ( label )
label . show ( )
2010-08-13 03:47:00 +02:00
label = gtk . Label ( _ ( " Note that you may not select any stat more than once or it will crash. " ) )
2010-07-17 03:09:55 +02:00
diaHudTable . vbox . add ( label )
label . show ( )
2010-08-13 03:47:00 +02:00
label = gtk . Label ( _ ( " It is not currently possible to select \" empty \" or anything else to that end. " ) )
2010-07-17 03:09:55 +02:00
diaHudTable . vbox . add ( label )
label . show ( )
2010-08-29 14:21:49 +02:00
label = gtk . Label ( _ ( " To configure things like colouring you will still have to use the Preferences dialogue or manually edit your HUD_config.xml. " ) )
2010-07-16 20:27:43 +02:00
diaHudTable . vbox . add ( label )
label . show ( )
self . hudConfiguratorTableContents = [ ]
table = gtk . Table ( rows = self . hudConfiguratorRows + 1 , columns = self . hudConfiguratorColumns + 1 , homogeneous = True )
2010-07-16 21:56:44 +02:00
statDir = dir ( Stats )
statDict = { }
for attr in statDir :
if attr . startswith ( ' __ ' ) : continue
if attr in ( " Charset " , " Configuration " , " Database " , " GInitiallyUnowned " , " gtk " , " pygtk " ,
" player " , " c " , " db_connection " , " do_stat " , " do_tip " , " stat_dict " ,
" h " , " re " , " re_Percent " , " re_Places " , ) : continue
statDict [ attr ] = eval ( " Stats. %s .__doc__ " % ( attr ) )
2010-07-16 20:27:43 +02:00
for rowNumber in range ( self . hudConfiguratorRows + 1 ) :
newRow = [ ]
for columnNumber in range ( self . hudConfiguratorColumns + 1 ) :
if rowNumber == 0 :
if columnNumber == 0 :
pass
else :
label = gtk . Label ( " column " + str ( columnNumber ) )
table . attach ( child = label , left_attach = columnNumber , right_attach = columnNumber + 1 , top_attach = rowNumber , bottom_attach = rowNumber + 1 )
label . show ( )
2010-07-16 21:00:29 +02:00
elif columnNumber == 0 :
label = gtk . Label ( " row " + str ( rowNumber ) )
table . attach ( child = label , left_attach = columnNumber , right_attach = columnNumber + 1 , top_attach = rowNumber , bottom_attach = rowNumber + 1 )
label . show ( )
2010-07-16 20:27:43 +02:00
else :
2010-07-16 21:00:29 +02:00
comboBox = gtk . combo_box_new_text ( )
2010-07-16 21:56:44 +02:00
for stat in statDict . keys ( ) :
comboBox . append_text ( stat )
2010-07-16 21:00:29 +02:00
comboBox . set_active ( 0 )
newRow . append ( comboBox )
table . attach ( child = comboBox , left_attach = columnNumber , right_attach = columnNumber + 1 , top_attach = rowNumber , bottom_attach = rowNumber + 1 )
comboBox . show ( )
2010-07-17 00:23:48 +02:00
if rowNumber != 0 :
self . hudConfiguratorTableContents . append ( newRow )
2010-07-16 20:27:43 +02:00
diaHudTable . vbox . add ( table )
table . show ( )
response = diaHudTable . run ( )
diaHudTable . destroy ( )
if response == gtk . RESPONSE_ACCEPT :
self . storeNewHudStatConfig ( )
#end def diaHudConfiguratorTable
def storeNewHudStatConfig ( self ) :
2010-07-17 00:23:48 +02:00
""" stores selections made in diaHudConfiguratorTable """
2010-07-16 20:32:01 +02:00
self . obtain_global_lock ( " diaHudConfiguratorTable " )
2010-07-17 00:23:48 +02:00
statTable = [ ]
2010-07-16 21:56:44 +02:00
for row in self . hudConfiguratorTableContents :
2010-07-17 00:23:48 +02:00
newRow = [ ]
2010-07-16 21:56:44 +02:00
for column in row :
2010-07-17 00:23:48 +02:00
newField = column . get_active_text ( )
newRow . append ( newField )
statTable . append ( newRow )
self . config . editStats ( self . hudConfiguratorGame , statTable )
self . config . save ( ) #TODO: make it not store in horrible formatting
2010-07-16 20:32:01 +02:00
self . release_global_lock ( )
2010-07-16 20:27:43 +02:00
#end def storeNewHudStatConfig
2010-07-11 09:47:05 +02:00
def dia_dump_db ( self , widget , data = None ) :
2010-07-17 05:11:09 +02:00
filename = " database-dump.sql "
result = self . db . dumpDatabase ( )
dumpFile = open ( filename , ' w ' )
dumpFile . write ( result )
dumpFile . close ( )
2010-07-11 09:47:05 +02:00
#end def dia_database_stats
2009-03-03 12:32:01 +01:00
2009-05-23 22:42:26 +02:00
def dia_load_profile ( self , widget , data = None ) :
2009-03-03 12:32:01 +01:00
""" Dialogue to select a file to load a profile from """
2010-07-10 21:11:59 +02:00
if self . obtain_global_lock ( " fpdb.dia_load_profile " ) : # returns true if successful
2009-06-23 21:45:11 +02:00
#try:
# chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
# action=gtk.FILE_CHOOSER_ACTION_OPEN,
# buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
# chooser.set_filename(self.profile)
# response = chooser.run()
2009-11-22 06:00:23 +01:00
# chooser.destroy()
2009-06-23 21:45:11 +02:00
# if response == gtk.RESPONSE_OK:
# self.load_profile(chooser.get_filename())
# elif response == gtk.RESPONSE_CANCEL:
# print 'User cancelled loading profile'
#except:
# pass
2009-07-31 06:13:51 +02:00
#try:
self . load_profile ( )
#except:
# pass
2009-06-04 21:27:15 +02:00
self . release_global_lock ( )
2009-03-03 12:32:01 +01:00
2009-05-23 22:42:26 +02:00
def dia_recreate_tables ( self , widget , data = None ) :
2009-03-03 12:32:01 +01:00
""" Dialogue that asks user to confirm that he wants to delete and recreate the tables """
2010-07-10 21:11:59 +02:00
if self . obtain_global_lock ( " fpdb.dia_recreate_tables " ) : # returns true if successful
2009-06-04 21:27:15 +02:00
2009-07-18 23:21:29 +02:00
#lock_released = False
2010-06-24 22:34:50 +02:00
dia_confirm = gtk . MessageDialog ( parent = self . window , flags = gtk . DIALOG_DESTROY_WITH_PARENT , type = gtk . MESSAGE_WARNING ,
2010-08-13 03:51:03 +02:00
buttons = ( gtk . BUTTONS_YES_NO ) , message_format = _ ( " Confirm deleting and recreating tables " ) )
2010-08-29 20:35:16 +02:00
diastring = _ ( " Please confirm that you want to (re-)create the tables. " ) \
+ ( _ ( " If there already are tables in the database %s on %s they will be deleted and you will have to re-import your histories. \n " ) % ( self . db . database , self . db . host ) ) \
+ _ ( " This may take a while. " )
2009-08-16 11:46:41 +02:00
dia_confirm . format_secondary_text ( diastring ) #todo: make above string with bold for db, host and deleted
2010-06-24 22:34:50 +02:00
# disable windowclose, do not want the the underlying processing interrupted mid-process
dia_confirm . set_deletable ( False )
2009-08-16 11:46:41 +02:00
response = dia_confirm . run ( )
dia_confirm . destroy ( )
if response == gtk . RESPONSE_YES :
2009-10-13 22:53:51 +02:00
#if self.db.backend == self.fdb_lock.fdb.MYSQL_INNODB:
2009-11-22 06:00:23 +01:00
# mysql requires locks on all tables or none - easier to release this lock
2009-08-16 11:46:41 +02:00
# than lock all the other tables
# ToDo: lock all other tables so that lock doesn't have to be released
# self.release_global_lock()
# lock_released = True
self . db . recreate_tables ( )
2010-07-18 17:21:27 +02:00
# find any guibulkimport/guiautoimport windows and clear player cache:
2010-07-14 22:07:20 +02:00
for t in self . threads :
2010-07-18 17:21:27 +02:00
if isinstance ( t , GuiBulkImport . GuiBulkImport ) or isinstance ( t , GuiAutoImport . GuiAutoImport ) :
2010-07-14 22:07:20 +02:00
t . importer . database . resetPlayerIDs ( )
2010-07-04 23:19:57 +02:00
self . release_global_lock ( )
2009-08-16 11:46:41 +02:00
#else:
# for other dbs use same connection as holds global lock
# self.fdb_lock.fdb.recreate_tables()
elif response == gtk . RESPONSE_NO :
2010-07-11 20:00:27 +02:00
self . release_global_lock ( )
2010-08-13 03:51:03 +02:00
print _ ( ' User cancelled recreating tables ' )
2009-07-18 23:21:29 +02:00
#if not lock_released:
2010-07-04 23:19:57 +02:00
#end def dia_recreate_tables
2009-11-22 06:00:23 +01:00
2009-07-27 23:28:06 +02:00
def dia_recreate_hudcache ( self , widget , data = None ) :
2010-07-10 21:11:59 +02:00
if self . obtain_global_lock ( " dia_recreate_hudcache " ) :
2010-06-24 22:34:50 +02:00
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 " )
2010-08-13 03:51:03 +02:00
diastring = _ ( " Please confirm that you want to re-create the HUD cache. " )
2009-09-27 00:32:44 +02:00
self . dia_confirm . format_secondary_text ( diastring )
2010-06-24 22:34:50 +02:00
# disable windowclose, do not want the the underlying processing interrupted mid-process
self . dia_confirm . set_deletable ( False )
2009-09-27 00:32:44 +02:00
2009-11-30 22:43:29 +01:00
hb1 = gtk . HBox ( True , 1 )
self . h_start_date = gtk . Entry ( max = 12 )
self . h_start_date . set_text ( self . db . get_hero_hudcache_start ( ) )
2010-08-13 03:51:03 +02:00
lbl = gtk . Label ( _ ( " Hero ' s cache starts: " ) )
2009-11-30 22:43:29 +01:00
btn = gtk . Button ( )
btn . set_image ( gtk . image_new_from_stock ( gtk . STOCK_INDEX , gtk . ICON_SIZE_BUTTON ) )
btn . connect ( ' clicked ' , self . __calendar_dialog , self . h_start_date )
hb1 . pack_start ( lbl , expand = True , padding = 3 )
hb1 . pack_start ( self . h_start_date , expand = True , padding = 2 )
hb1 . pack_start ( btn , expand = False , padding = 3 )
self . dia_confirm . vbox . add ( hb1 )
hb1 . show_all ( )
hb2 = gtk . HBox ( True , 1 )
2009-09-27 00:32:44 +02:00
self . start_date = gtk . Entry ( max = 12 )
2009-09-27 02:42:26 +02:00
self . start_date . set_text ( self . db . get_hero_hudcache_start ( ) )
2010-08-13 03:51:03 +02:00
lbl = gtk . Label ( _ ( " Villains ' cache starts: " ) )
2009-09-27 00:32:44 +02:00
btn = gtk . Button ( )
btn . set_image ( gtk . image_new_from_stock ( gtk . STOCK_INDEX , gtk . ICON_SIZE_BUTTON ) )
btn . connect ( ' clicked ' , self . __calendar_dialog , self . start_date )
2009-11-30 22:43:29 +01:00
hb2 . pack_start ( lbl , expand = True , padding = 3 )
hb2 . pack_start ( self . start_date , expand = True , padding = 2 )
hb2 . pack_start ( btn , expand = False , padding = 3 )
self . dia_confirm . vbox . add ( hb2 )
hb2 . show_all ( )
2009-09-27 00:32:44 +02:00
response = self . dia_confirm . run ( )
2009-07-31 06:15:25 +02:00
if response == gtk . RESPONSE_YES :
2010-08-13 03:51:03 +02:00
lbl = gtk . Label ( _ ( " Rebuilding HUD Cache ... " ) )
2009-11-30 22:43:29 +01:00
self . dia_confirm . vbox . add ( lbl )
lbl . show ( )
while gtk . events_pending ( ) :
gtk . main_iteration_do ( False )
self . db . rebuild_hudcache ( self . h_start_date . get_text ( ) , self . start_date . get_text ( ) )
2009-09-27 00:32:44 +02:00
elif response == gtk . RESPONSE_NO :
2010-08-13 03:51:03 +02:00
print _ ( ' User cancelled rebuilding hud cache ' )
2009-09-27 00:32:44 +02:00
2009-11-30 22:43:29 +01:00
self . dia_confirm . destroy ( )
2009-07-27 23:28:06 +02:00
self . release_global_lock ( )
2009-09-27 00:32:44 +02:00
2009-11-30 00:02:45 +01:00
def dia_rebuild_indexes ( self , widget , data = None ) :
2010-07-10 21:11:59 +02:00
if self . obtain_global_lock ( " dia_rebuild_indexes " ) :
2010-06-24 22:34:50 +02:00
self . dia_confirm = gtk . MessageDialog ( parent = self . window
, flags = gtk . DIALOG_DESTROY_WITH_PARENT
2009-11-30 00:02:45 +01:00
, type = gtk . MESSAGE_WARNING
, buttons = ( gtk . BUTTONS_YES_NO )
2010-08-13 03:51:03 +02:00
, message_format = _ ( " Confirm rebuilding database indexes " ) )
diastring = _ ( " Please confirm that you want to rebuild the database indexes. " )
2009-11-30 00:02:45 +01:00
self . dia_confirm . format_secondary_text ( diastring )
2010-06-24 22:34:50 +02:00
# disable windowclose, do not want the the underlying processing interrupted mid-process
self . dia_confirm . set_deletable ( False )
2009-11-30 00:02:45 +01:00
response = self . dia_confirm . run ( )
if response == gtk . RESPONSE_YES :
2010-06-25 19:06:51 +02:00
#FIXME these progress messages do not seem to work in *nix
2010-08-13 03:51:03 +02:00
lbl = gtk . Label ( _ ( " Rebuilding Indexes ... " ) )
2009-11-30 22:43:29 +01:00
self . dia_confirm . vbox . add ( lbl )
lbl . show ( )
while gtk . events_pending ( ) :
gtk . main_iteration_do ( False )
2009-11-30 00:02:45 +01:00
self . db . rebuild_indexes ( )
2009-11-30 22:43:29 +01:00
2010-08-13 03:51:03 +02:00
lbl . set_text ( _ ( " Cleaning Database ... " ) )
2009-11-30 22:43:29 +01:00
while gtk . events_pending ( ) :
gtk . main_iteration_do ( False )
2009-11-30 00:02:45 +01:00
self . db . vacuumDB ( )
2009-11-30 22:43:29 +01:00
2010-08-13 03:51:03 +02:00
lbl . set_text ( _ ( " Analyzing Database ... " ) )
2009-11-30 22:43:29 +01:00
while gtk . events_pending ( ) :
gtk . main_iteration_do ( False )
2009-11-30 00:02:45 +01:00
self . db . analyzeDB ( )
elif response == gtk . RESPONSE_NO :
2010-08-13 03:51:03 +02:00
print _ ( ' User cancelled rebuilding db indexes ' )
2009-11-30 00:02:45 +01:00
2009-11-30 22:43:29 +01:00
self . dia_confirm . destroy ( )
2009-11-30 00:02:45 +01:00
self . release_global_lock ( )
2009-12-05 16:54:49 +01:00
def dia_logs ( self , widget , data = None ) :
2009-12-07 23:55:12 +01:00
""" opens the log viewer window """
2009-12-05 16:54:49 +01:00
2009-12-07 23:55:12 +01:00
#lock_set = False
2010-07-10 21:11:59 +02:00
#if self.obtain_global_lock("dia_logs"):
2009-12-07 23:55:12 +01:00
# lock_set = True
2009-12-05 16:54:49 +01:00
2009-12-09 22:58:56 +01:00
# remove members from self.threads if close messages received
self . process_close_messages ( )
viewer = None
2009-12-07 23:55:12 +01:00
for i , t in enumerate ( self . threads ) :
if str ( t . __class__ ) == ' GuiLogView.GuiLogView ' :
2009-12-09 22:58:56 +01:00
viewer = t
break
2009-12-07 23:55:12 +01:00
2009-12-09 22:58:56 +01:00
if viewer is None :
#print "creating new log viewer"
new_thread = GuiLogView . GuiLogView ( self . config , self . window , self . closeq )
self . threads . append ( new_thread )
else :
#print "showing existing log viewer"
viewer . get_dialog ( ) . present ( )
2009-12-07 23:55:12 +01:00
#if lock_set:
# self.release_global_lock()
2009-12-05 16:54:49 +01:00
def addLogText ( self , text ) :
end_iter = self . logbuffer . get_end_iter ( )
self . logbuffer . insert ( end_iter , text )
self . logview . scroll_to_mark ( self . logbuffer . get_insert ( ) , 0 )
2009-12-09 22:58:56 +01:00
def process_close_messages ( self ) :
# check for close messages
try :
while True :
name = self . closeq . get ( False )
for i , t in enumerate ( self . threads ) :
if str ( t . __class__ ) == str ( name ) :
# thread has ended so remove from list:
del self . threads [ i ]
break
except Queue . Empty :
# no close messages on queue, do nothing
pass
2009-09-27 00:32:44 +02:00
def __calendar_dialog ( self , widget , entry ) :
2010-06-24 22:34:50 +02:00
# do not alter the modality of the parent
# self.dia_confirm.set_modal(False)
2009-09-27 00:32:44 +02:00
d = gtk . Window ( gtk . WINDOW_TOPLEVEL )
2010-06-24 22:34:50 +02:00
d . set_transient_for ( self . dia_confirm )
d . set_destroy_with_parent ( True )
d . set_modal ( True )
2010-08-13 03:51:03 +02:00
d . set_title ( _ ( ' Pick a date ' ) )
2009-09-27 00:32:44 +02:00
vb = gtk . VBox ( )
cal = gtk . Calendar ( )
vb . pack_start ( cal , expand = False , padding = 0 )
2010-08-13 03:51:03 +02:00
btn = gtk . Button ( _ ( ' Done ' ) )
2009-09-27 00:32:44 +02:00
btn . connect ( ' clicked ' , self . __get_date , cal , entry , d )
vb . pack_start ( btn , expand = False , padding = 4 )
d . add ( vb )
d . set_position ( gtk . WIN_POS_MOUSE )
d . show_all ( )
def __get_dates ( self ) :
2009-11-30 22:43:29 +01:00
t1 = self . h_start_date . get_text ( )
2009-09-27 00:32:44 +02:00
if t1 == ' ' :
t1 = ' 1970-01-01 '
2009-11-30 22:43:29 +01:00
t2 = self . start_date . get_text ( )
if t2 == ' ' :
t2 = ' 1970-01-01 '
return ( t1 , t2 )
2009-09-27 00:32:44 +02:00
def __get_date ( self , widget , calendar , entry , win ) :
# year and day are correct, month is 0..11
( year , month , day ) = calendar . get_date ( )
month + = 1
ds = ' %04d - %02d - %02d ' % ( year , month , day )
entry . set_text ( ds )
win . destroy ( )
self . dia_confirm . set_modal ( True )
2009-11-22 06:00:23 +01:00
2009-05-23 22:42:26 +02:00
def dia_save_profile ( self , widget , data = None ) :
2010-08-13 04:09:28 +02:00
self . warning_box ( _ ( " Unimplemented: Save Profile (try saving a HUD layout, that should do it) " ) )
2009-11-22 06:00:23 +01:00
2009-03-03 12:32:01 +01:00
def get_menu ( self , window ) :
""" returns the menu for this program """
2009-05-23 22:42:26 +02:00
fpdbmenu = """
< ui >
< menubar name = " MenuBar " >
< menu action = " main " >
< menuitem action = " LoadProf " / >
< menuitem action = " SaveProf " / >
2010-07-15 03:32:10 +02:00
< menuitem action = " hudConfigurator " / >
2009-11-24 20:50:48 +01:00
< menuitem action = " Preferences " / >
2009-05-23 22:42:26 +02:00
< separator / >
< menuitem action = " Quit " / >
< / menu >
< menu action = " import " >
< menuitem action = " bulkimp " / >
2010-11-10 04:49:49 +01:00
< menuitem action = " tourneyimp " / >
2010-08-10 03:28:57 +02:00
< menuitem action = " imapimport " / >
2009-05-23 22:42:26 +02:00
< menuitem action = " autoimp " / >
< / menu >
< menu action = " viewers " >
< menuitem action = " autoimp " / >
2010-07-15 03:32:10 +02:00
< menuitem action = " hudConfigurator " / >
2009-05-23 22:42:26 +02:00
< menuitem action = " graphs " / >
2010-09-04 08:16:46 +02:00
< menuitem action = " tourneygraphs " / >
2010-07-09 04:47:33 +02:00
< menuitem action = " ringplayerstats " / >
< menuitem action = " tourneyplayerstats " / >
2010-08-09 23:22:58 +02:00
< menuitem action = " tourneyviewer " / >
2009-05-23 22:42:26 +02:00
< menuitem action = " posnstats " / >
2009-10-21 11:22:47 +02:00
< menuitem action = " sessionstats " / >
2009-05-23 22:42:26 +02:00
< / menu >
< menu action = " database " >
2010-02-20 19:59:49 +01:00
< menuitem action = " maintaindbs " / >
2009-05-23 22:42:26 +02:00
< menuitem action = " createtabs " / >
2009-07-27 23:28:06 +02:00
< menuitem action = " rebuildhudcache " / >
2009-11-30 00:02:45 +01:00
< menuitem action = " rebuildindexes " / >
2010-07-11 09:47:05 +02:00
< menuitem action = " databasestats " / >
< menuitem action = " dumptofile " / >
2009-05-23 22:42:26 +02:00
< / menu >
< menu action = " help " >
2009-12-05 16:54:49 +01:00
< menuitem action = " Logs " / >
2009-05-23 22:42:26 +02:00
< separator / >
< menuitem action = " About " / >
< / menu >
< / menubar >
< / ui > """
uimanager = gtk . UIManager ( )
accel_group = uimanager . get_accel_group ( )
actiongroup = gtk . ActionGroup ( ' UIManagerExample ' )
# Create actions
2010-08-13 02:49:01 +02:00
actiongroup . add_actions ( [ ( ' main ' , None , _ ( ' _Main ' ) ) ,
( ' Quit ' , gtk . STOCK_QUIT , _ ( ' _Quit ' ) , None , ' Quit the Program ' , self . quit ) ,
2010-08-13 04:09:28 +02:00
( ' LoadProf ' , None , _ ( ' _Load Profile (broken) ' ) , _ ( ' <control>L ' ) , ' Load your profile ' , self . dia_load_profile ) ,
( ' SaveProf ' , None , _ ( ' _Save Profile (todo) ' ) , _ ( ' <control>S ' ) , ' Save your profile ' , self . dia_save_profile ) ,
( ' Preferences ' , None , _ ( ' Pre_ferences ' ) , _ ( ' <control>F ' ) , ' Edit your preferences ' , self . dia_preferences ) ,
2010-08-13 03:28:27 +02:00
( ' import ' , None , _ ( ' _Import ' ) ) ,
2010-08-13 04:09:28 +02:00
( ' bulkimp ' , None , _ ( ' _Bulk Import ' ) , _ ( ' <control>B ' ) , ' Bulk Import ' , self . tab_bulk_import ) ,
2010-11-10 04:49:49 +01:00
( ' tourneyimp ' , None , _ ( ' Tournament _Results Import ' ) , _ ( ' <control>R ' ) , ' Tournament Results Import ' , self . tab_tourney_import ) ,
2010-08-13 04:09:28 +02:00
( ' imapimport ' , None , _ ( ' _Import through eMail/IMAP ' ) , _ ( ' <control>I ' ) , ' Import through eMail/IMAP ' , self . tab_imap_import ) ,
2010-08-13 03:28:27 +02:00
( ' viewers ' , None , _ ( ' _Viewers ' ) ) ,
2010-08-13 04:09:28 +02:00
( ' autoimp ' , None , _ ( ' _Auto Import and HUD ' ) , _ ( ' <control>A ' ) , ' Auto Import and HUD ' , self . tab_auto_import ) ,
( ' hudConfigurator ' , None , _ ( ' _HUD Configurator ' ) , _ ( ' <control>H ' ) , ' HUD Configurator ' , self . diaHudConfigurator ) ,
( ' graphs ' , None , _ ( ' _Graphs ' ) , _ ( ' <control>G ' ) , ' Graphs ' , self . tabGraphViewer ) ,
2010-09-04 08:16:46 +02:00
( ' tourneygraphs ' , None , _ ( ' Tourney Graphs ' ) , None , ' TourneyGraphs ' , self . tabTourneyGraphViewer ) ,
2010-11-09 22:42:40 +01:00
( ' ringplayerstats ' , None , _ ( ' Ring _Player Stats (tabulated view, not on pgsql) ' ) , _ ( ' <control>P ' ) , ' Ring Player Stats (tabulated view, not on pgsql) ' , self . tab_ring_player_stats ) ,
( ' tourneyplayerstats ' , None , _ ( ' _Tourney Stats (tabulated view, not on pgsql) ' ) , _ ( ' <control>T ' ) , ' Tourney Stats (tabulated view, not on pgsql) ' , self . tab_tourney_player_stats ) ,
2010-08-13 03:28:27 +02:00
( ' tourneyviewer ' , None , _ ( ' Tourney _Viewer ' ) , None , ' Tourney Viewer) ' , self . tab_tourney_viewer_stats ) ,
2010-11-09 22:42:40 +01:00
( ' posnstats ' , None , _ ( ' P_ositional Stats (tabulated view, not on sqlite) ' ) , _ ( ' <control>O ' ) , ' Positional Stats (tabulated view, not on sqlite) ' , self . tab_positional_stats ) ,
2010-08-13 03:28:27 +02:00
( ' sessionstats ' , None , _ ( ' Session Stats ' ) , None , ' Session Stats ' , self . tab_session_stats ) ,
( ' database ' , None , _ ( ' _Database ' ) ) ,
( ' maintaindbs ' , None , _ ( ' _Maintain Databases ' ) , None , ' Maintain Databases ' , self . dia_maintain_dbs ) ,
( ' createtabs ' , None , _ ( ' Create or Recreate _Tables ' ) , None , ' Create or Recreate Tables ' , self . dia_recreate_tables ) ,
( ' rebuildhudcache ' , None , _ ( ' Rebuild HUD Cache ' ) , None , ' Rebuild HUD Cache ' , self . dia_recreate_hudcache ) ,
( ' rebuildindexes ' , None , _ ( ' Rebuild DB Indexes ' ) , None , ' Rebuild DB Indexes ' , self . dia_rebuild_indexes ) ,
( ' databasestats ' , None , _ ( ' _Statistics ' ) , None , ' View Database Statistics ' , self . dia_database_stats ) ,
( ' dumptofile ' , None , _ ( ' Dump Database to Textfile (takes ALOT of time) ' ) , None , ' Dump Database to Textfile (takes ALOT of time) ' , self . dia_dump_db ) ,
( ' help ' , None , _ ( ' _Help ' ) ) ,
( ' Logs ' , None , _ ( ' _Log Messages ' ) , None , ' Log and Debug Messages ' , self . dia_logs ) ,
( ' About ' , None , _ ( ' A_bout, License, Copying ' ) , None , ' About the program ' , self . dia_about ) ,
2009-05-23 22:42:26 +02:00
] )
2010-08-13 04:09:28 +02:00
actiongroup . get_action ( ' Quit ' ) . set_property ( ' short-label ' , _ ( ' _Quit ' ) )
2009-05-23 22:42:26 +02:00
uimanager . insert_action_group ( actiongroup , 0 )
merge_id = uimanager . add_ui_from_string ( fpdbmenu )
# Create a MenuBar
menubar = uimanager . get_widget ( ' /MenuBar ' )
2009-03-03 12:32:01 +01:00
window . add_accel_group ( accel_group )
2009-05-23 22:42:26 +02:00
return menubar
2010-07-08 19:46:25 +02:00
#end def get_menu
2009-03-03 12:32:01 +01:00
2010-02-20 19:59:49 +01:00
def load_profile ( self , create_db = False ) :
2009-03-03 12:32:01 +01:00
""" Loads profile from the provided path name. """
2009-06-23 21:45:11 +02:00
self . config = Configuration . Config ( file = options . config , dbname = options . dbname )
2010-02-20 11:27:58 +01:00
if self . config . file_error :
2010-08-13 03:28:27 +02:00
self . warning_box ( _ ( " There is an error in your config file \n " ) + self . config . file
+ _ ( " \n \n Error is: " ) + str ( self . config . file_error )
, diatitle = _ ( " CONFIG FILE ERROR " ) )
2010-06-14 23:52:23 +02:00
sys . exit ( )
2010-02-20 11:27:58 +01:00
2010-01-31 12:25:24 +01:00
log = Configuration . get_logger ( " logging.conf " , " fpdb " , log_dir = self . config . dir_log )
2010-08-17 23:30:15 +02:00
print ( _ ( " Logfile is %s \n " ) % os . path . join ( self . config . dir_log , self . config . log_file ) )
2010-01-31 13:24:32 +01:00
if self . config . example_copy :
2010-08-13 03:28:27 +02:00
self . info_box ( _ ( " Config file " )
, _ ( " has been created at: \n %s . \n " ) % self . config . file
2010-08-29 19:12:48 +02:00
+ _ ( " Edit your screen_name and hand history path in the supported_sites section of the Preferences window (Main menu) before trying to import hands. " ) )
2009-03-03 12:32:01 +01:00
self . settings = { }
2009-07-18 23:21:29 +02:00
self . settings [ ' global_lock ' ] = self . lock
2009-03-03 12:32:01 +01:00
if ( os . sep == " / " ) :
self . settings [ ' os ' ] = " linuxmac "
else :
self . settings [ ' os ' ] = " windows "
2009-06-15 05:14:53 +02:00
self . settings . update ( { ' cl_options ' : cl_options } )
2009-03-27 15:53:44 +01:00
self . settings . update ( self . config . get_db_parameters ( ) )
2009-03-03 12:32:01 +01:00
self . settings . update ( self . config . get_import_parameters ( ) )
self . settings . update ( self . config . get_default_paths ( ) )
2010-08-12 23:16:27 +02:00
if self . db is not None and self . db . is_connected ( ) :
2009-03-03 12:32:01 +01:00
self . db . disconnect ( )
2009-11-03 19:18:51 +01:00
self . sql = SQL . Sql ( db_server = self . settings [ ' db-server ' ] )
2009-12-12 10:51:07 +01:00
err_msg = None
2009-10-09 13:31:25 +02:00
try :
self . db = Database . Database ( self . config , sql = self . sql )
2010-02-01 23:31:00 +01:00
if self . db . get_backend_name ( ) == ' SQLite ' :
# tell sqlite users where the db file is
2010-08-17 23:30:15 +02:00
print ( _ ( " Connected to SQLite: %s " ) % self . db . db_path )
2009-11-22 06:00:23 +01:00
except Exceptions . FpdbMySQLAccessDenied :
2010-08-13 03:28:27 +02:00
err_msg = _ ( " MySQL Server reports: Access denied. Are your permissions set correctly? " )
2009-11-27 13:19:43 +01:00
except Exceptions . FpdbMySQLNoDatabase :
2010-08-13 03:28:27 +02:00
err_msg = _ ( " MySQL client reports: 2002 or 2003 error. Unable to connect - " ) \
+ _ ( " Please check that the MySQL service has been started " )
2009-12-12 10:51:07 +01:00
except Exceptions . FpdbPostgresqlAccessDenied :
2010-08-29 19:12:48 +02:00
err_msg = _ ( " PostgreSQL Server reports: Access denied. Are your permissions set correctly? " )
2009-12-12 10:51:07 +01:00
except Exceptions . FpdbPostgresqlNoDatabase :
2010-08-29 19:12:48 +02:00
err_msg = _ ( " PostgreSQL client reports: Unable to connect - " ) \
+ _ ( " Please check that the PostgreSQL service has been started " )
2009-12-12 10:51:07 +01:00
if err_msg is not None :
self . db = None
self . warning_box ( err_msg )
2010-08-12 23:16:27 +02:00
if self . db is not None and not self . db . is_connected ( ) :
self . db = None
2009-11-22 06:00:23 +01:00
# except FpdbMySQLFailedError:
# self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR")
# exit()
# except FpdbError:
# #print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
# self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
# err = traceback.extract_tb(sys.exc_info()[2])[-1]
# print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
# sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
# except:
# #print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
# self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
# err = traceback.extract_tb(sys.exc_info()[2])[-1]
# print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
# sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
2009-06-28 20:19:32 +02:00
2009-12-12 10:51:07 +01:00
if self . db is not None and self . db . wrongDbVersion :
2010-08-13 03:28:27 +02:00
diaDbVersionWarning = gtk . Dialog ( title = _ ( " Strong Warning - Invalid database version " ) , parent = None , flags = 0 , buttons = ( gtk . STOCK_OK , gtk . RESPONSE_OK ) )
2009-03-03 12:32:01 +01:00
2010-08-13 03:28:27 +02:00
label = gtk . Label ( _ ( " An invalid DB version or missing tables have been detected. " ) )
2009-03-03 12:32:01 +01:00
diaDbVersionWarning . vbox . add ( label )
label . show ( )
2010-08-13 03:28:27 +02:00
label = gtk . Label ( _ ( " This error is not necessarily fatal but it is strongly recommended that you recreate the tables by using the Database menu. " ) )
2009-03-03 12:32:01 +01:00
diaDbVersionWarning . vbox . add ( label )
label . show ( )
2010-08-13 03:28:27 +02:00
label = gtk . Label ( _ ( " Not doing this will likely lead to misbehaviour including fpdb crashes, corrupt data etc. " ) )
2009-03-03 12:32:01 +01:00
diaDbVersionWarning . vbox . add ( label )
label . show ( )
response = diaDbVersionWarning . run ( )
diaDbVersionWarning . destroy ( )
2009-11-03 20:30:52 +01:00
if self . status_bar is None :
2009-12-12 10:51:07 +01:00
self . status_bar = gtk . Label ( " " )
2009-06-23 21:45:11 +02:00
self . main_vbox . pack_end ( self . status_bar , False , True , 0 )
self . status_bar . show ( )
2010-08-12 23:16:27 +02:00
if self . db is not None and self . db . is_connected ( ) :
2010-08-13 03:28:27 +02:00
self . status_bar . set_text ( _ ( " Status: Connected to %s database named %s on host %s " )
2009-12-12 10:51:07 +01:00
% ( self . db . get_backend_name ( ) , self . db . database , self . db . host ) )
# rollback to make sure any locks are cleared:
self . db . rollback ( )
2009-11-22 06:00:23 +01:00
2009-09-10 01:20:50 +02:00
self . validate_config ( )
2009-03-03 12:32:01 +01:00
2010-07-10 20:10:04 +02:00
def obtain_global_lock ( self , source ) :
ret = self . lock . acquire ( source = source ) # will return false if lock is already held
2009-07-18 23:21:29 +02:00
if ret :
2010-08-29 19:12:48 +02:00
print ( _ ( " \n Global lock taken by %s " ) % source )
2010-07-10 20:10:04 +02:00
self . lockTakenBy = source
2009-07-18 23:21:29 +02:00
else :
2010-08-29 19:12:48 +02:00
print ( _ ( " \n Failed to get global lock, it is currently held by %s " ) % source )
2009-07-18 23:21:29 +02:00
return ret
# need to release it later:
# self.lock.release()
2009-06-09 22:38:30 +02:00
def quit ( self , widget , data = None ) :
2009-11-01 01:06:16 +01:00
# TODO: can we get some / all of the stuff done in this function to execute on any kind of abort?
2010-06-25 19:06:51 +02:00
#FIXME get two "quitting normally" messages, following the addition of the self.window.destroy() call
2010-07-13 22:23:32 +02:00
# ... because self.window.destroy() leads to self.destroy() which calls this!
if not self . quitting :
2010-08-13 03:28:27 +02:00
print _ ( " Quitting normally " )
2010-07-13 22:23:32 +02:00
self . quitting = True
2009-11-01 01:06:16 +01:00
# TODO: check if current settings differ from profile, if so offer to save or abort
2010-07-12 16:48:12 +02:00
2010-07-13 18:04:26 +02:00
if self . db != None :
if self . db . backend == self . db . MYSQL_INNODB :
try :
2010-10-12 00:23:22 +02:00
import _mysql_exceptions
2010-08-12 23:16:27 +02:00
if self . db is not None and self . db . is_connected ( ) :
2010-07-13 18:04:26 +02:00
self . db . disconnect ( )
except _mysql_exceptions . OperationalError : # oh, damn, we're already disconnected
pass
else :
2010-08-12 23:16:27 +02:00
if self . db is not None and self . db . is_connected ( ) :
2010-07-12 16:48:12 +02:00
self . db . disconnect ( )
else :
2010-02-05 14:58:47 +01:00
pass
2009-10-26 23:26:22 +01:00
self . statusIcon . set_visible ( False )
2010-06-25 19:06:51 +02:00
self . window . destroy ( ) # explicitly destroy to allow child windows to close cleanly
2009-03-03 12:32:01 +01:00
gtk . main_quit ( )
def release_global_lock ( self ) :
2009-07-18 23:21:29 +02:00
self . lock . release ( )
2010-07-10 20:10:04 +02:00
self . lockTakenBy = None
2010-08-13 03:28:27 +02:00
print _ ( " Global lock released. \n " )
2009-03-03 12:32:01 +01:00
2009-05-23 22:42:26 +02:00
def tab_auto_import ( self , widget , data = None ) :
2009-03-03 12:32:01 +01:00
""" opens the auto import tab """
2010-06-28 00:21:40 +02:00
new_aimp_thread = GuiAutoImport . GuiAutoImport ( self . settings , self . config , self . sql , self . window )
2009-03-03 12:32:01 +01:00
self . threads . append ( new_aimp_thread )
aimp_tab = new_aimp_thread . get_vbox ( )
2010-08-13 03:28:27 +02:00
self . add_and_display_tab ( aimp_tab , _ ( " Auto Import " ) )
2009-03-03 12:32:01 +01:00
2009-05-23 22:42:26 +02:00
def tab_bulk_import ( self , widget , data = None ) :
2009-03-03 12:32:01 +01:00
""" opens a tab for bulk importing """
2010-09-05 00:12:29 +02:00
new_import_thread = GuiBulkImport . GuiBulkImport ( self . settings , self . config , self . sql , self . window )
2009-03-03 12:32:01 +01:00
self . threads . append ( new_import_thread )
bulk_tab = new_import_thread . get_vbox ( )
2010-08-13 03:28:27 +02:00
self . add_and_display_tab ( bulk_tab , _ ( " Bulk Import " ) )
2009-03-03 12:32:01 +01:00
2010-11-10 04:49:49 +01:00
def tab_tourney_import ( self , widget , data = None ) :
""" opens a tab for bulk importing """
new_import_thread = GuiTourneyImport . GuiTourneyImport ( self . settings , self . config , self . sql , self . window )
self . threads . append ( new_import_thread )
bulk_tab = new_import_thread . get_vbox ( )
self . add_and_display_tab ( bulk_tab , _ ( " Tournament Results Import " ) )
2010-08-10 03:28:57 +02:00
def tab_imap_import ( self , widget , data = None ) :
new_thread = GuiImapFetcher . GuiImapFetcher ( self . config , self . db , self . sql , self . window )
self . threads . append ( new_thread )
tab = new_thread . get_vbox ( )
2010-08-13 03:28:27 +02:00
self . add_and_display_tab ( tab , _ ( " eMail Import " ) )
2010-08-10 03:28:57 +02:00
#end def tab_import_imap_summaries
2010-07-09 04:47:33 +02:00
def tab_ring_player_stats ( self , widget , data = None ) :
2010-07-11 05:49:58 +02:00
new_ps_thread = GuiRingPlayerStats . GuiRingPlayerStats ( self . config , self . sql , self . window )
2009-03-03 12:32:01 +01:00
self . threads . append ( new_ps_thread )
ps_tab = new_ps_thread . get_vbox ( )
2010-08-13 03:28:27 +02:00
self . add_and_display_tab ( ps_tab , _ ( " Ring Player Stats " ) )
2010-07-09 04:47:33 +02:00
def tab_tourney_player_stats ( self , widget , data = None ) :
2010-07-10 02:09:58 +02:00
new_ps_thread = GuiTourneyPlayerStats . GuiTourneyPlayerStats ( self . config , self . db , self . sql , self . window )
2009-03-03 12:32:01 +01:00
self . threads . append ( new_ps_thread )
ps_tab = new_ps_thread . get_vbox ( )
2010-11-09 22:42:40 +01:00
self . add_and_display_tab ( ps_tab , _ ( " Tourney Stats " ) )
2009-03-03 12:32:01 +01:00
2010-08-09 23:22:58 +02:00
def tab_tourney_viewer_stats ( self , widget , data = None ) :
new_thread = GuiTourneyViewer . GuiTourneyViewer ( self . config , self . db , self . sql , self . window )
self . threads . append ( new_thread )
tab = new_thread . get_vbox ( )
2010-08-13 03:28:27 +02:00
self . add_and_display_tab ( tab , _ ( " Tourney Viewer " ) )
2010-08-09 23:22:58 +02:00
2009-05-23 22:42:26 +02:00
def tab_positional_stats ( self , widget , data = None ) :
2009-07-19 19:28:13 +02:00
new_ps_thread = GuiPositionalStats . GuiPositionalStats ( self . config , self . sql )
2009-03-03 12:32:01 +01:00
self . threads . append ( new_ps_thread )
ps_tab = new_ps_thread . get_vbox ( )
2010-08-13 03:28:27 +02:00
self . add_and_display_tab ( ps_tab , _ ( " Positional Stats " ) )
2009-03-03 12:32:01 +01:00
2009-10-21 11:22:47 +02:00
def tab_session_stats ( self , widget , data = None ) :
new_ps_thread = GuiSessionViewer . GuiSessionViewer ( self . config , self . sql , self . window )
self . threads . append ( new_ps_thread )
ps_tab = new_ps_thread . get_vbox ( )
2010-08-13 03:28:27 +02:00
self . add_and_display_tab ( ps_tab , _ ( " Session Stats " ) )
2009-10-21 11:22:47 +02:00
2009-05-23 22:42:26 +02:00
def tab_main_help ( self , widget , data = None ) :
2009-03-03 12:32:01 +01:00
""" Displays a tab with the main fpdb help screen """
2010-08-13 05:01:01 +02:00
mh_tab = gtk . Label ( _ ( """ Fpdb needs translators!
2010-08-13 04:36:22 +02:00
If you speak another language and have a few minutes or more to spare get in touch by emailing steffen @schaumburger.info
Welcome to Fpdb !
2010-07-14 20:58:37 +02:00
To be notified of new snapshots and releases go to https : / / lists . sourceforge . net / lists / listinfo / fpdb - announce and subscribe .
If you want to follow development more closely go to https : / / lists . sourceforge . net / lists / listinfo / fpdb - main and subscribe .
2010-06-25 08:16:56 +02:00
This program is currently in an alpha - state , so our database format is still sometimes changed .
You should therefore always keep your hand history files so that you can re - import after an update , if necessary .
2010-07-10 16:24:32 +02:00
2010-08-13 04:36:22 +02:00
For documentation please visit our website / wiki at http : / / fpdb . sourceforge . net / .
2010-06-21 13:00:09 +02:00
If you need help click on Contact - Get Help on our website .
Please note that default . conf is no longer needed nor used , all configuration now happens in HUD_config . xml .
2010-07-04 03:05:16 +02:00
This program is free / libre open source software licensed partially under the AGPL3 , and partially under GPL2 or later .
2010-08-02 11:53:02 +02:00
The Windows installer package includes code licensed under the MIT license .
2010-08-13 03:28:27 +02:00
You can find the full license texts in agpl - 3.0 . txt , gpl - 2.0 . txt , gpl - 3.0 . txt and mit . txt in the fpdb installation directory . """ ))
self . add_and_display_tab ( mh_tab , _ ( " Help " ) )
2009-03-03 12:32:01 +01:00
2009-05-23 22:42:26 +02:00
def tabGraphViewer ( self , widget , data = None ) :
2009-03-03 12:32:01 +01:00
""" opens a graph viewer tab """
2010-06-28 00:21:40 +02:00
new_gv_thread = GuiGraphViewer . GuiGraphViewer ( self . sql , self . config , self . window )
2009-03-03 12:32:01 +01:00
self . threads . append ( new_gv_thread )
2009-09-10 00:41:32 +02:00
gv_tab = new_gv_thread . get_vbox ( )
2010-08-13 03:28:27 +02:00
self . add_and_display_tab ( gv_tab , _ ( " Graphs " ) )
2009-03-03 12:32:01 +01:00
2010-09-04 08:16:46 +02:00
def tabTourneyGraphViewer ( self , widget , data = None ) :
""" opens a graph viewer tab """
new_gv_thread = GuiTourneyGraphViewer . GuiTourneyGraphViewer ( self . sql , self . config , self . window )
self . threads . append ( new_gv_thread )
gv_tab = new_gv_thread . get_vbox ( )
self . add_and_display_tab ( gv_tab , _ ( " Tourney Graphs " ) )
2009-03-03 12:32:01 +01:00
def __init__ ( self ) :
2009-07-19 13:28:17 +02:00
# no more than 1 process can this lock at a time:
self . lock = interlocks . InterProcessLock ( name = " fpdb_global_lock " )
2009-06-23 21:45:11 +02:00
self . db = None
self . status_bar = None
2010-07-13 22:23:32 +02:00
self . quitting = False
2009-03-03 12:32:01 +01:00
2010-08-21 13:24:34 +02:00
self . visible = False
2009-03-03 12:32:01 +01:00
self . window = gtk . Window ( gtk . WINDOW_TOPLEVEL )
self . window . connect ( " delete_event " , self . delete_event )
self . window . connect ( " destroy " , self . destroy )
2010-07-10 16:40:10 +02:00
self . window . set_title ( " Free Poker DB - v %s " % ( VERSION , ) )
2009-03-03 12:32:01 +01:00
self . window . set_border_width ( 1 )
2010-06-14 23:52:23 +02:00
defx , defy = 900 , 720
sx , sy = gtk . gdk . screen_width ( ) , gtk . gdk . screen_height ( )
if sx < defx : defx = sx
if sy < defy : defy = sy
self . window . set_default_size ( defx , defy )
2009-03-03 12:32:01 +01:00
self . window . set_resizable ( True )
self . main_vbox = gtk . VBox ( False , 1 )
self . main_vbox . set_border_width ( 1 )
self . window . add ( self . main_vbox )
self . main_vbox . show ( )
menubar = self . get_menu ( self . window )
self . main_vbox . pack_start ( menubar , False , True , 0 )
menubar . show ( )
#done menubar
2009-12-07 23:55:12 +01:00
self . threads = [ ] # objects used by tabs - no need for threads, gtk handles it
2009-12-09 22:58:56 +01:00
self . closeq = Queue . Queue ( 20 ) # used to signal ending of a thread (only logviewer for now)
2009-12-07 23:55:12 +01:00
2009-11-28 23:00:44 +01:00
self . nb = gtk . Notebook ( )
self . nb . set_show_tabs ( True )
self . nb . show ( )
self . main_vbox . pack_start ( self . nb , True , True , 0 )
2009-12-07 23:55:12 +01:00
self . tabs = [ ] # the event_boxes forming the actual tabs
self . tab_names = [ ] # names of tabs used since program started, not removed if tab is closed
self . pages = [ ] # the contents of the page, not removed if tab is closed
self . nb_tab_names = [ ] # list of tab names currently displayed in notebook
2009-03-03 12:32:01 +01:00
self . tab_main_help ( None , None )
self . window . show ( )
2010-08-21 13:24:34 +02:00
self . visible = True # Flip on
2010-02-20 19:59:49 +01:00
self . load_profile ( create_db = True )
2009-11-22 06:00:23 +01:00
2010-02-02 22:53:03 +01:00
if not options . errorsToConsole :
fileName = os . path . join ( self . config . dir_log , ' fpdb-errors.txt ' )
2010-08-29 19:12:48 +02:00
print ( _ ( " \n Note: error output is being diverted to fpdb-errors.txt and HUD-errors.txt in: %s " ) % self . config . dir_log ) \
+ _ ( " \n Any major error will be reported there _only_. \n " )
2010-02-02 22:53:03 +01:00
errorFile = open ( fileName , ' w ' , 0 )
sys . stderr = errorFile
2009-10-26 06:36:29 +01:00
self . statusIcon = gtk . StatusIcon ( )
2010-02-06 13:27:15 +01:00
# use getcwd() here instead of sys.path[0] so that py2exe works:
cards = os . path . join ( os . getcwd ( ) , ' .. ' , ' gfx ' , ' fpdb-cards.png ' )
if os . path . exists ( cards ) :
self . statusIcon . set_from_file ( cards )
2010-10-04 13:04:52 +02:00
self . window . set_icon_from_file ( cards )
2009-10-27 14:28:11 +01:00
elif os . path . exists ( ' /usr/share/pixmaps/fpdb-cards.png ' ) :
2009-10-27 14:24:49 +01:00
self . statusIcon . set_from_file ( ' /usr/share/pixmaps/fpdb-cards.png ' )
2010-10-04 13:04:52 +02:00
self . window . set_icon_from_file ( ' /usr/share/pixmaps/fpdb-cards.png ' )
2009-10-27 14:24:49 +01:00
else :
self . statusIcon . set_from_stock ( gtk . STOCK_HOME )
2010-10-04 13:04:52 +02:00
self . window . set_icon_stock ( gtk . STOCK_HOME )
2009-10-26 06:36:29 +01:00
self . statusIcon . set_tooltip ( " Free Poker Database " )
self . statusIcon . connect ( ' activate ' , self . statusicon_activate )
self . statusMenu = gtk . Menu ( )
menuItem = gtk . ImageMenuItem ( gtk . STOCK_ABOUT )
menuItem . connect ( ' activate ' , self . dia_about )
self . statusMenu . append ( menuItem )
2010-06-24 22:34:50 +02:00
2009-10-26 06:36:29 +01:00
menuItem = gtk . ImageMenuItem ( gtk . STOCK_QUIT )
menuItem . connect ( ' activate ' , self . quit )
self . statusMenu . append ( menuItem )
2010-06-24 22:34:50 +02:00
2009-10-26 06:36:29 +01:00
self . statusIcon . connect ( ' popup-menu ' , self . statusicon_menu , self . statusMenu )
self . statusIcon . set_visible ( True )
2009-11-22 06:00:23 +01:00
2009-10-26 06:36:29 +01:00
self . window . connect ( ' window-state-event ' , self . window_state_event_cb )
2010-08-13 03:28:27 +02:00
sys . stderr . write ( _ ( " fpdb starting ... " ) )
2009-11-22 06:00:23 +01:00
2010-08-21 13:24:34 +02:00
def __iconify ( self ) :
self . visible = False
self . window . set_skip_taskbar_hint ( True )
2010-08-21 18:32:46 +02:00
self . window . set_skip_pager_hint ( True )
2010-08-21 13:24:34 +02:00
def __deiconify ( self ) :
self . visible = True
self . window . set_skip_taskbar_hint ( False )
2010-08-21 18:32:46 +02:00
self . window . set_skip_pager_hint ( False )
2009-11-22 06:00:23 +01:00
2010-08-21 13:24:34 +02:00
def window_state_event_cb ( self , window , event ) :
# Deal with iconification first
if event . changed_mask & gtk . gdk . WINDOW_STATE_ICONIFIED :
2009-10-26 06:36:29 +01:00
if event . new_window_state & gtk . gdk . WINDOW_STATE_ICONIFIED :
2010-08-21 13:24:34 +02:00
self . __iconify ( )
2009-10-26 06:36:29 +01:00
else :
2010-08-21 13:24:34 +02:00
self . __deiconify ( )
if not event . new_window_state & gtk . gdk . WINDOW_STATE_WITHDRAWN :
return True
# And then the tray icon click
if event . new_window_state & gtk . gdk . WINDOW_STATE_WITHDRAWN :
self . __iconify ( )
else :
self . __deiconify ( )
2009-10-26 12:29:32 +01:00
# Tell GTK not to propagate this signal any further
return True
2009-11-22 06:00:23 +01:00
2009-10-26 06:36:29 +01:00
def statusicon_menu ( self , widget , button , time , data = None ) :
# we don't need to pass data here, since we do keep track of most all
# our variables .. the example code that i looked at for this
# didn't use any long scope variables.. which might be an alright
# idea too sometime
if button == 3 :
if data :
data . show_all ( )
data . popup ( None , None , None , 3 , time )
pass
2009-11-22 06:00:23 +01:00
2009-10-26 06:36:29 +01:00
def statusicon_activate ( self , widget , data = None ) :
2009-10-27 18:45:52 +01:00
# Let's allow the tray icon to toggle window visibility, the way
# most other apps work
2010-08-21 13:24:34 +02:00
if self . visible :
2009-10-27 18:45:52 +01:00
self . window . hide ( )
else :
self . window . present ( )
2009-11-22 06:00:23 +01:00
2010-01-31 13:24:32 +01:00
def info_box ( self , str1 , str2 ) :
2010-06-25 19:06:51 +02:00
diapath = gtk . MessageDialog ( parent = self . window , flags = gtk . DIALOG_DESTROY_WITH_PARENT , type = gtk . MESSAGE_INFO
2010-01-31 13:24:32 +01:00
, buttons = ( gtk . BUTTONS_OK ) , message_format = str1 )
diapath . format_secondary_text ( str2 )
response = diapath . run ( )
diapath . destroy ( )
return response
2010-08-13 03:28:27 +02:00
def warning_box ( self , str , diatitle = _ ( " FPDB WARNING " ) ) :
2010-06-25 19:06:51 +02:00
diaWarning = gtk . Dialog ( title = diatitle , parent = self . window , flags = gtk . DIALOG_DESTROY_WITH_PARENT , buttons = ( gtk . STOCK_OK , gtk . RESPONSE_OK ) )
2009-09-10 01:20:50 +02:00
2010-01-31 13:24:32 +01:00
label = gtk . Label ( str )
diaWarning . vbox . add ( label )
label . show ( )
2009-09-10 01:20:50 +02:00
2010-01-31 13:24:32 +01:00
response = diaWarning . run ( )
diaWarning . destroy ( )
return response
2009-11-22 06:00:23 +01:00
2009-09-10 01:20:50 +02:00
def validate_config ( self ) :
2010-08-31 23:44:41 +02:00
# can this be removed now?
2010-02-19 23:50:45 +01:00
if self . config . get_import_parameters ( ) . get ( ' saveStarsHH ' ) :
hhbase = self . config . get_import_parameters ( ) . get ( " hhArchiveBase " )
hhbase = os . path . expanduser ( hhbase )
#hhdir = os.path.join(hhbase,site)
hhdir = hhbase
if not os . path . isdir ( hhdir ) :
diapath = gtk . MessageDialog ( parent = None , flags = 0 , type = gtk . MESSAGE_WARNING , buttons = ( gtk . BUTTONS_YES_NO ) , message_format = " Setup hh dir " )
2010-08-29 19:12:48 +02:00
diastring = _ ( " WARNING: Unable to find output hand history directory %s \n \n Press YES to create this directory, or NO to select a new one. " ) % hhdir
2010-02-19 23:50:45 +01:00
diapath . format_secondary_text ( diastring )
response = diapath . run ( )
diapath . destroy ( )
if response == gtk . RESPONSE_YES :
try :
os . makedirs ( hhdir )
except :
2010-08-13 03:28:27 +02:00
self . warning_box ( _ ( " WARNING: Unable to create hand output directory. Importing is not likely to work until this is fixed. " ) )
2010-02-19 23:50:45 +01:00
elif response == gtk . RESPONSE_NO :
self . select_hhArchiveBase ( )
2009-11-22 06:00:23 +01:00
2010-08-31 23:44:41 +02:00
# check if sites in config file are in DB
for site in self . config . get_supported_sites ( True ) : # get site names from config file
try :
self . config . get_site_id ( site ) # and check against list from db
2010-10-24 21:40:04 +02:00
except KeyError , exc :
2010-08-31 23:44:41 +02:00
log . warning ( " site %s missing from db " % site )
dia = gtk . MessageDialog ( parent = None , flags = 0 , type = gtk . MESSAGE_WARNING , buttons = ( gtk . BUTTONS_YES_NO ) , message_format = " Unknown Site " )
diastring = _ ( " WARNING: Unable to find site ' %s ' \n \n Press YES to add this site to the database. " ) % site
dia . format_secondary_text ( diastring )
response = dia . run ( )
dia . destroy ( )
if response == gtk . RESPONSE_YES :
self . add_site ( site )
def add_site ( self , site ) :
dia = gtk . Dialog ( title = " Add Site " , parent = self . window
, flags = gtk . DIALOG_DESTROY_WITH_PARENT
, buttons = ( gtk . STOCK_SAVE , gtk . RESPONSE_ACCEPT
, gtk . STOCK_CANCEL , gtk . RESPONSE_REJECT )
)
h = gtk . HBox ( )
dia . vbox . pack_start ( h , padding = 5 ) # sets horizontal padding
label = gtk . Label ( _ ( " \n Enter short code for %s \n (up to 3 characters): \n " ) % site )
h . pack_start ( label , padding = 20 ) # sets horizontal padding
#label.set_alignment(1.0, 0.5)
h = gtk . HBox ( )
dia . vbox . add ( h )
e_code = gtk . Entry ( max = 3 )
e_code . set_width_chars ( 5 )
h . pack_start ( e_code , True , False , padding = 5 )
label = gtk . Label ( " " )
dia . vbox . add ( label ) # create space below entry, maybe padding arg above makes this redundant?
dia . show_all ( )
response = dia . run ( )
site_code = e_code . get_text ( )
if response == gtk . RESPONSE_ACCEPT and site_code is not None and site_code != " " :
self . db . add_site ( site , site_code )
self . db . commit ( )
dia . destroy ( )
2009-03-03 12:32:01 +01:00
def main ( self ) :
gtk . main ( )
return 0
2008-08-04 05:44:28 +02:00
2009-11-30 22:43:29 +01:00
2008-08-04 05:44:28 +02:00
if __name__ == " __main__ " :
2009-03-03 12:32:01 +01:00
me = fpdb ( )
me . main ( )