diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py
index 0348bc21..d40f37f9 100755
--- a/pyfpdb/Configuration.py
+++ b/pyfpdb/Configuration.py
@@ -519,6 +519,9 @@ class Config:
file = None
return file
+ def get_doc(self):
+ return self.doc
+
def get_site_node(self, site):
for site_node in self.doc.getElementsByTagName("site"):
if site_node.getAttribute("site_name") == site:
@@ -553,11 +556,9 @@ class Config:
return location_node
def save(self, file = None):
- if file is not None:
- with open(file, 'w') as f:
- self.doc.writexml(f)
- else:
- shutil.move(self.file, self.file+".backup")
+ if file is None:
+ file = self.file
+ shutil.move(file, file+".backup")
with open(file, 'w') as f:
self.doc.writexml(f)
diff --git a/pyfpdb/GuiPrefs.py b/pyfpdb/GuiPrefs.py
new file mode 100755
index 00000000..ada9cb51
--- /dev/null
+++ b/pyfpdb/GuiPrefs.py
@@ -0,0 +1,169 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+#Copyright 2008 Carl Gherardi
+#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 .
+#In the "official" distribution you can find the license in
+#agpl-3.0.txt in the docs folder of the package.
+
+
+import xml.dom.minidom
+from xml.dom.minidom import Node
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+import Configuration
+
+
+class GuiPrefs:
+
+ def __init__(self, config, mainwin, dia):
+ self.config = config
+ self.main_window = mainwin
+ self.dialog = dia
+
+ self.tree_box = gtk.ScrolledWindow()
+ self.tree_box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ self.dialog.add(self.tree_box)
+ self.dialog.show()
+
+ self.doc = None
+ self.configStore = None
+ self.configView = None
+
+ self.fillFrames()
+
+ def fillFrames(self):
+ self.doc = self.config.get_doc()
+
+ self.configStore = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_STRING, gobject.TYPE_STRING)
+ self.configView = gtk.TreeView(self.configStore)
+ self.configView.set_enable_tree_lines(True)
+
+ configColumn = gtk.TreeViewColumn("Setting")
+ self.configView.append_column(configColumn)
+ cRender = gtk.CellRendererText()
+ configColumn.pack_start(cRender, True)
+ configColumn.add_attribute(cRender, 'text', 1)
+
+ configColumn = gtk.TreeViewColumn("Value")
+ self.configView.append_column(configColumn)
+ cRender = gtk.CellRendererText()
+ configColumn.pack_start(cRender, True)
+ configColumn.add_attribute(cRender, 'text', 2)
+
+ if self.doc.documentElement.tagName == 'FreePokerToolsConfig':
+ self.configStore.clear()
+ self.root = self.configStore.append( None, [self.doc.documentElement, "fpdb", None] )
+ for elem in self.doc.documentElement.childNodes:
+ iter = self.addTreeRows(self.root, elem)
+ if self.root != None:
+ self.configView.expand_row(self.configStore.get_path(self.root), False)
+ self.configView.connect("row-activated", self.rowChosen)
+ self.configView.show()
+ self.tree_box.add(self.configView)
+ self.tree_box.show()
+ self.dialog.show()
+
+ def addTreeRows(self, parent, node):
+ if (node.nodeType == node.ELEMENT_NODE):
+ (setting, value) = (node.nodeName, None)
+ elif (node.nodeType == node.TEXT_NODE):
+ # text nodes hold the whitespace (or whatever) between the xml elements, not used here
+ (setting, value) = ("TEXT: ["+node.nodeValue+"|"+node.nodeValue+"]", node.data)
+ else:
+ (setting, value) = ("?? "+node.nodeValue, "type="+str(node.nodeType))
+
+ #iter = self.configStore.append( parent, [node.nodeValue, None] )
+ iter = None
+ if node.nodeType != node.TEXT_NODE and node.nodeType != node.COMMENT_NODE:
+ iter = self.configStore.append( parent, [node, setting, value] )
+ if node.hasAttributes():
+ for i in xrange(node.attributes.length):
+ self.configStore.append( iter, [node, node.attributes.item(i).localName, node.attributes.item(i).value] )
+ if node.hasChildNodes():
+ for elem in node.childNodes:
+ self.addTreeRows(iter, elem)
+ return iter
+
+ def rowChosen(self, tview, path, something2, data=None):
+ # tview should= self.configStore
+ tmodel = tview.get_model()
+ iter = tmodel.get_iter(path)
+ if tmodel.iter_has_child(iter):
+ # toggle children display
+ if tview.row_expanded(path):
+ tview.collapse_row(tmodel.get_path(iter))
+ else:
+ tview.expand_row(tmodel.get_path(iter), False)
+ else:
+ # display value and allow edit
+ name = tmodel.get_value( iter, 1 )
+ val = tmodel.get_value( iter, 2 )
+ dia_edit = gtk.Dialog(name,
+ self.main_window,
+ gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
+ gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+ #dia_edit.set_default_size(350, 100)
+ entry = gtk.Entry()
+ if val:
+ entry.set_text(val)
+ entry.set_width_chars(40)
+ dia_edit.vbox.pack_start(entry, False, False, 0)
+ entry.show()
+ entry.connect("activate", self.__set_entry, dia_edit)
+ response = dia_edit.run()
+ if response == gtk.RESPONSE_ACCEPT:
+ # update configStore
+ new_val = entry.get_text()
+ tmodel.set_value(iter, 2, new_val)
+ tmodel.get_value(iter, 0).setAttribute(name, new_val)
+ dia_edit.destroy()
+
+ def __set_entry(self, w, dia=None):
+ if dia is not None:
+ dia.response(gtk.RESPONSE_ACCEPT)
+
+
+
+if __name__=="__main__":
+
+ config = Configuration.Config()
+
+ win = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ win.set_title("Test Preferences Dialog")
+ win.set_border_width(1)
+ win.set_default_size(600, 500)
+ win.set_resizable(True)
+
+ dia = gtk.Dialog("Preferences",
+ win,
+ gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
+ gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT))
+ dia.set_default_size(500, 500)
+ prefs = GuiPrefs(config, win, dia.vbox)
+ response = dia.run()
+ if response == gtk.RESPONSE_ACCEPT:
+ # save updated config
+ config.save()
+ dia.destroy()
+
+
+
+
diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py
index d0a5b815..80d3fb93 100755
--- a/pyfpdb/fpdb.py
+++ b/pyfpdb/fpdb.py
@@ -69,6 +69,7 @@ import gtk
import interlocks
+import GuiPrefs
import GuiBulkImport
import GuiPlayerStats
import GuiPositionalStats
@@ -146,6 +147,20 @@ class fpdb:
dia.run()
dia.destroy()
+ def dia_preferences(self, widget, data=None):
+ dia = gtk.Dialog("Preferences",
+ 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(500, 500)
+ prefs = GuiPrefs.GuiPrefs(self.config, self.window, dia.vbox)
+ response = dia.run()
+ if response == gtk.RESPONSE_ACCEPT:
+ # save updated config
+ self.config.save()
+ dia.destroy()
+
def dia_create_del_database(self, widget, data=None):
self.warning_box("Unimplemented: Create/Delete Database")
self.obtain_global_lock()
@@ -350,6 +365,7 @@ class fpdb:
+
@@ -396,6 +412,7 @@ class fpdb:
('LoadProf', None, '_Load Profile (broken)', 'L', 'Load your profile', self.dia_load_profile),
('EditProf', None, '_Edit Profile (todo)', 'E', 'Edit your profile', self.dia_edit_profile),
('SaveProf', None, '_Save Profile (todo)', 'S', 'Save your profile', self.dia_save_profile),
+ ('Preferences', None, '_Preferences', None, 'Edit your preferences', self.dia_preferences),
('import', None, '_Import'),
('sethharchive', None, '_Set HandHistory Archive Directory', None, 'Set HandHistory Archive Directory', self.select_hhArchiveBase),
('bulkimp', None, '_Bulk Import', 'B', 'Bulk Import', self.tab_bulk_import),