1 /*
2 Copyright (c) 1991-1999 Thomas T. Wetmore IV
3
4 Permission is hereby granted, free of charge, to any person
5 obtaining a copy of this software and associated documentation
6 files (the "Software"), to deal in the Software without
7 restriction, including without limitation the rights to use, copy,
8 modify, merge, publish, distribute, sublicense, and/or sell copies
9 of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be
13 included in all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 /* modified 05 Jan 2000 by Paul B. McBride (pmcbride@tiac.net) */
25 /*=============================================================
26 * tandem.c -- LifeLines tandem browsing operations
27 * Copyright(c) 1991-94 by T.T. Wetmore IV; all rights reserved
28 * pre-SourceForge version information:
29 * 2.3.4 - 24 Jun 93 2.3.5 - 01 Sep 93
30 * 2.3.6 - 01 Nov 93 3.0.0 - 05 May 94
31 * 3.0.2 - 29 Dec 94
32 *===========================================================*/
33
34 #include "llstdlib.h"
35 /* llstdlib.h pulls in standard.h, config.h, sys_inc.h */
36 #include "table.h"
37 #include "translat.h"
38 #include "gedcom.h"
39 #include "indiseq.h"
40 #include "liflines.h"
41 #include "feedback.h"
42 #include "llinesi.h"
43
44 #include "menuitem.h"
45 #include "screen.h"
46
47 /*********************************************
48 * external/imported variables
49 *********************************************/
50
51 extern STRING qSnofath, qSnomoth, qSnospse, qSnocofp;
52 extern STRING qStwohsb, qStwowif, qSidsbrs, qSidplst, qSidcbrs;
53 extern STRING qSidhbrs, qSidwbrs, qSid1wbr, qSid2wbr;
54 extern STRING qSnowife;
55
56 /*********************************************
57 * local function prototypes
58 *********************************************/
59
60 static BOOLEAN handle_tandem_scroll_cmds(INT c);
61
62 /*********************************************
63 * local function definitions
64 * body of module
65 *********************************************/
66
67 /*=============================================
68 * browse_tandem -- Two person browse operation
69 *===========================================*/
browse_tandem(RECORD * prec1,RECORD * prec2,INDISEQ * pseq)70 INT browse_tandem (RECORD *prec1, RECORD *prec2, INDISEQ *pseq)
71 {
72 RECORD current1, current2;
73 INT nkey1p, nkey2p, modep;
74 RECORD tmp=0;
75 STRING key, name;
76 INDISEQ seq;
77 INT c, rc;
78 BOOLEAN reuse=FALSE;
79 static INT mode = 'n';
80
81 ASSERT(prec1);
82 ASSERT(*prec1);
83 ASSERT(nztype(*prec1)=='I');
84 ASSERT(prec2);
85 ASSERT(*prec2);
86 ASSERT(nztype(*prec2)=='I');
87 ASSERT(!*pseq);
88 current1 = *prec1;
89 current2 = *prec2;
90
91 *prec1 = 0;
92 *prec2 = 0;
93 *pseq = 0;
94
95 show_reset_scroll();
96 nkey1p = 0; /* force redraw */
97 nkey2p = 0;
98 modep = mode;
99
100 while (TRUE) {
101 if (nzkeynum(current1) != nkey1p
102 || nzkeynum(current2) != nkey2p
103 || mode != modep) {
104 show_reset_scroll();
105 }
106 display_2indi(current1, current2, mode);
107 c = interact_2indi();
108 /* last keynum & mode, so can tell if changed */
109 nkey1p = nzkeynum(current1);
110 nkey2p = nzkeynum(current2);
111 modep = mode;
112 if (handle_menu_cmds(c, &reuse))
113 continue;
114 if (handle_indi_mode_cmds(c, &mode))
115 continue;
116 if (handle_tandem_scroll_cmds(c))
117 continue;
118 switch (c)
119 {
120 case CMD_EDIT: /* edit top person */
121 edit_indi(current1, &disp_long_rfmt);
122 break;
123 case CMD_TOP: /* browse top person */
124 *prec1 = current1;
125 return BROWSE_INDI;
126 case CMD_FATHER: /* browse top person's father */
127 if ((tmp = choose_father(current1, NULL, _(qSnofath),
128 _(qSidhbrs), NOASK1)) != 0) {
129 current1 = tmp;
130 }
131 break;
132 case CMD_MOTHER: /* browse top person's mother */
133 if ((tmp = choose_mother(current1, NULL, _(qSnomoth),
134 _(qSidwbrs), NOASK1)) != 0) {
135 current1 = tmp;
136 }
137 break;
138 case CMD_SPOUSE: /* browse top person's spouse/s */
139 if ((tmp = choose_spouse(current1, _(qSnospse), _(qSidsbrs))) != 0)
140 current1 = tmp;
141 break;
142 case CMD_CHILDREN: /* browse top person's children */
143 if ((tmp = choose_child(current1, NULL, _(qSnocofp),
144 _(qSidcbrs), NOASK1)) != 0)
145 current1 = tmp;
146 break;
147 case CMD_MERGE_BOTTOM_TO_TOP: /* merge two persons */
148 if ((tmp = merge_two_indis(nztop(current2), nztop(current1), TRUE))) {
149 *prec1 = tmp;
150 return BROWSE_INDI;
151 }
152 break;
153 case CMD_COPY_TOP_TO_BOTTOM: /* copy top person to bottom */
154 current2 = current1;
155 break;
156 case CMD_SWAPTOPBOTTOM: /* swap two persons */
157 tmp = current1;
158 current1 = current2;
159 current2 = tmp;
160 break;
161 case CMD_ADDFAMILY: /* make two persons parents in family */
162 tmp = add_family_by_edit(current1, current2, NULL, &disp_long_rfmt);
163 if (tmp) {
164 *prec1 = tmp;
165 return BROWSE_FAM;
166 }
167 break;
168 case CMD_BROWSE: /* browse to new person list */
169 seq = ask_for_indiseq(_(qSidplst), 'I', &rc);
170 if (!seq) break;
171 if (length_indiseq(seq) == 1) {
172 element_indiseq(seq, 0, &key, &name);
173 *prec1 = key_to_record(key);
174 remove_indiseq(seq);
175 return BROWSE_INDI;
176 }
177 *pseq = seq;
178 return BROWSE_LIST;
179 break;
180 case CMD_DEPTH_DOWN: /* decrease pedigree depth */
181 pedigree_increase_generations(-1);
182 break;
183 case CMD_DEPTH_UP: /* increase pedigree depth */
184 pedigree_increase_generations(+1);
185 break;
186 case CMD_QUIT:
187 return BROWSE_QUIT;
188 }
189 }
190 }
191 /*==================================================
192 * browse_2fam -- Handle two family browse operation
193 *================================================*/
browse_2fam(RECORD * prec1,RECORD * prec2,INDISEQ * pseq)194 INT browse_2fam (RECORD *prec1, RECORD *prec2, INDISEQ *pseq)
195 {
196 RECORD current1, current2;
197 INT nkey1p, nkey2p, modep;
198 RECORD tmp, tmp2;
199 INT c;
200 BOOLEAN reuse=FALSE;
201 static INT mode = 'n';
202
203 ASSERT(prec1);
204 ASSERT(*prec1);
205 ASSERT(nztype(*prec1)=='F');
206 ASSERT(prec2);
207 ASSERT(*prec2);
208 ASSERT(nztype(*prec2)=='F');
209 ASSERT(!*pseq);
210 current1 = *prec1;
211 current2 = *prec2;
212
213 *prec1 = 0;
214 *prec2 = 0;
215 *pseq = 0;
216
217 show_reset_scroll();
218 nkey1p = 0; /* force redraw */
219 nkey2p = 0;
220 modep = mode;
221
222 while (TRUE) {
223 if (nzkeynum(current1) != nkey1p
224 || nzkeynum(current2) != nkey2p
225 || mode != modep) {
226 show_reset_scroll();
227 }
228 display_2fam(current1, current2, mode);
229 c = interact_2fam();
230 /* last keynum & mode, so can tell if changed */
231 nkey1p = nzkeynum(current1);
232 nkey2p = nzkeynum(current2);
233 modep = mode;
234 if (handle_menu_cmds(c, &reuse))
235 continue;
236 if (handle_fam_mode_cmds(c, &mode))
237 continue;
238 if (handle_tandem_scroll_cmds(c))
239 continue;
240 switch (c)
241 {
242 case CMD_EDIT: /* edit top fam */
243 edit_family(current1, &disp_long_rfmt);
244 break;
245 case CMD_TOP: /* browse top fam */
246 *prec1 = current1;
247 return BROWSE_FAM;
248 case CMD_BOTTOM: /* browse bottom fam */
249 *prec1 = current2;
250 return BROWSE_FAM;
251 case CMD_BOTH_FATHERS: /* browse to husbs/faths */
252 {
253 RECORD fam1=0, fam2=0;
254 if (fam_to_husb(current1, &fam1) == 1
255 && fam_to_husb(current2, &fam2) == 1) {
256 *prec1 = fam1;
257 *prec2 = fam2;
258 return BROWSE_TAND;
259 }
260 }
261 message(_(qStwohsb));
262 break;
263 case CMD_BOTH_MOTHERS: /* browse to wives/moths */
264 if ((tmp = choose_mother(NULL, current1, _(qSnowife),
265 _(qSid1wbr), NOASK1)) != 0) {
266 if ((tmp2 = choose_mother(NULL, current2, _(qSnowife),
267 _(qSid2wbr), NOASK1)) != 0) {
268 *prec1 = tmp;
269 *prec2 = tmp2;
270 return BROWSE_TAND;
271 }
272 }
273 message(_(qStwowif));
274 break;
275 case CMD_MERGE_BOTTOM_TO_TOP: /* merge two fams */
276 if ((tmp = merge_two_fams(nztop(current2), nztop(current1))) != 0) {
277 *prec1 = tmp;
278 return BROWSE_FAM;
279 }
280 break;
281 case CMD_SWAPTOPBOTTOM: /* swap two fams */
282 tmp = current1;
283 current1 = current2;
284 current2 = tmp;
285 break;
286 case CMD_TOGGLE_CHILDNUMS: /* toggle children numbers */
287 show_childnumbers();
288 break;
289 case CMD_QUIT: /* Return to main menu */
290 return BROWSE_QUIT;
291 }
292 }
293 }
294 /*======================================================
295 * handle_tandem_scroll_cmds -- Handle tandem scrolling
296 * Created: 2001/02/04, Perry Rapp
297 *====================================================*/
298 static BOOLEAN
handle_tandem_scroll_cmds(INT c)299 handle_tandem_scroll_cmds (INT c)
300 {
301 switch(c) {
302 case CMD_SCROLL_TOP_UP: show_scroll(-1); return TRUE;
303 case CMD_SCROLL_TOP_DOWN: show_scroll(+1); return TRUE;
304 case CMD_SCROLL_BOTTOM_UP: show_scroll2(-1); return TRUE;
305 case CMD_SCROLL_BOTTOM_DOWN: show_scroll2(+1); return TRUE;
306 case CMD_SCROLL_BOTH_UP: show_scroll(-1); show_scroll2(-1); return TRUE;
307 case CMD_SCROLL_BOTH_DOWN: show_scroll(+1); show_scroll2(+1); return TRUE;
308 }
309 return FALSE;
310 }
311