Compare commits
513
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5b0d2e347 | ||
|
|
d6e1ebf801 | ||
|
|
236028d808 | ||
|
|
3c6253d4ff | ||
|
|
ca154e46cd | ||
|
|
d087a88d93 | ||
|
|
498284b2ba | ||
|
|
84eb262c26 | ||
|
|
497cc66a20 | ||
|
|
9d28157f31 | ||
|
|
7683470cf3 | ||
|
|
f48d15de5c | ||
|
|
5704b4d113 | ||
|
|
a35defb35e | ||
|
|
164db015e9 | ||
|
|
afd0dbf40e | ||
|
|
fca7917515 | ||
|
|
e4a8cc44ae | ||
|
|
7d93d35994 | ||
|
|
8a41d0afd9 | ||
|
|
9a83d2341b | ||
|
|
776c4b639a | ||
|
|
545ec06e6d | ||
|
|
debe141034 | ||
|
|
135e5639e1 | ||
|
|
9c7c5453b1 | ||
|
|
de34eab12c | ||
|
|
4b2030d48b | ||
|
|
52f4f76c82 | ||
|
|
6a9be24e1c | ||
|
|
487435d411 | ||
|
|
c6dcfef776 | ||
|
|
5866b28877 | ||
|
|
e9b643c5d6 | ||
|
|
4cc6d3f904 | ||
|
|
f18c6c9189 | ||
|
|
aae0360818 | ||
|
|
f649702b1d | ||
|
|
83c2b7940d | ||
|
|
3f0475b252 | ||
|
|
9c1af31a35 | ||
|
|
431effe789 | ||
|
|
2bc8f50ac2 | ||
|
|
5a6e6959de | ||
|
|
5b5bf3344f | ||
|
|
af15d80cdb | ||
|
|
613c11b64f | ||
|
|
dec5bb6390 | ||
|
|
fb178130c8 | ||
|
|
93812faa40 | ||
|
|
6d990ba147 | ||
|
|
f8316f1794 | ||
|
|
e36d39f208 | ||
|
|
dbc96aad2e | ||
|
|
990a833d21 | ||
|
|
af25513134 | ||
|
|
853d2a638d | ||
|
|
a4c22a3b46 | ||
|
|
963f99536e | ||
|
|
6844392c3d | ||
|
|
a7bc1ad0f8 | ||
|
|
01f6e569a7 | ||
|
|
6d533d4c35 | ||
|
|
55e41fadf4 | ||
|
|
ee5ee7db3f | ||
|
|
5fdcc32703 | ||
|
|
b4aa00dac7 | ||
|
|
834662a823 | ||
|
|
b25211037a | ||
|
|
35a03d7994 | ||
|
|
1a7fad0ab1 | ||
|
|
ac84dc2e26 | ||
|
|
e6ddc51d72 | ||
|
|
e6c1c5f689 | ||
|
|
5a44ced7b1 | ||
|
|
ba9e469215 | ||
|
|
7cc523ac4e | ||
|
|
f8d54b64bc | ||
|
|
ce3c465ef5 | ||
|
|
275e9eebfd | ||
|
|
c9cb640f28 | ||
|
|
3eaa8115c2 | ||
|
|
285e23303c | ||
|
|
bda858cc5f | ||
|
|
597e6a150d | ||
|
|
b9c091a72e | ||
|
|
2732634e98 | ||
|
|
23f0fae4e3 | ||
|
|
f459fc1ee4 | ||
|
|
602097c854 | ||
|
|
75991dd5cd | ||
|
|
c5951cab7c | ||
|
|
4c4605e744 | ||
|
|
fcab11a0ee | ||
|
|
28e4707cd1 | ||
|
|
ffe4ea5306 | ||
|
|
809a810c37 | ||
|
|
d1592c55be | ||
|
|
14c76f563f | ||
|
|
7ba22af095 | ||
|
|
fba0650302 | ||
|
|
4b5383170c | ||
|
|
9d78dd6613 | ||
|
|
31e415f442 | ||
|
|
fe54661b54 | ||
|
|
e0570c9d3a | ||
|
|
615abec162 | ||
|
|
d71ccad5b5 | ||
|
|
4b694197cf | ||
|
|
38651e2349 | ||
|
|
bd9393ddbf | ||
|
|
a6ecbce949 | ||
|
|
690c95b098 | ||
|
|
f89f313836 | ||
|
|
49d21ff189 | ||
|
|
0687de05f4 | ||
|
|
562c14ebb4 | ||
|
|
b135a50fe9 | ||
|
|
51db87f2c4 | ||
|
|
6335ba09de | ||
|
|
0e6b7ed78b | ||
|
|
ac8bfe2732 | ||
|
|
e8835aa513 | ||
|
|
91cf708449 | ||
|
|
d397a2a64f | ||
|
|
95e0b720a9 | ||
|
|
3552b01910 | ||
|
|
2da9d7e1ab | ||
|
|
5e7f896e92 | ||
|
|
d47c4534c6 | ||
|
|
20d1cb0110 | ||
|
|
8abec7ba25 | ||
|
|
465c9d1a0b | ||
|
|
7947af1fb7 | ||
|
|
e291b76c00 | ||
|
|
2cde7624f5 | ||
|
|
6eb3c3f9b2 | ||
|
|
0ebbeb30b8 | ||
|
|
82500dc151 | ||
|
|
1f576221d7 | ||
|
|
b7b5045497 | ||
|
|
37db7366c1 | ||
|
|
30acde6546 | ||
|
|
26fed05e64 | ||
|
|
2554a1decd | ||
|
|
cfa140e165 | ||
|
|
fbc6414670 | ||
|
|
8cc62188e1 | ||
|
|
40399556c2 | ||
|
|
940b2471c4 | ||
|
|
718b763b6d | ||
|
|
234994bfaf | ||
|
|
c62229a449 | ||
|
|
f4b5710959 | ||
|
|
84d1485cec | ||
|
|
960a62b4c8 | ||
|
|
94313ae388 | ||
|
|
d43de411bc | ||
|
|
6d48930121 | ||
|
|
5bd5a98ba9 | ||
|
|
26dd3db5bc | ||
|
|
057c962fe0 | ||
|
|
bd8f5317ba | ||
|
|
6a6ccadf6a | ||
|
|
4cd92c86e1 | ||
|
|
2cfdd5f179 | ||
|
|
1c41b04d3d | ||
|
|
57456a3fdf | ||
|
|
28babdfd20 | ||
|
|
83177dbe7b | ||
|
|
5ccc779779 | ||
|
|
6cd32e4b74 | ||
|
|
f0f32f6122 | ||
|
|
c81b322009 | ||
|
|
d7fcfc6fb1 | ||
|
|
466bffef30 | ||
|
|
7272f94206 | ||
|
|
450991f5c3 | ||
|
|
76c8eb47cf | ||
|
|
07218ca4c4 | ||
|
|
1d1281ae10 | ||
|
|
c207cf819b | ||
|
|
b294f3608b | ||
|
|
7423eec380 | ||
|
|
59c14c507c | ||
|
|
9d055bb444 | ||
|
|
494311f234 | ||
|
|
56762c8444 | ||
|
|
6eb21926ed | ||
|
|
1de0ef724f | ||
|
|
6e5f90e580 | ||
|
|
cdaddc3479 | ||
|
|
641adf57de | ||
|
|
1e34c037f3 | ||
|
|
501be49025 | ||
|
|
94f8838dd6 | ||
|
|
a5f68318db | ||
|
|
02cd032f72 | ||
|
|
ee565d5d6b | ||
|
|
b09fa93eea | ||
|
|
48abb86bb8 | ||
|
|
eb337a8d29 | ||
|
|
52e908a5a1 | ||
|
|
9e8420aaac | ||
|
|
72767dce85 | ||
|
|
385c3c3d9b | ||
|
|
b9e1ba0195 | ||
|
|
f1ded0d689 | ||
|
|
f45b4316b5 | ||
|
|
49599fa9c3 | ||
|
|
170336d573 | ||
|
|
78216846f2 | ||
|
|
b236953ebe | ||
|
|
c4a2e2791d | ||
|
|
705fbf4007 | ||
|
|
72838423a0 | ||
|
|
a5970e71bc | ||
|
|
430124cdc4 | ||
|
|
4e7b70b2b4 | ||
|
|
5125046ac1 | ||
|
|
a2a8faec04 | ||
|
|
8476afd5f3 | ||
|
|
500435cf98 | ||
|
|
47f9471b55 | ||
|
|
ea9ed2ddde | ||
|
|
bd4e7688a7 | ||
|
|
1b32bc543c | ||
|
|
ccf9f5b311 | ||
|
|
9b5749fc8e | ||
|
|
53b832c4f8 | ||
|
|
94ff7d085a | ||
|
|
3c2cc180c4 | ||
|
|
b49b9f7941 | ||
|
|
5f31494546 | ||
|
|
ee26d9b0d5 | ||
|
|
dddfd7f083 | ||
|
|
ba01db947b | ||
|
|
1157557105 | ||
|
|
c09cf15e78 | ||
|
|
8e4d65cfc0 | ||
|
|
70bfdbf73a | ||
|
|
9c2027e437 | ||
|
|
1da2cb2ab2 | ||
|
|
71ed8bd1fc | ||
|
|
17afb65f7a | ||
|
|
ba627e4e9d | ||
|
|
66142929da | ||
|
|
2ecd1e022e | ||
|
|
6b858a2385 | ||
|
|
917714b9c6 | ||
|
|
8c73b202c3 | ||
|
|
5befb6046b | ||
|
|
1fafeab275 | ||
|
|
6eb37cbdcf | ||
|
|
b0ef00da80 | ||
|
|
ce44bc6b8d | ||
|
|
45561e1596 | ||
|
|
f19488da77 | ||
|
|
de2a2c2e67 | ||
|
|
afbf70ed3f | ||
|
|
0b7d3bcb41 | ||
|
|
bc49dcb2d9 | ||
|
|
5386daf355 | ||
|
|
505ec7440c | ||
|
|
c980ef955a | ||
|
|
177044c5db | ||
|
|
d107631a40 | ||
|
|
b817556ccd | ||
|
|
a91dc48e42 | ||
|
|
25c01a5a78 | ||
|
|
431985b420 | ||
|
|
baca380914 | ||
|
|
5652e047e6 | ||
|
|
da52e4cdcb | ||
|
|
4c9752d6bc | ||
|
|
c322cbfd5f | ||
|
|
77afdabed8 | ||
|
|
b3d21f8454 | ||
|
|
9aede5be4f | ||
|
|
c4282e685d | ||
|
|
d1716a8387 | ||
|
|
10e437384c | ||
|
|
581c713311 | ||
|
|
0637992264 | ||
|
|
8e3560821d | ||
|
|
d5502f02df | ||
|
|
d50a527fd4 | ||
|
|
71e08f0ef7 | ||
|
|
b29f07c524 | ||
|
|
0b3cbc5c12 | ||
|
|
507e9ec8d6 | ||
|
|
29bf07cb1c | ||
|
|
25864a5d16 | ||
|
|
840e77aec8 | ||
|
|
fc9759c177 | ||
|
|
5acd0f70c8 | ||
|
|
b8f71776d2 | ||
|
|
c9172e064f | ||
|
|
6d8dbdae60 | ||
|
|
cd24dc27bf | ||
|
|
76da035636 | ||
|
|
6da75fba18 | ||
|
|
4297c5c77f | ||
|
|
d0609e0666 | ||
|
|
bce48c7231 | ||
|
|
e9295da5a1 | ||
|
|
8e82370798 | ||
|
|
34fa469ffe | ||
|
|
517ab79472 | ||
|
|
9a85727a75 | ||
|
|
8619a1b03d | ||
|
|
19df538d3e | ||
|
|
e07febd145 | ||
|
|
6659dcc927 | ||
|
|
5ecb4d2145 | ||
|
|
44a1904dbd | ||
|
|
cb3d543bd6 | ||
|
|
514e8f9d3f | ||
|
|
5fcab02199 | ||
|
|
29750623a9 | ||
|
|
79cc2ba4b1 | ||
|
|
4f177aa1d9 | ||
|
|
116ec44e79 | ||
|
|
5f618ba6ec | ||
|
|
d48d1122f3 | ||
|
|
c2db8cf1fb | ||
|
|
c9913ba9eb | ||
|
|
a972560b9a | ||
|
|
0a3a99769d | ||
|
|
c84ac60e96 | ||
|
|
7eb951c8cd | ||
|
|
a9c2363951 | ||
|
|
fdf94834c5 | ||
|
|
e94fb3f66f | ||
|
|
12a642b166 | ||
|
|
fca98024fc | ||
|
|
5e30c890b9 | ||
|
|
c5b0bdffe1 | ||
|
|
bbfb853ee9 | ||
|
|
878931e076 | ||
|
|
ad71da397f | ||
|
|
6470c49eda | ||
|
|
a3656c2be5 | ||
|
|
81a83ce2d9 | ||
|
|
400c0db84b | ||
|
|
ea2d2eb2f5 | ||
|
|
f0852c0a41 | ||
|
|
a10093408e | ||
|
|
1b56b2e9fe | ||
|
|
e9d2e361da | ||
|
|
bb8a97372c | ||
|
|
b37590b2b5 | ||
|
|
1e79a2aed6 | ||
|
|
42e2e8960d | ||
|
|
3a4781aaa0 | ||
|
|
4d900e41e8 | ||
|
|
1566aa7f43 | ||
|
|
3b21c9457c | ||
|
|
c0ef6c74a7 | ||
|
|
b9200ade80 | ||
|
|
f597681a11 | ||
|
|
7f9afcec58 | ||
|
|
180995643b | ||
|
|
9e9d522099 | ||
|
|
0015f16e9f | ||
|
|
6d0b902aab | ||
|
|
f185911423 | ||
|
|
c7127fe162 | ||
|
|
c6633a559e | ||
|
|
5d84e3b1e2 | ||
|
|
d10d443c9d | ||
|
|
930c47b290 | ||
|
|
3ae4e233db | ||
|
|
bdbcc5efb2 | ||
|
|
231a26fbf0 | ||
|
|
9d3c20898c | ||
|
|
b2a8a557ab | ||
|
|
4f92f8d713 | ||
|
|
708ab325bd | ||
|
|
9fa3b9a9d2 | ||
|
|
7cdbc88fc3 | ||
|
|
3153f10118 | ||
|
|
8efc6f0184 | ||
|
|
797075b59f | ||
|
|
95e5848d03 | ||
|
|
05f91734e2 | ||
|
|
15a9ca94f3 | ||
|
|
e43452178c | ||
|
|
722af724f9 | ||
|
|
d0606fe836 | ||
|
|
9ccef7848e | ||
|
|
37063335fe | ||
|
|
69dbf66558 | ||
|
|
65c3b60c55 | ||
|
|
f0c39aae21 | ||
|
|
42fbb1aa57 | ||
|
|
6e2827a62e | ||
|
|
6dbc57aaac | ||
|
|
31fb009b66 | ||
|
|
6f43a05424 | ||
|
|
c2a49e1dd8 | ||
|
|
0dda10baf9 | ||
|
|
8ce73d3956 | ||
|
|
1a2b50e645 | ||
|
|
cc52eab90d | ||
|
|
fee2d84f67 | ||
|
|
a614049b08 | ||
|
|
1d7d2c5289 | ||
|
|
b5f738859a | ||
|
|
ae56bee828 | ||
|
|
254930fc55 | ||
|
|
c200651f74 | ||
|
|
7f7b155e36 | ||
|
|
02a02b8499 | ||
|
|
890be35845 | ||
|
|
e16e91d973 | ||
|
|
72f4ca9df9 | ||
|
|
0bfb3a622d | ||
|
|
c34b30fa0d | ||
|
|
5417a69408 | ||
|
|
5c04db932d | ||
|
|
146dcc3773 | ||
|
|
3cf4da5cee | ||
|
|
57ed71a842 | ||
|
|
06d28806f3 | ||
|
|
c4d27e603d | ||
|
|
20baece6b3 | ||
|
|
666df8e6f2 | ||
|
|
e498b18d52 | ||
|
|
3ebb888cce | ||
|
|
dabf4f4756 | ||
|
|
dda2662b0b | ||
|
|
d1ae849c1b | ||
|
|
237c4a055b | ||
|
|
fbd2afdf8c | ||
|
|
844cb231c7 | ||
|
|
eb42ce4ce2 | ||
|
|
ecc30300d4 | ||
|
|
a533c3abd4 | ||
|
|
1edbdc33d9 | ||
|
|
9b017678ad | ||
|
|
d7c5e02a55 | ||
|
|
2445590149 | ||
|
|
0f2d8769f0 | ||
|
|
a7e6e1b089 | ||
|
|
e36ffede8e | ||
|
|
bac46805f9 | ||
|
|
1e0e05a43e | ||
|
|
cd04faca60 | ||
|
|
86d0cc8b26 | ||
|
|
2f2a0712a0 | ||
|
|
8ca8e2f4bd | ||
|
|
c645246b2c | ||
|
|
8de51db5fe | ||
|
|
795a745793 | ||
|
|
3d057838ff | ||
|
|
cc6e62dc66 | ||
|
|
c98e4e94df | ||
|
|
5224211634 | ||
|
|
04bb731620 | ||
|
|
c1274ebdef | ||
|
|
d6d7855caa | ||
|
|
c844f30bd0 | ||
|
|
505ab40201 | ||
|
|
4937994904 | ||
|
|
1c556b7134 | ||
|
|
ba5c5835f9 | ||
|
|
6b78d5ae01 | ||
|
|
56de9475f6 | ||
|
|
a92154970b | ||
|
|
7fce761948 | ||
|
|
80e78696ab | ||
|
|
6f3186c82c | ||
|
|
9884160929 | ||
|
|
b7805d90a8 | ||
|
|
7163ce148a | ||
|
|
9bb68012d5 | ||
|
|
d5781b27a7 | ||
|
|
54a0d23f27 | ||
|
|
7457c9f5f6 | ||
|
|
8236591a71 | ||
|
|
41fadda92b | ||
|
|
dbb777d411 | ||
|
|
66753f3d3b | ||
|
|
9da589e7b7 | ||
|
|
beda493165 | ||
|
|
2799d50a90 | ||
|
|
06819df7ac | ||
|
|
3700908cdc | ||
|
|
66f9048cb8 | ||
|
|
3b2deb1021 | ||
|
|
5ae168c618 | ||
|
|
dd8be64503 | ||
|
|
f076668200 | ||
|
|
d0d3849250 | ||
|
|
408c7cf4a4 | ||
|
|
a84ee1da33 | ||
|
|
bf24fcee1f | ||
|
|
c595f6d4b0 | ||
|
|
31e4cf1114 | ||
|
|
548e8d20c3 | ||
|
|
e6f1e2a82e | ||
|
|
512231d54b | ||
|
|
f55b046171 | ||
|
|
a1cc0b2788 | ||
|
|
eda3cd2c94 | ||
|
|
c0053b6117 | ||
|
|
bcf2cd4fa4 | ||
|
|
63aa9b9ea3 | ||
|
|
d9937bcfc3 | ||
|
|
ee46a8f43a | ||
|
|
6f1ad8ce5a | ||
|
|
249efbaa53 |
No files matched your search
@@ -4,7 +4,7 @@ This file contains some useful details on the installation from source code
|
||||
for GRAMPS. It does not cover installation of a pre-built binary package.
|
||||
For that use your package manager, the rest is already done by the packager.
|
||||
|
||||
Uninstall old version
|
||||
uninstall old version
|
||||
---------------------
|
||||
If you do a source install in the same place of an existing install,
|
||||
you need to remove the old version first. You can delete the old
|
||||
@@ -20,7 +20,7 @@ files, meaning that files of a previous version that are no longer
|
||||
present in the new version can still be loaded, making the new install
|
||||
unstable.
|
||||
|
||||
Configure vs autogen scripts
|
||||
configure vs autogen scripts
|
||||
----------------------------
|
||||
If you are building from released tarball, you should be able to just
|
||||
run "./configure && make". However, if you're building from the SVN,
|
||||
@@ -36,16 +36,6 @@ packages to be installed:
|
||||
differently on other distros) and maybe something else. If autogen.sh
|
||||
fails, it should inform you what's missing.
|
||||
|
||||
Custom directory installation
|
||||
-------------------------------------
|
||||
If you would like to install GRAMPS without being root, or in an
|
||||
alternative location on windows, supply the --prefix argument to autogen
|
||||
or configure.
|
||||
|
||||
For example:
|
||||
./autogen.sh --prefix=$HOME/my_gramps_path
|
||||
or
|
||||
./autogen.sh --prefix=/cygdrive/c/Projects/gramps
|
||||
|
||||
Regular vs local installation
|
||||
-----------------------------
|
||||
@@ -67,6 +57,7 @@ permissions for you:
|
||||
Whether you're doing local install or regular install, YOU MUST INSTALL
|
||||
MIME TYPES. YOU HAVE BEEN WARNED!
|
||||
|
||||
|
||||
Installing under non-default prefix
|
||||
-----------------------------------
|
||||
As hinted above, mime types for gramps MUST be properly installed.
|
||||
@@ -89,6 +80,7 @@ likely do everything correctly, so no extra care needs to be
|
||||
taken. You should take extra care only if you are installing under
|
||||
something like --prefix=/usr/local/my_gramps, /var/gramps123/blah, etc.
|
||||
|
||||
|
||||
Packager's issues
|
||||
------------------
|
||||
The above mime types must be installed. However, the
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ SUBDIRS = m4 po src data example
|
||||
EXTRA_DIST = \
|
||||
config.rpath autogen.sh \
|
||||
FAQ COPYING \
|
||||
intltool-extract.in intltool-merge.in intltool-update.in
|
||||
intltool-extract.in intltool-merge.in intltool-update.in
|
||||
|
||||
bin_SCRIPTS = gramps
|
||||
|
||||
|
||||
@@ -1,75 +1,3 @@
|
||||
Version 3.2.5 -- the "I intend to live forever" bug fix release.
|
||||
* fix Gramps so it again runs with Python 2.5
|
||||
* write all notes and sources to gedcom files
|
||||
* cli fixes
|
||||
* GeneWeb and LegacyGedcom fixes
|
||||
* NarrativeWeb fixes
|
||||
* memory leak fixes
|
||||
* various other small fixes
|
||||
* many translation updates
|
||||
|
||||
Version 3.2.4 -- the "Tententen" bug fix release.
|
||||
* fix a crash on newer distro's after an export is finished
|
||||
* styled notes cleanup and consistency improvement (nar web behaves like the pdf/html output of reports)
|
||||
* newlines in styled notes are written as newlines so users can make simple lists
|
||||
* many NarrativeWeb fixes
|
||||
* gedcom output fixes
|
||||
* non latin character fixes (mainly for windows)
|
||||
* recursive filter fixes
|
||||
* undo fixes
|
||||
* many translation updates
|
||||
|
||||
Version 3.2.3 -- the "I used to eat there. Really good noodles." release.
|
||||
* Bug fixes:
|
||||
-> several GLADE fixes
|
||||
-> several GEDCOM fixes (both export and import)
|
||||
-> several crash fixes
|
||||
-> encoding fix (Windows only)
|
||||
-> privacy/living fixes
|
||||
-> updates to NarrativeWeb and the css stylsheets
|
||||
* Translation updates: bg, ca, de, es, fr, he, nb, nl, pl, sk, sv
|
||||
|
||||
Version 3.2.2 -- the "Mea navis aëricumbens anguillis abundat" release.
|
||||
* This release is a quick fix to a problem introduced by NarrativeWeb in the previous release.
|
||||
* Also includes a few small fixes and translation updates to hr and it.
|
||||
* See the release notes from the 3.2.1 release for the full list of changes and translation updates.
|
||||
|
||||
Version 3.2.1 -- the "One of those men is my father" release.
|
||||
* Many bug fixes:
|
||||
-> fixed missing icons
|
||||
-> load/reload plugins must unload old plugins
|
||||
-> import/export fixes (date ranges, underscore, latitude/longitude)
|
||||
-> narrative web crash fixes and many updates, html notes, css updates
|
||||
-> geoview fixes and updates
|
||||
-> unicode error in soundex
|
||||
-> fixed crash on data entry
|
||||
* Translation updates: bg, ca, de, es, fr, he, hr, it, nb, nl, sk, sv
|
||||
|
||||
Version 3.2.0 -- the "I am your father" release.
|
||||
* New Plugin System:
|
||||
-> In the Help Menu -> Menu Status, all available plugins are visible. All
|
||||
plugins can be hidden, saving resources and hiding options you do not need.
|
||||
* Faster:
|
||||
-> Many under the hood improvements have occurred that should improve
|
||||
performance enormously. New features are implemented as plugins that can
|
||||
be hidden.
|
||||
-> Performance improvement example: Insertion of a new person in a family
|
||||
tree with 30000 people previously took 4 seconds on a 1.4GHz PC running
|
||||
Gramps 3.1, but now takes milliseconds.
|
||||
* New Views:
|
||||
-> There are new views, and some existing views have been greatly improved
|
||||
-> People view can now be sorted on the columns
|
||||
-> A Place treeview is present, nicely grouping your places under country
|
||||
groups
|
||||
-> GeoView has left it's beta status behind and shows your data on an online
|
||||
map (OpenStreetMap or Google Maps, a fast internet connection is required)
|
||||
-> Help Menu -> Extra Reports/Tools open a webpage with downloadable views
|
||||
* Other Improvements:
|
||||
-> Styled Notes now in most output formats that support styles
|
||||
-> New languages
|
||||
-> Select language in which report should be created (not yet available in
|
||||
all reports)
|
||||
|
||||
Version 3.1.3 -- the "What name?" release.
|
||||
* contains translation updates, crash fixes, bug fixes, and minor updates.
|
||||
* fixes and updates to:
|
||||
|
||||
@@ -7,54 +7,24 @@ Requirements
|
||||
The following packages *MUST* be installed in order for Gramps to work:
|
||||
Python 2.5 or greater
|
||||
PyGTK2 2.12 or greater
|
||||
Python Glade bindings
|
||||
librsvg2 (svg icon view)
|
||||
xdg-utils
|
||||
|
||||
The following package is needed for full translation of the interface
|
||||
to your language:
|
||||
language-pack-gnome-xx
|
||||
Translation of GTK elements to your language, with
|
||||
with xx your language code eg for Dutch you need
|
||||
language-pack-gnome-nl. The translation of the
|
||||
Gramps strings is included with the source code.
|
||||
|
||||
|
||||
The following packages are *STRONGLY RECOMMENDED* to be installed:
|
||||
GraphViz Enable creation of graphs using GraphViz engine
|
||||
http://www.graphviz.org
|
||||
|
||||
The following packages are *STRONGLY RECOMMENDED* to be installed:
|
||||
PyWebKitGtk or python-gtkmozembed: PACKAGERS, Test if on your distribution
|
||||
webkit and Gramps is stable. If you get crashes, patch
|
||||
src/plugins/view/htmlrenderer.py and
|
||||
src/plugins/view/geoview.gpr.py, so as to remove:
|
||||
import webkit
|
||||
Then use the gecko package (python-gtkmozembed) instead.
|
||||
If WEBKIT ang GECKO are installed, webkit will be used as
|
||||
the javascript engine is faster (google maps).
|
||||
* PyWebKitGtk
|
||||
Enable html rendering for Geographic view and Web view
|
||||
Often called python-webkit package.
|
||||
Be careful, webkit is always in a development phase.
|
||||
|
||||
* python-gtkmozembed
|
||||
Enable html rendering for Geographic view and Web view
|
||||
The gecko (firefox) equivalent to webkit, at the moment
|
||||
of writing, more stable than webkit.
|
||||
It can be in python-gnome2-extras or python-gtkhtml2
|
||||
depending on distributions.
|
||||
|
||||
The following packages are optional
|
||||
python gtkspell & python enchant : Enable spell checking in the notes,
|
||||
the first contains the libraries, the second is
|
||||
needed to query the installed languages. Both must
|
||||
be present for spell check to activate
|
||||
python gtkspell Enable spell checking in the notes
|
||||
pyenchant Enable query of installed spell check dictionaries
|
||||
|
||||
ttf-freefont More font support in the reports
|
||||
|
||||
No longer needed in 3.1:
|
||||
No longer needed in 3.0:
|
||||
yelp Gnome help browser. At the moment no help is shipped
|
||||
No longer needed in 3.2:
|
||||
python glade bindings
|
||||
with version 3.0.
|
||||
|
||||
|
||||
Documentation
|
||||
---------------------------------
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
PKG_NAME="gramps"
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
srcfile=$srcdir/src/gramps.py
|
||||
srcfile=$srcdir/src/gramps_main.py
|
||||
|
||||
REQUIRED_AUTOMAKE_VERSION=1.9
|
||||
DIE=0
|
||||
@@ -19,7 +19,7 @@ then
|
||||
fi
|
||||
. ./gramps-autogen.sh
|
||||
|
||||
CONFIGURE_DEF_OPT=
|
||||
CONFIGURE_DEF_OPT='--enable-maintainer-mode'
|
||||
|
||||
autogen_options $@
|
||||
|
||||
|
||||
+45
-23
@@ -5,14 +5,14 @@ dnl May need to run automake && aclocal first
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
dnl NOTE: arg to macro below becomes the "VERSION"
|
||||
AC_INIT(gramps, 3.2.5, [gramps-bugs@lists.sourceforge.net])
|
||||
AC_INIT(gramps, 3.1.4, [gramps-bugs@lists.sourceforge.net])
|
||||
AC_CONFIG_SRCDIR(configure.in)
|
||||
AM_INIT_AUTOMAKE([1.6.3 foreign])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
RELEASE=0.SVN$(svnversion -n .)
|
||||
dnl RELEASE=0beta3
|
||||
dnl RELEASE=0beta
|
||||
dnl RELEASE=0rc1
|
||||
dnl RELEASE=1
|
||||
|
||||
@@ -33,7 +33,7 @@ AC_SUBST(RELEASE)
|
||||
AC_SUBST(VERSIONSTRING)
|
||||
|
||||
dnl Add the languages which your application supports here.
|
||||
ALL_LINGUAS="hu zh_CN cs da de es fr it nb nl nn pl pt_BR ru sv fi lt sk bg hr sl ca sq he"
|
||||
ALL_LINGUAS="hu zh_CN cs da de es fr it nb nl nn pl pt_BR ro ru sv eo fi lt sk tr bg hr sl ca mk sq he"
|
||||
GETTEXT_PACKAGE=gramps
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define to the Gettext package name.])
|
||||
@@ -85,6 +85,29 @@ then
|
||||
fi
|
||||
AC_MSG_RESULT($has_pygtk)
|
||||
|
||||
AC_MSG_CHECKING(Python bindings for glade)
|
||||
cat > conftest.py <<EOF
|
||||
$pygtk_require
|
||||
try:
|
||||
# Do not import gtk.glade, this can raise a RuntimeError if the
|
||||
# display cannot be opened. Just search it.
|
||||
import imp
|
||||
imp.find_module('glade',[[imp.find_module('gtk')[1]]])
|
||||
out("gtk.glade")
|
||||
except ImportError:
|
||||
out("NO")
|
||||
EOF
|
||||
$PYTHON conftest.py
|
||||
has_pyglade=`cat conftest.out`
|
||||
rm -f conftest.out conftest.py
|
||||
if test NO = "$has_pyglade"
|
||||
then
|
||||
AC_MSG_ERROR([
|
||||
|
||||
**** The python bindings for glade (pygtk2-libglade) could not be found.])
|
||||
fi
|
||||
AC_MSG_RESULT($has_pyglade)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
po/Makefile.in
|
||||
m4/Makefile
|
||||
@@ -92,28 +115,16 @@ Makefile
|
||||
gramps.sh
|
||||
src/const.py
|
||||
src/Makefile
|
||||
src/cli/Makefile
|
||||
src/gen/Makefile
|
||||
src/gen/db/Makefile
|
||||
src/gen/display/Makefile
|
||||
src/gen/lib/Makefile
|
||||
src/gen/mime/Makefile
|
||||
src/gen/plug/Makefile
|
||||
src/gen/plug/docbackend/Makefile
|
||||
src/gen/plug/docgen/Makefile
|
||||
src/gen/plug/menu/Makefile
|
||||
src/gen/proxy/Makefile
|
||||
src/gen/utils/Makefile
|
||||
src/gui/Makefile
|
||||
src/gui/editors/Makefile
|
||||
src/gui/editors/displaytabs/Makefile
|
||||
src/gui/selectors/Makefile
|
||||
src/gui/views/Makefile
|
||||
src/gui/views/treemodels/Makefile
|
||||
src/gui/widgets/Makefile
|
||||
src/Config/Makefile
|
||||
src/FilterEditor/Makefile
|
||||
src/Mime/Makefile
|
||||
src/DisplayTabs/Makefile
|
||||
src/DisplayModels/Makefile
|
||||
src/Selectors/Makefile
|
||||
src/GrampsLogger/Makefile
|
||||
src/Merge/Makefile
|
||||
src/docgen/Makefile
|
||||
src/Editors/Makefile
|
||||
src/Filters/Makefile
|
||||
src/Filters/Rules/Makefile
|
||||
src/Filters/Rules/Person/Makefile
|
||||
@@ -125,7 +136,10 @@ src/Filters/Rules/MediaObject/Makefile
|
||||
src/Filters/Rules/Repository/Makefile
|
||||
src/Filters/Rules/Note/Makefile
|
||||
src/Filters/SideBar/Makefile
|
||||
src/DataViews/Makefile
|
||||
src/BasicUtils/Makefile
|
||||
src/Simple/Makefile
|
||||
src/GrampsDbUtils/Makefile
|
||||
src/GrampsLocale/Makefile
|
||||
src/PluginUtils/Makefile
|
||||
src/ReportBase/Makefile
|
||||
@@ -142,10 +156,18 @@ src/plugins/quickview/Makefile
|
||||
src/plugins/rel/Makefile
|
||||
src/plugins/textreport/Makefile
|
||||
src/plugins/tool/Makefile
|
||||
src/plugins/view/Makefile
|
||||
src/plugins/webreport/Makefile
|
||||
src/DateHandler/Makefile
|
||||
src/widgets/Makefile
|
||||
src/gen/Makefile
|
||||
src/gen/proxy/Makefile
|
||||
src/gen/db/Makefile
|
||||
src/gen/lib/Makefile
|
||||
src/gen/utils/Makefile
|
||||
src/gen/plug/Makefile
|
||||
src/gen/plug/menu/Makefile
|
||||
src/data/Makefile
|
||||
src/data/templates/Makefile
|
||||
src/glade/Makefile
|
||||
src/images/Makefile
|
||||
src/images/scalable/Makefile
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[Desktop Entry]
|
||||
_Name=Gramps Genealogy System
|
||||
_Name=GRAMPS Genealogy System
|
||||
_Comment=Manage genealogical information, perform genealogical research and analysis
|
||||
Icon=gramps
|
||||
Terminal=false
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
application/x-gramps:
|
||||
_description=Gramps database
|
||||
_description=GRAMPS database
|
||||
default_action_type=application
|
||||
short_list_application_ids=gramps
|
||||
short_list_application_ids_for_novice_user_level=gramps
|
||||
@@ -10,7 +10,7 @@ application/x-gramps:
|
||||
open=gramps %f
|
||||
|
||||
application/x-gramps-package:
|
||||
_description=Gramps package
|
||||
_description=GRAMPS package
|
||||
default_action_type=application
|
||||
short_list_application_ids=gramps
|
||||
short_list_application_ids_for_novice_user_level=gramps
|
||||
@@ -21,7 +21,7 @@ application/x-gramps-package:
|
||||
open=gramps %f
|
||||
|
||||
application/x-gramps-xml:
|
||||
_description=Gramps XML database
|
||||
_description=GRAMPS XML database
|
||||
default_action_type=application
|
||||
short_list_application_ids=gramps
|
||||
short_list_application_ids_for_novice_user_level=gramps
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
<mime-type type="application/x-gramps">
|
||||
<_comment>Gramps database</_comment>
|
||||
<_comment>GRAMPS database</_comment>
|
||||
<glob pattern="*.grdb"/>
|
||||
</mime-type>
|
||||
<mime-type type="application/x-gedcom">
|
||||
@@ -18,11 +18,11 @@
|
||||
</magic>
|
||||
</mime-type>
|
||||
<mime-type type="application/x-gramps-package">
|
||||
<_comment>Gramps package</_comment>
|
||||
<_comment>GRAMPS package</_comment>
|
||||
<glob pattern="*.gpkg"/>
|
||||
</mime-type>
|
||||
<mime-type type="application/x-gramps-xml">
|
||||
<_comment>Gramps XML database</_comment>
|
||||
<_comment>GRAMPS XML database</_comment>
|
||||
<glob pattern="*.gramps"/>
|
||||
<magic priority="80">
|
||||
<match type="string" value="<!DOCTYPE database" offset="0:256"/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.TH gramps 1 "@VERSION@" "Mars 2009" "@VERSION@"
|
||||
.SH NOM
|
||||
gramps \- Gramps est une application de généalogie. Gramps est l'acronyme de Genealogical Research and Analysis Management Programming System (Systeme de Programmation pour Recherche, Analyse et Gestion de données généalogiques)
|
||||
gramps \- GRAMPS est une application de généalogie. GRAMPS est l'acronyme de Genealogical Research and Analysis Management Programming System (Systeme de Programmation pour Recherche, Analyse et Gestion de données généalogiques)
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B gramps
|
||||
@@ -45,7 +45,7 @@ Il peut importer/exporter le format le plus utilisé par les autres logiciels de
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI gramps " FICHIER"
|
||||
Si \fIFICHIER\fR est désigné (sans autres commandes) comme arbre familial ou comme répertoire d'arbre familial, alors une session interactive est ouverte. Si FICHIER est un format de fichier supporté par Gramps, une base vide est créée dont le nom est celui du \fIFICHIER\fP et les données y seront importées. Les autres options sont ignorées. Ce type de lancement permet d'utiliser gramps pour manipuler des données comme dans un navigateur web. Les formats natifs de gramps sont acceptés, voir ci-dessous.
|
||||
Si \fIFICHIER\fR est désigné (sans autres commandes) comme arbre familial ou comme répertoire d'arbre familial, alors une session interactive est ouverte. Si FICHIER est un format de fichier supporté par GRAMPS, une base vide est créée dont le nom est celui du \fIFICHIER\fP et les données y seront importées. Les autres options sont ignorées. Ce type de lancement permet d'utiliser gramps pour manipuler des données comme dans un navigateur web. Les formats natifs de gramps sont acceptés, voir ci-dessous.
|
||||
.br
|
||||
|
||||
.TP
|
||||
@@ -60,7 +60,7 @@ Le format spécifique du \fIFICHIER\fR est précédé par les arguments
|
||||
|
||||
Les formats de sortie disponibles sont \fBgramps\-xml\fR (deviné si \fIFICHIER\fR se termine par
|
||||
\fB.gramps\fR), et \fBgedcom\fR (deviné si \fIFICHIER\fR se termine par \fB.ged\fR), ou
|
||||
tout autre fichier d'exportation disponible dans le système de plugin Gramps.
|
||||
tout autre fichier d'exportation disponible dans le système de plugin GRAMPS.
|
||||
.br
|
||||
|
||||
Les formats disponibles pour l'importation sont \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR,
|
||||
@@ -244,11 +244,11 @@ Le programme vérifie si ces variables d'environnement sont déclarées:
|
||||
\fBLANG\fR - décrit, quelle langue est utilisée:
|
||||
Ex.: pour le français on peut définir fr_FR.UTF-8.
|
||||
|
||||
\fBGRAMPSHOME\fR - si défini, force Gramps à utiliser un répertoire spécifique pour y conserver ses préférences et bases de données. Par défaut, cette variable n'est pas active et Gramps sait que les options et bases de données doivent être créées
|
||||
\fBGRAMPSHOME\fR - si défini, force GRAMPS à utiliser un répertoire spécifique pour y conserver ses préférences et bases de données. Par défaut, cette variable n'est pas active et GRAMPS sait que les options et bases de données doivent être créées
|
||||
dans le répertoire par défaut de l'utilisateur (la variable d'environnement HOME pour Linux ou USERPROFILE pour Windows 2000/XP).
|
||||
|
||||
.SH CONCEPTS
|
||||
Gramps est un système basé sur le support de plugin-python, permettant d'importer et d'exporter, la saisie,
|
||||
GRAMPS est un système basé sur le support de plugin-python, permettant d'importer et d'exporter, la saisie,
|
||||
générer des rapports, des outils, et afficher des filtres pouvant être ajoutés sans modifier le programme.
|
||||
.LP
|
||||
Par ailleurs, gramps permet la génération directe : impression, rapports avec sortie vers d'autres formats, comme \fIOpenOffice.org\fR, \fIAbiWord\fR, HTML,
|
||||
|
||||
@@ -49,7 +49,7 @@ wide by almost all other genealogy software.
|
||||
.BI gramps " FILE"
|
||||
When \fIFILE\fR is given (without any flags) as a family tree name or as
|
||||
a family tree database directory, then it is opened and an interactive
|
||||
session is started. If FILE is a file format understood by Gramps, an empty
|
||||
session is started. If FILE is a file format understood by GRAMPS, an empty
|
||||
family tree is created whose name is based on the \fIFILE\fP name
|
||||
and the data is imported into it. The rest of the
|
||||
options is ignored. This way of launching is suitable for using gramps
|
||||
@@ -69,9 +69,9 @@ the format of that file is guessed according to its extension or MIME-type.
|
||||
.br
|
||||
|
||||
Formats
|
||||
available for export are \fBgramps\-xml\fR (guessed if \fIFILE\fR ends with
|
||||
available for output are \fBgramps\-xml\fR (guessed if \fIFILE\fR ends with
|
||||
\fB.gramps\fR), \fBgedcom\fR (guessed if \fIFILE\fR ends with \fB.ged\fR), or
|
||||
any file export available through the Gramps plugin system.
|
||||
any file export available through the GRAMPS plugin system.
|
||||
.br
|
||||
|
||||
Formats
|
||||
@@ -269,7 +269,7 @@ The program checks whether these environment variables are set:
|
||||
\fBLANG\fR - describe, which language to use:
|
||||
Ex.: for polish language this variable has to be set to pl_PL.UTF-8.
|
||||
|
||||
\fBGRAMPSHOME\fR - if set, force Gramps to use the specified directory to keep
|
||||
\fBGRAMPSHOME\fR - if set, force GRAMPS to use the specified directory to keep
|
||||
program settings and databases there. By default, this variable is not set and
|
||||
gramps assumes that the folder with all databases and profile settings
|
||||
should be created within the user profile folder (described by environment
|
||||
|
||||
@@ -47,13 +47,13 @@ wordt wereldwijd gebruikt door bijna alle genealogische software.
|
||||
.BI gramps "BESTAND"
|
||||
Wanneer \fIBESTAND\fR opgegeven wordt (zonder vlaggen) als een familiestamboom
|
||||
of als een familistamboommap, dan wordt dit bestand geopend en een interactieve
|
||||
sessie wordt gestart. Indien BESTAND een bestandsformaat dat door Gramps
|
||||
sessie wordt gestart. Indien BESTAND een bestandsformaat dat door GRAMPS
|
||||
herkent wordt, zal een lege familiestamboom aangemaakt worden. De bestandsnaam
|
||||
wordt gebaseerd op de \fIBESTAND\fP naam en de gegevens worden in dit bestand
|
||||
geïmporteerd. Met resterende opties wordt geen rekening gehouden. Deze wijze
|
||||
van opstarten is zeer bruikbaar om Gramps te gebruiken voor genealogische
|
||||
van opstarten is zeer bruikbaar om GRAMPS te gebruiken voor genealogische
|
||||
gegevens via een webbrowser. Deze opstartmethode kan gelijk welk gegevensformaat
|
||||
eigen aan Gramps behandelen, zie onder.
|
||||
eigen aan GRAMPS behandelen, zie onder.
|
||||
.br
|
||||
|
||||
.TP
|
||||
@@ -71,7 +71,7 @@ MIME-type.
|
||||
Formaten
|
||||
beschikbaar voor uitvoer zijn \fBgramps\-xml\fR (guessed if \fIFILE\fR ends with
|
||||
\fB.gramps\fR), \fBgedcom\fR (guessed if \fIFILE\fR ends with \fB.ged\fR), or
|
||||
any file export available through the Gramps plugin system.
|
||||
any file export available through the GRAMPS plugin system.
|
||||
.br
|
||||
|
||||
Formats
|
||||
@@ -206,7 +206,7 @@ Host:port on which the sound server to use is running
|
||||
.SH "werking"
|
||||
.br
|
||||
Indien het eerste argument in de opdrachtregel niet start met dash (dus geen
|
||||
vlag) dan zal Gramps trachten om het bestand te openen met een naam die in het
|
||||
vlag) dan zal GRAMPS trachten om het bestand te openen met een naam die in het
|
||||
eerste argument werd opgegeven. Vervolgens wordt een interactieve sessie
|
||||
gestart en de overige argumenten van de opdrachtregel worden genegeerd.
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ jest używany przez większość programów genealogicznych na świecie.
|
||||
.BI gramps " PLIK"
|
||||
Kiedy \fIPLIK\fR jest podany (bez żadnych flag) jako nazwa drzewa rodzinnego
|
||||
albo nazwa katalogu z drzewem, to wybrane drzewo jest otwierane i rozpoczynana
|
||||
jest sesja interaktywna. Jeśli PLIK jest formatem rozpoznawanym przez Gramps,
|
||||
jest sesja interaktywna. Jeśli PLIK jest formatem rozpoznawanym przez GRAMPS,
|
||||
to tworzone jest puste drzewo, którego nazwa bazuje na nazwie \fIPLIKU\fP
|
||||
i dane są do niego importowane. Pozostałe opcje są wtedy ignorowane.
|
||||
Jest to sposób na używanie programu jako uchwytu obsługującego
|
||||
@@ -77,7 +77,7 @@ Dostępne formaty wyjściowe to:
|
||||
.br
|
||||
\fBgedcom\fR (przyjmowany jeśli \fIPLIK\fR kończy się na \fB.ged\fR),
|
||||
.br
|
||||
lub dowolny plik eksportu obsługiwany przez system wtyczek Gramps.
|
||||
lub dowolny plik eksportu obsługiwany przez system wtyczek GRAMPS.
|
||||
.br
|
||||
|
||||
Formaty
|
||||
|
||||
+36
-36
@@ -1,9 +1,9 @@
|
||||
.TH Gramps 1 "@VERSION@" "Januari 2008" "@VERSION@"
|
||||
.TH gramps 1 "@VERSION@" "Januari 2008" "@VERSION@"
|
||||
.SH NAMN
|
||||
Gramps \- Genealogical Research and Analysis Management Programming System.
|
||||
gramps \- Genealogical Research and Analysis Management Programming System.
|
||||
|
||||
.SH SAMMANFATTNING
|
||||
.B Gramps
|
||||
.B gramps
|
||||
.RB [ \-?|\-\^\-help ]
|
||||
.RB [ \-\^\-usage ]
|
||||
.RB [ \-\^\-version ]
|
||||
@@ -46,14 +46,14 @@ hela världen av nästan all släktforskningsprogramvara.
|
||||
|
||||
.SH ALTERNATIV
|
||||
.TP
|
||||
.BI Gramps " FIL"
|
||||
.BI gramps " FIL"
|
||||
När \fIFIL\fR ges (utan några flaggor) som namn på ett familjeträd eller som
|
||||
en mapp med familjeträd, så öppnas detta och en interaktiv session startas.
|
||||
Om FIL är en fil, vars format förstås av Gramps, skapas ett tomt famljeträd,
|
||||
Om FIL är en fil, vars format försås av GRAMPS, skapas ett tomt famljeträd,
|
||||
vars namn är grundat på namnet \fIFIL\fP och vars data importeras till det.
|
||||
Resterande alternativ ignoreras. Detta sätt att starta passar vid användning av Gramps
|
||||
Resterande alternativ ignoreras. Detta sätt att starta passar vid användning av gramps
|
||||
som en hanterare för släktforskningsdata i t. ex. en web-läsare.
|
||||
Detta startsätt accepterar alla inbyggda dataformat för Gramps, se nedan.
|
||||
Detta startsätt accepterar alla inbyggda dataformat för gramps, se nedan.
|
||||
.br
|
||||
|
||||
.TP
|
||||
@@ -67,13 +67,13 @@ Uttryckligen specificera format på \fIFIL\fR givet av föregående
|
||||
gissas filformat för den filen utgående från dess filändelse eller dess MIME-typ.
|
||||
.br
|
||||
|
||||
De format, som är tillgängliga för utmatnig, är \fBGramps\-xml\fR (gissas om \fIFIL\fR slutar på
|
||||
\fB.Gramps\fR), \fBgedcom\fR (gissas om \fIFIL\fR slutar med \fB.ged\fR) eller
|
||||
någon filexport, som är tillgänglig via Gramps tilläggsprogramsystem.
|
||||
De format, som är tillgängliga för utmatnig, är \fBgramps\-xml\fR (gissas om \fIFIL\fR slutar på
|
||||
\fB.gramps\fR), \fBgedcom\fR (gissas om \fIFIL\fR slutar med \fB.ged\fR) eller
|
||||
någon filexport, som är tillgänglig via GRAMPS tilläggsprogramsystem.
|
||||
.br
|
||||
|
||||
De format, som är tillgängliga för inmatnig, är \fBgrdb\fR, \fBGramps\-xml\fR, \fBgedcom\fR,
|
||||
\fBGramps\-pkg\fR (gissas om \fIFIL\fR slutar med \fB.gpkg\fR) och
|
||||
De format, som är tillgängliga för inmatnig, är \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR,
|
||||
\fBgramps\-pkg\fR (gissas om \fIFIL\fR slutar med \fB.gpkg\fR) och
|
||||
\fBgeneweb\fR (gissas om \fIFIL\fR slutar med \fB.gw\fR).
|
||||
.br
|
||||
|
||||
@@ -81,8 +81,8 @@ De format, som är tillgängliga för export är
|
||||
.ig
|
||||
\fBgrdb\fR,
|
||||
..
|
||||
\fBGramps\-xml\fR, \fBgedcom\fR,
|
||||
\fBGramps\-pkg\fR, \fBwft\fR (gissas om \fIFIL\fR slutar med \fB.wft\fR),
|
||||
\fBgramps\-xml\fR, \fBgedcom\fR,
|
||||
\fBgramps\-pkg\fR, \fBwft\fR (gissas om \fIFIL\fR slutar med \fB.wft\fR),
|
||||
\fBgeneweb\fR och \fBiso\fR (gissas aldrig, specificeras alltid med
|
||||
\fB\-f\fR-alternativ).
|
||||
|
||||
@@ -103,24 +103,24 @@ session med den angivna databasen.
|
||||
.TP
|
||||
.BI \-i,\-\^\-import= " FIL"
|
||||
Importera data från \fIFIL\fR. Om du inte har specificerat en databas, skapas en temporär sådan,
|
||||
som tas bort när Gramps avslutas.
|
||||
som tas bort när gramps avslutas.
|
||||
.br
|
||||
|
||||
Om mer är en indatafil anges, måste varje föregås av en \fB\-i\fR-flagga.
|
||||
Filerna importeras i den givna ordningen,
|
||||
t.ex. \fB\-i\fR \fIFIL1\fR \fB\-i\fR \fIFIL2\fR
|
||||
och \fB\-i\fR \fIFIL2\fR \fB\-i\fR \fIFIL1\fR kan skapa skilda
|
||||
Gramps IDs i den resulterande databasen.
|
||||
gramps IDs i den resulterande databasen.
|
||||
|
||||
.TP
|
||||
.BI \-e,\-\^\-export= " FIL"
|
||||
Exporterar data till \fIFIL\fR. För \fBiso\fR-format, är \fIFIL\fR i själva verket namnet på den mapp,
|
||||
som Gramps databas kommer att skrivas till.
|
||||
som gramps databas kommer att skrivas till.
|
||||
För
|
||||
.ig
|
||||
\fBgrdb\fR,
|
||||
..
|
||||
\fBGramps\-xml\fR, \fBgedcom\fR, \fBwft\fR, \fBGramps\-pkg\fR
|
||||
\fBgramps\-xml\fR, \fBgedcom\fR, \fBwft\fR, \fBgramps\-pkg\fR
|
||||
och \fBgeneweb\fR, är \fIFIL\fR namnet på resultatfilen.
|
||||
.br
|
||||
|
||||
@@ -176,7 +176,7 @@ Kopplar på avlusningshjälpmedel för utveckling och tester.
|
||||
För detaljer hänvisas till källkoder
|
||||
.TP
|
||||
.BI \-\^\-version
|
||||
Skriver ur Gramps versionsnummer och avslutar
|
||||
Skriver ur gramps versionsnummer och avslutar
|
||||
\" change 0 to 1 to enable output of OAF options
|
||||
.if 0 \{
|
||||
.PP
|
||||
@@ -209,11 +209,11 @@ Host:port on which the sound server to use is running
|
||||
.SH "Operation"
|
||||
.br
|
||||
Om första argumentet på kommandoraden inte inledds med ett minustecken (d. v. s. ingen flagga),
|
||||
kommer Gramps att försöka öppna den fil, vars namn givits av det första argumentet samt påbörja
|
||||
kommer gramps att försöka öppna den fil, vars namn givits av det första argumentet samt påbörja
|
||||
en interaktiv session utan att ta hänsyn till resten av argumenten på kommandoraden.
|
||||
|
||||
.LP
|
||||
Om \fB\-O\fR-flagga givits, kommer Gramps att försöka öppna den omnämnda databasen
|
||||
Om \fB\-O\fR-flagga givits, kommer gramps att försöka öppna den omnämnda databasen
|
||||
och sedan arbeta med dess data, enligt ytterligare instruktioner på kommandoraden.
|
||||
|
||||
.LP
|
||||
@@ -228,51 +228,51 @@ Den gällande ordningen är alltid: all import (om någon) -> alla åtgärder (o
|
||||
-> all export (om någon). Men öppning måste alltid ske först!
|
||||
|
||||
.LP
|
||||
Om inget \fB\-O\fR- eller \fB\-i\fR-alternativ givits, kommer Gramps att starta sitt
|
||||
Om inget \fB\-O\fR- eller \fB\-i\fR-alternativ givits, kommer gramps att starta sitt
|
||||
huvudfönster samt påbörja den vanliga interaktiva sessionen med en tom databas,
|
||||
då hur som helst inget data finns att bearbeta.
|
||||
|
||||
.LP
|
||||
Om inget \fB\-e\fR- eller \fB\-a\fR-alternativ givits, kommer Gramps att starta sitt
|
||||
Om inget \fB\-e\fR- eller \fB\-a\fR-alternativ givits, kommer gramps att starta sitt
|
||||
huvudfönster samt påbörja den vanliga interaktiva sessionen med den databas, som blev
|
||||
resultet från all import. Denna databas återfinns i \fBimport_db.grdb\fR
|
||||
under \fB~/.Gramps/import\fR-mappen.
|
||||
under \fB~/.gramps/import\fR-mappen.
|
||||
|
||||
.LP
|
||||
De fel som inträffar under import, export eller vid åtgärder kommer antingen att skrivas till
|
||||
\fIstdout\fR (om dessa avbrott hanteras av Gramps) eller
|
||||
\fIstdout\fR (om dessa avbrott hanteras av gramps) eller
|
||||
till \fIstderr\fR (om dessa inte hanteras). Använd vanliga skalkommandon för att styra om
|
||||
\fIstdout\fR och \fIstderr\fR till att spara medelanden och fel i filer.
|
||||
|
||||
.SH EXAMPEL
|
||||
.TP
|
||||
För att öppna ett befintligt familjeträd och importera en xml-fil till det, kan man skriva:
|
||||
\fBGramps\fR \fB\-O\fR \fI'Mitt familjeträd'\fR \fB\-i\fR \fI~/db3.Gramps\fR
|
||||
\fBgramps\fR \fB\-O\fR \fI'Mitt familjeträd'\fR \fB\-i\fR \fI~/db3.gramps\fR
|
||||
.TP
|
||||
Ovanstående ändrar det öppnade familjeträdet, för att göra samma sak, men importera bägge till ett tillfälligt familjeträd och påbörja en interaktiv session, kan man skriva:
|
||||
\fBGramps\fR \fB\-i\fR \fI'My Family Tree'\fR \fB\-i\fR \fI~/db3.Gramps\fR
|
||||
\fBgramps\fR \fB\-i\fR \fI'My Family Tree'\fR \fB\-i\fR \fI~/db3.gramps\fR
|
||||
.TP
|
||||
För att importera fyra databaser (vars format kan avgöras av deras namn) och sedan felkontrollera den resulterande databasen, kan man skriva:
|
||||
\fBGramps\fR \fB\-i\fR \fIFIL1.ged\fR \fB\-i\fR \fIFIL2.tgz\fR \fB\-i\fR \fI~/db3.Gramps\fR \fB\-i\fR \fIFIL4.wft\fR \fB\-a\fR \fIcheck\fR
|
||||
\fBgramps\fR \fB\-i\fR \fIFIL1.ged\fR \fB\-i\fR \fIFIL2.tgz\fR \fB\-i\fR \fI~/db3.gramps\fR \fB\-i\fR \fIFIL4.wft\fR \fB\-a\fR \fIcheck\fR
|
||||
.TP
|
||||
För att uttryckligen specificera formaten i examplet ovan, lägg till filnamn med passande \fB\-f\fR-alternativ:
|
||||
\fBGramps\fR \fB\-i\fR \fIFIL1.ged\fR \fB\-f\fR \fIgedcom\fR \fB\-i\fR \fIFIL2.tgz\fR \fB\-f\fR \fIGramps-pkg\fR \fB\-i\fR \fI~/db3.Gramps\fR \fB\-f\fR \fIGramps-xml\fR \fB\-i\fR \fIFIL4.wft\fR \fB\-f\fR \fIwft\fR \fB\-a\fR \fIcheck\fR
|
||||
\fBgramps\fR \fB\-i\fR \fIFIL1.ged\fR \fB\-f\fR \fIgedcom\fR \fB\-i\fR \fIFIL2.tgz\fR \fB\-f\fR \fIgramps-pkg\fR \fB\-i\fR \fI~/db3.gramps\fR \fB\-f\fR \fIgramps-xml\fR \fB\-i\fR \fIFIL4.wft\fR \fB\-f\fR \fIwft\fR \fB\-a\fR \fIcheck\fR
|
||||
.TP
|
||||
För att spara den databas, som är resultat av all import, ange \fB\-e\fR-flagga (använd \fB\-f\fR om filnamnet inte tillåter Gramps att gissa dess format):
|
||||
\fBGramps\fR \fB\-i\fR \fIFIL1.ged\fR \fB\-i\fR \fIFIL2.tgz\fR \fB\-e\fR \fI~/new-package\fR \fB\-f\fR \fIGramps-pkg\fR
|
||||
För att spara den databas, som är resultat av all import, ange \fB\-e\fR-flagga (använd \fB\-f\fR om filnamnet inte tillåter gramps att gissa dess format):
|
||||
\fBgramps\fR \fB\-i\fR \fIFIL1.ged\fR \fB\-i\fR \fIFIL2.tgz\fR \fB\-e\fR \fI~/new-package\fR \fB\-f\fR \fIgramps-pkg\fR
|
||||
.TP
|
||||
För att importera tre databaser och påbörja en interaklive Gramps-session med importresultatet:
|
||||
\fBGramps\fR \fB\-i\fR \fIFIL1.ged\fR \fB\-i\fR \fIFIL2.tgz\fR \fB\-i\fR \fI~/db3.Gramps\fR
|
||||
För att importera tre databaser och påbörja en interaklive gramps-session med importresultatet:
|
||||
\fBgramps\fR \fB\-i\fR \fIFIL1.ged\fR \fB\-i\fR \fIFIL2.tgz\fR \fB\-i\fR \fI~/db3.gramps\fR
|
||||
.TP
|
||||
För att köra verifieringsverktyget från kommandoraden och mata ut resultatet till stdout:
|
||||
\fBGramps\fR \fB\-O\fR \fIfile.grdb\fR \fB-a\fR \fItool\fR \fB-p\fR \fBname\fR=\fIverify\fR
|
||||
\fBgramps\fR \fB\-O\fR \fIfile.grdb\fR \fB-a\fR \fItool\fR \fB-p\fR \fBname\fR=\fIverify\fR
|
||||
.TP
|
||||
Slutligen, för att påbörja en normal interaktiv session skriv bara:
|
||||
\fBGramps\fR
|
||||
\fBgramps\fR
|
||||
|
||||
.SH BEGREPP
|
||||
Stöder ett python\-baserat system för tilläggsprogram, som möjliggör att import- och export-funktioner,
|
||||
rapportgeneratorer, verktyg samt visningsfilter, kan komplettera Gramps utan ändringar i huvudprogrammet.
|
||||
rapportgeneratorer, verktyg samt visningsfilter, kan komplettera gramps utan ändringar i huvudprogrammet.
|
||||
.LP
|
||||
Förutom att skapa utskrift på skrivare direkt, kan rapportgeneratorer ha andra målsystem som \fIOpenOffice.org\fR, \fIAbiWord\fR, HTML eller LaTeX så att användaren kan tillåtas att ändra format för att passa behoven.
|
||||
|
||||
|
||||
Vendored
+5
-12
@@ -3,16 +3,9 @@ gramps for Debian
|
||||
|
||||
This is the Debian package of GRAMPS.
|
||||
|
||||
Regarding the extra dependencies:
|
||||
If you do not install python-reportlab (gramps Recommends it be
|
||||
installed) then you will be able to create usable PDF files only if
|
||||
your database contains solely latin (iso-8859-1) characters. Reportlab
|
||||
will generate PDF files containing non-latin characters although they
|
||||
are quite large as the font must be included in the file.
|
||||
|
||||
Recommends: graphviz
|
||||
Enable creation of graphs
|
||||
Recommends: python-gtkmozembed
|
||||
Recommends: python-webkit
|
||||
Enable html rendering for Geographic view and Web view. If both
|
||||
are installed webkit will be used. python-gtkmozembed may be more
|
||||
stable.
|
||||
Suggests: ttf-freefont
|
||||
Allows more fonts in reports
|
||||
Suggests: python-gtkspell python-enchant
|
||||
allows spell checking in the notes. Both need to be installed.
|
||||
Vendored
+6
-251
@@ -1,265 +1,20 @@
|
||||
gramps (3.2.0-0beta1) unstable; urgency=low
|
||||
|
||||
* New upstream release
|
||||
* works with gtk 2.19. Closes: #566958
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Fri, 05 Mar 2010 14:05:39 -0500
|
||||
|
||||
gramps (3.1.3-2) unstable; urgency=low
|
||||
|
||||
* Switch to dpkg-source 3.0 (quilt) format
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Tue, 05 Jan 2010 20:04:30 -0500
|
||||
|
||||
gramps (3.1.3-1) unstable; urgency=low
|
||||
gramps (3.0.0-1) gutsy; urgency=low
|
||||
|
||||
* New upstream release
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Sun, 06 Dec 2009 13:46:48 -0500
|
||||
-- Stephane Charette <stephanecharette@gmail.com> Mon, 31 Mar 2008 19:42:05 -0700
|
||||
|
||||
gramps (3.1.2-2) unstable; urgency=low
|
||||
|
||||
* allow python >= 2.5. Closes: #547150
|
||||
* fix Relationship Graph to use new format for URLs. Closes: #532559
|
||||
* Web report creation fixed. Closes: #537355
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Tue, 17 Nov 2009 11:38:43 -0500
|
||||
|
||||
gramps (3.1.2-1.1) unstable; urgency=low
|
||||
|
||||
* Non-maintainer upload.
|
||||
* debian/control: drop Recommends on python-gnome2-desktop: it is now
|
||||
gone and none of its modules are used anyhow (Closes: #541560)
|
||||
|
||||
-- Stefano Zacchiroli <zack@debian.org> Thu, 08 Oct 2009 13:52:35 +0200
|
||||
|
||||
gramps (3.1.2-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* Replace Recommends on python-gnome2-extras with python-gtkspell
|
||||
* Do not create the directory /etc/gconf/schemas/. Closes: Bug#525683
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Sun, 07 Jun 2009 14:01:16 -0400
|
||||
|
||||
gramps (3.1.1-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Tue, 10 Mar 2009 09:26:52 -0400
|
||||
|
||||
gramps (3.1.0-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* link /usr/share/common-licenses/GPL-2 from /usr/share/gramps/COPYING
|
||||
so gramps can find the file.
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Sat, 07 Mar 2009 22:03:09 -0500
|
||||
|
||||
gramps (3.0.4-1) unstable; urgency=low
|
||||
|
||||
* New upstream version. Closes: #506621, #506818
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Sun, 07 Dec 2008 21:39:55 -0500
|
||||
|
||||
gramps (3.0.3-1) unstable; urgency=low
|
||||
|
||||
* New upstream version
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 20 Oct 2008 20:43:35 -0400
|
||||
|
||||
gramps (3.0.2-1) unstable; urgency=low
|
||||
|
||||
* New upstream version
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Sat, 27 Sep 2008 17:25:09 -0400
|
||||
|
||||
gramps (3.0.1-2) unstable; urgency=low
|
||||
|
||||
* Remove dependency on gnome-doc-utils and scrollkeeper
|
||||
* Disable spell checking in src/Spell.py due to the spell checker
|
||||
crashing. Closes: #492212
|
||||
Spell checking will be reenabled once the offending package is
|
||||
identified and fixed.
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Fri, 29 Aug 2008 11:09:04 -0400
|
||||
|
||||
gramps (3.0.1-1) unstable; urgency=low
|
||||
|
||||
* New upstream version
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 19 May 2008 09:38:28 -0400
|
||||
|
||||
gramps (3.0.0-6) unstable; urgency=low
|
||||
|
||||
* Fix typo in _EditChildRef.py which can cause gramps to crash. Closes: #476163
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Tue, 15 Apr 2008 23:37:04 -0400
|
||||
|
||||
gramps (3.0.0-5) unstable; urgency=low
|
||||
|
||||
* Remove gtkspell Recommends as it is now provided by python-gnome2-extras.
|
||||
Closes: Bug#474755
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 07 Apr 2008 17:25:18 -0400
|
||||
|
||||
gramps (3.0.0-4) unstable; urgency=low
|
||||
|
||||
* Fix the binary package python dependency properly. A recent python
|
||||
(>= 2.4.4-6) is needed to ensure python2.5 is supported properly.
|
||||
Closes: #474056
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Thu, 03 Apr 2008 09:46:28 -0400
|
||||
|
||||
gramps (3.0.0-3) unstable; urgency=low
|
||||
|
||||
* Build-Depends on Python2.5. Closes: Bug#473946, #474056
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Wed, 02 Apr 2008 08:28:27 -0400
|
||||
|
||||
gramps (3.0.0-2) unstable; urgency=low
|
||||
|
||||
* Explicitly require python version >= 2.5
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Wed, 26 Mar 2008 09:34:25 -0400
|
||||
|
||||
gramps (3.0.0-1) unstable; urgency=low
|
||||
|
||||
* New upstream release. Closes: #472681
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Tue, 25 Mar 2008 09:35:00 -0400
|
||||
|
||||
gramps (2.2.10-2) unstable; urgency=low
|
||||
|
||||
* Remove build dependency on python-xml. Closes: Bug#468625
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Fri, 29 Feb 2008 13:30:11 -0500
|
||||
|
||||
gramps (2.2.10-1) unstable; urgency=low
|
||||
|
||||
* New upstream release
|
||||
* Added dh_icons to debian/rules. Closes: #454761
|
||||
* Remove version from scrollkeeper dependency. Closes: #456600
|
||||
* Fixed typos in description. Closes: #433559
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 14 Jan 2008 09:57:25 -0500
|
||||
|
||||
gramps (2.2.9-2) unstable; urgency=low
|
||||
|
||||
* Move debhelper to Build-Depends. Closes: #447948
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Wed, 24 Oct 2007 20:03:36 -0400
|
||||
|
||||
gramps (2.2.9-1) unstable; urgency=low
|
||||
gramps (2.90.0-0beta) unstable; urgency=low
|
||||
|
||||
* New upstream release
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Thu, 18 Oct 2007 13:14:30 -0400
|
||||
-- Stephane Charette <stephanecharette@gmail.com> Wed, 16 Jan 2008 21:45:00 -0800
|
||||
|
||||
gramps (2.2.8-2) unstable; urgency=low
|
||||
|
||||
* Work around a bug in gnome-python-extras which caused a deallocation
|
||||
of the TextView in the check if a spell checker is present.
|
||||
Closes: #445864
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Tue, 09 Oct 2007 17:26:54 -0400
|
||||
|
||||
gramps (2.2.8-1) unstable; urgency=low
|
||||
|
||||
* New Upstream version
|
||||
* Misleading error message changed. Closes: #418033
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 28 May 2007 21:00:51 -0400
|
||||
|
||||
gramps (2.2.7-2) unstable; urgency=low
|
||||
|
||||
* Added dependency on librsvg2-common
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 23 Apr 2007 19:32:00 -0400
|
||||
|
||||
gramps (2.2.7-1) unstable; urgency=low
|
||||
|
||||
* New upstream version
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Sun, 22 Apr 2007 20:08:55 -0400
|
||||
|
||||
gramps (2.2.6-1) unstable; urgency=low
|
||||
|
||||
* New upstream version
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 29 Jan 2007 20:12:05 -0500
|
||||
|
||||
gramps (2.2.5-0rc1-1) unstable; urgency=low
|
||||
|
||||
* rc1 of 2.2.5
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Thu, 25 Jan 2007 23:04:24 -0500
|
||||
|
||||
gramps (2.2.4-1) unstable; urgency=low
|
||||
gramps (2.1.6-1) unstable; urgency=low
|
||||
|
||||
* New upstream release
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Wed, 27 Dec 2006 18:04:11 -0500
|
||||
|
||||
gramps (2.2.3-1) unstable; urgency=low
|
||||
|
||||
* New upstream release
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 27 Nov 2006 00:27:23 -0500
|
||||
|
||||
gramps (2.2.2-2) unstable; urgency=low
|
||||
|
||||
* call dh_desktop in debian/rules so .desktop file is registered. Closes: Bug#398423
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 13 Nov 2006 20:26:00 -0500
|
||||
|
||||
gramps (2.2.2-1) unstable; urgency=low
|
||||
|
||||
* Bumped upstream version number. 2.2.1-3 and -4 should have been 2.2.2
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Sat, 4 Nov 2006 16:34:47 -0500
|
||||
|
||||
gramps (2.2.1-4) unstable; urgency=low
|
||||
|
||||
* add missing Build-Depends-Indep. Closes: #396874
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Fri, 3 Nov 2006 11:03:35 -0500
|
||||
|
||||
gramps (2.2.1-3) unstable; urgency=low
|
||||
|
||||
* New Upstream release
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Fri, 3 Nov 2006 08:07:38 -0500
|
||||
|
||||
gramps (2.2.1-2) unstable; urgency=low
|
||||
|
||||
* Upload to sid
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Wed, 1 Nov 2006 20:50:28 -0500
|
||||
|
||||
gramps (2.2.1-1) experimental; urgency=low
|
||||
|
||||
* New upstream release
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Mon, 30 Oct 2006 10:32:43 -0500
|
||||
|
||||
gramps (2.1.95-1) experimental; urgency=low
|
||||
|
||||
* Beta release of version 2.2
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Tue, 29 Aug 2006 11:40:08 -0400
|
||||
|
||||
|
||||
gramps (2.1.90-1) experimental; urgency=low
|
||||
|
||||
* Beta release of version 2.2
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Tue, 25 Jul 2006 00:18:15 -0400
|
||||
|
||||
gramps (2.0.11-2) unstable; urgency=low
|
||||
|
||||
* Complies with new python policy
|
||||
|
||||
-- James A. Treacy <treacy@debian.org> Wed, 5 Jul 2006 14:47:56 -0400
|
||||
-- Alex Roitman <shura@gramps-project.org> Thu, 22 Jun 2006 13:28:14 -0700
|
||||
|
||||
gramps (2.0.11-1) unstable; urgency=low
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
7
|
||||
4
|
||||
Vendored
+16
-20
@@ -1,27 +1,23 @@
|
||||
Source: gramps
|
||||
Section: gnome
|
||||
Priority: optional
|
||||
Maintainer: Stéphane Charette <stephanecharette@gmail.com>
|
||||
Build-Depends-Indep: libxml-parser-perl, python-gtk2, gettext, python-central (>= 0.5.6), python, intltool
|
||||
Build-Depends: debhelper (>= 7)
|
||||
Standards-Version: 3.8.3
|
||||
Homepage: http://www.gramps-project.org/
|
||||
XS-Python-Version: >=2.5
|
||||
Maintainer: James A. Treacy <treacy@debian.org>
|
||||
Build-Depends-Indep: debhelper (>=5.0.37.2), python-xml, python-gnome2, python-glade2, scrollkeeper, libglib2.0-dev, build-essential, gnome-doc-utils, intltool, xsltproc, python-central (>= 0.4.17)
|
||||
Standards-Version: 3.6.2
|
||||
XS-Python-Version: current
|
||||
|
||||
Package: gramps
|
||||
Architecture: all
|
||||
Depends: ${python:Depends}, librsvg2-common, python-gtk2, xdg-utils, ${misc:Depends}
|
||||
Replaces: gramps-manual, gramps-extending-doc
|
||||
Conflicts: gramps-manual, gramps-extending-doc, gramps-common, python-gtk-1.2
|
||||
Recommends: graphviz, python-webkit, python-gtkmozembed
|
||||
Suggests: ttf-freefont, python-enchant, python-gtkspell
|
||||
Description: Genealogical research program
|
||||
GRAMPS is an Open Source genealogy program written in Python, using
|
||||
the GTK/GNOME interface. It is an extremely flexible program fitting
|
||||
the needs for both the amateur genealogist and serious genealogical
|
||||
researcher.
|
||||
GRAMPS has the ability to import GEDCOM files exported from many
|
||||
proprietary genealogy programs and can produce a large number of
|
||||
reports in many popular formats.
|
||||
XB-Python-Version: ${python:Versions}
|
||||
Depends: ${python:Depends}, python-gnome2, python-glade2, ${misc:Depends}
|
||||
Replaces: gramps-manual, gramps-extending-doc, gramps-help
|
||||
Conflicts: gramps-manual, gramps-extending-doc, gramps-common
|
||||
Recommends: graphviz, ttf-freefont, python-reportlab, python-gnome2-extras
|
||||
Description: Genealogical Research and Analysis Management Program
|
||||
GRAMPS, the Genealogical Research and Analysis Management Programming
|
||||
System, is an Open Source genealogy program written in Python, using
|
||||
the GTK/GNOME interface.
|
||||
GRAMPS has the ability to import GEDCOM files that are used in such
|
||||
programs as FamilyTree Maker for Windows and can produce reports
|
||||
in various formats such as the popular ABIWord and OpenOffice.org
|
||||
formats as well as HTML and PDF.
|
||||
|
||||
Vendored
-1
@@ -1,2 +1 @@
|
||||
usr/share/pixmaps
|
||||
usr/share/mime/packages
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
/usr/bin/
|
||||
/usr/share/
|
||||
/etc
|
||||
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
||||
?package(gramps):needs="X11" section="Applications/Office"\
|
||||
?package(gramps):needs="X11" section="Apps/Tools"\
|
||||
title="gramps" command="/usr/bin/gramps"\
|
||||
icon="/usr/share/pixmaps/gramps.xpm"
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
2
|
||||
Vendored
+32
-29
@@ -4,68 +4,71 @@ build: build-stamp
|
||||
build-stamp:
|
||||
dh_testdir
|
||||
|
||||
#./autogen.sh --prefix=/usr --mandir=\$${prefix}/share/man --sysconfdir=/etc
|
||||
./configure --enable-packager-mode --prefix=/usr --mandir=\$${prefix}/share/man --sysconfdir=/etc
|
||||
# ./configure --prefix=`pwd`/debian/tmp/usr --mandir=\$${prefix}/share/man
|
||||
./configure \
|
||||
--enable-packager-mode \
|
||||
--disable-scrollkeeper \
|
||||
--prefix=/usr \
|
||||
--mandir=\$${prefix}/share/man \
|
||||
--sysconfdir=/etc
|
||||
$(MAKE)
|
||||
# $(MAKE) html
|
||||
|
||||
touch build-stamp
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
-rm -f build-stamp
|
||||
|
||||
# [ ! -f Makefile ] || $(MAKE) distclean
|
||||
# -rm -f src/*.pyo src/*/*.pyo
|
||||
# -rm -f config.status config.log
|
||||
-$(MAKE) clean
|
||||
-rm -f src/*.pyo src/*/*.pyo src/*/*/*.pyo src/*/*/*/*.pyo
|
||||
-rm -f config.status config.log
|
||||
|
||||
dh_auto_clean
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_prep
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/tmp.
|
||||
# GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1
|
||||
GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1
|
||||
$(MAKE) install DESTDIR=`pwd`/debian/gramps
|
||||
-rm -f debian/gramps/usr/share/gramps/COPYING
|
||||
ln -s /usr/share/common-licenses/GPL-2 debian/gramps/usr/share/gramps/COPYING
|
||||
-rm -rf debian/gramps/usr/var
|
||||
# cp src/data/gramps.xml debian/gramps/usr/share/mime/packages
|
||||
# Remove help-related dirs, they will go into gramps-help package
|
||||
-rm -rf debian/gramps/usr/share/gnome
|
||||
-rm -rf debian/gramps/usr/share/omf
|
||||
|
||||
# Remove byte-compiled python files
|
||||
-find debian/gramps/usr/share/ -name "*.pyo" -exec rm -f '{}' ';'
|
||||
|
||||
# Copy icon file
|
||||
cp debian/gramps.xpm debian/gramps/usr/share/pixmaps/
|
||||
# cp src/gramps.xpm debian/tmp/usr/share/pixmaps/
|
||||
# cp src/images/gramps.svg debian/gramps/usr/share/pixmaps/
|
||||
# chmod 644 debian/gramps/usr/share/pixmaps/gramps.svg
|
||||
#cp src/data/gramps.svg debian/gramps/usr/share/pixmaps/
|
||||
#chmod 644 debian/gramps/usr/share/pixmaps/gramps.svg
|
||||
|
||||
# Instal gramps-help things
|
||||
#$(MAKE) -C help install DESTDIR=`pwd`/debian/gramps-help
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_installdocs FAQ
|
||||
dh_installmenu
|
||||
# dh_installman
|
||||
dh_installdocs
|
||||
dh_installmenu --package=gramps
|
||||
dh_installman --package=gramps
|
||||
dh_installmime -i
|
||||
# dh_installchangelogs ChangeLog
|
||||
dh_installchangelogs
|
||||
dh_icons
|
||||
# dh_movefiles -i
|
||||
# dh_gconf -i
|
||||
dh_link -i
|
||||
dh_installchangelogs --package=gramps ChangeLog
|
||||
#dh_installchangelogs --package=gramps-help help/ChangeLog
|
||||
dh_gconf --package=gramps
|
||||
#dh_scrollkeeper --package=gramps-help
|
||||
dh_compress -i
|
||||
dh_fixperms -i
|
||||
dh_pycentral -i
|
||||
dh_installdeb -i
|
||||
dh_python --package=gramps
|
||||
dh_installdeb -i
|
||||
dh_gencontrol -i
|
||||
dh_md5sums -i
|
||||
dh_builddeb -i
|
||||
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf _build/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in _build/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in _build/dirhtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in _build/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in _build/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator _build/qthelp/Gramps.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile _build/qthelp/Gramps.qhc"
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in _build/latex."
|
||||
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
|
||||
"run these through (pdf)latex."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
|
||||
@echo
|
||||
@echo "The overview file is in _build/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in _build/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in _build/doctest/output.txt."
|
||||
@@ -1,72 +0,0 @@
|
||||
Installation and building the docs
|
||||
==================================
|
||||
|
||||
You need to install sphinx. Assuming you have installed the python setuptools, just do:
|
||||
|
||||
sudo easy_install sphinx
|
||||
|
||||
Once installed, go to the docs directory, and do:
|
||||
|
||||
make html
|
||||
|
||||
Which will produce the html output in docs/_build/html
|
||||
|
||||
|
||||
Documentation Guidelines
|
||||
=======================
|
||||
|
||||
Doc strings in python files should be written in reStructured text: http://docutils.sourceforge.net/docs/user/rst/quickref.html
|
||||
|
||||
The typical docstring for GRAMPS should look like this:
|
||||
|
||||
"""Brief synopsis
|
||||
|
||||
This is a longer explanation, which may include *italics* or **bold**, or
|
||||
a link to another method :meth:`~gen.lib.person.Person.get_handle`
|
||||
Then, you need to provide optional subsection in this order (just to be
|
||||
consistent and have a uniform documentation, nothing prevent you to switch
|
||||
the order).
|
||||
|
||||
:param arg1: the first value
|
||||
:type arg1: int or float or :class:`~gen.lib.baseobj.BaseObject`
|
||||
:param arg2: the second value
|
||||
:type arg2: int or float
|
||||
:param arg3: the third value
|
||||
|
||||
:returns: arg1/arg2 +arg3
|
||||
:rtype: float, this is the return type
|
||||
|
||||
|
||||
:Examples:
|
||||
|
||||
>>> import template
|
||||
>>> a = MainClass()
|
||||
>>> a.function2(1,1,1)
|
||||
2
|
||||
|
||||
:note:
|
||||
can be useful to emphasize
|
||||
important feature
|
||||
|
||||
:See Also:
|
||||
:class:`MainClass1`
|
||||
|
||||
:Warnings:
|
||||
arg2 must be non-zero.
|
||||
|
||||
:Todo:
|
||||
check that arg2 is non zero.
|
||||
"""
|
||||
|
||||
For a class, use :cvar variable: for class variable, :ivar variable: for instance class
|
||||
variable, .. attribute:: attribute: for attributes, ....
|
||||
See http://sphinx.pocoo.org/markup/desc.html and http://sphinx.pocoo.org/markup/inline.html
|
||||
|
||||
Tips and Tricks
|
||||
===============
|
||||
Change in many files something:
|
||||
|
||||
perl -pi -w -e "s/L{PersonRef}/:class:\`\~gen.lib.personref.PersonRef\`/g;" *.py
|
||||
|
||||
here L{PersonRef} is changed in :class:`~gen.lib.personref.PersonRef
|
||||
`
|
||||
@@ -1,42 +0,0 @@
|
||||
##################
|
||||
Code Documentation
|
||||
##################
|
||||
|
||||
*GRAMPS* provides several general API. The most important is the *gen* module, providing access to all code that can be of interest outside of the GRAMPS program.
|
||||
|
||||
The :mod:`gen` Module
|
||||
=======================
|
||||
|
||||
.. automodule:: gen
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
gen/gen_lib
|
||||
gen/gen_db
|
||||
gen/gen_proxy
|
||||
gen/gen_utils
|
||||
|
||||
The GRAMPS Application
|
||||
========================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
corecli/cli
|
||||
coregui/gui
|
||||
utils
|
||||
|
||||
Usefull snippets
|
||||
===================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
html
|
||||
-202
@@ -1,202 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sat Jun 20 00:07:37 2009.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.append(os.path.abspath('.'))
|
||||
|
||||
#documentation in root/docs, allow import from root/src where GRAMPS modules life
|
||||
sourcedir = (os.path.abspath('.')).split(os.sep)[:-1] + ['src']
|
||||
sys.path.append((os.sep).join(sourcedir))
|
||||
#make it possible to add plugins --> walk the plugin dir and add to sys.path.append
|
||||
for (dirpath, dirnames, filenames) in os.walk((os.sep).join(sourcedir + ['plugins'])):
|
||||
# add the directory to the python search path
|
||||
sys.path.append(dirpath)
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Gramps'
|
||||
copyright = u'2009, The Gramps Project'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '3.2'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '3.2.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of documents that shouldn't be included in the build.
|
||||
#unused_docs = []
|
||||
|
||||
# List of directories, relative to source directory, that shouldn't be searched
|
||||
# for source files.
|
||||
exclude_trees = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_use_modindex = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = ''
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Grampsdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Gramps.tex', u'Gramps Documentation',
|
||||
u'The Gramps Project', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_use_modindex = True
|
||||
@@ -1,4 +0,0 @@
|
||||
The :mod:`cli` Module
|
||||
=====================
|
||||
|
||||
Todo
|
||||
@@ -1,4 +0,0 @@
|
||||
The :mod:`gui` Module
|
||||
=====================
|
||||
|
||||
Todo
|
||||
@@ -1,4 +0,0 @@
|
||||
Developer Guide
|
||||
===============
|
||||
|
||||
Please consult the API documentation, and the development part of `our wiki <http://gramps-project.org>`_\ .
|
||||
@@ -1,159 +0,0 @@
|
||||
##########################
|
||||
The :mod:`gen.db` Module
|
||||
##########################
|
||||
|
||||
Contents:
|
||||
|
||||
.. automodule:: gen.db
|
||||
|
||||
*****************************
|
||||
Base object
|
||||
*****************************
|
||||
|
||||
GrampsDbBase
|
||||
====================================
|
||||
.. automodule:: gen.db.base
|
||||
.. autoclass:: GrampsDbBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Read object
|
||||
*****************************
|
||||
|
||||
GrampsDbRead
|
||||
====================================
|
||||
.. automodule:: gen.db.read
|
||||
.. autoclass:: GrampsDbRead
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Write object
|
||||
*****************************
|
||||
|
||||
GrampsDbWrite
|
||||
====================================
|
||||
.. automodule:: gen.db.write
|
||||
.. autoclass:: GrampsDBDir
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Cursor
|
||||
*****************************
|
||||
|
||||
GrampsCursor
|
||||
====================================
|
||||
.. automodule:: gen.db.cursor
|
||||
.. autoclass:: GrampsCursor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
BSDDB txn
|
||||
*****************************
|
||||
|
||||
BSDDBtxn
|
||||
====================================
|
||||
.. automodule:: gen.db.bsddbtxn
|
||||
.. autoclass:: BSDDBTxn
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Txn object
|
||||
*****************************
|
||||
|
||||
GrampsDbTxn
|
||||
====================================
|
||||
.. automodule:: gen.db.txn
|
||||
.. autoclass:: GrampsDbTxn
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Undoredo object
|
||||
*****************************
|
||||
|
||||
GrampsDbUndo
|
||||
====================================
|
||||
.. automodule:: gen.db.undoredo
|
||||
.. autoclass:: GrampsDbUndo
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
GrampsDbUndoList
|
||||
====================================
|
||||
|
||||
.. autoclass:: GrampsDbUndoList
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
GrampsDbUndoBSDDB
|
||||
====================================
|
||||
|
||||
.. autoclass:: GrampsDbUndoBSDDB
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Dbconst object
|
||||
*****************************
|
||||
|
||||
DbConst
|
||||
====================================
|
||||
.. automodule:: gen.db.dbconst
|
||||
:members:
|
||||
|
||||
*****************************
|
||||
Exceptions object
|
||||
*****************************
|
||||
|
||||
GrampsDbException
|
||||
====================================
|
||||
.. automodule:: gen.db.exceptions
|
||||
.. autoclass:: GrampsDbException
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
GrampsDbWriteFailure
|
||||
====================================
|
||||
|
||||
.. autoclass:: GrampsDbWriteFailure
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
FileVersionError
|
||||
====================================
|
||||
|
||||
.. autoclass:: FileVersionError
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
FileVersionDeclineToUpgrade
|
||||
====================================
|
||||
|
||||
.. autoclass:: FileVersionDeclineToUpgrade
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Upgrade utilities
|
||||
*****************************
|
||||
|
||||
.. automodule:: gen.db.upgrade
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -1,489 +0,0 @@
|
||||
##########################
|
||||
The :mod:`gen.lib` Module
|
||||
##########################
|
||||
|
||||
Contents:
|
||||
|
||||
.. automodule:: gen.lib
|
||||
|
||||
*****************************
|
||||
Base objects
|
||||
*****************************
|
||||
|
||||
BaseObject
|
||||
====================================
|
||||
.. automodule:: gen.lib.baseobj
|
||||
.. autoclass:: gen.lib.baseobj.BaseObject
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
RefBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.refbase
|
||||
.. autoclass:: RefBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
PrivacyBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.privacybase
|
||||
.. autoclass:: PrivacyBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
SourceBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.srcbase
|
||||
.. autoclass:: SourceBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
NoteBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.notebase
|
||||
.. autoclass:: NoteBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
MediaBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.mediabase
|
||||
.. autoclass:: MediaBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
PlaceBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.placebase
|
||||
.. autoclass:: PlaceBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
LocationBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.locationbase
|
||||
.. autoclass:: LocationBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
AddressBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.addressbase
|
||||
.. autoclass:: AddressBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
AttributeBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.attrbase
|
||||
.. autoclass:: AttributeBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
DateBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.datebase
|
||||
.. autoclass:: DateBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
UrlBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.urlbase
|
||||
.. autoclass:: UrlBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
LdsOrdBase
|
||||
====================================
|
||||
.. automodule:: gen.lib.ldsordbase
|
||||
.. autoclass:: LdsOrdBase
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Primary objects
|
||||
*****************************
|
||||
|
||||
BasicPrimaryObject
|
||||
====================================
|
||||
.. automodule:: gen.lib.primaryobj
|
||||
.. autoclass:: BasicPrimaryObject
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
PrimaryObject
|
||||
====================================
|
||||
.. autoclass:: PrimaryObject
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Person
|
||||
====================================
|
||||
.. automodule:: gen.lib.person
|
||||
.. autoclass:: Person
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Family
|
||||
====================================
|
||||
.. automodule:: gen.lib.family
|
||||
.. autoclass:: Family
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Event
|
||||
====================================
|
||||
.. automodule:: gen.lib.event
|
||||
.. autoclass:: Event
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Place
|
||||
====================================
|
||||
.. automodule:: gen.lib.place
|
||||
.. autoclass:: Place
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Source
|
||||
====================================
|
||||
.. automodule:: gen.lib.src
|
||||
.. autoclass:: Source
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Media Object
|
||||
====================================
|
||||
.. automodule:: gen.lib.mediaobj
|
||||
.. autoclass:: MediaObject
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Repository
|
||||
====================================
|
||||
.. automodule:: gen.lib.repo
|
||||
.. autoclass:: Repository
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Note
|
||||
====================================
|
||||
.. automodule:: gen.lib.note
|
||||
.. autoclass:: Note
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Secondary objects
|
||||
*****************************
|
||||
|
||||
Secondary Object
|
||||
====================================
|
||||
.. automodule:: gen.lib.secondaryobj
|
||||
.. autoclass:: SecondaryObject
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Address
|
||||
====================================
|
||||
.. automodule:: gen.lib.address
|
||||
.. autoclass:: Address
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Location
|
||||
====================================
|
||||
.. automodule:: gen.lib.location
|
||||
.. autoclass:: Location
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Attribute
|
||||
====================================
|
||||
.. automodule:: gen.lib.attribute
|
||||
.. autoclass:: Attribute
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
LdsOrd
|
||||
====================================
|
||||
.. automodule:: gen.lib.ldsord
|
||||
.. autoclass:: LdsOrd
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Name
|
||||
====================================
|
||||
.. automodule:: gen.lib.name
|
||||
.. autoclass:: Name
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Url
|
||||
====================================
|
||||
.. automodule:: gen.lib.url
|
||||
.. autoclass:: Url
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
*****************************
|
||||
Reference objects
|
||||
*****************************
|
||||
|
||||
PersonRef
|
||||
====================================
|
||||
.. automodule:: gen.lib.personref
|
||||
.. autoclass:: PersonRef
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ChildRef
|
||||
====================================
|
||||
.. automodule:: gen.lib.childref
|
||||
.. autoclass:: ChildRef
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
EventRef
|
||||
====================================
|
||||
.. automodule:: gen.lib.eventref
|
||||
.. autoclass:: EventRef
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
MediaRef
|
||||
====================================
|
||||
.. automodule:: gen.lib.mediaref
|
||||
.. autoclass:: MediaRef
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
SourceRef
|
||||
====================================
|
||||
.. automodule:: gen.lib.srcref
|
||||
.. autoclass:: SourceRef
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
RepoRef
|
||||
====================================
|
||||
.. automodule:: gen.lib.reporef
|
||||
.. autoclass:: RepoRef
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Date objects
|
||||
*****************************
|
||||
.. automodule:: gen.lib.date
|
||||
|
||||
Date
|
||||
====================================
|
||||
.. autoclass:: Date
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Span
|
||||
====================================
|
||||
.. autoclass:: Span
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
DateError
|
||||
====================================
|
||||
.. autoexception:: DateError
|
||||
|
||||
*****************************
|
||||
Text objects
|
||||
*****************************
|
||||
|
||||
StyledTextTag
|
||||
===================
|
||||
.. automodule:: gen.lib.styledtexttag
|
||||
.. autoclass:: StyledTextTag
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
StyledText
|
||||
===========
|
||||
.. automodule:: gen.lib.styledtext
|
||||
.. autoclass:: StyledText
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Meta data
|
||||
*****************************
|
||||
|
||||
GenderStats
|
||||
============
|
||||
|
||||
.. automodule:: gen.lib.genderstats
|
||||
.. autoclass:: GenderStats
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Researcher
|
||||
===========
|
||||
.. automodule:: gen.lib.researcher
|
||||
.. autoclass:: Researcher
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
*****************************
|
||||
Type classes
|
||||
*****************************
|
||||
.. automodule:: gen.lib.grampstype
|
||||
.. autoclass:: GrampsTypeMeta
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
GrampsType
|
||||
===========
|
||||
.. autoclass:: GrampsType
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
NameType
|
||||
===========
|
||||
.. automodule:: gen.lib.nametype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
AttributeType
|
||||
=============
|
||||
.. automodule:: gen.lib.attrtype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
UrlType
|
||||
========
|
||||
.. automodule:: gen.lib.urltype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ChildRefType
|
||||
=============
|
||||
.. automodule:: gen.lib.childreftype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
RepositoryType
|
||||
==============
|
||||
.. automodule:: gen.lib.repotype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
EventType
|
||||
===========
|
||||
.. automodule:: gen.lib.eventtype
|
||||
.. autoclass:: EventType
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
FamilyRelType
|
||||
=============
|
||||
.. automodule:: gen.lib.familyreltype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
SourceMediaType
|
||||
================
|
||||
.. automodule:: gen.lib.srcmediatype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
EventRoleType
|
||||
==============
|
||||
.. automodule:: gen.lib.eventroletype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
MarkerType
|
||||
==========
|
||||
.. automodule:: gen.lib.markertype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
NoteType
|
||||
=========
|
||||
.. automodule:: gen.lib.notetype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
StyledTextTagType
|
||||
==================
|
||||
.. automodule:: gen.lib.styledtexttagtype
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
############################
|
||||
The :mod:`gen.proxy` Module
|
||||
############################
|
||||
|
||||
Contents:
|
||||
|
||||
.. automodule:: gen.proxy
|
||||
|
||||
**TODO**
|
||||
@@ -1,9 +0,0 @@
|
||||
############################
|
||||
The :mod:`gen.utils` Module
|
||||
############################
|
||||
|
||||
Contents:
|
||||
|
||||
.. automodule:: gen.utils
|
||||
|
||||
**TODO**
|
||||
@@ -1,11 +0,0 @@
|
||||
##########################
|
||||
The :class:`Html` Class
|
||||
##########################
|
||||
|
||||
Contents:
|
||||
|
||||
.. automodule:: libhtml
|
||||
.. autoclass:: Html
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -1,24 +0,0 @@
|
||||
.. Gramps documentation master file, created by
|
||||
sphinx-quickstart on Sat Jun 20 00:07:37 2009.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to Gramps's documentation!
|
||||
==================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
user_guide
|
||||
developer_guide
|
||||
api
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#########################################
|
||||
The :class:`RelationshipCalculator` Class
|
||||
#########################################
|
||||
|
||||
Contents:
|
||||
|
||||
.. automodule:: Relationship
|
||||
.. autoclass:: RelationshipCalculator
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -1,4 +0,0 @@
|
||||
User Guide
|
||||
==========
|
||||
|
||||
Please consult the manual which you find on `our wiki <http://www.gramps-project.org/wiki/index.php?title=User_manual>`_\ .
|
||||
@@ -1,12 +0,0 @@
|
||||
############################
|
||||
The :mod:`Utils` Module
|
||||
############################
|
||||
|
||||
Contents:
|
||||
|
||||
.. automodule:: Utils
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
+1
-1
@@ -25,4 +25,4 @@ PACKAGE=@PACKAGE@
|
||||
|
||||
export GRAMPSDIR=@datadir@/@PACKAGE@
|
||||
|
||||
exec @PYTHON@ -O $GRAMPSDIR/gramps.py "$@"
|
||||
exec @PYTHON@ $GRAMPSDIR/gramps.py "$@"
|
||||
+445
-535
File diff suppressed because it is too large.
Load diff
+7
-15
@@ -1,31 +1,23 @@
|
||||
src/DataViews/MapView.py
|
||||
src/Filters/Rules/_HasGalleryBase.py
|
||||
src/Filters/Rules/_HasLDSBase.py
|
||||
src/Filters/Rules/_HasNoteBase.py
|
||||
src/Filters/Rules/_HasReferenceCountOf.py
|
||||
src/Filters/Rules/_HasSourceBase.py
|
||||
src/Filters/Rules/_MatchesEventFilterBase.py
|
||||
src/Filters/Rules/_MatchesSourceFilterBase.py
|
||||
src/gen/db/write.py
|
||||
src/gen/lib/styledtext.py
|
||||
src/gen/lib/styledtexttagtype.py
|
||||
src/LdsUtils.py
|
||||
src/Mime/_WinMime.py
|
||||
src/plugins/docgen/PdfDoc.py
|
||||
src/plugins/export/ExportDjango.gpr.py
|
||||
src/plugins/import/ImportDjango.gpr.py
|
||||
src/plugins/gramplet/DeepConnections.py
|
||||
src/plugins/gramplet/NoteGramplet.py
|
||||
src/plugins/gramplet/PluginManagerGramplet.py
|
||||
src/plugins/gramplet/PythonGramplet.py
|
||||
src/plugins/import/ImportSql.py
|
||||
src/plugins/tool/DateParserDisplayTest.py
|
||||
src/plugins/tool/DumpGenderStats.py
|
||||
src/plugins/tool/PHPGedViewConnector.py
|
||||
src/plugins/tool/TestcaseGenerator.py
|
||||
src/plugins/tool/phpgedview.glade
|
||||
src/plugins/gramplet/HeadlineNewsGramplet.py
|
||||
src/plugins/quickview/AllNames.py
|
||||
src/plugins/quickview/Query.py
|
||||
src/ReportBase/_DocReportDialog.py
|
||||
src/web/grampsdb/views.py
|
||||
src/web/utils.py
|
||||
src/plugins/gramplet/FaqGramplet.py
|
||||
src/plugins/gramplet/HeadlineNewsGramplet.py
|
||||
src/plugins/quickview/Query.py
|
||||
src/plugins/tool/eval.glade
|
||||
src/plugins/tool/leak.glade
|
||||
|
||||
+1
-1
@@ -158,7 +158,7 @@ class Check_runaway( Check ):
|
||||
class Check_xml_chars( Check ):
|
||||
# Special XML characters
|
||||
# It is not allowed to have a quote, an ampersand or an angle bracket
|
||||
xml_chars_pat = re.compile( r'<(?!(b>|/b>|i>|/i>|br/>)) | (?<=!(<b|/b|<i|/i|r/))> | " | & (?!(quot|nbsp|gt|amp);)', re.VERBOSE )
|
||||
xml_chars_pat = re.compile( r'(?<=\W) > | " | & (?!(quot|nbsp|gt|amp);)', re.VERBOSE )
|
||||
|
||||
def __init__( self ):
|
||||
Check.__init__( self )
|
||||
|
||||
+18423
-19785
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+20837
-20583
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+17
-7
@@ -22,14 +22,28 @@
|
||||
|
||||
""" Unittest for testing POTFILES.in and Makefile contents """
|
||||
|
||||
# PYTHONPATH=/../src python po_test.py
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import glob
|
||||
from test import test_util
|
||||
test_util.path_append_parent()
|
||||
|
||||
excluded_files = ["src/DataViews/_MapView.py",
|
||||
"src/plugins/PHPGedViewConnector.py",
|
||||
"src/plugins/phpgedview.glade",
|
||||
"src/plugins/Ancestors.py",
|
||||
"src/plugins/DesGraph.py",
|
||||
"src/plugins/FtmStyleAncestors.py",
|
||||
"src/plugins/FtmStyleDescendants.py",
|
||||
"src/plugins/IndivSummary.py",
|
||||
"src/date_test.py",
|
||||
"src/plugins/CmdRef.py",
|
||||
"src/plugins/DumpGenderStats.py",
|
||||
"src/plugins/Eval.py",
|
||||
"src/plugins/Leak.py",
|
||||
"src/plugins/TestcaseGenerator.py"
|
||||
]
|
||||
|
||||
def get_potfile(filename):
|
||||
fp = open(filename, "r")
|
||||
retvals = []
|
||||
@@ -39,10 +53,6 @@ def get_potfile(filename):
|
||||
fp.close()
|
||||
return retvals
|
||||
|
||||
# POTFILES.skip
|
||||
|
||||
excluded_files = get_potfile("../POTFILES.skip")
|
||||
|
||||
class TestPOT(unittest.TestCase):
|
||||
potfiles = get_potfile("../POTFILES.in")
|
||||
count = 1
|
||||
@@ -162,7 +172,7 @@ def suite2():
|
||||
if glob.fnmatch.fnmatch(potfile,"*.py"):
|
||||
suite.addTest(TestGetText('test_gettext_py_%04d', potfile,
|
||||
["import gettext",
|
||||
"from gen.ggettext",
|
||||
"from gettext",
|
||||
"import sgettext"]))
|
||||
elif glob.fnmatch.fnmatch(potfile,"*.glade"):
|
||||
suite.addTest(TestGetText('test_gettext_glade_%04d', potfile,
|
||||
|
||||
+18658
-20050
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,609 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham, A. Roitman
|
||||
# Copyright (C) 2007-2008 B. Malengier
|
||||
# Copyright (C) 2008 Lukasz Rymarczyk
|
||||
# Copyright (C) 2008 Raphael Ackermann
|
||||
# Copyright (C) 2008 Brian G. Matherly
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Module responsible for handling the command line arguments for GRAMPS.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import os
|
||||
import sys
|
||||
import getopt
|
||||
from gettext import gettext as _
|
||||
import logging
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import const
|
||||
import Config
|
||||
import RecentFiles
|
||||
import Utils
|
||||
import gen
|
||||
from DbManager import CLIDbManager, NAME_FILE, find_locker_name
|
||||
|
||||
from PluginUtils import Tool
|
||||
from gen.plug import PluginManager
|
||||
from ReportBase import CATEGORY_BOOK, CATEGORY_CODE, cl_report
|
||||
|
||||
# Note: Make sure to edit const.py POPT_TABLE too!
|
||||
_help = """
|
||||
Usage: gramps.py [OPTION...]
|
||||
--load-modules=MODULE1,MODULE2,... Dynamic modules to load
|
||||
|
||||
Help options
|
||||
-?, --help Show this help message
|
||||
--usage Display brief usage message
|
||||
|
||||
Application options
|
||||
-O, --open=FAMILY_TREE Open family tree
|
||||
-i, --import=FILENAME Import file
|
||||
-e, --export=FILENAME Export file
|
||||
-f, --format=FORMAT Specify format
|
||||
-a, --action=ACTION Specify action
|
||||
-p, --options=OPTIONS_STRING Specify options
|
||||
-d, --debug=LOGGER_NAME Enable debug logs
|
||||
-l List Family Trees
|
||||
-L List Family Tree Details
|
||||
-u, --force-unlock Force unlock of family tree
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# ArgHandler
|
||||
#-------------------------------------------------------------------------
|
||||
class ArgHandler(object):
|
||||
"""
|
||||
This class is responsible for handling command line arguments (if any)
|
||||
given to gramps. The valid arguments are:
|
||||
|
||||
FAMTREE : family tree name or database dir to open.
|
||||
All following arguments will be ignored.
|
||||
-O, --open=FAMTREE : Family tree or family tree database dir to open.
|
||||
-i, --import=FILE : filename to import.
|
||||
-e, --export=FILE : filename to export.
|
||||
-f, --format=FORMAT : format of the file preceding this option.
|
||||
|
||||
If the filename (no flags) is specified, the interactive session is
|
||||
launched using data from filename.
|
||||
In this mode (filename, no flags), the rest of the arguments is ignored.
|
||||
This is a mode suitable by default for GUI launchers, mime type handlers,
|
||||
and the like
|
||||
|
||||
If no filename or -i option is given, a new interactive session (empty
|
||||
database) is launched, since no data is given anyway.
|
||||
|
||||
If -O or -i option is given, but no -e or -a options are given, an
|
||||
interactive session is launched with the FILE (specified with -i).
|
||||
|
||||
If both input (-O or -i) and processing (-e or -a) options are given,
|
||||
interactive session will not be launched.
|
||||
"""
|
||||
|
||||
def __init__(self, state, vm, args):
|
||||
self.state = state
|
||||
self.vm = vm
|
||||
self.args = args
|
||||
|
||||
self.open_gui = None
|
||||
self.open = None
|
||||
self.cl = 0
|
||||
self.exports = []
|
||||
self.actions = []
|
||||
self.imports = []
|
||||
self.imp_db_path = None
|
||||
self.list = False
|
||||
self.list_more = False
|
||||
self.help = False
|
||||
self.force_unlock = False
|
||||
self.dbman = CLIDbManager(self.state)
|
||||
|
||||
self.parse_args()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Argument parser: sorts out given arguments
|
||||
#-------------------------------------------------------------------------
|
||||
def parse_args(self):
|
||||
"""
|
||||
Fill in lists with open, exports, imports, and actions options.
|
||||
|
||||
Any parsing errors lead to abort.
|
||||
|
||||
Possible:
|
||||
1/ Just the family tree (name or database dir)
|
||||
2/ -O, Open of a family tree
|
||||
3/ -i, Import of any format understood by an importer, optionally provide
|
||||
-f to indicate format
|
||||
4/ -e, export a family tree in required format, optionally provide
|
||||
-f to indicate format
|
||||
5/ -a, --action: An action (possible: 'check', 'summary', 'report',
|
||||
'tool')
|
||||
6/ -u, --force-unlock: A locked database can be unlocked by given this
|
||||
argument when opening it
|
||||
|
||||
"""
|
||||
try:
|
||||
options, leftargs = getopt.getopt(self.args[1:],
|
||||
const.SHORTOPTS, const.LONGOPTS)
|
||||
except getopt.GetoptError, msg:
|
||||
print msg
|
||||
# return without filling anything if we could not parse the args
|
||||
print "Error parsing the arguments: %s " % self.args[1:]
|
||||
print "Type gramps --help for an overview of commands, or ",
|
||||
print "read manual pages."
|
||||
sys.exit(0)
|
||||
|
||||
if leftargs:
|
||||
# if there were an argument without option,
|
||||
# use it as a file to open and return
|
||||
self.open_gui = leftargs[0]
|
||||
print "Trying to open: %s ..." % leftargs[0]
|
||||
#see if force open is on
|
||||
for opt_ix in range(len(options)):
|
||||
option, value = options[opt_ix]
|
||||
if option in ('-u', '--force-unlock'):
|
||||
self.force_unlock = True
|
||||
break
|
||||
return
|
||||
|
||||
# Go over all given option and place them into appropriate lists
|
||||
for opt_ix in range(len(options)):
|
||||
option, value = options[opt_ix]
|
||||
if option in ( '-O', '--open'):
|
||||
self.__handle_open_option(value)
|
||||
elif option in ( '-i', '--import'):
|
||||
format = None
|
||||
if opt_ix < len(options) - 1 \
|
||||
and options[opt_ix + 1][0] in ( '-f', '--format'):
|
||||
format = options[opt_ix + 1][1]
|
||||
self.__handle_import_option(value, format)
|
||||
elif option in ( '-e', '--export' ):
|
||||
format = None
|
||||
if opt_ix < len(options) - 1 \
|
||||
and options[opt_ix + 1][0] in ( '-f', '--format'):
|
||||
format = options[opt_ix + 1][1]
|
||||
self.__handle_export_option(value, format)
|
||||
elif option in ( '-a', '--action' ):
|
||||
action = value
|
||||
if action not in ( 'check', 'summary', 'report', 'tool' ):
|
||||
print "Unknown action: %s. Ignoring." % action
|
||||
continue
|
||||
options_str = ""
|
||||
if opt_ix < len(options)-1 \
|
||||
and options[opt_ix+1][0] in ( '-p', '--options' ):
|
||||
options_str = options[opt_ix+1][1]
|
||||
self.actions.append((action, options_str))
|
||||
elif option in ('-d', '--debug'):
|
||||
logger = logging.getLogger(value)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
elif option in ('-l',):
|
||||
self.list = True
|
||||
elif option in ('-L',):
|
||||
self.list_more = True
|
||||
elif option in ('-h', '-?', '--help'):
|
||||
self.help = True
|
||||
elif option in ('-u', '--force-unlock'):
|
||||
self.force_unlock = True
|
||||
|
||||
def __handle_open_option(self, value):
|
||||
"""
|
||||
Handle the "-O" or "--open" option.
|
||||
"""
|
||||
db_path = self.__deduce_db_path(value)
|
||||
|
||||
if db_path:
|
||||
# We have a potential database path.
|
||||
# Check if it is good.
|
||||
if not self.__check_db(db_path, self.force_unlock):
|
||||
sys.exit(0)
|
||||
self.open = db_path
|
||||
else:
|
||||
print _('Input family tree "%s" does not exist.') % value
|
||||
print _("If gedcom, gramps-xml or grdb, use the -i option to "
|
||||
"import into a family tree instead")
|
||||
sys.exit(0)
|
||||
|
||||
def __handle_import_option(self, value, format):
|
||||
"""
|
||||
Handle the "-i" or "--import" option.
|
||||
"""
|
||||
fname = value
|
||||
fullpath = os.path.abspath(os.path.expanduser(fname))
|
||||
if not os.path.exists(fullpath):
|
||||
print 'Import file not found.'
|
||||
print "Ignoring import file: %s" % fname
|
||||
return
|
||||
|
||||
if format is None:
|
||||
# Guess the file format based on the file extension.
|
||||
# This will get the lower case extension without a period,
|
||||
# or an empty string.
|
||||
format = os.path.splitext(fname)[-1][1:].lower()
|
||||
|
||||
pmgr = PluginManager.get_instance()
|
||||
plugin_found = False
|
||||
for plugin in pmgr.get_import_plugins():
|
||||
if format == plugin.get_extension():
|
||||
plugin_found = True
|
||||
|
||||
if plugin_found:
|
||||
self.imports.append((fname, format))
|
||||
else:
|
||||
print 'Unrecognized type: "%s" for import file: %s' \
|
||||
% (format, fname)
|
||||
print "Ignoring import file: %s" % fname
|
||||
|
||||
def __handle_export_option(self, value, format):
|
||||
"""
|
||||
Handle the "-e" or "--export" option.
|
||||
"""
|
||||
fname = value
|
||||
fullpath = os.path.abspath(os.path.expanduser(fname))
|
||||
if os.path.exists(fullpath):
|
||||
print "WARNING: Output file already exist!"
|
||||
print "WARNING: It will be overwritten:\n %s" % fullpath
|
||||
answer = None
|
||||
while not answer:
|
||||
answer = raw_input('OK to overwrite? (yes/no) ')
|
||||
if answer.upper() in ('Y','YES'):
|
||||
print "Will overwrite the existing file: %s" % fullpath
|
||||
else:
|
||||
print "Will skip the output file: %s" % fullpath
|
||||
return
|
||||
|
||||
if format is None:
|
||||
# Guess the file format based on the file extension.
|
||||
# This will get the lower case extension without a period,
|
||||
# or an empty string.
|
||||
format = os.path.splitext(fname)[-1][1:].lower()
|
||||
|
||||
pmgr = PluginManager.get_instance()
|
||||
plugin_found = False
|
||||
for plugin in pmgr.get_export_plugins():
|
||||
if format == plugin.get_extension():
|
||||
plugin_found = True
|
||||
|
||||
if plugin_found:
|
||||
self.exports.append((fullpath, format))
|
||||
else:
|
||||
print "Unrecognized format for export file %s" % fname
|
||||
print "Ignoring export file: %s" % fname
|
||||
|
||||
def __deduce_db_path(self, db_name_or_path):
|
||||
"""
|
||||
Attempt to find a database path for the given parameter.
|
||||
|
||||
@return: The path to a Gramps DB
|
||||
or None if a database can not be deduced.
|
||||
"""
|
||||
# First, check if this is the name of a family tree
|
||||
db_path = self.dbman.get_family_tree_path(db_name_or_path)
|
||||
|
||||
if db_path is None:
|
||||
# This is not a known database name.
|
||||
# Check if the user provided a db path instead.
|
||||
fullpath = os.path.abspath(os.path.expanduser(db_name_or_path))
|
||||
if os.path.isdir(fullpath):
|
||||
# The user provided a directory. Check if it is a valid tree.
|
||||
name_file_path = os.path.join(fullpath, NAME_FILE)
|
||||
if os.path.isfile(name_file_path):
|
||||
db_path = fullpath
|
||||
|
||||
return db_path
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Determine the need for GUI
|
||||
#-------------------------------------------------------------------------
|
||||
def need_gui(self):
|
||||
"""
|
||||
Determine whether we need a GUI session for the given tasks.
|
||||
"""
|
||||
if self.open_gui:
|
||||
# No-option argument, definitely GUI
|
||||
return True
|
||||
|
||||
# If we have data to work with:
|
||||
if (self.open or self.imports):
|
||||
if (self.exports or self.actions):
|
||||
# have both data and what to do with it => no GUI
|
||||
return False
|
||||
else:
|
||||
# data given, but no action/export => GUI
|
||||
return True
|
||||
|
||||
# No data, can only do GUI here
|
||||
return True
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Overall argument handler:
|
||||
# sorts out the sequence and details of operations
|
||||
#-------------------------------------------------------------------------
|
||||
def handle_args(self):
|
||||
"""
|
||||
Depending on the given arguments, import or open data, launch
|
||||
session, write files, and/or perform actions.
|
||||
"""
|
||||
|
||||
if self.list:
|
||||
print 'List of known family trees in your database path\n'
|
||||
for name, dirname in self.dbman.family_tree_list():
|
||||
print dirname, ', with name ', name
|
||||
sys.exit(0)
|
||||
|
||||
if self.list_more:
|
||||
print 'GRAMPS Family Trees:'
|
||||
summary_list = self.dbman.family_tree_summary()
|
||||
for summary in summary_list:
|
||||
print "Family Tree \"%s\":" % summary["Family tree"]
|
||||
for item in summary:
|
||||
if item != "Family tree":
|
||||
print " %s: %s" % (item, summary[item])
|
||||
sys.exit(0)
|
||||
|
||||
if self.help:
|
||||
print _help
|
||||
sys.exit(0)
|
||||
|
||||
if self.open_gui:
|
||||
# First check if a Gramps database was provided
|
||||
# (either a database path or a database name)
|
||||
db_path = self.__deduce_db_path(self.open_gui)
|
||||
|
||||
if not db_path:
|
||||
# Apparently it is not a database. See if it is a file that
|
||||
# can be imported.
|
||||
db_path, title = self.dbman.import_new_db(self.open_gui, None)
|
||||
|
||||
if db_path:
|
||||
# Test if not locked or problematic
|
||||
if not self.__check_db(db_path, self.force_unlock):
|
||||
sys.exit(0)
|
||||
# Add the file to the recent items
|
||||
path = os.path.join(db_path, "name.txt")
|
||||
try:
|
||||
ifile = open(path)
|
||||
title = ifile.readline().strip()
|
||||
ifile.close()
|
||||
except:
|
||||
title = db_path
|
||||
RecentFiles.recent_files(db_path, title)
|
||||
else:
|
||||
sys.exit(1)
|
||||
return db_path
|
||||
|
||||
if self.open:
|
||||
# Family Tree to open was given. Open it
|
||||
# Then go on and process the rest of the command line arguments.
|
||||
self.cl = bool(self.exports or self.actions)
|
||||
|
||||
filename = self.open
|
||||
|
||||
try:
|
||||
self.vm.open_activate(filename)
|
||||
print "Opened successfully!"
|
||||
except:
|
||||
print "Error opening the file."
|
||||
print "Exiting..."
|
||||
sys.exit(1)
|
||||
|
||||
if self.imports:
|
||||
self.cl = bool(self.exports or self.actions or self.cl)
|
||||
|
||||
if not self.open:
|
||||
# Create empty dir for imported database(s)
|
||||
self.imp_db_path = Utils.get_empty_tempdir("import_dbdir")
|
||||
|
||||
newdb = gen.db.GrampsDBDir()
|
||||
newdb.write_version(self.imp_db_path)
|
||||
|
||||
if not self.vm.db_loader.read_file(self.imp_db_path):
|
||||
sys.exit(0)
|
||||
|
||||
for imp in self.imports:
|
||||
print "Importing: file %s, format %s." % imp
|
||||
self.cl_import(imp[0], imp[1])
|
||||
|
||||
elif len(self.args) > 1 and not self.open:
|
||||
print "No data was given -- will launch interactive session."
|
||||
print "To use in the command-line mode,", \
|
||||
"supply at least one input file to process."
|
||||
print "Launching interactive session..."
|
||||
|
||||
if self.cl:
|
||||
for (action, options_str) in self.actions:
|
||||
print "Performing action: %s." % action
|
||||
if options_str:
|
||||
print "Using options string: %s" % options_str
|
||||
self.cl_action(action, options_str)
|
||||
|
||||
for expt in self.exports:
|
||||
print "Exporting: file %s, format %s." % expt
|
||||
self.cl_export(expt[0], expt[1])
|
||||
|
||||
print "Cleaning up."
|
||||
# remove files in import db subdir after use
|
||||
self.state.db.close()
|
||||
if self.imp_db_path:
|
||||
Utils.rm_tempdir(self.imp_db_path)
|
||||
print "Exiting."
|
||||
sys.exit(0)
|
||||
|
||||
elif Config.get(Config.RECENT_FILE) and Config.get(Config.AUTOLOAD):
|
||||
filename = Config.get(Config.RECENT_FILE)
|
||||
if os.path.isdir(filename) and \
|
||||
os.path.isfile(os.path.join(filename, "name.txt")) and \
|
||||
self.__check_db(filename):
|
||||
self.vm.db_loader.read_file(filename)
|
||||
return filename
|
||||
|
||||
def __check_db(self, dbpath, force_unlock = False):
|
||||
# Test if not locked or problematic
|
||||
if force_unlock:
|
||||
self.dbman.break_lock(dbpath)
|
||||
if self.dbman.is_locked(dbpath):
|
||||
print _("Database is locked, cannot open it!")
|
||||
print _(" Info: %s") % find_locker_name(dbpath)
|
||||
return False
|
||||
if self.dbman.needs_recovery(dbpath):
|
||||
print _("Database needs recovery, cannot open it!")
|
||||
return False
|
||||
return True
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Import handler
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def cl_import(self, filename, format):
|
||||
"""
|
||||
Command-line import routine. Try to import filename using the format.
|
||||
Any errors will cause the sys.exit(1) call.
|
||||
"""
|
||||
pmgr = PluginManager.get_instance()
|
||||
for plugin in pmgr.get_import_plugins():
|
||||
if format == plugin.get_extension():
|
||||
import_function = plugin.get_import_function()
|
||||
import_function(self.state.db, filename, None)
|
||||
|
||||
if not self.cl:
|
||||
if self.imp_db_path:
|
||||
return self.vm.open_activate(self.imp_db_path)
|
||||
else:
|
||||
return self.vm.open_activate(self.open)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Export handler
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def cl_export(self, filename, format):
|
||||
"""
|
||||
Command-line export routine.
|
||||
Try to write into filename using the format.
|
||||
Any errors will cause the sys.exit(1) call.
|
||||
"""
|
||||
pmgr = PluginManager.get_instance()
|
||||
for plugin in pmgr.get_export_plugins():
|
||||
if format == plugin.get_extension():
|
||||
export_function = plugin.get_export_function()
|
||||
export_function(self.state.db, filename)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Action handler
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def cl_action(self, action, options_str):
|
||||
"""
|
||||
Command-line action routine. Try to perform specified action.
|
||||
"""
|
||||
pmgr = PluginManager.get_instance()
|
||||
if action == 'check':
|
||||
import Check
|
||||
checker = Check.CheckIntegrity(self.state.db, None, None)
|
||||
checker.check_for_broken_family_links()
|
||||
checker.cleanup_missing_photos(1)
|
||||
checker.check_parent_relationships()
|
||||
checker.cleanup_empty_families(0)
|
||||
errs = checker.build_report(1)
|
||||
if errs:
|
||||
checker.report(1)
|
||||
elif action == 'summary':
|
||||
import Summary
|
||||
text = Summary.build_report(self.state.db, None)
|
||||
print text
|
||||
elif action == "report":
|
||||
try:
|
||||
options_str_dict = dict( [ tuple(chunk.split('='))
|
||||
for chunk in options_str.split(',') ] )
|
||||
except:
|
||||
options_str_dict = {}
|
||||
print "Ignoring invalid options string."
|
||||
|
||||
name = options_str_dict.pop('name', None)
|
||||
_cl_list = pmgr.get_cl_list()
|
||||
if name:
|
||||
for item in _cl_list:
|
||||
if name == item[0]:
|
||||
category = item[1]
|
||||
report_class = item[2]
|
||||
options_class = item[3]
|
||||
if category in (CATEGORY_BOOK, CATEGORY_CODE):
|
||||
options_class(self.state.db, name, category,
|
||||
options_str_dict)
|
||||
else:
|
||||
cl_report(self.state.db, name, category, report_class,
|
||||
options_class, options_str_dict)
|
||||
return
|
||||
# name exists, but is not in the list of valid report names
|
||||
msg = "Unknown report name."
|
||||
else:
|
||||
msg = "Report name not given. Please use -p name=reportname."
|
||||
|
||||
print "%s\n Available names are:" % msg
|
||||
for item in _cl_list:
|
||||
# Print cli report name ([item[0]) and GUI report name (item[4])
|
||||
if len(item[0]) <= 25:
|
||||
print " %s%s- %s" % (item[0],
|
||||
" " * (26 - len(item[0])), item[4])
|
||||
else:
|
||||
print " %s\t- %s" % (item[0], item[4])
|
||||
|
||||
elif action == "tool":
|
||||
try:
|
||||
options_str_dict = dict( [ tuple(chunk.split('=')) for
|
||||
chunk in options_str.split(',') ] )
|
||||
except:
|
||||
options_str_dict = {}
|
||||
print "Ignoring invalid options string."
|
||||
|
||||
name = options_str_dict.pop('name', None)
|
||||
_cli_tool_list = pmgr.get_cl_tool_list()
|
||||
if name:
|
||||
for item in _cli_tool_list:
|
||||
if name == item[0]:
|
||||
category = item[1]
|
||||
tool_class = item[2]
|
||||
options_class = item[3]
|
||||
Tool.cli_tool(self.state, name, category, tool_class,
|
||||
options_class, options_str_dict)
|
||||
return
|
||||
msg = "Unknown tool name."
|
||||
else:
|
||||
msg = "Tool name not given. Please use -p name=toolname."
|
||||
|
||||
print "%s\n Available names are:" % msg
|
||||
for item in _cli_tool_list:
|
||||
print " %s" % item[0]
|
||||
else:
|
||||
print "Unknown action: %s." % action
|
||||
sys.exit(1)
|
||||
|
||||
+3
-4
@@ -25,7 +25,7 @@
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
from gettext import gettext as _
|
||||
import os
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -170,7 +170,6 @@ class Assistant(gtk.Object, ManagedWindow.ManagedWindow):
|
||||
gtk.main_iteration()
|
||||
|
||||
def destroy(self, *obj):
|
||||
self.window.emit('delete-event', None)
|
||||
self.window.destroy()
|
||||
|
||||
def do_get_property(self, prop):
|
||||
@@ -322,10 +321,10 @@ if __name__ == "__main__":
|
||||
|
||||
a = Assistant(complete)
|
||||
a.add_text_page('Getting started',
|
||||
'Welcome to Gramps, the Genealogical Research '
|
||||
'Welcome to GRAMPS, the Genealogical Research '
|
||||
'and Analysis Management Programming System.\n'
|
||||
'Several options and information need to be gathered '
|
||||
'before Gramps is ready to be used. Any of this '
|
||||
'before GRAMPS is ready to be used. Any of this '
|
||||
'information can be changed in the future in the '
|
||||
'Preferences dialog under the Settings menu.')
|
||||
|
||||
|
||||
+24
-26
@@ -45,9 +45,8 @@ def fill_combo(combo, data_list):
|
||||
"""
|
||||
store = gtk.ListStore(gobject.TYPE_STRING)
|
||||
|
||||
for data in data_list:
|
||||
if data:
|
||||
store.append(row=[data])
|
||||
for data in [ item for item in data_list if item ]:
|
||||
store.append(row=[data])
|
||||
|
||||
combo.set_model(store)
|
||||
combo.set_text_column(0)
|
||||
@@ -61,13 +60,11 @@ def fill_entry(entry, data_list):
|
||||
"""
|
||||
Fill a entry with completion data
|
||||
"""
|
||||
|
||||
store = gtk.ListStore(gobject.TYPE_STRING)
|
||||
|
||||
for data in data_list:
|
||||
if data:
|
||||
store.append(row=[data])
|
||||
|
||||
for data in [ item for item in data_list if item ]:
|
||||
store.append(row=[data])
|
||||
|
||||
completion = gtk.EntryCompletion()
|
||||
completion.set_model(store)
|
||||
completion.set_minimum_key_length(1)
|
||||
@@ -114,14 +111,14 @@ class StandardCustomSelector(object):
|
||||
"""
|
||||
Constructor for the StandardCustomSelector class.
|
||||
|
||||
:param cbe: Existing ComboBoxEntry widget to use.
|
||||
:type cbe: gtk.ComboBoxEntry
|
||||
:param mapping: The mapping between integer and string constants.
|
||||
:type mapping: dict
|
||||
:param custom_key: The key corresponding to the custom string entry
|
||||
:type custom_key: int
|
||||
:param active_key: The key for the entry to make active upon creation
|
||||
:type active_key: int
|
||||
@param cbe: Existing ComboBoxEntry widget to use.
|
||||
@type cbe: gtk.ComboBoxEntry
|
||||
@param mapping: The mapping between integer and string constants.
|
||||
@type mapping: dict
|
||||
@param custom_key: The key corresponding to the custom string entry
|
||||
@type custom_key: int
|
||||
@param active_key: The key for the entry to make active upon creation
|
||||
@type active_key: int
|
||||
"""
|
||||
|
||||
# set variables
|
||||
@@ -158,14 +155,15 @@ class StandardCustomSelector(object):
|
||||
"""
|
||||
Fill with data
|
||||
"""
|
||||
keys = sorted(self.mapping, self.by_value)
|
||||
keys = self.mapping.keys()
|
||||
keys.sort(self.by_value)
|
||||
index = 0
|
||||
for key in keys:
|
||||
if key != self.custom_key:
|
||||
self.store.append(row=[key, self.mapping[key]])
|
||||
if key == self.active_key:
|
||||
self.active_index = index
|
||||
index += 1
|
||||
index = index + 1
|
||||
|
||||
if self.additional:
|
||||
for event_type in self.additional:
|
||||
@@ -179,7 +177,7 @@ class StandardCustomSelector(object):
|
||||
self.store.append(row=[int(event_type), str(event_type)])
|
||||
if key == self.active_key:
|
||||
self.active_index = index
|
||||
index += 1
|
||||
index = index + 1
|
||||
|
||||
def by_value(self, first, second):
|
||||
"""
|
||||
@@ -193,8 +191,8 @@ class StandardCustomSelector(object):
|
||||
"""
|
||||
Get selected values.
|
||||
|
||||
:returns: Returns (int,str) tuple corresponding to the selection.
|
||||
:rtype: tuple
|
||||
@return: Returns (int,str) tuple corresponding to the selection.
|
||||
@rtype: tuple
|
||||
"""
|
||||
active_iter = self.selector.get_active_iter()
|
||||
if active_iter:
|
||||
@@ -205,8 +203,8 @@ class StandardCustomSelector(object):
|
||||
else:
|
||||
int_val = self.custom_key
|
||||
str_val = self.selector.child.get_text().strip()
|
||||
if str_val in self.mapping.itervalues():
|
||||
for key in self.mapping:
|
||||
if str_val in self.mapping.values():
|
||||
for key in self.mapping.keys():
|
||||
if str_val == self.mapping[key]:
|
||||
int_val = key
|
||||
break
|
||||
@@ -218,11 +216,11 @@ class StandardCustomSelector(object):
|
||||
"""
|
||||
Set values according to given tuple.
|
||||
|
||||
:param val: (int,str) tuple with the values to set.
|
||||
:type val: tuple
|
||||
@param val: (int,str) tuple with the values to set.
|
||||
@type val: tuple
|
||||
"""
|
||||
key, text = val
|
||||
if key in self.mapping and key != self.custom_key:
|
||||
if key in self.mapping.keys() and key != self.custom_key:
|
||||
self.store.foreach(self.set_int_value, key)
|
||||
elif self.custom_key is not None:
|
||||
self.selector.child.set_text(text)
|
||||
|
||||
+1907
File diff suppressed because it is too large.
Load diff
@@ -1,16 +1,17 @@
|
||||
# This is the src/gen/display level Makefile for Gramps
|
||||
# This is the src/BasicUtils level Makefile for Gramps
|
||||
# We could use GNU make's ':=' syntax for nice wildcard use,
|
||||
# but that is not necessarily portable.
|
||||
# If not using GNU make, then list all .py files individually
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/gen/display
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/BasicUtils
|
||||
|
||||
pkgdata_PYTHON = \
|
||||
name.py\
|
||||
_UpdateCallback.py\
|
||||
_NameDisplay.py\
|
||||
__init__.py
|
||||
|
||||
pkgpyexecdir = @pkgpyexecdir@/gen/display
|
||||
pkgpythondir = @pkgpythondir@/gen/display
|
||||
pkgpyexecdir = @pkgpyexecdir@/BasicUtils
|
||||
pkgpythondir = @pkgpythondir@/BasicUtils
|
||||
|
||||
|
||||
dist_pkgdata_DATA =
|
||||
@@ -18,7 +19,7 @@ dist_pkgdata_DATA =
|
||||
# Clean up all the byte-compiled files
|
||||
MOSTLYCLEANFILES = *pyc *pyo
|
||||
|
||||
GRAMPS_PY_MODPATH = "../../"
|
||||
GRAMPS_PY_MODPATH = "../"
|
||||
|
||||
pycheck:
|
||||
(export PYTHONPATH=$(GRAMPS_PY_MODPATH); \
|
||||
@@ -2,7 +2,6 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2004-2007 Donald N. Allingham
|
||||
# Copyright (C) 2010 Brian G. Matherly
|
||||
#
|
||||
# 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
|
||||
@@ -30,7 +29,7 @@ Class handling language-specific displaying of names.
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import sgettext as _
|
||||
from TransUtils import sgettext as _
|
||||
import re
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -39,9 +38,10 @@ import re
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.lib import Name
|
||||
from Errors import NameDisplayError
|
||||
|
||||
try:
|
||||
import config
|
||||
import Config
|
||||
WITH_GRAMPS_CONFIG=True
|
||||
except ImportError:
|
||||
WITH_GRAMPS_CONFIG=False
|
||||
@@ -79,23 +79,7 @@ _F_RAWFN = 4 # name format raw function
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
# Because of occurring in an exec(), this couldn't be in a lambda:
|
||||
def _make_cmp(a, b): return -cmp(a[1], b[1])
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# NameDisplayError class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class NameDisplayError(Exception):
|
||||
"""
|
||||
Error used to report that the name display format string is invalid.
|
||||
"""
|
||||
def __init__(self, value):
|
||||
Exception.__init__(self)
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
def _make_cmp(a,b): return -cmp(a[1], b[1])
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -110,8 +94,13 @@ class NameDisplay(object):
|
||||
format_funcs = {}
|
||||
raw_format_funcs = {}
|
||||
|
||||
# FIXME: Is this used anywhere? I cannot see that it is.
|
||||
sort_field = (Name.get_surname, Name.get_surname,
|
||||
Name.get_first_name, Name.get_patronymic,
|
||||
Name.get_first_name)
|
||||
|
||||
STANDARD_FORMATS = [
|
||||
(Name.DEF,_("Default format (defined by Gramps preferences)"),'',_ACT),
|
||||
(Name.DEF,_("Default format (defined by GRAMPS preferences)"),'',_ACT),
|
||||
(Name.LNFN,_("Surname, Given Patronymic"),'%p %l, %f %y %s',_ACT),
|
||||
(Name.FNLN,_("Given Surname"),'%f %y %p %l %s',_ACT),
|
||||
(Name.PTFN,_("Patronymic, Given"),'%p %y, %s %f',_ACT),
|
||||
@@ -124,22 +113,22 @@ class NameDisplay(object):
|
||||
self.set_name_format(self.STANDARD_FORMATS)
|
||||
|
||||
if WITH_GRAMPS_CONFIG:
|
||||
self.default_format = config.get('preferences.name-format')
|
||||
self.default_format = Config.get(Config.NAME_FORMAT)
|
||||
if self.default_format == 0:
|
||||
self.default_format = Name.LNFN
|
||||
config.set('preferences.name-format', self.default_format)
|
||||
Config.set(Config.NAME_FORMAT,self.default_format)
|
||||
else:
|
||||
self.default_format = 1
|
||||
|
||||
self.set_default_format(self.default_format)
|
||||
|
||||
def _format_fn(self, fmt_str):
|
||||
return lambda x: self.format_str(x, fmt_str)
|
||||
def _format_fn(self,fmt_str):
|
||||
return lambda x: self.format_str(x,fmt_str)
|
||||
|
||||
def _format_raw_fn(self, fmt_str):
|
||||
return lambda x: self.format_str_raw(x, fmt_str)
|
||||
def _format_raw_fn(self,fmt_str):
|
||||
return lambda x: self.format_str_raw(x,fmt_str)
|
||||
|
||||
def _raw_lnfn(self, raw_data):
|
||||
def _raw_lnfn(self,raw_data):
|
||||
result = "%s %s, %s %s %s" % (raw_data[_PREFIX],
|
||||
raw_data[_SURNAME],
|
||||
raw_data[_FIRSTNAME],
|
||||
@@ -147,7 +136,7 @@ class NameDisplay(object):
|
||||
raw_data[_SUFFIX])
|
||||
return ' '.join(result.split())
|
||||
|
||||
def _raw_fnln(self, raw_data):
|
||||
def _raw_fnln(self,raw_data):
|
||||
result = "%s %s %s %s %s" % (raw_data[_FIRSTNAME],
|
||||
raw_data[_PATRONYM],
|
||||
raw_data[_PREFIX],
|
||||
@@ -155,18 +144,18 @@ class NameDisplay(object):
|
||||
raw_data[_SUFFIX])
|
||||
return ' '.join(result.split())
|
||||
|
||||
def _raw_ptfn(self, raw_data):
|
||||
def _raw_ptfn(self,raw_data):
|
||||
result = "%s %s, %s %s" % (raw_data[_PREFIX],
|
||||
raw_data[_PATRONYM],
|
||||
raw_data[_SUFFIX],
|
||||
raw_data[_FIRSTNAME])
|
||||
return ' '.join(result.split())
|
||||
|
||||
def _raw_fn(self, raw_data):
|
||||
def _raw_fn(self,raw_data):
|
||||
result = raw_data[_FIRSTNAME]
|
||||
return ' '.join(result.split())
|
||||
|
||||
def set_name_format(self, formats):
|
||||
def set_name_format(self,formats):
|
||||
raw_func_dict = {
|
||||
Name.LNFN : self._raw_lnfn,
|
||||
Name.FNLN : self._raw_fnln,
|
||||
@@ -174,22 +163,22 @@ class NameDisplay(object):
|
||||
Name.FN : self._raw_fn,
|
||||
}
|
||||
|
||||
for (num, name, fmt_str, act) in formats:
|
||||
for (num, name,fmt_str,act) in formats:
|
||||
func = self._format_fn(fmt_str)
|
||||
func_raw = raw_func_dict.get(num)
|
||||
if func_raw is None:
|
||||
func_raw = self._format_raw_fn(fmt_str)
|
||||
self.name_formats[num] = (name, fmt_str, act, func, func_raw)
|
||||
self.name_formats[num] = (name,fmt_str,act,func,func_raw)
|
||||
|
||||
def add_name_format(self, name, fmt_str):
|
||||
def add_name_format(self, name,fmt_str):
|
||||
num = -1
|
||||
while num in self.name_formats:
|
||||
num -= 1
|
||||
self.set_name_format([(num, name, fmt_str,_ACT)])
|
||||
self.set_name_format([(num, name,fmt_str,_ACT)])
|
||||
return num
|
||||
|
||||
def edit_name_format(self, num, name, fmt_str):
|
||||
self.set_name_format([(num, name, fmt_str,_ACT)])
|
||||
def edit_name_format(self, num, name,fmt_str):
|
||||
self.set_name_format([(num, name,fmt_str,_ACT)])
|
||||
if self.default_format == num:
|
||||
self.set_default_format(num)
|
||||
|
||||
@@ -224,7 +213,7 @@ class NameDisplay(object):
|
||||
except:
|
||||
pass
|
||||
|
||||
def get_name_format(self, also_default=False,
|
||||
def get_name_format(self,also_default=False,
|
||||
only_custom=False,
|
||||
only_active=True):
|
||||
"""
|
||||
@@ -232,7 +221,8 @@ class NameDisplay(object):
|
||||
"""
|
||||
the_list = []
|
||||
|
||||
keys = sorted(self.name_formats, self._sort_name_format)
|
||||
keys = self.name_formats.keys()
|
||||
keys.sort(self._sort_name_format)
|
||||
|
||||
for num in keys:
|
||||
if ((also_default or num) and
|
||||
@@ -242,17 +232,13 @@ class NameDisplay(object):
|
||||
|
||||
return the_list
|
||||
|
||||
def _sort_name_format(self, x, y):
|
||||
if x < 0:
|
||||
if y < 0:
|
||||
return x+y
|
||||
else:
|
||||
return -x+y
|
||||
def _sort_name_format(self,x,y):
|
||||
if x<0:
|
||||
if y<0: return x+y
|
||||
else: return -x+y
|
||||
else:
|
||||
if y < 0:
|
||||
return -x+y
|
||||
else:
|
||||
return x-y
|
||||
if y<0: return -x+y
|
||||
else: return x-y
|
||||
|
||||
def _is_format_valid(self, num):
|
||||
try:
|
||||
@@ -271,7 +257,7 @@ class NameDisplay(object):
|
||||
going to some length to optimise it as much as possible.
|
||||
|
||||
This method constructs a new function that is specifically written
|
||||
to format a name given a particular format string. This is worthwhile
|
||||
to format a name given a particualar format string. This is worthwhile
|
||||
because the format string itself rarely changes, so by caching the new
|
||||
function and calling it directly when asked to format a name to the
|
||||
same format string again we can be as quick as possible.
|
||||
@@ -314,7 +300,7 @@ class NameDisplay(object):
|
||||
going to some length to optimise it as much as possible.
|
||||
|
||||
This method constructs a new function that is specifically written
|
||||
to format a name given a particular format string. This is worthwhile
|
||||
to format a name given a particualar format string. This is worthwhile
|
||||
because the format string itself rarely changes, so by caching the new
|
||||
function and calling it directly when asked to format a name to the
|
||||
same format string again we can be as quick as possible.
|
||||
@@ -354,38 +340,39 @@ class NameDisplay(object):
|
||||
# key-word replacement. Just replace ikeywords with
|
||||
# %codes (ie, replace "irstnamefay" with "%f", and
|
||||
# "IRSTNAMEFAY" for %F)
|
||||
|
||||
if (len(format_str) > 2 and
|
||||
format_str[0] == format_str[-1] == '"'):
|
||||
format_str[0] == '"' and
|
||||
format_str[-1] == '"'):
|
||||
pass
|
||||
else:
|
||||
d_keys = [(code, _tuple[2]) for code, _tuple in d.iteritems()]
|
||||
d_keys = [(code, d[code][2]) for code in d.keys()]
|
||||
d_keys.sort(_make_cmp) # reverse sort by ikeyword
|
||||
for (code, ikeyword) in d_keys:
|
||||
exp, keyword, ikeyword = d[code]
|
||||
#ikeyword = unicode(ikeyword, "utf8")
|
||||
format_str = format_str.replace(ikeyword, "%"+ code)
|
||||
format_str = format_str.replace(ikeyword.title(), "%"+ code)
|
||||
format_str = format_str.replace(ikeyword.upper(), "%"+ code.upper())
|
||||
ikeyword = unicode(ikeyword, "utf8")
|
||||
format_str = format_str.replace(ikeyword,"%"+ code)
|
||||
format_str = format_str.replace(ikeyword.title(),"%"+ code)
|
||||
format_str = format_str.replace(ikeyword.upper(),"%"+ code.upper())
|
||||
# Next, go through and do key-word replacement.
|
||||
# Just replace keywords with
|
||||
# %codes (ie, replace "firstname" with "%f", and
|
||||
# "FIRSTNAME" for %F)
|
||||
if (len(format_str) > 2 and
|
||||
format_str[0] == format_str[-1] == '"'):
|
||||
pass
|
||||
format_str[0] == '"' and
|
||||
format_str[-1] == '"'):
|
||||
format_str = format_str[1:-1]
|
||||
else:
|
||||
d_keys = [(code, _tuple[1]) for code, _tuple in d.iteritems()]
|
||||
d_keys = [(code, d[code][1]) for code in d.keys()]
|
||||
d_keys.sort(_make_cmp) # reverse sort by keyword
|
||||
# if in double quotes, just use % codes
|
||||
for (code, keyword) in d_keys:
|
||||
exp, keyword, ikeyword = d[code]
|
||||
keyword = unicode(keyword, "utf8")
|
||||
format_str = format_str.replace(keyword, "%"+ code)
|
||||
format_str = format_str.replace(keyword.title(), "%"+ code)
|
||||
format_str = format_str.replace(keyword.upper(), "%"+ code.upper())
|
||||
format_str = format_str.replace(keyword,"%"+ code)
|
||||
format_str = format_str.replace(keyword.title(),"%"+ code)
|
||||
format_str = format_str.replace(keyword.upper(),"%"+ code.upper())
|
||||
# Get lower and upper versions of codes:
|
||||
codes = d.keys() + [c.upper() for c in d]
|
||||
codes = d.keys() + [c.upper() for c in d.keys()]
|
||||
# Next, list out the matching patterns:
|
||||
# If it starts with "!" however, treat the punctuation verbatim:
|
||||
if len(format_str) > 0 and format_str[0] == "!":
|
||||
@@ -393,14 +380,11 @@ class NameDisplay(object):
|
||||
]
|
||||
format_str = format_str[1:]
|
||||
else:
|
||||
patterns = [
|
||||
",\W*\"%(" + ("|".join(codes)) + ")\"", # ,\W*"%s"
|
||||
",\W*\(%(" + ("|".join(codes)) + ")\)", # ,\W*(%s)
|
||||
",\W*%(" + ("|".join(codes)) + ")", # ,\W*%s
|
||||
"\"%(" + ("|".join(codes)) + ")\"", # "%s"
|
||||
"\(%(" + ("|".join(codes)) + ")\)", # (%s)
|
||||
"%(" + ("|".join(codes)) + ")", # %s
|
||||
]
|
||||
patterns = [",\W*\(%(" + ("|".join(codes)) + ")\)", # ,\W*(%s)
|
||||
",\W*%(" + ("|".join(codes)) + ")", # ,\W*%s
|
||||
"\(%(" + ("|".join(codes)) + ")\)", # (%s)
|
||||
"%(" + ("|".join(codes)) + ")", # %s
|
||||
]
|
||||
new_fmt = format_str
|
||||
|
||||
# replace the specific format string flags with a
|
||||
@@ -426,8 +410,8 @@ class NameDisplay(object):
|
||||
if p == '' and s == '':
|
||||
param = param + (field,)
|
||||
else:
|
||||
param = param + ("ifNotEmpty(%s,'%s','%s')" % (field, p, s), )
|
||||
mat = pat.search(format_str, mat.end())
|
||||
param = param + ("ifNotEmpty(%s,'%s','%s')" % (field,p,s), )
|
||||
mat = pat.search(format_str,mat.end())
|
||||
s = """
|
||||
def fn(%s):
|
||||
def ifNotEmpty(str,p,s):
|
||||
@@ -440,12 +424,12 @@ def fn(%s):
|
||||
|
||||
return fn
|
||||
|
||||
def format_str(self, name, format_str):
|
||||
def format_str(self, name,format_str):
|
||||
return self._format_str_base(name.first_name, name.surname, name.prefix,
|
||||
name.suffix, name.patronymic, name.title,
|
||||
name.call,format_str)
|
||||
|
||||
def format_str_raw(self, raw_data, format_str):
|
||||
def format_str_raw(self,raw_data,format_str):
|
||||
"""
|
||||
Format a name from the raw name list. To make this as fast as possible
|
||||
this uses _gen_raw_func to generate a new method for each new format_string.
|
||||
@@ -462,8 +446,8 @@ def fn(%s):
|
||||
return ' '.join(s.split())
|
||||
|
||||
|
||||
def _format_str_base(self, first, surname, prefix, suffix, patronymic,
|
||||
title, call, format_str):
|
||||
def _format_str_base(self,first,surname,prefix,suffix,patronymic,
|
||||
title,call,format_str):
|
||||
"""
|
||||
Generates name from a format string.
|
||||
|
||||
@@ -487,7 +471,7 @@ def fn(%s):
|
||||
self.__class__.format_funcs[format_str] = func
|
||||
try:
|
||||
s = func(first,surname,prefix,suffix,patronymic,title,call)
|
||||
except (ValueError, TypeError,):
|
||||
except (ValueError,TypeError,):
|
||||
raise NameDisplayError, "Incomplete format string"
|
||||
|
||||
return ' '.join(s.split())
|
||||
@@ -497,7 +481,7 @@ def fn(%s):
|
||||
def sort_string(self, name):
|
||||
return u"%-25s%-30s%s" % (name.surname, name.first_name, name.suffix)
|
||||
|
||||
def sorted(self, person):
|
||||
def sorted(self,person):
|
||||
"""
|
||||
Return a text string representing the L{gen.lib.Person} instance's
|
||||
L{Name} in a manner that should be used for displaying a sorted
|
||||
@@ -527,7 +511,7 @@ def fn(%s):
|
||||
num = self._is_format_valid(name.sort_as)
|
||||
return self.name_formats[num][_F_FN](name)
|
||||
|
||||
def raw_sorted_name(self, raw_data):
|
||||
def raw_sorted_name(self,raw_data):
|
||||
"""
|
||||
Return a text string representing the L{Name} instance
|
||||
in a manner that should be used for displaying a sorted
|
||||
@@ -541,7 +525,7 @@ def fn(%s):
|
||||
num = self._is_format_valid(raw_data[_SORT])
|
||||
return self.name_formats[num][_F_RAWFN](raw_data)
|
||||
|
||||
def display(self, person):
|
||||
def display(self,person):
|
||||
"""
|
||||
Return a text string representing the L{gen.lib.Person} instance's
|
||||
L{Name} in a manner that should be used for normal displaying.
|
||||
@@ -556,7 +540,7 @@ def fn(%s):
|
||||
name = person.get_primary_name()
|
||||
return self.display_name(name)
|
||||
|
||||
def display_formal(self, person):
|
||||
def display_formal(self,person):
|
||||
"""
|
||||
Return a text string representing the L{gen.lib.Person} instance's
|
||||
L{Name} in a manner that should be used for normal displaying.
|
||||
@@ -588,13 +572,14 @@ def fn(%s):
|
||||
num = self._is_format_valid(name.display_as)
|
||||
return self.name_formats[num][_F_FN](name)
|
||||
|
||||
def display_given(self, person):
|
||||
def display_given(self,person):
|
||||
name = person.get_primary_name()
|
||||
return self.format_str(person.get_primary_name(),'%f %y')
|
||||
|
||||
def name_grouping(self, db, person):
|
||||
return self.name_grouping_name(db, person.primary_name)
|
||||
def name_grouping(self,db,person):
|
||||
return self.name_grouping_name(db,person.primary_name)
|
||||
|
||||
def name_grouping_name(self, db, pn):
|
||||
def name_grouping_name(self,db,pn):
|
||||
if pn.group_as:
|
||||
return pn.group_as
|
||||
sv = pn.sort_as
|
||||
@@ -602,10 +587,8 @@ def fn(%s):
|
||||
return db.get_name_group_mapping(pn.surname)
|
||||
elif sv == Name.PTFN:
|
||||
return db.get_name_group_mapping(pn.patronymic)
|
||||
elif sv == Name.FN:
|
||||
return db.get_name_group_mapping(pn.first_name)
|
||||
else:
|
||||
return db.get_name_group_mapping(pn.surname)
|
||||
return db.get_name_group_mapping(pn.first_name)
|
||||
|
||||
def name_grouping_data(self, db, pn):
|
||||
if pn[_GROUP]:
|
||||
@@ -615,9 +598,7 @@ def fn(%s):
|
||||
return db.get_name_group_mapping(pn[_SURNAME])
|
||||
elif sv == Name.PTFN:
|
||||
return db.get_name_group_mapping(pn[_PATRONYM])
|
||||
elif sv == Name.FN:
|
||||
return db.get_name_group_mapping(pn[_FIRSTNAME])
|
||||
else:
|
||||
return db.get_name_group_mapping(pn[_SURNAME])
|
||||
return db.get_name_group_mapping(pn[_FIRSTNAME])
|
||||
|
||||
displayer = NameDisplay()
|
||||
File renamed without changes.
@@ -2,7 +2,6 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2004-2007 Donald N. Allingham
|
||||
# Copyright (C) 2010 Brian G. Matherly
|
||||
#
|
||||
# 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
|
||||
@@ -21,3 +20,5 @@
|
||||
|
||||
# $Id: __init__.py$
|
||||
|
||||
from _UpdateCallback import UpdateCallback
|
||||
from _NameDisplay import displayer as name_displayer
|
||||
+39
-28
@@ -51,10 +51,11 @@ import gtk
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import GrampsDisplay
|
||||
from BasicUtils import name_displayer
|
||||
import ListModel
|
||||
import Utils
|
||||
import const
|
||||
from gen.ggettext import sgettext as _
|
||||
from TransUtils import sgettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -104,7 +105,7 @@ class Bookmarks :
|
||||
"""
|
||||
Connect the person-delete signal
|
||||
"""
|
||||
raise NotImplementedError
|
||||
self.dbstate.db.connect('person-delete', self.remove_handles)
|
||||
|
||||
def update_bookmarks(self, bookmarks):
|
||||
"""
|
||||
@@ -126,7 +127,6 @@ class Bookmarks :
|
||||
self.uistate.uimanager.remove_ui(self.active)
|
||||
self.uistate.uimanager.remove_action_group(self.action_group)
|
||||
self.action_group = gtk.ActionGroup('Bookmarks')
|
||||
self.uistate.uimanager.ensure_update()
|
||||
self.active = DISABLED
|
||||
|
||||
def redraw_and_report_change(self):
|
||||
@@ -140,12 +140,13 @@ class Bookmarks :
|
||||
text.write(TOP)
|
||||
|
||||
self.undisplay()
|
||||
|
||||
|
||||
actions = []
|
||||
count = 0
|
||||
|
||||
if len(self.bookmarks.get()) > 0:
|
||||
text.write('<placeholder name="GoToBook">')
|
||||
|
||||
for item in self.bookmarks.get():
|
||||
try:
|
||||
label, obj = self.make_label(item)
|
||||
@@ -166,10 +167,12 @@ class Bookmarks :
|
||||
text.close()
|
||||
|
||||
def make_label(self, handle):
|
||||
raise NotImplementedError
|
||||
person = self.dbstate.db.get_person_from_handle(handle)
|
||||
name = name_displayer.display(person)
|
||||
return ("%s [%s]" % (name, person.gramps_id), person)
|
||||
|
||||
def callback(self, handle):
|
||||
raise NotImplementedError
|
||||
return make_callback(handle, self.dbstate.change_active_handle)
|
||||
|
||||
def add(self, person_handle):
|
||||
"""Append the person to the bottom of the bookmarks."""
|
||||
@@ -195,7 +198,7 @@ class Bookmarks :
|
||||
|
||||
def draw_window(self):
|
||||
"""Draw the bookmark dialog box."""
|
||||
title = _("%(title)s - Gramps") % {'title': _("Organize Bookmarks")}
|
||||
title = _("%(title)s - GRAMPS") % {'title': _("Organize Bookmarks")}
|
||||
self.top = gtk.Dialog(title)
|
||||
self.top.set_default_size(400, 350)
|
||||
self.top.set_modal(True)
|
||||
@@ -278,7 +281,7 @@ class Bookmarks :
|
||||
self.namemodel.remove(the_iter)
|
||||
self.modified = True
|
||||
if row > 0:
|
||||
row -= 1
|
||||
row = row - 1
|
||||
self.namemodel.select_row(row)
|
||||
|
||||
def up_clicked(self, obj):
|
||||
@@ -323,19 +326,6 @@ class ListBookmarks(Bookmarks):
|
||||
def do_callback(self, handle):
|
||||
self.goto_handle(handle)
|
||||
|
||||
class PersonBookmarks(ListBookmarks) :
|
||||
"Handle the bookmarks interface for Gramps."
|
||||
|
||||
def __init__(self, dbstate, uistate, bookmarks, goto_handle):
|
||||
ListBookmarks.__init__(self, dbstate, uistate, bookmarks,
|
||||
goto_handle)
|
||||
|
||||
def make_label(self, handle):
|
||||
return Utils.navigation_label(self.dbstate.db, 'Person', handle)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('person-delete', self.remove_handles)
|
||||
|
||||
class FamilyBookmarks(ListBookmarks) :
|
||||
"Handle the bookmarks interface for Gramps."
|
||||
|
||||
@@ -344,7 +334,9 @@ class FamilyBookmarks(ListBookmarks) :
|
||||
goto_handle)
|
||||
|
||||
def make_label(self, handle):
|
||||
return Utils.navigation_label(self.dbstate.db, 'Family', handle)
|
||||
obj = self.dbstate.db.get_family_from_handle(handle)
|
||||
name = Utils.family_name(obj, self.dbstate.db)
|
||||
return ("%s [%s]" % (name, obj.gramps_id), obj)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('family-delete', self.remove_handles)
|
||||
@@ -357,7 +349,12 @@ class EventBookmarks(ListBookmarks) :
|
||||
goto_handle)
|
||||
|
||||
def make_label(self, handle):
|
||||
return Utils.navigation_label(self.dbstate.db, 'Event', handle)
|
||||
obj = self.dbstate.db.get_event_from_handle(handle)
|
||||
if obj.get_description() == "":
|
||||
name = str(obj.get_type())
|
||||
else:
|
||||
name = obj.get_description()
|
||||
return ("%s [%s]" % (name, obj.gramps_id), obj)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('event-delete', self.remove_handles)
|
||||
@@ -369,7 +366,9 @@ class SourceBookmarks(ListBookmarks) :
|
||||
goto_handle)
|
||||
|
||||
def make_label(self, handle):
|
||||
return Utils.navigation_label(self.dbstate.db, 'Source', handle)
|
||||
obj = self.dbstate.db.get_source_from_handle(handle)
|
||||
name = obj.get_title()
|
||||
return ("%s [%s]" % (name, obj.gramps_id), obj)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('source-delete', self.remove_handles)
|
||||
@@ -382,7 +381,9 @@ class MediaBookmarks(ListBookmarks) :
|
||||
goto_handle)
|
||||
|
||||
def make_label(self, handle):
|
||||
return Utils.navigation_label(self.dbstate.db, 'Media', handle)
|
||||
obj = self.dbstate.db.get_object_from_handle(handle)
|
||||
name = obj.get_description()
|
||||
return ("%s [%s]" % (name, obj.gramps_id), obj)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('media-delete', self.remove_handles)
|
||||
@@ -395,7 +396,9 @@ class RepoBookmarks(ListBookmarks) :
|
||||
goto_handle)
|
||||
|
||||
def make_label(self, handle):
|
||||
return Utils.navigation_label(self.dbstate.db, 'Repository', handle)
|
||||
obj = self.dbstate.db.get_repository_from_handle(handle)
|
||||
name = obj.get_name()
|
||||
return ("%s [%s]" % (name, obj.gramps_id), obj)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('repository-delete', self.remove_handles)
|
||||
@@ -408,7 +411,9 @@ class PlaceBookmarks(ListBookmarks) :
|
||||
goto_handle)
|
||||
|
||||
def make_label(self, handle):
|
||||
return Utils.navigation_label(self.dbstate.db, 'Place', handle)
|
||||
obj = self.dbstate.db.get_place_from_handle(handle)
|
||||
name = obj.get_title()
|
||||
return ("%s [%s]" % (name, obj.gramps_id), obj)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('place-delete', self.remove_handles)
|
||||
@@ -421,7 +426,13 @@ class NoteBookmarks(ListBookmarks) :
|
||||
goto_handle)
|
||||
|
||||
def make_label(self, handle):
|
||||
return Utils.navigation_label(self.dbstate.db, 'Note', handle)
|
||||
obj = self.dbstate.db.get_note_from_handle(handle)
|
||||
name = obj.get().replace('\n', ' ')
|
||||
#String must be unicode for truncation to work for non ascii characters
|
||||
name = unicode(name)
|
||||
if len(name) > 40:
|
||||
name = name[:40]+"..."
|
||||
return ("%s [%s]" % (name, obj.gramps_id), obj)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('note-delete', self.remove_handles)
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2003 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Handle the column ordering
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
import logging
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
from gtk import glade
|
||||
import gobject
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import const
|
||||
import ManagedWindow
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# set up logging
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
__LOG = logging.getLogger(".ColumnOrder")
|
||||
|
||||
|
||||
class ColumnOrder(ManagedWindow.ManagedWindow):
|
||||
"""
|
||||
Column ordering selection dialog
|
||||
"""
|
||||
|
||||
def __init__(self, win_name, uistate, arglist, column_names, callback):
|
||||
"""
|
||||
Create the Column Ordering dialog
|
||||
"""
|
||||
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self)
|
||||
|
||||
self.glade = glade.XML(const.GLADE_FILE, "columns", "gramps")
|
||||
|
||||
self.set_window(self.glade.get_widget('columns'), None, win_name)
|
||||
|
||||
self.tree = self.glade.get_widget('list')
|
||||
self.arglist = arglist
|
||||
self.callback = callback
|
||||
|
||||
self.model = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING,
|
||||
gobject.TYPE_INT, object)
|
||||
|
||||
self.tree.set_model(self.model)
|
||||
|
||||
checkbox = gtk.CellRendererToggle()
|
||||
checkbox.connect('toggled', toggled, self.model)
|
||||
renderer = gtk.CellRendererText()
|
||||
|
||||
column_n = gtk.TreeViewColumn(_('Display'), checkbox, active=0)
|
||||
column_n.set_min_width(50)
|
||||
self.tree.append_column(column_n)
|
||||
|
||||
column_n = gtk.TreeViewColumn(_('Column Name'), renderer, text=1)
|
||||
column_n.set_min_width(225)
|
||||
self.tree.append_column(column_n)
|
||||
|
||||
self.glade.get_widget('okbutton').connect('clicked',
|
||||
self.ok_clicked)
|
||||
self.glade.get_widget('cancelbutton').connect('clicked',
|
||||
self.cancel_clicked)
|
||||
|
||||
for item in self.arglist:
|
||||
node = self.model.append()
|
||||
self.model.set(node,
|
||||
0, item[0],
|
||||
1, column_names[item[1]],
|
||||
2, item[1],
|
||||
3, item)
|
||||
|
||||
def build_menu_names(self, obj):
|
||||
"""
|
||||
Build the information for the Managed Window menu entries
|
||||
"""
|
||||
return (_('Column Editor'), _('Column Editor'))
|
||||
|
||||
def ok_clicked(self, obj):
|
||||
"""
|
||||
called with the OK button is pressed
|
||||
"""
|
||||
newlist = []
|
||||
for i in range(0, len(self.arglist)):
|
||||
node = self.model.get_iter((int(i), ))
|
||||
enable = self.model.get_value(node, 0)
|
||||
index = self.model.get_value(node, 2)
|
||||
value = self.model.get_value(node, 3)
|
||||
newlist.append((enable, index, value[2]))
|
||||
|
||||
self.callback(newlist)
|
||||
self.close()
|
||||
|
||||
def cancel_clicked(self, obj):
|
||||
"""
|
||||
Called with the Cancel button is pressed.
|
||||
"""
|
||||
self.close()
|
||||
|
||||
def toggled(cell, path, model):
|
||||
"""
|
||||
Called when the cell information is changed, updating the
|
||||
data model so the that change occurs.
|
||||
"""
|
||||
node = model.get_iter((int(path), ))
|
||||
value = not model.get_value(node, 0)
|
||||
model.set(node, 0, value)
|
||||
@@ -1,23 +1,22 @@
|
||||
# This is the src/gen/mime level Makefile for Gramps
|
||||
# This is the src/Config level Makefile for Gramps
|
||||
# We could use GNU make's ':=' syntax for nice wildcard use,
|
||||
# but that is not necessarily portable.
|
||||
# If not using GNU make, then list all .py files individually
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/gen/mime
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/Config
|
||||
|
||||
pkgdata_PYTHON = \
|
||||
__init__.py\
|
||||
_gnomemime.py\
|
||||
_winmime.py\
|
||||
_pythonmime.py
|
||||
_GrampsConfigKeys.py\
|
||||
_GrampsIniKeys.py
|
||||
|
||||
pkgpyexecdir = @pkgpyexecdir@/gen/mime
|
||||
pkgpythondir = @pkgpythondir@/gen/mime
|
||||
pkgpyexecdir = @pkgpyexecdir@/Config
|
||||
pkgpythondir = @pkgpythondir@/Config
|
||||
|
||||
# Clean up all the byte-compiled files
|
||||
MOSTLYCLEANFILES = *pyc *pyo
|
||||
|
||||
GRAMPS_PY_MODPATH = "../../"
|
||||
GRAMPS_PY_MODPATH = "../"
|
||||
|
||||
pycheck:
|
||||
(export PYTHONPATH=$(GRAMPS_PY_MODPATH); \
|
||||
@@ -0,0 +1,365 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2006-2007 Donald N. Allingham
|
||||
# Copyright (C) 2008-2009 Gary Burton
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
import os
|
||||
from gettext import gettext as _
|
||||
|
||||
import const
|
||||
|
||||
"""
|
||||
Adding a new configuration key:
|
||||
|
||||
Add a value in the form of:
|
||||
|
||||
VARIABLE = ( category, key_name, type)
|
||||
|
||||
Where:
|
||||
|
||||
cateogory is a single word string defining the grouping along
|
||||
with related keys
|
||||
|
||||
key_name is a single word string defining the actual configuration
|
||||
name
|
||||
|
||||
type is an integer defining the type of the value of the
|
||||
configuration value.
|
||||
|
||||
0 - boolean
|
||||
1 - integer
|
||||
2 - string
|
||||
|
||||
Then add the variable to the default_value map at the end of the
|
||||
file, and provide a default value according to the value's type.
|
||||
"""
|
||||
|
||||
EXPORT_NO_PRIVATE = ('export', 'no-private', 0)
|
||||
EXPORT_RESTRICT = ('export', 'restrict-living', 0)
|
||||
EXPORT_NO_UNLINKED = ('export', 'no-unlinked', 0)
|
||||
DEFAULT_SOURCE = ('preferences', 'default-source', 0)
|
||||
RELATION_SHADE = ('preferences', 'relation-shade', 0)
|
||||
ONLINE_MAPS = ('preferences', 'online-maps', 0)
|
||||
FAMILY_DETAILS = ('preferences', 'family-details', 0)
|
||||
COMPLETE_COLOR = ('preferences', 'complete-color', 2)
|
||||
TODO_COLOR = ('preferences', 'todo-color', 2)
|
||||
CUSTOM_MARKER_COLOR = ('preferences', 'custom-marker-color', 2)
|
||||
FAMILY_WARN = ('preferences', 'family-warn', 0)
|
||||
HIDE_EP_MSG = ('preferences', 'hide-ep-msg', 0)
|
||||
LAST_VIEW = ('preferences', 'last-view', 1)
|
||||
USE_LAST_VIEW = ('preferences', 'use-last-view', 0)
|
||||
FAMILY_SIBLINGS = ('preferences', 'family-siblings', 0)
|
||||
AUTOLOAD = ('behavior', 'autoload', 0)
|
||||
SPELLCHECK = ('behavior', 'spellcheck', 0)
|
||||
BETAWARN = ('behavior', 'betawarn', 0)
|
||||
WELCOME = ('behavior', 'welcome', 1)
|
||||
DATE_FORMAT = ('preferences', 'date-format', 1)
|
||||
DONT_ASK = ('interface', 'dont-ask', 0)
|
||||
RELEDITBTN = ('interface', 'releditbtn', 0)
|
||||
HEIGHT = ('interface', 'height', 1)
|
||||
WIDTH = ('interface', 'width', 1)
|
||||
FAMILY_HEIGHT = ('interface', 'family-height', 1)
|
||||
FAMILY_WIDTH = ('interface', 'family-width', 1)
|
||||
NOTE_HEIGHT = ('interface', 'note-height', 1)
|
||||
NOTE_WIDTH = ('interface', 'note-width', 1)
|
||||
PERSON_HEIGHT = ('interface', 'person-height', 1)
|
||||
PERSON_WIDTH = ('interface', 'person-width', 1)
|
||||
PREFIX_SUFFIX = ('interface', 'prefix-suffix', 1)
|
||||
PATRO_TITLE = ('interface', 'patro-title', 1)
|
||||
EVENT_HEIGHT = ('interface', 'event-height', 1)
|
||||
EVENT_WIDTH = ('interface', 'event-width', 1)
|
||||
EVENT_REF_HEIGHT = ('interface', 'event-ref-height', 1)
|
||||
EVENT_REF_WIDTH = ('interface', 'event-ref-width', 1)
|
||||
CHILD_REF_HEIGHT = ('interface', 'child-ref-height', 1)
|
||||
CHILD_REF_WIDTH = ('interface', 'child-ref-width', 1)
|
||||
PLACE_HEIGHT = ('interface', 'place-height', 1)
|
||||
PLACE_WIDTH = ('interface', 'place-width', 1)
|
||||
REPO_HEIGHT = ('interface', 'repo-height', 1)
|
||||
REPO_WIDTH = ('interface', 'repo-width', 1)
|
||||
MEDIA_HEIGHT = ('interface', 'media-height', 1)
|
||||
MEDIA_WIDTH = ('interface', 'media-width', 1)
|
||||
ADDRESS_HEIGHT = ('interface', 'address-height', 1)
|
||||
ADDRESS_WIDTH = ('interface', 'address-width', 1)
|
||||
ATTRIBUTE_HEIGHT = ('interface', 'attribute-height', 1)
|
||||
ATTRIBUTE_WIDTH = ('interface', 'attribute-width', 1)
|
||||
NAME_HEIGHT = ('interface', 'name-height', 1)
|
||||
NAME_WIDTH = ('interface', 'name-width', 1)
|
||||
SOURCE_HEIGHT = ('interface', 'source-height', 1)
|
||||
SOURCE_WIDTH = ('interface', 'source-width', 1)
|
||||
SOURCE_REF_HEIGHT = ('interface', 'source-ref-height', 1)
|
||||
SOURCE_REF_WIDTH = ('interface', 'source-ref-width', 1)
|
||||
SOURCE_SEL_WIDTH = ('interface', 'source-sel-width', 1)
|
||||
SOURCE_SEL_HEIGHT = ('interface', 'source-sel-height', 1)
|
||||
EVENT_SEL_WIDTH = ('interface', 'event-sel-width', 1)
|
||||
EVENT_SEL_HEIGHT = ('interface', 'event-sel-height', 1)
|
||||
FAMILY_SEL_WIDTH = ('interface', 'family-sel-width', 1)
|
||||
FAMILY_SEL_HEIGHT = ('interface', 'family-sel-height', 1)
|
||||
NOTE_SEL_WIDTH = ('interface', 'note-sel-width', 1)
|
||||
NOTE_SEL_HEIGHT = ('interface', 'note-sel-height', 1)
|
||||
REPO_SEL_WIDTH = ('interface', 'repo-sel-width', 1)
|
||||
REPO_SEL_HEIGHT = ('interface', 'repo-sel-height', 1)
|
||||
PLACE_SEL_WIDTH = ('interface', 'place-sel-width', 1)
|
||||
PLACE_SEL_HEIGHT = ('interface', 'place-sel-height', 1)
|
||||
PERSON_SEL_WIDTH = ('interface', 'person-sel-width', 1)
|
||||
PERSON_SEL_HEIGHT = ('interface', 'person-sel-height', 1)
|
||||
MEDIA_SEL_WIDTH = ('interface', 'media-sel-width', 1)
|
||||
MEDIA_SEL_HEIGHT = ('interface', 'media-sel-height', 1)
|
||||
FILTER = ('interface', 'filter', 0)
|
||||
PEDVIEW_TREESIZE = ('interface', 'pedview-tree-size', 1)
|
||||
PEDVIEW_LAYOUT = ('interface', 'pedview-layout', 1)
|
||||
PEDVIEW_SHOW_MARRIAGE= ('interface', 'pedview-show-marriage', 0)
|
||||
PEDVIEW_SHOW_IMAGES = ('interface', 'pedview-show-images', 0)
|
||||
CLIPBOARD_WIDTH = ('interface', 'clipboard-width', 1)
|
||||
CLIPBOARD_HEIGHT = ('interface', 'clipboard-height', 1)
|
||||
DATABASE_PATH = ('behavior', 'database-path', 2)
|
||||
FPREFIX = ('preferences', 'fprefix', 2)
|
||||
EPREFIX = ('preferences', 'eprefix', 2)
|
||||
RPREFIX = ('preferences', 'rprefix', 2)
|
||||
NPREFIX = ('preferences', 'nprefix', 2)
|
||||
IPREFIX = ('preferences', 'iprefix', 2)
|
||||
OPREFIX = ('preferences', 'oprefix', 2)
|
||||
PPREFIX = ('preferences', 'pprefix', 2)
|
||||
SPREFIX = ('preferences', 'sprefix', 2)
|
||||
GOUTPUT_PREFERENCE = ('preferences', 'goutput-preference', 2)
|
||||
OUTPUT_PREFERENCE = ('preferences', 'output-preference', 2)
|
||||
PAPER_METRIC = ('preferences', 'paper-metric', 1)
|
||||
PAPER_PREFERENCE = ('preferences', 'paper-preference', 2)
|
||||
RECENT_FILE = ('paths', 'recent-file', 2)
|
||||
RECENT_IMPORT_DIR = ('paths', 'recent-import-dir', 2)
|
||||
RECENT_EXPORT_DIR = ('paths', 'recent-export-dir', 2)
|
||||
RECENT_EXPORT_TYPE = ('behavior', 'recent-export-type', 1)
|
||||
NAME_FORMAT = ('preferences', 'name-format', 1)
|
||||
REPORT_DIRECTORY = ('paths', 'report-directory', 2)
|
||||
RESEARCHER_ADDR = ('researcher', 'researcher-addr', 2)
|
||||
RESEARCHER_CITY = ('researcher', 'researcher-city', 2)
|
||||
RESEARCHER_COUNTRY = ('researcher', 'researcher-country', 2)
|
||||
RESEARCHER_EMAIL = ('researcher', 'researcher-email', 2)
|
||||
RESEARCHER_NAME = ('researcher', 'researcher-name', 2)
|
||||
RESEARCHER_PHONE = ('researcher', 'researcher-phone', 2)
|
||||
RESEARCHER_POSTAL = ('researcher', 'researcher-postal', 2)
|
||||
RESEARCHER_STATE = ('researcher', 'researcher-state', 2)
|
||||
STARTUP = ('behavior', 'startup', 1)
|
||||
SIZE_CHECKED = ('interface', 'size-checked', 0)
|
||||
STATUSBAR = ('interface', 'statusbar', 1)
|
||||
SURNAME_GUESSING = ('behavior', 'surname-guessing', 1)
|
||||
TOOLBAR_ON = ('interface', 'toolbar-on', 0)
|
||||
USE_TIPS = ('behavior', 'use-tips', 0)
|
||||
POP_PLUGIN_STATUS = ('behavior', 'pop-plugin-status', 0)
|
||||
VIEW = ('interface', 'view', 0)
|
||||
SIDEBAR_TEXT = ('interface', 'sidebar-text', 0)
|
||||
WEBSITE_DIRECTORY = ('paths', 'website-directory', 2)
|
||||
LDS_HEIGHT = ('interface', 'lds-height', 1)
|
||||
LDS_WIDTH = ('interface', 'lds-width', 1)
|
||||
LOCATION_HEIGHT = ('interface', 'location-height', 1)
|
||||
LOCATION_WIDTH = ('interface', 'location-width', 1)
|
||||
MAPSERVICE = ('interface', 'mapservice', 2)
|
||||
MEDIA_REF_HEIGHT = ('interface', 'media-ref-height', 1)
|
||||
MEDIA_REF_WIDTH = ('interface', 'media-ref-width', 1)
|
||||
URL_HEIGHT = ('interface', 'url-height', 1)
|
||||
URL_WIDTH = ('interface', 'url-width', 1)
|
||||
PERSON_REF_HEIGHT = ('interface', 'person-ref-height', 1)
|
||||
PERSON_REF_WIDTH = ('interface', 'person-ref-width', 1)
|
||||
REPO_REF_HEIGHT = ('interface', 'repo-ref-height', 1)
|
||||
REPO_REF_WIDTH = ('interface', 'repo-ref-width', 1)
|
||||
OWNER_WARN = ('behavior', 'owner-warn', 0)
|
||||
DATE_BEFORE_RANGE = ('behavior', 'date-before-range', 1)
|
||||
DATE_AFTER_RANGE = ('behavior', 'date-after-range', 1)
|
||||
DATE_ABOUT_RANGE = ('behavior', 'date-about-range', 1)
|
||||
MAX_AGE_PROB_ALIVE = ('behavior', 'max-age-prob-alive', 1)
|
||||
MAX_SIB_AGE_DIFF = ('behavior', 'max-sib-age-diff', 1)
|
||||
MIN_GENERATION_YEARS = ('behavior', 'min-generation-years', 1)
|
||||
AVG_GENERATION_GAP = ('behavior', 'avg-generation-gap', 1)
|
||||
GENERATION_DEPTH = ('behavior', 'generation-depth', 1)
|
||||
DATA_VIEWS = ('interface','data-views', 2)
|
||||
ADDMEDIA_IMGDIR = ('behavior', 'addmedia-image-dir', 2)
|
||||
ADDMEDIA_RELPATH = ('behavior', 'addmedia-relative-path', 0)
|
||||
NO_SURNAME_TEXT = ('preferences', 'no-surname-text', 2)
|
||||
NO_GIVEN_TEXT = ('preferences', 'no-given-text', 2)
|
||||
NO_RECORD_TEXT = ('preferences', 'no-record-text', 2)
|
||||
PRIVATE_SURNAME_TEXT = ('preferences', 'private-surname-text', 2)
|
||||
PRIVATE_GIVEN_TEXT = ('preferences', 'private-given-text', 2)
|
||||
PRIVATE_RECORD_TEXT = ('preferences', 'private-record-text', 2)
|
||||
RELATION_DISPLAY_THEME= ('preferences', 'relation-display-theme', 2)
|
||||
INVALID_DATE_FORMAT = ('preferences', 'invalid-date-format', 2)
|
||||
FULLSCREEN = ('interface', 'fullscreen', 0)
|
||||
GEOVIEW = ('preferences', 'geoview', 0)
|
||||
GEOVIEW_GOOGLEMAPS = ('preferences', 'googlemap', 0)
|
||||
GEOVIEW_OPENLAYERS = ('preferences', 'openlayers', 0)
|
||||
GEOVIEW_YAHOO = ('preferences', 'yahoo', 0)
|
||||
GEOVIEW_MICROSOFT = ('preferences', 'microsoft', 0)
|
||||
|
||||
default_value = {
|
||||
DEFAULT_SOURCE : False,
|
||||
RELATION_SHADE : True,
|
||||
ONLINE_MAPS : False,
|
||||
FAMILY_DETAILS : True,
|
||||
COMPLETE_COLOR : '#008b00',
|
||||
TODO_COLOR : '#ff0000',
|
||||
CUSTOM_MARKER_COLOR : '#8b008b',
|
||||
FAMILY_WARN : True,
|
||||
HIDE_EP_MSG : False,
|
||||
LAST_VIEW : 0,
|
||||
USE_LAST_VIEW : True,
|
||||
FAMILY_SIBLINGS : True,
|
||||
AUTOLOAD : False,
|
||||
SPELLCHECK : False,
|
||||
BETAWARN : False,
|
||||
WELCOME : 100,
|
||||
DATE_FORMAT : 0,
|
||||
DONT_ASK : False,
|
||||
RELEDITBTN : False,
|
||||
HEIGHT : 500,
|
||||
WIDTH : 775,
|
||||
FAMILY_HEIGHT : 500,
|
||||
FAMILY_WIDTH : 700,
|
||||
NOTE_HEIGHT : 500,
|
||||
NOTE_WIDTH : 700,
|
||||
PERSON_HEIGHT : 550,
|
||||
PERSON_WIDTH : 750,
|
||||
PREFIX_SUFFIX : 0,
|
||||
PATRO_TITLE : 0,
|
||||
EVENT_HEIGHT : 450,
|
||||
EVENT_WIDTH : 600,
|
||||
EVENT_REF_HEIGHT : 450,
|
||||
EVENT_REF_WIDTH : 600,
|
||||
CHILD_REF_HEIGHT : 450,
|
||||
CHILD_REF_WIDTH : 600,
|
||||
PLACE_HEIGHT : 450,
|
||||
PLACE_WIDTH : 650,
|
||||
REPO_HEIGHT : 450,
|
||||
REPO_WIDTH : 650,
|
||||
MEDIA_HEIGHT : 450,
|
||||
MEDIA_WIDTH : 650,
|
||||
ADDRESS_HEIGHT : 450,
|
||||
ADDRESS_WIDTH : 650,
|
||||
ATTRIBUTE_HEIGHT : 350,
|
||||
ATTRIBUTE_WIDTH : 600,
|
||||
NAME_HEIGHT : 350,
|
||||
NAME_WIDTH : 600,
|
||||
SOURCE_HEIGHT : 450,
|
||||
SOURCE_WIDTH : 600,
|
||||
SOURCE_REF_HEIGHT : 450,
|
||||
SOURCE_REF_WIDTH : 600,
|
||||
SOURCE_SEL_WIDTH : 600,
|
||||
SOURCE_SEL_HEIGHT : 450,
|
||||
EVENT_SEL_WIDTH : 600,
|
||||
EVENT_SEL_HEIGHT : 450,
|
||||
FAMILY_SEL_WIDTH : 600,
|
||||
FAMILY_SEL_HEIGHT : 450,
|
||||
NOTE_SEL_WIDTH : 600,
|
||||
NOTE_SEL_HEIGHT : 450,
|
||||
REPO_SEL_WIDTH : 600,
|
||||
REPO_SEL_HEIGHT : 450,
|
||||
PLACE_SEL_WIDTH : 600,
|
||||
PLACE_SEL_HEIGHT : 450,
|
||||
PERSON_SEL_WIDTH : 600,
|
||||
PERSON_SEL_HEIGHT : 450,
|
||||
MEDIA_SEL_WIDTH : 600,
|
||||
MEDIA_SEL_HEIGHT : 450,
|
||||
CLIPBOARD_WIDTH : 300,
|
||||
CLIPBOARD_HEIGHT : 300,
|
||||
FILTER : False,
|
||||
PEDVIEW_TREESIZE : 0,
|
||||
PEDVIEW_LAYOUT : 0,
|
||||
PEDVIEW_SHOW_MARRIAGE: False,
|
||||
PEDVIEW_SHOW_IMAGES : True,
|
||||
DATABASE_PATH : os.path.join( const.HOME_DIR, 'grampsdb'),
|
||||
FPREFIX : 'F%04d',
|
||||
EPREFIX : 'E%04d',
|
||||
RPREFIX : 'R%04d',
|
||||
NPREFIX : 'N%04d',
|
||||
IPREFIX : 'I%04d',
|
||||
OPREFIX : 'O%04d',
|
||||
PPREFIX : 'P%04d',
|
||||
SPREFIX : 'S%04d',
|
||||
GOUTPUT_PREFERENCE : 'No default format',
|
||||
OUTPUT_PREFERENCE : 'No default format',
|
||||
PAPER_METRIC : 0,
|
||||
PAPER_PREFERENCE : 'Letter',
|
||||
RECENT_FILE : '',
|
||||
RECENT_IMPORT_DIR : '',
|
||||
RECENT_EXPORT_DIR : '',
|
||||
RECENT_EXPORT_TYPE : 1,
|
||||
NAME_FORMAT : 1,
|
||||
REPORT_DIRECTORY : const.USER_HOME,
|
||||
RESEARCHER_ADDR : '',
|
||||
RESEARCHER_CITY : '',
|
||||
RESEARCHER_COUNTRY : '',
|
||||
RESEARCHER_EMAIL : '',
|
||||
RESEARCHER_NAME : '',
|
||||
RESEARCHER_PHONE : '',
|
||||
RESEARCHER_POSTAL : '',
|
||||
RESEARCHER_STATE : '',
|
||||
STARTUP : 0,
|
||||
SIZE_CHECKED : False,
|
||||
STATUSBAR : 1,
|
||||
SURNAME_GUESSING : 0,
|
||||
TOOLBAR_ON : True,
|
||||
USE_TIPS : False,
|
||||
POP_PLUGIN_STATUS : False,
|
||||
VIEW : True,
|
||||
SIDEBAR_TEXT : True,
|
||||
WEBSITE_DIRECTORY : const.USER_HOME,
|
||||
LDS_HEIGHT : 450,
|
||||
LDS_WIDTH : 600,
|
||||
LOCATION_HEIGHT : 250,
|
||||
LOCATION_WIDTH : 600,
|
||||
MAPSERVICE : 'OpenStreetMap',
|
||||
MEDIA_REF_HEIGHT : 450,
|
||||
MEDIA_REF_WIDTH : 600,
|
||||
URL_HEIGHT : 150,
|
||||
URL_WIDTH : 600,
|
||||
PERSON_REF_HEIGHT : 350,
|
||||
PERSON_REF_WIDTH : 600,
|
||||
REPO_REF_HEIGHT : 450,
|
||||
REPO_REF_WIDTH : 600,
|
||||
OWNER_WARN : False,
|
||||
EXPORT_NO_PRIVATE : True,
|
||||
EXPORT_RESTRICT : True,
|
||||
EXPORT_NO_UNLINKED : True,
|
||||
DATE_BEFORE_RANGE : 10,
|
||||
DATE_AFTER_RANGE : 10,
|
||||
DATE_ABOUT_RANGE : 10,
|
||||
MAX_AGE_PROB_ALIVE : 110,
|
||||
MAX_SIB_AGE_DIFF : 20,
|
||||
MIN_GENERATION_YEARS : 13,
|
||||
AVG_GENERATION_GAP : 20,
|
||||
GENERATION_DEPTH : 15,
|
||||
DATA_VIEWS: ('GrampletView,PersonView,RelationshipView,FamilyListView,'
|
||||
'PedigreeView,EventView,SourceView,PlaceView,MediaView,'
|
||||
'RepositoryView,NoteView'),
|
||||
ADDMEDIA_IMGDIR : '',
|
||||
ADDMEDIA_RELPATH : False,
|
||||
NO_SURNAME_TEXT : "[%s]" % _("Missing Surname"),
|
||||
NO_GIVEN_TEXT : "[%s]" % _("Missing Given Name"),
|
||||
NO_RECORD_TEXT : "[%s]" % _("Missing Record"),
|
||||
PRIVATE_SURNAME_TEXT : "[%s]" % _("Living"),
|
||||
PRIVATE_GIVEN_TEXT : "[%s]" % _("Living"),
|
||||
PRIVATE_RECORD_TEXT : "[%s]" % _("Private Record"),
|
||||
RELATION_DISPLAY_THEME: "CLASSIC",
|
||||
INVALID_DATE_FORMAT : "<b>%s</b>",
|
||||
FULLSCREEN : False,
|
||||
GEOVIEW : False,
|
||||
GEOVIEW_GOOGLEMAPS : True,
|
||||
GEOVIEW_OPENLAYERS : False,
|
||||
GEOVIEW_YAHOO : False,
|
||||
GEOVIEW_MICROSOFT : False,
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2005-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Low-level handling of .ini keys.
|
||||
"""
|
||||
import os
|
||||
import time
|
||||
import ConfigParser
|
||||
import errno
|
||||
import const
|
||||
from Config import DATE_FORMAT, NAME_FORMAT, default_value
|
||||
|
||||
NL = "\n" # FIX: newlines on Mac/Windows, if different?
|
||||
|
||||
INIFILE = os.path.join(const.HOME_DIR,"keys.ini")
|
||||
|
||||
def make_bool(val):
|
||||
""" Function to turn strings into booleans. """
|
||||
# these are the possible strings that should be considered False
|
||||
if val.lower() in ["0", "false", "none", ""]:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
class IniKeyClient(object):
|
||||
""" Class to emulate gconf's client """
|
||||
def __init__(self, filename = None):
|
||||
""" Constructor takes an optional filename """
|
||||
self.data = {}
|
||||
self.callbacks = {}
|
||||
self.filename = filename
|
||||
if self.filename and os.path.exists(filename):
|
||||
self.data = self.load_ini(self.filename)
|
||||
|
||||
def notify_add(self, path, func):
|
||||
"""
|
||||
I think that these are callbacks that get called when the keys
|
||||
are set.
|
||||
"""
|
||||
parts = path.split("/") # FIX: make path-sep independent
|
||||
# /apps/gramps/section/key
|
||||
section = parts[-2]
|
||||
key = parts[-1]
|
||||
if section not in self.callbacks:
|
||||
self.callbacks[section] = {}
|
||||
if key not in self.callbacks[section]:
|
||||
self.callbacks[section][key] = []
|
||||
if func not in self.callbacks[section][key]:
|
||||
self.callbacks[section][key].append(func)
|
||||
|
||||
def load_ini(self, filename):
|
||||
""" Load .ini into dict of dicts, which it returns """
|
||||
cp = ConfigParser.ConfigParser()
|
||||
cp.read(filename)
|
||||
data = {}
|
||||
for sec in cp.sections():
|
||||
name = sec.lower()
|
||||
if name not in data:
|
||||
data[name] = {}
|
||||
for opt in cp.options(sec):
|
||||
data[name][opt.lower()] = cp.get(sec, opt).strip()
|
||||
return data
|
||||
|
||||
def save_ini(self, filename = None):
|
||||
"""
|
||||
Saves the current section/keys to a .ini file. Optional filename
|
||||
will override the default filename, if one.
|
||||
"""
|
||||
if not filename:
|
||||
filename = self.filename
|
||||
if filename:
|
||||
try:
|
||||
head, tail = os.path.split( filename )
|
||||
os.makedirs( head )
|
||||
except OSError, e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
fp = open(filename, "w")
|
||||
fp.write(";; Gramps key file" + NL)
|
||||
fp.write((";; Automatically created at %s" % time.strftime("%Y/%m/%d %H:%M:%S")) + NL + NL)
|
||||
sections = self.data.keys()
|
||||
sections.sort()
|
||||
for section in sections:
|
||||
fp.write(("[%s]" + NL) % section)
|
||||
keys = self.data[section].keys()
|
||||
keys.sort()
|
||||
for key in keys:
|
||||
fp.write(("%s=%s" + NL)% (key, self.data[section][key]))
|
||||
fp.write(NL)
|
||||
fp.close()
|
||||
# else, no filename given
|
||||
|
||||
def get_bool(self, key):
|
||||
""" Emulates gconf's client method """
|
||||
return make_bool(self.data[key[0]][key[1]])
|
||||
|
||||
def get_string(self, key):
|
||||
""" Emulates gconf's client method """
|
||||
return self.data[key[0]][key[1]]
|
||||
|
||||
def get_int(self, key):
|
||||
""" Emulates gconf's client method """
|
||||
try:
|
||||
val = int(self.data[key[0]][key[1]])
|
||||
return val
|
||||
except ValueError:
|
||||
if self.data[key[0]][key[1]].lower() in ["true"]:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def set_bool(self, key, val):
|
||||
""" Emulates gconf's client method """
|
||||
if key[0] not in self.data:
|
||||
self.data[key[0]] = {}
|
||||
self.data[key[0]][key[1]] = str(val)
|
||||
if key[0] in self.callbacks and key[1] in self.callbacks[key[0]]:
|
||||
for func in self.callbacks[key[0]][key[1]]:
|
||||
func(self,0,self.data[key[0]][key[1]],None)
|
||||
|
||||
def set_string(self, key, val):
|
||||
""" Emulates gconf's client method """
|
||||
if key[0] not in self.data:
|
||||
self.data[key[0]] = {}
|
||||
self.data[key[0]][key[1]] = val
|
||||
if key[0] in self.callbacks and key[1] in self.callbacks[key[0]]:
|
||||
for func in self.callbacks[key[0]][key[1]]:
|
||||
func(self,0,self.data[key[0]][key[1]],None)
|
||||
|
||||
def set_int(self, key, val):
|
||||
""" Emulates gconf's client method """
|
||||
if key[0] not in self.data:
|
||||
self.data[key[0]] = {}
|
||||
self.data[key[0]][key[1]] = str(val)
|
||||
if key[0] in self.callbacks and key[1] in self.callbacks[key[0]]:
|
||||
for func in self.callbacks[key[0]][key[1]]:
|
||||
func(self,0,self.data[key[0]][key[1]],None)
|
||||
|
||||
def suggest_sync(self):
|
||||
self.save_ini() # save back to default file, if named
|
||||
|
||||
client = IniKeyClient(INIFILE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Functions to obtain values from .ini keys
|
||||
# and store values into .ini keys
|
||||
#
|
||||
# All gramps keys should be accessed through these functions!
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
|
||||
def get_date_format(_date_format_list=[]):
|
||||
return get_int(DATE_FORMAT,
|
||||
range(len(_date_format_list)))
|
||||
|
||||
def save_date_format(val,_date_format_list=[]):
|
||||
set_int(DATE_FORMAT, val,
|
||||
range(len(_date_format_list)))
|
||||
|
||||
def get_name_format(_name_format_list):
|
||||
return get_int(NAME_FORMAT,
|
||||
range(len(_name_format_list)))
|
||||
|
||||
def save_name_format(val,_name_format_list):
|
||||
set_int(NAME_FORMAT, val,
|
||||
range(len(_name_format_list)))
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Low-level grabbing and saving keys with error checking.
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
def set(key, value):
|
||||
if key[2] == 0:
|
||||
set_bool(key, value)
|
||||
elif key[2] == 1:
|
||||
set_int(key, value)
|
||||
else:
|
||||
set_string(key, value)
|
||||
|
||||
def get(key):
|
||||
if key[2] == 0:
|
||||
val = get_bool(key)
|
||||
elif key[2] == 1:
|
||||
val = get_int(key)
|
||||
else:
|
||||
val = get_string(key)
|
||||
if val is None or val == "":
|
||||
val = default_value[key]
|
||||
return val
|
||||
|
||||
def get_bool(key):
|
||||
try:
|
||||
val = client.get_bool(key)
|
||||
except KeyError:
|
||||
val = None
|
||||
if val in (True, False):
|
||||
return val
|
||||
elif key in default_value:
|
||||
return default_value[key]
|
||||
else:
|
||||
print "No default value for %s" % key
|
||||
return False
|
||||
|
||||
def set_bool(key, val):
|
||||
if val in (True,False):
|
||||
client.set_bool(key,val)
|
||||
|
||||
def get_int(key, correct_tuple=None):
|
||||
try:
|
||||
return client.get_int(key)
|
||||
except KeyError:
|
||||
return default_value[key]
|
||||
|
||||
def set_int(key, val, correct_tuple=None):
|
||||
if not correct_tuple or val in correct_tuple:
|
||||
client.set_int(key, val)
|
||||
|
||||
def get_string(key, test_func=None):
|
||||
try:
|
||||
val = client.get_string(key)
|
||||
except KeyError:
|
||||
val = ""
|
||||
if not test_func or test_func(val):
|
||||
return val
|
||||
else:
|
||||
return default_value[key]
|
||||
|
||||
def set_string(key, val, test_func=None):
|
||||
if not test_func or test_func(val):
|
||||
client.set_string(key, val)
|
||||
|
||||
def sync():
|
||||
client.suggest_sync()
|
||||
|
||||
def get_default(key,sample=''):
|
||||
return default_value[key]
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2009 Benny Malengier
|
||||
# Copyright (C) 2004-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -21,9 +21,11 @@
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Package init for the gui package.
|
||||
This package implements access to GRAMPS configuration.
|
||||
It provides the choice between different storage backends.
|
||||
|
||||
"""
|
||||
|
||||
# DO NOT IMPORT METHODS/CLASSES FROM src/gui HERE ! Only __all__
|
||||
from _GrampsConfigKeys import *
|
||||
from _GrampsIniKeys import *
|
||||
|
||||
__all__ = [ "editors", "selectors", "views", "widgets" ]
|
||||
@@ -24,15 +24,6 @@
|
||||
Provide the event view.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
import logging
|
||||
_LOG = logging.getLogger(".plugins.eventview")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
@@ -46,35 +37,34 @@ import gtk
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import EventModel
|
||||
import PageView
|
||||
import DisplayModels
|
||||
import Utils
|
||||
import Errors
|
||||
import Bookmarks
|
||||
import config
|
||||
import Config
|
||||
from DdTargets import DdTargets
|
||||
from gui.editors import EditEvent, DeleteEventQuery
|
||||
from Editors import EditEvent, DelEventQuery
|
||||
from Filters.SideBar import EventSidebarFilter
|
||||
from gen.plug import CATEGORY_QR_EVENT
|
||||
from ReportBase import CATEGORY_QR_EVENT
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# EventView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class EventView(ListView):
|
||||
class EventView(PageView.ListView):
|
||||
"""
|
||||
EventView class, derived from the ListView
|
||||
"""
|
||||
# columns in the model used in view
|
||||
COL_DESCR = 0
|
||||
COL_ID = 1
|
||||
COL_TYPE = 2
|
||||
COL_DATE = 3
|
||||
COL_PLACE = 4
|
||||
COL_CHAN = 5
|
||||
COL_PARTIC = 6
|
||||
# name of the columns
|
||||
COLUMN_NAMES = [
|
||||
_('Description'),
|
||||
_('ID'),
|
||||
@@ -82,27 +72,19 @@ class EventView(ListView):
|
||||
_('Date'),
|
||||
_('Place'),
|
||||
_('Last Changed'),
|
||||
_('Main Participants'),
|
||||
]
|
||||
# columns that contain markup
|
||||
MARKUP_COLS = [COL_DATE]
|
||||
# default setting with visible columns, order of the col, and their size
|
||||
CONFIGSETTINGS = (
|
||||
('columns.visible', [COL_DESCR, COL_ID, COL_TYPE, COL_DATE, COL_PLACE]),
|
||||
('columns.rank', [COL_DESCR, COL_ID, COL_TYPE, COL_PARTIC, COL_DATE,
|
||||
COL_PLACE, COL_CHAN]),
|
||||
('columns.size', [200, 75, 100, 230, 150, 200, 100])
|
||||
)
|
||||
|
||||
ADD_MSG = _("Add a new event")
|
||||
EDIT_MSG = _("Edit the selected event")
|
||||
DEL_MSG = _("Delete the selected event")
|
||||
FILTER_TYPE = "Event"
|
||||
QR_CATEGORY = CATEGORY_QR_EVENT
|
||||
|
||||
def __init__(self, dbstate, uistate, nav_group=0):
|
||||
def __init__(self, dbstate, uistate):
|
||||
"""
|
||||
Create the Event View
|
||||
"""
|
||||
|
||||
signal_map = {
|
||||
'event-add' : self.row_add,
|
||||
'event-update' : self.row_update,
|
||||
@@ -110,26 +92,22 @@ class EventView(ListView):
|
||||
'event-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('Events'), dbstate, uistate,
|
||||
EventView.COLUMN_NAMES, len(EventView.COLUMN_NAMES),
|
||||
EventModel,
|
||||
signal_map, dbstate.db.get_event_bookmarks(),
|
||||
Bookmarks.EventBookmarks, nav_group,
|
||||
multiple=True,
|
||||
filter_class=EventSidebarFilter,
|
||||
markup = EventView.MARKUP_COLS)
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
config.connect("interface.filter", self.filter_toggle)
|
||||
uistate.connect('nameformat-changed', self.build_tree)
|
||||
PageView.ListView.__init__(
|
||||
self, _('Events'), dbstate, uistate,
|
||||
EventView.COLUMN_NAMES, len(EventView.COLUMN_NAMES),
|
||||
DisplayModels.EventModel,
|
||||
signal_map, dbstate.db.get_event_bookmarks(),
|
||||
Bookmarks.EventBookmarks,
|
||||
multiple=True,
|
||||
filter_class=EventSidebarFilter)
|
||||
|
||||
def navigation_type(self):
|
||||
return 'Event'
|
||||
Config.client.notify_add("/apps/gramps/interface/filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def get_bookmarks(self):
|
||||
"""
|
||||
@@ -143,6 +121,12 @@ class EventView(ListView):
|
||||
"""
|
||||
return DdTargets.EVENT
|
||||
|
||||
def column_order(self):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
return self.dbstate.db.get_event_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
Use the gramps-event stock icon
|
||||
@@ -161,13 +145,6 @@ class EventView(ListView):
|
||||
<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"/>
|
||||
@@ -179,14 +156,11 @@ class EventView(ListView):
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<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"/>
|
||||
@@ -194,9 +168,6 @@ class EventView(ListView):
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
<separator/>
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
@@ -208,9 +179,11 @@ class EventView(ListView):
|
||||
</ui>'''
|
||||
|
||||
def define_actions(self):
|
||||
ListView.define_actions(self)
|
||||
PageView.ListView.define_actions(self)
|
||||
self._add_action('FilterEdit', None, _('Event Filter Editor'),
|
||||
callback=self.filter_editor,)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor,)
|
||||
self._add_action('QuickReport', None,
|
||||
_("Quick View"), None, None, None)
|
||||
self._add_action('Dummy', None,
|
||||
@@ -223,6 +196,23 @@ class EventView(ListView):
|
||||
else:
|
||||
return None
|
||||
|
||||
def _column_editor(self, obj):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Event Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_event_column_order(),
|
||||
EventView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def set_column_order(self, clist):
|
||||
self.dbstate.db.set_event_column_order(clist)
|
||||
self.build_columns()
|
||||
|
||||
def add(self, obj):
|
||||
try:
|
||||
EditEvent(self.dbstate, self.uistate, [], gen.lib.Event())
|
||||
@@ -243,8 +233,8 @@ class EventView(ListView):
|
||||
|
||||
object = self.dbstate.db.get_event_from_handle(handle)
|
||||
|
||||
query = DeleteEventQuery(self.dbstate, self.uistate, object,
|
||||
person_list, family_list)
|
||||
query = DelEventQuery(self.dbstate, self.uistate, object,
|
||||
person_list, family_list)
|
||||
is_used = len(person_list) + len(family_list) > 0
|
||||
return (query, is_used, object)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Family View.
|
||||
FamilyList View.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -28,9 +28,8 @@ Family View.
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
import logging
|
||||
_LOG = logging.getLogger(".plugins.eventview")
|
||||
from gettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GNOME/GTK+ modules
|
||||
@@ -44,31 +43,21 @@ import gtk
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import FamilyModel
|
||||
from gui.editors import EditFamily
|
||||
import PageView
|
||||
import DisplayModels
|
||||
import Bookmarks
|
||||
import Errors
|
||||
import config
|
||||
import Config
|
||||
from Filters.SideBar import FamilySidebarFilter
|
||||
from gen.plug import CATEGORY_QR_FAMILY
|
||||
from ReportBase import CATEGORY_QR_FAMILY
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# FamilyView
|
||||
# FamilyListView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class FamilyView(ListView):
|
||||
""" FamilyView class, derived from the ListView
|
||||
"""
|
||||
# columns in the model used in view
|
||||
COL_ID = 0
|
||||
COL_FATHER = 1
|
||||
COL_MOTHER = 2
|
||||
COL_REL = 3
|
||||
COL_MARDATE = 4
|
||||
COL_CHAN = 5
|
||||
# name of the columns
|
||||
class FamilyListView(PageView.ListView):
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('ID'),
|
||||
_('Father'),
|
||||
@@ -77,14 +66,6 @@ class FamilyView(ListView):
|
||||
_('Marriage Date'),
|
||||
_('Last Changed'),
|
||||
]
|
||||
#default setting with visible columns, order of the col, and their size
|
||||
CONFIGSETTINGS = (
|
||||
('columns.visible', [COL_ID, COL_FATHER, COL_MOTHER, COL_REL,
|
||||
COL_MARDATE]),
|
||||
('columns.rank', [COL_ID, COL_FATHER, COL_MOTHER, COL_REL,
|
||||
COL_MARDATE, COL_CHAN]),
|
||||
('columns.size', [75, 200, 200, 100, 100, 100])
|
||||
)
|
||||
|
||||
ADD_MSG = _("Add a new family")
|
||||
EDIT_MSG = _("Edit the selected family")
|
||||
@@ -92,7 +73,7 @@ class FamilyView(ListView):
|
||||
FILTER_TYPE = "Family"
|
||||
QR_CATEGORY = CATEGORY_QR_FAMILY
|
||||
|
||||
def __init__(self, dbstate, uistate, nav_group=0):
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'family-add' : self.row_add,
|
||||
@@ -101,24 +82,37 @@ class FamilyView(ListView):
|
||||
'family-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('Families'), dbstate, uistate,
|
||||
FamilyView.COLUMN_NAMES, len(FamilyView.COLUMN_NAMES),
|
||||
FamilyModel,
|
||||
signal_map, dbstate.db.get_family_bookmarks(),
|
||||
Bookmarks.FamilyBookmarks, nav_group,
|
||||
filter_class=FamilySidebarFilter)
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
config.connect("interface.filter", self.filter_toggle)
|
||||
uistate.connect('nameformat-changed', self.build_tree)
|
||||
PageView.ListView.__init__(
|
||||
self, _('Families'), dbstate, uistate,
|
||||
FamilyListView.COLUMN_NAMES, len(FamilyListView.COLUMN_NAMES),
|
||||
DisplayModels.FamilyModel,
|
||||
signal_map, dbstate.db.get_family_bookmarks(),
|
||||
Bookmarks.FamilyBookmarks, filter_class=FamilySidebarFilter)
|
||||
|
||||
Config.client.notify_add("/apps/gramps/interface/filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def navigation_type(self):
|
||||
return 'Family'
|
||||
def column_order(self):
|
||||
return self.dbstate.db.get_family_list_column_order()
|
||||
|
||||
def _column_editor(self, obj):
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Family Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_family_list_column_order(),
|
||||
FamilyListView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def set_column_order(self, clist):
|
||||
self.dbstate.db.set_family_list_column_order(clist)
|
||||
self.build_columns()
|
||||
|
||||
def get_stock(self):
|
||||
return 'gramps-family'
|
||||
@@ -131,19 +125,13 @@ class FamilyView(ListView):
|
||||
<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"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
@@ -154,10 +142,6 @@ class FamilyView(ListView):
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonNavigation">
|
||||
<toolitem action="Back"/>
|
||||
<toolitem action="Forward"/>
|
||||
</placeholder>
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
@@ -165,9 +149,6 @@ class FamilyView(ListView):
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
<separator/>
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
@@ -181,7 +162,9 @@ class FamilyView(ListView):
|
||||
def define_actions(self):
|
||||
"""Add the Forward action group to handle the Forward button."""
|
||||
|
||||
ListView.define_actions(self)
|
||||
PageView.ListView.define_actions(self)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor...'), callback=self._column_editor)
|
||||
|
||||
self._add_action('FilterEdit', None, _('Family Filter Editor'),
|
||||
callback=self.filter_editor,)
|
||||
@@ -208,6 +191,7 @@ class FamilyView(ListView):
|
||||
"no one was selected."))
|
||||
|
||||
def add(self, obj):
|
||||
from Editors import EditFamily
|
||||
family = gen.lib.Family()
|
||||
try:
|
||||
EditFamily(self.dbstate, self.uistate, [], family)
|
||||
@@ -215,21 +199,23 @@ class FamilyView(ListView):
|
||||
pass
|
||||
|
||||
def remove(self, obj):
|
||||
from QuestionDialog import QuestionDialog2
|
||||
from Utils import data_recover_msg
|
||||
msg = _('Deleting item will remove it from the database.')
|
||||
msg = msg + '\n' + data_recover_msg
|
||||
q = QuestionDialog2(_('Delete %s?') % _('family'), msg,
|
||||
_('_Delete Item'), _('Cancel'))
|
||||
if q.run():
|
||||
self.uistate.set_busy_cursor(1)
|
||||
map(self.dbstate.db.remove_family_relationships,
|
||||
self.selected_handles())
|
||||
self.build_tree()
|
||||
self.uistate.set_busy_cursor(0)
|
||||
from QuestionDialog import QuestionDialog2
|
||||
from Utils import data_recover_msg
|
||||
msg = _('Deleting item will remove it from the database.')
|
||||
msg = msg + '\n' + data_recover_msg
|
||||
q = QuestionDialog2(_('Delete %s?') % _('family'), msg,
|
||||
_('_Delete Item'), _('Cancel'))
|
||||
if q.run():
|
||||
self.uistate.set_busy_cursor(1)
|
||||
import gen.utils
|
||||
for handle in self.selected_handles():
|
||||
gen.utils.remove_family_relationships(self.dbstate.db, handle)
|
||||
self.build_tree()
|
||||
self.uistate.set_busy_cursor(0)
|
||||
|
||||
def edit(self, obj):
|
||||
for handle in self.selected_handles():
|
||||
from Editors import EditFamily
|
||||
family = self.dbstate.db.get_family_from_handle(handle)
|
||||
try:
|
||||
EditFamily(self.dbstate, self.uistate, [], family)
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -3,19 +3,27 @@
|
||||
# but that is not necessarily portable.
|
||||
# If not using GNU make, then list all .py files individually
|
||||
|
||||
SUBDIRS = \
|
||||
treemodels
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/gui/views
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/DataViews
|
||||
|
||||
pkgdata_PYTHON = \
|
||||
__init__.py \
|
||||
listview.py \
|
||||
navigationview.py \
|
||||
pageview.py
|
||||
__init__.py\
|
||||
GeoView.py\
|
||||
GrampletView.py\
|
||||
PersonView.py\
|
||||
RelationView.py\
|
||||
FamilyList.py\
|
||||
PedigreeView.py\
|
||||
EventView.py\
|
||||
SourceView.py\
|
||||
PlaceView.py\
|
||||
MediaView.py\
|
||||
NoteView.py\
|
||||
RepositoryView.py
|
||||
|
||||
pkgpyexecdir = @pkgpyexecdir@/gui/views
|
||||
pkgpythondir = @pkgpythondir@/gui/views
|
||||
# _MapView.py
|
||||
|
||||
pkgpyexecdir = @pkgpyexecdir@/DataViews
|
||||
pkgpythondir = @pkgpythondir@/DataViews
|
||||
|
||||
# Clean up all the byte-compiled files
|
||||
MOSTLYCLEANFILES = *pyc *pyo
|
||||
@@ -0,0 +1,844 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id:MapView.py 9912 2008-01-22 09:17:46Z acraphae $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
import gc
|
||||
import logging
|
||||
import os
|
||||
import math
|
||||
import urllib
|
||||
import urllib2
|
||||
from xml.dom.minidom import parseString as xmlStringParser
|
||||
|
||||
log = logging.getLogger(".")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gobject
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps Modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import PageView
|
||||
import Config
|
||||
import const
|
||||
|
||||
use_online_map = Config.get(Config.ONLINE_MAPS)
|
||||
|
||||
# Some initial places for debugging
|
||||
glob_loc_data = [ # (Name, longitude, latitude)
|
||||
("_Center", 0,0),
|
||||
("_North",0,90),
|
||||
("_South",0,-90),
|
||||
("_West",-180,0),
|
||||
("_East",180,0),
|
||||
("Chicago",-87.75,41.83),
|
||||
("Berlin",13.42,52.53),
|
||||
("Honolulu",-157.83,21.32),
|
||||
("Madrid",-3.72,40.42),
|
||||
("Moscow",37.70,55.75),
|
||||
("Vienna",16.37,48.22),
|
||||
("Sydney",151.17,-33.92),
|
||||
("Rio de Janeiro",-43.28,-22.88),
|
||||
("Tokyo",139.75,35.67),
|
||||
("Cape Town",18.47,-33.93),
|
||||
("Anchorage",-150.00,61.17),
|
||||
("Mannheim-Wallstadt",8.55,49.48),
|
||||
("Mannheim-Neckarau",8.48,49.45),
|
||||
("Gorxheimertal",8.73,49.53)]
|
||||
|
||||
enable_debug = False
|
||||
|
||||
|
||||
# Draws a map image and tries to allocate space in the correct aspect ratio
|
||||
class GuideMap(gtk.DrawingArea):
|
||||
def __init__(self, map_pixbuf):
|
||||
gtk.DrawingArea.__init__(self)
|
||||
self.map_pixbuf = map_pixbuf
|
||||
self.connect("expose-event", self.expose_cb)
|
||||
self.connect("size-allocate", self.size_allocate_cb)
|
||||
self.gc = None
|
||||
self.current_area = None
|
||||
self.current_spot = None
|
||||
self.old_size = (-1,-1)
|
||||
|
||||
# Set hightlight region
|
||||
def hightlight_area( self, area):
|
||||
self.current_area = area
|
||||
self.queue_draw()
|
||||
|
||||
# Set hightlight region
|
||||
def hightlight_spot( self, spot):
|
||||
self.current_spot = spot
|
||||
self.queue_draw()
|
||||
|
||||
# Redraw the image
|
||||
def expose_cb(self,widget,event):
|
||||
if not self.gc:
|
||||
self.gc = self.window.new_gc()
|
||||
self.gc.set_foreground( self.get_colormap().alloc_color("red"))
|
||||
self.gc.set_background( self.get_colormap().alloc_color("blue"))
|
||||
if self.backbuf and self.gc:
|
||||
self.window.draw_pixbuf( self.gc, self.backbuf, 0,0, 0,0, -1,-1)
|
||||
if self.current_area:
|
||||
r = self.map_to_screen(self.current_area[0],
|
||||
self.current_area[1],
|
||||
self.current_area[2],
|
||||
self.current_area[3])
|
||||
self.window.draw_rectangle( self.gc, False,
|
||||
r[0],r[1],r[2],r[3])
|
||||
if self.current_spot:
|
||||
r = self.map_to_screen(self.current_spot[0],
|
||||
self.current_spot[1])
|
||||
self.window.draw_line( self.gc,0,r[1],
|
||||
self.backbuf.get_width(),r[1])
|
||||
self.window.draw_line( self.gc,r[0],0,
|
||||
r[0],self.backbuf.get_height())
|
||||
|
||||
|
||||
# Scale backbuffer
|
||||
def size_allocate_cb(self,widget,allocation):
|
||||
# Always request a height, that is half of the width
|
||||
w = max( 128,allocation.width)
|
||||
self.set_size_request(-1,w/2)
|
||||
|
||||
# only create new backbuffer if size is different
|
||||
new_size = (allocation.width,allocation.height)
|
||||
if new_size is not self.old_size:
|
||||
self.old_size = new_size
|
||||
self.backbuf = self.map_pixbuf.scale_simple(
|
||||
self.old_size[0],
|
||||
self.old_size[1],
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
gc.collect()
|
||||
|
||||
def map_to_screen( self, x,y,w=None, h=None):
|
||||
px = int((float(x) + 180.0) / 360.0 * self.backbuf.get_width())
|
||||
py = int((90-float(y)) / 180.0 * self.backbuf.get_height())
|
||||
if w and h:
|
||||
pw = int(float(w) / 360.0 * self.backbuf.get_width())
|
||||
ph = int(float(h) / 180.0 * self.backbuf.get_height())
|
||||
return (px,py,pw,ph)
|
||||
return (px,py)
|
||||
|
||||
# Map tile files used by the ZoomMap
|
||||
class MapTile(object):
|
||||
def __init__( self, filename, x, y, w, h, pw, ph):
|
||||
self.filename = filename
|
||||
self.full_path = os.path.join(const.IMAGE_DIR,filename)
|
||||
self.map_x = float(x)
|
||||
self.map_y = float(y)
|
||||
self.map_width = float(w)
|
||||
self.map_height = float(h)
|
||||
self.map_pixel_width = float(pw)
|
||||
self.map_pixel_height = float(ph)
|
||||
self.source_pixbuf = None
|
||||
self.source_scale = self.map_pixel_width / self.map_width
|
||||
self.scale = None
|
||||
self.scaled_pixbuf = None
|
||||
self.scaled_map_x = None
|
||||
self.scaled_map_y = None
|
||||
|
||||
def set_viewport( self, target_scale, x_in, y_in, w_in, h_in):
|
||||
# intersect viewport with map area
|
||||
x = max(self.map_x, max(-180.0,x_in))
|
||||
y = min(self.map_y, min( 90.0,y_in))
|
||||
xmax = min( min(180.0,x_in+w_in), self.map_x+self.map_width)
|
||||
ymin = max( max(-90.0,y_in-h_in), self.map_y-self.map_width)
|
||||
w = xmax-x
|
||||
h = y-ymin
|
||||
|
||||
if w > 0.0 and h > 0.0:
|
||||
# crop source tile to not scale the whole IMAGE_DIR
|
||||
xoffset = max(0,math.floor((x - self.map_x) * self.source_scale))
|
||||
xmax = max(0,math.ceil((x+w - self.map_x) * self.source_scale))
|
||||
yoffset = min(self.map_pixel_width,math.floor(-(y - self.map_y) * self.source_scale))
|
||||
ymax = min(self.map_pixel_height,math.ceil(-(y-h - self.map_y) * self.source_scale))
|
||||
|
||||
rescale = target_scale / self.source_scale
|
||||
if int((xmax-xoffset)*rescale) > 0 and int((ymax-yoffset)*rescale) > 0:
|
||||
self.scaled_map_x = self.map_x + xoffset / self.source_scale
|
||||
self.scaled_map_y = self.map_y - yoffset / self.source_scale
|
||||
self.scaled_map_pixel_w = int((xmax-xoffset)*rescale)
|
||||
self.scaled_map_pixel_h = int((ymax-yoffset)*rescale)
|
||||
|
||||
if enable_debug:
|
||||
print
|
||||
print "Source-Map origin: %f x %f, %f, %f" % (self.map_x,self.map_y,self.map_width,self.map_height)
|
||||
print "Source-Map pixels: %f x %f" % (self.map_pixel_width,self.map_pixel_height)
|
||||
print "Source-Map scale: %f" % self.source_scale
|
||||
print "Target origin: %f x %f, %f, %f" % (x,y,w, h)
|
||||
print "Target scale: %f" % target_scale
|
||||
print "Target crop: %f x %f, %f x %f" % (xoffset,yoffset,xmax,ymax)
|
||||
print "Origin of crop: %f x %f" % (self.scaled_map_x,self.scaled_map_y)
|
||||
print "scaled tile size: %f x %f pix" % (self.scaled_map_pixel_w,self.scaled_map_pixel_h)
|
||||
|
||||
try:
|
||||
if not self.source_pixbuf:
|
||||
self.source_pixbuf = gtk.gdk.pixbuf_new_from_file( self.full_path)
|
||||
|
||||
clip_pixbuf = self.source_pixbuf.subpixbuf(int(xoffset),int(yoffset),int(xmax-xoffset),int(ymax-yoffset))
|
||||
|
||||
self.scale = target_scale
|
||||
self.scaled_pixbuf = clip_pixbuf.scale_simple( int((xmax-xoffset)*rescale), int((ymax-yoffset)*rescale), gtk.gdk.INTERP_BILINEAR)
|
||||
clip_pixbuf = None
|
||||
except:
|
||||
pass
|
||||
|
||||
else:
|
||||
self.scale = None
|
||||
self.scaled_pixbuf = None
|
||||
else:
|
||||
self.scale = None
|
||||
self.scaled_pixbuf = None
|
||||
|
||||
def free(self):
|
||||
self.scale = None
|
||||
self.scaled_pixbuf = None
|
||||
|
||||
class WMSMapTile(object):
|
||||
def __init__(self,capabilities,change_cb=None):
|
||||
self.change_cb = change_cb
|
||||
self.scaled_pixbuf = None
|
||||
self.handler_running = False
|
||||
self.target_scale = 0.0
|
||||
self.scaled_map_x = 0.0
|
||||
self.scaled_map_y = 0.0
|
||||
self.scaled_map_pixel_w = 0.0
|
||||
self.scaled_map_pixel_h = 0.0
|
||||
self.capabilities_url = capabilities
|
||||
u_reader = urllib2.urlopen(self.capabilities_url)
|
||||
# TODO: Put into an idle handler or thread
|
||||
response_body = u_reader.read()
|
||||
u_reader.close()
|
||||
xml_doc = xmlStringParser( response_body)
|
||||
# validate name of root element
|
||||
e = xml_doc.documentElement
|
||||
if e.nodeName != "WMT_MS_Capabilities":
|
||||
print "unsupported Document type '%s'" % e.nodeName
|
||||
return None
|
||||
self.map_request_params = {}
|
||||
self.map_request_params["VERSION"] = e.getAttribute("version")
|
||||
self.map_request_params["REQUEST"] = "GetMap"
|
||||
self.map_request_params["SERVICE"] = "WMS"
|
||||
self.map_request_params["REQUEST"] = "GetMap"
|
||||
self.map_request_params["REQUEST"] = "GetMap"
|
||||
self.map_request_params["FORMAT"] = "image/png"
|
||||
self.map_request_params["SRS"] = "epsg:4326"
|
||||
self.map_request_params["LAYERS"] = ""
|
||||
# Child-nodes of root element
|
||||
for n in e.childNodes:
|
||||
if n.nodeName == "Service":
|
||||
# Parse Service header
|
||||
map_title = n.getElementsByTagName("Title")[0].firstChild.data
|
||||
print " MAP Title: %s" % map_title
|
||||
try:
|
||||
map_fees = e.getElementsByTagName("Fees")[0].firstChild.data
|
||||
except IndexError:
|
||||
map_fees = "-"
|
||||
print " MAP Fees: %s" % map_fees
|
||||
try:
|
||||
map_access_constraints = e.getElementsByTagName("AccessConstraints")[0].firstChild.data
|
||||
except IndexError:
|
||||
map_access_constraints = "-"
|
||||
print " MAP AccessConstraints: %s" % map_access_constraints
|
||||
|
||||
elif n.nodeName == "Capability":
|
||||
# Parse Capabilities
|
||||
for n2 in n.childNodes:
|
||||
if n2.nodeName == "Request":
|
||||
t1 = n2.getElementsByTagName("GetMap")[0]
|
||||
t2 = t1.getElementsByTagName("DCPType")[0]
|
||||
t3 = t2.getElementsByTagName("HTTP")[0]
|
||||
t4 = t3.getElementsByTagName("Get")[0]
|
||||
t5 = t4.getElementsByTagName("OnlineResource")[0]
|
||||
self.map_get_url = t5.getAttribute("xlink:href")
|
||||
if enable_debug:
|
||||
print(" Map Tile base url: %s" % self.map_get_url)
|
||||
elif n2.nodeName == "Layer":
|
||||
# parse Layers
|
||||
if not self._srs_is_supported(n2.getElementsByTagName("SRS")[0].firstChild.data):
|
||||
print "Layer coordinates not supported :-("
|
||||
return None
|
||||
layer_title = n2.getElementsByTagName("Title")[0].firstChild.data
|
||||
if enable_debug:
|
||||
print " Layer: %s" % layer_title
|
||||
for n3 in n2.childNodes:
|
||||
if n3.nodeName == "Layer":
|
||||
# parse Layers
|
||||
layer_title = n3.getElementsByTagName("Name")[0].firstChild.data
|
||||
if enable_debug:
|
||||
print " - Layer: %s" % layer_title
|
||||
if self.map_request_params["LAYERS"]:
|
||||
self.map_request_params["LAYERS"] += ","
|
||||
self.map_request_params["LAYERS"] += layer_title
|
||||
def _srs_is_supported( self, srs_string):
|
||||
list = srs_string.lower().split()
|
||||
if "epsg:4326" in list:
|
||||
return True
|
||||
return False
|
||||
|
||||
def idle_handler( self):
|
||||
""" fetches parts of the download and feeds them into a PixbufLoader """
|
||||
if enable_debug:
|
||||
print "idle_handler"
|
||||
if not self.handler_running or not self.url_handler:
|
||||
return False
|
||||
buf = self.url_handler.read(5000)
|
||||
if enable_debug:
|
||||
print len(buf)
|
||||
if len(buf) > 0:
|
||||
self.pixbufloader.write(buf)
|
||||
self.scaled_pixbuf = self.pixbufloader.get_pixbuf()
|
||||
else:
|
||||
if enable_debug:
|
||||
print "no more content."
|
||||
self.handler_running = False
|
||||
self.url_handler.close()
|
||||
try:
|
||||
self.pixbufloader.close()
|
||||
except gobject.GError:
|
||||
pass # dont crash if nothing or not an image has been downloaded
|
||||
return False
|
||||
self.change_cb()
|
||||
return True
|
||||
|
||||
def set_viewport( self, target_scale, x_in, y_in, w_in, h_in):
|
||||
new_scaled_map_pixel_w = int(w_in*target_scale)
|
||||
new_scaled_map_pixel_h = int(h_in*target_scale)
|
||||
if self.target_scale != target_scale\
|
||||
or self.scaled_map_x > x_in\
|
||||
or self.scaled_map_y < y_in\
|
||||
or self.scaled_map_pixel_w < new_scaled_map_pixel_w\
|
||||
or self.scaled_map_pixel_h < new_scaled_map_pixel_h:
|
||||
# only download new map is new viewport is larger
|
||||
# TODO: Fix above to be correct and add a cache of already downloaded tiles
|
||||
self.target_scale = target_scale
|
||||
self.scaled_map_x = x_in
|
||||
self.scaled_map_y = y_in
|
||||
self.scaled_map_pixel_w = int(w_in*target_scale)
|
||||
self.scaled_map_pixel_h = int(h_in*target_scale)
|
||||
self.map_request_params["BBOX"] = "%f,%f,%f,%f" % (x_in,y_in-h_in,x_in+w_in,y_in) # Neds to be set for request
|
||||
self.map_request_params["WIDTH"] = int(w_in*target_scale)
|
||||
self.map_request_params["HEIGHT"] = int(h_in*target_scale)
|
||||
params = urllib.urlencode(self.map_request_params)
|
||||
if self.handler_running:
|
||||
if enable_debug:
|
||||
print "stopping current download"
|
||||
self.url_handler.close()
|
||||
try:
|
||||
self.pixbufloader.close()
|
||||
except gobject.GError:
|
||||
pass # dont crash if nothing or not an image has been downloaded
|
||||
self.scaled_pixbuf = None
|
||||
self.url_handler = urllib.urlopen(self.map_get_url+params)
|
||||
self.handler_running = gobject.idle_add(self.idle_handler)
|
||||
self.pixbufloader = gtk.gdk.PixbufLoader()
|
||||
else:
|
||||
if enable_debug:
|
||||
print "new viewport fits inside old one. No download required."
|
||||
|
||||
def free(self):
|
||||
pass
|
||||
|
||||
# Zoomable map image
|
||||
class ZoomMap( gtk.DrawingArea):
|
||||
def __init__( self, place_marker_pixbuf, hightlight_marker_pixbuf):
|
||||
gtk.DrawingArea.__init__(self)
|
||||
self.place_marker_pixbuf = place_marker_pixbuf
|
||||
self.hightlight_marker_pixbuf = hightlight_marker_pixbuf
|
||||
self.add_events(gtk.gdk.POINTER_MOTION_MASK) # position overlay
|
||||
self.connect("expose-event", self.expose_cb)
|
||||
self.connect("size-allocate", self.size_allocate_cb)
|
||||
if enable_debug:
|
||||
self.connect("motion-notify-event", self.motion_notify_event_cb)
|
||||
self.gc = None
|
||||
self.current_pixel_size = (-1,-1)
|
||||
self.zoom_pos = (0,0)
|
||||
self.magnifer = 0.0 # in pixel per degree
|
||||
self.guide = None
|
||||
self.textlayout = self.create_pango_layout("")
|
||||
self.map_sources = {}
|
||||
self.initial_exposed = False
|
||||
if use_online_map:
|
||||
self.map_sources[0.0] = []
|
||||
self.map_sources[0.0].append(WMSMapTile("http://www2.demis.nl/wms/wms.asp?wms=WorldMap&VERSION=1.1.1&REQUEST=GetCapabilities",self.queue_draw))
|
||||
|
||||
def add_map_source( self,filename, x, y, w, h,pw,ph):
|
||||
tile = MapTile( filename, x, y, w, h, pw, ph)
|
||||
if not tile.source_scale in self.map_sources:
|
||||
self.map_sources[tile.source_scale] = []
|
||||
self.map_sources[tile.source_scale].append( tile)
|
||||
|
||||
# Set the guide map that should follow the zoom area
|
||||
def set_guide( self, guide):
|
||||
self.guide = guide
|
||||
|
||||
def set_location_model( self, model, idx_name, idx_long, idx_lat):
|
||||
self.location_model = model
|
||||
self.idx_name = idx_name
|
||||
self.idx_long = idx_long
|
||||
self.idx_lat = idx_lat
|
||||
|
||||
def motion_notify_event_cb(self,widget,event):
|
||||
self.textlayout.set_text( "Position: %03.0f,%03.0f pixel" % (event.x,event.y))
|
||||
(w, h) = self.textlayout.get_pixel_size()
|
||||
self.gc.set_foreground( self.get_colormap().alloc_color("white"))
|
||||
self.window.draw_rectangle( self.gc, True, 10,50,w, h)
|
||||
self.gc.set_foreground( self.get_colormap().alloc_color("red"))
|
||||
self.window.draw_layout( self.gc, 10, 50, self.textlayout)
|
||||
(lon,lat) = self.screen_to_map(event.x,event.y)
|
||||
self.textlayout.set_text( "Position: %03.0f,%03.0f degree" % (lon,lat))
|
||||
(w, h) = self.textlayout.get_pixel_size()
|
||||
self.gc.set_foreground( self.get_colormap().alloc_color("white"))
|
||||
self.window.draw_rectangle( self.gc, True, 10,70,w, h)
|
||||
self.gc.set_foreground( self.get_colormap().alloc_color("red"))
|
||||
self.window.draw_layout( self.gc, 10, 70, self.textlayout)
|
||||
|
||||
# Redraw the image
|
||||
def expose_cb(self,widget,event):
|
||||
if not self.gc:
|
||||
self.gc = self.window.new_gc()
|
||||
self.gc.set_foreground( self.get_colormap().alloc_color("red"))
|
||||
self.gc.set_background( self.get_colormap().alloc_color("blue"))
|
||||
if not self.backbuf:
|
||||
self.size_allocate_cb( self,self.get_allocation())
|
||||
if self.backbuf and self.gc:
|
||||
#draw all maps
|
||||
scales = self.map_sources.keys()
|
||||
scales.sort()
|
||||
for scale in scales:
|
||||
for map in self.map_sources[scale]:
|
||||
if map.scaled_pixbuf:
|
||||
(px,py) = self.map_to_screen( map.scaled_map_x, map.scaled_map_y)
|
||||
self.window.draw_pixbuf( self.gc, map.scaled_pixbuf, 0,0, px,py)
|
||||
if enable_debug:
|
||||
self.window.draw_rectangle( self.gc, False, px,py,map.scaled_map_pixel_w,map.scaled_map_pixel_h)
|
||||
self.window.draw_line( self.gc, px,py,px+map.scaled_map_pixel_w,py+map.scaled_map_pixel_h)
|
||||
self.window.draw_line( self.gc, px,py+map.scaled_map_pixel_h,px+map.scaled_map_pixel_w,py)
|
||||
gc.collect()
|
||||
|
||||
|
||||
# draw all available locations
|
||||
if self.location_model:
|
||||
iter = self.location_model.get_iter_first()
|
||||
while iter:
|
||||
(n,x,y) = self.location_model.get( iter, self.idx_name, self.idx_long, self.idx_lat)
|
||||
(px,py) = self.map_to_screen( x, y)
|
||||
#if px > 0 and py > 0 and px < self.backbuf.get_width() and py < self.backbuf.get_height():
|
||||
# draw only visible markers
|
||||
#self.window.draw_pixbuf(
|
||||
# self.gc,
|
||||
# self.place_marker_pixbuf,
|
||||
# 0,0,
|
||||
# px-self.place_marker_pixbuf.get_width()/2,
|
||||
# py-self.place_marker_pixbuf.get_height()/2,
|
||||
# -1,-1)
|
||||
self.textlayout.set_text(n)
|
||||
self.window.draw_layout(
|
||||
self.gc,
|
||||
px,py,
|
||||
self.textlayout)
|
||||
iter = self.location_model.iter_next( iter)
|
||||
|
||||
# hightlight current location
|
||||
(px,py) = self.map_to_screen( self.zoom_pos[0], self.zoom_pos[1])
|
||||
self.window.draw_pixbuf(
|
||||
self.gc,
|
||||
self.hightlight_marker_pixbuf,
|
||||
0,0,
|
||||
px-self.hightlight_marker_pixbuf.get_width()/2,
|
||||
py-self.hightlight_marker_pixbuf.get_height()/2,
|
||||
-1,-1)
|
||||
#self.window.draw_rectangle( self.gc, False, px-3,py-3, 6,6)
|
||||
|
||||
#(px1,py1) = self.map_to_screen(-180, 90)
|
||||
#(px2,py2) = self.map_to_screen( 180,-90)
|
||||
#self.window.draw_rectangle( self.gc, False, px1,py1,px2-px1,py2-py1)
|
||||
#self.window.draw_line( self.gc, px1,py1,px2,py2)
|
||||
#self.window.draw_line( self.gc, px1,py2,px2,py1)
|
||||
if enable_debug:
|
||||
# Output debugging info
|
||||
self.textlayout.set_text( "Magnifer: %f pixel per degree" % self.magnifer)
|
||||
self.window.draw_layout( self.gc, 10, 10, self.textlayout)
|
||||
self.textlayout.set_text( "Current map: %f pixel per degree" % self.selected_map_scale)
|
||||
self.window.draw_layout( self.gc, 10, 30, self.textlayout)
|
||||
|
||||
def map_to_screen( self, lon, lat):
|
||||
px = int(self.current_pixel_size[0] / 2.0 + (lon - self.zoom_pos[0]) * self.magnifer)
|
||||
py = int(self.current_pixel_size[1] / 2.0 - (lat - self.zoom_pos[1]) * self.magnifer)
|
||||
return( px, py)
|
||||
|
||||
def screen_to_map( self, px, py):
|
||||
px = float(px)
|
||||
py = float(py)
|
||||
lon = (px - self.current_pixel_size[0]/2) / self.magnifer + self.zoom_pos[0];
|
||||
lat = -(py - self.current_pixel_size[1]/2) / self.magnifer + self.zoom_pos[1];
|
||||
return( lon, lat)
|
||||
|
||||
# Scale backbuffer
|
||||
def size_allocate_cb(self,widget,allocation):
|
||||
# only create new backbuffer if size is different
|
||||
new_size = (allocation.width,allocation.height)
|
||||
if new_size is not self.current_pixel_size or not self.backbuf:
|
||||
self.backbuf = True
|
||||
self.current_pixel_size = new_size
|
||||
if self.magnifer == 0.0:
|
||||
# scale map to full width
|
||||
self.magnifer = self.current_pixel_size[0] / 360.0
|
||||
x0,y0 = self.screen_to_map( 0, 0)
|
||||
x1,y1 = self.screen_to_map( new_size[0], new_size[1])
|
||||
self.guide.hightlight_area( (x0,y0,x1-x0, y0-y1))
|
||||
|
||||
def cmpfunc(s):
|
||||
return((self.magnifer-s)*(self.magnifer-s))
|
||||
|
||||
# select best matching tile set
|
||||
self.selected_map_scale = None
|
||||
smallest_scale = None
|
||||
largest_scale = None
|
||||
for s in self.map_sources.keys():
|
||||
if not self.selected_map_scale or cmpfunc(s) < cmpfunc(self.selected_map_scale):
|
||||
self.selected_map_scale = s
|
||||
if not smallest_scale or s < smallest_scale:
|
||||
smallest_scale = s
|
||||
if not largest_scale or s > largest_scale:
|
||||
largest_scale = s
|
||||
if enable_debug:
|
||||
print "scale of display: %f" % self.magnifer
|
||||
print "available map scales:"
|
||||
print self.map_sources.keys()
|
||||
print "largest scale: %f" % largest_scale
|
||||
print "smallest scale: %f" % smallest_scale
|
||||
print "selected scale: %f" % self.selected_map_scale
|
||||
|
||||
for s in self.map_sources.keys():
|
||||
for map in self.map_sources[s]:
|
||||
if s == self.selected_map_scale or s == smallest_scale:
|
||||
map.set_viewport( self.magnifer, x0, y0, x1-x0, y0-y1)
|
||||
else:
|
||||
map.free()
|
||||
|
||||
# Scroll to requested position
|
||||
def scroll_to( self, long, lat):
|
||||
self.zoom_pos = (float( min(180,(max(-180,long)))), float(min(90,(max(-90,lat)))))
|
||||
self.backbuf = None
|
||||
if self.guide:
|
||||
self.guide.hightlight_spot( self.zoom_pos)
|
||||
self.queue_draw()
|
||||
|
||||
def zoom_out(self):
|
||||
self.magnifer = max( 1.0, self.magnifer * 2.0/3.0)
|
||||
self.backbuf = None
|
||||
self.queue_draw()
|
||||
|
||||
def zoom_in(self):
|
||||
self.magnifer = min( 1000.0, self.magnifer * 1.5)
|
||||
self.backbuf = None
|
||||
self.queue_draw()
|
||||
|
||||
def zoom_normal(self):
|
||||
self.magnifer = 1.0
|
||||
self.magnifer = self.selected_map_scale
|
||||
self.backbuf = None
|
||||
self.queue_draw()
|
||||
|
||||
def zoom_fit(self):
|
||||
self.magnifer = self.current_pixel_size[0] / 360.0
|
||||
self.backbuf = None
|
||||
self.queue_draw()
|
||||
|
||||
|
||||
# Place list widget
|
||||
class MapPlacesList(gtk.TreeView):
|
||||
def __init__(self, data):
|
||||
self.lstore = gtk.ListStore(
|
||||
gobject.TYPE_STRING,
|
||||
gobject.TYPE_FLOAT,
|
||||
gobject.TYPE_FLOAT)
|
||||
|
||||
self.change_data( data)
|
||||
|
||||
gtk.TreeView.__init__(self, self.lstore)
|
||||
self.set_rules_hint(True)
|
||||
self.set_search_column(0)
|
||||
|
||||
column = gtk.TreeViewColumn('Place', gtk.CellRendererText(), text=0)
|
||||
column.set_sort_column_id(0)
|
||||
self.append_column(column)
|
||||
|
||||
column = gtk.TreeViewColumn('Lat', gtk.CellRendererText(), text=1)
|
||||
column.set_sort_column_id(1)
|
||||
self.append_column(column)
|
||||
|
||||
column = gtk.TreeViewColumn('Long', gtk.CellRendererText(),text=2)
|
||||
column.set_sort_column_id(2)
|
||||
self.append_column(column)
|
||||
|
||||
def change_data( self, data):
|
||||
self.lstore.clear()
|
||||
for item in data:
|
||||
iter = self.lstore.append()
|
||||
self.lstore.set(iter,
|
||||
0, item[0],
|
||||
1, item[1],
|
||||
2, item[2])
|
||||
|
||||
|
||||
|
||||
# Map View main class
|
||||
class MapView(PageView.PageView):
|
||||
def __init__(self,dbstate,uistate):
|
||||
PageView.PageView.__init__(self, _('Maps'), dbstate, uistate)
|
||||
dbstate.connect('database-changed',self.change_db)
|
||||
self.current_marker = None
|
||||
|
||||
def navigation_type(self):
|
||||
return PageView.NAVIGATION_NONE
|
||||
|
||||
def define_actions(self):
|
||||
self._add_action('ZoomIn',gtk.STOCK_ZOOM_IN,
|
||||
_("Zoom _In"),tip=_("Zoom in by a factor of 2"),
|
||||
callback=self.zoom_in_cb)
|
||||
self._add_action('ZoomOut',gtk.STOCK_ZOOM_OUT,
|
||||
_("Zoom _Out"),tip=_("Zoom out by a factor of 2"),
|
||||
callback=self.zoom_out_cb)
|
||||
self._add_action('ZoomNormal',gtk.STOCK_ZOOM_100,
|
||||
_("_Normal Size"), tip=_("Return to normal size"),
|
||||
callback=self.zoom_100_cb)
|
||||
self._add_action('ZoomFit',gtk.STOCK_ZOOM_FIT,
|
||||
_("Best _Fit"),
|
||||
tip=_("Produce the best fit of the map in the window"),
|
||||
callback=self.zoom_fit_cb)
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
Return the name of the stock icon to use for the display.
|
||||
This assumes that this icon has already been registered with
|
||||
GNOME as a stock icon.
|
||||
"""
|
||||
return 'gramps-map'
|
||||
|
||||
|
||||
# For debugging: Reads in location from xearth
|
||||
def get_xearth_markers(self):
|
||||
data = []
|
||||
try:
|
||||
f = open("/etc/xearth/xearth.markers")
|
||||
l = f.readline()
|
||||
#linere = re.compile('[^0-9.-]*(-?[0-9]+\.[0-9]+)[^0-9.-]*(-?[0-9]+\.[0-9]+).*"([^"])".*', "I")
|
||||
while l:
|
||||
if not l[0] == "#":
|
||||
l = l.strip().replace('"',"").replace(" "," ").replace(" "," ").replace(" "," ").replace(" # ",", ")
|
||||
m = l.split( None, 2)
|
||||
if len(m) == 3:
|
||||
data.append( (m[2],float(m[1]),float(m[0])))
|
||||
l = f.readline()
|
||||
except IOError:
|
||||
pass
|
||||
return data
|
||||
|
||||
# Reads in locations from current GRAMPS database
|
||||
def get_markers_from_database(self, db):
|
||||
data = []
|
||||
for place_handle in db.get_place_handles():
|
||||
place = db.get_place_from_handle( place_handle)
|
||||
if place:
|
||||
try:
|
||||
data.append( (place.get_title(),float(place.get_longitude()),float(place.get_latitude())))
|
||||
except (TypeError, ValueError):
|
||||
# ignore places that dont have usable data
|
||||
pass
|
||||
return data
|
||||
|
||||
# Reads in textfiles from NIMA:
|
||||
# http://earth-info.nga.mil/gns/html/cntry_files.html
|
||||
def parse_nima_countryfile(self, filename):
|
||||
import csv
|
||||
data = []
|
||||
try:
|
||||
csvreader = csv.reader(open(filename), "excel-tab")
|
||||
l = csvreader.next() # skip header
|
||||
l = csvreader.next()
|
||||
line = 1
|
||||
while l:
|
||||
if l[17] == "N" and l[9] == "P":
|
||||
city = l[22]
|
||||
lat = float( l[3])
|
||||
lon = float( l[4])
|
||||
|
||||
if line % 10 == 0:
|
||||
data.append( (city, lon, lat))
|
||||
l = csvreader.next()
|
||||
line = line + 1
|
||||
except (IOError,StopIteration):
|
||||
pass
|
||||
return data
|
||||
|
||||
def build_widget(self):
|
||||
hbox = gtk.HBox( False, 4)
|
||||
hbox.set_border_width( 4)
|
||||
|
||||
no = gtk.Image()
|
||||
# The large zoomable map
|
||||
self.zoom_map = ZoomMap(
|
||||
gtk.gdk.pixbuf_new_from_file(os.path.join(const.IMAGE_DIR,"bad.png")),
|
||||
gtk.gdk.pixbuf_new_from_file(os.path.join(const.IMAGE_DIR,"good.png")))
|
||||
if not use_online_map:
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_0.jpg', -180,90, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_1.jpg', -135,90, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_2.jpg', -90,90, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_3.jpg', -45,90, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_4.jpg', 0,90, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_5.jpg', 45,90, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_6.jpg', 90,90, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_0_7.jpg', 135,90, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_0.jpg', -180,45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_1.jpg', -135,45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_2.jpg', -90,45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_3.jpg', -45,45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_4.jpg', 0,45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_5.jpg', 45,45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_6.jpg', 90,45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_1_7.jpg', 135,45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_0.jpg', -180,0, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_1.jpg', -135,0, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_2.jpg', -90,0, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_3.jpg', -45,0, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_4.jpg', 0,0, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_5.jpg', 45,0, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_6.jpg', 90,0, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_2_7.jpg', 135,0, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_0.jpg', -180,-45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_1.jpg', -135,-45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_2.jpg', -90,-45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_3.jpg', -45,-45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_4.jpg', 0,-45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_5.jpg', 45,-45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_6.jpg', 90,-45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x3200x1600_tile_3_7.jpg', 135,-45, 45,45, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_0_0.jpg', -180,90, 90,90, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_0_1.jpg', -90,90, 90,90, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_0_2.jpg', 0,90, 90,90, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_0_3.jpg', 90,90, 90,90, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_1_0.jpg', -180,0, 90,90, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_1_1.jpg', -90,0, 90,90, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_1_2.jpg', 0,0, 90,90, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x1600x800_tile_1_3.jpg', 90,0, 90,90, 400,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x800x400.jpg', -180,90, 360,180, 800,400)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x400x200.jpg', -180,90, 360,180, 400,200)
|
||||
self.zoom_map.add_map_source('world.topo.200407.3x128x60.jpg', -180,90, 360,180, 128,60)
|
||||
|
||||
self.zoom_map.set_size_request(300,300)
|
||||
hbox.pack_start( self.zoom_map, True, True, 0)
|
||||
|
||||
# On the right side
|
||||
vbox = gtk.VBox( False, 4)
|
||||
hbox.pack_start( vbox, False, False, 0)
|
||||
|
||||
# The small guide map
|
||||
self.guide_map = GuideMap(
|
||||
gtk.gdk.pixbuf_new_from_file(os.path.join(const.IMAGE_DIR,"world.topo.200407.3x128x60.jpg")))
|
||||
self.guide_map.set_size_request(128,64)
|
||||
vbox.pack_start( self.guide_map, False, True, 0)
|
||||
|
||||
self.zoom_map.set_guide(self.guide_map)
|
||||
|
||||
# and the place list
|
||||
self.place_list_view = MapPlacesList( [])
|
||||
self.zoom_map.set_location_model(self.place_list_view.get_model(), 0,1,2)
|
||||
self.place_list_view.connect("cursor-changed", self.entry_select_cb)
|
||||
self.place_list_view.set_size_request(128,-1)
|
||||
vport = gtk.ScrolledWindow()
|
||||
vbox.pack_start(vport,True,True,0)
|
||||
vport.add( self.place_list_view)
|
||||
|
||||
self.rebuild_places()
|
||||
|
||||
return hbox
|
||||
|
||||
def ui_definition(self):
|
||||
"""
|
||||
Specifies the UIManager XML code that defines the menus and buttons
|
||||
associated with the interface.
|
||||
"""
|
||||
return '''<ui>
|
||||
<toolbar name="ToolBar">
|
||||
<toolitem action="ZoomIn"/>
|
||||
<toolitem action="ZoomOut"/>
|
||||
<toolitem action="ZoomNormal"/>
|
||||
<toolitem action="ZoomFit"/>
|
||||
</toolbar>
|
||||
</ui>'''
|
||||
|
||||
def change_db(self,db):
|
||||
"""
|
||||
Callback associated with DbState. Whenenver the database
|
||||
changes, this task is called. In this case, we rebuild the
|
||||
columns, and connect signals to the connected database. Tere
|
||||
is no need to store the database, since we will get the value
|
||||
from self.state.db
|
||||
"""
|
||||
db.connect('place-rebuild',self.rebuild_places)
|
||||
db.connect('place-update',self.rebuild_places)
|
||||
|
||||
def rebuild_places(self, handle_list=None):
|
||||
d = glob_loc_data
|
||||
try:
|
||||
d = d + self.get_xearth_markers()
|
||||
#d = self.parse_nima_countryfile("/tmp/gm.txt")
|
||||
d = d + self.get_markers_from_database( self.dbstate.db)
|
||||
except:
|
||||
log.error("Failed to rebuild places.", exc_info=True)
|
||||
self.place_list_view.change_data( d)
|
||||
|
||||
def entry_select_cb(self,treeview):
|
||||
s = treeview.get_selection()
|
||||
(model,sel) = s.get_selected_rows()
|
||||
for path in sel:
|
||||
iter = model.get_iter(path)
|
||||
self.zoom_map.scroll_to(model.get_value(iter,1),
|
||||
model.get_value(iter,2))
|
||||
break
|
||||
|
||||
def zoom_in_cb(self, obj):
|
||||
self.zoom_map.zoom_in()
|
||||
|
||||
def zoom_out_cb(self, obj):
|
||||
self.zoom_map.zoom_out()
|
||||
|
||||
def zoom_100_cb(self, obj):
|
||||
self.zoom_map.zoom_normal()
|
||||
|
||||
def zoom_fit_cb(self, obj):
|
||||
self.zoom_map.zoom_fit()
|
||||
@@ -29,12 +29,11 @@ Media View.
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
from gettext import gettext as _
|
||||
import urlparse
|
||||
import os
|
||||
import sys
|
||||
import cPickle as pickle
|
||||
import urllib
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
@@ -47,43 +46,36 @@ import gtk
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gui.utils import open_file_with_default_application
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import MediaModel
|
||||
import PageView
|
||||
import DisplayModels
|
||||
import ThumbNails
|
||||
import const
|
||||
import constfunc
|
||||
import config
|
||||
import Config
|
||||
import Utils
|
||||
import Bookmarks
|
||||
import gen.mime
|
||||
import Mime
|
||||
import gen.lib
|
||||
from gui.editors import EditMedia, DeleteMediaQuery
|
||||
from QuestionDialog import ErrorDialog
|
||||
from Editors import EditMedia, DeleteMediaQuery
|
||||
import Errors
|
||||
from Filters.SideBar import MediaSidebarFilter
|
||||
from DdTargets import DdTargets
|
||||
from gen.plug import CATEGORY_QR_MEDIA
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# MediaView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class MediaView(ListView):
|
||||
class MediaView(PageView.ListView):
|
||||
"""
|
||||
Provide the Media View interface on the GRAMPS main window. This allows
|
||||
people to manage all media items in their database. This is very similar
|
||||
to the other list based views, with the exception that it also has a
|
||||
to the other list based views, with the exeception that it also has a
|
||||
thumbnail image at the top of the view that must be updated when the
|
||||
selection changes or when the selected media object changes.
|
||||
"""
|
||||
COL_TITLE = 0
|
||||
COL_ID = 1
|
||||
COL_TYPE = 2
|
||||
COL_PATH = 3
|
||||
COL_CHAN = 4
|
||||
COL_DATE = 5
|
||||
#name of the columns
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('Title'),
|
||||
_('ID'),
|
||||
@@ -92,24 +84,15 @@ class MediaView(ListView):
|
||||
_('Last Changed'),
|
||||
_('Date'),
|
||||
]
|
||||
# default setting with visible columns, order of the col, and their size
|
||||
CONFIGSETTINGS = (
|
||||
('columns.visible', [COL_TITLE, COL_ID, COL_TYPE, COL_PATH,
|
||||
COL_DATE]),
|
||||
('columns.rank', [COL_TITLE, COL_ID, COL_TYPE, COL_PATH,
|
||||
COL_DATE, COL_CHAN]),
|
||||
('columns.size', [200, 75, 100, 200, 150, 150])
|
||||
)
|
||||
|
||||
ADD_MSG = _("Add a new media object")
|
||||
EDIT_MSG = _("Edit the selected media object")
|
||||
DEL_MSG = _("Delete the selected media object")
|
||||
FILTER_TYPE = 'MediaObject'
|
||||
QR_CATEGORY = CATEGORY_QR_MEDIA
|
||||
|
||||
_DND_TYPE = DdTargets.URI_LIST
|
||||
|
||||
def __init__(self, dbstate, uistate, nav_group=0):
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'media-add' : self.row_add,
|
||||
@@ -118,13 +101,12 @@ class MediaView(ListView):
|
||||
'media-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
PageView.ListView.__init__(
|
||||
self, _('Media'), dbstate, uistate,
|
||||
MediaView.COLUMN_NAMES, len(MediaView.COLUMN_NAMES),
|
||||
MediaModel,
|
||||
DisplayModels.MediaModel,
|
||||
signal_map, dbstate.db.get_media_bookmarks(),
|
||||
Bookmarks.MediaBookmarks, nav_group,
|
||||
filter_class=MediaSidebarFilter,
|
||||
Bookmarks.MediaBookmarks, filter_class=MediaSidebarFilter,
|
||||
multiple=True)
|
||||
|
||||
self.func_list = {
|
||||
@@ -132,36 +114,31 @@ class MediaView(ListView):
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def navigation_type(self):
|
||||
return 'Media'
|
||||
Config.client.notify_add("/apps/gramps/interface/filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def _set_dnd(self):
|
||||
"""
|
||||
Set up drag-n-drop. The source and destination are set by calling .target()
|
||||
Set up drag-n-drop. The source and destionation are set by calling .target()
|
||||
on the _DND_TYPE. Obviously, this means that there must be a _DND_TYPE
|
||||
variable defined that points to an entry in DdTargets.
|
||||
"""
|
||||
|
||||
dnd_types = [ self._DND_TYPE.target() ]
|
||||
|
||||
self.list.drag_dest_set(gtk.DEST_DEFAULT_MOTION|gtk.DEST_DEFAULT_DROP,
|
||||
dnd_types,
|
||||
gtk.gdk.ACTION_MOVE|gtk.gdk.ACTION_COPY)
|
||||
self.list.drag_dest_set(gtk.DEST_DEFAULT_ALL, dnd_types,
|
||||
gtk.gdk.ACTION_COPY)
|
||||
self.list.drag_source_set(gtk.gdk.BUTTON1_MASK,
|
||||
[self._DND_TYPE.target()],
|
||||
gtk.gdk.ACTION_COPY)
|
||||
#connected in listview already
|
||||
#self.list.connect('drag_data_get', self.drag_data_get)
|
||||
self.list.connect('drag_data_get', self.drag_data_get)
|
||||
self.list.connect('drag_data_received', self.drag_data_received)
|
||||
|
||||
def drag_data_get(self, widget, context, sel_data, info, time):
|
||||
"""
|
||||
Provide the drag_data_get function, which passes a tuple consisting of:
|
||||
|
||||
1) Drag type defined by the .drag_type field specified by the value
|
||||
1) Drag type defined by the .drag_type field specfied by the value
|
||||
assigned to _DND_TYPE
|
||||
2) The id value of this object, used for the purpose of determining
|
||||
the source of the object. If the source of the object is the same
|
||||
@@ -196,36 +173,28 @@ class MediaView(ListView):
|
||||
|
||||
If the selection data is define, extract the value from sel_data.data,
|
||||
and decide if this is a move or a reorder.
|
||||
The only data we accept on mediaview is dropping a file, so URI_LIST.
|
||||
We assume this is what we obtain
|
||||
"""
|
||||
if not sel_data:
|
||||
return
|
||||
#modern file managers provide URI_LIST. For Windows split sel_data.data
|
||||
if constfunc.win():
|
||||
files = sel_data.data.split('\n')
|
||||
else:
|
||||
files = sel_data.get_uris()
|
||||
for file in files:
|
||||
clean_string = Utils.fix_encoding(
|
||||
file.replace('\0',' ').replace("\r", " ").strip())
|
||||
protocol, site, mfile, j, k, l = urlparse.urlparse(clean_string)
|
||||
if protocol == "file":
|
||||
name = unicode(urllib.url2pathname(
|
||||
mfile.encode(sys.getfilesystemencoding())))
|
||||
mime = gen.mime.get_type(name)
|
||||
if not gen.mime.is_valid_type(mime):
|
||||
return
|
||||
photo = gen.lib.MediaObject()
|
||||
photo.set_path(name)
|
||||
photo.set_mime_type(mime)
|
||||
basename = os.path.basename(name)
|
||||
(root, ext) = os.path.splitext(basename)
|
||||
photo.set_description(root)
|
||||
trans = self.dbstate.db.transaction_begin()
|
||||
self.dbstate.db.add_object(photo, trans)
|
||||
self.dbstate.db.transaction_commit(trans,
|
||||
_("Drag Media Object"))
|
||||
if sel_data and sel_data.data:
|
||||
cleaned_string = sel_data.data.replace('\0', ' ')
|
||||
cleaned_string = cleaned_string.replace("\r", " ").strip()
|
||||
data_list = Utils.fix_encoding(cleaned_string).split('\n')
|
||||
for d in [item.strip() for item in data_list]:
|
||||
protocol, site, mfile, j, k, l = urlparse.urlparse(d)
|
||||
if protocol == "file":
|
||||
name = Utils.fix_encoding(mfile)
|
||||
mime = Mime.get_type(name)
|
||||
if not Mime.is_valid_type(mime):
|
||||
return
|
||||
photo = gen.lib.MediaObject()
|
||||
photo.set_path(name)
|
||||
photo.set_mime_type(mime)
|
||||
basename = os.path.basename(name)
|
||||
(root, ext) = os.path.splitext(basename)
|
||||
photo.set_description(root)
|
||||
trans = self.dbstate.db.transaction_begin()
|
||||
self.dbstate.db.add_object(photo, trans)
|
||||
self.dbstate.db.transaction_commit(trans,
|
||||
_("Drag Media Object"))
|
||||
widget.emit_stop_by_name('drag_data_received')
|
||||
|
||||
def get_bookmarks(self):
|
||||
@@ -240,20 +209,15 @@ class MediaView(ListView):
|
||||
sure that the common List View actions are defined as well, so we
|
||||
call the parent function.
|
||||
"""
|
||||
ListView.define_actions(self)
|
||||
PageView.ListView.define_actions(self)
|
||||
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor)
|
||||
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('QuickReport', None, _("Quick View"), None, None, None)
|
||||
self._add_action('Dummy', None, ' ', None, None, self.dummy_report)
|
||||
|
||||
def view_media(self, obj):
|
||||
"""
|
||||
@@ -262,18 +226,33 @@ class MediaView(ListView):
|
||||
for handle in self.selected_handles():
|
||||
ref_obj = self.dbstate.db.get_object_from_handle(handle)
|
||||
mpath = Utils.media_path_full(self.dbstate.db, ref_obj.get_path())
|
||||
open_file_with_default_application(mpath)
|
||||
Utils.open_file_with_default_application(mpath)
|
||||
|
||||
def open_containing_folder(self, obj):
|
||||
def _column_editor(self, obj):
|
||||
"""
|
||||
Launch external viewers for the selected objects.
|
||||
Start the column editor dialog
|
||||
"""
|
||||
for handle in self.selected_handles():
|
||||
ref_obj = self.dbstate.db.get_object_from_handle(handle)
|
||||
mpath = Utils.media_path_full(self.dbstate.db, ref_obj.get_path())
|
||||
if mpath:
|
||||
mfolder, mfile = os.path.split(mpath)
|
||||
open_file_with_default_application(mfolder)
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Media Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_media_column_order(),
|
||||
MediaView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def set_column_order(self, clist):
|
||||
"""
|
||||
Saves the column order to the database
|
||||
"""
|
||||
self.dbstate.db.set_media_column_order(clist)
|
||||
self.build_columns()
|
||||
|
||||
def column_order(self):
|
||||
"""
|
||||
Get the column order from the database
|
||||
"""
|
||||
return self.dbstate.db.get_media_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
@@ -285,7 +264,7 @@ class MediaView(ListView):
|
||||
"""
|
||||
Builds the View from GTK components
|
||||
"""
|
||||
base = ListView.build_widget(self)
|
||||
base = PageView.ListView.build_widget(self)
|
||||
vbox = gtk.VBox()
|
||||
vbox.set_border_width(0)
|
||||
vbox.set_spacing(4)
|
||||
@@ -321,7 +300,7 @@ class MediaView(ListView):
|
||||
handle the normal operation, then call row_change to make sure that
|
||||
the thumbnail is updated properly if needed.
|
||||
"""
|
||||
ListView.row_update(self, obj)
|
||||
PageView.ListView.row_update(self, obj)
|
||||
if self.active:
|
||||
self.row_change(obj)
|
||||
|
||||
@@ -338,7 +317,7 @@ class MediaView(ListView):
|
||||
pix = ThumbNails.get_thumbnail_image(
|
||||
Utils.media_path_full(self.dbstate.db, obj.get_path()))
|
||||
self.image.set_from_pixbuf(pix)
|
||||
|
||||
|
||||
def ui_definition(self):
|
||||
"""
|
||||
Return the UIManager XML description of the menus
|
||||
@@ -356,6 +335,7 @@ class MediaView(ListView):
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
@@ -364,19 +344,8 @@ class MediaView(ListView):
|
||||
<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"/>
|
||||
@@ -386,29 +355,13 @@ class MediaView(ListView):
|
||||
<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="OpenMedia"/>
|
||||
<menuitem action="Remove"/>
|
||||
<separator/>
|
||||
<menu name="QuickReport" action="QuickReport">
|
||||
<menuitem action="Dummy"/>
|
||||
</menu>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def dummy_report(self, obj):
|
||||
""" For the xml UI definition of popup to work, the submenu
|
||||
Quick Report must have an entry in the xml
|
||||
As this submenu will be dynamically built, we offer a dummy action
|
||||
"""
|
||||
pass
|
||||
|
||||
def add(self, obj):
|
||||
"""Add a new media object to the media list"""
|
||||
try:
|
||||
@@ -21,16 +21,8 @@
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Note View.
|
||||
Place View.
|
||||
"""
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
import logging
|
||||
_LOG = logging.getLogger(".plugins.noteview")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -44,54 +36,46 @@ import gtk
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import NoteModel
|
||||
import PageView
|
||||
import DisplayModels
|
||||
import Utils
|
||||
import Errors
|
||||
import Bookmarks
|
||||
import config
|
||||
import Config
|
||||
import ColumnOrder
|
||||
from gen.lib import Note
|
||||
from DdTargets import DdTargets
|
||||
from Filters.SideBar import NoteSidebarFilter
|
||||
from gui.editors import EditNote, DeleteNoteQuery
|
||||
from gen.plug import CATEGORY_QR_NOTE
|
||||
from Editors import EditNote, DeleteNoteQuery
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# NoteView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class NoteView(ListView):
|
||||
"""
|
||||
Noteview, a normal flat listview for the notes
|
||||
"""
|
||||
COL_PREVIEW = 0
|
||||
COL_ID = 1
|
||||
COL_TYPE = 2
|
||||
COL_MARKER = 3
|
||||
COL_CHAN = 4
|
||||
class NoteView(PageView.ListView):
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('Preview'),
|
||||
_('ID'),
|
||||
_('Type'),
|
||||
_('Marker'),
|
||||
_('Last Changed')
|
||||
]
|
||||
# default setting with visible columns, order of the col, and their size
|
||||
CONFIGSETTINGS = (
|
||||
('columns.visible', [COL_PREVIEW, COL_ID, COL_TYPE, COL_MARKER]),
|
||||
('columns.rank', [COL_PREVIEW, COL_ID, COL_TYPE, COL_MARKER,
|
||||
COL_CHAN]),
|
||||
('columns.size', [350, 75, 100, 100, 100]))
|
||||
|
||||
ADD_MSG = _("Add a new note")
|
||||
EDIT_MSG = _("Edit the selected note")
|
||||
DEL_MSG = _("Delete the selected note")
|
||||
FILTER_TYPE = "Note"
|
||||
QR_CATEGORY = CATEGORY_QR_NOTE
|
||||
|
||||
def __init__(self, dbstate, uistate, nav_group=0):
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'note-add' : self.row_add,
|
||||
@@ -105,19 +89,16 @@ class NoteView(ListView):
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
PageView.ListView.__init__(
|
||||
self, _('Notes'), dbstate, uistate, NoteView.COLUMN_NAMES,
|
||||
len(NoteView.COLUMN_NAMES), NoteModel, signal_map,
|
||||
len(NoteView.COLUMN_NAMES), DisplayModels.NoteModel, signal_map,
|
||||
dbstate.db.get_note_bookmarks(),
|
||||
Bookmarks.NoteBookmarks, nav_group,
|
||||
Bookmarks.NoteBookmarks,
|
||||
filter_class=NoteSidebarFilter,
|
||||
multiple=True)
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def navigation_type(self):
|
||||
return 'Note'
|
||||
Config.client.notify_add("/apps/gramps/interface/filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def get_bookmarks(self):
|
||||
"""
|
||||
@@ -131,6 +112,12 @@ class NoteView(ListView):
|
||||
"""
|
||||
return DdTargets.NOTE_LINK
|
||||
|
||||
def column_order(self):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
return self.dbstate.db.get_note_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
Use the gramps-event stock icon
|
||||
@@ -154,27 +141,17 @@ class NoteView(ListView):
|
||||
<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"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<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"/>
|
||||
@@ -182,32 +159,18 @@ class NoteView(ListView):
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
<separator/>
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<separator/>
|
||||
<menu name="QuickReport" action="QuickReport">
|
||||
<menuitem action="Dummy"/>
|
||||
</menu>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def dummy_report(self, obj):
|
||||
""" For the xml UI definition of popup to work, the submenu
|
||||
Quick Report must have an entry in the xml
|
||||
As this submenu will be dynamically built, we offer a dummy action
|
||||
"""
|
||||
pass
|
||||
|
||||
def define_actions(self):
|
||||
ListView.define_actions(self)
|
||||
PageView.ListView.define_actions(self)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor)
|
||||
self._add_action('FilterEdit', None, _('Note Filter Editor'),
|
||||
callback=self.filter_editor,)
|
||||
self._add_action('QuickReport', None, _("Quick View"), None, None, None)
|
||||
self._add_action('Dummy', None, ' ', None, None, self.dummy_report)
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
obj = self.dbstate.db.get_note_from_gramps_id(gid)
|
||||
@@ -216,6 +179,21 @@ class NoteView(ListView):
|
||||
else:
|
||||
return None
|
||||
|
||||
def _column_editor(self, obj):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Note Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_note_column_order(),
|
||||
NoteView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def set_column_order(self, clist):
|
||||
self.dbstate.db.set_note_column_order(clist)
|
||||
self.build_columns()
|
||||
|
||||
def add(self, obj):
|
||||
try:
|
||||
EditNote(self.dbstate, self.uistate, [], Note())
|
||||
@@ -27,11 +27,10 @@
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import sgettext as _
|
||||
from gen.ggettext import ngettext
|
||||
from TransUtils import sgettext as _
|
||||
from gettext import ngettext
|
||||
from cgi import escape
|
||||
import math
|
||||
import sys
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -52,21 +51,18 @@ except:
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gui.views.navigationview import NavigationView
|
||||
from gen.display.name import displayer as name_displayer
|
||||
from Utils import (media_path_full, probably_alive, find_children,
|
||||
find_parents, find_witnessed_people)
|
||||
from libformatting import FormattingHelper
|
||||
import PageView
|
||||
from BasicUtils import name_displayer
|
||||
import Utils
|
||||
import DateHandler
|
||||
import ThumbNails
|
||||
import Errors
|
||||
from gui.editors import EditPerson, EditFamily
|
||||
from ReportBase import ReportUtils
|
||||
from Editors import EditPerson, EditFamily
|
||||
from DdTargets import DdTargets
|
||||
import cPickle as pickle
|
||||
import config
|
||||
import Config
|
||||
from QuestionDialog import RunDatabaseRepair, ErrorDialog
|
||||
import Bookmarks
|
||||
import const
|
||||
from gui.filtereditor import FilterEditor
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -170,11 +166,8 @@ class PersonBoxWidget_cairo( gtk.DrawingArea, _PersonWidget_base):
|
||||
self.bgcolor = (211/256.0, 215/256.0, 207/256.0)
|
||||
self.bordercolor = (0,0,0)
|
||||
self.image = image
|
||||
image1 = image
|
||||
if isinstance(image1, unicode):
|
||||
image1 = image.encode(sys.getfilesystemencoding())
|
||||
try:
|
||||
self.img_surf = cairo.ImageSurface.create_from_png(image1)
|
||||
self.img_surf = cairo.ImageSurface.create_from_png(image)
|
||||
except:
|
||||
self.image = False
|
||||
self.connect("enter-notify-event", self.on_enter_cb) # enable mouse-over
|
||||
@@ -230,7 +223,7 @@ class PersonBoxWidget_cairo( gtk.DrawingArea, _PersonWidget_base):
|
||||
self.context.translate(3,3)
|
||||
self.context.new_path()
|
||||
self.context.append_path( path)
|
||||
self.context.set_source_rgba(*(self.bordercolor[:3] + (0.4,)))
|
||||
self.context.set_source_rgba( self.bordercolor[0], self.bordercolor[1], self.bordercolor[2],0.4)
|
||||
self.context.fill_preserve()
|
||||
self.context.set_line_width(0)
|
||||
self.context.stroke()
|
||||
@@ -242,7 +235,7 @@ class PersonBoxWidget_cairo( gtk.DrawingArea, _PersonWidget_base):
|
||||
|
||||
# background
|
||||
self.context.append_path( path)
|
||||
self.context.set_source_rgb(*self.bgcolor[:3])
|
||||
self.context.set_source_rgb( self.bgcolor[0], self.bgcolor[1], self.bgcolor[2])
|
||||
self.context.fill_preserve()
|
||||
self.context.stroke()
|
||||
|
||||
@@ -269,7 +262,7 @@ class PersonBoxWidget_cairo( gtk.DrawingArea, _PersonWidget_base):
|
||||
else:
|
||||
self.context.set_line_width(2)
|
||||
self.context.append_path( path)
|
||||
self.context.set_source_rgb(*self.bordercolor[:3])
|
||||
self.context.set_source_rgb( self.bordercolor[0], self.bordercolor[1], self.bordercolor[2])
|
||||
self.context.stroke()
|
||||
|
||||
|
||||
@@ -364,39 +357,131 @@ class PersonBoxWidget( gtk.DrawingArea, _PersonWidget_base):
|
||||
else:
|
||||
self.window.draw_rectangle(self.border_gc, False, 0, 0, alloc.width-4, alloc.height-4)
|
||||
|
||||
class FormattingHelper(object):
|
||||
def __init__(self,dbstate):
|
||||
self.dbstate = dbstate
|
||||
self._text_cache = {}
|
||||
self._markup_cache = {}
|
||||
|
||||
def format_relation( self, family, line_count):
|
||||
text = ""
|
||||
for event_ref in family.get_event_ref_list():
|
||||
event = self.dbstate.db.get_event_from_handle(event_ref.ref)
|
||||
if event and event.get_type() == gen.lib.EventType.MARRIAGE and \
|
||||
(event_ref.get_role() == gen.lib.EventRoleType.FAMILY or
|
||||
event_ref.get_role() == gen.lib.EventRoleType.PRIMARY ):
|
||||
if line_count < 3:
|
||||
return DateHandler.get_date(event)
|
||||
name = str(event.get_type())
|
||||
text += name
|
||||
text += "\n"
|
||||
text += DateHandler.get_date(event)
|
||||
text += "\n"
|
||||
text += self.get_place_name(event.get_place_handle())
|
||||
if line_count < 5:
|
||||
return text;
|
||||
break
|
||||
if not text:
|
||||
text = str(family.get_relationship())
|
||||
return text
|
||||
|
||||
def get_place_name( self, place_handle):
|
||||
text = ""
|
||||
place = self.dbstate.db.get_place_from_handle(place_handle)
|
||||
if place:
|
||||
place_title = self.dbstate.db.get_place_from_handle(place_handle).get_title()
|
||||
if place_title != "":
|
||||
if len(place_title) > 25:
|
||||
text = place_title[:24]+"..."
|
||||
else:
|
||||
text = place_title
|
||||
return text
|
||||
|
||||
def format_person( self, person, line_count, use_markup=False):
|
||||
if not person:
|
||||
return ""
|
||||
if use_markup:
|
||||
if person.handle in self._markup_cache:
|
||||
if line_count in self._markup_cache[person.handle]:
|
||||
return self._markup_cache[person.handle][line_count]
|
||||
name = escape(name_displayer.display(person))
|
||||
else:
|
||||
if person.handle in self._text_cache:
|
||||
if line_count in self._text_cache[person.handle]:
|
||||
return self._text_cache[person.handle][line_count]
|
||||
name = name_displayer.display(person)
|
||||
text = name
|
||||
if line_count >= 3:
|
||||
birth = ReportUtils.get_birth_or_fallback(self.dbstate.db, person)
|
||||
if birth and use_markup and birth.get_type() != gen.lib.EventType.BIRTH:
|
||||
bdate = "<i>%s</i>" % escape(DateHandler.get_date(birth))
|
||||
bplace = "<i>%s</i>" % escape(self.get_place_name(birth.get_place_handle()))
|
||||
elif birth and use_markup:
|
||||
bdate = escape(DateHandler.get_date(birth))
|
||||
bplace = escape(self.get_place_name(birth.get_place_handle()))
|
||||
elif birth:
|
||||
bdate = DateHandler.get_date(birth)
|
||||
bplace = self.get_place_name(birth.get_place_handle())
|
||||
else:
|
||||
bdate = ""
|
||||
bplace = ""
|
||||
death = ReportUtils.get_death_or_fallback(self.dbstate.db, person)
|
||||
if death and use_markup and death.get_type() != gen.lib.EventType.DEATH:
|
||||
ddate = "<i>%s</i>" % escape(DateHandler.get_date(death))
|
||||
dplace = "<i>%s</i>" % escape(self.get_place_name(death.get_place_handle()))
|
||||
elif death and use_markup:
|
||||
ddate = escape(DateHandler.get_date(death))
|
||||
dplace = escape(self.get_place_name(death.get_place_handle()))
|
||||
elif death:
|
||||
ddate = DateHandler.get_date(death)
|
||||
dplace = self.get_place_name(death.get_place_handle())
|
||||
else:
|
||||
ddate = ""
|
||||
dplace = ""
|
||||
|
||||
if line_count < 5:
|
||||
text = "%s\n* %s\n+ %s" % (name,bdate,ddate)
|
||||
else:
|
||||
text = "%s\n* %s\n %s\n+ %s\n %s" % (name,bdate,bplace,ddate,dplace)
|
||||
if use_markup:
|
||||
if not person.handle in self._markup_cache:
|
||||
self._markup_cache[person.handle] = {}
|
||||
self._markup_cache[person.handle][line_count] = text
|
||||
else:
|
||||
if not person.handle in self._text_cache:
|
||||
self._text_cache[person.handle] = {}
|
||||
self._text_cache[person.handle][line_count] = text
|
||||
return text
|
||||
|
||||
def clear_cache( self):
|
||||
self._text_cache = {}
|
||||
self._markup_cache = {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# PedigreeView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class PedigreeView(NavigationView):
|
||||
class PedigreeView(PageView.PersonNavView):
|
||||
|
||||
def __init__(self, dbstate, uistate, nav_group=0):
|
||||
NavigationView.__init__(self, _('Pedigree'), dbstate, uistate,
|
||||
dbstate.db.get_bookmarks(),
|
||||
Bookmarks.PersonBookmarks,
|
||||
nav_group)
|
||||
def __init__(self,dbstate,uistate):
|
||||
PageView.PersonNavView.__init__(self, _('Pedigree'), dbstate, uistate)
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
}
|
||||
|
||||
self.dbstate = dbstate
|
||||
self.dbstate.connect('database-changed',self.change_db)
|
||||
uistate.connect('nameformat-changed', self.person_rebuild)
|
||||
|
||||
#self.dbstate.connect('active-changed',self.goto_active_person)
|
||||
self.force_size = config.get('interface.pedview-tree-size') # Automatic resize
|
||||
self.tree_style = config.get('interface.pedview-layout') # Nice tree
|
||||
self.show_images = config.get('interface.pedview-show-images') # Show photos of persons
|
||||
self.show_marriage_data = config.get('interface.pedview-show-marriage') # Hide marriage data by default
|
||||
self.format_helper = FormattingHelper(self.dbstate)
|
||||
self.force_size = Config.get(Config.PEDVIEW_TREESIZE) # Automatic resize
|
||||
self.tree_style = Config.get(Config.PEDVIEW_LAYOUT) # Nice tree
|
||||
self.show_images = Config.get(Config.PEDVIEW_SHOW_IMAGES) # Show photos of persons
|
||||
self.show_marriage_data = Config.get(Config.PEDVIEW_SHOW_MARRIAGE) # Hide marriage data by default
|
||||
self.format_helper = FormattingHelper( self.dbstate)
|
||||
|
||||
def change_page(self):
|
||||
NavigationView.change_page(self)
|
||||
self.uistate.clear_filter_results()
|
||||
if self.dirty:
|
||||
self.rebuild_trees(self.get_active())
|
||||
self.dirty = False
|
||||
|
||||
def init_parent_signals_cb(self, widget, event):
|
||||
# required to properly bootstrap the signal handlers.
|
||||
@@ -420,14 +505,21 @@ class PedigreeView(NavigationView):
|
||||
# for PyGtk < 2.4
|
||||
self.notebook.append_page(frame,gtk.Label(""))
|
||||
|
||||
def set_active(self):
|
||||
PageView.PersonNavView.set_active(self)
|
||||
self.key_active_changed = self.dbstate.connect('active-changed',
|
||||
self.goto_active_person)
|
||||
self.build_tree()
|
||||
|
||||
def set_inactive(self):
|
||||
PageView.PersonNavView.set_inactive(self)
|
||||
self.dbstate.disconnect(self.key_active_changed)
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
The category stock icon
|
||||
"""
|
||||
return 'gramps-pedigree'
|
||||
|
||||
def get_viewtype_stock(self):
|
||||
"""Type of view in category
|
||||
Return the name of the stock icon to use for the display.
|
||||
This assumes that this icon has already been registered with
|
||||
GNOME as a stock icon.
|
||||
"""
|
||||
return 'gramps-pedigree'
|
||||
|
||||
@@ -509,17 +601,7 @@ class PedigreeView(NavigationView):
|
||||
at the beginning of the history.
|
||||
"""
|
||||
|
||||
NavigationView.define_actions(self)
|
||||
|
||||
self._add_action('FilterEdit', None, _('Person Filter Editor'),
|
||||
callback=self.filter_editor)
|
||||
|
||||
def filter_editor(self, obj):
|
||||
try:
|
||||
FilterEditor('Person', const.CUSTOM_FILTERS,
|
||||
self.dbstate, self.uistate)
|
||||
except Errors.WindowActiveError:
|
||||
return
|
||||
PageView.PersonNavView.define_actions(self)
|
||||
|
||||
def build_tree(self):
|
||||
"""
|
||||
@@ -528,7 +610,11 @@ class PedigreeView(NavigationView):
|
||||
information.
|
||||
"""
|
||||
try:
|
||||
self.rebuild_trees(self.get_active())
|
||||
active = self.dbstate.get_active_person()
|
||||
if active:
|
||||
self.rebuild_trees(active.handle)
|
||||
else:
|
||||
self.rebuild_trees(None)
|
||||
except AttributeError, msg:
|
||||
RunDatabaseRepair(str(msg))
|
||||
|
||||
@@ -553,17 +639,11 @@ class PedigreeView(NavigationView):
|
||||
self.bookmarks.redraw()
|
||||
self.build_tree()
|
||||
|
||||
def navigation_type(self):
|
||||
return 'Person'
|
||||
|
||||
def goto_handle(self, handle=None):
|
||||
def goto_active_person(self, handle=None):
|
||||
self.dirty = True
|
||||
if handle:
|
||||
person = self.dbstate.db.get_person_from_handle(handle)
|
||||
if person:
|
||||
self.rebuild_trees(handle)
|
||||
else:
|
||||
self.rebuild_trees(None)
|
||||
self.rebuild_trees(handle)
|
||||
self.handle_history(handle)
|
||||
else:
|
||||
self.rebuild_trees(None)
|
||||
self.uistate.modify_statusbar(self.dbstate)
|
||||
@@ -577,8 +657,10 @@ class PedigreeView(NavigationView):
|
||||
def person_rebuild(self,dummy=None):
|
||||
self.format_helper.clear_cache()
|
||||
self.dirty = True
|
||||
if self.active:
|
||||
self.rebuild_trees(self.get_active())
|
||||
if self.dbstate.active:
|
||||
self.rebuild_trees(self.dbstate.active.handle)
|
||||
else:
|
||||
self.rebuild_trees(None)
|
||||
|
||||
def request_resize(self):
|
||||
self.size_request_cb(self.notebook.parent,None,None)
|
||||
@@ -596,75 +678,14 @@ class PedigreeView(NavigationView):
|
||||
else:
|
||||
self.notebook.set_current_page(self.force_size-2)
|
||||
|
||||
def rebuild_trees(self, person_handle):
|
||||
|
||||
def rebuild_trees(self,person_handle):
|
||||
person = None
|
||||
if person_handle:
|
||||
person = self.dbstate.db.get_person_from_handle(person_handle)
|
||||
person = self.dbstate.db.get_person_from_handle( person_handle)
|
||||
|
||||
self.dirty = False
|
||||
|
||||
if self.tree_style not in (0, 1):
|
||||
self.tree_style = 0
|
||||
|
||||
if self.tree_style == 0:
|
||||
pos_2 =(((0,0,1,3),(1,0,3),(2,1,1,1)),
|
||||
((2,0,1,1),None,None),
|
||||
((2,2,1,1),None,None))
|
||||
pos_3 =(((0,2,1,3),(1,1,5),(2,3,1,1)),
|
||||
((2,0,1,3),(3,0,3),(4,1,1,1)),
|
||||
((2,4,1,3),(3,4,3),(4,5,1,1)),
|
||||
((4,0,1,1),None,None),
|
||||
((4,2,1,1),None,None),
|
||||
((4,4,1,1),None,None),
|
||||
((4,6,1,1),None,None))
|
||||
pos_4 =(((0,6,1,3),(1,3,9),(2,5,1,5)),
|
||||
((2,2,1,3),(3,1,5),(4,3,1,1)),
|
||||
((2,10,1,3),(3,9,5),(4,11,1,1)),
|
||||
((4,0,1,3),(5,0,3),(6,1,1,1)),
|
||||
((4,4,1,3),(5,4,3),(6,5,1,1)),
|
||||
((4,8,1,3),(5,8,3),(6,9,1,1)),
|
||||
((4,12,1,3),(5,12,3),(6,13,1,1)),
|
||||
((6,0,1,1),None,None),
|
||||
((6,2,1,1),None,None),
|
||||
((6,4,1,1),None,None),
|
||||
((6,6,1,1),None,None),
|
||||
((6,8,1,1),None,None),
|
||||
((6,10,1,1),None,None),
|
||||
((6,12,1,1),None,None),
|
||||
((6,14,1,1),None,None))
|
||||
pos_5 =(((0,14,1,3),(1,7,17),(2,13,1,5)),
|
||||
((2,6,1,3),(3,3,9),(4,5,1,5)),
|
||||
((2,22,1,3),(3,19,9),(4,21,1,5)),
|
||||
((4,2,1,3),(5,1,5),(6,3,1,1)),
|
||||
((4,10,1,3),(5,9,5),(6,11,1,1)),
|
||||
((4,18,1,3),(5,17,5),(6,19,1,1)),
|
||||
((4,26,1,3),(5,25,5),(6,27,1,1)),
|
||||
((6,0,1,3),(7,0,3),(8,1,1,1)),
|
||||
((6,4,1,3),(7,4,3),(8,5,1,1)),
|
||||
((6,8,1,3),(7,8,3),(8,9,1,1)),
|
||||
((6,12,1,3),(7,12,3),(8,13,1,1)),
|
||||
((6,16,1,3),(7,16,3),(8,17,1,1)),
|
||||
((6,20,1,3),(7,20,3),(8,21,1,1)),
|
||||
((6,24,1,3),(7,24,3),(8,25,1,1)),
|
||||
((6,28,1,3),(7,28,3),(8,29,1,1)),
|
||||
((8,0,1,1),None,None),
|
||||
((8,2,1,1),None,None),
|
||||
((8,4,1,1),None,None),
|
||||
((8,6,1,1),None,None),
|
||||
((8,8,1,1),None,None),
|
||||
((8,10,1,1),None,None),
|
||||
((8,12,1,1),None,None),
|
||||
((8,14,1,1),None,None),
|
||||
((8,16,1,1),None,None),
|
||||
((8,18,1,1),None,None),
|
||||
((8,20,1,1),None,None),
|
||||
((8,22,1,1),None,None),
|
||||
((8,24,1,1),None,None),
|
||||
((8,26,1,1),None,None),
|
||||
((8,28,1,1),None,None),
|
||||
((8,30,1,1),None,None))
|
||||
elif self.tree_style == 1:
|
||||
if self.tree_style == 1:
|
||||
# format of the definition is:
|
||||
# ((each box of the pedigree has a node here),
|
||||
# ((person data), (connection line), (marriage data)),
|
||||
@@ -726,6 +747,64 @@ class PedigreeView(NavigationView):
|
||||
((8,26,3,1),None,None),
|
||||
((8,28,3,1),None,None),
|
||||
((8,30,3,1),None,None),)
|
||||
else:
|
||||
#elif self.tree_style == 0:
|
||||
pos_2 =(((0,0,1,3),(1,0,3),(2,1,1,1)),
|
||||
((2,0,1,1),None,None),
|
||||
((2,2,1,1),None,None))
|
||||
pos_3 =(((0,2,1,3),(1,1,5),(2,3,1,1)),
|
||||
((2,0,1,3),(3,0,3),(4,1,1,1)),
|
||||
((2,4,1,3),(3,4,3),(4,5,1,1)),
|
||||
((4,0,1,1),None,None),
|
||||
((4,2,1,1),None,None),
|
||||
((4,4,1,1),None,None),
|
||||
((4,6,1,1),None,None))
|
||||
pos_4 =(((0,6,1,3),(1,3,9),(2,5,1,5)),
|
||||
((2,2,1,3),(3,1,5),(4,3,1,1)),
|
||||
((2,10,1,3),(3,9,5),(4,11,1,1)),
|
||||
((4,0,1,3),(5,0,3),(6,1,1,1)),
|
||||
((4,4,1,3),(5,4,3),(6,5,1,1)),
|
||||
((4,8,1,3),(5,8,3),(6,9,1,1)),
|
||||
((4,12,1,3),(5,12,3),(6,13,1,1)),
|
||||
((6,0,1,1),None,None),
|
||||
((6,2,1,1),None,None),
|
||||
((6,4,1,1),None,None),
|
||||
((6,6,1,1),None,None),
|
||||
((6,8,1,1),None,None),
|
||||
((6,10,1,1),None,None),
|
||||
((6,12,1,1),None,None),
|
||||
((6,14,1,1),None,None))
|
||||
pos_5 =(((0,14,1,3),(1,7,17),(2,13,1,5)),
|
||||
((2,6,1,3),(3,3,9),(4,5,1,5)),
|
||||
((2,22,1,3),(3,19,9),(4,21,1,5)),
|
||||
((4,2,1,3),(5,1,5),(6,3,1,1)),
|
||||
((4,10,1,3),(5,9,5),(6,11,1,1)),
|
||||
((4,18,1,3),(5,17,5),(6,19,1,1)),
|
||||
((4,26,1,3),(5,25,5),(6,27,1,1)),
|
||||
((6,0,1,3),(7,0,3),(8,1,1,1)),
|
||||
((6,4,1,3),(7,4,3),(8,5,1,1)),
|
||||
((6,8,1,3),(7,8,3),(8,9,1,1)),
|
||||
((6,12,1,3),(7,12,3),(8,13,1,1)),
|
||||
((6,16,1,3),(7,16,3),(8,17,1,1)),
|
||||
((6,20,1,3),(7,20,3),(8,21,1,1)),
|
||||
((6,24,1,3),(7,24,3),(8,25,1,1)),
|
||||
((6,28,1,3),(7,28,3),(8,29,1,1)),
|
||||
((8,0,1,1),None,None),
|
||||
((8,2,1,1),None,None),
|
||||
((8,4,1,1),None,None),
|
||||
((8,6,1,1),None,None),
|
||||
((8,8,1,1),None,None),
|
||||
((8,10,1,1),None,None),
|
||||
((8,12,1,1),None,None),
|
||||
((8,14,1,1),None,None),
|
||||
((8,16,1,1),None,None),
|
||||
((8,18,1,1),None,None),
|
||||
((8,20,1,1),None,None),
|
||||
((8,22,1,1),None,None),
|
||||
((8,24,1,1),None,None),
|
||||
((8,26,1,1),None,None),
|
||||
((8,28,1,1),None,None),
|
||||
((8,30,1,1),None,None))
|
||||
|
||||
# Build ancestor tree only one for all different sizes
|
||||
lst = [None]*31
|
||||
@@ -789,7 +868,7 @@ class PedigreeView(NavigationView):
|
||||
mtype = obj.get_mime_type()
|
||||
if mtype and mtype[0:5] == "image":
|
||||
image = ThumbNails.get_thumbnail_path(
|
||||
media_path_full(
|
||||
Utils.media_path_full(
|
||||
self.dbstate.db,
|
||||
obj.get_path()),
|
||||
rectangle=ph.get_rectangle())
|
||||
@@ -909,7 +988,7 @@ class PedigreeView(NavigationView):
|
||||
l.add(gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_IN))
|
||||
if lst[1]:
|
||||
l.connect("clicked",self.on_childmenu_changed,lst[1][0].handle)
|
||||
l.set_tooltip_text(_("Jump to father"))
|
||||
l.set_tooltip_text(("Jump to father"))
|
||||
else:
|
||||
l.set_sensitive(False)
|
||||
ymid = int(math.floor(ymax/4))
|
||||
@@ -918,7 +997,7 @@ class PedigreeView(NavigationView):
|
||||
l.add(gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_IN))
|
||||
if lst[2]:
|
||||
l.connect("clicked",self.on_childmenu_changed,lst[2][0].handle)
|
||||
l.set_tooltip_text(_("Jump to mother"))
|
||||
l.set_tooltip_text(("Jump to mother"))
|
||||
else:
|
||||
l.set_sensitive(False)
|
||||
ymid = int(math.floor(ymax/4*3))
|
||||
@@ -1015,7 +1094,7 @@ class PedigreeView(NavigationView):
|
||||
def home(self, obj):
|
||||
defperson = self.dbstate.db.get_default_person()
|
||||
if defperson:
|
||||
self.change_active(defperson.get_handle())
|
||||
self.dbstate.change_active_person(defperson)
|
||||
|
||||
def edit_person_cb(self, obj,person_handle):
|
||||
person = self.dbstate.db.get_person_from_handle(person_handle)
|
||||
@@ -1105,17 +1184,16 @@ class PedigreeView(NavigationView):
|
||||
def on_show_child_menu(self, obj):
|
||||
"""User clicked button to move to child of active person"""
|
||||
|
||||
person = self.dbstate.db.get_person_from_handle(self.get_active())
|
||||
if person:
|
||||
if self.dbstate.active:
|
||||
# Build and display the menu attached to the left pointing arrow
|
||||
# button. The menu consists of the children of the current root
|
||||
# person of the tree. Attach a child to each menu item.
|
||||
|
||||
childlist = find_children(self.dbstate.db, person)
|
||||
childlist = find_children(self.dbstate.db,self.dbstate.active)
|
||||
if len(childlist) == 1:
|
||||
child = self.dbstate.db.get_person_from_handle(childlist[0])
|
||||
if child:
|
||||
self.change_active(childlist[0])
|
||||
self.dbstate.change_active_person(child)
|
||||
elif len(childlist) > 1:
|
||||
myMenu = gtk.Menu()
|
||||
for child_handle in childlist:
|
||||
@@ -1143,35 +1221,44 @@ class PedigreeView(NavigationView):
|
||||
def on_childmenu_changed(self, obj,person_handle):
|
||||
"""Callback for the pulldown menu selection, changing to the person
|
||||
attached with menu item."""
|
||||
self.change_active(person_handle)
|
||||
self.dbstate.change_active_handle(person_handle)
|
||||
return True
|
||||
|
||||
def change_force_size_cb(self,event,data):
|
||||
if data in [0,2,3,4,5]:
|
||||
config.set('interface.pedview-tree-size',data)
|
||||
Config.set(Config.PEDVIEW_TREESIZE,data)
|
||||
self.force_size = data
|
||||
self.dirty = True
|
||||
self.size_request_cb(self.notebook.parent,None) # switch to matching size
|
||||
|
||||
def change_tree_style_cb(self,event,data):
|
||||
if data in [0,1]:
|
||||
config.set('interface.pedview-layout',data)
|
||||
Config.set(Config.PEDVIEW_LAYOUT,data)
|
||||
if self.tree_style != data:
|
||||
self.dirty = True
|
||||
self.tree_style = data
|
||||
self.rebuild_trees(self.get_active()) # Rebuild using new style
|
||||
if self.dbstate.active:
|
||||
self.rebuild_trees(self.dbstate.active.handle) # Rebuild using new style
|
||||
else:
|
||||
self.rebuild_trees(None)
|
||||
|
||||
def change_show_images_cb(self,event):
|
||||
self.show_images = not self.show_images
|
||||
config.set('interface.pedview-show-images',self.show_images)
|
||||
Config.set(Config.PEDVIEW_SHOW_IMAGES,self.show_images)
|
||||
self.dirty = True
|
||||
self.rebuild_trees(self.get_active()) # Rebuild using new style
|
||||
if self.dbstate.active:
|
||||
self.rebuild_trees(self.dbstate.active.handle) # Rebuild using new style
|
||||
else:
|
||||
self.rebuild_trees(None)
|
||||
|
||||
def change_show_marriage_cb(self,event):
|
||||
self.show_marriage_data = not self.show_marriage_data
|
||||
config.set('interface.pedview-show-marriage', self.show_marriage_data)
|
||||
Config.set(Config.PEDVIEW_SHOW_MARRIAGE,self.show_marriage_data)
|
||||
self.dirty = True
|
||||
self.rebuild_trees(self.get_active()) # Rebuild using new style
|
||||
if self.dbstate.active:
|
||||
self.rebuild_trees(self.dbstate.active.handle) # Rebuild using new style
|
||||
else:
|
||||
self.rebuild_trees(None)
|
||||
|
||||
def find_tree(self,person,index,depth,lst,val=0):
|
||||
"""Recursively build a list of ancestors"""
|
||||
@@ -1180,7 +1267,7 @@ class PedigreeView(NavigationView):
|
||||
return
|
||||
|
||||
try:
|
||||
alive = probably_alive(person, self.dbstate.db)
|
||||
alive = Utils.probably_alive(person, self.dbstate.db)
|
||||
except RuntimeError:
|
||||
ErrorDialog(_('Relationship loop detected'),
|
||||
_('A person was found to be his/her own ancestor.'))
|
||||
@@ -1598,3 +1685,130 @@ class PedigreeView(NavigationView):
|
||||
self.add_settings_to_menu(menu)
|
||||
menu.popup(None,None,None,event.button,event.time)
|
||||
return 1
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Function to return children's list of a person
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def find_children(db,p):
|
||||
"""
|
||||
Return the list of all children's IDs for a person.
|
||||
"""
|
||||
childlist = []
|
||||
for family_handle in p.get_family_handle_list():
|
||||
family = db.get_family_from_handle(family_handle)
|
||||
for child_ref in family.get_child_ref_list():
|
||||
childlist.append(child_ref.ref)
|
||||
return childlist
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Function to return parent's list of a person
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def find_parents(db,p):
|
||||
"""
|
||||
Return the unique list of all parents' IDs for a person.
|
||||
"""
|
||||
parentlist = []
|
||||
for f in p.get_parent_family_handle_list():
|
||||
family = db.get_family_from_handle(f)
|
||||
father_handle = family.get_father_handle()
|
||||
mother_handle = family.get_mother_handle()
|
||||
if father_handle not in parentlist:
|
||||
parentlist.append(father_handle)
|
||||
if mother_handle not in parentlist:
|
||||
parentlist.append(mother_handle)
|
||||
return parentlist
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Function to return persons, that share the same event.
|
||||
# This for example links witnesses to the tree
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def find_witnessed_people(db,p):
|
||||
people = []
|
||||
for event_ref in p.get_event_ref_list():
|
||||
for l in db.find_backlink_handles( event_ref.ref):
|
||||
if l[0] == 'Person' and l[1] != p.get_handle() and l[1] not in people:
|
||||
people.append(l[1])
|
||||
if l[0] == 'Family':
|
||||
fam = db.get_family_from_handle(l[1])
|
||||
if fam:
|
||||
father_handle = fam.get_father_handle()
|
||||
if father_handle and father_handle != p.get_handle() and father_handle not in people:
|
||||
people.append(father_handle)
|
||||
mother_handle = fam.get_mother_handle()
|
||||
if mother_handle and mother_handle != p.get_handle() and mother_handle not in people:
|
||||
people.append(mother_handle)
|
||||
for f in p.get_family_handle_list():
|
||||
family = db.get_family_from_handle(f)
|
||||
for event_ref in family.get_event_ref_list():
|
||||
for l in db.find_backlink_handles( event_ref.ref):
|
||||
if l[0] == 'Person' and l[1] != p.get_handle() and l[1] not in people:
|
||||
people.append(l[1])
|
||||
for pref in p.get_person_ref_list():
|
||||
if pref.ref != p.get_handle and pref.ref not in people:
|
||||
people.append(pref.ref)
|
||||
return people
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Functions to build the text displayed in the details view of a DispBox
|
||||
# aditionally used by PedigreeView to get the largest area covered by a DispBox
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def build_detail_string(db,person):
|
||||
|
||||
detail_text = name_displayer.display(person)
|
||||
|
||||
def format_event(db, label, event):
|
||||
if not event:
|
||||
return u""
|
||||
ed = DateHandler.get_date(event)
|
||||
ep = None
|
||||
place_handle = event.get_place_handle()
|
||||
if place_handle:
|
||||
place_title = db.get_place_from_handle(place_handle).get_title()
|
||||
if place_title != "":
|
||||
if len(place_title) > 15:
|
||||
ep = place_title[:14]+"..."
|
||||
else:
|
||||
ep = place_title
|
||||
if ep:
|
||||
return u"\n%s %s, %s" % (label,ed,ep)
|
||||
return u"\n%s %s" % (label,ed)
|
||||
|
||||
|
||||
birth_ref = person.get_birth_ref()
|
||||
if birth_ref:
|
||||
detail_text += format_event(db, _BORN,
|
||||
db.get_event_from_handle(birth_ref.ref))
|
||||
else:
|
||||
for event_ref in person.get_event_ref_list():
|
||||
event = db.get_event_from_handle(event_ref.ref)
|
||||
if event and event.get_type() == gen.lib.EventType.BAPTISM:
|
||||
detail_text += format_event(db, _BAPT, event)
|
||||
break
|
||||
if event and event.get_type() == gen.lib.EventType.CHRISTEN:
|
||||
detail_text += format_event(db, _CHRI, event)
|
||||
break
|
||||
|
||||
death_ref = person.get_death_ref()
|
||||
if death_ref:
|
||||
detail_text += format_event(db, _DIED,
|
||||
db.get_event_from_handle(death_ref.ref))
|
||||
else:
|
||||
for event_ref in person.get_event_ref_list():
|
||||
event = db.get_event_from_handle(event_ref.ref)
|
||||
if event and event.get_type() == gen.lib.EventType.BURIAL:
|
||||
detail_text += format_event(db, _BURI, event)
|
||||
break
|
||||
if event and event.get_type() == gen.lib.EventType.CREMATION:
|
||||
detail_text += format_event(db, _CREM, event)
|
||||
break
|
||||
|
||||
return detail_text
|
||||
File diff suppressed because it is too large.
Load diff
@@ -21,7 +21,7 @@
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Base view for Place Views
|
||||
Place View
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -44,47 +44,33 @@ import gtk
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gui.views.listview import ListView
|
||||
from gui.utils import add_menuitem
|
||||
import PageView
|
||||
import DisplayModels
|
||||
import Utils
|
||||
import Errors
|
||||
import Bookmarks
|
||||
import config
|
||||
import Config
|
||||
from QuestionDialog import ErrorDialog
|
||||
from gui.pluginmanager import GuiPluginManager
|
||||
from gen.plug import PluginManager
|
||||
from DdTargets import DdTargets
|
||||
from gui.editors import EditPlace, DeletePlaceQuery
|
||||
from Editors import EditPlace, DeletePlaceQuery
|
||||
from Filters.SideBar import PlaceSidebarFilter
|
||||
from gen.plug import CATEGORY_QR_PLACE
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
from gettext import gettext as _
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# PlaceBaseView
|
||||
# PlaceView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class PlaceBaseView(ListView):
|
||||
""" base view class for place views, be they flat list or tree
|
||||
"""
|
||||
COL_NAME = 0
|
||||
COL_ID = 1
|
||||
COL_PARISH = 2
|
||||
COL_ZIP = 3
|
||||
COL_CITY = 4
|
||||
COL_COUNTY = 5
|
||||
COL_STATE = 6
|
||||
COL_COUNTRY = 7
|
||||
COL_LAT = 8
|
||||
COL_LON = 9
|
||||
COL_CHAN = 10
|
||||
COL_STREET = 11
|
||||
# name of the columns
|
||||
class PlaceView(PageView.ListView):
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('Place Name'),
|
||||
_('ID'),
|
||||
@@ -99,26 +85,13 @@ class PlaceBaseView(ListView):
|
||||
_('Last Changed'),
|
||||
_('Street'),
|
||||
]
|
||||
# columns that contain markup
|
||||
MARKUP_COLS = [COL_NAME]
|
||||
# default setting with visible columns, order of the col, and their size
|
||||
CONFIGSETTINGS = (
|
||||
('columns.visible', [COL_NAME, COL_ID, COL_STREET, COL_CITY, COL_STATE
|
||||
]),
|
||||
('columns.rank', [COL_NAME, COL_ID, COL_STREET, COL_ZIP, COL_CITY,
|
||||
COL_COUNTY, COL_STATE, COL_COUNTRY, COL_LAT,
|
||||
COL_LON, COL_PARISH, COL_CHAN]),
|
||||
('columns.size', [250, 75, 100, 100, 100, 100, 150, 150, 150,
|
||||
150, 150, 100])
|
||||
)
|
||||
|
||||
ADD_MSG = _("Add a new place")
|
||||
EDIT_MSG = _("Edit the selected place")
|
||||
DEL_MSG = _("Delete the selected place")
|
||||
FILTER_TYPE = "Place"
|
||||
QR_CATEGORY = CATEGORY_QR_PLACE
|
||||
|
||||
def __init__(self, dbstate, uistate, title, model, nav_group,
|
||||
markup=None):
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'place-add' : self.row_add,
|
||||
@@ -132,29 +105,28 @@ class PlaceBaseView(ListView):
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
self.mapservice = config.get('interface.mapservice')
|
||||
self.mapservice = Config.get(Config.MAPSERVICE)
|
||||
self.mapservicedata = {}
|
||||
|
||||
ListView.__init__(
|
||||
self, title, dbstate, uistate,
|
||||
self.COLUMN_NAMES, 13,
|
||||
model, signal_map,
|
||||
PageView.ListView.__init__(
|
||||
self, _('Places'), dbstate, uistate, PlaceView.COLUMN_NAMES,
|
||||
len(PlaceView.COLUMN_NAMES),
|
||||
DisplayModels.PlaceModel, signal_map,
|
||||
dbstate.db.get_place_bookmarks(),
|
||||
Bookmarks.PlaceBookmarks, nav_group,
|
||||
Bookmarks.PlaceBookmarks,
|
||||
multiple=True,
|
||||
filter_class=PlaceSidebarFilter, markup=markup)
|
||||
filter_class=PlaceSidebarFilter)
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
Config.client.notify_add("/apps/gramps/interface/filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def navigation_type(self):
|
||||
return 'Place'
|
||||
|
||||
def get_bookmarks(self):
|
||||
return self.dbstate.db.get_place_bookmarks()
|
||||
|
||||
def define_actions(self):
|
||||
ListView.define_actions(self)
|
||||
PageView.ListView.define_actions(self)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor)
|
||||
self._add_action('FastMerge', None, _('_Merge...'),
|
||||
callback=self.fast_merge)
|
||||
self._add_toolmenu_action('MapsList', _('Loading...'),
|
||||
@@ -169,8 +141,6 @@ class PlaceBaseView(ListView):
|
||||
"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)
|
||||
self._add_action('Dummy', None, ' ', None, None, self.dummy_report)
|
||||
|
||||
def change_page(self):
|
||||
"""
|
||||
@@ -182,7 +152,7 @@ class PlaceBaseView(ListView):
|
||||
4. set icon and label of the menutoolbutton now that it is realized
|
||||
5. store label so it can be changed when selection changes
|
||||
"""
|
||||
ListView.change_page(self)
|
||||
PageView.ListView.change_page(self)
|
||||
#menutoolbutton actions are stored in PageView class,
|
||||
# obtain the widgets where we need to add to menu
|
||||
actionservices = self.action_toolmenu['MapsList']
|
||||
@@ -208,10 +178,6 @@ class PlaceBaseView(ListView):
|
||||
self.mapslistlabel.append(lbl)
|
||||
widget.set_label_widget(self.mapslistlabel[-1])
|
||||
widget.set_stock_id(gtk.STOCK_JUMP_TO)
|
||||
if self.drag_info():
|
||||
self.list.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
|
||||
[('text/plain', 0, 0), self.drag_info().target()],
|
||||
gtk.gdk.ACTION_COPY)
|
||||
|
||||
def __create_maps_menu_actions(self):
|
||||
"""
|
||||
@@ -222,12 +188,12 @@ class PlaceBaseView(ListView):
|
||||
|
||||
#select the map services to show
|
||||
self.mapservicedata = {}
|
||||
servlist = GuiPluginManager.get_instance().get_reg_mapservices()
|
||||
for i, pdata in enumerate(servlist):
|
||||
key = pdata.id.replace(' ', '-')
|
||||
add_menuitem(menu, pdata.name, None,
|
||||
servlist = PluginManager.get_instance().get_mapservice_list()
|
||||
for i, service in zip(range(len(servlist)), servlist):
|
||||
key = service[2].replace(' ', '-')
|
||||
Utils.add_menuitem(menu, service[1], None,
|
||||
make_callback(self.set_mapservice, key))
|
||||
self.mapservicedata[key] = pdata
|
||||
self.mapservicedata[key] = (service[0], service[2], service[3])
|
||||
|
||||
return menu
|
||||
|
||||
@@ -240,14 +206,14 @@ class PlaceBaseView(ListView):
|
||||
for label in self.mapslistlabel:
|
||||
label.set_label(self.mapservice_label())
|
||||
label.show()
|
||||
config.set('interface.mapservice', mapkey)
|
||||
config.save()
|
||||
Config.set(Config.MAPSERVICE, mapkey)
|
||||
Config.sync()
|
||||
|
||||
def mapservice_label(self):
|
||||
"""
|
||||
return the current label for the menutoolbutton
|
||||
"""
|
||||
return self.mapservicedata[self.mapservice].name
|
||||
return self.mapservicedata[self.mapservice][1]
|
||||
|
||||
def gotomap(self, obj):
|
||||
"""
|
||||
@@ -259,7 +225,7 @@ class PlaceBaseView(ListView):
|
||||
msg2 = _("Check your installation.")
|
||||
ErrorDialog(msg, msg2)
|
||||
return
|
||||
|
||||
|
||||
place_handles = self.selected_handles()
|
||||
try:
|
||||
place_handle = self.selected_handles()[0]
|
||||
@@ -276,18 +242,28 @@ class PlaceBaseView(ListView):
|
||||
places = [(x, None) for x in place_handles]
|
||||
|
||||
#run the mapservice:
|
||||
pmgr = GuiPluginManager.get_instance()
|
||||
serv = self.mapservicedata[self.mapservice]
|
||||
mod = pmgr.load_plugin(serv)
|
||||
if mod:
|
||||
servfunc = eval('mod.' + serv.mapservice)
|
||||
servfunc()(self.dbstate.db, places)
|
||||
else:
|
||||
print 'Failed to load map plugin, see Plugin Manager'
|
||||
self.mapservicedata[self.mapservice][0](self.dbstate.db, places)
|
||||
|
||||
def drag_info(self):
|
||||
return DdTargets.PLACE_LINK
|
||||
|
||||
def _column_editor(self, obj):
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Place Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_place_column_order(),
|
||||
PlaceView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def set_column_order(self, clist):
|
||||
self.dbstate.db.set_place_column_order(clist)
|
||||
self.build_columns()
|
||||
|
||||
def column_order(self):
|
||||
return self.dbstate.db.get_place_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
return 'gramps-place'
|
||||
|
||||
@@ -305,19 +281,13 @@ class PlaceBaseView(ListView):
|
||||
<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"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
<placeholder name="Merge">
|
||||
<menuitem action="FastMerge"/>
|
||||
@@ -325,10 +295,6 @@ class PlaceBaseView(ListView):
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonNavigation">
|
||||
<toolitem action="Back"/>
|
||||
<toolitem action="Forward"/>
|
||||
</placeholder>
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
@@ -338,28 +304,13 @@ class PlaceBaseView(ListView):
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
<separator/>
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<separator/>
|
||||
<menu name="QuickReport" action="QuickReport">
|
||||
<menuitem action="Dummy"/>
|
||||
</menu>
|
||||
<separator/>
|
||||
<menuitem action="GotoMap"/>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def dummy_report(self, obj):
|
||||
""" For the xml UI definition of popup to work, the submenu
|
||||
Quick Report must have an entry in the xml
|
||||
As this submenu will be dynamically built, we offer a dummy action
|
||||
"""
|
||||
pass
|
||||
|
||||
def add(self, obj):
|
||||
try:
|
||||
EditPlace(self.dbstate, self.uistate, [], gen.lib.Place())
|
||||
Loaded 100 of 1229 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user