* src/ViewManager.py: integrate the new DbManager

* src/glade/gramps.glade: integrate the new DbManager
	* src/gramps_main.py: integrate the new DbManager
	* src/DbManager.py: integrate the new DbManager


svn: r8320
This commit is contained in:
Don Allingham 2007-03-27 03:18:49 +00:00
parent bfe0e121fb
commit 911590e880
5 changed files with 452 additions and 22 deletions

View File

@ -1,5 +1,8 @@
2007-03-26 Don Allingham <don@gramps-project.org>
* src/ViewManager.py: integrate the new DbManager
* src/glade/gramps.glade: integrate the new DbManager
* src/gramps_main.py: integrate the new DbManager
* src/DbManager.py: integrate the new DbManager
* src/DisplayModels/_PeopleModel.py (PeopleModel._build_search_sub):
switch back to old format for handling cursor until bug can be resolved

200
src/DbManager.py Normal file
View File

@ -0,0 +1,200 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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 General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id: Bookmarks.py 8197 2007-02-20 20:56:48Z hippy $
"Handle bookmarks for the gramps interface"
__author__ = "Donald N. Allingham"
__version__ = "$Revision: 8197 $"
#-------------------------------------------------------------------------
#
# Standard python modules
#
#-------------------------------------------------------------------------
import const
import os
import time
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# set up logging
#
#-------------------------------------------------------------------------
import logging
log = logging.getLogger(".Bookmarks")
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gtk
import gtk.glade
#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
import QuestionDialog
DEFAULT_DIR = os.path.expanduser("~/grampsdb")
DEFAULT_TITLE = _("Unnamed Database")
NAME_FILE = "name.txt"
META_NAME = "meta_data.db"
NAME_COL = 0
PATH_COL = 1
FILE_COL = 2
DATE_COL = 3
class DbManager:
def __init__(self):
self.glade = gtk.glade.XML(const.gladeFile, "dbmanager", "gramps")
self.top = self.glade.get_widget('dbmanager')
self.connect = self.glade.get_widget('ok')
self.cancel = self.glade.get_widget('cancel')
self.new = self.glade.get_widget('new')
self.remove = self.glade.get_widget('remove')
self.dblist = self.glade.get_widget('dblist')
self.model = None
self.connect_signals()
self.build_interface()
self.populate()
def connect_signals(self):
self.remove.connect('clicked', self.remove_db)
self.new.connect('clicked', self.new_db)
def build_interface(self):
render = gtk.CellRendererText()
render.set_property('editable',True)
render.connect('edited', self.change_name)
column = gtk.TreeViewColumn(_('Database name'), render,
text=NAME_COL)
self.dblist.append_column(column)
render = gtk.CellRendererText()
column = gtk.TreeViewColumn(_('Last modified'), render, text=DATE_COL)
self.dblist.append_column(column)
self.dblist.set_rules_hint(True)
def populate(self):
self.model = gtk.ListStore(str, str, str, str, int)
sort_list = []
for dpath in os.listdir(DEFAULT_DIR):
path_name = os.path.join(DEFAULT_DIR, dpath, NAME_FILE)
if os.path.isfile(path_name):
name = file(path_name).readline().strip()
meta = os.path.join(DEFAULT_DIR, dpath, META_NAME)
if os.path.isfile(meta):
tval = int(time.time())
last = time.asctime(time.localtime(time.time()))
else:
tval = 0
last = _("Never")
sort_list.append((name,
os.path.join(DEFAULT_DIR, dpath),
path_name,
last,
tval))
sort_list.sort()
for items in sort_list:
data = [items[0], items[1], items[2], items[3], items[4]]
self.model.append(data)
self.dblist.set_model(self.model)
def run(self):
value = self.top.run()
if value == gtk.RESPONSE_OK:
(model, node) = self.dblist.get_selection().get_selected()
if node:
self.top.destroy()
return self.model.get_value(node, PATH_COL)
else:
self.top.destroy()
return None
else:
self.top.destroy()
return None
def change_name(self, text, path, new_text):
if len(new_text) > 0:
iter = self.model.get_iter(path)
filename = self.model.get_value(iter, FILE_COL)
try:
f = open(filename, "w")
f.write(new_text)
f.close()
self.model.set_value(iter, NAME_COL, new_text)
except:
pass
def remove_db(self, obj):
store, iter = self.dblist.get_selection().get_selected()
path = store.get_path(iter)
row = store[path]
self.data_to_delete = (row[0], row[1], row[2])
QuestionDialog.QuestionDialog(
_("Remove the '%s' database?") % self.data_to_delete[0],
_("Removing this database will permanently destroy "
"the data."),
_("Remove database"),
self.really_delete_db)
self.populate()
def really_delete_db(self):
for (top, dirs, files) in os.walk(self.data_to_delete[1]):
for f in files:
os.unlink(os.path.join(top,f))
os.rmdir(top)
def new_db(self, obj):
while True:
base = "%x" % int(time.time())
new_path = os.path.join(DEFAULT_DIR, base)
if not os.path.isdir(new_path):
break
os.mkdir(new_path)
path_name = os.path.join(new_path, NAME_FILE)
title = DEFAULT_TITLE
f = open(path_name, "w")
f.write(title)
f.close()
node = self.model.append([title, new_path, path_name, _("Never"), 0])
self.dblist.get_selection().select_iter(node)
if __name__ == "__main__":
a = DbManager(None,None)
a.run()

View File

@ -105,7 +105,6 @@ _KNOWN_FORMATS = {
UIDEFAULT = '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<menuitem action="New"/>
<menuitem action="Open"/>
<menu action="OpenRecent">
</menu>
@ -167,8 +166,6 @@ UIDEFAULT = '''<ui>
</menu>
</menubar>
<toolbar name="ToolBar">
<toolitem action="New"/>
<separator/>
<placeholder name="CommonNavigation"/>
<separator/>
<toolitem action="ScratchPad"/>
@ -279,30 +276,30 @@ class ViewManager:
toolbar = self.uimanager.get_widget('/ToolBar')
self.filter_menu = self.uimanager.get_widget('/MenuBar/ViewMenu/Filter/')
openbtn = gtk.MenuToolButton(gtk.STOCK_OPEN)
openbtn = gtk.MenuToolButton('gramps-db')
openbtn.connect('clicked', self.open_activate)
openbtn.set_sensitive(False)
self.uistate.set_open_widget(openbtn)
toolbar.insert(openbtn, 1)
toolbar.insert(openbtn, 0)
self.open_tips = gtk.Tooltips()
openbtn.set_arrow_tooltip(self.open_tips,
_("Open a recently opened database"),
_("Open a recently opened database"))
_("Connect to a recent database"),
_("Connect to a recent database"))
openbtn.set_tooltip(self.open_tips,
_("Open an existing database"),
_("Open an existing database")
_("Manage databases"),
_("Manage databases")
)
openbtn.show()
self.person_nav = Navigation.PersonNavigation(self.state, self.uistate)
self._navigation_type[PageView.NAVIGATION_PERSON] = (self.person_nav,
None)
self.recent_manager = DisplayState.RecentDocsMenu(
self.uistate, self.state, self.read_recent_file)
self.recent_manager.build()
#self.recent_manager = DisplayState.RecentDocsMenu(
# self.uistate, self.state, self.read_recent_file)
#self.recent_manager.build()
self.db_loader = DbLoader(self.state, self.uistate)
@ -333,10 +330,8 @@ class ViewManager:
def _init_lists(self):
self._file_action_list = [
('FileMenu', None, _('_File')),
('New', gtk.STOCK_NEW, _('_New'), "<control>n",
_("Create a new database"), self.new_activate),
('Open', gtk.STOCK_OPEN, _('_Open'), "<control>o",
_("Open an existing database"), self.open_activate),
('Open', 'gramps-db', _('_Manage Databases'), "<control>o",
_("Manage databases"), self.open_activate),
('OpenRecent', None, _('Open _Recent'), None,
_("Open an existing database")),
('Quit', gtk.STOCK_QUIT, _('_Quit'), "<control>q",None,self.quit),
@ -905,8 +900,91 @@ class ViewManager:
self.post_load()
def open_activate(self, obj):
(filename, filetype) = self.db_loader.open_file()
self.post_load_newdb(filename, filetype)
import DbManager
dialog = DbManager.DbManager()
filename = dialog.run()
if filename:
self.read_file(filename, 'x-directory/normal')
try:
os.chdir(os.path.dirname(filename))
except:
pass
self.post_load_newdb(filename, 'x-directory/normal')
def read_file(self, filename, filetype):
"""
This method takes care of changing database, and loading the data.
This method should only return on success.
Returning on failure makes no sense, because we cannot recover,
since database has already beeen changed.
Therefore, any errors should raise exceptions.
On success, return with the disabled signals. The post-load routine
should enable signals, as well as finish up with other UI goodies.
"""
import GrampsDb
if os.path.exists(filename):
if not os.access(filename, os.W_OK):
mode = "r"
QuestionDialog.WarningDialog(_('Read only database'),
_('You do not have write access '
'to the selected file.'))
else:
mode = "w"
elif filetype == 'unknown':
QuestionDialog.WarningDialog(
_('Missing or Invalid database'),
_('%s could not be found.\n'
'It is possible that this file no longer exists '
'or has been moved.') % filename)
return False
else:
mode = 'w'
try:
dbclass = GrampsDb.gramps_db_factory(db_type = filetype)
except GrampsDb.GrampsDbException, msg:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
_("This may be caused by an improper installation of GRAMPS.") +
"\n" + str(msg))
return
self.state.change_database(dbclass(Config.get(Config.TRANSACTIONS)))
self.state.db.disable_signals()
self.uistate.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
self.uistate.progress.show()
try:
self.state.db.load(filename,self.uistate.pulse_progressbar,mode)
self.state.db.set_save_path(filename)
try:
os.chdir(os.path.dirname(filename))
except:
print "could not change directory"
except DBRunRecoveryError, msg:
QuestionDialog.ErrorDialog(
_("Low level database corruption detected"),
_("GRAMPS has detected a problem in the underlying "
"Berkeley database. Please exit the program, and GRAMPS "
"will attempt to run the recovery repair operation "
"the next time you open this database. If this "
"problem persists, create a new database, import "
"from a backup database, and report the problem to "
"gramps-bugs@lists.sourceforge.net."))
except (DBAccessError, DBPageNotFoundError,DBInvalidArgError), msg:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
str(msg[1]))
except Exception:
log.error("Failed to open database.", exc_info=True)
return True
def save_as_activate(self, obj):
if self.state.db.db_is_open:
@ -977,7 +1055,7 @@ class ViewManager:
self.state.db.enable_signals()
self.state.signal_change()
Config.set(Config.RECENT_FILE, filename)
#Config.set(Config.RECENT_FILE, filename)
self.relationship = self.RelClass(self.state.db)
@ -992,8 +1070,8 @@ class ViewManager:
self.file_loaded = True
RecentFiles.recent_files(filename, filetype)
self.recent_manager.build()
#RecentFiles.recent_files(filename, filetype)
#self.recent_manager.build()
# Call common post_load
self.post_load()

View File

@ -15415,4 +15415,152 @@ Very High</property>
</child>
</widget>
<widget class="GtkDialog" id="dbmanager">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="title" translatable="yes">GRAMPS - Database Manager</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="default_width">500</property>
<property name="default_height">250</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox26">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area25">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancel">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-7</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="ok">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-connect</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox138">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow88">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="dblist">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">True</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVButtonBox" id="vbuttonbox2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="new">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-new</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="remove">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-remove</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">6</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -94,6 +94,7 @@ def register_stock_icons ():
]
items = [
('gramps-db',_('Databases'),gtk.gdk.CONTROL_MASK,0,''),
('gramps-address',_('Address'),gtk.gdk.CONTROL_MASK,0,''),
('gramps-attribute',_('Attribute'),gtk.gdk.CONTROL_MASK,0,''),
#('gramps-bookmark',_('Bookmarks'),gtk.gdk.CONTROL_MASK,0,''),