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