Compare commits

...
118 Commits
Author SHA1 Message Date
SNoiraud f5e53e53bc FR10850 V2: freeze/unfreeze button per gramplet
Fixes #10850

This is the second method to avoid reloading gramplet automaticaly.
2018-10-31 20:36:45 +01:00
prculley 263a082afe Merge in changes from Gramps50 2018-10-29 09:32:35 -05:00
Richard Clay dd9ddab849 In personsidebarfilter, search on each part of name
Instead of requiring that the entire search string matches a single one of the Person's names, the function will require that each word in the search string matches any of the Person's name fields.

Fixes #7950
2018-10-20 21:30:20 +01:00
Malte Renken cfa278886b RelGraphReport: Add an option to omit "irrelevant" family nodes 2018-10-12 20:58:04 +01:00
MJBMZ 1c430a6b91 Replace rounded corners checkbox by dropdown
It now allows rounded corners to be set more explicitly for
different genders (None/Male/Female/Both).
2018-10-12 20:25:51 +01:00
jose1711 b0eb712933 Do not use hyphen for living persons in hourglass graph 2018-10-12 19:36:42 +01:00
Jgon6 51a7ad9483 Include death anniversaries as an option in the birthdays report
Added the optional ability to list the anniversry of peoples deaths in
the birthday and anniversary report

Resolves #3540
2018-10-12 19:19:59 +01:00
Jgon6 d6e9d62fad Add an option to show years in the birthday report
Added an option to the birthday report that allows for the year of birth
(or in the case of a wedding it's year) to be printed in the report.

Resolves #5948
2018-10-12 19:19:59 +01:00
Jgon6 3bac4a1036 Added symbols to the birthdays report showing the type of event
Issue #3540
2018-10-12 19:19:59 +01:00
Jgon6 1995a7068c Birthday report dead indicator now user defineable
Fixed the birthday report so the dead icon is able to be set within the
options window
2018-10-12 19:19:59 +01:00
Jgon6 5dc06d023d Indicate if a person is dead in the birthdays report
Added a text option to have a string that will show after a persons name
in the birthday and anniversary report. This works for both birthdays
and anniversaries.

Issue #3540
2018-10-12 19:19:43 +01:00
SNoiraud d98a1857dc Make relationships optional in narrative web
Fixes #10454
2018-10-12 18:46:39 +01:00
Paul Franklin 7da8811327 Setting the year as an ordinal number in Croatian
With this commit, the "master" version of the Statistics Chart
report will show a year as an ordinal number in Croatian.

So our translators will have until 5.1.0 is released to translate
the two new strings, in all the supported gramps languages.

Issue #10822
2018-10-07 23:45:40 -07:00
prculley 15db2dd603 Disable OSX specific menu items, added in 'Gramps' menu 2018-10-07 16:49:12 +01:00
prculley 97b15322d4 Add config option to use Toolbar Text 2018-10-07 16:49:12 +01:00
prculley 824bf7e40f Geps044 - Replace deprecated Gtk.UIManager, Gtk.Actions etc. 2018-10-07 16:49:12 +01:00
milotype 56fa261ef2 Better typography in graph reports
Replace hyphen with en-dash.
2018-10-07 16:16:19 +01:00
Robin van der Vliet 1efab19f1e Esperanto Translation Update eo.po (#660)
Made a lot of corrections and other stylistic improvements to the Esperanto file.
2018-09-27 11:21:15 +10:00
prculley 51e294f748 Fix up bad translation files after merge 2018-08-09 10:54:12 -05:00
Leonhaeuser cb65fd93ca Reviewed German translation Thanks to bmendl 2018-08-09 10:35:49 -05:00
niememat 5b9600d835 Fix translation in Finnish 2018-08-09 10:35:15 -05:00
John Ralls cf80d17040 File copy doesn't work if the glob can match directories. 2018-08-09 10:35:14 -05:00
John Ralls d4f906f22d Install the docs/gramps directory in the bundle.
Fixes bug #10705.
2018-08-09 10:35:14 -05:00
niememat d189e334d8 Fix and updated translation in Finnish 2018-08-09 10:35:14 -05:00
Ross Gammon a48a94d872 Update the Debian changelog after the 5.0.0 release 2018-08-09 10:35:13 -05:00
John Ralls 8e5dc220dc Release Gramps-5.0.0 on Mac. 2018-08-09 10:35:13 -05:00
Nick Hall dca2f610dc Bump to 5.0.1 2018-08-09 10:34:31 -05:00
Nick Hall 3d1833e307 Release Gramps 5.0.0 2018-08-09 10:33:57 -05:00
Nick Hall aa221cc3c7 Update Changelog and NEWS files 2018-08-09 10:33:19 -05:00
Nick Hall 51b7d1c420 Update translation template for new release 2018-08-09 10:30:58 -05:00
niememat 674d286f87 Fix translation in Finnish 2018-08-09 10:30:58 -05:00
John Ralls 0161c4b917 Correct binary test logic for primary mask.
state & get_primary_mask(another) tested (state & (primary | other)),
which will be true if state matches *either* primary *or* other, but
what is wanted in a not-negated test is state matching all bits of
(primary | other). match_primary_mask does that.

On the other hand there are also cases of "not state & (primary | other)".
no_match_primary_mask handles that, returning true if state matches none
 of the bits in (primary | other).

Fixes #10646.
2018-08-09 10:30:57 -05:00
prculley de31a42fc8 Fix BaseSelector to avoid long delay before display on large trees
Fixes #10634
2018-08-09 10:30:57 -05:00
SNoiraud 9c508de5fd Export options > Gui alignment issue
Fixes #10576
2018-08-09 10:30:57 -05:00
niememat 1b00d95ce4 New fix translation in Finnish 2018-08-09 10:30:57 -05:00
Espen Berg 78870decb8 Revised Norwegian bokmål 2018-08-09 10:30:56 -05:00
Espen Berg 1a5696eb2c Revised Norwegian bokmål 2018-08-09 10:30:24 -05:00
niememat 269d38da2c Fix translation in Finnish 2018-08-09 10:27:26 -05:00
Nick Hall 99f77b0a88 Fix dialog button order on non-Mac systems
Resolves #10585.
2018-08-09 10:27:25 -05:00
De Tran 264fdda4d0 Fix and update Vietnamese translation
Resolves #10681.
2018-08-09 10:27:24 -05:00
Sveinn í Felli 8092b88ad4 Update Icelandic translation 2018-08-09 10:12:17 -05:00
jose1711 3251e2ae88 Fix and update Slovak translation 2018-08-09 10:09:53 -05:00
jose1711 f718c5f8b4 Fix typo in translation 2018-08-09 10:09:53 -05:00
niememat a96a446b47 Fix translation in Finnish 2018-08-09 10:09:53 -05:00
niememat 5658411acf Fix translation in Finnish 2018-08-09 10:09:53 -05:00
niememat a4403d719e Fix translation in Finnish 2018-08-09 10:09:52 -05:00
Luigi Toscano 8597a10c40 Update Italian translation 2018-08-09 10:09:52 -05:00
Nick Hall d0c0045dc1 Update English (British) translation 2018-08-09 10:09:52 -05:00
De Tran 868abdc0d9 Update Vietnamese translation 2018-08-09 10:08:37 -05:00
Kaj Mikkelsen ebf88bf5c5 Update Danish translation 2018-08-09 10:08:35 -05:00
Lajos Nemeséri c3814a4e42 Update Hungarian translation 2018-08-09 10:07:53 -05:00
John Ralls 52fe365919 Switch included moduleset to gitlab.gnome.org.
Fixes bug #10733.
2018-08-09 07:21:18 -07:00
prculley bc39dda9e7 Use msgcat merged po files instead of git merge versions 2018-07-13 07:35:36 -05:00
prculley 257275f169 Merge from gramps50 2018-07-12 11:10:22 -05:00
Espen Berg 9e61809b17 Received revised Norsk Nynorsk from Sigmund Lorentsen 2018-05-01 2018-05-17 21:30:15 +02:00
Espen Berg 9e2b935db1 revised Norwegian bokmål 2018-05-17 21:28:34 +02:00
Nick Hall 9a386574d8 Revert "Clone event w/o references (2nd pass, part B)"
This reverts commit 208feceb03.

Changes requested in the PR not made.  Such a change requires
discussion on the list first.
2018-05-12 23:09:27 +01:00
Nick Hall 90bdb0a840 Revert "Embedded Clone Event w. references (2nd pass, part A)"
This reverts commit ae322dbdc8.

Changes requested in the PR not made.  Such a change requires
discussion on the list first.
2018-05-12 22:59:52 +01:00
Alois Poettker ae322dbdc8 Embedded Clone Event w. references (2nd pass, part A) 2018-04-23 11:00:26 +02:00
Alois Poettker 208feceb03 Clone event w/o references (2nd pass, part B)
Feature request #9604

This functionality in the Event list doubles an event with all the tags, citations, media, attributes and notes, but without the references. Its like an event addition, but with default values.
2018-04-23 11:00:26 +02:00
Paulo Henrique Moraes 32dd3a2e14 [pt_BR]Translation updates and corrections (#582)
- Portuguese (Brazil)
2018-03-15 11:26:59 +11:00
Jgon6 0ae51c9522 Changed behavior of "Look up with Map Services"
Removed the section that looked up by city, and country from the Map
Services lookup for Google and Open Street Map.

Resolves #9486
2018-03-03 17:35:51 +00:00
Nick Hall 59bd9f040d Merge branch 'gramps50' 2018-03-03 17:29:32 +00:00
Paulo Henrique Moraes df00dd1f32 Brazilian portuguese update 2018-02-23 14:58:38 -03:00
niememat ca49b56774 Update finnish translation 2018-02-20 18:22:28 +02:00
Nick Hall 19f8c3561c Merge branch 'gramps50' 2018-02-09 00:13:43 +00:00
Serge Noiraud 79ff9bc216 Geocoding: associate a lat/lon to a place name (#515)
* Geocoding: associate a lat/lon to a place name

Fixes #09642

* Some cleanup

* update README.md

* Remove url from message dialog
2018-01-18 09:11:51 +01:00
prculley b54672d28d Leak (Uncollected Objects); allow user to cancel long screen update 2018-01-08 19:22:27 +00:00
mb06cs 6b42d71158 endoflinereport.py: sort generation during output 2018-01-06 13:32:43 +01:00
Paweł Tomkiel ac593d814d fixing polish places translations 2018-01-04 23:07:42 +00:00
Nick Hall 617e2212c8 new gramps.pot translation template 2018-01-04 22:59:31 +00:00
Nick Hall ad15ef7961 Merge branch 'gramps50' 2018-01-03 21:32:14 +00:00
niememat 406faa5603 Update finnish translation 2017-11-25 10:44:45 +02:00
Serge Noiraud 4e0d562208 Various Feature Requests in Narrative Web (#468)
Issue #06772
2017-11-23 09:40:52 +01:00
Serge Noiraud 43ef686622 Narrative Web Feature requests : (#466)
Sort "Surname" web page by given name and birth date.
Surname list doesn't use default name format

Fixes #05315, #08067
2017-11-23 09:39:12 +01:00
Serge Noiraud d59fe6b2af Display Lat/Lon optionally on places list page (#467)
Fixes #05382
2017-11-23 09:37:47 +01:00
Serge Noiraud d677a1a785 Add extra page to narrativeweb. (#465)
Fixes #02630
2017-11-23 09:36:13 +01:00
Leonhaeuser be776d6a31 updated German date handler: added some missing Latin month names and some old German month names 2017-10-05 21:34:23 +02:00
Nick Hall 1482fedb9c Merge branch 'gramps50' 2017-09-23 17:08:52 +01:00
Sam Manzi 00f8df60ce Revert "Tidy up mocking code (#438)[First commit]"
This reverts commit 8ebb4d35fa.
2017-09-23 07:50:48 +10:00
Jonathan Biegert f31caf1ea4 enable Graphviz node port selection, optionable (p.r. 456)
This enables the headport and tailport attributes for all edges in
the Graphviz file. The default (off) value makes the arrows between
persons and/or family nodes attach their ends to the respective node
at any position. When this option is selected, the position facing
the node on the other side of the arrow is always chosen.
2017-09-17 17:20:23 -07:00
Nick Hall 8ebb4d35fa Tidy up mocking code (#438)[First commit] 2017-09-17 11:03:39 +10:00
Serge Noiraud c5f2717623 Gramps 'Views' are not named in the window header (#448)
Resolves #001675
2017-09-12 10:05:46 +10:00
Serge Noiraud e5d5cfbd3a Allow Home person to be set in Relationship and Pedigree view (#446)
Resolves #0001970
2017-09-01 10:41:24 +10:00
Sebastian Schubert bd5f6e4711 example.gramps: add some non-primary participants to events
The following additional participants were added:
Death of Garner, Anderson:
* Page, Elizabeth (Witness)
* Farmer, Miranda Keziah (Witness)
* Page, David (Informant)

Birth of Thornton, James Arthur:
* Jankowski, Margaret Jane "Maggie" (Witness)
* Garner, Raymond E. (Informant)

Marriage of Garner, Lewis Anderson and Martel, Luella Jacques:
* Garner, Robert W. (Witness)
* Martel, Henry (Witness)
* Page, Robert (Clergy)
* Blanco, L. J. (Clergy)
2017-08-08 12:41:54 +01:00
Leonhaeuser e15deff4ed synced with gramps 50 2017-08-03 20:46:41 +02:00
romjerome 9d906c29a2 update french translation 2017-08-01 12:20:05 +02:00
romjerome 6577d43e4e merge forward (working release steps on gramps42) 2017-08-01 12:03:46 +02:00
Alois Poettker 1a065485e3 Extend Pro-Gen importer II
Adapted to Pro-Gen test fix, expanded functionality and fixed
minor bugs.
2017-07-27 19:05:52 +01:00
schoonc 009783a59a Add pycharm dir to .gitignore 2017-07-27 18:23:55 +01:00
Nick Hall 1b4f70c808 Fix permissions on leak gramplet 2017-07-27 18:18:53 +01:00
niememat dd4a727521 Update finnish translation 2017-07-27 09:48:08 +03:00
Paul Culley ebb7111f25 An improved Leak (Uncollected Objects) Gramplet (#345)
* Improved leak detector (debugging tool)

* Fix DummyDb so it garbage collector can reclaim it after close

* Fix leak gramplet so pop-ups use correct transient parent
2017-07-27 12:15:38 +10:00
Nick Hall 86fd14613e Merge branch 'gramps50' 2017-07-25 21:45:37 +01:00
Alois Poettker 5276461239 Tidy up code 2017-07-18 18:25:29 +01:00
Alois Poettker 40f47bc22d Delete multiple events 2017-07-18 18:20:55 +01:00
Nick Hall 8150403ccb Revert "Simplify import plugin unit tests"
This works with python 3.6 but not with 3.4.

This reverts commit b43d94ab16.
2017-07-18 16:57:55 +01:00
Nick Hall b43d94ab16 Simplify import plugin unit tests 2017-07-18 16:15:01 +01:00
Nick Hall 849290a3b7 Fix Pro-Gen unit test 2017-07-18 00:06:30 +01:00
Leonhaeuser 0b617e9fd6 update German translation
Fix #0010131
2017-07-15 00:23:00 +02:00
Lajos Nemeséri 6eb435142e Update Hungarian translation 2017-07-08 13:34:34 +02:00
Alois Poettker e14ea777d5 Extend Pro-Gen importer functionality 2017-07-02 23:16:10 +01:00
Paul Franklin 46d73a16a0 add verify.py rules: match same birth or death date as marriage date
Issue #2583
2017-07-02 13:37:17 -07:00
Fedik 4d2b918d39 Update Ukrainian translation 2017-07-02 17:23:56 +03:00
romjerome 4acfdcce52 update french translation 2017-06-30 09:20:12 +02:00
arnaullv f3b3eec211 Updated catalan translation to latest template 2017-06-26 22:06:29 +01:00
niememat a840566e02 Update fix finnish translation 2017-06-24 19:33:00 +03:00
Nick Hall f6a2199f68 Merge branch 'gramps50' 2017-06-22 17:47:33 +01:00
Nick Hall dfc9dde32d Merge branch 'gramps50' 2017-06-15 16:44:15 +01:00
Zdeněk Hataš 50f93f54ec czech translation update 2017-06-05 11:49:50 +02:00
Nick Hall 9cb1d96725 Merge branch 'gramps50' 2017-06-03 22:20:03 +01:00
Nick Hall 40013dccc3 Merge branch 'gramps50' 2017-06-02 23:53:56 +01:00
Serge Noiraud 24af1b8420 8200: Person Relatives Tab should use the type from the relationship (#396)
* 8200: Person Relatives Tab should use the type from the relationship

* 8200: Flag variables as there are now two variables.
2017-06-02 20:07:31 +02:00
Serge Noiraud 213d656df4 10049: tabs reorganization in narrative web. (#406) 2017-06-02 13:20:21 +02:00
Nick Hall c09b4e96d2 Remove trailing whitespace 2017-05-23 19:52:19 +01:00
Nick Hall a80875e00c Update Travis for gramps51 2017-05-23 19:51:24 +01:00
Nick Hall bbdedb5097 Update a few missed version numbers 2017-05-23 19:49:23 +01:00
Nick Hall dd0671b111 Bump all version numbers to 5.1 2017-05-23 18:30:29 +01:00
155 changed files with 84304 additions and 59125 deletions

No files matched your search

+3
View File
@@ -23,5 +23,8 @@ test/data
Thumbs.db
ehthumbs.db
# IDE
.idea/
# Glade temp files
*~
+6 -6
View File
@@ -72,7 +72,7 @@ install:
# by the automatic git checkout.
# Download Sean Ross-Ross's Pure Python module containing a framework to
# manipulate and analyze python ast�s and bytecode. This is loaded to
# manipulate and analyze python ast�s and bytecode. This is loaded to
# /home/travis/build/gramps-project/gramps/meta
# FIXME: This should be loaded from the release directory at
# https://pypi.python.org/pypi/meta
@@ -95,11 +95,11 @@ before_script:
# set GRAMPS_RESOURCES for locale, data,image and documentation
- export GRAMPS_RESOURCES=.
# Install addons
- mkdir -p ~/.gramps/gramps50/plugins/
- wget https://github.com/gramps-project/addons/raw/master/gramps50/download/CliMerge.addon.tgz
- tar -C ~/.gramps/gramps50/plugins -xzf CliMerge.addon.tgz
- wget https://github.com/gramps-project/addons/raw/master/gramps50/download/ExportRaw.addon.tgz
- tar -C ~/.gramps/gramps50/plugins -xzf ExportRaw.addon.tgz
- mkdir -p ~/.gramps/gramps51/plugins/
- wget https://github.com/gramps-project/addons/raw/master/gramps51/download/CliMerge.addon.tgz
- tar -C ~/.gramps/gramps51/plugins -xzf CliMerge.addon.tgz
- wget https://github.com/gramps-project/addons/raw/master/gramps51/download/ExportRaw.addon.tgz
- tar -C ~/.gramps/gramps51/plugins -xzf ExportRaw.addon.tgz
script:
# Ignore the virtualenv entirely. Use nosetests3, python3 (3.4.0) and coverage
+1 -3
View File
@@ -1,5 +1,5 @@
include ChangeLog
include AUTHORS
include ChangeLog
include COPYING
include FAQ
include Gramps.py
@@ -10,11 +10,9 @@ include RELEASE_NOTES
include TODO
include CONTRIBUTING
include TestPlan.txt
recursive-include bash *
recursive-include data *
recursive-include debian *
recursive-include docs *
recursive-include example *
recursive-include gramps *
recursive-include help *
recursive-include images *
+8 -1543
View File
File diff suppressed because it is too large. Load diff
+13 -1
View File
@@ -11,7 +11,7 @@ Requirements
The following packages **MUST** be installed in order for Gramps to work:
* **Python** 3.2 or greater - The programming language used by Gramps. https://www.python.org/
* **GTK** 3.10 or greater - A cross-platform widget toolkit for creating graphical user interfaces. http://www.gtk.org/
* **GTK** 3.12 or greater - A cross-platform widget toolkit for creating graphical user interfaces. http://www.gtk.org/
* **pygobject** 3.12 or greater - Python Bindings for GLib/GObject/GIO/GTK+ https://wiki.gnome.org/Projects/PyGObject
The following three packages with GObject Introspection bindings (the gi packages)
@@ -103,6 +103,18 @@ The following packages are optional:
More font support in the reports
* **geocodeglib**
A library use to associate a geographical position (latitude, longitude)
to a place name. This is used if you already have osmgpsmap installed.
If installed, when you add or link a place from the map, you have a red line
at the end of the table for selection.
Debian, Ubuntu, ... : gir1.2-geocodeglib-1.0
Fedora, Redhat, ... : geocode-glib
openSUSE : geocode-glib
ArchLinux : geocode-glib
...
Optional packages required by Third-party Addons
------------------------------------------------
+722 -501
View File
File diff suppressed because it is too large. Load diff
+38 -13
View File
@@ -3,7 +3,7 @@
"http://gramps-project.org/xml/1.7.1/grampsxml.dtd">
<database xmlns="http://gramps-project.org/xml/1.7.1/">
<header>
<created date="2018-03-08" version="5.0.0"/>
<created date="2017-08-08" version="5.1.0"/>
<researcher>
<resname>Alex Roitman,,,</resname>
</researcher>
@@ -951,7 +951,7 @@
<place hlink="_L3WJQCD3US67V2CNZT"/>
<description>Birth of Garner, Anderson</description>
</event>
<event handle="_a5af0eb7dfb557da07e" change="1284030599" id="E0179">
<event handle="_a5af0eb7dfb557da07e" change="1502187535" id="E0179">
<type>Death</type>
<dateval val="1887-04-07"/>
<place hlink="_AKFKQC2N4SM243HCTN"/>
@@ -6262,7 +6262,7 @@
<dateval val="1842-06-28"/>
<description>Death of Moreno, Joseph McDowell</description>
</event>
<event handle="_a5af0ec45b25c630e03" change="1284030608" id="E1179">
<event handle="_a5af0ec45b25c630e03" change="1502187451" id="E1179">
<type>Birth</type>
<dateval val="1911-07-12"/>
<description>Birth of Thornton, James Arthur</description>
@@ -15003,7 +15003,7 @@
<type>Marriage</type>
<description>Marriage of Johnson, Henry and Sparks, Catherine</description>
</event>
<event handle="_a5af0ed5df832ee65c1" change="1328026859" id="E2815">
<event handle="_a5af0ed5df832ee65c1" change="1502187371" id="E2815">
<type>Marriage</type>
<dateval val="1875-04-01"/>
<place hlink="_RF5KQCNJRQY8OGTX2H"/>
@@ -18649,7 +18649,7 @@
<parentin hlink="_F4CKQCJZ24JRE9Z889"/>
<citationref hlink="_c140d2472c91aad494f"/>
</person>
<person handle="_14LKQCYZJEAXTS3XX" change="1185438865" id="I1376">
<person handle="_14LKQCYZJEAXTS3XX" change="1502187492" id="I1376">
<gender>F</gender>
<name type="Birth Name">
<first>Elizabeth</first>
@@ -18657,6 +18657,7 @@
</name>
<eventref hlink="_a5af0ebb003796f79a0" role="Primary"/>
<eventref hlink="_a5af0ebb0143dab99ff" role="Primary"/>
<eventref hlink="_a5af0eb7dfb557da07e" role="Witness"/>
<childof hlink="_5IUJQCRJY47YQ8PU7N"/>
<parentin hlink="_I4LKQCOAGPFH4R90A7"/>
<citationref hlink="_c140d24731407d57b3c"/>
@@ -19904,7 +19905,7 @@
<childof hlink="_IO5KQC6H0Q6Y517LR9"/>
<citationref hlink="_c140d24a1fd2319b703"/>
</person>
<person handle="_35WJQC1B7T7NPV8OLV" change="1284030051" id="I0106">
<person handle="_35WJQC1B7T7NPV8OLV" change="1502187260" id="I0106">
<gender>M</gender>
<name type="Birth Name">
<first>Robert W.</first>
@@ -19913,6 +19914,11 @@
<eventref hlink="_a5af0eb74ac73f86aa7" role="Primary"/>
<eventref hlink="_a5af0eb74ba358391ae" role="Primary"/>
<eventref hlink="_a5af0eb74c852f7c633" role="Primary"/>
<eventref hlink="_a5af0ed5df832ee65c1" role="Witness">
<attribute type="Age" value="23">
<citationref hlink="_c140dafeb317af2fd79"/>
</attribute>
</eventref>
<childof hlink="_X3WJQCSF48F6809142"/>
<parentin hlink="_8OUJQCUVZ0XML7BQLF"/>
<citationref hlink="_c140d24a27e19bb381a"/>
@@ -21991,13 +21997,14 @@
<childof hlink="_GCDKQCHI74ZPMI5GDJ"/>
<citationref hlink="_c140d24f3f8704aa41b"/>
</person>
<person handle="_6G0KQC2UXYC66XDDC2" change="1185438865" id="I0363">
<person handle="_6G0KQC2UXYC66XDDC2" change="1502187537" id="I0363">
<gender>F</gender>
<name type="Birth Name">
<first>Miranda Keziah</first>
<surname>Farmer</surname>
</name>
<eventref hlink="_a5af0ec7a76244d962d" role="Primary"/>
<eventref hlink="_a5af0eb7dfb557da07e" role="Witness"/>
<childof hlink="_8NVJQCGMJTCL7E6ZDV"/>
<citationref hlink="_c140d24f439709d3118"/>
</person>
@@ -22989,7 +22996,7 @@
<parentin hlink="_FBVJQCFBI50TW78O49"/>
<citationref hlink="_c140d2522702664ec52"/>
</person>
<person handle="_8CLKQCT97PJOGREJ7W" change="1185438865" id="I1387">
<person handle="_8CLKQCT97PJOGREJ7W" change="1502187387" id="I1387">
<gender>M</gender>
<name type="Birth Name">
<first>Robert</first>
@@ -22997,6 +23004,11 @@
</name>
<eventref hlink="_a5af0ebb3737a6ad088" role="Primary"/>
<eventref hlink="_a5af0ebb39b441e9607" role="Primary"/>
<eventref hlink="_a5af0ed5df832ee65c1" role="Clergy">
<attribute type="Age" value="23">
<citationref hlink="_c140dafeb317af2fd79"/>
</attribute>
</eventref>
<childof hlink="_5IUJQCRJY47YQ8PU7N"/>
<parentin hlink="_H6LKQCWVIFNRNGHFVH"/>
<citationref hlink="_c140d2522d804491375"/>
@@ -23803,7 +23815,7 @@
<childof hlink="_5DBKQCVAB0XMBEW8R9"/>
<citationref hlink="_c140d25425874b0b827"/>
</person>
<person handle="_9HUJQC6ONNW8SMSKGQ" change="1185438865" id="I0038">
<person handle="_9HUJQC6ONNW8SMSKGQ" change="1502187526" id="I0038">
<gender>M</gender>
<name type="Birth Name">
<first>David</first>
@@ -23812,6 +23824,7 @@
<eventref hlink="_a5af0ec7eb514c52fbf" role="Primary"/>
<eventref hlink="_a5af0ec7ec844213b55" role="Primary"/>
<eventref hlink="_a5af0ec7ed61c743fc8" role="Primary"/>
<eventref hlink="_a5af0eb7dfb557da07e" role="Informant"/>
<childof hlink="_5IUJQCRJY47YQ8PU7N"/>
<parentin hlink="_3HUJQCK4DH582YUTZG"/>
<citationref hlink="_c140d2542c764516f13"/>
@@ -24506,7 +24519,7 @@
<parentin hlink="_8NVJQCGMJTCL7E6ZDV"/>
<citationref hlink="_c140d2560004fad8df6"/>
</person>
<person handle="_ANLKQCQSQNE5LDZMRC" change="1185438865" id="I1402">
<person handle="_ANLKQCQSQNE5LDZMRC" change="1502187434" id="I1402">
<gender>F</gender>
<name type="Birth Name">
<first>Margaret Jane &quot;Maggie&quot;</first>
@@ -24514,6 +24527,7 @@
</name>
<eventref hlink="_a5af0ebb7d47a006ee2" role="Primary"/>
<eventref hlink="_a5af0ebb7e54e14970f" role="Primary"/>
<eventref hlink="_a5af0ec45b25c630e03" role="Witness"/>
<childof hlink="_VDLKQCQQ1ADTJG1D1F"/>
<parentin hlink="_SNLKQCD0VNJ627062Y"/>
<citationref hlink="_c140d25607213be35da"/>
@@ -24882,13 +24896,18 @@
<parentin hlink="_JFYJQCG2KLRQN835JD"/>
<citationref hlink="_c140d256e3403ba129d"/>
</person>
<person handle="_B3BKQCSV0G3NKSKWDX" change="1185438865" id="I0880">
<person handle="_B3BKQCSV0G3NKSKWDX" change="1502187344" id="I0880">
<gender>F</gender>
<name type="Birth Name">
<first>L. J.</first>
<surname>Blanco</surname>
</name>
<eventref hlink="_a5af0ed2cf617169903" role="Primary"/>
<eventref hlink="_a5af0ed5df832ee65c1" role="Clergy">
<attribute type="Age" value="23">
<citationref hlink="_c140dafeb317af2fd79"/>
</attribute>
</eventref>
<childof hlink="_1BVJQCNTFAGS8273LJ"/>
<citationref hlink="_c140d256ec4306a51ca"/>
</person>
@@ -31930,7 +31949,7 @@
<childof hlink="_UDMKQC5D3A2PXPUGNC"/>
<citationref hlink="_c140d266ec93334f40f"/>
</person>
<person handle="_MG5KQC6ZKSVO4A63G2" change="1328026883" id="I0624">
<person handle="_MG5KQC6ZKSVO4A63G2" change="1502187451" id="I0624">
<gender>M</gender>
<name type="Birth Name">
<first>Raymond E.</first>
@@ -31938,6 +31957,7 @@
</name>
<eventref hlink="_a5af0ece8bd1125a1a9" role="Primary"/>
<eventref hlink="_a5af0ece8d15511ddf9" role="Primary"/>
<eventref hlink="_a5af0ec45b25c630e03" role="Informant"/>
<childof hlink="_9OUJQCBOHW9UEK9CNV"/>
<citationref hlink="_c140d266f0d5d178784"/>
</person>
@@ -32336,7 +32356,7 @@
<parentin hlink="_F4CKQCJZ24JRE9Z889"/>
<citationref hlink="_c140d267ccb7aef0cd0"/>
</person>
<person handle="_N4DKQCPEMZ7OO62O7J" change="1185438865" id="I0975">
<person handle="_N4DKQCPEMZ7OO62O7J" change="1502187308" id="I0975">
<gender>M</gender>
<name type="Birth Name">
<first>Henry</first>
@@ -32345,6 +32365,11 @@
<eventref hlink="_a5af0ed483738d4ed1e" role="Primary"/>
<eventref hlink="_a5af0ed484a144d229b" role="Primary"/>
<eventref hlink="_a5af0ed48605fb6b9eb" role="Primary"/>
<eventref hlink="_a5af0ed5df832ee65c1" role="Witness">
<attribute type="Age" value="23">
<citationref hlink="_c140dafeb317af2fd79"/>
</attribute>
</eventref>
<parentin hlink="_7PUJQC4PPS4EDIVMYE"/>
<citationref hlink="_c140d267d2128356d8e"/>
</person>
+5 -1
View File
@@ -155,7 +155,7 @@ register('behavior.translator-needed', True)
register('behavior.use-tips', False)
register('behavior.welcome', 100)
register('behavior.web-search-url', 'http://google.com/#&q=%(text)s')
register('behavior.addons-url', "https://raw.githubusercontent.com/gramps-project/addons/master/gramps50")
register('behavior.addons-url', "https://raw.githubusercontent.com/gramps-project/addons/master/gramps51")
register('database.backend', 'bsddb')
register('database.compress-backup', True)
@@ -196,6 +196,7 @@ register('interface.view-categories',
register('interface.filter', False)
register('interface.fullscreen', False)
register('interface.grampletbar-close', False)
register('interface.grampletbar-freeze', False)
register('interface.ignore-gexiv2', False)
register('interface.ignore-pil', False)
register('interface.ignore-osmgpsmap', False)
@@ -217,6 +218,7 @@ register('interface.sidebar-text', True)
register('interface.size-checked', False)
register('interface.statusbar', 1)
register('interface.toolbar-on', True)
register('interface.toolbar-text', False)
register('interface.view', True)
register('interface.surname-box-height', 150)
register('interface.treemodel-cache-size', 1000)
@@ -228,6 +230,8 @@ register('paths.report-directory', USER_HOME)
register('paths.website-directory', USER_HOME)
register('paths.website-cms-uri', '')
register('paths.website-cal-uri', '')
register('paths.website-extra-page-uri', '')
register('paths.website-extra-page-name', '')
register('paths.quick-backup-directory', USER_HOME)
register('paths.quick-backup-filename',
"%(filename)s_%(year)d-%(month)02d-%(day)02d.%(extension)s")
+1
View File
@@ -139,6 +139,7 @@ git_revision = get_git_revision(ROOT_DIR).replace('\n', '')
if sys.platform == 'win32' and git_revision == "":
git_revision = get_git_revision(os.path.split(ROOT_DIR)[1])
VERSION += git_revision
#VERSION += "-1"
#
# Glade files
+2 -1
View File
@@ -216,8 +216,9 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
"""
Create a new DummyDb instance.
"""
DbReadBase.__init__(self)
Callback.__init__(self)
self.basedb = None
self.__feature = {} # {"feature": VALUE, ...}
self.db_is_open = False
self.readonly = True
self.name_formats = []
+32 -3
View File
@@ -291,17 +291,46 @@ class Gramplet:
"""
The main interface for running the :meth:`main` method.
"""
from gi.repository import GLib
if ((not self.active) and
not self.gui.force_update):
self.dirty = True
if self.dbstate.is_open():
#print " %s is not active" % self.gui.gname
#print(" %s is not active" % self.gui.gname)
self.update_has_data()
else:
self.set_has_data(False)
return
#print " %s is UPDATING" % self.gui.gname
#print(" %s is UPDATING" % self.gui.gname)
uva = self.uistate.viewmanager.active_page
# The dashboard has no sidebar or bottombar
if uva.bottombar:
for gramplets in [uva.bottombar.get_children()]:
for gramplet in gramplets:
for i in range(gramplet.pui.gui.pane.get_n_pages()):
child = gramplet.pui.gui.pane.get_nth_page(i)
label = gramplet.pui.gui.pane.get_tab_label(child)
act_grplet = (i == gramplet.pui.gui.pane.get_current_page())
if (gramplet.title == child.get_title() and
gramplet.title == self.gui.title and
not label.get_freeze().get_active() and
act_grplet):
self._really_update()
for gramplets in [uva.sidebar.get_children()]:
for gramplet in gramplets:
for i in range(gramplet.pui.gui.pane.get_n_pages()):
child = gramplet.pui.gui.pane.get_nth_page(i)
label = gramplet.pui.gui.pane.get_tab_label(child)
act_grplet = (i == gramplet.pui.gui.pane.get_current_page())
if (gramplet.title == child.get_title() and
gramplet.title == self.gui.title and
not label.get_freeze().get_active() and
act_grplet):
self._really_update()
else:
self._really_update()
def _really_update(self):
from gi.repository import GLib
self.dirty = False
LOG.debug("gramplet updater: %s: running" % self.gui.title)
if self._idle_id != 0:
+14
View File
@@ -8,6 +8,7 @@
# Copyright (C) 2007 Brian G. Matherly
# Copyright (C) 2009 Benny Malengier
# Copyright (C) 2009 Gary Burton
# Copyright (C) 2017 Jonathan Biegert <azrdev@qrdn.de>
# Copyright (C) 2017 Mindaugas Baranauskas
# Copyright (C) 2017 Paul Culley
#
@@ -72,6 +73,11 @@ _RANKDIR = [{'name' : _("Vertical (↓)"), 'value' : "TB"},
{'name' : _("Horizontal (→)"), 'value' : "LR"},
{'name' : _("Horizontal (←)"), 'value' : "RL"}]
_NODE_PORTS = {"TB" : ("n", "s"),
"BT" : ("s", "n"),
"LR" : ("w", "e"),
"RL" : ("e", "w")}
_PAGEDIR = [{'name' : _("Bottom, left"), 'value' : "BL"},
{'name' : _("Bottom, right"), 'value' : "BR"},
{'name' : _("Top, left"), 'value' : "TL"},
@@ -183,6 +189,10 @@ class GVOptions:
spline.set_help(_("How the lines between objects will be drawn."))
menu.add_option(category, "spline", spline)
node_ports = BooleanOption(_("Alternate line attachment"), False)
node_ports.set_help(_("Whether lines attach to nodes differently"))
menu.add_option(category, "node_ports", node_ports)
# the page direction option only makes sense when the
# number of horizontal and/or vertical pages is > 1,
# so we need to remember these 3 controls for later
@@ -409,6 +419,7 @@ class GVDocBase(BaseDoc, GVDoc):
self.vpages = get_option('v_pages').get_value()
self.usesubgraphs = get_option('usesubgraphs').get_value()
self.spline = get_option('spline').get_value()
self.node_ports = get_option('node_ports').get_value()
paper_size = paper_style.get_size()
@@ -456,6 +467,9 @@ class GVDocBase(BaseDoc, GVDoc):
' splines="%s";\n' % self.spline +
'\n' +
' edge [len=0.5 style=solid fontsize=%d];\n' % self.fontsize)
if self.node_ports:
self.write(' edge [headport=%s tailport=%s];\n'
% _NODE_PORTS[self.rankdir])
if self.fontfamily:
self.write(' node [style=filled fontname="%s" fontsize=%d];\n'
+2 -2
View File
@@ -459,12 +459,12 @@ def run():
if argpars.need_gui():
LOG.debug("A GUI is needed, set it up")
try:
from .gui.grampsgui import startgtkloop
from .gui.grampsgui import startgramps
# no DISPLAY is a RuntimeError in an older pygtk (e.g. F14's 2.17)
except RuntimeError as msg:
error += [(_("Configuration error:"), str(msg))]
return error
startgtkloop(error, argpars)
startgramps(error, argpars)
else:
# CLI use of Gramps
argpars.print_help()
-45
View File
@@ -1,45 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2015 Nick Hall
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
"""
A replacement ActionGroup that correctly loads named icons from an icon theme.
"""
from gi.repository import Gtk
class ActionGroup(Gtk.ActionGroup):
def add_actions(self, action_list, **kwargs):
Gtk.ActionGroup.add_actions(self, action_list, **kwargs)
self.fix_icon_name(action_list)
def add_toggle_actions(self, action_list, **kwargs):
Gtk.ActionGroup.add_toggle_actions(self, action_list, **kwargs)
self.fix_icon_name(action_list)
def add_radio_actions(self, action_list, **kwargs):
Gtk.ActionGroup.add_radio_actions(self, action_list, **kwargs)
self.fix_icon_name(action_list)
def fix_icon_name(self, action_list):
for action_tuple in action_list:
if action_tuple[1]:
action = self.get_action(action_tuple[0])
action.set_icon_name(action_tuple[1])
+13
View File
@@ -984,6 +984,12 @@ class GrampsPreferences(ConfigureDialog):
"""
self.uistate.emit('grampletbar-close-changed')
def cb_grampletbar_freeze(self, obj):
"""
Gramplet bar freeze/unfreeze button preference callback
"""
self.uistate.emit('grampletbar-freeze-changed')
def add_formats_panel(self, configdialog):
row = 0
grid = Gtk.Grid()
@@ -1185,6 +1191,13 @@ class GrampsPreferences(ConfigureDialog):
row, 'interface.grampletbar-close', stop=3,
extra_callback=self.cb_grampletbar_close)
row += 1
# Gramplet bar freeze button:
self.add_checkbox(grid,
_("Enable freeze/unfreeze for the active gramplet"),
row, 'interface.grampletbar-freeze', stop=3,
extra_callback=self.cb_grampletbar_freeze)
row += 1
return _('Display'), grid
def auto_title_changed(self, obj):
+49 -29
View File
@@ -28,6 +28,7 @@
#-------------------------------------------------------------------------
import os
from io import StringIO
import html
#-------------------------------------------------------------------------
#
@@ -65,6 +66,7 @@ from .glade import Glade
from gramps.gen.utils.db import navigation_label
from .widgets.progressdialog import ProgressMonitor, GtkProgressDialog
from .dialog import ErrorDialog
from .uimanager import ActionGroup
DISABLED = -1
@@ -246,14 +248,34 @@ class History(Callback):
#
#-------------------------------------------------------------------------
_RCT_TOP = '<ui><menubar name="MenuBar"><menu action="FileMenu"><menu action="OpenRecent">'
_RCT_BTM = '</menu></menu></menubar></ui>'
_RCT_TOP = '<placeholder id="OpenRecentMenu">'
_RCT_MENU = '''
<item>
<attribute name="action">win.%s</attribute>
<attribute name="label" translatable="no">%s</attribute>
</item>'''
_RCT_BTM = '\n </placeholder>\n'
_RCT_BAR_TOP = ('<object class="GtkMenu" id="OpenBtnMenu">\n'
'<property name="visible">True</property>\n'
'<property name="can_focus">False</property>')
_RCT_BAR = '''
<child>
<object class="GtkMenuItem">
<property name="action-name">win.%s</property>
<property name="label" translatable="yes">%s</property>
<property name="use_underline">False</property>
<property name="visible">True</property>
</object>
</child>'''
_RCT_BAR_BTM = '\n</object>\n'
from gramps.gen.recentfiles import RecentFiles
class RecentDocsMenu:
def __init__(self, uistate, state, fileopen):
self.action_group = Gtk.ActionGroup(name='RecentFiles')
self.ui_xml = []
self.action_group = ActionGroup('RecentFiles')
self.active = DISABLED
self.uistate = uistate
self.uimanager = uistate.uimanager
@@ -268,55 +290,52 @@ class RecentDocsMenu:
ErrorDialog(_('Cannot load database'), str(err),
parent=self.uistate.window)
def build(self):
buf = StringIO()
buf.write(_RCT_TOP)
def build(self, update_menu=True):
gramps_rf = RecentFiles()
count = 0
if self.active != DISABLED:
self.uimanager.remove_ui(self.active)
self.uimanager.remove_ui(self.ui_xml)
self.uimanager.remove_action_group(self.action_group)
self.action_group = Gtk.ActionGroup(name='RecentFiles')
self.active = DISABLED
actions = []
actionlist = []
menu = _RCT_TOP
bar = _RCT_BAR_TOP
rfiles = gramps_rf.gramps_recent_files
rfiles.sort(key=lambda x: x.get_time(), reverse=True)
new_menu = Gtk.Menu()
#new_menu = Gtk.Menu()
#new_menu.set_tooltip_text(_("Connect to a recent database"))
for item in rfiles:
try:
title = item.get_name()
title = html.escape(item.get_name())
filename = os.path.basename(item.get_path())
action_id = "RecentMenu%d" % count
buf.write('<menuitem action="%s"/>' % action_id)
actions.append((action_id, None, title, None, None,
make_callback(item, self.load)))
mitem = Gtk.MenuItem(label=title, use_underline=False)
mitem.connect('activate', make_callback(item, self.load))
mitem.show()
new_menu.append(mitem)
# add the menuitem for this file
menu += _RCT_MENU % (action_id, title)
# add the action for this file
actionlist.append((action_id, make_callback(item, self.load)))
# add the toolbar menuitem
bar += _RCT_BAR % (action_id, title)
except RuntimeError:
# ignore no longer existing files
_LOG.info("Ignoring the RecentItem %s (%s)" % (title, filename))
count += 1
buf.write(_RCT_BTM)
self.action_group.add_actions(actions)
self.uimanager.insert_action_group(self.action_group, 1)
self.active = self.uimanager.add_ui_from_string(buf.getvalue())
self.uimanager.ensure_update()
buf.close()
if len(rfiles) > 0:
new_menu.show()
self.uistate.set_open_recent_menu(new_menu)
menu += _RCT_BTM
bar += _RCT_BAR_BTM
self.ui_xml = [menu, bar]
self.action_group.add_actions(actionlist)
self.uimanager.insert_action_group(self.action_group)
self.active = self.uimanager.add_ui_from_string(self.ui_xml)
if update_menu:
self.uimanager.update_menu()
def make_callback(val, func):
return lambda x: func(val)
return lambda x, y: func(val)
from .logger import RotateHandler
@@ -379,6 +398,7 @@ class DisplayState(Callback):
'nameformat-changed' : None,
'placeformat-changed' : None,
'grampletbar-close-changed' : None,
'grampletbar-freeze-changed' : None,
'update-available' : (list, ),
'autobackup' : None,
}
+3 -2
View File
@@ -180,7 +180,6 @@ class EditNote(EditPrimary):
self.set_window(win, None, self.get_menu_title())
self.setup_configs('interface.note', 700, 500)
vboxnote = self.top.get_object('vbox131')
notebook = self.top.get_object('note_notebook')
#recreate start page as GrampsTab
@@ -271,7 +270,9 @@ class EditNote(EditPrimary):
# create a formatting toolbar
if not self.dbstate.db.readonly:
vbox = self.top.get_object('container')
vbox.pack_start(self.texteditor.get_toolbar(), False, False, 0)
toolbar, self.action_group = self.texteditor.create_toolbar(
self.uistate.uimanager, self.window)
vbox.pack_start(toolbar, False, False, 0)
self.texteditor.set_transient_parent(self.window)
# setup initial values for textview and textbuffer
+28 -24
View File
@@ -676,33 +676,33 @@ class EditPerson(EditPrimary):
EditMediaRef(self.dbstate, self.uistate, self.track,
media_obj, media_ref, self.load_photo)
def _top_contextmenu(self):
def _top_contextmenu(self, prefix):
"""
Override from base class, the menuitems and actiongroups for the top
of context menu.
"""
self.all_action = Gtk.ActionGroup(name="/PersonAll")
self.home_action = Gtk.ActionGroup(name="/PersonHome")
self.track_ref_for_deletion("all_action")
self.track_ref_for_deletion("home_action")
if self.added:
# Don't add items if not a real person yet
return '', []
self.all_action.add_actions([
('ActivePerson', None, _("Make Active Person"),
None, None, self._make_active),
])
self.home_action.add_actions([
('HomePerson', 'go-home', _("Make Home Person"),
None, None, self._make_home_person),
])
_actions = [('ActivePerson', self._make_active),
('HomePerson', self._make_home_person)]
self.all_action.set_visible(not self.added)
self.home_action.set_visible(not self.added)
ui_top_cm = (
'''
<item>
<attribute name="action">{prefix}.ActivePerson</attribute>
<attribute name="label" translatable="yes">Make Active Person'''
'''</attribute>
</item>
<item>
<attribute name="action">{prefix}.HomePerson</attribute>
<attribute name="label" translatable="yes">Make Home Person'''
'''</attribute>
</item>
'''.format(prefix=prefix))
ui_top_cm = '''
<menuitem action="ActivePerson"/>
<menuitem action="HomePerson"/>'''
return ui_top_cm, [self.all_action, self.home_action]
return ui_top_cm, _actions
def _top_drag_data_get(self, widget, context, sel_data, info, time):
if info == DdTargets.PERSON_LINK.app_id:
@@ -713,17 +713,21 @@ class EditPerson(EditPrimary):
"""
Override base class, make inactive home action if not needed.
"""
if self.added:
return
home_action = self.uistate.uimanager.get_action(self.action_group,
'HomePerson')
if (self.dbstate.db.get_default_person() and
self.obj.get_handle() ==
self.dbstate.db.get_default_person().get_handle()):
self.home_action.set_sensitive(False)
home_action.set_enabled(False)
else:
self.home_action.set_sensitive(True)
home_action.set_enabled(True)
def _make_active(self, obj):
def _make_active(self, obj, value):
self.uistate.set_active(self.obj.get_handle(), 'Person')
def _make_home_person(self, obj):
def _make_home_person(self, obj, value):
handle = self.obj.get_handle()
if handle:
self.dbstate.db.set_default_person_handle(handle)
+45 -25
View File
@@ -32,6 +32,7 @@ import abc
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
from gi.repository.Gio import SimpleActionGroup
#-------------------------------------------------------------------------
#
@@ -49,6 +50,8 @@ from ..display import display_help
from ..dialog import SaveDialog
from gramps.gen.lib import PrimaryObject
from ..dbguielement import DbGUIElement
from ..uimanager import ActionGroup
class EditPrimary(ManagedWindow, DbGUIElement, metaclass=abc.ABCMeta):
@@ -75,6 +78,7 @@ class EditPrimary(ManagedWindow, DbGUIElement, metaclass=abc.ABCMeta):
self.get_from_gramps_id = get_from_gramps_id
self.contexteventbox = None
self.__tabs = []
self.action_group = None
ManagedWindow.__init__(self, uistate, track, obj)
DbGUIElement.__init__(self, self.db)
@@ -184,6 +188,8 @@ class EditPrimary(ManagedWindow, DbGUIElement, metaclass=abc.ABCMeta):
self.dbstate.disconnect(self.dbstate_connect_key)
self._cleanup_connects()
self._cleanup_on_exit()
if self.action_group:
self.uistate.uimanager.remove_action_group(self.action_group)
self.get_from_handle = None
self.get_from_gramps_id = None
ManagedWindow.close(self)
@@ -283,48 +289,62 @@ class EditPrimary(ManagedWindow, DbGUIElement, metaclass=abc.ABCMeta):
return False
#build the possible popup menu
self._build_popup_ui()
menu_model = self._build_popup_ui()
if not menu_model:
return False
#set or unset sensitivity in popup
self._post_build_popup_ui()
menu = self.popupmanager.get_widget('/Popup')
if menu:
menu.popup(None, None, None, None, event.button, event.time)
return True
menu = Gtk.Menu.new_from_model(menu_model)
menu.attach_to_widget(obj, None)
menu.show_all()
if Gtk.MINOR_VERSION < 22:
# ToDo The following is reported to work poorly with Wayland
menu.popup(None, None, None, None,
event.button, event.time)
else:
menu.popup_at_pointer(event)
return True
return False
def _build_popup_ui(self):
"""
Create actions and ui of context menu
If you don't need a popup, override this and return None
"""
from ..plug.quick import create_quickreport_menu
self.popupmanager = Gtk.UIManager()
#add custom actions
(ui_top, action_groups) = self._top_contextmenu()
for action in action_groups :
self.popupmanager.insert_action_group(action, -1)
prefix = str(id(self))
#get custom ui and actions
(ui_top, actions) = self._top_contextmenu(prefix)
#see which quick reports are available now:
ui_qr = ''
if self.QR_CATEGORY > -1 :
(ui_qr, reportactions) = create_quickreport_menu(self.QR_CATEGORY,
self.dbstate, self.uistate,
self.obj, track=self.track)
self.report_action = Gtk.ActionGroup(name="/PersonReport")
self.report_action.add_actions(reportactions)
self.report_action.set_visible(True)
self.popupmanager.insert_action_group(self.report_action, -1)
(ui_qr, reportactions) = create_quickreport_menu(
self.QR_CATEGORY, self.dbstate, self.uistate,
self.obj, prefix, track=self.track)
actions.extend(reportactions)
popupui = '''
<ui>
<popup name="Popup">''' + ui_top + '''
<separator/>''' + ui_qr + '''
</popup>
</ui>'''
popupui = '''<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="Popup">''' + ui_top + '''
<section>
''' + ui_qr + '''
</section>
</menu>
</interface>'''
self.popupmanager.add_ui_from_string(popupui)
builder = Gtk.Builder.new_from_string(popupui, -1)
def _top_contextmenu(self):
self.action_group = ActionGroup('EditPopup' + prefix, actions,
prefix)
act_grp = SimpleActionGroup()
self.window.insert_action_group(prefix, act_grp)
self.window.set_application(self.uistate.uimanager.app)
self.uistate.uimanager.insert_action_group(self.action_group, act_grp)
return builder.get_object('Popup')
def _top_contextmenu(self, prefix):
"""
Derived class can create a ui with menuitems and corresponding list of
actiongroups
@@ -186,8 +186,10 @@ class PersonSidebarFilter(SidebarFilter):
# if the name is not empty, choose either the regular expression
# version or the normal text match
if name:
rule = RegExpName([name], use_regex=regex)
generic_filter.add_rule(rule)
name_parts = name.split(sep=" ")
for name_part in name_parts:
rule = RegExpName([name_part], use_regex=regex)
generic_filter.add_rule(rule)
# if the id is not empty, choose either the regular expression
# version or the normal text match
+452 -70
View File
@@ -3,6 +3,7 @@
#
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2009 Benny Malengier
# Copyright (C) 2018 Paul Culley
#
# 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
@@ -50,7 +51,369 @@ _ = glocale.translation.gettext
MIN_PYGOBJECT_VERSION = (3, 12, 0)
PYGOBJ_ERR = False
MIN_GTK_VERSION = (3, 10)
MIN_GTK_VERSION = (3, 12)
UIDEFAULT = (
'''<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="menubar"><section id="menubar-update">
<submenu id='m1'>
<attribute name="label" translatable="yes">_Family Trees</attribute>
<section id="ftree">
<item>
<attribute name="action">win.Open</attribute>
<attribute name="label" translatable="yes">'''
'''_Manage Family Trees</attribute>
</item>
<submenu>
<attribute name="action">win.OpenRecent</attribute>
<attribute name="label" translatable="yes">Open _Recent</attribute>
<placeholder id="OpenRecentMenu">
</placeholder>
</submenu>
<item groups='RO'>
<attribute name="action">win.Close</attribute>
<attribute name="label" translatable="yes">_Close</attribute>
</item>
</section>
<section groups='RO RW'>
<item groups='RW'>
<attribute name="action">win.Import</attribute>
<attribute name="label" translatable="yes">_Import...</attribute>
</item>
<item>
<attribute name="action">win.Export</attribute>
<attribute name="label" translatable="yes">_Export...</attribute>
</item>
<placeholder id="LocalExport">
</placeholder>
<item>
<attribute name="action">win.Backup</attribute>
<attribute name="label" translatable="yes">Make Backup...</attribute>
</item>
</section>
<section>
<item groups='RO'>
<attribute name="action">win.Abandon</attribute>
<attribute name="label" translatable="yes">'''
'''_Abandon Changes and Quit</attribute>
</item>
<placeholder groups='OSX' id='osxquit'>
<item>
<attribute name="action">app.quit</attribute>
<attribute name="label" translatable="yes">_Quit</attribute>
</item>
</placeholder>
</section>
</submenu>
<submenu id='m2' groups='RW'>
<attribute name="label" translatable="yes">_Add</attribute>
<section>
<item>
<attribute name="action">win.PersonAdd</attribute>
<attribute name="label" translatable="yes">Person</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.FamilyAdd</attribute>
<attribute name="label" translatable="yes">Family</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.EventAdd</attribute>
<attribute name="label" translatable="yes">Event</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.PlaceAdd</attribute>
<attribute name="label" translatable="yes">Place</attribute>
</item>
<item>
<attribute name="action">win.SourceAdd</attribute>
<attribute name="label" translatable="yes">Source</attribute>
</item>
<item>
<attribute name="action">win.CitationAdd</attribute>
<attribute name="label" translatable="yes">Citation</attribute>
</item>
<item>
<attribute name="action">win.RepositoryAdd</attribute>
<attribute name="label" translatable="yes">Repository</attribute>
</item>
<item>
<attribute name="action">win.MediaAdd</attribute>
<attribute name="label" translatable="yes">Media</attribute>
</item>
<item>
<attribute name="action">win.NoteAdd</attribute>
<attribute name="label" translatable="yes">Note</attribute>
</item>
</section>
</submenu>
<submenu id='m3'>
<attribute name="label" translatable="yes">_Edit</attribute>
<section groups='RW'>
<placeholder id="undo">
</placeholder>
<placeholder id="redo">
</placeholder>
<item>
<attribute name="action">win.UndoHistory</attribute>
<attribute name="label" translatable="yes">Undo History</attribute>
</item>
</section>
<section id='CommonEdit' groups='RW'>
</section>
<section id='TagMenu' groups='RW'>
</section>
<section groups='RW'>
<item>
<attribute name="action">win.Clipboard</attribute>
<attribute name="label" translatable="yes">Clip_board</attribute>
</item>
</section>
<section>
<placeholder groups='OSX' id='osxpref'>
<item>
<attribute name="action">app.preferences</attribute>
<attribute name="label" translatable="yes">'''
'''_Preferences...</attribute>
</item>
</placeholder>
<placeholder id='otheredit'>
</placeholder>
</section>
</submenu>
<submenu id='m4'>
<attribute name="label" translatable="yes">_View</attribute>
<section>
<item>
<attribute name="action">win.ConfigView</attribute>
<attribute name="label" translatable="yes">_Configure...</attribute>
</item>
<item>
<attribute name="action">win.Navigator</attribute>
<attribute name="label" translatable="yes">_Navigator</attribute>
</item>
<item>
<attribute name="action">win.Toolbar</attribute>
<attribute name="label" translatable="yes">_Toolbar</attribute>
</item>
<placeholder id='Bars'>
</placeholder>
<item>
<attribute name="action">win.Fullscreen</attribute>
<attribute name="label" translatable="yes">F_ull Screen</attribute>
</item>
</section>
<section id="ViewsInCatagory">
</section>
</submenu>
<submenu id="m5" groups='RO'>
<attribute name="label" translatable="yes">_Go</attribute>
<placeholder id="CommonGo">
</placeholder>
<section id="CommonHistory">
</section>
</submenu>
<submenu id='m6' groups='RW'>
<attribute name="label" translatable="yes">_Bookmarks</attribute>
<section id="AddEditBook">
</section>
<section id="GoToBook">
</section>
</submenu>
<submenu id='m7' groups='RO'>
<attribute name="label" translatable="yes">_Reports</attribute>
<section>
<item>
<attribute name="action">win.Books</attribute>
<attribute name="label" translatable="yes">Books...</attribute>
</item>
</section>
<section id="P_ReportsMenu">
</section>
</submenu>
<submenu id='m8' groups='RW'>
<attribute name="label" translatable="yes">_Tools</attribute>
<section id="P_ToolsMenu">
</section>
</submenu>
<submenu id='m9' groups='RO'>
<attribute name="label" translatable="yes">_Windows</attribute>
<section id="WinMenu">
</section>
</submenu>
<submenu id='m10'>
<attribute name="label" translatable="yes">_Help</attribute>
<section>
<item>
<attribute name="action">win.UserManual</attribute>
<attribute name="label" translatable="yes">_User Manual</attribute>
</item>
<item>
<attribute name="action">win.FAQ</attribute>
<attribute name="label" translatable="yes">_FAQ</attribute>
</item>
<item>
<attribute name="action">win.KeyBindings</attribute>
<attribute name="label" translatable="yes">_Key Bindings</attribute>
</item>
<item>
<attribute name="action">win.TipOfDay</attribute>
<attribute name="label" translatable="yes">Tip of the Day</attribute>
</item>
<item>
<attribute name="action">win.PluginStatus</attribute>
<attribute name="label" translatable="yes">'''
'''_Plugin Manager</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePage</attribute>
<attribute name="label" translatable="yes">'''
'''Gramps _Home Page</attribute>
</item>
<item>
<attribute name="action">win.MailingLists</attribute>
<attribute name="label" translatable="yes">'''
'''Gramps _Mailing Lists</attribute>
</item>
<item>
<attribute name="action">win.ReportBug</attribute>
<attribute name="label" translatable="yes">_Report a Bug</attribute>
</item>
<item>
<attribute name="action">win.ExtraPlugins</attribute>
<attribute name="label" translatable="yes">'''
'''_Extra Reports/Tools</attribute>
</item>
</section>
<section groups='OSX'>
<item>
<attribute name="action">app.about</attribute>
<attribute name="label" translatable="yes">_About</attribute>
</item>
</section>
</submenu>
</section></menu>
<object class="GtkMenu" id="OpenBtnMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<object class="GtkToolbar" id="ToolBar">
<property name="hexpand">1</property>
<property name="toolbar-style">GTK_TOOLBAR_ICONS</property>
<style>
<class name="primary-toolbar"/>
</style>
<child>
<object class="GtkToolButton">
<property name="icon-name">gramps</property>
<property name="action-name">win.Open</property>
<property name="tooltip_text" translatable="yes">'''
'''Manage databases</property>
<property name="label" translatable="yes">_Family Trees</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToolItem">
<child>
<object class="GtkMenuButton">
<property name="tooltip_text" translatable="yes">'''
'''Connect to a recent database</property>
<property name="popup">OpenBtnMenu</property>
<property name="relief">GTK_RELIEF_NONE</property>
</object>
</child>
</object>
</child>
<placeholder id='CommonNavigation'>
</placeholder>
<placeholder id='BarCommonEdit'>
</placeholder>
<placeholder id='TagTool'>
</placeholder>
<child groups='RW'>
<object class="GtkToolButton" id="Clipboard">
<property name="icon-name">edit-paste</property>
<property name="action-name">win.Clipboard</property>
<property name="tooltip_text" translatable="yes">'''
'''Open the Clipboard dialog</property>
<property name="label" translatable="yes">Clip_board</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem"/>
</child>
<child>
<object class="GtkToolButton" id="ConfigView">
<property name="icon-name">gramps-config</property>
<property name="action-name">win.ConfigView</property>
<property name="tooltip_text" translatable="yes">'''
'''Configure the active view</property>
<property name="label" translatable="yes">_Configure...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<placeholder id='ViewsInCategoryBar'>
</placeholder>
<child>
<object class="GtkSeparatorToolItem" id="sep"/>
</child>
<placeholder id="MoreButtons">
</placeholder>
<child groups='RO'>
<object class="GtkToolButton" id="Reports">
<property name="icon-name">gramps-reports</property>
<property name="action-name">win.Reports</property>
<property name="tooltip_text" translatable="yes">'''
'''Open the reports dialog</property>
<property name="label" translatable="yes">_Reports</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton" id="Tools">
<property name="icon-name">gramps-tools</property>
<property name="action-name">win.Tools</property>
<property name="tooltip_text" translatable="yes">'''
'''Open the tools dialog</property>
<property name="label" translatable="yes">_Tools</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<placeholder id='AfterTools'>
</placeholder>
</object>
<menu id="Popup">
</menu>
</interface>
''')
try:
#import gnome introspection, part of pygobject
@@ -235,9 +598,8 @@ class Gramps:
process. It may spawn several windows and control several databases.
"""
def __init__(self, argparser):
def __init__(self, argparser, app):
from gramps.gen.dbstate import DbState
from . import viewmanager
from .viewmanager import ViewManager
from gramps.cli.arghandler import ArgHandler
from .tipofday import TipOfDay
@@ -248,7 +610,7 @@ class Gramps:
theme.append_search_path(IMAGE_DIR)
dbstate = DbState()
self._vm = ViewManager(dbstate,
self._vm = ViewManager(app, dbstate,
config.get("interface.view-categories"))
if (lin()
@@ -256,7 +618,7 @@ class Gramps:
and not gettext.find(GTK_GETTEXT_DOMAIN)):
_display_gtk_gettext_message(parent=self._vm.window)
#_display_welcome_message(parent=self._vm.window)
_display_welcome_message(parent=self._vm.window)
_display_translator_message(parent=self._vm.window)
@@ -303,68 +665,18 @@ class Gramps:
#
#-------------------------------------------------------------------------
def __startgramps(errors, argparser):
def startgramps(errors, argparser):
"""
Main startup function started via GObject.timeout_add
First action inside the gtk loop
"""
try:
from .dialog import ErrorDialog
#handle first existing errors in GUI fashion
if errors:
for error in errors:
ErrorDialog(error[0], error[1]) # TODO no-parent
Gtk.main_quit()
sys.exit(1)
if argparser.errors:
for error in argparser.errors:
ErrorDialog(error[0], error[1]) # TODO no-parent
Gtk.main_quit()
sys.exit(1)
# add gui logger
from .logger import RotateHandler, GtkHandler
form = logging.Formatter(
fmt="%(relativeCreated)d: %(levelname)s: "
"%(filename)s: line %(lineno)d: %(message)s")
# Create the log handlers
rot_h = RotateHandler(capacity=20)
rot_h.setFormatter(form)
# Only error and critical log records should
# trigger the GUI handler.
gtkh = GtkHandler(rotate_handler=rot_h)
gtkh.setFormatter(form)
gtkh.setLevel(logging.ERROR)
logger = logging.getLogger()
logger.addHandler(rot_h)
logger.addHandler(gtkh)
except:
#make sure there is a clean exit if there is an error in above steps
quit_now = True
exit_code = 1
LOG.error(_("\nGramps failed to start. "
"Please report a bug about this.\n"
"This could be because of an error "
"in a (third party) View on startup.\n"
"To use another view, don't load a Family Tree, "
"change view, and then load your Family Tree.\n"
"You can also change manually "
"the startup view in the gramps.ini file \n"
"by changing the last-view parameter.\n"
), exc_info=True)
# start Gramps, errors stop the gtk loop
app = GrampsApplication(errors, argparser)
try:
quit_now = False
exit_code = 0
if has_display():
Gramps(argparser)
else:
if app.run():
print(_("Gramps terminated because of no DISPLAY"))
quit_now = True
exit_code = 1
except SystemExit as err:
quit_now = True
if err.code:
@@ -395,18 +707,88 @@ def __startgramps(errors, argparser):
), exc_info=True)
if quit_now:
#stop gtk loop and quit
Gtk.main_quit()
app.quit()
sys.exit(exit_code)
#function finished, return False to stop the timeout_add function calls
return False
def startgtkloop(errors, argparser):
"""
We start the gtk loop and run the function to start up Gramps
"""
GLib.timeout_add(100, __startgramps, errors, argparser, priority=100)
if os.path.exists(os.path.join(DATA_DIR, "gramps.accel")):
Gtk.AccelMap.load(os.path.join(DATA_DIR, "gramps.accel"))
Gtk.main()
# we do the following import here to avoid the Gtk require version warning
from .uimanager import UIManager
from gramps.gen.constfunc import is_quartz
class GrampsApplication(Gtk.Application):
def __init__(self, errors, argparser):
super().__init__(application_id="org.gramps-project.Gramps")
self.window = None
self.errors = errors
self.argparser = argparser
def do_startup(self):
Gtk.Application.do_startup(self)
self.uimanager = UIManager(self, UIDEFAULT)
if not is_quartz():
self.uimanager.show_groups = ['OSX']
self.uimanager.update_menu(init=True)
if os.path.exists(os.path.join(DATA_DIR, "gramps.accel")):
self.uimanager.load_accels(os.path.join(DATA_DIR, "gramps.accel"))
try:
from .dialog import ErrorDialog
#handle first existing errors in GUI fashion
if self.errors:
for error in self.errors:
ErrorDialog(error[0], error[1]) # TODO no-parent
Gtk.main_quit()
sys.exit(1)
if self.argparser.errors:
for error in self.argparser.errors:
ErrorDialog(error[0], error[1]) # TODO no-parent
Gtk.main_quit()
sys.exit(1)
# add gui logger
from .logger import RotateHandler, GtkHandler
form = logging.Formatter(
fmt="%(relativeCreated)d: %(levelname)s: "
"%(filename)s: line %(lineno)d: %(message)s")
# Create the log handlers
rot_h = RotateHandler(capacity=20)
rot_h.setFormatter(form)
# Only error and critical log records should
# trigger the GUI handler.
gtkh = GtkHandler(rotate_handler=rot_h)
gtkh.setFormatter(form)
gtkh.setLevel(logging.ERROR)
logger = logging.getLogger()
logger.addHandler(rot_h)
logger.addHandler(gtkh)
except:
#make sure there is a clean exit if error in above steps
exit_code = 1
LOG.error(_("\nGramps failed to start. "
"Please report a bug about this.\n"
"This could be because of an error "
"in a (third party) View on startup.\n"
"To use another view, don't load a Family Tree, "
"change view, and then load your Family Tree.\n"
"You can also change manually "
"the startup view in the gramps.ini file \n"
"by changing the last-view parameter.\n"
), exc_info=True)
#stop gtk loop and quit
self.quit()
sys.exit(exit_code)
def do_activate(self):
# We only allow a single window and raise any existing ones
if not self.window:
# Windows are associated with the application
# when the last one is closed the application shuts down
Gramps(self.argparser, self)
else:
print('Gramps is already running.')
self.window.present()
+25 -23
View File
@@ -31,7 +31,7 @@ the create/deletion of dialog windows.
#-------------------------------------------------------------------------
import os
from io import StringIO
import html
#-------------------------------------------------------------------------
#
# GNOME/GTK
@@ -49,6 +49,7 @@ from gramps.gen.const import GLADE_FILE, ICON
from gramps.gen.errors import WindowActiveError
from gramps.gen.config import config
from gramps.gen.constfunc import is_quartz
from .uimanager import ActionGroup
from .glade import Glade
#-------------------------------------------------------------------------
@@ -57,8 +58,8 @@ from .glade import Glade
#
#-------------------------------------------------------------------------
_win_top = '<ui><menubar name="MenuBar"><menu action="WindowsMenu">'
_win_btm = '</menu></menubar></ui>'
_win_top = '<section id="WinMenu">\n'
_win_btm = '</section>\n'
DISABLED = -1
#-----------------------------------------------------------------------
@@ -108,7 +109,7 @@ class GrampsWindowManager:
self.uimanager = uimanager
self.window_tree = []
self.id2item = {}
self.action_group = Gtk.ActionGroup(name='WindowManger')
self.action_group = ActionGroup(name='WindowManger')
self.active = DISABLED
self.ui = _win_top + _win_btm
@@ -125,9 +126,9 @@ class GrampsWindowManager:
"""
Enables the UI and action groups
"""
self.uimanager.insert_action_group(self.action_group, 1)
self.active = self.uimanager.add_ui_from_string(self.ui)
self.uimanager.ensure_update()
self.uimanager.insert_action_group(self.action_group)
self.active = self.uimanager.add_ui_from_string([self.ui])
self.uimanager.update_menu()
def get_item_from_track(self, track):
# Recursively find an item given track sequence
@@ -270,31 +271,35 @@ class GrampsWindowManager:
def call_back_factory(self, item):
if not isinstance(item, list):
def func(obj):
def func(*obj):
if item.window_id and self.id2item.get(item.window_id):
self.id2item[item.window_id]._present()
else:
def func(obj):
def func(*obj):
pass
return func
def generate_id(self, item):
return str(item.window_id)
return 'wm/' + str(item.window_id)
def display_menu_list(self, data, action_data, mlist):
menuitem = ('<item>\n'
'<attribute name="action">win.%s</attribute>\n'
'<attribute name="label" translatable="yes">'
'%s...</attribute>\n'
'</item>\n')
if isinstance(mlist, (list, tuple)):
i = mlist[0]
idval = self.generate_id(i)
data.write('<menu action="M:%s">' % idval)
action_data.append(("M:"+idval, None, i.submenu_label,
None, None, None))
data.write('<submenu>\n<attribute name="label"'
' translatable="yes">%s</attribute>\n' %
html.escape(i.submenu_label))
else:
i = mlist
idval = self.generate_id(i)
data.write('<menuitem action="%s"/>' % idval)
action_data.append((idval, None, i.menu_label, None, None,
self.call_back_factory(i)))
data.write(menuitem % (idval, html.escape(i.menu_label)))
action_data.append((idval, self.call_back_factory(i)))
if isinstance(mlist, (list, tuple)) and (len(mlist) > 1):
for i in mlist[1:]:
@@ -302,20 +307,17 @@ class GrampsWindowManager:
self.display_menu_list(data, action_data, i)
else:
idval = self.generate_id(i)
data.write('<menuitem action="%s"/>'
% self.generate_id(i))
action_data.append((idval, None, i.menu_label,
None, None,
self.call_back_factory(i)))
data.write(menuitem % (idval, html.escape(i.menu_label)))
action_data.append((idval, self.call_back_factory(i)))
if isinstance(mlist, (list, tuple)):
data.write('</menu>')
data.write('</submenu>\n')
def build_windows_menu(self):
if self.active != DISABLED:
self.uimanager.remove_ui(self.active)
self.uimanager.remove_action_group(self.action_group)
self.action_group = Gtk.ActionGroup(name='WindowManger')
self.action_group = ActionGroup(name='WindowManger')
action_data = []
data = StringIO()
+49 -31
View File
@@ -38,22 +38,21 @@ from gi.repository import Gdk
#-------------------------------------------------------------------------
from gramps.gen.plug import (START, END)
from .pluginmanager import GuiPluginManager
from .actiongroup import ActionGroup
from .uimanager import ActionGroup
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
UICATEGORY = '''<ui>
<menubar name="MenuBar">
<menu action="ViewMenu">
<placeholder name="ViewsInCategory">%s
</placeholder>
</menu>
</menubar>
</ui>
'''
UICATEGORY = ''' <section id="ViewsInCatagory">
%s
</section>
'''
UICATAGORYBAR = ''' <placeholder id='ViewsInCategoryBar'>
%s
</placeholder>
'''
CATEGORY_ICON = {
'Dashboard': 'gramps-gramplet',
@@ -88,7 +87,6 @@ class Navigator:
self.active_view = None
self.ui_category = {}
self.view_toggle_actions = {}
self.cat_view_group = None
self.merge_ids = []
@@ -139,13 +137,35 @@ class Navigator:
"""
Load the sidebar plugins.
"""
menuitem = '''
<item>
<attribute name="action">win.ViewInCatagory</attribute>
<attribute name="label" translatable="yes">%s</attribute>
<attribute name="target">%d %d</attribute>
</item>
'''
baritem = '''
<child>
<object class="GtkToggleToolButton" id="bar%d">
<property name="action-name">win.ViewInCatagory</property>
<property name="action-target">'%d %d'</property>
<property name="icon-name">%s</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">%s</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
'''
plugman = GuiPluginManager.get_instance()
categories = []
views = {}
for cat_num, cat_views in enumerate(self.viewmanager.get_views()):
uimenuitems = ''
self.view_toggle_actions[cat_num] = []
uibaritems = ''
for view_num, page in enumerate(cat_views):
if view_num == 0:
@@ -156,26 +176,26 @@ class Navigator:
cat_icon = 'gramps-view'
categories.append([cat_num, cat_name, cat_icon])
pageid = 'page_%i_%i' % (cat_num, view_num)
uimenuitems += '\n<menuitem action="%s"/>' % pageid
# id, stock, button text, UI, tooltip, page
if view_num < 9:
modifier = "<PRIMARY><ALT>%d" % ((view_num % 9) + 1)
else:
modifier = ""
accel = "<PRIMARY><ALT>%d" % ((view_num % 9) + 1)
self.viewmanager.uimanager.app.set_accels_for_action(
"win.ViewInCatagory('%d %d')" % (cat_num, view_num),
[accel])
uimenuitems += menuitem % (page[0].name, cat_num, view_num)
stock_icon = page[0].stock_icon
if stock_icon is None:
stock_icon = cat_icon
self.view_toggle_actions[cat_num].append((pageid,
stock_icon,
page[0].name, modifier, page[0].name, view_num))
uibaritems += baritem % (view_num, cat_num, view_num,
stock_icon, page[0].name,
page[0].name)
views[cat_num].append((view_num, page[0].name, stock_icon))
if len(cat_views) > 1:
#allow for switching views in a category
self.ui_category[cat_num] = UICATEGORY % uimenuitems
self.ui_category[cat_num] = [UICATEGORY % uimenuitems,
UICATAGORYBAR % uibaritems]
for pdata in plugman.get_reg_sidebars():
module = plugman.load_plugin(pdata)
@@ -229,12 +249,10 @@ class Navigator:
list(map(uimanager.remove_ui, self.merge_ids))
if cat_num in self.ui_category:
self.cat_view_group = ActionGroup(name='viewmenu')
self.cat_view_group.add_radio_actions(
self.view_toggle_actions[cat_num], value=view_num,
on_change=self.cb_view_clicked, user_data=cat_num)
self.cat_view_group.set_sensitive(True)
uimanager.insert_action_group(self.cat_view_group, 1)
action = ('ViewInCatagory', self.cb_view_clicked, '',
str(cat_num) + ' ' + str(view_num))
self.cat_view_group = ActionGroup('viewmenu', [action])
uimanager.insert_action_group(self.cat_view_group)
mergeid = uimanager.add_ui_from_string(self.ui_category[cat_num])
self.merge_ids.append(mergeid)
@@ -245,12 +263,12 @@ class Navigator:
return
sidebar.view_changed(cat_num, view_num)
def cb_view_clicked(self, radioaction, current, cat_num):
def cb_view_clicked(self, radioaction, value):
"""
Called when a view is selected from the menu.
"""
view_num = radioaction.get_current_value()
self.viewmanager.goto_page(cat_num, view_num)
cat_num, view_num = value.get_string().split()
self.viewmanager.goto_page(int(cat_num), int(view_num))
def __menu_button_pressed(self, button, event):
"""
+31 -28
View File
@@ -63,6 +63,12 @@ from gramps.gen.plug import (CATEGORY_QR_PERSON, CATEGORY_QR_FAMILY, CATEGORY_QR
from ._textbufdoc import TextBufDoc
from gramps.gen.simple import make_basic_stylesheet
MENUITEM = ('<item>\n'
'<attribute name="action">{prefix}.{action}</attribute>\n'
'<attribute name="label" translatable="yes">'
'{label}</attribute>\n'
'</item>\n')
def flatten(L):
"""
Flattens a possibly nested list. Removes None results, too.
@@ -77,7 +83,7 @@ def flatten(L):
retval.append(L)
return retval
def create_web_connect_menu(dbstate, uistate, nav_group, handle):
def create_web_connect_menu(dbstate, uistate, nav_group, handle, prefix):
"""
This functions querries the registered web connects. It collects
the connects of the requested category, which must be one of
@@ -88,12 +94,12 @@ def create_web_connect_menu(dbstate, uistate, nav_group, handle):
handle as input method. A tuple is returned, containing the ui
string of the menu, and its associated actions.
"""
top = ("<placeholder id='WebConnect'><submenu>\n"
'<attribute name="label" translatable="yes">'
'Web Connection</attribute>\n')
actions = []
ofile = StringIO()
ofile.write('<menu action="WebConnect">')
actions.append(('WebConnect', None, _("Web Connect"), None, None, None))
menu = Gtk.Menu()
menu.show()
ofile.write(top)
#select the web connects to show
showlst = []
pmgr = GuiPluginManager.get_instance()
@@ -109,16 +115,17 @@ def create_web_connect_menu(dbstate, uistate, nav_group, handle):
connections.sort(key=lambda plug: plug.name)
actions = []
for connect in connections:
ofile.write('<menuitem action="%s"/>' % connect.key)
actions.append((connect.key, None, connect.name, None, None,
connect(dbstate, uistate, nav_group, handle)))
ofile.write('</menu>')
retval = [ofile.getvalue()]
retval.extend(actions)
return retval
action = connect.key.replace(' ', '-')
ofile.write(MENUITEM.format(prefix=prefix, action=action,
label=connect.name))
callback = connect(dbstate, uistate, nav_group, handle)
actions.append((action,
lambda x, y: callback(x)))
ofile.write('</submenu></placeholder>\n')
return (ofile.getvalue(), actions)
def create_quickreport_menu(category, dbstate, uistate, handle, track=[]):
def create_quickreport_menu(category, dbstate, uistate, handle, prefix, track=[]):
""" This functions querries the registered quick reports with
quick_report_list of _PluginMgr.py
It collects the reports of the requested category, which must be one of
@@ -132,39 +139,35 @@ def create_quickreport_menu(category, dbstate, uistate, handle, track=[]):
A tuple is returned, containing the ui string of the quick report menu,
and its associated actions
"""
top = ("<submenu>\n"
'<attribute name="label" translatable="yes">'
'Quick View</attribute>\n')
actions = []
ofile = StringIO()
ofile.write('<menu action="QuickReport">')
actions.append(('QuickReport', None, _("Quick View"), None, None, None))
menu = Gtk.Menu()
menu.show()
ofile.write(top)
#select the reports to show
showlst = []
pmgr = GuiPluginManager.get_instance()
for pdata in pmgr.get_reg_quick_reports():
if pdata.supported and pdata.category == category :
#add tuple function, translated name, name, status
showlst.append(pdata)
showlst.sort(key=lambda x: x.name)
for pdata in showlst:
new_key = pdata.id.replace(' ', '-')
ofile.write('<menuitem action="%s"/>' % new_key)
actions.append((new_key, None, pdata.name, None, None,
make_quick_report_callback(pdata, category, dbstate,
uistate, handle, track=track)))
ofile.write('</menu>')
ofile.write(MENUITEM.format(prefix=prefix, action=new_key,
label=pdata.name))
actions.append((new_key, make_quick_report_callback(
pdata, category, dbstate, uistate, handle, track=track)))
ofile.write('</submenu>\n')
return (ofile.getvalue(), actions)
def make_quick_report_callback(pdata, category, dbstate, uistate, handle,
track=[]):
return lambda x: run_report(dbstate, uistate, category, handle, pdata,
track=track)
return lambda x, y: run_report(dbstate, uistate, category, handle, pdata,
track=track)
def get_quick_report_list(qv_category=None):
"""
+517
View File
@@ -0,0 +1,517 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2018 Paul Culley
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
"""
A replacement UIManager and ActionGroup.
"""
import copy
import sys
from ..gen.config import config
import logging
import xml.etree.ElementTree as ET
from gi.repository import GLib, Gio, Gtk
from ..gen.config import config
LOG = logging.getLogger('gui.uimanager')
ACTION_NAME = 0 # tuple index for action name
ACTION_CB = 1 # tuple index for action callback
ACTION_ACC = 2 # tuple index for action accelerator
ACTION_ST = 3 # tuple index for action state
class ActionGroup():
""" This class represents a group of actions that con be manipulated
together.
"""
def __init__(self, name, actionlist=None, prefix='win'):
"""
@param name: the action group name, used to match to the 'groups'
attribute in the ui xml.
@type name: string
@type actionlist: list
@param actionlist: the list of actions to add
The list contains tuples with the following contents:
string: Action Name
method: signal callback function.
None if just adding an accelerator
string: accelerator ex: '<Primary>Enter' or '' for no accelerator.
optional for non-stateful actions.
state: initial state for stateful actions.
'True' or 'False': the action is interpreted as a checkbox.
'None': non stateful action (optional)
'string': the action is interpreted as a Radio button
@type prefix: str
@param prefix: the prefix used by this group. If not provided, 'win'
is assumed.
"""
self.name = name
self.actionlist = actionlist if actionlist else []
self.prefix = prefix + '.'
self.act_group = None
self.sensitive = True
def add_actions(self, actionlist):
""" Add a list of actions to the current list
@type actionlist: list
@param actionlist: the list of actions to add
"""
self.actionlist.extend(actionlist)
class UIManager():
"""
This is Gramps UIManager, it is designed to replace the deprecated Gtk
UIManager. The replacement is not exact, but performs similar
functions, in some case with the same method names and parameters.
It is designed to be a singleton. The menu portion of this is responsible
only for Gramps main window menus and toolbar.
This was implemented to extend Gtk.Builder functions to allow editing
(merging) of the original builder XML with additional XML fragments during
operations. This allows changing of the menus and toolbar when the tree is
loaded, views are changed etc.
The ActionGroup portions can also be used by other windows. Other windows
needing menus or toolbars can create them via Gtk.Builder.
"""
def __init__(self, app, initial_xml):
"""
@param app: Gramps Gtk.Application reference
@type app: Gtk.Application
@param initial_xml: Initial (primary) XML string for Gramps menus and
toolbar
@type changexml: string
The xml is basically Gtk Builder xml, in particular the various menu
and toolbar elements. It is possible to add other elements as well.
The xml this supports has been extended in two ways;
1) there is an added "groups=" attribute to elements. This
attribute associates the element with one or more named ActionGroups
for making the element visible or not. If 'groups' is missing, the
element will be shown as long as enclosing elements are shown. The
element will be shown if the group is present and considered visible
by the uimanager. If more than one group is needed, they should be
separated by a space.
2) there is an added <placeholder> tag supported; this is used to mark
a place where merged UI XML can be inserted. During the update_menu
processing, elements enclosed in this tag pair are promoted to the
level of the placeholder tag, and the placeholder tag is removed.
Note that any elements can be merged (replaced) by the
add_ui_from_string method, not just placeholders. This works by
matching the "id=" attribute on the element, and replacing the
original element with the one from the add method.
Note that when added elements are removed by the remove_ui method, they
are replaced by the containing xml (with the 'id=') only, so don't put
anything inside of the containing xml to start with as it will be lost
during editing.
"""
self.app = app # the Gtk.Application of Gramps
self.et_xml = ET.fromstring(initial_xml)
self.builder = None
self.toolbar = None
self.action_groups = [] # current list of action groups
self.show_groups = [] # groups to show at the moment
self.accel_dict = {} # used to store accel overrides from file
def update_menu(self, init=False):
""" This updates the menus and toolbar when there is a change in the
ui; any addition or removal or set_visible operation needs to call
this. It is best to make the call only once, at the end, if multiple
changes are to be made.
It starts with the ET xml stored in self, cleans it up to meet the
Gtk.Builder specifications, and then updates the ui.
@param init: When True, this is first call and we set the builder
toolbar and menu to the application.
When False, we update the menus and toolbar
@type init: bool
"""
def iterator(parents):
""" This recursively goes through the ET xml and deals with the
'groups' attribute and <placeholder> tags, which are not valid for
builder. Empty submenus are also removed.
Groups processing removes elements that are not shown, as well as
the 'groups' attribute itself.
<placeholder> tags are removed and their enclosed elements are
promoted to the level of the placeholder.
@param parents: the current element to recursively process
@type parents: ET element
"""
indx = 0
while indx < len(parents):
child = parents[indx]
if len(child) >= 1:
# Recurse until we have a stand-alone child
iterator(child)
if((len(child) == 1 and child.tag == "submenu") or
(len(child) == 0 and child.tag == "section")):
# remove empty submenus and sections
# print('del', child.tag, child.attrib)
del parents[indx]
continue
# print(child.attrib)
groups = child.get('groups')
if not groups:
indx += 1
continue
del child.attrib['groups']
for group in groups.split(' '):
if group in self.show_groups:
indx += 1
break
else:
#print('del', child.tag, child.attrib, parents.tag,
# parents.attrib)
del parents[indx]
break
# The following looks for 'placeholder' elements and if found,
# promotes any children to the same level as the placeholder.
# this allows the user to insert elements without using a section.
indx = 0
while indx < len(parents):
if parents[indx].tag == "placeholder":
subtree = parents[indx]
#print('placholder del', parents[indx].tag,
# parents[indx].attrib, parents.tag, parents.attrib)
del parents[indx]
for child in subtree:
parents.insert(indx, child)
indx += 1
else:
indx += 1
if self.builder:
toolbar = self.builder.get_object("ToolBar") # previous toolbar
# need to copy the tree so we can preserve original for later edits.
editable = copy.deepcopy(self.et_xml)
iterator(editable) # clean up tree to builder specifications
xml_str = ET.tostring(editable, encoding="unicode")
#print(xml_str)
self.builder = Gtk.Builder.new_from_string(xml_str, -1)
if init:
self.app.menubar = self.builder.get_object("menubar")
self.app.set_menubar(self.app.menubar)
return
# The following is the only way I have found to update the menus.
# app.set_menubar can apparently only be used once, before
# ApplicationWindow creation, further uses do NOT cause the menus to
# update.
self.app.menubar.remove_all()
section = self.builder.get_object('menubar-update')
self.app.menubar.append_section(None, section)
# the following updates the toolbar from the new builder
toolbar_parent = toolbar.get_parent()
tb_show = toolbar.get_visible()
toolbar_parent.remove(toolbar)
toolbar = self.builder.get_object("ToolBar") # new toolbar
if config.get('interface.toolbar-text'):
toolbar.set_style(Gtk.ToolbarStyle.BOTH)
toolbar_parent.pack_start(toolbar, False, True, 0)
if tb_show:
toolbar.show_all()
else:
toolbar.hide()
#print('*** Update ui')
def add_ui_from_string(self, changexml):
""" This performs a merge operation on the xml elements that have
matching 'id's between the current ui xml and change xml strings.
The 'changexml' is a list of xml fragment strings used to replace
matching elements in the current xml.
There MUST one and only one matching id in the orig xml.
@param changexml: list of xml fragments to merge into main
@type changexml: list
@return: changexml
"""
try:
for xml in changexml:
if not xml:
# allow an xml fragment to be an empty string
continue
update = ET.fromstring(xml)
el_id = update.attrib['id']
# find the parent of the id'd element in original xml
parent = self.et_xml.find(".//*[@id='%s'].." % el_id)
if parent:
# we found it, now delete original, inset updated
for indx in range(len(parent)):
if parent[indx].get('id') == el_id:
del parent[indx]
parent.insert(indx, update)
else:
# updated item not present in original, just add it
# This allow addition of popups etc.
self.et_xml.append(update)
#results = ET.tostring(self.et_xml, encoding="unicode")
#print(results)
#print ('*** Add ui')
return changexml
except:
# the following is only here to assist debug
print('*****', sys.exc_info())
print(xml)
print(changexml)
assert False
def remove_ui(self, change_xml):
""" This removes the 'change_xml' from the current ui xml. It works on
any element with matching 'id', the actual element remains but any
children are removed.
The 'change_xml' is a list of xml strings originally used to replace
matching elements in the current ui xml.
@param change_xml: list of xml fragments to remove from main
@type change_xml: list
"""
# if not change_xml:
# import pydevd
# pydevd.settrace()
for xml in change_xml:
if not xml:
continue
update = ET.fromstring(xml)
el_id = update.attrib['id']
# find parent of id'd element
element = self.et_xml.find(".//*[@id='%s']" % el_id)
if element: # element may have already been deleted
for dummy in range(len(element)):
del element[0]
#results = ET.tostring(self.et_xml, encoding="unicode")
#print(results)
#print ('*** Remove ui')
return
def get_widget(self, obj):
""" Get the object from the builder.
@param obj: the widget to get
@type obj: string
@return: the object
"""
return self.builder.get_object(obj)
def insert_action_group(self, group, gio_group=None):
"""
This inserts (actually overwrites any matching actions) the action
group's actions to the app.
By default (with no gio_group), the action group is added to the main
Gramps window and the group assumes a 'win' prefix.
If not using the main window, the window MUST have the 'application'
property set for the accels to work. In this case the actiongroups
must be created like the following:
# create Gramps ActionGroup
self.action_group = ActionGroup('name', actions, 'prefix')
# create Gio action group
act_grp = SimpleActionGroup()
# associate window with Gio group and its prefix
window.insert_action_group('prefix', act_grp)
# make the window 'application' aware
window.set_application(uimanager.app)
# tell the uimanager about the groups.
uimanager.insert_action_group(self.action_group, act_grp)
@param group: the action group
@type group: ActionGroup
@param gio_group: the Gio action group associated with a window.
@type gio_group: Gio.SimpleActionGroup
"""
try:
assert isinstance(group.actionlist, list)
if gio_group:
window_group = group.act_group = gio_group
elif group.act_group:
window_group = group.act_group
else:
window_group = group.act_group = self.app.window
for item in group.actionlist:
# deal with accelerator overrides from a file
accel = self.accel_dict.get(group.prefix + item[ACTION_NAME])
if accel:
self.app.set_accels_for_action(
group.prefix + item[ACTION_NAME], [accel])
elif len(item) > 2 and item[ACTION_ACC]:
# deal with accelerators defined in the group
accels = self.app.get_actions_for_accel(item[ACTION_ACC])
if accels:
# diagnostic printout; a duplicate accelerator may be
# a problem if both are valid for the same window at
# the same time. If the actions are for a different
# window, this is not an error. Here we assume a
# different prefix is used for different windows.
for accel in accels:
if group.prefix in accel:
LOG.warning('**Duplicate Accelerator %s',
item[ACTION_ACC])
self.app.set_accels_for_action(
group.prefix + item[ACTION_NAME], [item[ACTION_ACC]])
if len(item) <= 3:
# Normal stateless actions
action = Gio.SimpleAction.new(item[ACTION_NAME], None)
if item[ACTION_CB]: # in case we have only accelerator
action.connect("activate", item[ACTION_CB])
elif isinstance(item[ACTION_ST], str):
# Radio Actions
action = Gio.SimpleAction.new_stateful(
item[ACTION_NAME], GLib.VariantType.new("s"),
GLib.Variant("s", item[ACTION_ST]))
action.connect("change-state", item[ACTION_CB])
elif isinstance(item[ACTION_ST], bool):
# Checkbox actions
action = Gio.SimpleAction.new_stateful(
item[ACTION_NAME], None,
GLib.Variant.new_boolean(item[ACTION_ST]))
action.connect("change-state", item[ACTION_CB])
window_group.add_action(action)
self.action_groups.append(group)
# if action sensitivity was set prior to actually inserting into
# UIManager, we need to do it now that we have the action
if not group.sensitive:
self.set_actions_sensitive(group, False)
except:
# the following is only to assist in debug
print(group.name, item)
assert False
def remove_action_group(self, group):
""" This removes the ActionGroup from the UIManager
@param group: the action group
@type group: ActionGroup
"""
if group.act_group:
window_group = group.act_group
else:
window_group = self.app.window
for item in group.actionlist:
window_group.remove_action(item[ACTION_NAME])
self.app.set_accels_for_action(group.prefix + item[ACTION_NAME],
[])
self.action_groups.remove(group)
def get_action_groups(self):
""" This returns a list of action Groups installed into the UIManager.
@return: list of groups
"""
return self.action_groups
def set_actions_sensitive(self, group, value):
""" This sets an ActionGroup enabled or disabled. A disabled action
will be greyed out in the UI.
@param group: the action group
@type group: ActionGroup
@param value: the state of the group
@type value: bool
"""
if group.act_group:
for item in group.actionlist:
action = group.act_group.lookup_action(item[ACTION_NAME])
if action:
# We check in case the group has not been inserted into
# UIManager yet
action.set_enabled(value)
group.sensitive = value
def get_actions_sensitive(self, group):
""" This gets an ActionGroup sensitive setting. A disabled action
will be greyed out in the UI.
We assume that the first action represents the group.
@param group: the action group
@type group: ActionGroup
@return: the state of the group
"""
item = group.actionlist[0]
action = group.act_group.lookup_action(item[ACTION_NAME])
return action.get_enabled()
def set_actions_visible(self, group, value):
""" This sets an ActionGroup visible and enabled or invisible and
disabled. Make sure that the menuitems or sections and toolbar items
have the 'groups=' xml attribute matching the group name for this to
work correctly.
@param group: the action group
@type group: ActionGroup
@param value: the state of the group
@type value: bool
"""
self.set_actions_sensitive(group, value)
if value:
if group.name not in self.show_groups:
self.show_groups.append(group.name)
else:
if group.name in self.show_groups:
self.show_groups.remove(group.name)
def get_action(self, group, actionname):
""" Return a single action from the group.
@param group: the action group
@type group: ActionGroup
@param actionname: the action name
@type actionname: string
@return: Gio.Action
"""
return group.act_group.lookup_action(actionname)
def dump_all_accels(self):
''' A function used diagnostically to see what accels are present.
This will only dump the current accel set, if other non-open windows
or views have accels, you will need to open them and run this again
and manually merge the result files. The results are in a
'gramps.accel' file located in the current working directory.'''
out_dict = {}
for group in self.action_groups:
for item in group.actionlist:
act = group.prefix + item[ACTION_NAME]
accels = self.app.get_accels_for_action(
group.prefix + item[ACTION_NAME])
out_dict[act] = accels[0] if accels else ''
import json
with open('gramps.accel', 'w', ) as hndl:
accels = json.dumps(out_dict, indent=0).replace('\n"', '\n# "')
hndl.write(accels)
def load_accels(self, filename):
""" This function loads accels from a file such as created by
dump_all_accels. The file contents is basically a Python dict
definition. As such it contains a line for each dict element.
These elements can be commented out with '#' at the beginning of the
line.
If used, this file overrides the accels defined in other Gramps code.
As such it must be loaded before any insert_action_group calls.
"""
import ast
with open(filename, 'r') as hndl:
accels = hndl.read()
self.accel_dict = ast.literal_eval(accels)
+280 -548
View File
File diff suppressed because it is too large. Load diff
+23 -19
View File
@@ -28,6 +28,7 @@
#-------------------------------------------------------------------------
from abc import ABCMeta, abstractmethod
from io import StringIO
import html
#-------------------------------------------------------------------------
#
@@ -51,6 +52,7 @@ from gi.repository import Gtk
from ..display import display_help
from ..listmodel import ListModel
from ..managedwindow import ManagedWindow
from ..uimanager import ActionGroup
from gramps.gen.utils.db import navigation_label
from gramps.gen.const import URL_MANUAL_PAGE
from gramps.gen.const import GRAMPS_LOCALE as glocale
@@ -72,9 +74,6 @@ WIKI_HELP_SEC = _('manual|Bookmarks')
#
#-------------------------------------------------------------------------
TOP = '''<ui><menubar name="MenuBar"><menu action="BookMenu">'''
BTM = '''</menu></menubar></ui>'''
DISABLED = -1
class Bookmarks(metaclass=ABCMeta):
@@ -94,7 +93,7 @@ class Bookmarks(metaclass=ABCMeta):
if self.dbstate.is_open():
self.update_bookmarks()
self.active = DISABLED
self.action_group = Gtk.ActionGroup(name='Bookmarks')
self.action_group = ActionGroup(name='Bookmarks')
if self.dbstate.is_open():
self.connect_signals()
self.dbstate.connect('database-changed', self.db_changed)
@@ -130,7 +129,8 @@ class Bookmarks(metaclass=ABCMeta):
"""
Redraw the display.
"""
self.redraw()
# used by navigationview; other updates follow
self.redraw(update_menu=False)
def undisplay(self):
"""
@@ -139,8 +139,7 @@ class Bookmarks(metaclass=ABCMeta):
if self.active != DISABLED:
self.uistate.uimanager.remove_ui(self.active)
self.uistate.uimanager.remove_action_group(self.action_group)
self.action_group = Gtk.ActionGroup(name='Bookmarks')
self.uistate.uimanager.ensure_update()
self.action_group = ActionGroup(name='Bookmarks')
self.active = DISABLED
def redraw_and_report_change(self):
@@ -148,10 +147,14 @@ class Bookmarks(metaclass=ABCMeta):
self.dbstate.db.report_bm_change()
self.redraw()
def redraw(self):
def redraw(self, update_menu=True):
"""Create the pulldown menu."""
menuitem = ('<item>\n'
'<attribute name="action">win.%s</attribute>\n'
'<attribute name="label" translatable="yes">'
'%s</attribute>\n'
'</item>\n')
text = StringIO()
text.write(TOP)
self.undisplay()
@@ -160,27 +163,28 @@ class Bookmarks(metaclass=ABCMeta):
bad_bookmarks = [] # list of bad bookmarks
if self.dbstate.is_open() and len(self.bookmarks.get()) > 0:
text.write('<placeholder name="GoToBook">')
text.write('<section id="GoToBook">\n')
for item in self.bookmarks.get():
try:
label, dummy_obj = self.make_label(item)
func = self.callback(item)
action_id = "BM:%s" % item
actions.append((action_id, None, label, None, None, func))
text.write('<menuitem action="%s"/>' % action_id)
action_id = "BM.%s" % item
actions.append((action_id, func))
text.write(menuitem % (action_id, html.escape(label)))
count += 1
except AttributeError:
pass
except HandleError:
# if bookmark contains handle to something missing now
bad_bookmarks.append(item)
text.write('</placeholder>')
text.write('</section>\n')
text.write(BTM)
self.action_group.add_actions(actions)
self.uistate.uimanager.insert_action_group(self.action_group, 1)
self.active = self.uistate.uimanager.add_ui_from_string(text.getvalue())
self.uistate.uimanager.ensure_update()
self.uistate.uimanager.insert_action_group(self.action_group)
self.active = self.uistate.uimanager.add_ui_from_string(
[text.getvalue()])
if update_menu:
self.uistate.uimanager.update_menu()
text.close()
# Clean up any bad bookmarks (can happen if Gramps crashes;
# modified bookmarks set is saved only on normal Gramps close)
@@ -547,4 +551,4 @@ def make_callback(handle, function):
"""
Build a unique call to the function with the associated handle.
"""
return lambda x: function(handle)
return lambda x, y: function(handle)
+73 -74
View File
@@ -55,7 +55,7 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from .pageview import PageView
from .navigationview import NavigationView
from ..actiongroup import ActionGroup
from ..uimanager import ActionGroup
from ..columnorder import ColumnOrder
from gramps.gen.config import config
from gramps.gen.errors import WindowActiveError, FilterError, HandleError
@@ -64,6 +64,7 @@ from ..widgets.menuitem import add_menuitem
from gramps.gen.const import CUSTOM_FILTERS
from gramps.gen.utils.debug import profile
from gramps.gen.utils.string import data_recover_msg
from gramps.gen.plug import CATEGORY_QR_PERSON
from ..dialog import QuestionDialog, QuestionDialog2, ErrorDialog
from ..editors import FilterEditor
from ..ddtargets import DdTargets
@@ -122,6 +123,8 @@ class ListView(NavigationView):
self.generic_filter = None
dbstate.connect('database-changed', self.change_db)
self.connect_signals()
self.at_popup_action = None
self.at_popup_menu = None
def no_database(self):
## TODO GTK3: This is never called!! Dbguielement disconnects
@@ -206,24 +209,19 @@ class ListView(NavigationView):
NavigationView.define_actions(self)
self.edit_action = ActionGroup(name=self.title + '/ChangeOrder')
self.edit_action = ActionGroup(name=self.title + '/Edits')
self.edit_action.add_actions([
('Add', 'list-add', _("_Add..."), "<PRIMARY>Insert",
self.ADD_MSG, self.add),
('Remove', 'list-remove', _("_Delete"), "<PRIMARY>Delete",
self.DEL_MSG, self.remove),
('Merge', 'gramps-merge', _('_Merge...'), None,
self.MERGE_MSG, self.merge),
('ExportTab', None, _('Export View...'), None, None,
self.export),
])
('Add', self.add, '<Primary>Insert'),
('Remove', self.remove, '<Primary>Delete'),
('PRIMARY-BackSpace', self.remove, '<PRIMARY>BackSpace'),
('Merge', self.merge), ])
self._add_action_group(self.edit_action)
self._add_action('Edit', 'gtk-edit', _("action|_Edit..."),
accel="<PRIMARY>Return",
tip=self.EDIT_MSG,
callback=self.edit)
self.action_list.extend([
('ExportTab', self.export),
('Edit', self.edit, '<Primary>Return'),
('PRIMARY-J', self.jump, '<PRIMARY>J'),
('FilterEdit', self.filter_editor)])
def build_columns(self, preserve_col=True):
"""
@@ -297,7 +295,7 @@ class ListView(NavigationView):
Called when the page is displayed.
"""
NavigationView.set_active(self)
self.uistate.viewmanager.tags.tag_enable()
self.uistate.viewmanager.tags.tag_enable(update_menu=False)
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.model.total())
@@ -309,9 +307,6 @@ class ListView(NavigationView):
NavigationView.set_inactive(self)
self.uistate.viewmanager.tags.tag_disable()
def __build_tree(self):
profile(self._build_tree)
def build_tree(self, force_sidebar=False, preserve_col=True):
if self.active:
cput0 = time.clock()
@@ -378,7 +373,7 @@ class ListView(NavigationView):
"""
return 'gramps-tree-list'
def filter_editor(self, obj):
def filter_editor(self, *obj):
try:
FilterEditor(self.FILTER_TYPE , CUSTOM_FILTERS,
self.dbstate, self.uistate)
@@ -447,7 +442,7 @@ class ListView(NavigationView):
self.uistate.push_message(self.dbstate,
_("Active object not visible"))
def add_bookmark(self, obj):
def add_bookmark(self, *obj):
mlist = []
self.selection.selected_foreach(self.blist, mlist)
@@ -857,6 +852,7 @@ class ListView(NavigationView):
"""
if not self.dbstate.is_open():
return False
menu = self.uimanager.get_widget('Popup')
if event.type == Gdk.EventType._2BUTTON_PRESS and event.button == 1:
if self.model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY:
self.edit(obj)
@@ -872,49 +868,54 @@ class ListView(NavigationView):
else:
self.edit(obj)
return True
elif is_right_click(event):
menu = self.uistate.uimanager.get_widget('/Popup')
if menu:
# Quick Reports
qr_menu = self.uistate.uimanager.\
get_widget('/Popup/QuickReport')
if qr_menu and self.QR_CATEGORY > -1 :
(ui, qr_actions) = create_quickreport_menu(
self.QR_CATEGORY,
self.dbstate,
self.uistate,
self.first_selected())
self.__build_menu(qr_menu, qr_actions)
elif is_right_click(event) and menu:
prefix = 'win'
self.at_popup_menu = []
actions = []
# Quick Reports
if self.QR_CATEGORY > -1:
(qr_ui, qr_actions) = create_quickreport_menu(
self.QR_CATEGORY, self.dbstate, self.uistate,
self.first_selected(), prefix)
if self.get_active() and qr_actions:
actions.extend(qr_actions)
qr_ui = ("<placeholder id='QuickReport'>%s</placeholder>" %
qr_ui)
self.at_popup_menu.append(qr_ui)
# Web Connects
web_menu = self.uistate.uimanager.\
get_widget('/Popup/WebConnect')
if web_menu:
web_actions = create_web_connect_menu(
self.dbstate,
self.uistate,
self.navigation_type(),
self.first_selected())
self.__build_menu(web_menu, web_actions)
# Web Connects
if self.QR_CATEGORY == CATEGORY_QR_PERSON:
(web_ui, web_actions) = create_web_connect_menu(
self.dbstate, self.uistate, self.navigation_type(),
self.first_selected(), prefix)
if self.get_active() and web_actions:
actions.extend(web_actions)
self.at_popup_menu.append(web_ui)
menu.popup(None, None, None, None, event.button, event.time)
return True
if self.at_popup_action:
self.uimanager.remove_ui(self.at_popup_menu)
self.uimanager.remove_action_group(self.at_popup_action)
self.at_popup_action = ActionGroup('AtPopupActions',
actions)
self.uimanager.insert_action_group(self.at_popup_action)
self.at_popup_menu = self.uimanager.add_ui_from_string(
self.at_popup_menu)
self.uimanager.update_menu()
menu = self.uimanager.get_widget('Popup')
popup_menu = Gtk.Menu.new_from_model(menu)
popup_menu.attach_to_widget(obj, None)
popup_menu.show_all()
if Gtk.MINOR_VERSION < 22:
# ToDo The following is reported to work poorly with Wayland
popup_menu.popup(None, None, None, None,
event.button, event.time)
else:
popup_menu.popup_at_pointer(event)
return True
return False
def __build_menu(self, menu, actions):
"""
Build a submenu for quick reports and web connects
"""
if self.get_active() and len(actions) > 1:
sub_menu = Gtk.Menu()
for action in actions[1:]:
add_menuitem(sub_menu, action[2], None, action[5])
menu.set_submenu(sub_menu)
menu.show()
else:
menu.hide()
def _key_press(self, obj, event):
"""
Called when a key is pressed on a listview
@@ -1008,9 +1009,6 @@ class ListView(NavigationView):
return True
return False
def key_delete(self):
self.remove(None)
def change_page(self):
"""
Called when a page is changed.
@@ -1020,8 +1018,9 @@ class ListView(NavigationView):
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.model.total())
self.edit_action.set_visible(True)
self.edit_action.set_sensitive(not self.dbstate.db.readonly)
self.uimanager.set_actions_visible(self.edit_action, True)
self.uimanager.set_actions_sensitive(self.edit_action,
not self.dbstate.db.readonly)
def on_delete(self):
"""
@@ -1051,7 +1050,7 @@ class ListView(NavigationView):
####################################################################
# Export data
####################################################################
def export(self, obj):
def export(self, *obj):
chooser = Gtk.FileChooserDialog(
_("Export View as Spreadsheet"),
self.uistate.window,
@@ -1153,25 +1152,25 @@ class ListView(NavigationView):
# Template functions
####################################################################
@abstractmethod
def edit(self, obj, data=None):
def edit(self, *obj):
"""
Template function to allow the editing of the selected object
"""
@abstractmethod
def remove(self, handle, data=None):
def remove(self, *obj):
"""
Template function to allow the removal of an object by its handle
"""
@abstractmethod
def add(self, obj, data=None):
def add(self, *obj):
"""
Template function to allow the adding of a new object
"""
@abstractmethod
def merge(self, obj, data=None):
def merge(self, *obj):
"""
Template function to allow the merger of two objects.
"""
@@ -1182,7 +1181,7 @@ class ListView(NavigationView):
Template function to allow the removal of an object by its handle
"""
def open_all_nodes(self, obj):
def open_all_nodes(self, *obj):
"""
Method for Treeviews to open all groups
obj: for use of method in event callback
@@ -1195,14 +1194,14 @@ class ListView(NavigationView):
self.uistate.set_busy_cursor(False)
self.uistate.modify_statusbar(self.dbstate)
def close_all_nodes(self, obj):
def close_all_nodes(self, *obj):
"""
Method for Treeviews to close all groups
obj: for use of method in event callback
"""
self.list.collapse_all()
def open_branch(self, obj):
def open_branch(self, *obj):
"""
Expand the selected branches and all children.
obj: for use of method in event callback
@@ -1217,7 +1216,7 @@ class ListView(NavigationView):
self.uistate.set_busy_cursor(False)
self.uistate.modify_statusbar(self.dbstate)
def close_branch(self, obj):
def close_branch(self, *obj):
"""
Collapse the selected branches.
:param obj: not used, present only to allow the use of the method in
+69 -74
View File
@@ -29,6 +29,7 @@ Provide the base classes for GRAMPS' DataView classes
#
#----------------------------------------------------------------
from abc import abstractmethod
import html
import logging
_LOG = logging.getLogger('.navigationview')
@@ -49,7 +50,7 @@ from gi.repository import Gtk
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from .pageview import PageView
from ..actiongroup import ActionGroup
from ..uimanager import ActionGroup
from gramps.gen.utils.db import navigation_label
from gramps.gen.constfunc import mod_key
from ..utils import match_primary_mask
@@ -57,19 +58,9 @@ from ..utils import match_primary_mask
DISABLED = -1
MRU_SIZE = 10
MRU_TOP = [
'<ui>'
'<menubar name="MenuBar">'
'<menu action="GoMenu">'
'<placeholder name="CommonHistory">'
]
MRU_TOP = '<section id="CommonHistory">'
MRU_BTM = '</section>'
MRU_BTM = [
'</placeholder>'
'</menu>'
'</menubar>'
'</ui>'
]
#------------------------------------------------------------------------------
#
# NavigationView
@@ -94,6 +85,7 @@ class NavigationView(PageView):
self.mru_signal = None
self.nav_group = nav_group
self.mru_active = DISABLED
self.uimanager = uistate.uimanager
self.uistate.register(state, self.navigation_type(), self.nav_group)
@@ -122,8 +114,8 @@ class NavigationView(PageView):
"""
PageView.disable_action_group(self)
self.fwd_action.set_visible(False)
self.back_action.set_visible(False)
self.uimanager.set_actions_visible(self.fwd_action, False)
self.uimanager.set_actions_visible(self.back_action, False)
def enable_action_group(self, obj):
"""
@@ -133,20 +125,25 @@ class NavigationView(PageView):
"""
PageView.enable_action_group(self, obj)
self.fwd_action.set_visible(True)
self.back_action.set_visible(True)
self.uimanager.set_actions_visible(self.fwd_action, True)
self.uimanager.set_actions_visible(self.back_action, True)
hobj = self.get_history()
self.fwd_action.set_sensitive(not hobj.at_end())
self.back_action.set_sensitive(not hobj.at_front())
self.uimanager.set_actions_sensitive(self.fwd_action,
not hobj.at_end())
self.uimanager.set_actions_sensitive(self.back_action,
not hobj.at_front())
def change_page(self):
"""
Called when the page changes.
"""
hobj = self.get_history()
self.fwd_action.set_sensitive(not hobj.at_end())
self.back_action.set_sensitive(not hobj.at_front())
self.other_action.set_sensitive(not self.dbstate.db.readonly)
self.uimanager.set_actions_sensitive(self.fwd_action,
not hobj.at_end())
self.uimanager.set_actions_sensitive(self.back_action,
not hobj.at_front())
self.uimanager.set_actions_sensitive(self.other_action,
not self.dbstate.db.readonly)
self.uistate.modify_statusbar(self.dbstate)
def set_active(self):
@@ -159,7 +156,7 @@ class NavigationView(PageView):
hobj = self.get_history()
self.active_signal = hobj.connect('active-changed', self.goto_active)
self.mru_signal = hobj.connect('mru-changed', self.update_mru_menu)
self.update_mru_menu(hobj.mru)
self.update_mru_menu(hobj.mru, update_menu=False)
self.goto_active(None)
@@ -199,8 +196,10 @@ class NavigationView(PageView):
self.goto_handle(active_handle)
hobj = self.get_history()
self.fwd_action.set_sensitive(not hobj.at_end())
self.back_action.set_sensitive(not hobj.at_front())
self.uimanager.set_actions_sensitive(self.fwd_action,
not hobj.at_end())
self.uimanager.set_actions_sensitive(self.back_action,
not hobj.at_front())
def get_active(self):
"""
@@ -238,7 +237,7 @@ class NavigationView(PageView):
####################################################################
# BOOKMARKS
####################################################################
def add_bookmark(self, obj):
def add_bookmark(self, *obj):
"""
Add a bookmark to the list.
"""
@@ -259,7 +258,7 @@ class NavigationView(PageView):
"no one was selected."),
parent=self.uistate.window)
def edit_bookmarks(self, obj):
def edit_bookmarks(self, *obj):
"""
Call the bookmark editor.
"""
@@ -271,12 +270,8 @@ class NavigationView(PageView):
"""
self.book_action = ActionGroup(name=self.title + '/Bookmark')
self.book_action.add_actions([
('AddBook', 'gramps-bookmark-new', _('_Add Bookmark'),
'<PRIMARY>d', None, self.add_bookmark),
('EditBook', 'gramps-bookmark-edit',
_("%(title)s...") % {'title': _("Organize Bookmarks")},
'<shift><PRIMARY>D', None,
self.edit_bookmarks),
('AddBook', self.add_bookmark, '<PRIMARY>d'),
('EditBook', self.edit_bookmarks, '<shift><PRIMARY>D'),
])
self._add_action_group(self.book_action)
@@ -290,35 +285,25 @@ class NavigationView(PageView):
"""
# add the Forward action group to handle the Forward button
self.fwd_action = ActionGroup(name=self.title + '/Forward')
self.fwd_action.add_actions([
('Forward', 'go-next', _("_Forward"),
"%sRight" % mod_key(), _("Go to the next object in the history"),
self.fwd_clicked)
])
self.fwd_action.add_actions([('Forward', self.fwd_clicked,
"%sRight" % mod_key())])
# add the Backward action group to handle the Forward button
self.back_action = ActionGroup(name=self.title + '/Backward')
self.back_action.add_actions([
('Back', 'go-previous', _("_Back"),
"%sLeft" % mod_key(), _("Go to the previous object in the history"),
self.back_clicked)
])
self.back_action.add_actions([('Back', self.back_clicked,
"%sLeft" % mod_key())])
self._add_action('HomePerson', 'go-home', _("_Home"),
accel="%sHome" % mod_key(),
tip=_("Go to the default person"), callback=self.home)
self._add_action('HomePerson', self.home, "%sHome" % mod_key())
self.other_action = ActionGroup(name=self.title + '/PersonOther')
self.other_action.add_actions([
('SetActive', 'go-home', _("Set _Home Person"), None,
None, self.set_default_person),
])
('SetActive', self.set_default_person)])
self._add_action_group(self.back_action)
self._add_action_group(self.fwd_action)
self._add_action_group(self.other_action)
def set_default_person(self, obj):
def set_default_person(self, *obj):
"""
Set the default person.
"""
@@ -326,7 +311,7 @@ class NavigationView(PageView):
if active:
self.dbstate.db.set_default_person_handle(active)
def home(self, obj):
def home(self, *obj):
"""
Move to the default person.
"""
@@ -342,7 +327,7 @@ class NavigationView(PageView):
"via the menu Edit ->Set Home Person."),
parent=self.uistate.window)
def jump(self):
def jump(self, *obj):
"""
A dialog to move to a Gramps ID entered by the user.
"""
@@ -383,7 +368,7 @@ class NavigationView(PageView):
"""
pass
def fwd_clicked(self, obj):
def fwd_clicked(self, *obj):
"""
Move forward one object in the history.
"""
@@ -392,11 +377,12 @@ class NavigationView(PageView):
if not hobj.at_end():
hobj.forward()
self.uistate.modify_statusbar(self.dbstate)
self.fwd_action.set_sensitive(not hobj.at_end())
self.back_action.set_sensitive(True)
self.uimanager.set_actions_sensitive(self.fwd_action,
not hobj.at_end())
self.uimanager.set_actions_sensitive(self.back_action, True)
hobj.lock = False
def back_clicked(self, obj):
def back_clicked(self, *obj):
"""
Move backward one object in the history.
"""
@@ -405,8 +391,9 @@ class NavigationView(PageView):
if not hobj.at_front():
hobj.back()
self.uistate.modify_statusbar(self.dbstate)
self.back_action.set_sensitive(not hobj.at_front())
self.fwd_action.set_sensitive(True)
self.uimanager.set_actions_sensitive(self.back_action,
not hobj.at_front())
self.uimanager.set_actions_sensitive(self.fwd_action, True)
hobj.lock = False
####################################################################
@@ -418,44 +405,52 @@ class NavigationView(PageView):
Remove the UI and action groups for the MRU list.
"""
if self.mru_active != DISABLED:
self.uistate.uimanager.remove_ui(self.mru_active)
self.uistate.uimanager.remove_action_group(self.mru_action)
self.uimanager.remove_ui(self.mru_active)
self.uimanager.remove_action_group(self.mru_action)
self.mru_active = DISABLED
def mru_enable(self):
def mru_enable(self, update_menu=False):
"""
Enables the UI and action groups for the MRU list.
"""
if self.mru_active == DISABLED:
self.uistate.uimanager.insert_action_group(self.mru_action, 1)
self.mru_active = self.uistate.uimanager.add_ui_from_string(self.mru_ui)
self.uistate.uimanager.ensure_update()
self.uimanager.insert_action_group(self.mru_action)
self.mru_active = self.uimanager.add_ui_from_string(self.mru_ui)
if update_menu:
self.uimanager.update_menu()
def update_mru_menu(self, items):
def update_mru_menu(self, items, update_menu=True):
"""
Builds the UI and action group for the MRU list.
"""
menuitem = ''' <item>
<attribute name="action">win.%s%02d</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
'''
menus = ''
self.mru_disable()
nav_type = self.navigation_type()
hobj = self.get_history()
menu_len = min(len(items) - 1, MRU_SIZE)
entry = '<menuitem action="%s%02d"/>'
data = [entry % (nav_type, index) for index in range(0, menu_len)]
self.mru_ui = "".join(MRU_TOP) + "".join(data) + "".join(MRU_BTM)
for index in range(0, menu_len):
name, obj = navigation_label(self.dbstate.db, nav_type,
items[index])
menus += menuitem % (nav_type, index, html.escape(name))
self.mru_ui = [MRU_TOP + menus + MRU_BTM]
mitems = items[-MRU_SIZE - 1:-1] # Ignore current handle
mitems.reverse()
data = []
for index, handle in enumerate(mitems):
name, obj = navigation_label(self.dbstate.db, nav_type, handle)
data.append(('%s%02d'%(nav_type, index), None, name,
"%s%d" % (mod_key(), index), None,
make_callback(hobj.push, handle)))
data.append(('%s%02d'%(nav_type, index),
make_callback(hobj.push, handle),
"%s%d" % (mod_key(), index)))
self.mru_action = ActionGroup(name=self.title + '/MRU')
self.mru_action.add_actions(data)
self.mru_enable()
self.mru_enable(update_menu)
####################################################################
# Template functions
@@ -503,4 +498,4 @@ def make_callback(func, handle):
"""
Generates a callback function based off the passed arguments
"""
return lambda x: func(handle)
return lambda x, y: func(handle)
+32 -49
View File
@@ -51,7 +51,7 @@ from ..dbguielement import DbGUIElement
from ..widgets.grampletbar import GrampletBar
from ..configure import ConfigureDialog
from gramps.gen.config import config
from ..actiongroup import ActionGroup
from ..uimanager import ActionGroup
#------------------------------------------------------------------------------
#
@@ -97,25 +97,24 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
self.uistate = uistate
self.action_list = []
self.action_toggle_list = []
self.action_toolmenu_list = []
self.action_toolmenu = {} #easy access to toolmenuaction and proxies
self.action_group = None
self.additional_action_groups = []
self.additional_uis = []
self.ui_def = '''<ui>
<menubar name="MenuBar">
<menu action="ViewMenu">
<placeholder name="Bars">
<menuitem action="Sidebar"/>
<menuitem action="Bottombar"/>
</placeholder>
</menu>
</menubar>
</ui>'''
self.ui_def = ['''
<placeholder id="Bars">
<item>
<attribute name="action">win.Sidebar</attribute>
<attribute name="label" translatable="yes">_Sidebar</attribute>
</item>
<item>
<attribute name="action">win.Bottombar</attribute>
<attribute name="label" translatable="yes">_Bottombar</attribute>
</item>
</placeholder>
''']
self.dirty = True
self.active = False
self._dirty_on_change_inactive = True
self.func_list = {}
if isinstance(self.pdata.category, tuple):
self.category, self.translated_category = self.pdata.category
@@ -201,24 +200,24 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
"""
self._config.set(setting, widget.get_position())
def __sidebar_toggled(self, action):
def __sidebar_toggled(self, action, value):
"""
Called when the sidebar is toggled.
"""
active = action.get_active()
if active:
action.set_state(value) # change GUI
if value.get_boolean():
self.sidebar.show()
self.sidebar_toggled(True)
else:
self.sidebar.hide()
self.sidebar_toggled(False)
def __bottombar_toggled(self, action):
def __bottombar_toggled(self, action, value):
"""
Called when the bottombar is toggled.
"""
active = action.get_active()
if active:
action.set_state(value) # change GUI
if value.get_boolean():
self.bottombar.show()
else:
self.bottombar.hide()
@@ -312,12 +311,6 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
return True
return False
def call_function(self, key):
"""
Calls the function associated with the key value
"""
self.func_list.get(key)()
def post(self):
"""
Called after a page is created.
@@ -332,6 +325,9 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
self.sidebar.set_active()
self.bottombar.set_active()
self.active = True
new_title = "%s - %s - Gramps" % (self.dbstate.db.get_dbname(),
self.get_title())
self.uistate.window.set_title(new_title)
if self.dirty:
self.uistate.set_busy_cursor(True)
self.build_tree()
@@ -370,14 +366,15 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
Turns off the visibility of the View's action group, if defined
"""
if self.action_group:
self.action_group.set_visible(False)
self.uistate.uimanager.set_actions_visible(self.action_group,
False)
def enable_action_group(self, obj):
"""
Turns on the visibility of the View's action group, if defined
"""
if self.action_group:
self.action_group.set_visible(True)
self.uistate.uimanager.set_actions_visible(self.action_group, True)
def get_stock(self):
"""
@@ -435,11 +432,9 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
View. The user typically defines self.action_list and
self.action_toggle_list in this function.
"""
self._add_toggle_action('Sidebar', None, _('_Sidebar'),
"<shift><PRIMARY>R", None, self.__sidebar_toggled,
self._add_toggle_action('Sidebar', self.__sidebar_toggled, '',
self.sidebar.get_property('visible'))
self._add_toggle_action('Bottombar', None, _('_Bottombar'),
"<shift><PRIMARY>B", None, self.__bottombar_toggled,
self._add_toggle_action('Bottombar', self.__bottombar_toggled, '',
self.bottombar.get_property('visible'))
def __build_action_group(self):
@@ -452,31 +447,19 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
if len(self.action_list) > 0:
self.action_group.add_actions(self.action_list)
if len(self.action_toggle_list) > 0:
self.action_group.add_toggle_actions(self.action_toggle_list)
self.action_group.add_actions(self.action_toggle_list)
def _add_action(self, name, icon_name, label, accel=None, tip=None,
callback=None):
def _add_action(self, name, callback=None, accel=None):
"""
Add an action to the action list for the current view.
"""
self.action_list.append((name, icon_name, label, accel, tip,
callback))
self.action_list.append((name, callback, accel))
def _add_toggle_action(self, name, icon_name, label, accel=None,
tip=None, callback=None, value=False):
def _add_toggle_action(self, name, callback=None, accel= None, value=False):
"""
Add a toggle action to the action list for the current view.
"""
self.action_toggle_list.append((name, icon_name, label, accel,
tip, callback, value))
def _add_toolmenu_action(self, name, label, tooltip, callback,
arrowtooltip):
"""
Add a menu action to the action list for the current view.
"""
self.action_toolmenu_list.append((name, label, tooltip, callback,
arrowtooltip))
self.action_toggle_list.append((name, callback, accel, value))
def get_actions(self):
"""
+80 -46
View File
@@ -50,7 +50,7 @@ from gramps.gen.const import URL_MANUAL_PAGE
from ..display import display_help
from ..dialog import ErrorDialog, QuestionDialog2
import gramps.gui.widgets.progressdialog as progressdlg
from ..actiongroup import ActionGroup
from ..uimanager import ActionGroup
from ..managedwindow import ManagedWindow
#-------------------------------------------------------------------------
@@ -58,29 +58,54 @@ from ..managedwindow import ManagedWindow
# Constants
#
#-------------------------------------------------------------------------
TAG_1 = '''<ui>
<menubar name="MenuBar">
<menu action="EditMenu">
<placeholder name="TagMenu">
<menu action="Tag">
'''
TAG_1 = '''
<section id='TagMenu' groups='RW'>
<submenu>
<attribute name="label" translatable="yes">Tag</attribute>
%s
</submenu>
</section>
'''
TAG_2 = '''
</menu>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="TagTool">
<toolitem action="TagButton"/>
TAG_2 = (
''' <placeholder id='TagTool' groups='RW'>
<child groups='RO'>
<object class="GtkToolButton" id="TagButton">
<property name="icon-name">gramps-tag</property>
<property name="action-name">win.TagButton</property>
<property name="tooltip_text" translatable="yes">'''
'''Tag selected rows</property>
<property name="label" translatable="yes">Tag</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
</toolbar>
<popup name="TagPopup">
'''
''')
TAG_3 = '''
</popup>
</ui>'''
<menu id='TagPopup' groups='RW'>
%s
</menu>'''
TAG_MENU = (
'''<section>
<item>
<attribute name="action">win.NewTag</attribute>
<attribute name="label" translatable="yes">'''
'''New Tag...</attribute>
</item>
<item>
<attribute name="action">win.OrganizeTags</attribute>
<attribute name="label" translatable="yes">'''
'''Organize Tags...</attribute>
</item>
</section>
<section>
%s
</section>
''')
WIKI_HELP_PAGE = '%s_-_Filters' % \
URL_MANUAL_PAGE
@@ -119,13 +144,14 @@ class Tags(DbGUIElement):
self._build_tag_menu()
def tag_enable(self):
def tag_enable(self, update_menu=True):
"""
Enables the UI and action groups for the tag menu.
"""
self.uistate.uimanager.insert_action_group(self.tag_action, 1)
self.uistate.uimanager.insert_action_group(self.tag_action)
self.tag_id = self.uistate.uimanager.add_ui_from_string(self.tag_ui)
self.uistate.uimanager.ensure_update()
if update_menu:
self.uistate.uimanager.update_menu()
def tag_disable(self):
"""
@@ -134,7 +160,6 @@ class Tags(DbGUIElement):
if self.tag_id is not None:
self.uistate.uimanager.remove_ui(self.tag_id)
self.uistate.uimanager.remove_action_group(self.tag_action)
self.uistate.uimanager.ensure_update()
self.tag_id = None
def _db_changed(self, db):
@@ -209,46 +234,55 @@ class Tags(DbGUIElement):
actions = []
if not self.dbstate.is_open():
self.tag_ui = ''
self.tag_ui = ['']
self.tag_action = ActionGroup(name='Tag')
return
tag_menu = '<menuitem action="NewTag"/>'
tag_menu += '<menuitem action="OrganizeTags"/>'
tag_menu += '<separator/>'
tag_menu = ''
menuitem = '''
<item>
<attribute name="action">win.TAG_%s</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>'''
for tag_name, handle in self.__tag_list:
tag_menu += '<menuitem action="TAG_%s"/>' % handle
actions.append(('TAG_%s' % handle, None, tag_name, None, None,
make_callback(self.tag_selected_rows, handle)))
tag_menu += menuitem % (handle, tag_name)
actions.append(('TAG_%s' % handle,
make_callback(self.tag_selected_rows, handle)))
tag_menu = TAG_MENU % tag_menu
self.tag_ui = TAG_1 + tag_menu + TAG_2 + tag_menu + TAG_3
self.tag_ui = [TAG_1 % tag_menu, TAG_2, TAG_3 % tag_menu]
actions.append(('Tag', 'gramps-tag', _('Tag'), None, None, None))
actions.append(('NewTag', 'gramps-tag-new', _('New Tag...'), None, None,
self.cb_new_tag))
actions.append(('OrganizeTags', None, _('Organize Tags...'), None, None,
self.cb_organize_tags))
actions.append(('TagButton', 'gramps-tag', _('Tag'), None,
_('Tag selected rows'), self.cb_tag_button))
actions.append(('NewTag', self.cb_new_tag))
actions.append(('OrganizeTags', self.cb_organize_tags))
actions.append(('TagButton', self.cb_tag_button))
self.tag_action = ActionGroup(name='Tag')
self.tag_action.add_actions(actions)
def cb_tag_button(self, action):
def cb_tag_button(self, *args):
"""
Display the popup menu when the toolbar button is clicked.
"""
menu = self.uistate.uimanager.get_widget('/TagPopup')
button = self.uistate.uimanager.get_widget('/ToolBar/TagTool/TagButton')
menu.popup(None, None, cb_menu_position, button, 0, 0)
menu = self.uistate.uimanager.get_widget('TagPopup')
button = self.uistate.uimanager.get_widget('TagButton')
popup_menu = Gtk.Menu.new_from_model(menu)
popup_menu.attach_to_widget(button, None)
popup_menu.show_all()
if Gtk.MINOR_VERSION < 22:
# ToDo The following is reported to work poorly with Wayland
popup_menu.popup(None, None, cb_menu_position, button, 0, 0)
else:
popup_menu.popup_at_widget(button, Gdk.Gravity.SOUTH,
Gdk.Gravity.NORTH_WEST, None)
def cb_organize_tags(self, action):
def cb_organize_tags(self, *action):
"""
Display the Organize Tags dialog.
"""
OrganizeTagsDialog(self.db, self.uistate, [])
def cb_new_tag(self, action):
def cb_new_tag(self, *action):
"""
Create a new tag and tag the selected objects.
"""
@@ -304,7 +338,7 @@ def make_callback(func, tag_handle):
"""
Generates a callback function based off the passed arguments
"""
return lambda x: func(tag_handle)
return lambda x, y: func(tag_handle)
#-------------------------------------------------------------------------
#
-4
View File
@@ -34,16 +34,12 @@ from .monitoredwidgets import *
from .selectionwidget import SelectionWidget, Region
from .shadebox import *
from .shortlistcomboentry import *
from .springseparator import *
from .statusbar import Statusbar
from .styledtextbuffer import *
from .styledtexteditor import *
from .toolcomboentry import *
from .undoablebuffer import *
from .undoableentry import *
from .undoablestyledbuffer import *
from .validatedcomboentry import *
from .validatedmaskedentry import *
from .valueaction import *
from .valuetoolitem import *
from .placewithin import *
+65 -1
View File
@@ -142,6 +142,7 @@ class GrampletBar(Gtk.Notebook):
self.set_current_page(config_settings[1])
uistate.connect('grampletbar-close-changed', self.cb_close_changed)
uistate.connect('grampletbar-freeze-changed', self.cb_freeze_changed)
# Connect after gramplets added to prevent making them active
self.connect('switch-page', self.__switch_page)
@@ -389,6 +390,11 @@ class GrampletBar(Gtk.Notebook):
else: # just a function; always show yes it has data
tablabel.set_has_data(True)
if config.get('interface.grampletbar-freeze'):
tablabel.use_freeze(True)
else:
tablabel.use_freeze(False)
if config.get('interface.grampletbar-close'):
tablabel.use_close(True)
else:
@@ -404,6 +410,14 @@ class GrampletBar(Gtk.Notebook):
tablabel = self.get_tab_label(gramplet)
tablabel.use_close(config.get('interface.grampletbar-close'))
def cb_freeze_changed(self):
"""
Freeze/unfreeze button preference changed.
"""
for gramplet in self.get_children():
tablabel = self.get_tab_label(gramplet)
tablabel.use_freeze(config.get('interface.grampletbar-freeze'))
def __delete_clicked(self, button, gramplet):
"""
Called when the delete button is clicked.
@@ -476,6 +490,16 @@ class GrampletBar(Gtk.Notebook):
gramplet.detached_window.close()
gramplet.detached_window = None
def __freeze_clicked(self, button):
"""
Called when the freeze/unfreeze button is clicked.
"""
for gramplet in self.get_children():
if gramplet and gramplet.pui:
if gramplet.pui.active:
if not self.freeze:
gramplet.pui.main()
def __button_clicked(self, button):
"""
Called when the drop-down button is clicked.
@@ -601,6 +625,7 @@ class TabGramplet(Gtk.ScrolledWindow, GuiGramplet):
self.add(self.textview)
self.show_all()
self.track = []
self.pane = pane
def get_title(self):
return self.title
@@ -721,6 +746,11 @@ class TabLabel(Gtk.Box):
self.label.set_tooltip_text(gramplet.tname)
self.label.show()
self.freezebtn = Gtk.ToggleButton()
self.freezebtn.connect("toggled", self.update_freeze, gramplet)
self.freezebtn.set_active(False)
self.update_freeze(self.freezebtn, gramplet)
self.closebtn = Gtk.Button()
image = Gtk.Image()
image.set_from_icon_name('window-close', Gtk.IconSize.MENU)
@@ -729,6 +759,7 @@ class TabLabel(Gtk.Box):
self.closebtn.set_relief(Gtk.ReliefStyle.NONE)
self.pack_start(self.label, True, True, 0)
self.pack_start(self.freezebtn, False, False, 0)
self.pack_end(self.closebtn, False, False, 0)
def set_has_data(self, has_data):
@@ -741,9 +772,42 @@ class TabLabel(Gtk.Box):
else:
self.label.set_text(self.text)
def update_freeze(self, obj, gramplet):
"""
Display the correct icon for the button according to user
gramplet preference.
"""
child = obj.get_child()
if child:
obj.remove(child)
image = Gtk.Image()
if obj.get_active():
image.set_from_icon_name('gramps-lock', Gtk.IconSize.MENU)
obj.set_tooltip_text(_('Gramplet update is freezed'))
else:
image.set_from_icon_name('gramps-unlock', Gtk.IconSize.MENU)
obj.set_tooltip_text(_('Gramplet update is allowed'))
image.show()
obj.add(image)
def get_freeze(self):
"""
return the freeze button
"""
return self.freezebtn
def use_freeze(self, use_freeze):
"""
Display the close button according to user preference.
"""
if use_freeze:
self.freezebtn.show()
else:
self.freezebtn.hide()
def use_close(self, use_close):
"""
Display the cose button according to user preference.
Display the close button according to user preference.
"""
if use_close:
self.closebtn.show()
+75 -34
View File
@@ -49,7 +49,7 @@ from gramps.gen.const import URL_MANUAL_PAGE, VERSION_DIR, COLON
from ..editors import EditPerson, EditFamily
from ..managedwindow import ManagedWindow
from ..utils import is_right_click, match_primary_mask, get_link_color
from .menuitem import add_menuitem
from ..uimanager import ActionGroup
from ..plug import make_gui_option
from ..plug.quick import run_quick_report_by_name
from ..display import display_help, display_url
@@ -189,6 +189,13 @@ def logical_true(value):
"""
return value in ["True", True, 1, "1"]
def make_callback(func, arg):
"""
Generates a callback function based off the passed arguments
"""
return lambda x, y: func(arg)
class LinkTag(Gtk.TextTag):
"""
Class for keeping track of link data.
@@ -999,6 +1006,8 @@ class GrampletPane(Gtk.ScrolledWindow):
self.pageview = pageview
self.pane = self
self._popup_xy = None
self.at_popup_action = None
self.at_popup_menu = None
user_gramplets = self.load_gramplets()
# build the GUI:
msg = _("Right click to add gramplets")
@@ -1349,8 +1358,7 @@ class GrampletPane(Gtk.ScrolledWindow):
self.place_gramplets(recolumn=True)
self.show()
def restore_gramplet(self, obj):
name = obj.get_child().get_label()
def restore_gramplet(self, name):
############### First kind: from current session
for gramplet in self.closed_gramplets:
if gramplet.title == name:
@@ -1392,8 +1400,7 @@ class GrampletPane(Gtk.ScrolledWindow):
else:
self.drop_widget(self, gramplet, 0, 0, 0)
def add_gramplet(self, obj):
tname = obj.get_child().get_label()
def add_gramplet(self, tname):
all_opts = get_gramplet_options_by_tname(tname)
name = all_opts["name"]
if all_opts is None:
@@ -1437,39 +1444,73 @@ class GrampletPane(Gtk.ScrolledWindow):
LOG.warning("Can't make gramplet of type '%s'.", name)
def _button_press(self, obj, event):
ui_def = (
''' <menu id="Popup">
<submenu>
<attribute name="action">win.AddGramplet</attribute>
<attribute name="label" translatable="yes">Add a gramplet</attribute>
%s
</submenu>
<submenu>
<attribute name="action">win.RestoreGramplet</attribute>
<attribute name="label" translatable="yes">'''
'''Restore a gramplet</attribute>
%s
</submenu>
</menu>
''')
menuitem = ('<item>\n'
'<attribute name="action">win.%s</attribute>\n'
'<attribute name="label" translatable="yes">'
'%s</attribute>\n'
'</item>\n')
if is_right_click(event):
self._popup_xy = (event.x, event.y)
uiman = self.uistate.uimanager
ag_menu = uiman.get_widget('/GrampletPopup/AddGramplet')
if ag_menu:
qr_menu = ag_menu.get_submenu()
qr_menu = Gtk.Menu()
names = [gplug.name for gplug in PLUGMAN.get_reg_gramplets()
if gplug.navtypes == []
or 'Dashboard' in gplug.navtypes]
names.sort()
actions = []
r_menuitems = ''
a_menuitems = ''
names = [gplug.name for gplug in PLUGMAN.get_reg_gramplets()
if gplug.navtypes == []
or 'Dashboard' in gplug.navtypes]
names.sort()
for name in names:
action_name = name.replace(' ', '-')
a_menuitems += menuitem % (action_name, name)
actions.append((action_name,
make_callback(self.add_gramplet, name)))
names = [gramplet.title for gramplet in self.closed_gramplets]
names.extend(opts["title"] for opts in self.closed_opts)
names.sort()
if len(names) > 0:
for name in names:
add_menuitem(qr_menu, name, None,
self.add_gramplet)
ag_menu.set_submenu(qr_menu)
rg_menu = uiman.get_widget('/GrampletPopup/RestoreGramplet')
if rg_menu:
qr_menu = rg_menu.get_submenu()
if qr_menu is not None:
rg_menu.set_submenu(None)
names = [gramplet.title for gramplet in self.closed_gramplets]
names.extend(opts["title"] for opts in self.closed_opts)
names.sort()
if len(names) > 0:
qr_menu = Gtk.Menu()
for name in names:
add_menuitem(qr_menu, name, None,
self.restore_gramplet)
rg_menu.set_submenu(qr_menu)
self.menu = uiman.get_widget('/GrampletPopup')
if self.menu:
#GTK3 does not show the popup, workaround: menu as attribute
self.menu.popup(None, None, None, None, event.button, event.time)
action_name = name.replace(' ', '-')
r_menuitems += menuitem % (action_name, name)
actions.append((action_name,
make_callback(self.restore_gramplet,
name)))
if self.at_popup_action:
uiman.remove_ui(self.at_popup_menu)
uiman.remove_action_group(self.at_popup_action)
self.at_popup_action = ActionGroup('AtPopupActions',
actions)
uiman.insert_action_group(self.at_popup_action)
self.at_popup_menu = uiman.add_ui_from_string([
ui_def % (a_menuitems, r_menuitems)])
uiman.update_menu()
menu = uiman.get_widget('Popup')
popup_menu = Gtk.Menu.new_from_model(menu)
popup_menu.attach_to_widget(obj, None)
popup_menu.show_all()
if Gtk.MINOR_VERSION < 22:
# ToDo The following is reported to work poorly with Wayland
popup_menu.popup(None, None, None, None,
event.button, event.time)
else:
popup_menu.popup_at_pointer(event)
return True
return False
+4 -1
View File
@@ -70,7 +70,10 @@ class ShortlistComboEntry(ValidatedComboEntry):
"""
__gtype_name__ = "ShortlistComboEntry"
def __init__(self, items, shortlist=True, validator=None):
def __init__(self):
pass
def init(self, items, shortlist=True, validator=None):
if not items:
raise ValueError
-76
View File
@@ -1,76 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Zsolt Foldvari
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
"Separator classes used for Toolbar."
__all__ = ["SpringSeparatorAction", "SpringSeparatorToolItem"]
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import logging
_LOG = logging.getLogger(".widgets.springseparator")
#-------------------------------------------------------------------------
#
# GTK modules
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# SpringSeparatorToolItem class
#
#-------------------------------------------------------------------------
class SpringSeparatorToolItem(Gtk.SeparatorToolItem):
"""Custom separator toolitem.
Its only purpose is to push following tool items to the right end
of the toolbar.
"""
__gtype_name__ = "SpringSeparatorToolItem"
def __init__(self):
Gtk.SeparatorToolItem.__init__(self)
self.set_draw(False)
self.set_expand(True)
#-------------------------------------------------------------------------
#
# SpringSeparatorAction class
#
#-------------------------------------------------------------------------
class SpringSeparatorAction(Gtk.Action):
"""Custom Action to hold a SpringSeparatorToolItem."""
__gtype_name__ = "SpringSeparatorAction"
def __init__(self, name, label, tooltip, stock_id):
Gtk.Action.__init__(self, name=name, label=label,
tooltip=tooltip, stock_id=stock_id)
## TODO GTK3, How to connect these? Used in styledtexteditor
##SpringSeparatorToolItem.set_related_action(SpringSeparatorAction)
##deprecated: SpringSeparatorAction.set_tool_item_type(SpringSeparatorToolItem)
+236 -183
View File
@@ -43,6 +43,8 @@ from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import Gtk
from gi.repository import Pango
from gi.repository.Gio import SimpleActionGroup
from gi.repository.GLib import Variant
#-------------------------------------------------------------------------
#
@@ -55,15 +57,12 @@ from .styledtextbuffer import (ALLOWED_STYLES,
MATCH_FLAVOR, MATCH_STRING,
LinkTag)
from .undoablestyledbuffer import UndoableStyledBuffer
from .valueaction import ValueAction
from .toolcomboentry import ToolComboEntry
from .springseparator import SpringSeparatorAction
from ..spell import Spell
from ..display import display_url
from ..utils import SystemFonts, match_primary_mask, get_link_color
from gramps.gen.config import config
from gramps.gen.constfunc import has_display, mac
from ..actiongroup import ActionGroup
from ..uimanager import ActionGroup
#-------------------------------------------------------------------------
#
@@ -75,33 +74,141 @@ if has_display():
HAND_CURSOR = Gdk.Cursor.new_for_display(display, Gdk.CursorType.HAND2)
REGULAR_CURSOR = Gdk.Cursor.new_for_display(display, Gdk.CursorType.XTERM)
FORMAT_TOOLBAR = '''
<ui>
<toolbar name="ToolBar">
<toolitem action="%d"/>
<toolitem action="%d"/>
<toolitem action="%d"/>
<toolitem action="%d"/>
<toolitem action="%d"/>
<toolitem action="Undo"/>
<toolitem action="Redo"/>
<toolitem action="%d"/>
<toolitem action="%d"/>
<toolitem action="%d"/>
<toolitem action="spring"/>
<toolitem action="clear"/>
</toolbar>
</ui>
''' % (StyledTextTagType.ITALIC,
StyledTextTagType.BOLD,
StyledTextTagType.UNDERLINE,
StyledTextTagType.FONTFACE,
StyledTextTagType.FONTSIZE,
StyledTextTagType.FONTCOLOR,
StyledTextTagType.HIGHLIGHT,
StyledTextTagType.LINK,
)
FORMAT_TOOLBAR = (
'''<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkToolbar" id="ToolBar">
<property name="hexpand">True</property>
<property name="toolbar-style">GTK_TOOLBAR_ICONS</property>
<style>
<class name="primary-toolbar"/>
</style>
<child>
<object class="GtkToggleToolButton">
<property name="icon-name">format-text-italic</property>
<property name="action-name">ste.ITALIC</property>
<property name="tooltip_text" translatable="yes">Italic</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="icon-name">format-text-bold</property>
<property name="action-name">ste.BOLD</property>
<property name="tooltip_text" translatable="yes">Bold</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="icon-name">format-text-underline</property>
<property name="action-name">ste.UNDERLINE</property>
<property name="tooltip_text" translatable="yes">Underline</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToolItem">
<property name="tooltip_text" translatable="yes">Font family</property>
<child>
<object class="ShortlistComboEntry" id="Fontface"></object>
</child>
</object>
</child>
<child>
<object class="GtkToolItem">
<property name="tooltip_text" translatable="yes">Font size</property>
<child>
<object class="ShortlistComboEntry" id="Fontsize"></object>
</child>
</object>
</child>
<child>
<object class="GtkToolButton">
<property name="icon-name">edit-undo</property>
<property name="action-name">ste.STUndo</property>
<property name="tooltip_text" translatable="yes">Undo</property>
<property name="label" translatable="yes">Undo</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="icon-name">edit-redo</property>
<property name="action-name">ste.STRedo</property>
<property name="tooltip_text" translatable="yes">Redo</property>
<property name="label" translatable="yes">Redo</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="icon-name">gramps-font-color</property>
<property name="action-name">ste.FONTCOLOR</property>
<property name="tooltip_text" translatable="yes">Font Color</property>
<property name="label" translatable="yes">Font Color</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="icon-name">gramps-font-bgcolor</property>
<property name="action-name">ste.HIGHLIGHT</property>
<property name="tooltip_text" translatable="yes">'''
'''Background Color</property>
<property name="label" translatable="yes">Background Color</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="icon-name">go-jump</property>
<property name="action-name">ste.LINK</property>
<property name="tooltip_text" translatable="yes">Link</property>
<property name="label" translatable="yes">Link</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem">
<property name="draw">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="icon-name">edit-clear</property>
<property name="action-name">ste.CLEAR</property>
<property name="tooltip_text" translatable="yes">'''
'''Clear Markup</property>
<property name="label" translatable="yes">Clear Markup</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</object>
</interface>
''')
FONT_SIZES = [8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22,
24, 26, 28, 32, 36, 40, 48, 56, 64, 72]
@@ -182,6 +289,7 @@ class StyledTextEditor(Gtk.TextView):
self.undo_disabled = self.textbuffer.undo_disabled # see bug 7097
self.textbuffer.connect('style-changed', self._on_buffer_style_changed)
self.textbuffer.connect('changed', self._on_buffer_changed)
self.undo_action = self.redo_action = None
Gtk.TextView.__init__(self)
self.set_buffer(self.textbuffer)
@@ -194,9 +302,9 @@ class StyledTextEditor(Gtk.TextView):
self._init_url_match()
self.url_match = None
self.toolbar = self._create_toolbar()
self.spellcheck = Spell(self)
self._internal_style_change = False
self.uimanager = None
self._connect_signals()
@@ -236,30 +344,6 @@ class StyledTextEditor(Gtk.TextView):
window.set_cursor(REGULAR_CURSOR)
self.url_match = None
def on_key_press_event(self, widget, event):
"""Signal handler.
Handle formatting shortcuts.
"""
if ((Gdk.keyval_name(event.keyval) == 'Z') and
match_primary_mask(event.get_state(), Gdk.ModifierType.SHIFT_MASK)):
self.redo()
return True
elif ((Gdk.keyval_name(event.keyval) == 'z') and
match_primary_mask(event.get_state())):
self.undo()
return True
else:
for accel, accel_name in self.action_accels.items():
key, mod = Gtk.accelerator_parse(accel)
if ((event.keyval == key) and (event.get_state() & mod)):
action_name = accel_name
action = self.action_group.get_action(action_name)
action.activate()
return True
return False
def on_insert_at_cursor(self, widget, string):
"""Signal handler. for debugging only."""
_LOG.debug("Textview insert '%s'" % string)
@@ -423,14 +507,13 @@ class StyledTextEditor(Gtk.TextView):
Reset the undoable buffer
"""
self.textbuffer.reset()
self.undo_action.set_sensitive(False)
self.redo_action.set_sensitive(False)
self.undo_action.set_enabled(False)
self.redo_action.set_enabled(False)
# private methods
def _connect_signals(self):
"""Connect to several signals of the super class Gtk.TextView."""
self.connect('key-press-event', self.on_key_press_event)
self.connect('insert-at-cursor', self.on_insert_at_cursor)
self.connect('delete-from-cursor', self.on_delete_from_cursor)
self.connect('paste-clipboard', self.on_paste_clipboard)
@@ -439,104 +522,74 @@ class StyledTextEditor(Gtk.TextView):
self.connect('button-release-event', self.on_button_release_event)
self.connect('populate-popup', self.on_populate_popup)
def _create_toolbar(self):
def create_toolbar(self, uimanager, window):
"""
Create a formatting toolbar.
:returns: toolbar containing text formatting toolitems.
:rtype: Gtk.Toolbar
"""
self.uimanager = uimanager
# build the toolbar
builder = Gtk.Builder.new_from_string(FORMAT_TOOLBAR, -1)
# define the actions...
# ...first the toggle actions, which have a ToggleToolButton as proxy
format_toggle_actions = [
(str(StyledTextTagType.ITALIC), 'format-text-italic', None, None,
_('Italic'), self._on_toggle_action_activate),
(str(StyledTextTagType.BOLD), 'format-text-bold', None, None,
_('Bold'), self._on_toggle_action_activate),
(str(StyledTextTagType.UNDERLINE), 'format-text-underline', None,
None, _('Underline'), self._on_toggle_action_activate),
_actions = [
('ITALIC', self._on_toggle_action_activate, '<PRIMARY>i', False),
('BOLD', self._on_toggle_action_activate, '<PRIMARY>b', False),
('UNDERLINE', self._on_toggle_action_activate, '<PRIMARY>u',
False),
('FONTCOLOR', self._on_action_activate),
('HIGHLIGHT', self._on_action_activate),
('LINK', self._on_link_activate),
('CLEAR', self._format_clear_cb),
('STUndo', self.undo, '<primary>z'),
('STRedo', self.redo, '<primary><shift>z'),
]
self.toggle_actions = [action[0] for action in format_toggle_actions]
# ...then the normal actions, which have a ToolButton as proxy
format_actions = [
(str(StyledTextTagType.FONTCOLOR), 'gramps-font-color',
_('Font Color'), None, _('Font Color'), self._on_action_activate),
(str(StyledTextTagType.HIGHLIGHT), 'gramps-font-bgcolor',
_('Background Color'), None, _('Background Color'),
self._on_action_activate),
(str(StyledTextTagType.LINK), 'go-jump', _('Link'), None,
_('Link'), self._on_link_activate),
('clear', 'edit-clear', _('Clear Markup'), None,
_('Clear Markup'), self._format_clear_cb),
]
# ...last the custom actions, which have custom proxies
default = StyledTextTagType.STYLE_DEFAULT[StyledTextTagType.FONTFACE]
# the following are done manually rather than using actions
fonts = SystemFonts()
fontface_action = ValueAction(str(StyledTextTagType.FONTFACE),
_("Font family"),
default,
ToolComboEntry,
fonts.get_system_fonts(),
False, #editable
True, #shortlist
None) # validator
fontface_action.connect('changed', self._on_valueaction_changed)
fontface = builder.get_object('Fontface')
fontface.init(fonts.get_system_fonts(), shortlist=True, validator=None)
fontface.set_entry_editable(False)
fontface.connect('changed', make_cb(
self._on_valueaction_changed, StyledTextTagType.FONTFACE))
# set initial value
default = StyledTextTagType.STYLE_DEFAULT[StyledTextTagType.FONTFACE]
self.fontface = fontface.get_child()
self.fontface.set_text(str(default))
fontface.show()
items = FONT_SIZES
fontsize = builder.get_object('Fontsize')
fontsize.init(items, shortlist=False, validator=is_valid_fontsize)
fontsize.set_entry_editable(True)
fontsize.connect('changed', make_cb(
self._on_valueaction_changed, StyledTextTagType.FONTSIZE))
# set initial value
default = StyledTextTagType.STYLE_DEFAULT[StyledTextTagType.FONTSIZE]
fontsize_action = ValueAction(str(StyledTextTagType.FONTSIZE),
_("Font size"),
default,
ToolComboEntry,
items,
True, #editable
False, #shortlist
is_valid_fontsize) #validator
fontsize_action.connect('changed', self._on_valueaction_changed)
spring = SpringSeparatorAction("spring", "", "", None)
# action accelerators
self.action_accels = {
'<PRIMARY>i': str(StyledTextTagType.ITALIC),
'<PRIMARY>b': str(StyledTextTagType.BOLD),
'<PRIMARY>u': str(StyledTextTagType.UNDERLINE),
}
self.fontsize = fontsize.get_child()
self.fontsize.set_text(str(default))
fontsize.show()
# create the action group and insert all the actions
self.action_group = ActionGroup(name='Format')
self.action_group.add_toggle_actions(format_toggle_actions)
self.undo_action = Gtk.Action(name="Undo", label=_('Undo'),
tooltip=_('Undo'))
self.undo_action.set_icon_name('edit-undo')
self.undo_action.connect('activate', self.undo)
self.redo_action = Gtk.Action.new(name="Redo", label=_('Redo'),
tooltip=_('Redo'))
self.redo_action.set_icon_name('edit-redo')
self.redo_action.connect('activate', self.redo)
self.action_group.add_action(self.undo_action)
self.action_group.add_action(self.redo_action)
self.action_group.add_actions(format_actions)
self.action_group.add_action(fontface_action)
self.action_group.add_action(fontsize_action)
self.action_group.add_action(spring)
self.action_group = ActionGroup('Format', _actions, 'ste')
act_grp = SimpleActionGroup()
window.insert_action_group('ste', act_grp)
window.set_application(uimanager.app)
uimanager.insert_action_group(self.action_group, act_grp)
# define the toolbar and create the proxies via ensure_update()
uimanager = Gtk.UIManager()
uimanager.insert_action_group(self.action_group, 0)
uimanager.add_ui_from_string(FORMAT_TOOLBAR)
uimanager.ensure_update()
self.undo_action = uimanager.get_action(self.action_group, "STUndo")
self.redo_action = uimanager.get_action(self.action_group, "STRedo")
# allow undo/redo to see actions if editable.
self.textbuffer.connect('changed', self._on_buffer_changed)
# undo/redo are initially greyed out, until something is changed
self.undo_action.set_enabled(False)
self.redo_action.set_enabled(False)
# get the toolbar and set it's style
toolbar = uimanager.get_widget('/ToolBar')
toolbar.set_style(Gtk.ToolbarStyle.ICONS)
self.undo_action.set_sensitive(False)
self.redo_action.set_sensitive(False)
toolbar = builder.get_object('ToolBar')
return toolbar
return toolbar, self.action_group
def set_transient_parent(self, parent=None):
self.transient_parent = parent
@@ -582,21 +635,22 @@ class StyledTextEditor(Gtk.TextView):
# Callback functions
def _on_toggle_action_activate(self, action):
def _on_toggle_action_activate(self, action, value):
"""
Toggle a style.
Toggle styles are e.g. 'bold', 'italic', 'underline'.
"""
action.set_state(value)
if self._internal_style_change:
return
style = int(action.get_name())
value = action.get_active()
_LOG.debug("applying style '%d' with value '%s'" % (style, str(value)))
self.textbuffer.apply_style(style, value)
style = action.get_name()
value = value.get_boolean()
_LOG.debug("applying style '%s' with value '%s'" % (style, str(value)))
self.textbuffer.apply_style(getattr(StyledTextTagType, style), value)
def _on_link_activate(self, action):
def _on_link_activate(self, action, value):
"""
Create a link of a selected region of text.
"""
@@ -633,10 +687,9 @@ class StyledTextEditor(Gtk.TextView):
else:
tag.data = uri
def _on_action_activate(self, action):
def _on_action_activate(self, action, value):
"""Apply a format set from a Gtk.Action type of action."""
style = int(action.get_name())
style = getattr(StyledTextTagType, action.get_name())
current_value = self.textbuffer.get_style_at_cursor(style)
if style == StyledTextTagType.FONTCOLOR:
@@ -668,14 +721,12 @@ class StyledTextEditor(Gtk.TextView):
(style, str(value)))
self.textbuffer.apply_style(style, value)
def _on_valueaction_changed(self, action):
"""Apply a format set by a ValueAction type of action."""
def _on_valueaction_changed(self, obj, style):
"""Apply a format set by a ShortListComboEntry."""
if self._internal_style_change:
return
style = int(action.get_name())
value = action.get_value()
value = obj.get_active_data()
try:
value = StyledTextTagType.STYLE_TYPE[style](value)
_LOG.debug("applying style '%d' with value '%s'" %
@@ -685,7 +736,7 @@ class StyledTextEditor(Gtk.TextView):
_LOG.debug("unable to convert '%s' to '%s'" %
(value, StyledTextTagType.STYLE_TYPE[style]))
def _format_clear_cb(self, action):
def _format_clear_cb(self, action, value):
"""
Remove all formats from the selection or from all.
@@ -709,24 +760,27 @@ class StyledTextEditor(Gtk.TextView):
def _on_buffer_changed(self, buffer):
"""synchronize the undo/redo buttons with what is possible"""
self.undo_action.set_sensitive(self.textbuffer.can_undo)
self.redo_action.set_sensitive(self.textbuffer.can_redo)
if self.undo_action:
self.undo_action.set_enabled(self.textbuffer.can_undo)
self.redo_action.set_enabled(self.textbuffer.can_redo)
def _on_buffer_style_changed(self, buffer, changed_styles):
"""Synchronize actions as the format changes at the buffer's cursor."""
if not self.uimanager:
return # never initialized a toolbar, not editable
types = [StyledTextTagType.ITALIC, StyledTextTagType.BOLD,
StyledTextTagType.UNDERLINE]
self._internal_style_change = True
for style, style_value in changed_styles.items():
if str(style) in self.toggle_actions:
action = self.action_group.get_action(str(style))
self._internal_style_change = True
action.set_active(style_value)
self._internal_style_change = False
if ((style == StyledTextTagType.FONTFACE) or
(style == StyledTextTagType.FONTSIZE)):
action = self.action_group.get_action(str(style))
self._internal_style_change = True
action.set_value(style_value)
self._internal_style_change = False
if style in types:
action = self.uimanager.get_action(
self.action_group, str(StyledTextTagType(style)).upper())
action.change_state(Variant.new_boolean(style_value))
elif (style == StyledTextTagType.FONTFACE):
self.fontface.set_text(style_value)
elif style == StyledTextTagType.FONTSIZE:
self.fontsize.set_text(str(style_value))
self._internal_style_change = False
def _spell_change_cb(self, menuitem, spellcheck):
"""Set spell checker spellcheck according to user selection."""
@@ -818,20 +872,17 @@ class StyledTextEditor(Gtk.TextView):
start, end = self.textbuffer.get_bounds()
return self.textbuffer.get_text(start, end, True)
def get_toolbar(self):
"""
Get the formatting toolbar of the editor.
:returns: toolbar widget to use as formatting GUI.
:rtype: Gtk.Toolbar
"""
return self.toolbar
def undo(self, obj=None):
def undo(self, *obj):
self.textbuffer.undo()
def redo(self, obj=None):
def redo(self, *obj):
self.textbuffer.redo()
#-------------------------------------------------------------------------
#
# Module functions
#
#-------------------------------------------------------------------------
def uri_dialog(self, uri, callback):
"""
@@ -851,12 +902,14 @@ def uri_dialog(self, uri, callback):
uri = "gramps://%s/handle/%s" % (object_class, handle)
EditLink(obj.dbstate, obj.uistate, obj.track, uri, callback)
#-------------------------------------------------------------------------
#
# Module functions
#
#-------------------------------------------------------------------------
def is_valid_fontsize(size):
"""Validator function for font size selector widget."""
return (size > 0) and (size < 73)
def make_cb(func, value):
"""
Generates a callback function based off the passed arguments
"""
return lambda x: func(x, value)
-78
View File
@@ -1,78 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Zsolt Foldvari
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
"ToolComboEntry class."
__all__ = ["ToolComboEntry"]
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import logging
_LOG = logging.getLogger(".widgets.toolcomboentry")
#-------------------------------------------------------------------------
#
# GTK modules
#
#-------------------------------------------------------------------------
#from gi.repository import GObject
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
from .valuetoolitem import ValueToolItem
from .shortlistcomboentry import ShortlistComboEntry
#-------------------------------------------------------------------------
#
# ToolComboEntry class
#
#-------------------------------------------------------------------------
class ToolComboEntry(ValueToolItem):
"""Tool bar item containing a ShortlistComboEntry widget."""
__gtype_name__ = "ToolComboEntry"
def _create_widget(self, items, editable, shortlist=True, validator=None):
self.set_border_width(2)
self.set_homogeneous(False)
self.set_expand(False)
combo = ShortlistComboEntry(items, shortlist, validator)
if (Gtk.MAJOR_VERSION, Gtk.MINOR_VERSION) < (3, 20):
combo.set_focus_on_click(False)
else:
Gtk.Widget.set_focus_on_click(combo, False)
combo.set_entry_editable(editable)
combo.show()
self.add(combo)
combo.connect('changed', self._on_widget_changed)
def set_value(self, value):
self.get_child().set_active_data(value)
def get_value(self):
return self.get_child().get_active_data()
+5 -1
View File
@@ -65,7 +65,8 @@ class ValidatedComboEntry(Gtk.ComboBox):
__gtype_name__ = "ValidatedComboEntry"
def __init__(self, datatype, model=None, column=-1, validator=None, width=-1):
Gtk.ComboBox.__init__(self, model=model)
Gtk.ComboBox.__init__(self)
self.set_model(model)
self._entry = Gtk.Entry()
self._entry.set_width_chars(width)
@@ -201,6 +202,9 @@ class ValidatedComboEntry(Gtk.ComboBox):
self._internal_change = True
new_iter = self._is_in_model(new_data)
if new_iter is None:
if self.get_active_iter() is None:
# allows response when changing between two non-model values
self.set_active(0)
self.set_active(-1)
else:
self.set_active_iter(new_iter)
-169
View File
@@ -1,169 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Zsolt Foldvari
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
"ValueAction class."
__all__ = ["ValueAction"]
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import logging
_LOG = logging.getLogger(".widgets.valueaction")
#-------------------------------------------------------------------------
#
# GTK modules
#
#-------------------------------------------------------------------------
from gi.repository import GObject
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
from .valuetoolitem import ValueToolItem
#-------------------------------------------------------------------------
#
# ValueAction class
#
#-------------------------------------------------------------------------
class ValueAction(Gtk.Action):
"""
Value action class.
(A ValueAction with menu item doesn't make any sense.)
"""
__gtype_name__ = "ValueAction"
__gsignals__ = {
'changed': (GObject.SignalFlags.RUN_FIRST,
None, #return value
()), # arguments
}
def __init__(self, name, tooltip, default, itemtype, *args):
"""
Create a new ValueAction instance.
:param name: the name of the action
:type name: str
:param tooltip: tooltip string
:type tooltip: str
:param default: default value for the action, it will set the type of
the action and thus the type of all the connected
proxies.
:type default: set by itemtype
:param itemtype: default tool item class
:type itemtype: :class:`.ValueToolItem` subclass
:param args: arguments to be passed to the default toolitem class
at creation. see: :meth:`do_create_tool_item`
:type args: list
"""
Gtk.Action.__init__(self, name=name, label='', tooltip=tooltip,
stock_id=None)
self._value = default
self._data_type = type(default)
# have to be remembered, because we can't access
# GtkAction->toolbar_item_type later.
self._default_toolitem_type = itemtype
##TODO GTK3: following is deprecated, must be replaced by
## itemtype.set_related_action(ValueAction) in calling class?
## self.set_tool_item_type(itemtype)
self._args_for_toolitem = args
self._handlers = {}
def do_changed(self):
"""
Default signal handler for 'changed' signal.
Synchronize all the proxies with the active value.
"""
for proxy in self.get_proxies():
proxy.handler_block(self._handlers[proxy])
proxy.set_value(self._value)
proxy.handler_unblock(self._handlers[proxy])
def do_create_tool_item(self):
"""
Create a 'default' toolbar item widget.
Override the default method, to be able to pass the required
parameters to the proxy's constructor.
This method is called from Gtk.UIManager.ensure_update(), when a
'toolitem' is found in the UI definition with a name refering to a
ValueAction. Thus, to use the action via the UIManager a 'default'
toolitem type has to be set with the Gtk.Action.set_tool_item_type()
method, before invoking the Gtk.UIManager.ensure_update() method.
Widgets other than the default type has to be created and added
manually with the Gtk.Action.connect_proxy() method.
:returns: a toolbar item connected to the action.
:rtype: :class:`.ValueToolItem` subclass
"""
proxy = self._default_toolitem_type(self._data_type,
self._args_for_toolitem)
self.connect_proxy(proxy)
return proxy
def _on_proxy_changed(self, proxy):
"""Signal handler for the proxies' 'changed' signal."""
value = proxy.get_value()
if value is not None:
self.set_value(value)
def connect_proxy(self, proxy):
"""
Connect a widget to an action object as a proxy.
:param proxy: widget to be connected
:type proxy: :class:`.ValueToolItem` subclass
"""
if not isinstance(proxy, ValueToolItem):
raise TypeError
# do this before connecting, so that we don't call the handler
proxy.set_value(self._value)
self._handlers[proxy] = proxy.connect('changed', self._on_proxy_changed)
# if this is called the proxy will appear on the proxy list twice. why?
#Gtk.Action.connect_proxy(self, proxy)
def set_value(self, value):
"""Set value to action."""
if not isinstance(value, self._data_type):
raise TypeError
self._value = value
self.emit('changed')
def get_value(self):
"""Get the value from the action."""
return self._value
-92
View File
@@ -1,92 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Zsolt Foldvari
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
"ValueToolItem class."
__all__ = ["ValueToolItem"]
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import logging
_LOG = logging.getLogger(".widgets.valuetoolitem")
#-------------------------------------------------------------------------
#
# GTK modules
#
#-------------------------------------------------------------------------
from gi.repository import GObject
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# ValueToolItem class
#
#-------------------------------------------------------------------------
class ValueToolItem(Gtk.ToolItem):
"""ValueToolItem is an abstract toolbar proxy for ValueAction.
For each kind of widget a separete tool item proxy has to be
subclassed from this ValueToolItem.
"""
__gtype_name__ = "ValueToolItem"
__gsignals__ = {
'changed': (GObject.SignalFlags.RUN_FIRST,
None, #return value
()), # arguments
}
def __init__(self, data_type, args):
Gtk.ToolItem.__init__(self)
self._data_type = data_type
self._create_widget(*args)
def _on_widget_changed(self, widget):
self.emit('changed')
def _create_widget(self, args):
"""Create the apropriate widget for the actual proxy."""
raise NotImplementedError
def set_value(self, value):
"""Set new value for the proxied widget.
The method is responsible converting the data type between action and
widget.
"""
raise NotImplementedError
def get_value(self):
"""Get value from the proxied widget.
The method is responsible converting the data type between action and
widget.
"""
raise NotImplementedError
+1 -1
View File
@@ -27,7 +27,7 @@ plg.name = _("BSDDB")
plg.name_accell = _("_BSDDB Database")
plg.description = _("Berkeley Software Distribution Database Backend")
plg.version = '1.0'
plg.gramps_target_version = "5.0"
plg.gramps_target_version = "5.1"
plg.status = STABLE
plg.fname = 'bsddb.py'
plg.ptype = DATABASE
+1 -1
View File
@@ -27,7 +27,7 @@ register(DATABASE,
name_accell=_('_SQLite Database'),
description=_('SQLite Database'),
version='1.0.0',
gramps_target_version='5.0',
gramps_target_version='5.1',
status=STABLE,
fname='sqlite.py',
databaseclass='SQLite',
+1 -1
View File
@@ -21,7 +21,7 @@ from gramps.gen.plug._pluginreg import newplugin, STABLE
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
+1 -1
View File
@@ -22,7 +22,7 @@ from gramps.gen.plug._pluginreg import *
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
# this is the default in gen/plug/_pluginreg.py: plg.require_active = True
+6 -14
View File
@@ -421,7 +421,7 @@ class Extract:
if date:
year = date.get_year()
if year:
return [str(year)]
return [self._get_date(Date(year))] # localized year
return [_T_("Date(s) missing")]
def get_month(self, event):
@@ -672,6 +672,7 @@ class Extract:
self._locale = rlocale
self._ = rlocale.translation.sgettext
self._get_type = rlocale.get_type
self._get_date = rlocale.get_date
data = []
ext = self.extractors
@@ -788,21 +789,12 @@ class StatisticsChart(Report):
else:
genders = None
# needed for keyword based localization
mapping = {
'genders': genders,
'year_from': year_from,
'year_to': year_to
}
if genders:
span_string = self._("%(genders)s born "
"%(year_from)04d-%(year_to)04d"
) % mapping
span_string = self._("%s born") % genders
else:
span_string = self._("Persons born "
"%(year_from)04d-%(year_to)04d"
) % mapping
span_string = self._("Persons born")
span_string += " %s-%s" % (self._get_date(Date(year_from)), # localized
self._get_date(Date(year_to)))
people = self.filter.apply(self.database,
self.database.iter_person_handles(),
+1 -1
View File
@@ -21,7 +21,7 @@ from gramps.gen.plug._pluginreg import newplugin, STABLE, EXPORT
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
+2 -2
View File
@@ -24,7 +24,7 @@ from gramps.gen.plug._pluginreg import register, STABLE, UNSTABLE, GRAMPLET
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
@@ -1271,7 +1271,7 @@ register(GRAMPLET,
gramps_target_version=MODULE_VERSION,
status = UNSTABLE,
fname="leak.py",
height=200,
height=400,
gramplet = 'Leak',
gramplet_title="Uncollected Objects",
)
+105 -37
View File
@@ -23,7 +23,13 @@
"""
Show uncollected objects in a window.
"""
#------------------------------------------------------------------------
#
# Python modules
#
#------------------------------------------------------------------------
import weakref
import sys
#------------------------------------------------------------------------
#
# GNOME/GTK modules
@@ -40,10 +46,11 @@ import gc
#------------------------------------------------------------------------
from gramps.gen.plug import Gramplet
from gramps.gui.dialog import InfoDialog
from gramps.gui.utils import is_right_click
from gramps.gui.utils import is_right_click, ProgressMeter
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
#-------------------------------------------------------------------------
#
# Leak
@@ -58,7 +65,7 @@ class Leak(Gramplet):
self.gui.get_container_widget().remove(self.gui.textview)
self.gui.get_container_widget().add(self.gui.WIDGET)
flags = gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_SAVEALL
flags = gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_SAVEALL
if hasattr(gc, "DEBUG_OBJECTS"):
flags = flags | gc.DEBUG_OBJECTS
gc.set_debug(flags)
@@ -74,24 +81,27 @@ class Leak(Gramplet):
self.top.pack_start(self.label, False, False, 6)
self.scroll = Gtk.ScrolledWindow()
#add a listview to the scrollable
# add a listview to the scrollable
self.list = Gtk.TreeView()
self.list.set_headers_visible(True)
self.list.connect('button-press-event', self._button_press)
self.scroll.add(self.list)
#make a model
self.modeldata = []
self.model = Gtk.ListStore(int, str)
# make a model
self.model = Gtk.ListStore(int, str, str)
self.list.set_model(self.model)
#set the columns
# set the columns
self.renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(_('Number'), self.renderer, text=0)
column.set_resizable(True)
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
self.list.append_column(column)
column = Gtk.TreeViewColumn(_('Referrer'), self.renderer, text=1)
column.set_resizable(True)
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
self.list.append_column(column)
column = Gtk.TreeViewColumn(_('Uncollected object'), self.renderer,
text=1)
text=2)
column.set_resizable(True)
column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
self.list.append_column(column)
@@ -109,7 +119,9 @@ class Leak(Gramplet):
return self.top
def main(self):
self.display()
self.label.set_text(_('Press Refresh to see initial results'))
self.model.clear()
# self.display() # We should only run this on demand
def _button_press(self, obj, event):
if event.type == Gdk.EventType._2BUTTON_PRESS and event.button == 1:
@@ -120,32 +132,52 @@ class Leak(Gramplet):
return True
def referenced_in(self):
model, iter = self.selection.get_selected()
if iter is not None:
count = model.get_value(iter, 0)
referrers = gc.get_referrers(self.modeldata[count])
model, _iter = self.selection.get_selected()
if _iter is not None:
count = model.get_value(_iter, 0)
gc.collect(2)
referrers = gc.get_referrers(self.junk[count])
text = ""
for referrer in referrers:
match = ""
try:
text += str(referrer) + '\n'
if referrer is not self.junk:
match = "**** "
for indx in range(len(self.junk)):
if referrer is self.junk[indx]:
match = str(indx) + ": "
break
match += str(referrer) + '\n'
except ReferenceError:
pass
InfoDialog(_('Referrers of %d') % count, text,
parent=self.uistate.window)
match += 'weakly-referenced object no longer exists %s'\
% type(referrer)
except:
print(sys.exc_info())
text += match
InfoDialog(_('Referrers of %d') % count, text, parent=self.parent)
def refers_to(self):
model, iter = self.selection.get_selected()
if iter is not None:
count = model.get_value(iter, 0)
referents = gc.get_referents(self.modeldata[count])
model, _iter = self.selection.get_selected()
if _iter is not None:
count = model.get_value(_iter, 0)
referents = gc.get_referents(self.junk[count])
text = ""
for referent in referents:
match = ""
try:
text += str(referent) + '\n'
match = "****: "
for indx in range(len(self.junk)):
if referent is self.junk[indx]:
match = str(indx) + ': '
break
match += str(referent) + '\n'
except ReferenceError:
pass
InfoDialog(_('%d refers to') % count, text,
parent=self.uistate.window)
match += '%s weakly-referenced object no longer'\
' exists\n' % type(referent)
except:
print(sys.exc_info())
text += match
InfoDialog(_('%d refers to') % count, text, parent=self.parent)
def display(self):
try:
@@ -155,21 +187,57 @@ class Leak(Gramplet):
"""
Dummy.
"""
gc.collect(2)
self.parent = self.top.get_toplevel()
progress = ProgressMeter(
_('Updating display...'), '', parent=self.parent, can_cancel=True)
self.model.clear()
count = 0
if len(gc.garbage):
for each in gc.garbage:
self.junk = []
gc.collect(2)
self.junk = gc.garbage
self.label.set_text(_('Uncollected Objects: %s') %
str(len(self.junk)))
progress.set_pass(_('Updating display...'), len(self.junk))
for count in range(0, len(self.junk)):
if progress.step():
break
try:
refs = []
referrers = gc.get_referrers(self.junk[count])
for referrer in referrers:
try:
if referrer is not self.junk:
for indx in range(0, len(self.junk)):
if referrer is self.junk[indx]:
refs.append(str(indx) + ' ')
break
except:
print(sys.exc_info())
if len(refs) > 3:
ref = ' '.join(refs[0:2]) + "..."
else:
ref = ' '.join(refs)
try:
self.modeldata.append(each)
self.model.append((count, str(each)))
self.model.append((count, ref, str(self.junk[count])))
except DBError:
self.modeldata.append(each)
self.model.append((count, 'db.DB instance at %s' % id(each)))
self.model.append((count, ref,
'db.DB instance at %s' %
id(self.junk[count])))
except ReferenceError:
pass
count += 1
self.label.set_text(_('Uncollected Objects: %s') % str(len(gc.garbage)))
self.model.append((
count, ref,
'weakly-referenced object no longer exists %s'
% type(self.junk[count])))
except TypeError:
self.model.append((
count, ref,
'Object cannot be displayed %s'
% type(self.junk[count])))
except:
print(sys.exc_info())
except ReferenceError:
InfoDialog(_('Reference Error'), "Refresh to correct",
parent=self.parent)
progress.close()
def apply_clicked(self, obj):
self.display()
+3 -1
View File
@@ -85,7 +85,9 @@ class RelativesGramplet(Gramplet):
spouse = database.get_person_from_handle(spouse_handle)
spousename = name_displayer.display(spouse)
text = "%s" % spousename
self.append_text(_("%d. Partner: ") % (famc))
self.append_text(_("%(count)d. %(relation)s: ") %
{"count": famc,
"relation": family.get_relationship()})
self.link(text, 'Person', spouse_handle)
self.append_text("\n")
else:
+1 -1
View File
@@ -21,7 +21,7 @@ from gramps.gen.plug._pluginreg import *
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
# this is the default in gen/plug/_pluginreg.py: plg.require_active = True
+14 -5
View File
@@ -79,6 +79,11 @@ _ARROWS = [ { 'name' : _("Descendants <- Ancestors"), 'value' : 'd' },
{ 'name' : _("Descendants <-> Ancestors"), 'value' : 'da' },
{ 'name' : _("Descendants - Ancestors"), 'value' : '' }]
_CORNERS = [ { 'name' : _("None"), 'value' : '' },
{ 'name' : _("Female"), 'value' : 'f' },
{ 'name' : _("Male"), 'value' : 'm' },
{ 'name' : _("Both"), 'value' : 'fm' }]
#------------------------------------------------------------------------
#
# A quick overview of the classes we'll be using:
@@ -151,9 +156,11 @@ class FamilyLinesOptions(MenuReportOptions):
"is unknown it will be shown with gray."))
add_option("color", color)
roundedcorners = BooleanOption(_('Use rounded corners'), False)
roundedcorners.set_help(
_("Use rounded corners to differentiate between women and men."))
roundedcorners = EnumeratedListOption(_("Rounded corners"), '')
for i in range( 0, len(_CORNERS) ):
roundedcorners.add_item(_CORNERS[i]["value"], _CORNERS[i]["name"])
roundedcorners.set_help(_("Use rounded corners e.g. to differentiate "
"between women and men."))
add_option("useroundedcorners", roundedcorners)
stdoptions.add_gramps_id_option(menu, category_name, ownline=True)
@@ -880,7 +887,7 @@ class FamilyLinesReport(Report):
label += '%s(' % line_delimiter
if birth_str:
label += '%s' % birth_str
label += ' - '
label += ' – '
if death_str:
label += '%s' % death_str
label += ')'
@@ -912,7 +919,9 @@ class FamilyLinesReport(Report):
border = ""
fill = ""
if gender == person.FEMALE and self._useroundedcorners:
if gender == person.FEMALE and ("f" in self._useroundedcorners):
style = "rounded"
elif gender == person.MALE and ("m" in self._useroundedcorners):
style = "rounded"
elif gender == person.UNKNOWN:
shape = "hexagon"
+6 -3
View File
@@ -226,12 +226,15 @@ class HourGlassReport(Report):
else:
death = ""
if death:
death = " – %s" % death
if self.includeid == 0: # no ID
label = "%s \\n(%s - %s)" % (name, birth, death)
label = "%s \\n(%s%s)" % (name, birth, death)
elif self.includeid == 1: # same line
label = "%s (%s)\\n(%s - %s)" % (name, p_id, birth, death)
label = "%s (%s)\\n(%s%s)" % (name, p_id, birth, death)
elif self.includeid == 2: # own line
label = "%s \\n(%s - %s)\\n(%s)" % (name, birth, death, p_id)
label = "%s \\n(%s%s)\\n(%s)" % (name, birth, death, p_id)
label = label.replace('"', '\\\"')
+15 -4
View File
@@ -144,6 +144,7 @@ class RelGraphReport(Report):
self.use_roundedcorners = get_value('useroundedcorners')
self.adoptionsdashed = get_value('dashed')
self.show_families = get_value('showfamily')
self.show_family_leaves = get_value('show_family_leaves')
self.use_subgraphs = get_value('usesubgraphs')
self.event_choice = get_value('event_choice')
self.occupation = get_value('occupation')
@@ -373,13 +374,18 @@ class RelGraphReport(Report):
if family is None:
continue
if fam_handle not in families_done:
families_done.add(fam_handle)
if not self.show_family_leaves:
family_members = {family.father_handle, family.mother_handle}.union(
child_ref.ref for child_ref in family.child_ref_list) - {None}
if len(family_members.intersection(person_handles)) < 2:
continue
self.__add_family(fam_handle)
families_done.add(fam_handle)
# If subgraphs are not chosen then each parent is linked
# separately to the family. This gives Graphviz greater
# control over the layout of the whole graph but
# may leave spouses not positioned together.
if not self.use_subgraphs:
if not self.use_subgraphs and fam_handle in families_done:
self.doc.add_link(p_id, family.get_gramps_id(), "",
self.arrowheadstyle,
self.arrowtailstyle)
@@ -597,7 +603,7 @@ class RelGraphReport(Report):
label += '%s(' % line_delimiter
if b_date:
label += '%s' % b_date
label += ' - '
label += ' – '
if d_date:
label += '%s' % d_date
label += ')'
@@ -608,7 +614,7 @@ class RelGraphReport(Report):
label += '%s(' % line_delimiter
if b_place:
label += '%s' % b_place
label += ' - '
label += ' – '
if d_place:
label += '%s' % d_place
label += ')'
@@ -840,6 +846,11 @@ class RelGraphOptions(MenuReportOptions):
_("Whether to include dates and/or places"))
add_option("event_choice", self.event_choice)
show_family_leaves = BooleanOption(_("Show all family nodes"), True)
show_family_leaves.set_help(_("Show family nodes even if the output "
"contains only one member of the family."))
add_option("show_family_leaves", show_family_leaves)
url = BooleanOption(_("Include URLs"), False)
url.set_help(_("Include a URL in each graph node so "
"that PDF and imagemap files can be "
+1 -1
View File
@@ -21,7 +21,7 @@ from gramps.gen.plug._pluginreg import newplugin, STABLE, IMPORT
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+226 -121
View File
@@ -48,7 +48,7 @@ _LOG = logging.getLogger(".gui.personview")
from gramps.gen.lib import Person, Surname
from gramps.gen.db import DbTxn
from gramps.gui.views.listview import ListView, TEXT, MARKUP, ICON
from gramps.gui.actiongroup import ActionGroup
from gramps.gui.uimanager import ActionGroup
from gramps.gen.utils.string import data_recover_msg
from gramps.gen.display.name import displayer as name_displayer
from gramps.gui.dialog import ErrorDialog, MultiSelectDialog, QuestionDialog
@@ -152,15 +152,10 @@ class BasePersonView(ListView):
multiple=True,
filter_class=PersonSidebarFilter)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
uistate.connect('nameformat-changed', self.build_tree)
uistate.connect('placeformat-changed', self.build_tree)
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
def navigation_type(self):
"""
@@ -187,70 +182,226 @@ class BasePersonView(ListView):
"""
return 'gramps-person'
def additional_ui(self):
"""
Defines the UI string for UIManager
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="SetActive"/>
<menuitem action="FilterEdit"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<menuitem action="HomePerson"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
<menu name="WebConnect" action="WebConnect"/>
</popup>
</ui>'''
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="LocalExport">
<item>
<attribute name="action">win.ExportTab</attribute>
<attribute name="label" translatable="yes">Export View...</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
''' % _("action|_Edit..."), # to use sgettext()
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.SetActive</attribute>
<attribute name="label" translatable="yes">'''
'''Set _Home Person</attribute>
</item>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Person Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the default person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-add</property>
<property name="action-name">win.Add</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Add...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Edit...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-remove</property>
<property name="action-name">win.Remove</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-merge</property>
<property name="action-name">win.Merge</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Merge...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
'''
<menu id="Popup">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">Forward</attribute>
</item>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
<item>
<attribute name="action">win.SetActive</attribute>
<attribute name="label" translatable="yes">'''
'''Set _Home Person</attribute>
</item>
</section>
<section id="PopUpTree">
</section>
<section>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
<section>
<placeholder id='QuickReport'>
</placeholder>
<placeholder id='WebConnect'>
</placeholder>
</section>
</menu>
''' % _('action|_Edit...') # to use sgettext()
]
def get_handle_from_gramps_id(self, gid):
"""
@@ -262,7 +413,7 @@ class BasePersonView(ListView):
else:
return None
def add(self, obj):
def add(self, *obj):
"""
Add a new person to the database.
"""
@@ -276,7 +427,7 @@ class BasePersonView(ListView):
except WindowActiveError:
pass
def edit(self, obj):
def edit(self, *obj):
"""
Edit an existing person in the database.
"""
@@ -287,7 +438,7 @@ class BasePersonView(ListView):
except WindowActiveError:
pass
def remove(self, obj):
def remove(self, *obj):
"""
Remove a person from the database.
"""
@@ -373,53 +524,7 @@ class BasePersonView(ListView):
ListView.define_actions(self)
self.all_action = ActionGroup(name=self.title + "/PersonAll")
self.edit_action = ActionGroup(name=self.title + "/PersonEdit")
self.all_action.add_actions([
('FilterEdit', None, _('Person Filter Editor'), None, None,
self.filter_editor),
('Edit', 'gtk-edit', _("action|_Edit..."),
"<PRIMARY>Return", self.EDIT_MSG, self.edit),
('QuickReport', None, _("Quick View"), None, None, None),
('WebConnect', None, _("Web Connection"), None, None, None),
])
self.edit_action.add_actions(
[
('Add', 'list-add', _("_Add..."), "<PRIMARY>Insert",
self.ADD_MSG, self.add),
('Remove', 'list-remove', _("_Delete"), "<PRIMARY>Delete",
self.DEL_MSG, self.remove),
('Merge', 'gramps-merge', _('_Merge...'), None,
self.MERGE_MSG, self.merge),
('ExportTab', None, _('Export View...'), None, None,
self.export),
])
self._add_action_group(self.edit_action)
self._add_action_group(self.all_action)
def enable_action_group(self, obj):
"""
Turns on the visibility of the View's action group.
"""
ListView.enable_action_group(self, obj)
self.all_action.set_visible(True)
self.edit_action.set_visible(True)
self.edit_action.set_sensitive(not self.dbstate.db.readonly)
def disable_action_group(self):
"""
Turns off the visibility of the View's action group.
"""
ListView.disable_action_group(self)
self.all_action.set_visible(False)
self.edit_action.set_visible(False)
def merge(self, obj):
def merge(self, *obj):
"""
Merge the selected people.
"""
+276 -137
View File
@@ -39,7 +39,6 @@ from gi.repository import Gtk
#-------------------------------------------------------------------------
from gramps.gen.lib import Place
from gramps.gui.views.listview import ListView, TEXT, ICON
from gramps.gui.widgets.menuitem import add_menuitem
from gramps.gen.errors import WindowActiveError
from gramps.gui.views.bookmarks import PlaceBookmarks
from gramps.gen.config import config
@@ -51,6 +50,7 @@ from gramps.gui.filters.sidebar import PlaceSidebarFilter
from gramps.gui.merge import MergePlace
from gramps.gen.plug import CATEGORY_QR_PLACE
from gramps.gen.utils.location import located_in
from gramps.gui.uimanager import ActionGroup
#-------------------------------------------------------------------------
#
@@ -58,7 +58,7 @@ from gramps.gen.utils.location import located_in
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
@@ -117,6 +117,7 @@ class PlaceBaseView(ListView):
self.mapservice = config.get('interface.mapservice')
self.mapservicedata = {}
self.map_action_group = None
ListView.__init__(
self, title, pdata, dbstate, uistate,
@@ -125,42 +126,17 @@ class PlaceBaseView(ListView):
multiple=True,
filter_class=PlaceSidebarFilter)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
self.maptoolbtn = None
uistate.connect('placeformat-changed', self.build_tree)
self.additional_uis.append(self.additional_ui())
_ui = self.__create_maps_menu_actions()
self.additional_uis.append(_ui)
def navigation_type(self):
return 'Place'
def define_actions(self):
ListView.define_actions(self)
self._add_toolmenu_action('MapsList', _('Loading...'),
_("Attempt to see selected locations with a Map "
"Service (OpenstreetMap, Google Maps, ...)"),
self.gotomap,
_('Select a Map Service'))
self._add_action('GotoMap', 'go-jump',
_('_Look up with Map Service'),
callback=self.gotomap,
tip=_("Attempt to see this location with a Map "
"Service (OpenstreetMap, Google Maps, ...)"))
self._add_action('FilterEdit', None, _('Place Filter Editor'),
callback=self.filter_editor)
self._add_action('QuickReport', None, _("Quick View"), None, None, None)
def set_inactive(self):
"""called by viewmanager when moving away from the page
Here we need to remove the menutoolbutton from the menu
"""
tb = self.uistate.viewmanager.uimanager.get_widget('/ToolBar')
tb.remove(self.maptoolbtn)
ListView.set_inactive(self)
self._add_action('GotoMap', self.gotomap)
def change_page(self):
"""
@@ -173,39 +149,6 @@ class PlaceBaseView(ListView):
5. store label so it can be changed when selection changes
"""
ListView.change_page(self)
#menutoolbutton has to be made and added in correct place on toolbar
if not self.maptoolbtn:
self.maptoolbtn = Gtk.MenuToolButton()
self.maptoolbtn.set_icon_name('go-jump')
self.maptoolbtn.connect('clicked', self.gotomap)
self.mmenu = self.__create_maps_menu_actions()
self.maptoolbtn.set_menu(self.mmenu)
self.maptoolbtn.show()
tb = self.uistate.viewmanager.uimanager.get_widget('/ToolBar')
ind = tb.get_item_index(self.uistate.viewmanager.uimanager.get_widget(
'/ToolBar/CommonEdit/Merge'))
tb.insert(self.maptoolbtn, ind+1)
widget = self.maptoolbtn
if not self.mapservicedata:
return
self.mapslistlabel = []
if not self.mapservice in self.mapservicedata:
#stored val no longer exists, use the first key instead
self.set_mapservice(list(self.mapservicedata.keys())[0])
#store all gtk labels to be able to update label on selection change_('Loading...'),
widget.set_menu(self.mmenu)
widget.set_arrow_tooltip_text(_('Select a Map Service'))
widget.set_tooltip_text(
_("Attempt to see selected locations with a Map "
"Service (OpenstreetMap, Google Maps, ...)"))
lbl = Gtk.Label(label=self.mapservice_label())
lbl.show()
self.mapslistlabel.append(lbl)
widget.set_label_widget(self.mapslistlabel[-1])
widget.set_icon_name('go-jump')
if self.drag_info():
self.list.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK,
[],
@@ -222,30 +165,52 @@ class PlaceBaseView(ListView):
Function creating a menu and actions that are used as dropdown menu
from the menutoolbutton
"""
menu = Gtk.Menu()
_bar = '''
<item>
<attribute name="action">win.MapChoice</attribute>
<attribute name="target">%s</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
'''
menu = ''
#select the map services to show
self.mapservicedata = {}
servlist = GuiPluginManager.get_instance().get_reg_mapservices()
for i, pdata in enumerate(servlist):
for pdata in servlist:
key = pdata.id.replace(' ', '-')
add_menuitem(menu, pdata.name, None,
make_callback(self.set_mapservice, key))
menu += _bar % (key, pdata.name)
self.mapservicedata[key] = pdata
return menu
if not self.mapservicedata:
return self.additional_ui
if self.mapservice not in self.mapservicedata:
#stored val no longer exists, use the most recent key instead
self.set_mapservice(None, key)
def set_mapservice(self, mapkey):
self._add_toggle_action('MapChoice', self.set_mapservice, '',
self.mapservice)
label = self.mapservice_label()
_ui = self.additional_ui[:]
_ui.append(self.map_ui_menu % menu)
_ui.append(self.map_ui % label)
return _ui
def set_mapservice(self, action, value):
"""
change the service that runs on click of the menutoolbutton
used as callback menu on menu clicks
"""
self.mapservice = mapkey
for label in self.mapslistlabel:
label.set_label(self.mapservice_label())
label.show()
if action:
action.set_state(value)
self.mapservice = mapkey = value.get_string()
config.set('interface.mapservice', mapkey)
config.save()
_ui = self.__create_maps_menu_actions()
self.uimanager.add_ui_from_string(_ui)
self.uimanager.update_menu()
return False
def mapservice_label(self):
"""
@@ -253,7 +218,7 @@ class PlaceBaseView(ListView):
"""
return self.mapservicedata[self.mapservice].name
def gotomap(self, obj):
def gotomap(self, *obj):
"""
Run the map service
"""
@@ -295,72 +260,245 @@ class PlaceBaseView(ListView):
def get_stock(self):
return 'gramps-place'
def additional_ui(self):
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
<separator/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
<separator/>
<menuitem action="GotoMap"/>
</popup>
</ui>'''
#
# Defines the UI string for UIManager
#
additional_ui = [
'''
<placeholder id="LocalExport">
<item>
<attribute name="action">win.ExportTab</attribute>
<attribute name="label" translatable="yes">Export View...</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
''' % _("action|_Edit..."), # to use sgettext()
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Place Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-add</property>
<property name="action-name">win.Add</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Add...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Edit...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-remove</property>
<property name="action-name">win.Remove</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-merge</property>
<property name="action-name">win.Merge</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Merge...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<placeholder id="PlaceMapUi"> </placeholder>
</placeholder>
''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
'''
<menu id="Popup">
<section id="PopUpTree">
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
<section>
<placeholder id='QuickReport'>
</placeholder>
</section>
<section>
<item>
<attribute name="action">win.GotoMap</attribute>
<attribute name="label" translatable="yes">'''
'''_Look up with Map Service</attribute>
</item>
</section>
</menu>
''' % _('action|_Edit...')] # to use sgettext()
def add(self, obj):
map_ui_menu = '''
<menu id="MapBtnMenu">
%s
</menu>
'''
map_ui = (
'''<placeholder id="PlaceMapUi">
<child>
<object class="GtkToolButton" id="GotoMap">
<property name="icon-name">go-jump</property>
<property name="action-name">win.GotoMap</property>
<property name="tooltip_text" translatable="yes">'''
'''Attempt to see selected locations with a Map Service '''
'''(OpenstreetMap, Google Maps, ...)</property>
<property name="label" translatable="yes">%s</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToolItem">
<child>
<object class="GtkMenuButton">
<property name="tooltip_text" translatable="yes">'''
'''Select a Map Service</property>
<property name="menu-model">MapBtnMenu</property>
<property name="relief">GTK_RELIEF_NONE</property>
<property name="use-popover">False</property>
</object>
</child>
</object>
</child>
</placeholder>
''')
def add(self, *obj):
try:
EditPlace(self.dbstate, self.uistate, [], Place())
except WindowActiveError:
pass
def remove(self, obj):
def remove(self, *obj):
for handle in self.selected_handles():
for link in self.dbstate.db.find_backlink_handles(handle,['Place']):
msg = _("Cannot delete place.")
@@ -390,7 +528,7 @@ class PlaceBaseView(ListView):
is_used = len(person_list) + len(family_list) + len(event_list) > 0
return (query, is_used, object)
def edit(self, obj):
def edit(self, *obj):
for handle in self.selected_handles():
place = self.dbstate.db.get_place_from_handle(handle)
try:
@@ -398,7 +536,7 @@ class PlaceBaseView(ListView):
except WindowActiveError:
pass
def merge(self, obj):
def merge(self, *obj):
"""
Merge the selected places.
"""
@@ -468,5 +606,6 @@ class PlaceBaseView(ListView):
"Place Notes",
"Place Backlinks"))
def make_callback(func, val):
return lambda x: func(val)
return lambda x, y: func(val)
+28 -8
View File
@@ -22,7 +22,7 @@ from gramps.gen.plug._pluginreg import register, STABLE, GENERAL
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
@@ -41,7 +41,7 @@ fname = 'libcairodoc.py',
authors = ["The Gramps project"],
authors_email = ["http://gramps-project.org"],
#load_on_reg = True
)
)
#------------------------------------------------------------------------
#
@@ -58,7 +58,7 @@ status = STABLE,
fname = 'libgedcom.py',
authors = ["The Gramps project"],
authors_email = ["http://gramps-project.org"],
)
)
#------------------------------------------------------------------------
#
@@ -94,8 +94,9 @@ fname = 'libgrampsxml.py',
authors = ["The Gramps project"],
authors_email = ["http://gramps-project.org"],
#load_on_reg = True
)
#------------------------------------------------------------------------
)
#------------------------------------------------------------------------
#
# libholiday
#
@@ -111,7 +112,7 @@ fname = 'libholiday.py',
authors = ["The Gramps project"],
authors_email = ["http://gramps-project.org"],
#load_on_reg = True
)
)
#------------------------------------------------------------------------
#
@@ -129,7 +130,7 @@ fname = 'libhtmlbackend.py',
authors = ["The Gramps project"],
authors_email = ["http://gramps-project.org"],
#load_on_reg = True
)
)
#------------------------------------------------------------------------
#
@@ -165,7 +166,7 @@ fname = 'libhtml.py',
authors = ["Gerald Britton"],
authors_email = ["gerald.britton@gmail.com"],
#load_on_reg = True
)
)
#------------------------------------------------------------------------
#
@@ -235,6 +236,24 @@ authors = ["The Gramps project"],
authors_email = ["http://gramps-project.org"],
)
#------------------------------------------------------------------------
#
# libprogen
#
#------------------------------------------------------------------------
register(GENERAL,
id = 'libprogen',
name = "Pro-Gen lib",
description = _("Provides common functionality for Pro-Gen import"),
version = '1.0',
gramps_target_version = MODULE_VERSION,
status = STABLE,
fname = 'libprogen.py',
authors = ["The Gramps project"],
authors_email = ["http://gramps-project.org"],
#load_on_reg = True
)
#------------------------------------------------------------------------
#
# libplaceview
@@ -268,6 +287,7 @@ fname = 'libsubstkeyword.py',
authors = ["The Gramps project"],
authors_email = ["http://gramps-project.org"],
)
#------------------------------------------------------------------------
#
# libtreebase
File diff suppressed because it is too large. Load diff
+34 -13
View File
@@ -191,7 +191,7 @@ class GeoGraphyView(OsmGps, NavigationView):
self.clearmap = None
self.nbplaces = 0
def add_bookmark(self, menu):
def add_bookmark(self, *menu):
"""
Add the place to the bookmark
"""
@@ -300,16 +300,7 @@ class GeoGraphyView(OsmGps, NavigationView):
another method.
"""
NavigationView.define_actions(self)
self.define_print_actions()
def define_print_actions(self):
"""
Associate the print button to the PrintView action.
"""
self._add_action('PrintView', 'document-print', _("_Print..."),
accel="<PRIMARY>P",
tip=_("Print or save the Map"),
callback=self.printview)
self._add_action('PrintView', self.printview, '<Primary>P')
def config_connect(self):
"""
@@ -345,7 +336,6 @@ class GeoGraphyView(OsmGps, NavigationView):
"""
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title(_('Map Menu'))
if config.get("geography.show_cross"):
title = _('Remove cross hair')
@@ -876,7 +866,7 @@ class GeoGraphyView(OsmGps, NavigationView):
# Printing functionalities
#
#-------------------------------------------------------------------------
def printview(self, obj):
def printview(self, *obj):
"""
Print or save the view that is currently shown
"""
@@ -1036,6 +1026,19 @@ class GeoGraphyView(OsmGps, NavigationView):
pass
kml.destroy()
def place_exists(self, place_name):
"""
Do we have already this place in our database ?
return the handle for this place.
"""
found = None
place_name = place_name.replace('-', ' ').lower()
for place in self.dbstate.db.iter_places():
if place.name.get_value().lower() == place_name:
found = place.handle
break
return found
def link_place(self, menu, event, lat, lon):
"""
Link an existing place using longitude and latitude of location centered
@@ -1110,6 +1113,24 @@ class GeoGraphyView(OsmGps, NavigationView):
placeref = PlaceRef()
placeref.ref = parent
new_place.add_placeref(placeref)
elif isinstance(parent, gi.overrides.Gtk.TreeModelRow):
# We are here because we selected a place from geocoding
# parent[0] : country
# parent[1] : state
# parent[2] : town
# parent[3] : name
value = PlaceSelection.untag_text(parent[2], 1)
plname = PlaceName()
plname.set_value(value)
handle = self.place_exists(value)
if handle:
# The town already exists. We create a place with name
placeref = PlaceRef()
placeref.ref = handle
new_place.add_placeref(placeref)
value = PlaceSelection.untag_text(parent[3], 1)
plname.set_value(value)
new_place.set_name(plname)
else:
found = None
for place in self.dbstate.db.iter_places():
+47 -4
View File
@@ -43,7 +43,14 @@ _LOG = logging.getLogger("maps.placeselection")
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gi
from gi.repository import Gtk
try:
gi.require_version('GeocodeGlib', '1.0')
from gi.repository import GeocodeGlib
GEOCODEGLIB = True
except:
GEOCODEGLIB = False
#-------------------------------------------------------------------------
#
@@ -66,6 +73,8 @@ from gramps.gen.display.place import displayer as _pd
#-------------------------------------------------------------------------
PLACE_REGEXP = re.compile('<span background="green">(.*)</span>')
PLACE_STRING = '<span background="green">%s</span>'
GEOCODE_REGEXP = re.compile('<span background="red">(.*)</span>')
GEOCODE_STRING = '<span background="red">%s</span>'
# pylint: disable=unused-argument
# pylint: disable=no-member
@@ -110,9 +119,14 @@ class PlaceSelection(ManagedWindow, OsmGps):
Gtk.Dialog(_('Place Selection in a region'), uistate.window,
buttons=(_('_Close'), Gtk.ResponseType.CLOSE)),
None, _('Place Selection in a region'), None)
label = Gtk.Label(label=_('Choose the radius of the selection.\n'
'On the map you should see a circle or an'
' oval depending on the latitude.'))
mylabel = _('Choose the radius of the selection.\n'
'On the map you should see a circle or an'
' oval depending on the latitude.')
mylabel += _('\nIn the following table you may have :'
'\n - a green row related to a selected place.')
if GEOCODEGLIB:
mylabel += _('\n - a red row related to a geocoding result.')
label = Gtk.Label(label=mylabel)
label.set_valign(Gtk.Align.END)
self.window.vbox.pack_start(label, False, True, 0)
adj = Gtk.Adjustment(value=1.0, lower=0.1, upper=3.0,
@@ -193,6 +207,17 @@ class PlaceSelection(ManagedWindow, OsmGps):
self.plist.append((place[0], place[1],
place[2], place[3], place[4]))
# here, we could add value from geography names services ...
if GEOCODEGLIB:
loc = GeocodeGlib.Location.new(lat, lon, 0)
obj = GeocodeGlib.Reverse.new_for_location(loc)
try:
result = GeocodeGlib.Reverse.resolve(obj)
self.plist.append((GEOCODE_STRING % result.get_country(),
GEOCODE_STRING % result.get_state(),
GEOCODE_STRING % result.get_town(),
GEOCODE_STRING % result.get_name(), ''))
except:
pass
# if we found no place, we must create a default place.
self.plist.append((_("New place with empty fields"), "",
@@ -299,4 +324,22 @@ class PlaceSelection(ManagedWindow, OsmGps):
"""
get location values and call the real function : add_place, edit_place
"""
self.function(self.plist[index][3], self.lat, self.lon)
self.function(self.plist[index], self.lat, self.lon)
def untag_text(text, tag):
"""
suppress the green or red color tag.
if tag = 0 : PLACE_REGEXP
if tag = 1 : GEOCODE_REGEXP
"""
if tag:
regtag = GEOCODE_REGEXP
else:
regtag = PLACE_REGEXP
match = regtag.match(text)
if match:
without_tags = match.groups()[0]
return without_tags
return text
-8
View File
@@ -45,7 +45,6 @@ class GoogleMapService(MapService):
def calc_url(self):
""" Determine the url to use on maps.google.com
Logic: use lat lon if present
otherwise use city and country if present
otherwise use description of the place
"""
place = self._get_first_place()[0]
@@ -55,13 +54,6 @@ class GoogleMapService(MapService):
longitude)
return
location = get_main_location(self.database, place)
city = location.get(PlaceType.CITY)
country = location.get(PlaceType.COUNTRY)
if city and country:
self.url = "http://maps.google.com/maps?q=%s,%s" % (city, country)
return
titledescr = place_displayer.display(self.database, place)
self.url = "http://maps.google.com/maps?q=%s" % \
'+'.join(titledescr.split())
+1 -1
View File
@@ -20,7 +20,7 @@
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
+1 -10
View File
@@ -46,8 +46,7 @@ class OpensStreetMapService(MapService):
def calc_url(self):
""" Determine the url to use
Logic: use lat lon if present
otherwise use city and country if present
Logic: Use lat lon if present
otherwise use description of the place
"""
place = self._get_first_place()[0]
@@ -58,14 +57,6 @@ class OpensStreetMapService(MapService):
return
location = get_main_location(self.database, place)
city = location.get(PlaceType.CITY)
country = location.get(PlaceType.COUNTRY)
if city and country:
self.url = "http://nominatim.openstreetmap.org/"\
"search.php?q=%s%%2C%s" % (city, country)
return
titledescr = place_displayer.display(self.database, place)
self.url = "http://nominatim.openstreetmap.org/"\
"search.php?q=%s" % '+'.join(titledescr.split())
+1 -1
View File
@@ -22,7 +22,7 @@ from gramps.gen.plug._pluginreg import *
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
+1 -1
View File
@@ -22,7 +22,7 @@ from gramps.gen.plug._pluginreg import newplugin, STABLE, RELCALC
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#
# Relationship calculators
@@ -88,14 +88,6 @@ class CategorySidebar(BaseSidebar):
button.drag_dest_set(0, [], 0)
button.connect('drag_motion', self.cb_switch_page_on_dnd, cat_num)
# toollbar buttons for switching views in a category
uitoolitems = ''
for view_num, view_name, view_icon in views[cat_num]:
pageid = 'page_%i_%i' % (cat_num, view_num)
uitoolitems += '\n<toolitem action="%s"/>' % pageid
if len(views[cat_num]) > 1:
self.ui_category[cat_num] = UICATEGORY % uitoolitems
vbox.show_all()
def get_top(self):
+1 -1
View File
@@ -20,7 +20,7 @@
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
+3 -1
View File
@@ -198,10 +198,12 @@ def make_tst_function(tstfile, file_name):
@patch('gramps.plugins.db.bsddb.write.time')
@patch('gramps.gen.utils.unknown.localtime')
@patch('gramps.gen.utils.unknown.time')
def tst(self, mocktime, mockltime, mockwtime, mockdtime):
@patch('time.localtime')
def tst(self, mockptime, mocktime, mockltime, mockwtime, mockdtime):
""" This compares the import file with the expected result '.gramps'
file.
"""
mockptime.side_effect = mock_localtime
mocktime.side_effect = mock_time
mockltime.side_effect = mock_localtime
mockwtime.side_effect = mock_time
+86 -15
View File
@@ -65,6 +65,7 @@ def _T_(value): # enable deferred translations (see Python docs 22.1.3.4)
_TITLE0 = _T_("Birthday and Anniversary Report")
_TITLE1 = _T_("My Birthday Report")
_TITLE2 = _T_("Produced with Gramps")
_DEADTXT = _T_("✝")
#------------------------------------------------------------------------
#
@@ -91,15 +92,18 @@ class BirthdayReport(Report):
self.relationships = mgobn('relationships')
self.year = mgobn('year')
self.country = mgobn('country')
self.anniversaries = mgobn('anniversaries')
self.maiden_name = mgobn('maiden_name')
self.alive = mgobn('alive')
self.birthdays = mgobn('birthdays')
self.anniversaries = mgobn('anniversaries')
self.death_anniversaries = mgobn('death_anniversaries')
self.text1 = mgobn('text1')
self.text2 = mgobn('text2')
self.text3 = mgobn('text3')
self.deadtxt = mgobn('deadtxt')
self.filter_option = menu.get_option_by_name('filter')
self.filter = self.filter_option.get_filter()
self.showyear = mgobn('showyear')
pid = mgobn('pid')
self.set_locale(menu.get_option_by_name('trans').get_value())
@@ -319,15 +323,23 @@ class BirthdayReport(Report):
if relation:
# FIXME this won't work for RTL languages
comment = " --- %s" % relation
deadtxt = ""
if (not alive):
deadtxt = self.deadtxt
yeartxt = ""
if self.showyear:
yeartxt = "(%s) " % year
if nyears == 0:
text = self._('%(person)s, birth%(relation)s') % {
text = self._('* %(person)s, birth%(relation)s') % {
'person' : short_name,
'relation' : comment}
else:
# translators: leave all/any {...} untranslated
text = ngettext('{person}, {age}{relation}',
'{person}, {age}{relation}',
nyears).format(person=short_name,
text = ngettext('* {year}{person}{dead}, {age}{relation}',
'* {year}{person}{dead}, {age}{relation}',
nyears).format(year=yeartxt,
person=short_name,
dead=deadtxt,
age=nyears,
relation=comment)
@@ -372,24 +384,71 @@ class BirthdayReport(Report):
nyears = self.year - year
if event_obj.is_valid():
prob_alive_date = Date(self.year, month, day)
alive1 = probably_alive(person, self.database,
prob_alive_date)
alive2 = probably_alive(spouse, self.database,
prob_alive_date)
deadtxt1 = ""
deadtxt2 = ""
if (not alive1):
deadtxt1 = self.deadtxt
if (not alive2):
deadtxt2 = self.deadtxt
yeartxt = ""
if self.showyear:
yeartxt = "(%s) " % year
if nyears == 0:
text = self._("%(spouse)s and\n %(person)s, wedding") % {
text = self._("⚭ %(spouse)s and\n %(person)s, wedding") % {
'spouse' : spouse_name,
'person' : short_name}
else:
# translators: leave all/any {...} untranslated
text = ngettext("{spouse} and\n {person}, {nyears}",
"{spouse} and\n {person}, {nyears}",
nyears).format(spouse=spouse_name, person=short_name, nyears=nyears)
prob_alive_date = Date(self.year, month, day)
alive1 = probably_alive(person, self.database,
prob_alive_date)
alive2 = probably_alive(spouse, self.database,
prob_alive_date)
text = ngettext("⚭ {year}{spouse}{deadtxt2} and\n {person}{deadtxt1}, {nyears}",
"⚭ {year}{spouse}{deadtxt2} and\n {person}{deadtxt1}, {nyears}",
nyears).format(year=yeartxt, spouse=spouse_name, deadtxt2=deadtxt2, person=short_name, deadtxt1=deadtxt1, nyears=nyears)
if (self.alive and alive1 and alive2) or not self.alive:
self.add_day_item(text, month, day, spouse)
death_ref = person.get_death_ref()
death_date = None
if death_ref:
death_event = self.database.get_event_from_handle(death_ref.ref)
death_date = death_event.get_date_object()
if (self.death_anniversaries and death_date is not None and death_date.is_valid()):
death_date = gregorian(death_date)
year = death_date.get_year()
month = death_date.get_month()
day = death_date.get_day()
nyears = self.year - year
comment = ""
if self.relationships:
relation = rel_calc.get_one_relationship(
self.database,
self.center_person,
person,
olocale=self._locale)
if relation:
# FIXME this won't work for RTL languages
comment = " --- %s" % relation
yeartxt = ""
if self.showyear:
yeartxt = "(%s) " % year
if nyears == 0:
text = _('✝ {person}, death {relation}').format(person=short_name,relation=comment)
else:
text = ngettext('✝ {year}{person}, {age}{relation}',
'✝ {year}{person}, {age}{relation}',
nyears).format(year=yeartxt,
person=short_name,
age=nyears,
relation=comment)
self.add_day_item(text, month, day, person)
#------------------------------------------------------------------------
#
# BirthdayOptions
@@ -449,10 +508,18 @@ class BirthdayOptions(MenuReportOptions):
alive.set_help(_("Include only living people in the report"))
menu.add_option(category_name, "alive", alive)
deadtxt = StringOption(_("Dead Symbol"), _(_DEADTXT))
deadtxt.set_help(_("This will show after name to indicate that person is dead"))
menu.add_option(category_name, "deadtxt", deadtxt)
self.__update_filters()
stdoptions.add_localization_option(menu, category_name)
showyear = BooleanOption(_("Show event year"), True)
showyear.set_help(_("Prints the year the event took place in the report"))
menu.add_option(category_name, "showyear", showyear)
category_name = _("Content")
year = NumberOption(_("Year of report"), time.localtime()[0],
@@ -493,6 +560,10 @@ class BirthdayOptions(MenuReportOptions):
anniversaries.set_help(_("Whether to include anniversaries"))
menu.add_option(category_name, "anniversaries", anniversaries)
death_anniversaries = BooleanOption(_("Include death anniversaries"), True)
death_anniversaries.set_help(_("Whether to include anniversaries of death"))
menu.add_option(category_name, "death_anniversaries", death_anniversaries)
show_relships = BooleanOption(
_("Include relationship to center person"), False)
show_relships.set_help(
+1 -1
View File
@@ -169,7 +169,7 @@ class EndOfLineReport(Report):
self.doc.end_paragraph()
self.doc.start_table('EolTable', 'EOL-Table')
for generation, handles in self.eol_map.items():
for generation, handles in sorted(self.eol_map.items()):
self.write_generation_row(generation)
for person_handle, pedigrees in handles.items():
self.write_person_row(person_handle)
+1 -1
View File
@@ -22,7 +22,7 @@ from gramps.gen.plug._pluginreg import *
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
# this is the default in gen/plug/_pluginreg.py: plg.require_active = True
+1 -1
View File
@@ -25,7 +25,7 @@ _ = glocale.translation.gettext
GRAMPS registration file
"""
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
+1 -1
View File
@@ -25,7 +25,7 @@ _ = glocale.translation.gettext
GRAMPS registration file
"""
MODULE_VERSION="5.0"
MODULE_VERSION="5.1"
#------------------------------------------------------------------------
#
+55
View File
@@ -435,6 +435,9 @@ class Verify(tool.Tool, ManagedWindow, UpdateCallback):
Disconnected(self.db, person),
InvalidBirthDate(self.db, person, invdate),
InvalidDeathDate(self.db, person, invdate),
BirthEqualsDeath(self.db, person),
BirthEqualsMarriage(self.db, person),
DeathEqualsMarriage(self.db, person),
]
for rule in rule_list:
@@ -1781,3 +1784,55 @@ class OldAgeButNoDeath(PersonRule):
""" return the rule's error message """
return _("Old age but no death")
class BirthEqualsDeath(PersonRule):
""" test if a person's birth date is the same as their death date """
ID = 33
SEVERITY = Rule.ERROR
def broken(self):
""" return boolean indicating whether this rule is violated """
birth_date = get_birth_date(self.db, self.obj)
death_date = get_death_date(self.db, self.obj)
birth_ok = birth_date > 0 if birth_date is not None else False
death_ok = death_date > 0 if death_date is not None else False
return death_ok and birth_ok and birth_date == death_date
def get_message(self):
""" return the rule's error message """
return _("Birth equals death")
class BirthEqualsMarriage(PersonRule):
""" test if a person's birth date is the same as their marriage date """
ID = 34
SEVERITY = Rule.ERROR
def broken(self):
""" return boolean indicating whether this rule is violated """
birth_date = get_birth_date(self.db, self.obj)
birth_ok = birth_date > 0 if birth_date is not None else False
for fhandle in self.obj.get_family_handle_list():
family = self.db.get_family_from_handle(fhandle)
marr_date = get_marriage_date(self.db, family)
marr_ok = marr_date > 0 if marr_date is not None else False
return marr_ok and birth_ok and birth_date == marr_date
def get_message(self):
""" return the rule's error message """
return _("Birth equals marriage")
class DeathEqualsMarriage(PersonRule):
""" test if a person's death date is the same as their marriage date """
ID = 35
SEVERITY = Rule.WARNING # it's possible
def broken(self):
""" return boolean indicating whether this rule is violated """
death_date = get_death_date(self.db, self.obj)
death_ok = death_date > 0 if death_date is not None else False
for fhandle in self.obj.get_family_handle_list():
family = self.db.get_family_from_handle(fhandle)
marr_date = get_marriage_date(self.db, family)
marr_ok = marr_date > 0 if marr_date is not None else False
return marr_ok and death_ok and death_date == marr_date
def get_message(self):
""" return the rule's error message """
return _("Death equals marriage")
+191 -94
View File
@@ -62,7 +62,7 @@ from gramps.gui.merge import MergeCitation
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
@@ -146,12 +146,7 @@ class CitationListView(ListView):
multiple=True,
filter_class=CitationSidebarFilter)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
def navigation_type(self):
return 'Citation'
@@ -159,94 +154,196 @@ class CitationListView(ListView):
def drag_info(self):
return DdTargets.CITATION_LINK
def define_actions(self):
"""
This defines the possible actions for the citation views.
Possible actions are:
add: Add a new citation and a new source (this can also be done
by source view add a source, then citation view add a new
citation to an existing source)
edit: Edit a citation.
merge: Merge the selected citations.
remove: Delete the selected citations.
"""
ListView.define_actions(self)
self.all_action = Gtk.ActionGroup(name=self.title + "/CitationAll")
self.edit_action = Gtk.ActionGroup(name=self.title + "/CitationEdit")
self._add_action('FilterEdit', None, _('Citation Filter Editor'),
callback=self.filter_editor,)
self._add_action('QuickReport', None, _("Quick View"), None, None, None)
self._add_action_group(self.edit_action)
self._add_action_group(self.all_action)
def get_stock(self):
return 'gramps-citation'
def additional_ui(self):
"""
Defines the UI string for UIManager
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
</popup>
</ui>'''
additional_ui = [
'''
<placeholder id="LocalExport">
<item>
<attribute name="action">win.ExportTab</attribute>
<attribute name="label" translatable="yes">Export View...</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
''' % _("action|_Edit..."), # to use sgettext()
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Citation Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-add</property>
<property name="action-name">win.Add</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Add...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Edit...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-remove</property>
<property name="action-name">win.Remove</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-merge</property>
<property name="action-name">win.Merge</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Merge...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
'''
<menu id="Popup">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">Forward</attribute>
</item>
</section>
<section id="PopUpTree">
</section>
<section>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
<section>
<placeholder id='QuickReport'>
</placeholder>
</section>
</menu>
''' % _('action|_Edit...') # to use sgettext()
]
def add(self, obj):
def add(self, *obj):
"""
add: Add a new citation and a new source (this can also be done
by source view add a source, then citation view add a new
@@ -269,7 +366,7 @@ class CitationListView(ListView):
except WindowActiveError:
pass
def remove(self, obj):
def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -280,7 +377,7 @@ class CitationListView(ListView):
is_used = any(the_lists)
return (query, is_used, object)
def edit(self, obj):
def edit(self, *obj):
"""
Edit a Citation
"""
@@ -301,7 +398,7 @@ class CitationListView(ListView):
"the same citation is being edited.\n\nTo edit this "
"citation, you need to close the object.")
def merge(self, obj):
def merge(self, *obj):
"""
Merge the selected citations.
"""
+240 -104
View File
@@ -65,7 +65,7 @@ from gramps.gui.merge import MergeCitation, MergeSource
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
#
@@ -147,12 +147,7 @@ class CitationTreeView(ListView):
multiple=True,
filter_class=SourceSidebarFilter)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
# Override change_active from NavigationView, so that only Citations can be
# put in the history list for the CitationTreeView
@@ -298,100 +293,241 @@ class CitationTreeView(ListView):
"""
ListView.define_actions(self)
self._add_action('Add source', 'gramps-source', _("Add source..."),
accel=None,
tip=self.ADD_SOURCE_MSG,
callback=self.add_source)
self._add_action('Add citation', 'gramps-citation',
_("Add citation..."),
accel=None,
tip=self.ADD_CITATION_MSG,
callback=self.share)
self.action_list.extend([
('AddSource', self.add_source),
('AddCitation', self.share),
('OpenAllNodes', self.open_all_nodes),
('CloseAllNodes', self.close_all_nodes), ])
self.all_action = Gtk.ActionGroup(name=self.title + "/CitationAll")
self.edit_action = Gtk.ActionGroup(name=self.title + "/CitationEdit")
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="LocalExport">
<item>
<attribute name="action">win.ExportTab</attribute>
<attribute name="label" translatable="yes">Export View...</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.AddSource</attribute>
<attribute name="label" translatable="yes">Add source...</attribute>
</item>
<item>
<attribute name="action">win.AddCitation</attribute>
<attribute name="label" translatable="yes">Add citation...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
''' % _("action|_Edit..."), # to use sgettext()
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Citation Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-add</property>
<property name="action-name">win.Add</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Add...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-source</property>
<property name="action-name">win.AddSource</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Add source...</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-citation</property>
<property name="action-name">win.AddCitation</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Add citation...</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Edit...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-remove</property>
<property name="action-name">win.Remove</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-merge</property>
<property name="action-name">win.Merge</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Merge...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''' % (ADD_MSG, ADD_SOURCE_MSG, ADD_CITATION_MSG, EDIT_MSG, DEL_MSG,
MERGE_MSG),
'''
<menu id="Popup">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">Forward</attribute>
</item>
</section>
<section id="PopUpTree">
<item>
<attribute name="action">win.OpenAllNodes</attribute>
<attribute name="label" translatable="yes">'''
'''Expand all Nodes</attribute>
</item>
<item>
<attribute name="action">win.CloseAllNodes</attribute>
<attribute name="label" translatable="yes">'''
'''Collapse all Nodes</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.AddCitation</attribute>
<attribute name="label" translatable="yes">'''
'''Add citation...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
<section>
<placeholder id='QuickReport'>
</placeholder>
</section>
</menu>
''' % _('action|_Edit...') # to use sgettext()
]
self._add_action('FilterEdit', None, _('Citation Filter Editor'),
callback=self.filter_editor,)
self._add_action('QuickReport', None, _("Quick View"), None, None, None)
self._add_action_group(self.edit_action)
self._add_action_group(self.all_action)
self.all_action.add_actions([
('OpenAllNodes', None, _("Expand all Nodes"), None, None,
self.open_all_nodes),
('CloseAllNodes', None, _("Collapse all Nodes"), None, None,
self.close_all_nodes),
])
def additional_ui(self):
"""
Defines the UI string for UIManager
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Add source"/>
<menuitem action="Add citation"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Add source"/>
<toolitem action="Add citation"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="OpenAllNodes"/>
<menuitem action="CloseAllNodes"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Add citation"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
</popup>
</ui>'''
def add_source(self, obj):
def add_source(self, *obj):
"""
add_source: Add a new source (this is also available from the
source view)
@@ -412,7 +548,7 @@ class CitationTreeView(ListView):
except WindowActiveError:
pass
def add(self, obj):
def add(self, *obj):
"""
add: Add a new citation and a new source (this can also be done
by source view add a source, then citation view add a new
@@ -435,7 +571,7 @@ class CitationTreeView(ListView):
except WindowActiveError:
pass
def share(self, obj):
def share(self, *obj):
"""
share: Add a new citation to an existing source (when a source is
selected)
@@ -455,7 +591,7 @@ class CitationTreeView(ListView):
self.__blocked_text(),
parent=self.uistate.window)
#
def remove(self, obj):
def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -477,7 +613,7 @@ class CitationTreeView(ListView):
is_used = any(the_lists)
return (query, is_used, source)
def edit(self, obj):
def edit(self, *obj):
"""
Edit either a Source or a Citation, depending on user selection
"""
@@ -518,7 +654,7 @@ class CitationTreeView(ListView):
"source is being edited.\n\nTo edit this "
"source, you need to close the object.")
def merge(self, obj):
def merge(self, *obj):
"""
Merge the selected citations.
"""
+14 -9
View File
@@ -49,12 +49,7 @@ class DashboardView(PageView):
Create a DashboardView, with the current dbstate and uistate
"""
PageView.__init__(self, _('Dashboard'), pdata, dbstate, uistate)
self.ui_def = '''<ui>
<popup name="GrampletPopup">
<menuitem action="AddGramplet"/>
<menuitem action="RestoreGramplet"/>
</popup>
</ui>'''
self.ui_def = [] # No special menu for Dashboard, Popup in GrampletPane
def build_interface(self):
"""
@@ -81,6 +76,12 @@ class DashboardView(PageView):
"""
pass
def get_title(self):
"""
Used to set the titlebar in the configuration window.
"""
return _('Dashboard')
def get_stock(self):
"""
Return image associated with the view, which is used for the
@@ -95,16 +96,20 @@ class DashboardView(PageView):
def define_actions(self):
"""
Defines the UIManager actions.
Defines the UIManager actions. Called by the ViewManager to set up the
View. The user typically defines self.action_list and
self.action_toggle_list in this function.
"""
self._add_action("AddGramplet", 'list-add', _("Add a gramplet"))
self._add_action("RestoreGramplet", None, _("Restore a gramplet"))
pass
def set_inactive(self):
self.active = False
self.widget.set_inactive()
def set_active(self):
new_title = "%s - %s - Gramps" % (self.dbstate.db.get_dbname(),
self.get_title())
self.uistate.window.set_title(new_title)
self.active = True
self.widget.set_active()
+252 -105
View File
@@ -3,6 +3,7 @@
# Copyright (C) 2001-2007 Donald N. Allingham
# Copyright (C) 2008 Gary Burton
# Copyright (C) 2011 Tim G L Lyons
# Copyright (C) 2017 Alois Poettker
#
# 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
@@ -28,35 +29,30 @@ Provide the event view.
# Standard python modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
import logging
_LOG = logging.getLogger(".plugins.eventview")
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
# Gramps modules
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import Event
from gramps.gui.views.listview import ListView, TEXT, MARKUP, ICON
from gramps.gui.views.treemodels import EventModel
from gramps.gui.dialog import ErrorDialog, MultiSelectDialog, QuestionDialog
from gramps.gen.errors import WindowActiveError
from gramps.gui.views.bookmarks import EventBookmarks
from gramps.gen.config import config
from gramps.gen.lib import Event
from gramps.gen.utils.string import data_recover_msg
from gramps.gui.ddtargets import DdTargets
from gramps.gui.dialog import ErrorDialog
from gramps.gui.editors import EditEvent, DeleteEventQuery
from gramps.gui.filters.sidebar import EventSidebarFilter
from gramps.gui.merge import MergeEvent
from gramps.gen.plug import CATEGORY_QR_EVENT
from gramps.gui.views.bookmarks import EventBookmarks
from gramps.gui.views.listview import ListView, TEXT, MARKUP, ICON
from gramps.gui.views.treemodels import EventModel
#-------------------------------------------------------------------------
#
@@ -130,15 +126,10 @@ class EventView(ListView):
multiple=True,
filter_class=EventSidebarFilter)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
uistate.connect('nameformat-changed', self.build_tree)
uistate.connect('placeformat-changed', self.build_tree)
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
def person_update(self, hndl_list):
""" Deal with person updates thay may effect the Main Participants
@@ -180,71 +171,191 @@ class EventView(ListView):
"""
return 'gramps-event'
def additional_ui(self):
"""
Defines the UI string for UIManager
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
</popup>
</ui>'''
def define_actions(self):
ListView.define_actions(self)
self._add_action('FilterEdit', None, _('Event Filter Editor'),
callback=self.filter_editor,)
self._add_action('QuickReport', None,
_("Quick View"), None, None, None)
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="LocalExport">
<item>
<attribute name="action">win.ExportTab</attribute>
<attribute name="label" translatable="yes">Export View...</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
''' % _("action|_Edit..."), # to use sgettext()
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Event Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-add</property>
<property name="action-name">win.Add</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Add...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Edit...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-remove</property>
<property name="action-name">win.Remove</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-merge</property>
<property name="action-name">win.Merge</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Merge...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
'''
<menu id="Popup">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">Forward</attribute>
</item>
</section>
<section id="PopUpTree">
</section>
<section>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
<section>
<placeholder id='QuickReport'>
</placeholder>
</section>
</menu>
''' % _('action|_Edit...') # to use sgettext()
]
def get_handle_from_gramps_id(self, gid):
obj = self.dbstate.db.get_event_from_gramps_id(gid)
@@ -253,32 +364,68 @@ class EventView(ListView):
else:
return None
def add(self, obj):
def add(self, *obj):
try:
EditEvent(self.dbstate, self.uistate, [], Event())
except WindowActiveError:
pass
def remove(self, obj):
self.remove_selected_objects()
def remove(self, *obj):
"""
Method called when deleting event(s) from the event view.
"""
handles = self.selected_handles()
if len(handles) == 1:
event = self.dbstate.db.get_event_from_handle(handles[0])
msg1 = self._message1_format(event)
msg2 = self._message2_format(event)
msg2 = "%s %s" % (msg2, data_recover_msg)
QuestionDialog(msg1,
msg2,
_('_Delete Event'),
lambda: self.delete_event_response(event),
parent=self.uistate.window)
else:
MultiSelectDialog(self._message1_format,
self._message2_format,
handles,
self.dbstate.db.get_event_from_handle,
yes_func=self.delete_event_response,
parent=self.uistate.window)
def _message1_format(self, event):
"""
Header format for remove dialogs.
"""
return _('Delete {type} [{gid}]?').format(type=str(event.type),
gid=event.gramps_id)
def _message2_format(self, event):
"""
Detailed message format for the remove dialogs.
"""
return _('Deleting item will remove it from the database.')
def delete_event_response(self, event):
"""
Delete the event from the database.
"""
person_list = [item[1] for item in
self.dbstate.db.find_backlink_handles(event.handle, ['Person'])]
family_list = [item[1] for item in
self.dbstate.db.find_backlink_handles(event.handle, ['Family'])]
query = DeleteEventQuery(self.dbstate, self.uistate, event,
person_list, family_list)
query.query_response()
def remove_object_from_handle(self, handle):
person_list = [
item[1] for item in
self.dbstate.db.find_backlink_handles(handle,['Person']) ]
"""
The remove_selected_objects method is not called in this view.
"""
pass
family_list = [
item[1] for item in
self.dbstate.db.find_backlink_handles(handle,['Family']) ]
object = self.dbstate.db.get_event_from_handle(handle)
query = DeleteEventQuery(self.dbstate, self.uistate, object,
person_list, family_list)
is_used = len(person_list) + len(family_list) > 0
return (query, is_used, object)
def edit(self, obj):
def edit(self, *obj):
for handle in self.selected_handles():
event = self.dbstate.db.get_event_from_handle(handle)
try:
@@ -286,7 +433,7 @@ class EventView(ListView):
except WindowActiveError:
pass
def merge(self, obj):
def merge(self, *obj):
"""
Merge the selected events.
"""
+209 -84
View File
@@ -29,7 +29,7 @@ Family View.
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
_ = glocale.translation.sgettext
import logging
_LOG = logging.getLogger(".plugins.eventview")
#-------------------------------------------------------------------------
@@ -120,14 +120,9 @@ class FamilyView(ListView):
multiple=True,
filter_class=FamilySidebarFilter)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
uistate.connect('nameformat-changed', self.build_tree)
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
def navigation_type(self):
return 'Family'
@@ -135,84 +130,214 @@ class FamilyView(ListView):
def get_stock(self):
return 'gramps-family'
def additional_ui(self):
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menuitem action="MakeFatherActive"/>
<menuitem action="MakeMotherActive"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
</popup>
</ui>'''
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="LocalExport">
<item>
<attribute name="action">win.ExportTab</attribute>
<attribute name="label" translatable="yes">Export View...</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
''' % _("action|_Edit..."), # to use sgettext()
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Family Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-add</property>
<property name="action-name">win.Add</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Add...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Edit...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-remove</property>
<property name="action-name">win.Remove</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-merge</property>
<property name="action-name">win.Merge</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Merge...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
'''
<menu id="Popup">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">Forward</attribute>
</item>
</section>
<section id="PopUpTree">
</section>
<section>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.MakeFatherActive</attribute>
<attribute name="label" translatable="yes">'''
'''Make Father Active Person</attribute>
</item>
<item>
<attribute name="action">win.MakeMotherActive</attribute>
<attribute name="label" translatable="yes">'''
'''Make Mother Active Person</attribute>
</item>
</section>
<section>
<placeholder id='QuickReport'>
</placeholder>
</section>
</menu>
''' % _('action|_Edit...') # to use sgettext()
]
def define_actions(self):
"""Add the Forward action group to handle the Forward button."""
ListView.define_actions(self)
self._add_action('FilterEdit', None, _('Family Filter Editor'),
callback=self.filter_editor,)
self.action_list.extend([
('MakeFatherActive', self._make_father_active),
('MakeMotherActive', self._make_mother_active), ])
self.all_action = Gtk.ActionGroup(name=self.title + "/FamilyAll")
self.all_action.add_actions([
('MakeFatherActive', None, _("Make Father Active Person"),
None, None, self._make_father_active),
('MakeMotherActive', None, _("Make Mother Active Person"),
None, None, self._make_mother_active),
('QuickReport', None, _("Quick View"), None, None, None),
])
self._add_action_group(self.all_action)
def add_bookmark(self, obj):
def add_bookmark(self, *obj):
mlist = self.selected_handles()
if mlist:
self.bookmarks.add(mlist[0])
@@ -223,14 +348,14 @@ class FamilyView(ListView):
_("A bookmark could not be set because "
"no one was selected."), parent=self.uistate.window)
def add(self, obj):
def add(self, *obj):
family = Family()
try:
EditFamily(self.dbstate, self.uistate, [], family)
except WindowActiveError:
pass
def remove(self, obj):
def remove(self, *obj):
"""
Method called when deleting a family from a family view.
"""
@@ -289,7 +414,7 @@ class FamilyView(ListView):
"""
pass
def edit(self, obj):
def edit(self, *obj):
for handle in self.selected_handles():
family = self.dbstate.db.get_family_from_handle(handle)
try:
@@ -297,7 +422,7 @@ class FamilyView(ListView):
except WindowActiveError:
pass
def merge(self, obj):
def merge(self, *obj):
"""
Merge the selected families.
"""
@@ -312,7 +437,7 @@ class FamilyView(ListView):
else:
MergeFamily(self.dbstate, self.uistate, [], mlist[0], mlist[1])
def _make_father_active(self, obj):
def _make_father_active(self, *obj):
"""
Make the father of the family the active person.
"""
@@ -322,7 +447,7 @@ class FamilyView(ListView):
if family:
self.uistate.set_active(family.father_handle, 'Person')
def _make_mother_active(self, obj):
def _make_mother_active(self, *obj):
"""
Make the mother of the family the active person.
"""
+6 -47
View File
@@ -47,6 +47,7 @@ import gramps.gui.widgets.fanchart2way as fanchart2way
from gramps.gui.views.navigationview import NavigationView
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gui.utils import SystemFonts
from gramps.plugins.view.fanchartview import FanChartView
# the print settings to remember between print sessions
PRINT_SETTINGS = None
@@ -101,13 +102,9 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
dbstate.connect('active-changed', self.active_changed)
dbstate.connect('database-changed', self.change_db)
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(FanChartView.additional_ui)
self.allfonts = [x for x in enumerate(SystemFonts().get_system_fonts())]
self.func_list.update({
'<PRIMARY>J' : self.jump,
})
def navigation_type(self):
return 'Person'
@@ -144,43 +141,6 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
"""
return 'gramps-fanchart'
def additional_ui(self):
return '''<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
'''
def define_actions(self):
"""
Required define_actions function for PageView. Builds the action
@@ -188,10 +148,9 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
"""
NavigationView.define_actions(self)
self._add_action('PrintView', Gtk.STOCK_PRINT, _("_Print..."),
accel="<PRIMARY>P",
tip=_("Print or save the Fan Chart View"),
callback=self.printview)
self._add_action('PrintView', self.printview, "<PRIMARY>P")
self._add_action('PRIMARY-J', self.jump, '<PRIMARY>J')
def build_tree(self):
"""
Generic method called by PageView to construct the view.
@@ -249,7 +208,7 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
if self.active:
self.bookmarks.redraw()
def printview(self, obj):
def printview(self, *obj):
"""
Print or save the view that is currently shown
"""
+6 -47
View File
@@ -46,6 +46,7 @@ import gramps.gui.widgets.fanchartdesc as fanchartdesc
from gramps.gui.views.navigationview import NavigationView
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gui.utils import SystemFonts
from gramps.plugins.view.fanchartview import FanChartView
# the print settings to remember between print sessions
PRINT_SETTINGS = None
@@ -96,13 +97,9 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
dbstate.connect('active-changed', self.active_changed)
dbstate.connect('database-changed', self.change_db)
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(FanChartView.additional_ui)
self.allfonts = [x for x in enumerate(SystemFonts().get_system_fonts())]
self.func_list.update({
'<PRIMARY>J' : self.jump,
})
def navigation_type(self):
return 'Person'
@@ -139,43 +136,6 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
"""
return 'gramps-fanchart'
def additional_ui(self):
return '''<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
'''
def define_actions(self):
"""
Required define_actions function for PageView. Builds the action
@@ -183,10 +143,9 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
"""
NavigationView.define_actions(self)
self._add_action('PrintView', 'document-print', _("_Print..."),
accel="<PRIMARY>P",
tip=_("Print or save the Fan Chart View"),
callback=self.printview)
self._add_action('PrintView', self.printview, "<PRIMARY>P")
self._add_action('PRIMARY-J', self.jump, '<PRIMARY>J')
def build_tree(self):
"""
Generic method called by PageView to construct the view.
@@ -244,7 +203,7 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
if self.active:
self.bookmarks.redraw()
def printview(self, obj):
def printview(self, *obj):
"""
Print or save the view that is currently shown
"""
+106 -46
View File
@@ -34,7 +34,7 @@ from gi.repository import Gdk
from gi.repository import Gtk
import cairo
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
#
@@ -93,13 +93,9 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
dbstate.connect('active-changed', self.active_changed)
dbstate.connect('database-changed', self.change_db)
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
self.allfonts = [x for x in enumerate(SystemFonts().get_system_fonts())]
self.func_list.update({
'<PRIMARY>J' : self.jump,
})
def navigation_type(self):
return 'Person'
@@ -135,42 +131,107 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
"""
return 'gramps-fanchart'
def additional_ui(self):
return '''<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">_Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the default person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Fan Chart View</property>
<property name="label" translatable="yes">_Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
def define_actions(self):
"""
@@ -179,10 +240,9 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
"""
NavigationView.define_actions(self)
self._add_action('PrintView', 'document-print', _("_Print..."),
accel="<PRIMARY>P",
tip=_("Print or save the Fan Chart View"),
callback=self.printview)
self._add_action('PrintView', self.printview, "<PRIMARY>P")
self._add_action('PRIMARY-J', self.jump, '<PRIMARY>J')
def build_tree(self):
"""
Generic method called by PageView to construct the view.
@@ -240,7 +300,7 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
if self.active:
self.bookmarks.redraw()
def printview(self, obj):
def printview(self, *obj):
"""
Print or save the view that is currently shown
"""
+118 -49
View File
@@ -54,12 +54,12 @@ from gramps.gen.datehandler import displayer, get_date
from gramps.gen.display.name import displayer as _nd
from gramps.gen.display.place import displayer as _pd
from gramps.gen.utils.place import conv_lat_lon
from gramps.gui.views.navigationview import NavigationView
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.plugins.lib.maps import constants
from gramps.plugins.lib.maps.geography import GeoGraphyView
from gramps.gui.selectors import SelectorFactory
from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback)
from gramps.gui.uimanager import ActionGroup
#-------------------------------------------------------------------------
#
@@ -67,43 +67,120 @@ from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback)
#
#-------------------------------------------------------------------------
_UI_DEF = '''\
<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
<toolitem action="RefPerson"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
'''
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">_Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the default person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">gramps-person</property>
<property name="action-name">win.RefPerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Select the person which is the reference for life ways</property>
<property name="label" translatable="yes">reference _Person</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">_Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=unused-argument
@@ -291,18 +368,10 @@ class GeoClose(GeoGraphyView):
"""
Define action for the reference person button.
"""
NavigationView.define_actions(self)
GeoGraphyView.define_actions(self)
self._add_action('RefPerson', self.select_person)
self.define_print_actions()
self.ref_person = Gtk.ActionGroup(name=self.title + '/Selection')
self.ref_person.add_actions([
('RefPerson', 'gramps-person', _('reference _Person'), None,
_("Select the person which is the reference for life ways"),
self.select_person),
])
self._add_action_group(self.ref_person)
def select_person(self, obj):
def select_person(self, *obj):
"""
Open a selection box to choose the ref person.
"""
+78 -33
View File
@@ -64,39 +64,84 @@ from gramps.gui.utils import ProgressMeter
#
#-------------------------------------------------------------------------
_UI_DEF = '''\
<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
'''
_UI_DEF = ['''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">_Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">Print or save the Map</property>
<property name="label" translatable="yes">_Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=unused-argument
# pylint: disable=no-member
+117 -48
View File
@@ -65,43 +65,120 @@ from gramps.gui.selectors import SelectorFactory
#
#-------------------------------------------------------------------------
_UI_DEF = '''\
<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
<toolitem action="RefFamily"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
'''
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">_Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the default person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">gramps-family</property>
<property name="action-name">win.RefFamily</property>
<property name="tooltip_text" translatable="yes">'''
'''Select the family which is the reference for life ways</property>
<property name="label" translatable="yes">reference _Family</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">_Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=unused-variable
@@ -287,18 +364,10 @@ class GeoFamClose(GeoGraphyView):
"""
Define action for the reference family button.
"""
NavigationView.define_actions(self)
GeoGraphyView.define_actions(self)
self._add_action('RefFamily', self.select_family)
self.define_print_actions()
self.ref_family = Gtk.ActionGroup(self.title + '/Selection')
self.ref_family.add_actions([
('RefFamily', 'gramps-family', _('reference _Family'), None,
_("Select the family which is the reference for life ways"),
self.select_family),
])
self._add_action_group(self.ref_family)
def select_family(self, obj):
def select_family(self, *obj):
"""
Open a selection box to choose the ref family.
"""
+82 -33
View File
@@ -63,39 +63,88 @@ from gramps.plugins.lib.maps.geography import GeoGraphyView
#
#-------------------------------------------------------------------------
_UI_DEF = '''\
<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
'''
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">_Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">...
...Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">_Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=unused-variable
+8 -7
View File
@@ -28,7 +28,7 @@
# pylint: disable=bad-whitespace
# pylint: disable=bad-whitespace
MODULE_VERSION = "5.0"
MODULE_VERSION = "5.1"
from gi import Repository
from gramps.gen.const import GRAMPS_LOCALE as glocale
@@ -64,14 +64,15 @@ if not OSMGPSMAP:
if has_display():
from gramps.gui.dialog import MessageHideDialog
from gramps.gen.const import URL_WIKISTRING
OSMGPS_DICT = {'gramps_wiki_build_osmgps_url' :
URL_WIKISTRING +
"GEPS_029:_GTK3-GObject_introspection"
"_Conversion#OsmGpsMap_for_Geography"}
TITLE = _("OsmGpsMap module not loaded.")
MESSAGE = _("Geography functionality will not be available.\n"
"To build it for Gramps see "
"%(gramps_wiki_build_osmgps_url)s") % OSMGPS_DICT
"Try to install:\n"
" gir1.2-osmgpsmap-1.0 (debian, ubuntu, ...)\n"
" osm-gps-map-gobject-1.0.1 for fedora, ...\n"
" typelib-1_0-OsmGpsMap-1_0 for openSuse\n"
" ...\n"
"To build it for Gramps see the Wiki (<F1>)\n"
" and search for 'build from source'")
if uistate:
MessageHideDialog(TITLE, MESSAGE,
'interface.ignore-osmgpsmap',
+101 -36
View File
@@ -64,42 +64,107 @@ from gramps.plugins.lib.maps.geography import GeoGraphyView
#
#-------------------------------------------------------------------------
_UI_DEF = '''\
<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
'''
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">_Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the default person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">_Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=unused-variable
+101 -36
View File
@@ -65,42 +65,107 @@ from gramps.plugins.lib.maps.geography import GeoGraphyView
#
#-------------------------------------------------------------------------
_UI_DEF = '''\
<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
'''
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">_Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the default person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">reference _Family</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=maybe-no-member
+82 -33
View File
@@ -65,39 +65,88 @@ from gramps.gui.utils import ProgressMeter
#
#-------------------------------------------------------------------------
_UI_DEF = '''\
<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="PrintView"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="PrintView"/>
</placeholder>
</toolbar>
</ui>
'''
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">_Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">_Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=maybe-no-member
+220 -87
View File
@@ -30,7 +30,7 @@ Media View.
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
_ = glocale.translation.sgettext
import os
from urllib.parse import urlparse
from urllib.request import url2pathname
@@ -133,12 +133,7 @@ class MediaView(ListView):
filter_class=MediaSidebarFilter,
multiple=True)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
self.uistate = uistate
def navigation_type(self):
@@ -206,19 +201,10 @@ class MediaView(ListView):
"""
ListView.define_actions(self)
self._add_action('FilterEdit', None, _('Media Filter Editor'),
callback=self.filter_editor)
self._add_action('OpenMedia', 'gramps-viewmedia', _('View'),
tip=_("View in the default viewer"),
callback=self.view_media)
self._add_action('OpenContainingFolder', None,
_('Open Containing _Folder'),
tip=_("Open the folder containing the media file"),
callback=self.open_containing_folder)
self._add_action('OpenMedia', self.view_media)
self._add_action('OpenContainingFolder', self.open_containing_folder)
self._add_action('QuickReport', None, _("Quick View"), None, None, None)
def view_media(self, obj):
def view_media(self, *obj):
"""
Launch external viewers for the selected objects.
"""
@@ -227,7 +213,7 @@ class MediaView(ListView):
mpath = media_path_full(self.dbstate.db, ref_obj.get_path())
open_file_with_default_application(mpath, self.uistate)
def open_containing_folder(self, obj):
def open_containing_folder(self, *obj):
"""
Launch external viewers for the selected objects.
"""
@@ -244,78 +230,225 @@ class MediaView(ListView):
"""
return 'gramps-media'
def additional_ui(self):
"""
Return the UIManager XML description of the menus
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
</placeholder>
<separator/>
<toolitem action="OpenMedia"/>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="OpenMedia"/>
<menuitem action="OpenContainingFolder"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
</popup>
</ui>'''
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="LocalExport">
<item>
<attribute name="action">win.ExportTab</attribute>
<attribute name="label" translatable="yes">Export View...</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
''' % _("action|_Edit..."), # to use sgettext()
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Media Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-add</property>
<property name="action-name">win.Add</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Add...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Edit...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-remove</property>
<property name="action-name">win.Remove</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-merge</property>
<property name="action-name">win.Merge</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Merge...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
'''
<placeholder id='AfterTools'>
<child>
<object class="GtkToolButton">
<property name="icon-name">gramps-viewmedia</property>
<property name="action-name">win.OpenMedia</property>
<property name="tooltip_text" translatable="yes">'''
'''View in the default viewer</property>
<property name="label" translatable="yes">View</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<menu id="Popup">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">Forward</attribute>
</item>
</section>
<section id="PopUpTree">
<item>
<attribute name="action">win.OpenMedia</attribute>
<attribute name="label" translatable="yes">View</attribute>
</item>
<item>
<attribute name="action">win.OpenContainingFolder</attribute>
<attribute name="label" translatable="yes">'''
'''Open Containing _Folder</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
<section>
<placeholder id='QuickReport'>
</placeholder>
</section>
</menu>
''' % _('action|_Edit...') # to use sgettext()
]
def add(self, obj):
def add(self, *obj):
"""Add a new media object to the media list"""
try:
EditMedia(self.dbstate, self.uistate, [], Media())
except WindowActiveError:
pass
def remove(self, obj):
def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -329,7 +462,7 @@ class MediaView(ListView):
is_used = any(the_lists)
return (query, is_used, object)
def edit(self, obj):
def edit(self, *obj):
"""
Edit the selected objects in the EditMedia dialog
"""
@@ -340,7 +473,7 @@ class MediaView(ListView):
except WindowActiveError:
pass
def merge(self, obj):
def merge(self, *obj):
"""
Merge the selected objects.
"""
+191 -75
View File
@@ -28,7 +28,7 @@ Note View.
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
_ = glocale.translation.sgettext
import logging
_LOG = logging.getLogger(".plugins.noteview")
@@ -113,12 +113,7 @@ class NoteView(ListView):
filter_class=NoteSidebarFilter,
multiple=True)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
def navigation_type(self):
return 'Note'
@@ -135,70 +130,191 @@ class NoteView(ListView):
"""
return 'gramps-notes'
def additional_ui(self):
"""
Defines the UI string for UIManager
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
</popup>
</ui>'''
def define_actions(self):
ListView.define_actions(self)
self._add_action('FilterEdit', None, _('Note Filter Editor'),
callback=self.filter_editor,)
self._add_action('QuickReport', None, _("Quick View"), None, None, None)
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="LocalExport">
<item>
<attribute name="action">win.ExportTab</attribute>
<attribute name="label" translatable="yes">Export View...</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
''' % _("action|_Edit..."), # to use sgettext()
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Note Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-add</property>
<property name="action-name">win.Add</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Add...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Edit...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-remove</property>
<property name="action-name">win.Remove</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-merge</property>
<property name="action-name">win.Merge</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Merge...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
'''
<menu id="Popup">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">Forward</attribute>
</item>
</section>
<section id="PopUpTree">
</section>
<section>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
<section>
<placeholder id='QuickReport'>
</placeholder>
</section>
</menu>
''' % _('action|_Edit...') # to use sgettext()
]
def get_handle_from_gramps_id(self, gid):
obj = self.dbstate.db.get_note_from_gramps_id(gid)
@@ -207,13 +323,13 @@ class NoteView(ListView):
else:
return None
def add(self, obj):
def add(self, *obj):
try:
EditNote(self.dbstate, self.uistate, [], Note())
except WindowActiveError:
pass
def remove(self, obj):
def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -223,7 +339,7 @@ class NoteView(ListView):
is_used = any(the_lists)
return (query, is_used, object)
def edit(self, obj):
def edit(self, *obj):
for handle in self.selected_handles():
note = self.dbstate.db.get_note_from_handle(handle)
try:
@@ -231,7 +347,7 @@ class NoteView(ListView):
except WindowActiveError:
pass
def merge(self, obj):
def merge(self, *obj):
"""
Merge the selected notes.
"""
+109 -54
View File
@@ -63,7 +63,6 @@ from gramps.gui.ddtargets import DdTargets
from gramps.gen.config import config
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gen.const import CUSTOM_FILTERS
from gramps.gen.constfunc import is_quartz, win
from gramps.gui.dialog import RunDatabaseRepair, ErrorDialog
from gramps.gui.utils import color_graph_box, hex_to_rgb_float, is_right_click
from gramps.gen.constfunc import lin
@@ -528,11 +527,6 @@ class PedigreeView(NavigationView):
NavigationView.__init__(self, _('Pedigree'), pdata, dbstate, uistate,
PersonBookmarks, nav_group)
self.func_list.update({
'F2' : self.kb_goto_home,
'<PRIMARY>J' : self.jump,
})
self.dbstate = dbstate
self.dbstate.connect('database-changed', self.change_db)
uistate.connect('nameformat-changed', self.person_rebuild)
@@ -551,7 +545,7 @@ class PedigreeView(NavigationView):
self.scrolledwindow = None
self.table = None
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
# Automatic resize
self.force_size = self._config.get('interface.pedview-tree-size')
@@ -572,10 +566,6 @@ class PedigreeView(NavigationView):
self.show_unknown_people = self._config.get(
'interface.pedview-show-unknown-people')
self.func_list.update({
'<PRIMARY>J' : self.jump,
})
def get_handle_from_gramps_id(self, gid):
"""
returns the handle of the specified object
@@ -642,40 +632,91 @@ class PedigreeView(NavigationView):
return self.scrolledwindow
def additional_ui(self):
"""
Specifies the UIManager XML code that defines the menus and buttons
associated with the interface.
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<menuitem action="FilterEdit"/>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
</toolbar>
</ui>'''
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Person Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the default person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
def define_actions(self):
"""
@@ -692,10 +733,11 @@ class PedigreeView(NavigationView):
"""
NavigationView.define_actions(self)
self._add_action('FilterEdit', None, _('Person Filter Editor'),
callback=self.cb_filter_editor)
self._add_action('FilterEdit', self.cb_filter_editor)
self._add_action('F2', self.kb_goto_home, 'F2')
self._add_action('PRIMARY-J', self.jump, '<PRIMARY>J')
def cb_filter_editor(self, obj):
def cb_filter_editor(self, *obj):
"""
Display the person filter editor.
"""
@@ -1281,6 +1323,13 @@ class PedigreeView(NavigationView):
if defperson:
self.change_active(defperson.get_handle())
def cb_set_home(self, menuitem, handle):
"""Set the root person to current person for database."""
active = self.uistate.get_active('Person')
if active:
self.dbstate.db.set_default_person_handle(handle)
self.cb_home(None)
def cb_edit_person(self, obj, person_handle):
"""
Open edit person window for person_handle.
@@ -1353,7 +1402,7 @@ class PedigreeView(NavigationView):
"""Right click option menu."""
self.menu = Gtk.Menu()
self.menu.set_reserve_toggle_size(False)
self.add_nav_portion_to_menu(self.menu)
self.add_nav_portion_to_menu(self.menu, None)
self.add_settings_to_menu(self.menu)
self.menu.popup(None, None, None, None, 0, event.time)
return True
@@ -1512,7 +1561,7 @@ class PedigreeView(NavigationView):
else:
self.scroll_direction = False
def kb_goto_home(self):
def kb_goto_home(self, *obj):
"""Goto home person from keyboard."""
self.cb_home(None)
@@ -1560,7 +1609,7 @@ class PedigreeView(NavigationView):
mother_handle)
self.find_tree(mother, (2*index)+2, depth+1, lst, mrel)
def add_nav_portion_to_menu(self, menu):
def add_nav_portion_to_menu(self, menu, person_handle):
"""
This function adds a common history-navigation portion
to the context menu. Used by both build_nav_menu() and
@@ -1585,6 +1634,12 @@ class PedigreeView(NavigationView):
item.connect("activate", callback)
item.show()
menu.append(item)
item = Gtk.MenuItem.new_with_mnemonic(_("Set _Home Person"))
item.connect("activate", self.cb_set_home, person_handle)
if person_handle is None:
item.set_sensitive(False)
item.show()
menu.append(item)
def add_settings_to_menu(self, menu):
"""
@@ -1637,7 +1692,7 @@ class PedigreeView(NavigationView):
self.menu.append(add_item)
# Add history-based navigation
self.add_nav_portion_to_menu(self.menu)
self.add_nav_portion_to_menu(self.menu, None)
self.add_settings_to_menu(self.menu)
self.menu.popup(None, None, None, None, 0, event.time)
return 1
@@ -1874,7 +1929,7 @@ class PedigreeView(NavigationView):
self.menu.append(item)
# Add history-based navigation
self.add_nav_portion_to_menu(self.menu)
self.add_nav_portion_to_menu(self.menu, person_handle)
self.add_settings_to_menu(self.menu)
self.menu.popup(None, None, None, None, 0, event.time)
return 1
@@ -1905,7 +1960,7 @@ class PedigreeView(NavigationView):
self.menu.append(item)
# Add history-based navigation
self.add_nav_portion_to_menu(self.menu)
self.add_nav_portion_to_menu(self.menu, None)
self.add_settings_to_menu(self.menu)
self.menu.popup(None, None, None, None, 0, event.time)
return 1
+20 -74
View File
@@ -78,82 +78,28 @@ class PersonTreeView(BasePersonView):
"""
BasePersonView.define_actions(self)
self.all_action.add_actions([
('OpenAllNodes', None, _("Expand all Nodes"), None, None,
self.open_all_nodes),
('CloseAllNodes', None, _("Collapse all Nodes"), None, None,
self.close_all_nodes),
])
self.action_list.extend([
('OpenAllNodes', self.open_all_nodes),
('CloseAllNodes', self.close_all_nodes)])
def additional_ui(self):
"""
Defines the UI string for UIManager
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="SetActive"/>
<menuitem action="FilterEdit"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<menuitem action="HomePerson"/>
<separator/>
<menuitem action="OpenAllNodes"/>
<menuitem action="CloseAllNodes"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
<menu name="WebConnect" action="WebConnect"/>
</popup>
</ui>'''
additional_ui = BasePersonView.additional_ui[:]
additional_ui.append( # Defines the UI string for UIManager
'''
<section id="PopUpTree">
<item>
<attribute name="action">win.OpenAllNodes</attribute>
<attribute name="label" translatable="yes">'''
'''Expand all Nodes</attribute>
</item>
<item>
<attribute name="action">win.CloseAllNodes</attribute>
<attribute name="label" translatable="yes">'''
'''Collapse all Nodes</attribute>
</item>
</section>
''')
def add(self, obj):
def add(self, *obj):
person = Person()
# attempt to get the current surname
+31 -72
View File
@@ -67,80 +67,39 @@ class PlaceTreeView(PlaceBaseView):
"""
PlaceBaseView.define_actions(self)
self._add_action('OpenBranch', None, _("Expand this Entire Group"),
callback=self.open_branch)
self._add_action('CloseBranch', None, _("Collapse this Entire Group"),
callback=self.close_branch)
self._add_action('OpenAllNodes', None, _("Expand all Nodes"),
callback=self.open_all_nodes)
self._add_action('CloseAllNodes', None, _("Collapse all Nodes"),
callback=self.close_all_nodes)
self._add_action('OpenBranch', self.open_branch)
self._add_action('CloseBranch', self.close_branch)
self._add_action('OpenAllNodes', self.open_all_nodes)
self._add_action('CloseAllNodes', self.close_all_nodes)
def additional_ui(self):
"""
A user interface definition including tree specific actions.
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
<separator/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="OpenBranch"/>
<menuitem action="CloseBranch"/>
<menuitem action="OpenAllNodes"/>
<menuitem action="CloseAllNodes"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
<separator/>
<menuitem action="GotoMap"/>
</popup>
</ui>'''
additional_ui = PlaceBaseView.additional_ui[:]
additional_ui.append(
'''
<section id="PopUpTree">
<item>
<attribute name="action">win.OpenBranch</attribute>
<attribute name="label" translatable="yes">'''
'''Expand this Entire Group</attribute>
</item>
<item>
<attribute name="action">win.CloseBranch</attribute>
<attribute name="label" translatable="yes">'''
'''Collapse this Entire Group</attribute>
</item>
<item>
<attribute name="action">win.OpenAllNodes</attribute>
<attribute name="label" translatable="yes">'''
'''Expand all Nodes</attribute>
</item>
<item>
<attribute name="action">win.CloseAllNodes</attribute>
<attribute name="label" translatable="yes">'''
'''Collapse all Nodes</attribute>
</item>
</section>
''')
def add(self, obj):
def add(self, *obj):
"""
Add a new place. Use the currently selected rows as parent places.
"""
+196 -95
View File
@@ -60,7 +60,7 @@ from gramps.gen.lib import (ChildRef, EventRoleType, EventType, Family,
from gramps.gen.lib.date import Today
from gramps.gen.db import DbTxn
from gramps.gui.views.navigationview import NavigationView
from gramps.gui.actiongroup import ActionGroup
from gramps.gui.uimanager import ActionGroup
from gramps.gui.editors import EditPerson, EditFamily
from gramps.gui.editors import FilterEditor
from gramps.gen.display.name import displayer as name_displayer
@@ -138,10 +138,6 @@ class RelationshipView(NavigationView):
PersonBookmarks,
nav_group)
self.func_list.update({
'<PRIMARY>J' : self.jump,
})
dbstate.connect('database-changed', self.change_db)
uistate.connect('nameformat-changed', self.build_tree)
uistate.connect('placeformat-changed', self.build_tree)
@@ -153,7 +149,7 @@ class RelationshipView(NavigationView):
self.reorder_sensitive = False
self.collapsed_items = {}
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
self.show_siblings = self._config.get('preferences.family-siblings')
self.show_details = self._config.get('preferences.family-details')
@@ -335,101 +331,205 @@ class RelationshipView(NavigationView):
container.show_all()
return container
def additional_ui(self):
"""
Specifies the UIManager XML code that defines the menus and buttons
associated with the interface.
"""
return '''<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="HomePerson"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<menuitem action="Edit"/>
<menuitem action="AddParentsMenu"/>
<menuitem action="ShareFamilyMenu"/>
<menuitem action="AddSpouseMenu"/>
<menuitem action="ChangeOrder"/>
<menuitem action="FilterEdit"/>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="ViewMenu">
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Edit"/>
<toolitem action="AddParents"/>
<toolitem action="ShareFamily"/>
<toolitem action="AddSpouse"/>
<toolitem action="ChangeOrder"/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<menuitem action="HomePerson"/>
<separator/>
</popup>
</ui>'''
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">'''
'''Organize Bookmarks...</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">Edit...</attribute>
</item>
<item>
<attribute name="action">win.AddParents</attribute>
<attribute name="label" translatable="yes">'''
'''Add New Parents...</attribute>
</item>
<item>
<attribute name="action">win.ShareFamily</attribute>
<attribute name="label" translatable="yes">'''
'''Add Existing Parents...</attribute>
</item>
<item>
<attribute name="action">win.AddSpouse</attribute>
<attribute name="label" translatable="yes">Add Partner...</attribute>
</item>
<item>
<attribute name="action">win.ChangeOrder</attribute>
<attribute name="label" translatable="yes">_Reorder</attribute>
</item>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Person Filter Editor</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the default person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">'''
'''Edit the active person</property>
<property name="label" translatable="yes">Edit...</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-parents-add</property>
<property name="action-name">win.AddParents</property>
<property name="tooltip_text" translatable="yes">'''
'''Add a new set of parents</property>
<property name="label" translatable="yes">Add</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-parents-open</property>
<property name="action-name">win.ShareFamily</property>
<property name="tooltip_text" translatable="yes">'''
'''Add person as child to an existing family</property>
<property name="label" translatable="yes">Share</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-spouse</property>
<property name="action-name">win.AddSpouse</property>
<property name="tooltip_text" translatable="yes">'''
'''Add a new family with person as parent</property>
<property name="label" translatable="yes">Partner</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">view-sort-ascending</property>
<property name="action-name">win.ChangeOrder</property>
<property name="tooltip_text" translatable="yes">'''
'''Change order of parents and families</property>
<property name="label" translatable="yes">_Reorder</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
def define_actions(self):
NavigationView.define_actions(self)
self.order_action = ActionGroup(name=self.title + '/ChangeOrder')
self.order_action.add_actions([
('ChangeOrder', 'view-sort-ascending', _('_Reorder'), None ,
_("Change order of parents and families"), self.reorder),
])
('ChangeOrder', self.reorder)])
self.family_action = ActionGroup(name=self.title + '/Family')
self.family_action.add_actions([
('Edit', 'gtk-edit', _('Edit...'), "<PRIMARY>Return",
_("Edit the active person"), self.edit_active),
('AddSpouse', 'gramps-spouse', _('Partner'), None ,
_("Add a new family with person as parent"), self.add_spouse),
('AddSpouseMenu', 'gramps-spouse', _('Add Partner...'), None ,
_("Add a new family with person as parent"), self.add_spouse),
('AddParents', 'gramps-parents-add', _('Add'), None ,
_("Add a new set of parents"), self.add_parents),
('AddParentsMenu', 'gramps-parents-add', _('Add New Parents...'),
None, _("Add a new set of parents"), self.add_parents),
('ShareFamily', 'gramps-parents-open', _('Share'),
None , _("Add person as child to an existing family"),
self.select_parents),
('ShareFamilyMenu', 'gramps-parents-open',
_('Add Existing Parents...'), None ,
_("Add person as child to an existing family"),
self.select_parents),
])
('Edit', self.edit_active, "<PRIMARY>Return"),
('AddSpouse', self.add_spouse),
('AddParents', self.add_parents),
('ShareFamily', self.select_parents)])
self._add_action('FilterEdit', None, _('Person Filter Editor'),
callback=self.filter_editor)
self._add_action('FilterEdit', callback=self.filter_editor)
self._add_action('PRIMARY-J', self.jump, '<PRIMARY>J')
self._add_action_group(self.order_action)
self._add_action_group(self.family_action)
self.order_action.set_sensitive(self.reorder_sensitive)
self.family_action.set_sensitive(False)
self.uimanager.set_actions_sensitive(self.order_action,
self.reorder_sensitive)
self.uimanager.set_actions_sensitive(self.family_action, False)
def filter_editor(self, obj):
def filter_editor(self, *obj):
try:
FilterEditor('Person', CUSTOM_FILTERS,
self.dbstate, self.uistate)
@@ -504,11 +604,11 @@ class RelationshipView(NavigationView):
if obj:
person = self.dbstate.db.get_person_from_handle(obj)
if not person:
self.family_action.set_sensitive(False)
self.order_action.set_sensitive(False)
self.uimanager.set_actions_sensitive(self.family_action, False)
self.uimanager.set_actions_sensitive(self.order_action, False)
self.redrawing = False
return
self.family_action.set_sensitive(True)
self.uimanager.set_actions_sensitive(self.family_action, True)
self.write_title(person)
@@ -548,7 +648,8 @@ class RelationshipView(NavigationView):
self.redrawing = False
self.uistate.modify_statusbar(self.dbstate)
self.order_action.set_sensitive(self.reorder_sensitive)
self.uimanager.set_actions_sensitive(self.order_action,
self.reorder_sensitive)
self.dirty = False
return True
@@ -1487,7 +1588,7 @@ class RelationshipView(NavigationView):
except WindowActiveError:
pass
def add_spouse(self, obj):
def add_spouse(self, *obj):
family = Family()
person = self.dbstate.db.get_person_from_handle(self.get_active())
@@ -1504,7 +1605,7 @@ class RelationshipView(NavigationView):
except WindowActiveError:
pass
def edit_active(self, obj):
def edit_active(self, obj, value):
phandle = self.get_active()
self.edit_person(obj, phandle)
@@ -1575,7 +1676,7 @@ class RelationshipView(NavigationView):
self.dbstate.db.add_child_to_family(family, child)
def select_parents(self, obj):
def select_parents(self, *obj):
SelectFamily = SelectorFactory('Family')
phandle = self.get_active()
@@ -1591,7 +1692,7 @@ class RelationshipView(NavigationView):
self.dbstate.db.add_child_to_family(family, child)
def add_parents(self, obj):
def add_parents(self, *obj):
family = Family()
person = self.dbstate.db.get_person_from_handle(self.get_active())
@@ -1636,7 +1737,7 @@ class RelationshipView(NavigationView):
if button_activated(event, _LEFT_BUTTON):
self.reorder(obj)
def reorder(self, obj, dumm1=None, dummy2=None):
def reorder(self, *obj):
if self.get_active():
try:
Reorder(self.dbstate, self.uistate, [], self.get_active())
+191 -73
View File
@@ -53,7 +53,7 @@ from gramps.gen.plug import CATEGORY_QR_REPOSITORY
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
@@ -132,12 +132,7 @@ class RepositoryView(ListView):
multiple=True,
filter_class=RepoSidebarFilter)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
self.additional_uis.append(self.additional_ui())
self.additional_uis.append(self.additional_ui)
def navigation_type(self):
return 'Repository'
@@ -145,76 +140,199 @@ class RepositoryView(ListView):
def drag_info(self):
return DdTargets.REPO_LINK
def define_actions(self):
ListView.define_actions(self)
self._add_action('FilterEdit', None, _('Repository Filter Editor'),
callback=self.filter_editor,)
self._add_action('QuickReport', None,
_("Quick View"), None, None, None)
def get_stock(self):
return 'gramps-repository'
def additional_ui(self):
return '''<ui>
<menubar name="MenuBar">
<menu action="FileMenu">
<placeholder name="LocalExport">
<menuitem action="ExportTab"/>
</placeholder>
</menu>
<menu action="BookMenu">
<placeholder name="AddEditBook">
<menuitem action="AddBook"/>
<menuitem action="EditBook"/>
</placeholder>
</menu>
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
</placeholder>
</menu>
<menu action="EditMenu">
<placeholder name="CommonEdit">
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
</placeholder>
</toolbar>
<popup name="Popup">
<menuitem action="Back"/>
<menuitem action="Forward"/>
<separator/>
<menuitem action="Add"/>
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
</popup>
</ui>'''
additional_ui = [ # Defines the UI string for UIManager
'''
<placeholder id="LocalExport">
<item>
<attribute name="action">win.ExportTab</attribute>
<attribute name="label" translatable="yes">Export View...</attribute>
</item>
</placeholder>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'),
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
''' % _("action|_Edit..."), # to use sgettext()
'''
<placeholder id='otheredit'>
<item>
<attribute name="action">win.FilterEdit</attribute>
<attribute name="label" translatable="yes">'''
'''Repository Filter Editor</attribute>
</item>
</placeholder>
''', # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-add</property>
<property name="action-name">win.Add</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Add...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gtk-edit</property>
<property name="action-name">win.Edit</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">Edit...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">list-remove</property>
<property name="action-name">win.Remove</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RW'>
<object class="GtkToolButton">
<property name="icon-name">gramps-merge</property>
<property name="action-name">win.Merge</property>
<property name="tooltip_text" translatable="yes">%s</property>
<property name="label" translatable="yes">_Merge...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
'''
<menu id="Popup">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">Forward</attribute>
</item>
</section>
<section id="PopUpTree">
</section>
<section>
<item>
<attribute name="action">win.Add</attribute>
<attribute name="label" translatable="yes">_Add...</attribute>
</item>
<item>
<attribute name="action">win.Edit</attribute>
<attribute name="label" translatable="yes">%s</attribute>
</item>
<item>
<attribute name="action">win.Remove</attribute>
<attribute name="label" translatable="yes">_Delete</attribute>
</item>
<item>
<attribute name="action">win.Merge</attribute>
<attribute name="label" translatable="yes">_Merge...</attribute>
</item>
</section>
<section>
<placeholder id='QuickReport'>
</placeholder>
</section>
</menu>
''' % _('action|_Edit...') # to use sgettext()
]
def add(self, obj):
def add(self, *obj):
EditRepository(self.dbstate, self.uistate, [], Repository())
def remove(self, obj):
def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -227,7 +345,7 @@ class RepositoryView(ListView):
is_used = len(source_list) > 0
return (query, is_used, object)
def edit(self, obj):
def edit(self, *obj):
for handle in self.selected_handles():
repos = self.dbstate.db.get_repository_from_handle(handle)
try:
@@ -235,7 +353,7 @@ class RepositoryView(ListView):
except WindowActiveError:
pass
def merge(self, obj):
def merge(self, *obj):
"""
Merge the selected repositories.
"""
Loaded 100 of 155 files, more files were not shown because too many files have changed in this diff. Show more